diff options
Diffstat (limited to 'drivers/net/usb/hso.c')
-rw-r--r-- | drivers/net/usb/hso.c | 142 |
1 files changed, 94 insertions, 48 deletions
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 43bc3fcc0d85..be0cc99e881a 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -286,6 +286,7 @@ struct hso_device { | |||
286 | u8 usb_gone; | 286 | u8 usb_gone; |
287 | struct work_struct async_get_intf; | 287 | struct work_struct async_get_intf; |
288 | struct work_struct async_put_intf; | 288 | struct work_struct async_put_intf; |
289 | struct work_struct reset_device; | ||
289 | 290 | ||
290 | struct usb_device *usb; | 291 | struct usb_device *usb; |
291 | struct usb_interface *interface; | 292 | struct usb_interface *interface; |
@@ -332,7 +333,8 @@ static void hso_kick_transmit(struct hso_serial *serial); | |||
332 | /* Helper functions */ | 333 | /* Helper functions */ |
333 | static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int, | 334 | static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int, |
334 | struct usb_device *usb, gfp_t gfp); | 335 | struct usb_device *usb, gfp_t gfp); |
335 | static void log_usb_status(int status, const char *function); | 336 | static void handle_usb_error(int status, const char *function, |
337 | struct hso_device *hso_dev); | ||
336 | static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf, | 338 | static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf, |
337 | int type, int dir); | 339 | int type, int dir); |
338 | static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports); | 340 | static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports); |
@@ -350,6 +352,7 @@ static void async_put_intf(struct work_struct *data); | |||
350 | static int hso_put_activity(struct hso_device *hso_dev); | 352 | static int hso_put_activity(struct hso_device *hso_dev); |
351 | static int hso_get_activity(struct hso_device *hso_dev); | 353 | static int hso_get_activity(struct hso_device *hso_dev); |
352 | static void tiocmget_intr_callback(struct urb *urb); | 354 | static void tiocmget_intr_callback(struct urb *urb); |
355 | static void reset_device(struct work_struct *data); | ||
353 | /*****************************************************************************/ | 356 | /*****************************************************************************/ |
354 | /* Helping functions */ | 357 | /* Helping functions */ |
355 | /*****************************************************************************/ | 358 | /*****************************************************************************/ |
@@ -461,10 +464,17 @@ static const struct usb_device_id hso_ids[] = { | |||
461 | {USB_DEVICE(0x0af0, 0x7501)}, /* GTM 382 */ | 464 | {USB_DEVICE(0x0af0, 0x7501)}, /* GTM 382 */ |
462 | {USB_DEVICE(0x0af0, 0x7601)}, /* GE40x */ | 465 | {USB_DEVICE(0x0af0, 0x7601)}, /* GE40x */ |
463 | {USB_DEVICE(0x0af0, 0x7701)}, | 466 | {USB_DEVICE(0x0af0, 0x7701)}, |
467 | {USB_DEVICE(0x0af0, 0x7706)}, | ||
464 | {USB_DEVICE(0x0af0, 0x7801)}, | 468 | {USB_DEVICE(0x0af0, 0x7801)}, |
465 | {USB_DEVICE(0x0af0, 0x7901)}, | 469 | {USB_DEVICE(0x0af0, 0x7901)}, |
470 | {USB_DEVICE(0x0af0, 0x7A01)}, | ||
471 | {USB_DEVICE(0x0af0, 0x7A05)}, | ||
466 | {USB_DEVICE(0x0af0, 0x8200)}, | 472 | {USB_DEVICE(0x0af0, 0x8200)}, |
467 | {USB_DEVICE(0x0af0, 0x8201)}, | 473 | {USB_DEVICE(0x0af0, 0x8201)}, |
474 | {USB_DEVICE(0x0af0, 0x8300)}, | ||
475 | {USB_DEVICE(0x0af0, 0x8302)}, | ||
476 | {USB_DEVICE(0x0af0, 0x8304)}, | ||
477 | {USB_DEVICE(0x0af0, 0x8400)}, | ||
468 | {USB_DEVICE(0x0af0, 0xd035)}, | 478 | {USB_DEVICE(0x0af0, 0xd035)}, |
469 | {USB_DEVICE(0x0af0, 0xd055)}, | 479 | {USB_DEVICE(0x0af0, 0xd055)}, |
470 | {USB_DEVICE(0x0af0, 0xd155)}, | 480 | {USB_DEVICE(0x0af0, 0xd155)}, |
@@ -473,6 +483,8 @@ static const struct usb_device_id hso_ids[] = { | |||
473 | {USB_DEVICE(0x0af0, 0xd157)}, | 483 | {USB_DEVICE(0x0af0, 0xd157)}, |
474 | {USB_DEVICE(0x0af0, 0xd257)}, | 484 | {USB_DEVICE(0x0af0, 0xd257)}, |
475 | {USB_DEVICE(0x0af0, 0xd357)}, | 485 | {USB_DEVICE(0x0af0, 0xd357)}, |
486 | {USB_DEVICE(0x0af0, 0xd058)}, | ||
487 | {USB_DEVICE(0x0af0, 0xc100)}, | ||
476 | {} | 488 | {} |
477 | }; | 489 | }; |
478 | MODULE_DEVICE_TABLE(usb, hso_ids); | 490 | MODULE_DEVICE_TABLE(usb, hso_ids); |
@@ -602,9 +614,9 @@ static struct hso_serial *get_serial_by_shared_int_and_type( | |||
602 | port = hso_mux_to_port(mux); | 614 | port = hso_mux_to_port(mux); |
603 | 615 | ||
604 | for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { | 616 | for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { |
605 | if (serial_table[i] | 617 | if (serial_table[i] && |
606 | && (dev2ser(serial_table[i])->shared_int == shared_int) | 618 | (dev2ser(serial_table[i])->shared_int == shared_int) && |
607 | && ((serial_table[i]->port_spec & HSO_PORT_MASK) == port)) { | 619 | ((serial_table[i]->port_spec & HSO_PORT_MASK) == port)) { |
608 | return dev2ser(serial_table[i]); | 620 | return dev2ser(serial_table[i]); |
609 | } | 621 | } |
610 | } | 622 | } |
@@ -655,8 +667,8 @@ static void set_serial_by_index(unsigned index, struct hso_serial *serial) | |||
655 | spin_unlock_irqrestore(&serial_table_lock, flags); | 667 | spin_unlock_irqrestore(&serial_table_lock, flags); |
656 | } | 668 | } |
657 | 669 | ||
658 | /* log a meaningful explanation of an USB status */ | 670 | static void handle_usb_error(int status, const char *function, |
659 | static void log_usb_status(int status, const char *function) | 671 | struct hso_device *hso_dev) |
660 | { | 672 | { |
661 | char *explanation; | 673 | char *explanation; |
662 | 674 | ||
@@ -685,10 +697,20 @@ static void log_usb_status(int status, const char *function) | |||
685 | case -EMSGSIZE: | 697 | case -EMSGSIZE: |
686 | explanation = "internal error"; | 698 | explanation = "internal error"; |
687 | break; | 699 | break; |
700 | case -EILSEQ: | ||
701 | case -EPROTO: | ||
702 | case -ETIME: | ||
703 | case -ETIMEDOUT: | ||
704 | explanation = "protocol error"; | ||
705 | if (hso_dev) | ||
706 | schedule_work(&hso_dev->reset_device); | ||
707 | break; | ||
688 | default: | 708 | default: |
689 | explanation = "unknown status"; | 709 | explanation = "unknown status"; |
690 | break; | 710 | break; |
691 | } | 711 | } |
712 | |||
713 | /* log a meaningful explanation of an USB status */ | ||
692 | D1("%s: received USB status - %s (%d)", function, explanation, status); | 714 | D1("%s: received USB status - %s (%d)", function, explanation, status); |
693 | } | 715 | } |
694 | 716 | ||
@@ -762,7 +784,7 @@ static void write_bulk_callback(struct urb *urb) | |||
762 | /* log status, but don't act on it, we don't need to resubmit anything | 784 | /* log status, but don't act on it, we don't need to resubmit anything |
763 | * anyhow */ | 785 | * anyhow */ |
764 | if (status) | 786 | if (status) |
765 | log_usb_status(status, __func__); | 787 | handle_usb_error(status, __func__, odev->parent); |
766 | 788 | ||
767 | hso_put_activity(odev->parent); | 789 | hso_put_activity(odev->parent); |
768 | 790 | ||
@@ -806,7 +828,7 @@ static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb, | |||
806 | result = usb_submit_urb(odev->mux_bulk_tx_urb, GFP_ATOMIC); | 828 | result = usb_submit_urb(odev->mux_bulk_tx_urb, GFP_ATOMIC); |
807 | if (result) { | 829 | if (result) { |
808 | dev_warn(&odev->parent->interface->dev, | 830 | dev_warn(&odev->parent->interface->dev, |
809 | "failed mux_bulk_tx_urb %d", result); | 831 | "failed mux_bulk_tx_urb %d\n", result); |
810 | net->stats.tx_errors++; | 832 | net->stats.tx_errors++; |
811 | netif_start_queue(net); | 833 | netif_start_queue(net); |
812 | } else { | 834 | } else { |
@@ -846,8 +868,8 @@ static void hso_net_tx_timeout(struct net_device *net) | |||
846 | dev_warn(&net->dev, "Tx timed out.\n"); | 868 | dev_warn(&net->dev, "Tx timed out.\n"); |
847 | 869 | ||
848 | /* Tear the waiting frame off the list */ | 870 | /* Tear the waiting frame off the list */ |
849 | if (odev->mux_bulk_tx_urb | 871 | if (odev->mux_bulk_tx_urb && |
850 | && (odev->mux_bulk_tx_urb->status == -EINPROGRESS)) | 872 | (odev->mux_bulk_tx_urb->status == -EINPROGRESS)) |
851 | usb_unlink_urb(odev->mux_bulk_tx_urb); | 873 | usb_unlink_urb(odev->mux_bulk_tx_urb); |
852 | 874 | ||
853 | /* Update statistics */ | 875 | /* Update statistics */ |
@@ -998,7 +1020,7 @@ static void read_bulk_callback(struct urb *urb) | |||
998 | 1020 | ||
999 | /* is al ok? (Filip: Who's Al ?) */ | 1021 | /* is al ok? (Filip: Who's Al ?) */ |
1000 | if (status) { | 1022 | if (status) { |
1001 | log_usb_status(status, __func__); | 1023 | handle_usb_error(status, __func__, odev->parent); |
1002 | return; | 1024 | return; |
1003 | } | 1025 | } |
1004 | 1026 | ||
@@ -1019,10 +1041,11 @@ static void read_bulk_callback(struct urb *urb) | |||
1019 | if (odev->parent->port_spec & HSO_INFO_CRC_BUG) { | 1041 | if (odev->parent->port_spec & HSO_INFO_CRC_BUG) { |
1020 | u32 rest; | 1042 | u32 rest; |
1021 | u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; | 1043 | u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; |
1022 | rest = urb->actual_length % odev->in_endp->wMaxPacketSize; | 1044 | rest = urb->actual_length % |
1023 | if (((rest == 5) || (rest == 6)) | 1045 | le16_to_cpu(odev->in_endp->wMaxPacketSize); |
1024 | && !memcmp(((u8 *) urb->transfer_buffer) + | 1046 | if (((rest == 5) || (rest == 6)) && |
1025 | urb->actual_length - 4, crc_check, 4)) { | 1047 | !memcmp(((u8 *) urb->transfer_buffer) + |
1048 | urb->actual_length - 4, crc_check, 4)) { | ||
1026 | urb->actual_length -= 4; | 1049 | urb->actual_length -= 4; |
1027 | } | 1050 | } |
1028 | } | 1051 | } |
@@ -1053,7 +1076,7 @@ static void read_bulk_callback(struct urb *urb) | |||
1053 | result = usb_submit_urb(urb, GFP_ATOMIC); | 1076 | result = usb_submit_urb(urb, GFP_ATOMIC); |
1054 | if (result) | 1077 | if (result) |
1055 | dev_warn(&odev->parent->interface->dev, | 1078 | dev_warn(&odev->parent->interface->dev, |
1056 | "%s failed submit mux_bulk_rx_urb %d", __func__, | 1079 | "%s failed submit mux_bulk_rx_urb %d\n", __func__, |
1057 | result); | 1080 | result); |
1058 | } | 1081 | } |
1059 | 1082 | ||
@@ -1132,9 +1155,6 @@ static void _hso_serial_set_termios(struct tty_struct *tty, | |||
1132 | static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb) | 1155 | static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb) |
1133 | { | 1156 | { |
1134 | int result; | 1157 | int result; |
1135 | #ifdef CONFIG_HSO_AUTOPM | ||
1136 | usb_mark_last_busy(urb->dev); | ||
1137 | #endif | ||
1138 | /* We are done with this URB, resubmit it. Prep the USB to wait for | 1158 | /* We are done with this URB, resubmit it. Prep the USB to wait for |
1139 | * another frame */ | 1159 | * another frame */ |
1140 | usb_fill_bulk_urb(urb, serial->parent->usb, | 1160 | usb_fill_bulk_urb(urb, serial->parent->usb, |
@@ -1207,7 +1227,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) | |||
1207 | D1("serial == NULL"); | 1227 | D1("serial == NULL"); |
1208 | return; | 1228 | return; |
1209 | } else if (status) { | 1229 | } else if (status) { |
1210 | log_usb_status(status, __func__); | 1230 | handle_usb_error(status, __func__, serial->parent); |
1211 | return; | 1231 | return; |
1212 | } | 1232 | } |
1213 | 1233 | ||
@@ -1225,10 +1245,10 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) | |||
1225 | u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; | 1245 | u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; |
1226 | rest = | 1246 | rest = |
1227 | urb->actual_length % | 1247 | urb->actual_length % |
1228 | serial->in_endp->wMaxPacketSize; | 1248 | le16_to_cpu(serial->in_endp->wMaxPacketSize); |
1229 | if (((rest == 5) || (rest == 6)) | 1249 | if (((rest == 5) || (rest == 6)) && |
1230 | && !memcmp(((u8 *) urb->transfer_buffer) + | 1250 | !memcmp(((u8 *) urb->transfer_buffer) + |
1231 | urb->actual_length - 4, crc_check, 4)) { | 1251 | urb->actual_length - 4, crc_check, 4)) { |
1232 | urb->actual_length -= 4; | 1252 | urb->actual_length -= 4; |
1233 | } | 1253 | } |
1234 | } | 1254 | } |
@@ -1513,7 +1533,7 @@ static void tiocmget_intr_callback(struct urb *urb) | |||
1513 | if (!serial) | 1533 | if (!serial) |
1514 | return; | 1534 | return; |
1515 | if (status) { | 1535 | if (status) { |
1516 | log_usb_status(status, __func__); | 1536 | handle_usb_error(status, __func__, serial->parent); |
1517 | return; | 1537 | return; |
1518 | } | 1538 | } |
1519 | tiocmget = serial->tiocmget; | 1539 | tiocmget = serial->tiocmget; |
@@ -1700,6 +1720,10 @@ static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, | |||
1700 | D1("no tty structures"); | 1720 | D1("no tty structures"); |
1701 | return -EINVAL; | 1721 | return -EINVAL; |
1702 | } | 1722 | } |
1723 | |||
1724 | if ((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM) | ||
1725 | return -EINVAL; | ||
1726 | |||
1703 | if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber; | 1727 | if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber; |
1704 | 1728 | ||
1705 | spin_lock_irqsave(&serial->serial_lock, flags); | 1729 | spin_lock_irqsave(&serial->serial_lock, flags); |
@@ -1838,7 +1862,7 @@ static int mux_device_request(struct hso_serial *serial, u8 type, u16 port, | |||
1838 | result = usb_submit_urb(ctrl_urb, GFP_ATOMIC); | 1862 | result = usb_submit_urb(ctrl_urb, GFP_ATOMIC); |
1839 | if (result) { | 1863 | if (result) { |
1840 | dev_err(&ctrl_urb->dev->dev, | 1864 | dev_err(&ctrl_urb->dev->dev, |
1841 | "%s failed submit ctrl_urb %d type %d", __func__, | 1865 | "%s failed submit ctrl_urb %d type %d\n", __func__, |
1842 | result, type); | 1866 | result, type); |
1843 | return result; | 1867 | return result; |
1844 | } | 1868 | } |
@@ -1888,7 +1912,7 @@ static void intr_callback(struct urb *urb) | |||
1888 | 1912 | ||
1889 | /* status check */ | 1913 | /* status check */ |
1890 | if (status) { | 1914 | if (status) { |
1891 | log_usb_status(status, __func__); | 1915 | handle_usb_error(status, __func__, NULL); |
1892 | return; | 1916 | return; |
1893 | } | 1917 | } |
1894 | D4("\n--- Got intr callback 0x%02X ---", status); | 1918 | D4("\n--- Got intr callback 0x%02X ---", status); |
@@ -1905,18 +1929,18 @@ static void intr_callback(struct urb *urb) | |||
1905 | if (serial != NULL) { | 1929 | if (serial != NULL) { |
1906 | D1("Pending read interrupt on port %d\n", i); | 1930 | D1("Pending read interrupt on port %d\n", i); |
1907 | spin_lock(&serial->serial_lock); | 1931 | spin_lock(&serial->serial_lock); |
1908 | if (serial->rx_state == RX_IDLE) { | 1932 | if (serial->rx_state == RX_IDLE && |
1933 | serial->open_count > 0) { | ||
1909 | /* Setup and send a ctrl req read on | 1934 | /* Setup and send a ctrl req read on |
1910 | * port i */ | 1935 | * port i */ |
1911 | if (!serial->rx_urb_filled[0]) { | 1936 | if (!serial->rx_urb_filled[0]) { |
1912 | serial->rx_state = RX_SENT; | 1937 | serial->rx_state = RX_SENT; |
1913 | hso_mux_serial_read(serial); | 1938 | hso_mux_serial_read(serial); |
1914 | } else | 1939 | } else |
1915 | serial->rx_state = RX_PENDING; | 1940 | serial->rx_state = RX_PENDING; |
1916 | |||
1917 | } else { | 1941 | } else { |
1918 | D1("Already pending a read on " | 1942 | D1("Already a read pending on " |
1919 | "port %d\n", i); | 1943 | "port %d or port not open\n", i); |
1920 | } | 1944 | } |
1921 | spin_unlock(&serial->serial_lock); | 1945 | spin_unlock(&serial->serial_lock); |
1922 | } | 1946 | } |
@@ -1958,7 +1982,7 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb) | |||
1958 | tty = tty_kref_get(serial->tty); | 1982 | tty = tty_kref_get(serial->tty); |
1959 | spin_unlock(&serial->serial_lock); | 1983 | spin_unlock(&serial->serial_lock); |
1960 | if (status) { | 1984 | if (status) { |
1961 | log_usb_status(status, __func__); | 1985 | handle_usb_error(status, __func__, serial->parent); |
1962 | tty_kref_put(tty); | 1986 | tty_kref_put(tty); |
1963 | return; | 1987 | return; |
1964 | } | 1988 | } |
@@ -2014,7 +2038,7 @@ static void ctrl_callback(struct urb *urb) | |||
2014 | tty = tty_kref_get(serial->tty); | 2038 | tty = tty_kref_get(serial->tty); |
2015 | spin_unlock(&serial->serial_lock); | 2039 | spin_unlock(&serial->serial_lock); |
2016 | if (status) { | 2040 | if (status) { |
2017 | log_usb_status(status, __func__); | 2041 | handle_usb_error(status, __func__, serial->parent); |
2018 | tty_kref_put(tty); | 2042 | tty_kref_put(tty); |
2019 | return; | 2043 | return; |
2020 | } | 2044 | } |
@@ -2358,12 +2382,12 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, | |||
2358 | serial->tx_data_length = tx_size; | 2382 | serial->tx_data_length = tx_size; |
2359 | serial->tx_data = kzalloc(serial->tx_data_length, GFP_KERNEL); | 2383 | serial->tx_data = kzalloc(serial->tx_data_length, GFP_KERNEL); |
2360 | if (!serial->tx_data) { | 2384 | if (!serial->tx_data) { |
2361 | dev_err(dev, "%s - Out of memory", __func__); | 2385 | dev_err(dev, "%s - Out of memory\n", __func__); |
2362 | goto exit; | 2386 | goto exit; |
2363 | } | 2387 | } |
2364 | serial->tx_buffer = kzalloc(serial->tx_data_length, GFP_KERNEL); | 2388 | serial->tx_buffer = kzalloc(serial->tx_data_length, GFP_KERNEL); |
2365 | if (!serial->tx_buffer) { | 2389 | if (!serial->tx_buffer) { |
2366 | dev_err(dev, "%s - Out of memory", __func__); | 2390 | dev_err(dev, "%s - Out of memory\n", __func__); |
2367 | goto exit; | 2391 | goto exit; |
2368 | } | 2392 | } |
2369 | 2393 | ||
@@ -2391,6 +2415,7 @@ static struct hso_device *hso_create_device(struct usb_interface *intf, | |||
2391 | 2415 | ||
2392 | INIT_WORK(&hso_dev->async_get_intf, async_get_intf); | 2416 | INIT_WORK(&hso_dev->async_get_intf, async_get_intf); |
2393 | INIT_WORK(&hso_dev->async_put_intf, async_put_intf); | 2417 | INIT_WORK(&hso_dev->async_put_intf, async_put_intf); |
2418 | INIT_WORK(&hso_dev->reset_device, reset_device); | ||
2394 | 2419 | ||
2395 | return hso_dev; | 2420 | return hso_dev; |
2396 | } | 2421 | } |
@@ -2831,13 +2856,14 @@ struct hso_shared_int *hso_create_shared_int(struct usb_interface *interface) | |||
2831 | 2856 | ||
2832 | mux->shared_intr_urb = usb_alloc_urb(0, GFP_KERNEL); | 2857 | mux->shared_intr_urb = usb_alloc_urb(0, GFP_KERNEL); |
2833 | if (!mux->shared_intr_urb) { | 2858 | if (!mux->shared_intr_urb) { |
2834 | dev_err(&interface->dev, "Could not allocate intr urb?"); | 2859 | dev_err(&interface->dev, "Could not allocate intr urb?\n"); |
2835 | goto exit; | 2860 | goto exit; |
2836 | } | 2861 | } |
2837 | mux->shared_intr_buf = kzalloc(mux->intr_endp->wMaxPacketSize, | 2862 | mux->shared_intr_buf = |
2838 | GFP_KERNEL); | 2863 | kzalloc(le16_to_cpu(mux->intr_endp->wMaxPacketSize), |
2864 | GFP_KERNEL); | ||
2839 | if (!mux->shared_intr_buf) { | 2865 | if (!mux->shared_intr_buf) { |
2840 | dev_err(&interface->dev, "Could not allocate intr buf?"); | 2866 | dev_err(&interface->dev, "Could not allocate intr buf?\n"); |
2841 | goto exit; | 2867 | goto exit; |
2842 | } | 2868 | } |
2843 | 2869 | ||
@@ -2982,8 +3008,8 @@ static int hso_probe(struct usb_interface *interface, | |||
2982 | 3008 | ||
2983 | case HSO_INTF_BULK: | 3009 | case HSO_INTF_BULK: |
2984 | /* It's a regular bulk interface */ | 3010 | /* It's a regular bulk interface */ |
2985 | if (((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) | 3011 | if (((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) && |
2986 | && !disable_net) | 3012 | !disable_net) |
2987 | hso_dev = hso_create_net_device(interface, port_spec); | 3013 | hso_dev = hso_create_net_device(interface, port_spec); |
2988 | else | 3014 | else |
2989 | hso_dev = | 3015 | hso_dev = |
@@ -3132,6 +3158,26 @@ out: | |||
3132 | return result; | 3158 | return result; |
3133 | } | 3159 | } |
3134 | 3160 | ||
3161 | static void reset_device(struct work_struct *data) | ||
3162 | { | ||
3163 | struct hso_device *hso_dev = | ||
3164 | container_of(data, struct hso_device, reset_device); | ||
3165 | struct usb_device *usb = hso_dev->usb; | ||
3166 | int result; | ||
3167 | |||
3168 | if (hso_dev->usb_gone) { | ||
3169 | D1("No reset during disconnect\n"); | ||
3170 | } else { | ||
3171 | result = usb_lock_device_for_reset(usb, hso_dev->interface); | ||
3172 | if (result < 0) | ||
3173 | D1("unable to lock device for reset: %d\n", result); | ||
3174 | else { | ||
3175 | usb_reset_device(usb); | ||
3176 | usb_unlock_device(usb); | ||
3177 | } | ||
3178 | } | ||
3179 | } | ||
3180 | |||
3135 | static void hso_serial_ref_free(struct kref *ref) | 3181 | static void hso_serial_ref_free(struct kref *ref) |
3136 | { | 3182 | { |
3137 | struct hso_device *hso_dev = container_of(ref, struct hso_device, ref); | 3183 | struct hso_device *hso_dev = container_of(ref, struct hso_device, ref); |
@@ -3146,8 +3192,8 @@ static void hso_free_interface(struct usb_interface *interface) | |||
3146 | int i; | 3192 | int i; |
3147 | 3193 | ||
3148 | for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { | 3194 | for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { |
3149 | if (serial_table[i] | 3195 | if (serial_table[i] && |
3150 | && (serial_table[i]->interface == interface)) { | 3196 | (serial_table[i]->interface == interface)) { |
3151 | hso_dev = dev2ser(serial_table[i]); | 3197 | hso_dev = dev2ser(serial_table[i]); |
3152 | spin_lock_irq(&hso_dev->serial_lock); | 3198 | spin_lock_irq(&hso_dev->serial_lock); |
3153 | tty = tty_kref_get(hso_dev->tty); | 3199 | tty = tty_kref_get(hso_dev->tty); |
@@ -3163,8 +3209,8 @@ static void hso_free_interface(struct usb_interface *interface) | |||
3163 | } | 3209 | } |
3164 | 3210 | ||
3165 | for (i = 0; i < HSO_MAX_NET_DEVICES; i++) { | 3211 | for (i = 0; i < HSO_MAX_NET_DEVICES; i++) { |
3166 | if (network_table[i] | 3212 | if (network_table[i] && |
3167 | && (network_table[i]->interface == interface)) { | 3213 | (network_table[i]->interface == interface)) { |
3168 | struct rfkill *rfk = dev2net(network_table[i])->rfkill; | 3214 | struct rfkill *rfk = dev2net(network_table[i])->rfkill; |
3169 | /* hso_stop_net_device doesn't stop the net queue since | 3215 | /* hso_stop_net_device doesn't stop the net queue since |
3170 | * traffic needs to start it again when suspended */ | 3216 | * traffic needs to start it again when suspended */ |
@@ -3232,13 +3278,13 @@ static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int, | |||
3232 | usb_rcvintpipe(usb, | 3278 | usb_rcvintpipe(usb, |
3233 | shared_int->intr_endp->bEndpointAddress & 0x7F), | 3279 | shared_int->intr_endp->bEndpointAddress & 0x7F), |
3234 | shared_int->shared_intr_buf, | 3280 | shared_int->shared_intr_buf, |
3235 | shared_int->intr_endp->wMaxPacketSize, | 3281 | 1, |
3236 | intr_callback, shared_int, | 3282 | intr_callback, shared_int, |
3237 | shared_int->intr_endp->bInterval); | 3283 | shared_int->intr_endp->bInterval); |
3238 | 3284 | ||
3239 | result = usb_submit_urb(shared_int->shared_intr_urb, gfp); | 3285 | result = usb_submit_urb(shared_int->shared_intr_urb, gfp); |
3240 | if (result) | 3286 | if (result) |
3241 | dev_warn(&usb->dev, "%s failed mux_intr_urb %d", __func__, | 3287 | dev_warn(&usb->dev, "%s failed mux_intr_urb %d\n", __func__, |
3242 | result); | 3288 | result); |
3243 | 3289 | ||
3244 | return result; | 3290 | return result; |