diff options
Diffstat (limited to 'drivers/usb/serial/option.c')
-rw-r--r-- | drivers/usb/serial/option.c | 41 |
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 */ |
46 | static int option_probe(struct usb_serial *serial, | ||
47 | const struct usb_device_id *id); | ||
46 | static int option_open(struct tty_struct *tty, struct usb_serial_port *port, | 48 | static int option_open(struct tty_struct *tty, struct usb_serial_port *port, |
47 | struct file *filp); | 49 | struct file *filp); |
48 | static void option_close(struct usb_serial_port *port); | 50 | static void option_close(struct usb_serial_port *port); |
49 | static void option_dtr_rts(struct usb_serial_port *port, int on); | 51 | static void option_dtr_rts(struct usb_serial_port *port, int on); |
50 | 52 | ||
51 | static int option_startup(struct usb_serial *serial); | 53 | static int option_startup(struct usb_serial *serial); |
52 | static void option_shutdown(struct usb_serial *serial); | 54 | static void option_disconnect(struct usb_serial *serial); |
55 | static void option_release(struct usb_serial *serial); | ||
53 | static int option_write_room(struct tty_struct *tty); | 56 | static int option_write_room(struct tty_struct *tty); |
54 | 57 | ||
55 | static void option_instat_callback(struct urb *urb); | 58 | static 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 | |||
308 | static struct usb_device_id option_ids[] = { | 315 | static 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 | }; |
528 | MODULE_DEVICE_TABLE(usb, option_ids); | 536 | MODULE_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) | |||
626 | module_init(option_init); | 636 | module_init(option_init); |
627 | module_exit(option_exit); | 637 | module_exit(option_exit); |
628 | 638 | ||
639 | static 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 | |||
629 | static void option_set_termios(struct tty_struct *tty, | 651 | static 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 | ||
1132 | static void option_shutdown(struct usb_serial *serial) | 1154 | static void option_disconnect(struct usb_serial *serial) |
1155 | { | ||
1156 | dbg("%s", __func__); | ||
1157 | |||
1158 | stop_read_write_urbs(serial); | ||
1159 | } | ||
1160 | |||
1161 | static 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]; |