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.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index a16d69fadba1..575816e6ba37 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -43,13 +43,16 @@
43#include <linux/usb/serial.h> 43#include <linux/usb/serial.h>
44 44
45/* Function prototypes */ 45/* Function prototypes */
46static int option_probe(struct usb_serial *serial,
47 const struct usb_device_id *id);
46static int option_open(struct tty_struct *tty, struct usb_serial_port *port, 48static int option_open(struct tty_struct *tty, struct usb_serial_port *port,
47 struct file *filp); 49 struct file *filp);
48static void option_close(struct usb_serial_port *port); 50static void option_close(struct usb_serial_port *port);
49static void option_dtr_rts(struct usb_serial_port *port, int on); 51static void option_dtr_rts(struct usb_serial_port *port, int on);
50 52
51static int option_startup(struct usb_serial *serial); 53static int option_startup(struct usb_serial *serial);
52static void option_shutdown(struct usb_serial *serial); 54static void option_disconnect(struct usb_serial *serial);
55static void option_release(struct usb_serial *serial);
53static int option_write_room(struct tty_struct *tty); 56static int option_write_room(struct tty_struct *tty);
54 57
55static void option_instat_callback(struct urb *urb); 58static void option_instat_callback(struct urb *urb);
@@ -202,9 +205,9 @@ static int option_resume(struct usb_serial *serial);
202#define NOVATELWIRELESS_PRODUCT_MC727 0x4100 205#define NOVATELWIRELESS_PRODUCT_MC727 0x4100
203#define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 206#define NOVATELWIRELESS_PRODUCT_MC950D 0x4400
204#define NOVATELWIRELESS_PRODUCT_U727 0x5010 207#define NOVATELWIRELESS_PRODUCT_U727 0x5010
208#define NOVATELWIRELESS_PRODUCT_MC760 0x6000
205 209
206/* FUTURE NOVATEL PRODUCTS */ 210/* FUTURE NOVATEL PRODUCTS */
207#define NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED 0X6000
208#define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001 211#define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001
209#define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0X7000 212#define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0X7000
210#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0X7001 213#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0X7001
@@ -305,6 +308,10 @@ static int option_resume(struct usb_serial *serial);
305#define DLINK_PRODUCT_DWM_652 0x3e04 308#define DLINK_PRODUCT_DWM_652 0x3e04
306 309
307 310
311/* TOSHIBA PRODUCTS */
312#define TOSHIBA_VENDOR_ID 0x0930
313#define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302
314
308static struct usb_device_id option_ids[] = { 315static struct usb_device_id option_ids[] = {
309 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, 316 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
310 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, 317 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -422,7 +429,7 @@ static struct usb_device_id option_ids[] = {
422 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ 429 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */
423 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ 430 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */
424 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */ 431 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */
425 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED) }, /* Novatel EVDO product */ 432 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC760) }, /* Novatel MC760/U760/USB760 */
426 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ 433 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */
427 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ 434 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */
428 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */ 435 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */
@@ -523,6 +530,7 @@ static struct usb_device_id option_ids[] = {
523 { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, 530 { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
524 { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, 531 { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
525 { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */ 532 { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */
533 { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */
526 { } /* Terminating entry */ 534 { } /* Terminating entry */
527}; 535};
528MODULE_DEVICE_TABLE(usb, option_ids); 536MODULE_DEVICE_TABLE(usb, option_ids);
@@ -550,6 +558,7 @@ static struct usb_serial_driver option_1port_device = {
550 .usb_driver = &option_driver, 558 .usb_driver = &option_driver,
551 .id_table = option_ids, 559 .id_table = option_ids,
552 .num_ports = 1, 560 .num_ports = 1,
561 .probe = option_probe,
553 .open = option_open, 562 .open = option_open,
554 .close = option_close, 563 .close = option_close,
555 .dtr_rts = option_dtr_rts, 564 .dtr_rts = option_dtr_rts,
@@ -560,7 +569,8 @@ static struct usb_serial_driver option_1port_device = {
560 .tiocmget = option_tiocmget, 569 .tiocmget = option_tiocmget,
561 .tiocmset = option_tiocmset, 570 .tiocmset = option_tiocmset,
562 .attach = option_startup, 571 .attach = option_startup,
563 .shutdown = option_shutdown, 572 .disconnect = option_disconnect,
573 .release = option_release,
564 .read_int_callback = option_instat_callback, 574 .read_int_callback = option_instat_callback,
565 .suspend = option_suspend, 575 .suspend = option_suspend,
566 .resume = option_resume, 576 .resume = option_resume,
@@ -626,6 +636,18 @@ static void __exit option_exit(void)
626module_init(option_init); 636module_init(option_init);
627module_exit(option_exit); 637module_exit(option_exit);
628 638
639static int option_probe(struct usb_serial *serial,
640 const struct usb_device_id *id)
641{
642 /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */
643 if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID &&
644 serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 &&
645 serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8)
646 return -ENODEV;
647
648 return 0;
649}
650
629static void option_set_termios(struct tty_struct *tty, 651static void option_set_termios(struct tty_struct *tty,
630 struct usb_serial_port *port, struct ktermios *old_termios) 652 struct usb_serial_port *port, struct ktermios *old_termios)
631{ 653{
@@ -1129,7 +1151,14 @@ static void stop_read_write_urbs(struct usb_serial *serial)
1129 } 1151 }
1130} 1152}
1131 1153
1132static void option_shutdown(struct usb_serial *serial) 1154static void option_disconnect(struct usb_serial *serial)
1155{
1156 dbg("%s", __func__);
1157
1158 stop_read_write_urbs(serial);
1159}
1160
1161static void option_release(struct usb_serial *serial)
1133{ 1162{
1134 int i, j; 1163 int i, j;
1135 struct usb_serial_port *port; 1164 struct usb_serial_port *port;
@@ -1137,8 +1166,6 @@ static void option_shutdown(struct usb_serial *serial)
1137 1166
1138 dbg("%s", __func__); 1167 dbg("%s", __func__);
1139 1168
1140 stop_read_write_urbs(serial);
1141
1142 /* Now free them */ 1169 /* Now free them */
1143 for (i = 0; i < serial->num_ports; ++i) { 1170 for (i = 0; i < serial->num_ports; ++i) {
1144 port = serial->port[i]; 1171 port = serial->port[i];