diff options
Diffstat (limited to 'drivers/usb/serial/option.c')
-rw-r--r-- | drivers/usb/serial/option.c | 96 |
1 files changed, 47 insertions, 49 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 1aae9028cd0b..e668a2460bd4 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -47,6 +47,7 @@ | |||
47 | /* Function prototypes */ | 47 | /* Function prototypes */ |
48 | static int option_probe(struct usb_serial *serial, | 48 | static int option_probe(struct usb_serial *serial, |
49 | const struct usb_device_id *id); | 49 | const struct usb_device_id *id); |
50 | static void option_release(struct usb_serial *serial); | ||
50 | static int option_send_setup(struct usb_serial_port *port); | 51 | static int option_send_setup(struct usb_serial_port *port); |
51 | static void option_instat_callback(struct urb *urb); | 52 | static void option_instat_callback(struct urb *urb); |
52 | 53 | ||
@@ -150,6 +151,7 @@ static void option_instat_callback(struct urb *urb); | |||
150 | #define HUAWEI_PRODUCT_E14AC 0x14AC | 151 | #define HUAWEI_PRODUCT_E14AC 0x14AC |
151 | #define HUAWEI_PRODUCT_K3806 0x14AE | 152 | #define HUAWEI_PRODUCT_K3806 0x14AE |
152 | #define HUAWEI_PRODUCT_K4605 0x14C6 | 153 | #define HUAWEI_PRODUCT_K4605 0x14C6 |
154 | #define HUAWEI_PRODUCT_K5005 0x14C8 | ||
153 | #define HUAWEI_PRODUCT_K3770 0x14C9 | 155 | #define HUAWEI_PRODUCT_K3770 0x14C9 |
154 | #define HUAWEI_PRODUCT_K3771 0x14CA | 156 | #define HUAWEI_PRODUCT_K3771 0x14CA |
155 | #define HUAWEI_PRODUCT_K4510 0x14CB | 157 | #define HUAWEI_PRODUCT_K4510 0x14CB |
@@ -425,7 +427,7 @@ static void option_instat_callback(struct urb *urb); | |||
425 | #define SAMSUNG_VENDOR_ID 0x04e8 | 427 | #define SAMSUNG_VENDOR_ID 0x04e8 |
426 | #define SAMSUNG_PRODUCT_GT_B3730 0x6889 | 428 | #define SAMSUNG_PRODUCT_GT_B3730 0x6889 |
427 | 429 | ||
428 | /* YUGA products www.yuga-info.com*/ | 430 | /* YUGA products www.yuga-info.com gavin.kx@qq.com */ |
429 | #define YUGA_VENDOR_ID 0x257A | 431 | #define YUGA_VENDOR_ID 0x257A |
430 | #define YUGA_PRODUCT_CEM600 0x1601 | 432 | #define YUGA_PRODUCT_CEM600 0x1601 |
431 | #define YUGA_PRODUCT_CEM610 0x1602 | 433 | #define YUGA_PRODUCT_CEM610 0x1602 |
@@ -442,6 +444,8 @@ static void option_instat_callback(struct urb *urb); | |||
442 | #define YUGA_PRODUCT_CEU516 0x160C | 444 | #define YUGA_PRODUCT_CEU516 0x160C |
443 | #define YUGA_PRODUCT_CEU528 0x160D | 445 | #define YUGA_PRODUCT_CEU528 0x160D |
444 | #define YUGA_PRODUCT_CEU526 0x160F | 446 | #define YUGA_PRODUCT_CEU526 0x160F |
447 | #define YUGA_PRODUCT_CEU881 0x161F | ||
448 | #define YUGA_PRODUCT_CEU882 0x162F | ||
445 | 449 | ||
446 | #define YUGA_PRODUCT_CWM600 0x2601 | 450 | #define YUGA_PRODUCT_CWM600 0x2601 |
447 | #define YUGA_PRODUCT_CWM610 0x2602 | 451 | #define YUGA_PRODUCT_CWM610 0x2602 |
@@ -457,23 +461,26 @@ static void option_instat_callback(struct urb *urb); | |||
457 | #define YUGA_PRODUCT_CWU518 0x260B | 461 | #define YUGA_PRODUCT_CWU518 0x260B |
458 | #define YUGA_PRODUCT_CWU516 0x260C | 462 | #define YUGA_PRODUCT_CWU516 0x260C |
459 | #define YUGA_PRODUCT_CWU528 0x260D | 463 | #define YUGA_PRODUCT_CWU528 0x260D |
464 | #define YUGA_PRODUCT_CWU581 0x260E | ||
460 | #define YUGA_PRODUCT_CWU526 0x260F | 465 | #define YUGA_PRODUCT_CWU526 0x260F |
461 | 466 | #define YUGA_PRODUCT_CWU582 0x261F | |
462 | #define YUGA_PRODUCT_CLM600 0x2601 | 467 | #define YUGA_PRODUCT_CWU583 0x262F |
463 | #define YUGA_PRODUCT_CLM610 0x2602 | 468 | |
464 | #define YUGA_PRODUCT_CLM500 0x2603 | 469 | #define YUGA_PRODUCT_CLM600 0x3601 |
465 | #define YUGA_PRODUCT_CLM510 0x2604 | 470 | #define YUGA_PRODUCT_CLM610 0x3602 |
466 | #define YUGA_PRODUCT_CLM800 0x2605 | 471 | #define YUGA_PRODUCT_CLM500 0x3603 |
467 | #define YUGA_PRODUCT_CLM900 0x2606 | 472 | #define YUGA_PRODUCT_CLM510 0x3604 |
468 | 473 | #define YUGA_PRODUCT_CLM800 0x3605 | |
469 | #define YUGA_PRODUCT_CLU718 0x2607 | 474 | #define YUGA_PRODUCT_CLM900 0x3606 |
470 | #define YUGA_PRODUCT_CLU716 0x2608 | 475 | |
471 | #define YUGA_PRODUCT_CLU728 0x2609 | 476 | #define YUGA_PRODUCT_CLU718 0x3607 |
472 | #define YUGA_PRODUCT_CLU726 0x260A | 477 | #define YUGA_PRODUCT_CLU716 0x3608 |
473 | #define YUGA_PRODUCT_CLU518 0x260B | 478 | #define YUGA_PRODUCT_CLU728 0x3609 |
474 | #define YUGA_PRODUCT_CLU516 0x260C | 479 | #define YUGA_PRODUCT_CLU726 0x360A |
475 | #define YUGA_PRODUCT_CLU528 0x260D | 480 | #define YUGA_PRODUCT_CLU518 0x360B |
476 | #define YUGA_PRODUCT_CLU526 0x260F | 481 | #define YUGA_PRODUCT_CLU516 0x360C |
482 | #define YUGA_PRODUCT_CLU528 0x360D | ||
483 | #define YUGA_PRODUCT_CLU526 0x360F | ||
477 | 484 | ||
478 | /* Viettel products */ | 485 | /* Viettel products */ |
479 | #define VIETTEL_VENDOR_ID 0x2262 | 486 | #define VIETTEL_VENDOR_ID 0x2262 |
@@ -666,6 +673,11 @@ static const struct usb_device_id option_ids[] = { | |||
666 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) }, | 673 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) }, |
667 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), | 674 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), |
668 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, | 675 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, |
676 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x31) }, | ||
677 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x32) }, | ||
678 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x31) }, | ||
679 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x32) }, | ||
680 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x33) }, | ||
669 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) }, | 681 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) }, |
670 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) }, | 682 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) }, |
671 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) }, | 683 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) }, |
@@ -1209,6 +1221,11 @@ static const struct usb_device_id option_ids[] = { | |||
1209 | { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) }, | 1221 | { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) }, |
1210 | { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) }, | 1222 | { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) }, |
1211 | { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) }, | 1223 | { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) }, |
1224 | { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU881) }, | ||
1225 | { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU882) }, | ||
1226 | { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU581) }, | ||
1227 | { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU582) }, | ||
1228 | { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU583) }, | ||
1212 | { USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) }, | 1229 | { USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) }, |
1213 | { USB_DEVICE_AND_INTERFACE_INFO(ZD_VENDOR_ID, ZD_PRODUCT_7000, 0xff, 0xff, 0xff) }, | 1230 | { USB_DEVICE_AND_INTERFACE_INFO(ZD_VENDOR_ID, ZD_PRODUCT_7000, 0xff, 0xff, 0xff) }, |
1214 | { USB_DEVICE(LG_VENDOR_ID, LG_PRODUCT_L02C) }, /* docomo L-02C modem */ | 1231 | { USB_DEVICE(LG_VENDOR_ID, LG_PRODUCT_L02C) }, /* docomo L-02C modem */ |
@@ -1245,7 +1262,7 @@ static struct usb_serial_driver option_1port_device = { | |||
1245 | .ioctl = usb_wwan_ioctl, | 1262 | .ioctl = usb_wwan_ioctl, |
1246 | .attach = usb_wwan_startup, | 1263 | .attach = usb_wwan_startup, |
1247 | .disconnect = usb_wwan_disconnect, | 1264 | .disconnect = usb_wwan_disconnect, |
1248 | .release = usb_wwan_release, | 1265 | .release = option_release, |
1249 | .read_int_callback = option_instat_callback, | 1266 | .read_int_callback = option_instat_callback, |
1250 | #ifdef CONFIG_PM | 1267 | #ifdef CONFIG_PM |
1251 | .suspend = usb_wwan_suspend, | 1268 | .suspend = usb_wwan_suspend, |
@@ -1259,35 +1276,6 @@ static struct usb_serial_driver * const serial_drivers[] = { | |||
1259 | 1276 | ||
1260 | static bool debug; | 1277 | static bool debug; |
1261 | 1278 | ||
1262 | /* per port private data */ | ||
1263 | |||
1264 | #define N_IN_URB 4 | ||
1265 | #define N_OUT_URB 4 | ||
1266 | #define IN_BUFLEN 4096 | ||
1267 | #define OUT_BUFLEN 4096 | ||
1268 | |||
1269 | struct option_port_private { | ||
1270 | /* Input endpoints and buffer for this port */ | ||
1271 | struct urb *in_urbs[N_IN_URB]; | ||
1272 | u8 *in_buffer[N_IN_URB]; | ||
1273 | /* Output endpoints and buffer for this port */ | ||
1274 | struct urb *out_urbs[N_OUT_URB]; | ||
1275 | u8 *out_buffer[N_OUT_URB]; | ||
1276 | unsigned long out_busy; /* Bit vector of URBs in use */ | ||
1277 | int opened; | ||
1278 | struct usb_anchor delayed; | ||
1279 | |||
1280 | /* Settings for the port */ | ||
1281 | int rts_state; /* Handshaking pins (outputs) */ | ||
1282 | int dtr_state; | ||
1283 | int cts_state; /* Handshaking pins (inputs) */ | ||
1284 | int dsr_state; | ||
1285 | int dcd_state; | ||
1286 | int ri_state; | ||
1287 | |||
1288 | unsigned long tx_start_time[N_OUT_URB]; | ||
1289 | }; | ||
1290 | |||
1291 | module_usb_serial_driver(serial_drivers, option_ids); | 1279 | module_usb_serial_driver(serial_drivers, option_ids); |
1292 | 1280 | ||
1293 | static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, | 1281 | static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, |
@@ -1356,12 +1344,22 @@ static int option_probe(struct usb_serial *serial, | |||
1356 | return 0; | 1344 | return 0; |
1357 | } | 1345 | } |
1358 | 1346 | ||
1347 | static void option_release(struct usb_serial *serial) | ||
1348 | { | ||
1349 | struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); | ||
1350 | |||
1351 | usb_wwan_release(serial); | ||
1352 | |||
1353 | kfree(priv); | ||
1354 | } | ||
1355 | |||
1359 | static void option_instat_callback(struct urb *urb) | 1356 | static void option_instat_callback(struct urb *urb) |
1360 | { | 1357 | { |
1361 | int err; | 1358 | int err; |
1362 | int status = urb->status; | 1359 | int status = urb->status; |
1363 | struct usb_serial_port *port = urb->context; | 1360 | struct usb_serial_port *port = urb->context; |
1364 | struct option_port_private *portdata = usb_get_serial_port_data(port); | 1361 | struct usb_wwan_port_private *portdata = |
1362 | usb_get_serial_port_data(port); | ||
1365 | 1363 | ||
1366 | dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata); | 1364 | dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata); |
1367 | 1365 | ||
@@ -1421,7 +1419,7 @@ static int option_send_setup(struct usb_serial_port *port) | |||
1421 | struct usb_serial *serial = port->serial; | 1419 | struct usb_serial *serial = port->serial; |
1422 | struct usb_wwan_intf_private *intfdata = | 1420 | struct usb_wwan_intf_private *intfdata = |
1423 | (struct usb_wwan_intf_private *) serial->private; | 1421 | (struct usb_wwan_intf_private *) serial->private; |
1424 | struct option_port_private *portdata; | 1422 | struct usb_wwan_port_private *portdata; |
1425 | int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; | 1423 | int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; |
1426 | int val = 0; | 1424 | int val = 0; |
1427 | 1425 | ||