| Greg Kroah-Hartman | 958e874 | 2002-04-09 12:14:34 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * USB Debug cable driver | 
|  | 3 | * | 
|  | 4 | * Copyright (C) 2006 Greg Kroah-Hartman <greg@kroah.com> | 
|  | 5 | * | 
|  | 6 | *	This program is free software; you can redistribute it and/or | 
|  | 7 | *	modify it under the terms of the GNU General Public License version | 
|  | 8 | *	2 as published by the Free Software Foundation. | 
|  | 9 | */ | 
|  | 10 |  | 
| Tejun Heo | 5a0e3ad | 2010-03-24 17:04:11 +0900 | [diff] [blame] | 11 | #include <linux/gfp.h> | 
| Greg Kroah-Hartman | 958e874 | 2002-04-09 12:14:34 -0700 | [diff] [blame] | 12 | #include <linux/kernel.h> | 
|  | 13 | #include <linux/init.h> | 
|  | 14 | #include <linux/tty.h> | 
|  | 15 | #include <linux/module.h> | 
|  | 16 | #include <linux/usb.h> | 
|  | 17 | #include <linux/usb/serial.h> | 
|  | 18 |  | 
| Aleksey Gorelov | 71be4f8 | 2008-06-19 15:22:17 -0700 | [diff] [blame] | 19 | #define USB_DEBUG_MAX_PACKET_SIZE	8 | 
| Jason Wessel | 98fcb5f | 2009-05-11 15:24:09 -0500 | [diff] [blame] | 20 | #define USB_DEBUG_BRK_SIZE		8 | 
|  | 21 | static char USB_DEBUG_BRK[USB_DEBUG_BRK_SIZE] = { | 
|  | 22 | 0x00, | 
|  | 23 | 0xff, | 
|  | 24 | 0x01, | 
|  | 25 | 0xfe, | 
|  | 26 | 0x00, | 
|  | 27 | 0xfe, | 
|  | 28 | 0x01, | 
|  | 29 | 0xff, | 
|  | 30 | }; | 
| Aleksey Gorelov | 71be4f8 | 2008-06-19 15:22:17 -0700 | [diff] [blame] | 31 |  | 
| Németh Márton | 7d40d7e | 2010-01-10 15:34:24 +0100 | [diff] [blame] | 32 | static const struct usb_device_id id_table[] = { | 
| Greg Kroah-Hartman | 958e874 | 2002-04-09 12:14:34 -0700 | [diff] [blame] | 33 | { USB_DEVICE(0x0525, 0x127a) }, | 
|  | 34 | { }, | 
|  | 35 | }; | 
|  | 36 | MODULE_DEVICE_TABLE(usb, id_table); | 
|  | 37 |  | 
|  | 38 | static struct usb_driver debug_driver = { | 
|  | 39 | .name =		"debug", | 
|  | 40 | .probe =	usb_serial_probe, | 
|  | 41 | .disconnect =	usb_serial_disconnect, | 
|  | 42 | .id_table =	id_table, | 
|  | 43 | .no_dynamic_id = 	1, | 
|  | 44 | }; | 
|  | 45 |  | 
| Jason Wessel | 98fcb5f | 2009-05-11 15:24:09 -0500 | [diff] [blame] | 46 | /* This HW really does not support a serial break, so one will be | 
|  | 47 | * emulated when ever the break state is set to true. | 
|  | 48 | */ | 
|  | 49 | static void usb_debug_break_ctl(struct tty_struct *tty, int break_state) | 
|  | 50 | { | 
|  | 51 | struct usb_serial_port *port = tty->driver_data; | 
|  | 52 | if (!break_state) | 
|  | 53 | return; | 
|  | 54 | usb_serial_generic_write(tty, port, USB_DEBUG_BRK, USB_DEBUG_BRK_SIZE); | 
|  | 55 | } | 
|  | 56 |  | 
|  | 57 | static void usb_debug_read_bulk_callback(struct urb *urb) | 
|  | 58 | { | 
|  | 59 | struct usb_serial_port *port = urb->context; | 
|  | 60 |  | 
|  | 61 | if (urb->actual_length == USB_DEBUG_BRK_SIZE && | 
|  | 62 | memcmp(urb->transfer_buffer, USB_DEBUG_BRK, | 
|  | 63 | USB_DEBUG_BRK_SIZE) == 0) { | 
|  | 64 | usb_serial_handle_break(port); | 
| Johan Hovold | 41bd72f | 2010-03-17 23:05:53 +0100 | [diff] [blame] | 65 | usb_serial_generic_submit_read_urb(port, GFP_ATOMIC); | 
| Jason Wessel | 98fcb5f | 2009-05-11 15:24:09 -0500 | [diff] [blame] | 66 | return; | 
|  | 67 | } | 
|  | 68 |  | 
|  | 69 | usb_serial_generic_read_bulk_callback(urb); | 
|  | 70 | } | 
|  | 71 |  | 
| Greg Kroah-Hartman | 958e874 | 2002-04-09 12:14:34 -0700 | [diff] [blame] | 72 | static struct usb_serial_driver debug_device = { | 
|  | 73 | .driver = { | 
|  | 74 | .owner =	THIS_MODULE, | 
|  | 75 | .name =		"debug", | 
|  | 76 | }, | 
|  | 77 | .id_table =		id_table, | 
| Alan Stern | 5620b5f | 2011-01-11 14:16:50 -0500 | [diff] [blame] | 78 | .usb_driver =		&debug_driver, | 
| Greg Kroah-Hartman | 958e874 | 2002-04-09 12:14:34 -0700 | [diff] [blame] | 79 | .num_ports =		1, | 
| Johan Hovold | 7288d75 | 2010-05-16 20:33:48 +0200 | [diff] [blame] | 80 | .bulk_out_size =	USB_DEBUG_MAX_PACKET_SIZE, | 
| Jason Wessel | 98fcb5f | 2009-05-11 15:24:09 -0500 | [diff] [blame] | 81 | .break_ctl =		usb_debug_break_ctl, | 
|  | 82 | .read_bulk_callback =	usb_debug_read_bulk_callback, | 
| Greg Kroah-Hartman | 958e874 | 2002-04-09 12:14:34 -0700 | [diff] [blame] | 83 | }; | 
|  | 84 |  | 
|  | 85 | static int __init debug_init(void) | 
|  | 86 | { | 
|  | 87 | int retval; | 
|  | 88 |  | 
|  | 89 | retval = usb_serial_register(&debug_device); | 
|  | 90 | if (retval) | 
|  | 91 | return retval; | 
|  | 92 | retval = usb_register(&debug_driver); | 
|  | 93 | if (retval) | 
|  | 94 | usb_serial_deregister(&debug_device); | 
|  | 95 | return retval; | 
|  | 96 | } | 
|  | 97 |  | 
|  | 98 | static void __exit debug_exit(void) | 
|  | 99 | { | 
|  | 100 | usb_deregister(&debug_driver); | 
|  | 101 | usb_serial_deregister(&debug_device); | 
|  | 102 | } | 
|  | 103 |  | 
|  | 104 | module_init(debug_init); | 
|  | 105 | module_exit(debug_exit); | 
|  | 106 | MODULE_LICENSE("GPL"); |