Commit 7b0c5f21f348a66de495868b8df0284e8dfd6bbf
Committed by
David S. Miller
1 parent
6eecdc5f95
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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>
Showing 1 changed file with 31 additions and 7 deletions Side-by-side Diff
drivers/net/usb/sierra_net.c
... | ... | @@ -426,6 +426,13 @@ |
426 | 426 | |
427 | 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 | 436 | /* tell modem we are ready */ |
430 | 437 | status = sierra_net_send_sync(dev); |
431 | 438 | if (status < 0) |
... | ... | @@ -704,6 +711,9 @@ |
704 | 711 | /* set context index initially to 0 - prepares tx hdr template */ |
705 | 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 | 717 | /* decrease the rx_urb_size and max_tx_size to 4k on USB 1.1 */ |
708 | 718 | dev->rx_urb_size = SIERRA_NET_RX_URB_SIZE; |
709 | 719 | if (dev->udev->speed != USB_SPEED_HIGH) |
710 | 720 | |
... | ... | @@ -739,12 +749,7 @@ |
739 | 749 | kfree(priv); |
740 | 750 | return -ENODEV; |
741 | 751 | } |
742 | - /* prepare sync message from template */ | |
743 | - memcpy(priv->sync_msg, sync_tmplate, sizeof(priv->sync_msg)); | |
744 | 752 | |
745 | - /* initiate the sync sequence */ | |
746 | - sierra_net_dosync(dev); | |
747 | - | |
748 | 753 | return 0; |
749 | 754 | } |
750 | 755 | |
751 | 756 | |
... | ... | @@ -766,8 +771,9 @@ |
766 | 771 | netdev_err(dev->net, |
767 | 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 | 777 | kfree(priv); |
772 | 778 | } |
773 | 779 | |
... | ... | @@ -908,6 +914,24 @@ |
908 | 914 | .tx_fixup = sierra_net_tx_fixup, |
909 | 915 | }; |
910 | 916 | |
917 | +static int | |
918 | +sierra_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 | 935 | #define DIRECT_IP_DEVICE(vend, prod) \ |
912 | 936 | {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 7), \ |
913 | 937 | .driver_info = (unsigned long)&sierra_net_info_direct_ip}, \ |
... | ... | @@ -930,7 +954,7 @@ |
930 | 954 | static struct usb_driver sierra_net_driver = { |
931 | 955 | .name = "sierra_net", |
932 | 956 | .id_table = products, |
933 | - .probe = usbnet_probe, | |
957 | + .probe = sierra_net_probe, | |
934 | 958 | .disconnect = usbnet_disconnect, |
935 | 959 | .suspend = usbnet_suspend, |
936 | 960 | .resume = usbnet_resume, |