diff options
Diffstat (limited to 'drivers/usb/serial/option.c')
-rw-r--r-- | drivers/usb/serial/option.c | 82 |
1 files changed, 12 insertions, 70 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 78ad4b3126a6..c856e6f40e22 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -9,39 +9,14 @@ | |||
9 | 9 | ||
10 | Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org> | 10 | Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org> |
11 | 11 | ||
12 | History: | 12 | History: see the git log. |
13 | |||
14 | 2005-05-19 v0.1 Initial version, based on incomplete docs | ||
15 | and analysis of misbehavior with the standard driver | ||
16 | 2005-05-20 v0.2 Extended the input buffer to avoid losing | ||
17 | random 64-byte chunks of data | ||
18 | 2005-05-21 v0.3 implemented chars_in_buffer() | ||
19 | turned on low_latency | ||
20 | simplified the code somewhat | ||
21 | 2005-05-24 v0.4 option_write() sometimes deadlocked under heavy load | ||
22 | removed some dead code | ||
23 | added sponsor notice | ||
24 | coding style clean-up | ||
25 | 2005-06-20 v0.4.1 add missing braces :-/ | ||
26 | killed end-of-line whitespace | ||
27 | 2005-07-15 v0.4.2 rename WLAN product to FUSION, add FUSION2 | ||
28 | 2005-09-10 v0.4.3 added HUAWEI E600 card and Audiovox AirCard | ||
29 | 2005-09-20 v0.4.4 increased recv buffer size: the card sometimes | ||
30 | wants to send >2000 bytes. | ||
31 | 2006-04-10 v0.5 fixed two array overrun errors :-/ | ||
32 | 2006-04-21 v0.5.1 added support for Sierra Wireless MC8755 | ||
33 | 2006-05-15 v0.6 re-enable multi-port support | ||
34 | 2006-06-01 v0.6.1 add COBRA | ||
35 | 2006-06-01 v0.6.2 add backwards-compatibility stuff | ||
36 | 2006-06-01 v0.6.3 add Novatel Wireless | ||
37 | 2006-06-01 v0.7 Option => GSM | ||
38 | 13 | ||
39 | Work sponsored by: Sigos GmbH, Germany <info@sigos.de> | 14 | Work sponsored by: Sigos GmbH, Germany <info@sigos.de> |
40 | 15 | ||
41 | This driver exists because the "normal" serial driver doesn't work too well | 16 | This driver exists because the "normal" serial driver doesn't work too well |
42 | with GSM modems. Issues: | 17 | with GSM modems. Issues: |
43 | - data loss -- one single Receive URB is not nearly enough | 18 | - data loss -- one single Receive URB is not nearly enough |
44 | - nonstandard flow (Option devices) and multiplex (Sierra) control | 19 | - nonstandard flow (Option devices) control |
45 | - controlling the baud rate doesn't make sense | 20 | - controlling the baud rate doesn't make sense |
46 | 21 | ||
47 | This driver is named "option" because the most common device it's | 22 | This driver is named "option" because the most common device it's |
@@ -53,7 +28,7 @@ | |||
53 | device features. | 28 | device features. |
54 | */ | 29 | */ |
55 | 30 | ||
56 | #define DRIVER_VERSION "v0.7.0" | 31 | #define DRIVER_VERSION "v0.7.1" |
57 | #define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>" | 32 | #define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>" |
58 | #define DRIVER_DESC "USB Driver for GSM modems" | 33 | #define DRIVER_DESC "USB Driver for GSM modems" |
59 | 34 | ||
@@ -64,7 +39,7 @@ | |||
64 | #include <linux/tty_flip.h> | 39 | #include <linux/tty_flip.h> |
65 | #include <linux/module.h> | 40 | #include <linux/module.h> |
66 | #include <linux/usb.h> | 41 | #include <linux/usb.h> |
67 | #include "usb-serial.h" | 42 | #include <linux/usb/serial.h> |
68 | 43 | ||
69 | /* Function prototypes */ | 44 | /* Function prototypes */ |
70 | static int option_open(struct usb_serial_port *port, struct file *filp); | 45 | static int option_open(struct usb_serial_port *port, struct file *filp); |
@@ -95,27 +70,29 @@ static int option_send_setup(struct usb_serial_port *port); | |||
95 | #define OPTION_VENDOR_ID 0x0AF0 | 70 | #define OPTION_VENDOR_ID 0x0AF0 |
96 | #define HUAWEI_VENDOR_ID 0x12D1 | 71 | #define HUAWEI_VENDOR_ID 0x12D1 |
97 | #define AUDIOVOX_VENDOR_ID 0x0F3D | 72 | #define AUDIOVOX_VENDOR_ID 0x0F3D |
98 | #define SIERRAWIRELESS_VENDOR_ID 0x1199 | ||
99 | #define NOVATELWIRELESS_VENDOR_ID 0x1410 | 73 | #define NOVATELWIRELESS_VENDOR_ID 0x1410 |
74 | #define ANYDATA_VENDOR_ID 0x16d5 | ||
100 | 75 | ||
101 | #define OPTION_PRODUCT_OLD 0x5000 | 76 | #define OPTION_PRODUCT_OLD 0x5000 |
102 | #define OPTION_PRODUCT_FUSION 0x6000 | 77 | #define OPTION_PRODUCT_FUSION 0x6000 |
103 | #define OPTION_PRODUCT_FUSION2 0x6300 | 78 | #define OPTION_PRODUCT_FUSION2 0x6300 |
104 | #define OPTION_PRODUCT_COBRA 0x6500 | 79 | #define OPTION_PRODUCT_COBRA 0x6500 |
80 | #define OPTION_PRODUCT_COBRA2 0x6600 | ||
105 | #define HUAWEI_PRODUCT_E600 0x1001 | 81 | #define HUAWEI_PRODUCT_E600 0x1001 |
106 | #define AUDIOVOX_PRODUCT_AIRCARD 0x0112 | 82 | #define AUDIOVOX_PRODUCT_AIRCARD 0x0112 |
107 | #define SIERRAWIRELESS_PRODUCT_MC8755 0x6802 | ||
108 | #define NOVATELWIRELESS_PRODUCT_U740 0x1400 | 83 | #define NOVATELWIRELESS_PRODUCT_U740 0x1400 |
84 | #define ANYDATA_PRODUCT_ID 0x6501 | ||
109 | 85 | ||
110 | static struct usb_device_id option_ids[] = { | 86 | static struct usb_device_id option_ids[] = { |
111 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) }, | 87 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) }, |
112 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) }, | 88 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) }, |
113 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) }, | 89 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) }, |
114 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, | 90 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, |
91 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) }, | ||
115 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, | 92 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, |
116 | { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, | 93 | { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, |
117 | { USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) }, | ||
118 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, | 94 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, |
95 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, | ||
119 | { } /* Terminating entry */ | 96 | { } /* Terminating entry */ |
120 | }; | 97 | }; |
121 | 98 | ||
@@ -124,13 +101,11 @@ static struct usb_device_id option_ids1[] = { | |||
124 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) }, | 101 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) }, |
125 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) }, | 102 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) }, |
126 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, | 103 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, |
104 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) }, | ||
127 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, | 105 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, |
128 | { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, | 106 | { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, |
129 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, | 107 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, |
130 | { } /* Terminating entry */ | 108 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, |
131 | }; | ||
132 | static struct usb_device_id option_ids3[] = { | ||
133 | { USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) }, | ||
134 | { } /* Terminating entry */ | 109 | { } /* Terminating entry */ |
135 | }; | 110 | }; |
136 | 111 | ||
@@ -147,37 +122,11 @@ static struct usb_driver option_driver = { | |||
147 | /* The card has three separate interfaces, which the serial driver | 122 | /* The card has three separate interfaces, which the serial driver |
148 | * recognizes separately, thus num_port=1. | 123 | * recognizes separately, thus num_port=1. |
149 | */ | 124 | */ |
150 | static struct usb_serial_driver option_3port_device = { | ||
151 | .driver = { | ||
152 | .owner = THIS_MODULE, | ||
153 | .name = "option", | ||
154 | }, | ||
155 | .description = "GSM modem (3-port)", | ||
156 | .id_table = option_ids3, | ||
157 | .num_interrupt_in = NUM_DONT_CARE, | ||
158 | .num_bulk_in = NUM_DONT_CARE, | ||
159 | .num_bulk_out = NUM_DONT_CARE, | ||
160 | .num_ports = 3, | ||
161 | .open = option_open, | ||
162 | .close = option_close, | ||
163 | .write = option_write, | ||
164 | .write_room = option_write_room, | ||
165 | .chars_in_buffer = option_chars_in_buffer, | ||
166 | .throttle = option_rx_throttle, | ||
167 | .unthrottle = option_rx_unthrottle, | ||
168 | .set_termios = option_set_termios, | ||
169 | .break_ctl = option_break_ctl, | ||
170 | .tiocmget = option_tiocmget, | ||
171 | .tiocmset = option_tiocmset, | ||
172 | .attach = option_startup, | ||
173 | .shutdown = option_shutdown, | ||
174 | .read_int_callback = option_instat_callback, | ||
175 | }; | ||
176 | 125 | ||
177 | static struct usb_serial_driver option_1port_device = { | 126 | static struct usb_serial_driver option_1port_device = { |
178 | .driver = { | 127 | .driver = { |
179 | .owner = THIS_MODULE, | 128 | .owner = THIS_MODULE, |
180 | .name = "option", | 129 | .name = "option1", |
181 | }, | 130 | }, |
182 | .description = "GSM modem (1-port)", | 131 | .description = "GSM modem (1-port)", |
183 | .id_table = option_ids1, | 132 | .id_table = option_ids1, |
@@ -241,9 +190,6 @@ static int __init option_init(void) | |||
241 | retval = usb_serial_register(&option_1port_device); | 190 | retval = usb_serial_register(&option_1port_device); |
242 | if (retval) | 191 | if (retval) |
243 | goto failed_1port_device_register; | 192 | goto failed_1port_device_register; |
244 | retval = usb_serial_register(&option_3port_device); | ||
245 | if (retval) | ||
246 | goto failed_3port_device_register; | ||
247 | retval = usb_register(&option_driver); | 193 | retval = usb_register(&option_driver); |
248 | if (retval) | 194 | if (retval) |
249 | goto failed_driver_register; | 195 | goto failed_driver_register; |
@@ -253,8 +199,6 @@ static int __init option_init(void) | |||
253 | return 0; | 199 | return 0; |
254 | 200 | ||
255 | failed_driver_register: | 201 | failed_driver_register: |
256 | usb_serial_deregister (&option_3port_device); | ||
257 | failed_3port_device_register: | ||
258 | usb_serial_deregister (&option_1port_device); | 202 | usb_serial_deregister (&option_1port_device); |
259 | failed_1port_device_register: | 203 | failed_1port_device_register: |
260 | return retval; | 204 | return retval; |
@@ -263,7 +207,6 @@ failed_1port_device_register: | |||
263 | static void __exit option_exit(void) | 207 | static void __exit option_exit(void) |
264 | { | 208 | { |
265 | usb_deregister (&option_driver); | 209 | usb_deregister (&option_driver); |
266 | usb_serial_deregister (&option_3port_device); | ||
267 | usb_serial_deregister (&option_1port_device); | 210 | usb_serial_deregister (&option_1port_device); |
268 | } | 211 | } |
269 | 212 | ||
@@ -652,7 +595,6 @@ static void option_setup_urbs(struct usb_serial *serial) | |||
652 | 595 | ||
653 | dbg("%s", __FUNCTION__); | 596 | dbg("%s", __FUNCTION__); |
654 | 597 | ||
655 | |||
656 | for (i = 0; i < serial->num_ports; i++) { | 598 | for (i = 0; i < serial->num_ports; i++) { |
657 | port = serial->port[i]; | 599 | port = serial->port[i]; |
658 | portdata = usb_get_serial_port_data(port); | 600 | portdata = usb_get_serial_port_data(port); |