aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2013-05-06 07:34:56 -0400
committerDavid S. Miller <davem@davemloft.net>2013-05-08 16:13:29 -0400
commit7b0c5f21f348a66de495868b8df0284e8dfd6bbf (patch)
tree3f76912aa4663581ba2557959f268efaf4508a5a
parent6eecdc5f95a393cb558503123eae9a9a6642e835 (diff)
sierra_net: keep status interrupt URB active
The driver and firmware sync up through SYNC messages, and the firmware's affirmative reply to these SYNC messages appears to be the "Reset" indication received via the status interrupt endpoint. Thus the driver needs the status interrupt endpoint always active so that the Reset indication can be received even if the netdev is closed, which is the case right after device insertion. If the Reset indication is not received by the driver, it continues sending SYNC messages to the firmware, which crashes about 10 seconds later and the device stops responding. Signed-off-by: Dan Williams <dcbw@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/usb/sierra_net.c38
1 files changed, 31 insertions, 7 deletions
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c
index a923d61c6fc5..a79e9d334928 100644
--- a/drivers/net/usb/sierra_net.c
+++ b/drivers/net/usb/sierra_net.c
@@ -426,6 +426,13 @@ static void sierra_net_dosync(struct usbnet *dev)
426 426
427 dev_dbg(&dev->udev->dev, "%s", __func__); 427 dev_dbg(&dev->udev->dev, "%s", __func__);
428 428
429 /* The SIERRA_NET_HIP_MSYNC_ID command appears to request that the
430 * firmware restart itself. After restarting, the modem will respond
431 * with the SIERRA_NET_HIP_RESTART_ID indication. The driver continues
432 * sending MSYNC commands every few seconds until it receives the
433 * RESTART event from the firmware
434 */
435
429 /* tell modem we are ready */ 436 /* tell modem we are ready */
430 status = sierra_net_send_sync(dev); 437 status = sierra_net_send_sync(dev);
431 if (status < 0) 438 if (status < 0)
@@ -704,6 +711,9 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
704 /* set context index initially to 0 - prepares tx hdr template */ 711 /* set context index initially to 0 - prepares tx hdr template */
705 sierra_net_set_ctx_index(priv, 0); 712 sierra_net_set_ctx_index(priv, 0);
706 713
714 /* prepare sync message template */
715 memcpy(priv->sync_msg, sync_tmplate, sizeof(priv->sync_msg));
716
707 /* decrease the rx_urb_size and max_tx_size to 4k on USB 1.1 */ 717 /* decrease the rx_urb_size and max_tx_size to 4k on USB 1.1 */
708 dev->rx_urb_size = SIERRA_NET_RX_URB_SIZE; 718 dev->rx_urb_size = SIERRA_NET_RX_URB_SIZE;
709 if (dev->udev->speed != USB_SPEED_HIGH) 719 if (dev->udev->speed != USB_SPEED_HIGH)
@@ -739,11 +749,6 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
739 kfree(priv); 749 kfree(priv);
740 return -ENODEV; 750 return -ENODEV;
741 } 751 }
742 /* prepare sync message from template */
743 memcpy(priv->sync_msg, sync_tmplate, sizeof(priv->sync_msg));
744
745 /* initiate the sync sequence */
746 sierra_net_dosync(dev);
747 752
748 return 0; 753 return 0;
749} 754}
@@ -766,8 +771,9 @@ static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf)
766 netdev_err(dev->net, 771 netdev_err(dev->net,
767 "usb_control_msg failed, status %d\n", status); 772 "usb_control_msg failed, status %d\n", status);
768 773
769 sierra_net_set_private(dev, NULL); 774 usbnet_status_stop(dev);
770 775
776 sierra_net_set_private(dev, NULL);
771 kfree(priv); 777 kfree(priv);
772} 778}
773 779
@@ -908,6 +914,24 @@ static const struct driver_info sierra_net_info_direct_ip = {
908 .tx_fixup = sierra_net_tx_fixup, 914 .tx_fixup = sierra_net_tx_fixup,
909}; 915};
910 916
917static int
918sierra_net_probe(struct usb_interface *udev, const struct usb_device_id *prod)
919{
920 int ret;
921
922 ret = usbnet_probe(udev, prod);
923 if (ret == 0) {
924 struct usbnet *dev = usb_get_intfdata(udev);
925
926 ret = usbnet_status_start(dev, GFP_KERNEL);
927 if (ret == 0) {
928 /* Interrupt URB now set up; initiate sync sequence */
929 sierra_net_dosync(dev);
930 }
931 }
932 return ret;
933}
934
911#define DIRECT_IP_DEVICE(vend, prod) \ 935#define DIRECT_IP_DEVICE(vend, prod) \
912 {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 7), \ 936 {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 7), \
913 .driver_info = (unsigned long)&sierra_net_info_direct_ip}, \ 937 .driver_info = (unsigned long)&sierra_net_info_direct_ip}, \
@@ -930,7 +954,7 @@ MODULE_DEVICE_TABLE(usb, products);
930static struct usb_driver sierra_net_driver = { 954static struct usb_driver sierra_net_driver = {
931 .name = "sierra_net", 955 .name = "sierra_net",
932 .id_table = products, 956 .id_table = products,
933 .probe = usbnet_probe, 957 .probe = sierra_net_probe,
934 .disconnect = usbnet_disconnect, 958 .disconnect = usbnet_disconnect,
935 .suspend = usbnet_suspend, 959 .suspend = usbnet_suspend,
936 .resume = usbnet_resume, 960 .resume = usbnet_resume,