2 USB Driver for GSM modems
4 Copyright (C) 2005 Matthias Urlichs <smurf@smurf.noris.de>
6 This driver is free software; you can redistribute it and/or modify
7 it under the terms of Version 2 of the GNU General Public License as
8 published by the Free Software Foundation.
10 Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org>
12 History: see the git log.
14 Work sponsored by: Sigos GmbH, Germany <info@sigos.de>
16 This driver exists because the "normal" serial driver doesn't work too well
17 with GSM modems. Issues:
18 - data loss -- one single Receive URB is not nearly enough
19 - nonstandard flow (Option devices) control
20 - controlling the baud rate doesn't make sense
22 This driver is named "option" because the most common device it's
23 used for is a PC-Card (with an internal OHCI-USB interface, behind
24 which the GSM interface sits), made by Option Inc.
26 Some of the "one port" devices actually exhibit multiple USB instances
27 on the USB bus. This is not a bug, these ports are used for different
31 #define DRIVER_VERSION "v0.7.1"
32 #define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
33 #define DRIVER_DESC "USB Driver for GSM modems"
35 #include <linux/kernel.h>
36 #include <linux/jiffies.h>
37 #include <linux/errno.h>
38 #include <linux/tty.h>
39 #include <linux/tty_flip.h>
40 #include <linux/module.h>
41 #include <linux/usb.h>
42 #include <linux/usb/serial.h>
44 /* Function prototypes */
45 static int option_open(struct usb_serial_port *port, struct file *filp);
46 static void option_close(struct usb_serial_port *port, struct file *filp);
47 static int option_startup(struct usb_serial *serial);
48 static void option_shutdown(struct usb_serial *serial);
49 static void option_rx_throttle(struct usb_serial_port *port);
50 static void option_rx_unthrottle(struct usb_serial_port *port);
51 static int option_write_room(struct usb_serial_port *port);
53 static void option_instat_callback(struct urb *urb);
55 static int option_write(struct usb_serial_port *port,
56 const unsigned char *buf, int count);
58 static int option_chars_in_buffer(struct usb_serial_port *port);
59 static int option_ioctl(struct usb_serial_port *port, struct file *file,
60 unsigned int cmd, unsigned long arg);
61 static void option_set_termios(struct usb_serial_port *port,
62 struct ktermios *old);
63 static void option_break_ctl(struct usb_serial_port *port, int break_state);
64 static int option_tiocmget(struct usb_serial_port *port, struct file *file);
65 static int option_tiocmset(struct usb_serial_port *port, struct file *file,
66 unsigned int set, unsigned int clear);
67 static int option_send_setup(struct usb_serial_port *port);
69 /* Vendor and product IDs */
70 #define OPTION_VENDOR_ID 0x0AF0
71 #define HUAWEI_VENDOR_ID 0x12D1
72 #define AUDIOVOX_VENDOR_ID 0x0F3D
73 #define NOVATELWIRELESS_VENDOR_ID 0x1410
74 #define ANYDATA_VENDOR_ID 0x16d5
76 #define OPTION_PRODUCT_OLD 0x5000
77 #define OPTION_PRODUCT_FUSION 0x6000
78 #define OPTION_PRODUCT_FUSION2 0x6300
79 #define OPTION_PRODUCT_COBRA 0x6500
80 #define OPTION_PRODUCT_COBRA2 0x6600
81 #define OPTION_PRODUCT_GTMAX36 0x6701
82 #define HUAWEI_PRODUCT_E600 0x1001
83 #define HUAWEI_PRODUCT_E220 0x1003
84 #define AUDIOVOX_PRODUCT_AIRCARD 0x0112
85 #define NOVATELWIRELESS_PRODUCT_U740 0x1400
86 #define ANYDATA_PRODUCT_ID 0x6501
88 static struct usb_device_id option_ids[] = {
89 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
90 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
91 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
92 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
93 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
94 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) },
95 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
96 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
97 { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
98 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
99 { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
100 { } /* Terminating entry */
103 static struct usb_device_id option_ids1[] = {
104 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
105 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
106 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
107 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
108 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
109 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) },
110 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
111 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
112 { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
113 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
114 { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
115 { } /* Terminating entry */
118 MODULE_DEVICE_TABLE(usb, option_ids);
120 static struct usb_driver option_driver = {
122 .probe = usb_serial_probe,
123 .disconnect = usb_serial_disconnect,
124 .id_table = option_ids,
128 /* The card has three separate interfaces, which the serial driver
129 * recognizes separately, thus num_port=1.
132 static struct usb_serial_driver option_1port_device = {
134 .owner = THIS_MODULE,
137 .description = "GSM modem (1-port)",
138 .id_table = option_ids1,
139 .num_interrupt_in = NUM_DONT_CARE,
140 .num_bulk_in = NUM_DONT_CARE,
141 .num_bulk_out = NUM_DONT_CARE,
144 .close = option_close,
145 .write = option_write,
146 .write_room = option_write_room,
147 .chars_in_buffer = option_chars_in_buffer,
148 .throttle = option_rx_throttle,
149 .unthrottle = option_rx_unthrottle,
150 .ioctl = option_ioctl,
151 .set_termios = option_set_termios,
152 .break_ctl = option_break_ctl,
153 .tiocmget = option_tiocmget,
154 .tiocmset = option_tiocmset,
155 .attach = option_startup,
156 .shutdown = option_shutdown,
157 .read_int_callback = option_instat_callback,
160 #ifdef CONFIG_USB_DEBUG
166 /* per port private data */
170 #define IN_BUFLEN 4096
171 #define OUT_BUFLEN 128
173 struct option_port_private {
174 /* Input endpoints and buffer for this port */
175 struct urb *in_urbs[N_IN_URB];
176 char in_buffer[N_IN_URB][IN_BUFLEN];
177 /* Output endpoints and buffer for this port */
178 struct urb *out_urbs[N_OUT_URB];
179 char out_buffer[N_OUT_URB][OUT_BUFLEN];
181 /* Settings for the port */
182 int rts_state; /* Handshaking pins (outputs) */
184 int cts_state; /* Handshaking pins (inputs) */
189 unsigned long tx_start_time[N_OUT_URB];
192 /* Functions used by new usb-serial code. */
193 static int __init option_init(void)
196 retval = usb_serial_register(&option_1port_device);
198 goto failed_1port_device_register;
199 retval = usb_register(&option_driver);
201 goto failed_driver_register;
203 info(DRIVER_DESC ": " DRIVER_VERSION);
207 failed_driver_register:
208 usb_serial_deregister (&option_1port_device);
209 failed_1port_device_register:
213 static void __exit option_exit(void)
215 usb_deregister (&option_driver);
216 usb_serial_deregister (&option_1port_device);
219 module_init(option_init);
220 module_exit(option_exit);
222 static void option_rx_throttle(struct usb_serial_port *port)
224 dbg("%s", __FUNCTION__);
227 static void option_rx_unthrottle(struct usb_serial_port *port)
229 dbg("%s", __FUNCTION__);
232 static void option_break_ctl(struct usb_serial_port *port, int break_state)
234 /* Unfortunately, I don't know how to send a break */
235 dbg("%s", __FUNCTION__);
238 static void option_set_termios(struct usb_serial_port *port,
239 struct ktermios *old_termios)
241 dbg("%s", __FUNCTION__);
243 option_send_setup(port);
246 static int option_tiocmget(struct usb_serial_port *port, struct file *file)
249 struct option_port_private *portdata;
251 portdata = usb_get_serial_port_data(port);
253 value = ((portdata->rts_state) ? TIOCM_RTS : 0) |
254 ((portdata->dtr_state) ? TIOCM_DTR : 0) |
255 ((portdata->cts_state) ? TIOCM_CTS : 0) |
256 ((portdata->dsr_state) ? TIOCM_DSR : 0) |
257 ((portdata->dcd_state) ? TIOCM_CAR : 0) |
258 ((portdata->ri_state) ? TIOCM_RNG : 0);
263 static int option_tiocmset(struct usb_serial_port *port, struct file *file,
264 unsigned int set, unsigned int clear)
266 struct option_port_private *portdata;
268 portdata = usb_get_serial_port_data(port);
271 portdata->rts_state = 1;
273 portdata->dtr_state = 1;
275 if (clear & TIOCM_RTS)
276 portdata->rts_state = 0;
277 if (clear & TIOCM_DTR)
278 portdata->dtr_state = 0;
279 return option_send_setup(port);
282 static int option_ioctl(struct usb_serial_port *port, struct file *file,
283 unsigned int cmd, unsigned long arg)
289 static int option_write(struct usb_serial_port *port,
290 const unsigned char *buf, int count)
292 struct option_port_private *portdata;
295 struct urb *this_urb = NULL; /* spurious */
298 portdata = usb_get_serial_port_data(port);
300 dbg("%s: write (%d chars)", __FUNCTION__, count);
304 for (i=0; left > 0 && i < N_OUT_URB; i++) {
306 if (todo > OUT_BUFLEN)
309 this_urb = portdata->out_urbs[i];
310 if (this_urb->status == -EINPROGRESS) {
311 if (time_before(jiffies,
312 portdata->tx_start_time[i] + 10 * HZ))
314 usb_unlink_urb(this_urb);
317 if (this_urb->status != 0)
318 dbg("usb_write %p failed (err=%d)",
319 this_urb, this_urb->status);
321 dbg("%s: endpoint %d buf %d", __FUNCTION__,
322 usb_pipeendpoint(this_urb->pipe), i);
325 memcpy (this_urb->transfer_buffer, buf, todo);
326 this_urb->transfer_buffer_length = todo;
328 this_urb->dev = port->serial->dev;
329 err = usb_submit_urb(this_urb, GFP_ATOMIC);
331 dbg("usb_submit_urb %p (write bulk) failed "
332 "(%d, has %d)", this_urb,
333 err, this_urb->status);
336 portdata->tx_start_time[i] = jiffies;
342 dbg("%s: wrote (did %d)", __FUNCTION__, count);
346 static void option_indat_callback(struct urb *urb)
350 struct usb_serial_port *port;
351 struct tty_struct *tty;
352 unsigned char *data = urb->transfer_buffer;
354 dbg("%s: %p", __FUNCTION__, urb);
356 endpoint = usb_pipeendpoint(urb->pipe);
357 port = (struct usb_serial_port *) urb->context;
360 dbg("%s: nonzero status: %d on endpoint %02x.",
361 __FUNCTION__, urb->status, endpoint);
364 if (urb->actual_length) {
365 tty_buffer_request_room(tty, urb->actual_length);
366 tty_insert_flip_string(tty, data, urb->actual_length);
367 tty_flip_buffer_push(tty);
369 dbg("%s: empty read urb received", __FUNCTION__);
372 /* Resubmit urb so we continue receiving */
373 if (port->open_count && urb->status != -ESHUTDOWN) {
374 err = usb_submit_urb(urb, GFP_ATOMIC);
376 printk(KERN_ERR "%s: resubmit read urb failed. "
377 "(%d)", __FUNCTION__, err);
383 static void option_outdat_callback(struct urb *urb)
385 struct usb_serial_port *port;
387 dbg("%s", __FUNCTION__);
389 port = (struct usb_serial_port *) urb->context;
391 usb_serial_port_softint(port);
394 static void option_instat_callback(struct urb *urb)
397 struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
398 struct option_port_private *portdata = usb_get_serial_port_data(port);
399 struct usb_serial *serial = port->serial;
401 dbg("%s", __FUNCTION__);
402 dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata);
404 if (urb->status == 0) {
405 struct usb_ctrlrequest *req_pkt =
406 (struct usb_ctrlrequest *)urb->transfer_buffer;
409 dbg("%s: NULL req_pkt\n", __FUNCTION__);
412 if ((req_pkt->bRequestType == 0xA1) &&
413 (req_pkt->bRequest == 0x20)) {
415 unsigned char signals = *((unsigned char *)
416 urb->transfer_buffer +
417 sizeof(struct usb_ctrlrequest));
419 dbg("%s: signal x%x", __FUNCTION__, signals);
421 old_dcd_state = portdata->dcd_state;
422 portdata->cts_state = 1;
423 portdata->dcd_state = ((signals & 0x01) ? 1 : 0);
424 portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
425 portdata->ri_state = ((signals & 0x08) ? 1 : 0);
427 if (port->tty && !C_CLOCAL(port->tty) &&
428 old_dcd_state && !portdata->dcd_state)
429 tty_hangup(port->tty);
431 dbg("%s: type %x req %x", __FUNCTION__,
432 req_pkt->bRequestType,req_pkt->bRequest);
435 dbg("%s: error %d", __FUNCTION__, urb->status);
437 /* Resubmit urb so we continue receiving IRQ data */
438 if (urb->status != -ESHUTDOWN) {
439 urb->dev = serial->dev;
440 err = usb_submit_urb(urb, GFP_ATOMIC);
442 dbg("%s: resubmit intr urb failed. (%d)",
447 static int option_write_room(struct usb_serial_port *port)
449 struct option_port_private *portdata;
452 struct urb *this_urb;
454 portdata = usb_get_serial_port_data(port);
456 for (i=0; i < N_OUT_URB; i++) {
457 this_urb = portdata->out_urbs[i];
458 if (this_urb && this_urb->status != -EINPROGRESS)
459 data_len += OUT_BUFLEN;
462 dbg("%s: %d", __FUNCTION__, data_len);
466 static int option_chars_in_buffer(struct usb_serial_port *port)
468 struct option_port_private *portdata;
471 struct urb *this_urb;
473 portdata = usb_get_serial_port_data(port);
475 for (i=0; i < N_OUT_URB; i++) {
476 this_urb = portdata->out_urbs[i];
477 if (this_urb && this_urb->status == -EINPROGRESS)
478 data_len += this_urb->transfer_buffer_length;
480 dbg("%s: %d", __FUNCTION__, data_len);
484 static int option_open(struct usb_serial_port *port, struct file *filp)
486 struct option_port_private *portdata;
487 struct usb_serial *serial = port->serial;
491 portdata = usb_get_serial_port_data(port);
493 dbg("%s", __FUNCTION__);
495 /* Set some sane defaults */
496 portdata->rts_state = 1;
497 portdata->dtr_state = 1;
499 /* Reset low level data toggle and start reading from endpoints */
500 for (i = 0; i < N_IN_URB; i++) {
501 urb = portdata->in_urbs[i];
504 if (urb->dev != serial->dev) {
505 dbg("%s: dev %p != %p", __FUNCTION__,
506 urb->dev, serial->dev);
511 * make sure endpoint data toggle is synchronized with the
514 usb_clear_halt(urb->dev, urb->pipe);
516 err = usb_submit_urb(urb, GFP_KERNEL);
518 dbg("%s: submit urb %d failed (%d) %d",
519 __FUNCTION__, i, err,
520 urb->transfer_buffer_length);
524 /* Reset low level data toggle on out endpoints */
525 for (i = 0; i < N_OUT_URB; i++) {
526 urb = portdata->out_urbs[i];
529 urb->dev = serial->dev;
530 /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
531 usb_pipeout(urb->pipe), 0); */
534 port->tty->low_latency = 1;
536 option_send_setup(port);
541 static inline void stop_urb(struct urb *urb)
543 if (urb && urb->status == -EINPROGRESS)
547 static void option_close(struct usb_serial_port *port, struct file *filp)
550 struct usb_serial *serial = port->serial;
551 struct option_port_private *portdata;
553 dbg("%s", __FUNCTION__);
554 portdata = usb_get_serial_port_data(port);
556 portdata->rts_state = 0;
557 portdata->dtr_state = 0;
560 option_send_setup(port);
562 /* Stop reading/writing urbs */
563 for (i = 0; i < N_IN_URB; i++)
564 stop_urb(portdata->in_urbs[i]);
565 for (i = 0; i < N_OUT_URB; i++)
566 stop_urb(portdata->out_urbs[i]);
571 /* Helper functions used by option_setup_urbs */
572 static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint,
573 int dir, void *ctx, char *buf, int len,
574 void (*callback)(struct urb *))
579 return NULL; /* endpoint not needed */
581 urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */
583 dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint);
587 /* Fill URB using supplied data. */
588 usb_fill_bulk_urb(urb, serial->dev,
589 usb_sndbulkpipe(serial->dev, endpoint) | dir,
590 buf, len, callback, ctx);
596 static void option_setup_urbs(struct usb_serial *serial)
599 struct usb_serial_port *port;
600 struct option_port_private *portdata;
602 dbg("%s", __FUNCTION__);
604 for (i = 0; i < serial->num_ports; i++) {
605 port = serial->port[i];
606 portdata = usb_get_serial_port_data(port);
608 /* Do indat endpoints first */
609 for (j = 0; j < N_IN_URB; ++j) {
610 portdata->in_urbs[j] = option_setup_urb (serial,
611 port->bulk_in_endpointAddress, USB_DIR_IN, port,
612 portdata->in_buffer[j], IN_BUFLEN, option_indat_callback);
615 /* outdat endpoints */
616 for (j = 0; j < N_OUT_URB; ++j) {
617 portdata->out_urbs[j] = option_setup_urb (serial,
618 port->bulk_out_endpointAddress, USB_DIR_OUT, port,
619 portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback);
624 static int option_send_setup(struct usb_serial_port *port)
626 struct usb_serial *serial = port->serial;
627 struct option_port_private *portdata;
629 dbg("%s", __FUNCTION__);
631 if (port->number != 0)
634 portdata = usb_get_serial_port_data(port);
638 if (portdata->dtr_state)
640 if (portdata->rts_state)
643 return usb_control_msg(serial->dev,
644 usb_rcvctrlpipe(serial->dev, 0),
645 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);
651 static int option_startup(struct usb_serial *serial)
654 struct usb_serial_port *port;
655 struct option_port_private *portdata;
657 dbg("%s", __FUNCTION__);
659 /* Now setup per port private data */
660 for (i = 0; i < serial->num_ports; i++) {
661 port = serial->port[i];
662 portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
664 dbg("%s: kmalloc for option_port_private (%d) failed!.",
669 usb_set_serial_port_data(port, portdata);
671 if (! port->interrupt_in_urb)
673 err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
675 dbg("%s: submit irq_in urb failed %d",
679 option_setup_urbs(serial);
684 static void option_shutdown(struct usb_serial *serial)
687 struct usb_serial_port *port;
688 struct option_port_private *portdata;
690 dbg("%s", __FUNCTION__);
692 /* Stop reading/writing urbs */
693 for (i = 0; i < serial->num_ports; ++i) {
694 port = serial->port[i];
695 portdata = usb_get_serial_port_data(port);
696 for (j = 0; j < N_IN_URB; j++)
697 stop_urb(portdata->in_urbs[j]);
698 for (j = 0; j < N_OUT_URB; j++)
699 stop_urb(portdata->out_urbs[j]);
703 for (i = 0; i < serial->num_ports; ++i) {
704 port = serial->port[i];
705 portdata = usb_get_serial_port_data(port);
707 for (j = 0; j < N_IN_URB; j++) {
708 if (portdata->in_urbs[j]) {
709 usb_free_urb(portdata->in_urbs[j]);
710 portdata->in_urbs[j] = NULL;
713 for (j = 0; j < N_OUT_URB; j++) {
714 if (portdata->out_urbs[j]) {
715 usb_free_urb(portdata->out_urbs[j]);
716 portdata->out_urbs[j] = NULL;
721 /* Now free per port private data */
722 for (i = 0; i < serial->num_ports; i++) {
723 port = serial->port[i];
724 kfree(usb_get_serial_port_data(port));
728 MODULE_AUTHOR(DRIVER_AUTHOR);
729 MODULE_DESCRIPTION(DRIVER_DESC);
730 MODULE_VERSION(DRIVER_VERSION);
731 MODULE_LICENSE("GPL");
733 #ifdef CONFIG_USB_DEBUG
734 module_param(debug, bool, S_IRUGO | S_IWUSR);
735 MODULE_PARM_DESC(debug, "Debug messages");