aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/option.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/option.c')
-rw-r--r--drivers/usb/serial/option.c82
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 */
70static int option_open(struct usb_serial_port *port, struct file *filp); 45static 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
110static struct usb_device_id option_ids[] = { 86static 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};
132static 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 */
150static 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
177static struct usb_serial_driver option_1port_device = { 126static 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
255failed_driver_register: 201failed_driver_register:
256 usb_serial_deregister (&option_3port_device);
257failed_3port_device_register:
258 usb_serial_deregister (&option_1port_device); 202 usb_serial_deregister (&option_1port_device);
259failed_1port_device_register: 203failed_1port_device_register:
260 return retval; 204 return retval;
@@ -263,7 +207,6 @@ failed_1port_device_register:
263static void __exit option_exit(void) 207static 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);