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.c83
1 files changed, 12 insertions, 71 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index b0861b61bba7..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,11 +28,10 @@
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
60#include <linux/config.h>
61#include <linux/kernel.h> 35#include <linux/kernel.h>
62#include <linux/jiffies.h> 36#include <linux/jiffies.h>
63#include <linux/errno.h> 37#include <linux/errno.h>
@@ -65,7 +39,7 @@
65#include <linux/tty_flip.h> 39#include <linux/tty_flip.h>
66#include <linux/module.h> 40#include <linux/module.h>
67#include <linux/usb.h> 41#include <linux/usb.h>
68#include "usb-serial.h" 42#include <linux/usb/serial.h>
69 43
70/* Function prototypes */ 44/* Function prototypes */
71static int option_open(struct usb_serial_port *port, struct file *filp); 45static int option_open(struct usb_serial_port *port, struct file *filp);
@@ -96,27 +70,29 @@ static int option_send_setup(struct usb_serial_port *port);
96#define OPTION_VENDOR_ID 0x0AF0 70#define OPTION_VENDOR_ID 0x0AF0
97#define HUAWEI_VENDOR_ID 0x12D1 71#define HUAWEI_VENDOR_ID 0x12D1
98#define AUDIOVOX_VENDOR_ID 0x0F3D 72#define AUDIOVOX_VENDOR_ID 0x0F3D
99#define SIERRAWIRELESS_VENDOR_ID 0x1199
100#define NOVATELWIRELESS_VENDOR_ID 0x1410 73#define NOVATELWIRELESS_VENDOR_ID 0x1410
74#define ANYDATA_VENDOR_ID 0x16d5
101 75
102#define OPTION_PRODUCT_OLD 0x5000 76#define OPTION_PRODUCT_OLD 0x5000
103#define OPTION_PRODUCT_FUSION 0x6000 77#define OPTION_PRODUCT_FUSION 0x6000
104#define OPTION_PRODUCT_FUSION2 0x6300 78#define OPTION_PRODUCT_FUSION2 0x6300
105#define OPTION_PRODUCT_COBRA 0x6500 79#define OPTION_PRODUCT_COBRA 0x6500
80#define OPTION_PRODUCT_COBRA2 0x6600
106#define HUAWEI_PRODUCT_E600 0x1001 81#define HUAWEI_PRODUCT_E600 0x1001
107#define AUDIOVOX_PRODUCT_AIRCARD 0x0112 82#define AUDIOVOX_PRODUCT_AIRCARD 0x0112
108#define SIERRAWIRELESS_PRODUCT_MC8755 0x6802
109#define NOVATELWIRELESS_PRODUCT_U740 0x1400 83#define NOVATELWIRELESS_PRODUCT_U740 0x1400
84#define ANYDATA_PRODUCT_ID 0x6501
110 85
111static struct usb_device_id option_ids[] = { 86static struct usb_device_id option_ids[] = {
112 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) }, 87 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
113 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) }, 88 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
114 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) }, 89 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
115 { 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) },
116 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, 92 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
117 { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, 93 { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
118 { USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) },
119 { 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) },
120 { } /* Terminating entry */ 96 { } /* Terminating entry */
121}; 97};
122 98
@@ -125,13 +101,11 @@ static struct usb_device_id option_ids1[] = {
125 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) }, 101 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
126 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) }, 102 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
127 { 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) },
128 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, 105 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
129 { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, 106 { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
130 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, 107 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
131 { } /* Terminating entry */ 108 { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
132};
133static struct usb_device_id option_ids3[] = {
134 { USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) },
135 { } /* Terminating entry */ 109 { } /* Terminating entry */
136}; 110};
137 111
@@ -148,37 +122,11 @@ static struct usb_driver option_driver = {
148/* The card has three separate interfaces, which the serial driver 122/* The card has three separate interfaces, which the serial driver
149 * recognizes separately, thus num_port=1. 123 * recognizes separately, thus num_port=1.
150 */ 124 */
151static struct usb_serial_driver option_3port_device = {
152 .driver = {
153 .owner = THIS_MODULE,
154 .name = "option",
155 },
156 .description = "GSM modem (3-port)",
157 .id_table = option_ids3,
158 .num_interrupt_in = NUM_DONT_CARE,
159 .num_bulk_in = NUM_DONT_CARE,
160 .num_bulk_out = NUM_DONT_CARE,
161 .num_ports = 3,
162 .open = option_open,
163 .close = option_close,
164 .write = option_write,
165 .write_room = option_write_room,
166 .chars_in_buffer = option_chars_in_buffer,
167 .throttle = option_rx_throttle,
168 .unthrottle = option_rx_unthrottle,
169 .set_termios = option_set_termios,
170 .break_ctl = option_break_ctl,
171 .tiocmget = option_tiocmget,
172 .tiocmset = option_tiocmset,
173 .attach = option_startup,
174 .shutdown = option_shutdown,
175 .read_int_callback = option_instat_callback,
176};
177 125
178static struct usb_serial_driver option_1port_device = { 126static struct usb_serial_driver option_1port_device = {
179 .driver = { 127 .driver = {
180 .owner = THIS_MODULE, 128 .owner = THIS_MODULE,
181 .name = "option", 129 .name = "option1",
182 }, 130 },
183 .description = "GSM modem (1-port)", 131 .description = "GSM modem (1-port)",
184 .id_table = option_ids1, 132 .id_table = option_ids1,
@@ -242,9 +190,6 @@ static int __init option_init(void)
242 retval = usb_serial_register(&option_1port_device); 190 retval = usb_serial_register(&option_1port_device);
243 if (retval) 191 if (retval)
244 goto failed_1port_device_register; 192 goto failed_1port_device_register;
245 retval = usb_serial_register(&option_3port_device);
246 if (retval)
247 goto failed_3port_device_register;
248 retval = usb_register(&option_driver); 193 retval = usb_register(&option_driver);
249 if (retval) 194 if (retval)
250 goto failed_driver_register; 195 goto failed_driver_register;
@@ -254,8 +199,6 @@ static int __init option_init(void)
254 return 0; 199 return 0;
255 200
256failed_driver_register: 201failed_driver_register:
257 usb_serial_deregister (&option_3port_device);
258failed_3port_device_register:
259 usb_serial_deregister (&option_1port_device); 202 usb_serial_deregister (&option_1port_device);
260failed_1port_device_register: 203failed_1port_device_register:
261 return retval; 204 return retval;
@@ -264,7 +207,6 @@ failed_1port_device_register:
264static void __exit option_exit(void) 207static void __exit option_exit(void)
265{ 208{
266 usb_deregister (&option_driver); 209 usb_deregister (&option_driver);
267 usb_serial_deregister (&option_3port_device);
268 usb_serial_deregister (&option_1port_device); 210 usb_serial_deregister (&option_1port_device);
269} 211}
270 212
@@ -653,7 +595,6 @@ static void option_setup_urbs(struct usb_serial *serial)
653 595
654 dbg("%s", __FUNCTION__); 596 dbg("%s", __FUNCTION__);
655 597
656
657 for (i = 0; i < serial->num_ports; i++) { 598 for (i = 0; i < serial->num_ports; i++) {
658 port = serial->port[i]; 599 port = serial->port[i];
659 portdata = usb_get_serial_port_data(port); 600 portdata = usb_get_serial_port_data(port);