diff options
Diffstat (limited to 'drivers/net/usb/usbnet.c')
-rw-r--r-- | drivers/net/usb/usbnet.c | 218 |
1 files changed, 168 insertions, 50 deletions
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index ca5ca5ae061d..035fab04c0a0 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -140,8 +140,8 @@ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf) | |||
140 | if (!alt || !in || !out) | 140 | if (!alt || !in || !out) |
141 | return -EINVAL; | 141 | return -EINVAL; |
142 | 142 | ||
143 | if (alt->desc.bAlternateSetting != 0 | 143 | if (alt->desc.bAlternateSetting != 0 || |
144 | || !(dev->driver_info->flags & FLAG_NO_SETINT)) { | 144 | !(dev->driver_info->flags & FLAG_NO_SETINT)) { |
145 | tmp = usb_set_interface (dev->udev, alt->desc.bInterfaceNumber, | 145 | tmp = usb_set_interface (dev->udev, alt->desc.bInterfaceNumber, |
146 | alt->desc.bAlternateSetting); | 146 | alt->desc.bAlternateSetting); |
147 | if (tmp < 0) | 147 | if (tmp < 0) |
@@ -351,9 +351,10 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) | |||
351 | 351 | ||
352 | spin_lock_irqsave (&dev->rxq.lock, lockflags); | 352 | spin_lock_irqsave (&dev->rxq.lock, lockflags); |
353 | 353 | ||
354 | if (netif_running (dev->net) | 354 | if (netif_running (dev->net) && |
355 | && netif_device_present (dev->net) | 355 | netif_device_present (dev->net) && |
356 | && !test_bit (EVENT_RX_HALT, &dev->flags)) { | 356 | !test_bit (EVENT_RX_HALT, &dev->flags) && |
357 | !test_bit (EVENT_DEV_ASLEEP, &dev->flags)) { | ||
357 | switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) { | 358 | switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) { |
358 | case -EPIPE: | 359 | case -EPIPE: |
359 | usbnet_defer_kevent (dev, EVENT_RX_HALT); | 360 | usbnet_defer_kevent (dev, EVENT_RX_HALT); |
@@ -391,8 +392,8 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) | |||
391 | 392 | ||
392 | static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) | 393 | static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) |
393 | { | 394 | { |
394 | if (dev->driver_info->rx_fixup | 395 | if (dev->driver_info->rx_fixup && |
395 | && !dev->driver_info->rx_fixup (dev, skb)) | 396 | !dev->driver_info->rx_fixup (dev, skb)) |
396 | goto error; | 397 | goto error; |
397 | // else network stack removes extra byte if we forced a short packet | 398 | // else network stack removes extra byte if we forced a short packet |
398 | 399 | ||
@@ -484,8 +485,8 @@ block: | |||
484 | defer_bh(dev, skb, &dev->rxq); | 485 | defer_bh(dev, skb, &dev->rxq); |
485 | 486 | ||
486 | if (urb) { | 487 | if (urb) { |
487 | if (netif_running (dev->net) | 488 | if (netif_running (dev->net) && |
488 | && !test_bit (EVENT_RX_HALT, &dev->flags)) { | 489 | !test_bit (EVENT_RX_HALT, &dev->flags)) { |
489 | rx_submit (dev, urb, GFP_ATOMIC); | 490 | rx_submit (dev, urb, GFP_ATOMIC); |
490 | return; | 491 | return; |
491 | } | 492 | } |
@@ -611,15 +612,39 @@ EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs); | |||
611 | /*-------------------------------------------------------------------------*/ | 612 | /*-------------------------------------------------------------------------*/ |
612 | 613 | ||
613 | // precondition: never called in_interrupt | 614 | // precondition: never called in_interrupt |
615 | static void usbnet_terminate_urbs(struct usbnet *dev) | ||
616 | { | ||
617 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup); | ||
618 | DECLARE_WAITQUEUE(wait, current); | ||
619 | int temp; | ||
620 | |||
621 | /* ensure there are no more active urbs */ | ||
622 | add_wait_queue(&unlink_wakeup, &wait); | ||
623 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
624 | dev->wait = &unlink_wakeup; | ||
625 | temp = unlink_urbs(dev, &dev->txq) + | ||
626 | unlink_urbs(dev, &dev->rxq); | ||
627 | |||
628 | /* maybe wait for deletions to finish. */ | ||
629 | while (!skb_queue_empty(&dev->rxq) | ||
630 | && !skb_queue_empty(&dev->txq) | ||
631 | && !skb_queue_empty(&dev->done)) { | ||
632 | schedule_timeout(UNLINK_TIMEOUT_MS); | ||
633 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
634 | if (netif_msg_ifdown(dev)) | ||
635 | devdbg(dev, "waited for %d urb completions", | ||
636 | temp); | ||
637 | } | ||
638 | set_current_state(TASK_RUNNING); | ||
639 | dev->wait = NULL; | ||
640 | remove_wait_queue(&unlink_wakeup, &wait); | ||
641 | } | ||
614 | 642 | ||
615 | int usbnet_stop (struct net_device *net) | 643 | int usbnet_stop (struct net_device *net) |
616 | { | 644 | { |
617 | struct usbnet *dev = netdev_priv(net); | 645 | struct usbnet *dev = netdev_priv(net); |
618 | struct driver_info *info = dev->driver_info; | 646 | struct driver_info *info = dev->driver_info; |
619 | int temp; | ||
620 | int retval; | 647 | int retval; |
621 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK (unlink_wakeup); | ||
622 | DECLARE_WAITQUEUE (wait, current); | ||
623 | 648 | ||
624 | netif_stop_queue (net); | 649 | netif_stop_queue (net); |
625 | 650 | ||
@@ -641,25 +666,8 @@ int usbnet_stop (struct net_device *net) | |||
641 | info->description); | 666 | info->description); |
642 | } | 667 | } |
643 | 668 | ||
644 | if (!(info->flags & FLAG_AVOID_UNLINK_URBS)) { | 669 | if (!(info->flags & FLAG_AVOID_UNLINK_URBS)) |
645 | /* ensure there are no more active urbs */ | 670 | usbnet_terminate_urbs(dev); |
646 | add_wait_queue(&unlink_wakeup, &wait); | ||
647 | dev->wait = &unlink_wakeup; | ||
648 | temp = unlink_urbs(dev, &dev->txq) + | ||
649 | unlink_urbs(dev, &dev->rxq); | ||
650 | |||
651 | /* maybe wait for deletions to finish. */ | ||
652 | while (!skb_queue_empty(&dev->rxq) | ||
653 | && !skb_queue_empty(&dev->txq) | ||
654 | && !skb_queue_empty(&dev->done)) { | ||
655 | msleep(UNLINK_TIMEOUT_MS); | ||
656 | if (netif_msg_ifdown(dev)) | ||
657 | devdbg(dev, "waited for %d urb completions", | ||
658 | temp); | ||
659 | } | ||
660 | dev->wait = NULL; | ||
661 | remove_wait_queue(&unlink_wakeup, &wait); | ||
662 | } | ||
663 | 671 | ||
664 | usb_kill_urb(dev->interrupt); | 672 | usb_kill_urb(dev->interrupt); |
665 | 673 | ||
@@ -672,7 +680,10 @@ int usbnet_stop (struct net_device *net) | |||
672 | dev->flags = 0; | 680 | dev->flags = 0; |
673 | del_timer_sync (&dev->delay); | 681 | del_timer_sync (&dev->delay); |
674 | tasklet_kill (&dev->bh); | 682 | tasklet_kill (&dev->bh); |
675 | usb_autopm_put_interface(dev->intf); | 683 | if (info->manage_power) |
684 | info->manage_power(dev, 0); | ||
685 | else | ||
686 | usb_autopm_put_interface(dev->intf); | ||
676 | 687 | ||
677 | return 0; | 688 | return 0; |
678 | } | 689 | } |
@@ -753,6 +764,12 @@ int usbnet_open (struct net_device *net) | |||
753 | 764 | ||
754 | // delay posting reads until we're fully open | 765 | // delay posting reads until we're fully open |
755 | tasklet_schedule (&dev->bh); | 766 | tasklet_schedule (&dev->bh); |
767 | if (info->manage_power) { | ||
768 | retval = info->manage_power(dev, 1); | ||
769 | if (retval < 0) | ||
770 | goto done; | ||
771 | usb_autopm_put_interface(dev->intf); | ||
772 | } | ||
756 | return retval; | 773 | return retval; |
757 | done: | 774 | done: |
758 | usb_autopm_put_interface(dev->intf); | 775 | usb_autopm_put_interface(dev->intf); |
@@ -881,11 +898,16 @@ kevent (struct work_struct *work) | |||
881 | /* usb_clear_halt() needs a thread context */ | 898 | /* usb_clear_halt() needs a thread context */ |
882 | if (test_bit (EVENT_TX_HALT, &dev->flags)) { | 899 | if (test_bit (EVENT_TX_HALT, &dev->flags)) { |
883 | unlink_urbs (dev, &dev->txq); | 900 | unlink_urbs (dev, &dev->txq); |
901 | status = usb_autopm_get_interface(dev->intf); | ||
902 | if (status < 0) | ||
903 | goto fail_pipe; | ||
884 | status = usb_clear_halt (dev->udev, dev->out); | 904 | status = usb_clear_halt (dev->udev, dev->out); |
885 | if (status < 0 | 905 | usb_autopm_put_interface(dev->intf); |
886 | && status != -EPIPE | 906 | if (status < 0 && |
887 | && status != -ESHUTDOWN) { | 907 | status != -EPIPE && |
908 | status != -ESHUTDOWN) { | ||
888 | if (netif_msg_tx_err (dev)) | 909 | if (netif_msg_tx_err (dev)) |
910 | fail_pipe: | ||
889 | deverr (dev, "can't clear tx halt, status %d", | 911 | deverr (dev, "can't clear tx halt, status %d", |
890 | status); | 912 | status); |
891 | } else { | 913 | } else { |
@@ -896,11 +918,16 @@ kevent (struct work_struct *work) | |||
896 | } | 918 | } |
897 | if (test_bit (EVENT_RX_HALT, &dev->flags)) { | 919 | if (test_bit (EVENT_RX_HALT, &dev->flags)) { |
898 | unlink_urbs (dev, &dev->rxq); | 920 | unlink_urbs (dev, &dev->rxq); |
921 | status = usb_autopm_get_interface(dev->intf); | ||
922 | if (status < 0) | ||
923 | goto fail_halt; | ||
899 | status = usb_clear_halt (dev->udev, dev->in); | 924 | status = usb_clear_halt (dev->udev, dev->in); |
900 | if (status < 0 | 925 | usb_autopm_put_interface(dev->intf); |
901 | && status != -EPIPE | 926 | if (status < 0 && |
902 | && status != -ESHUTDOWN) { | 927 | status != -EPIPE && |
928 | status != -ESHUTDOWN) { | ||
903 | if (netif_msg_rx_err (dev)) | 929 | if (netif_msg_rx_err (dev)) |
930 | fail_halt: | ||
904 | deverr (dev, "can't clear rx halt, status %d", | 931 | deverr (dev, "can't clear rx halt, status %d", |
905 | status); | 932 | status); |
906 | } else { | 933 | } else { |
@@ -919,7 +946,12 @@ kevent (struct work_struct *work) | |||
919 | clear_bit (EVENT_RX_MEMORY, &dev->flags); | 946 | clear_bit (EVENT_RX_MEMORY, &dev->flags); |
920 | if (urb != NULL) { | 947 | if (urb != NULL) { |
921 | clear_bit (EVENT_RX_MEMORY, &dev->flags); | 948 | clear_bit (EVENT_RX_MEMORY, &dev->flags); |
949 | status = usb_autopm_get_interface(dev->intf); | ||
950 | if (status < 0) | ||
951 | goto fail_lowmem; | ||
922 | rx_submit (dev, urb, GFP_KERNEL); | 952 | rx_submit (dev, urb, GFP_KERNEL); |
953 | usb_autopm_put_interface(dev->intf); | ||
954 | fail_lowmem: | ||
923 | tasklet_schedule (&dev->bh); | 955 | tasklet_schedule (&dev->bh); |
924 | } | 956 | } |
925 | } | 957 | } |
@@ -929,11 +961,18 @@ kevent (struct work_struct *work) | |||
929 | int retval = 0; | 961 | int retval = 0; |
930 | 962 | ||
931 | clear_bit (EVENT_LINK_RESET, &dev->flags); | 963 | clear_bit (EVENT_LINK_RESET, &dev->flags); |
964 | status = usb_autopm_get_interface(dev->intf); | ||
965 | if (status < 0) | ||
966 | goto skip_reset; | ||
932 | if(info->link_reset && (retval = info->link_reset(dev)) < 0) { | 967 | if(info->link_reset && (retval = info->link_reset(dev)) < 0) { |
968 | usb_autopm_put_interface(dev->intf); | ||
969 | skip_reset: | ||
933 | devinfo(dev, "link reset failed (%d) usbnet usb-%s-%s, %s", | 970 | devinfo(dev, "link reset failed (%d) usbnet usb-%s-%s, %s", |
934 | retval, | 971 | retval, |
935 | dev->udev->bus->bus_name, dev->udev->devpath, | 972 | dev->udev->bus->bus_name, dev->udev->devpath, |
936 | info->description); | 973 | info->description); |
974 | } else { | ||
975 | usb_autopm_put_interface(dev->intf); | ||
937 | } | 976 | } |
938 | } | 977 | } |
939 | 978 | ||
@@ -971,6 +1010,7 @@ static void tx_complete (struct urb *urb) | |||
971 | case -EPROTO: | 1010 | case -EPROTO: |
972 | case -ETIME: | 1011 | case -ETIME: |
973 | case -EILSEQ: | 1012 | case -EILSEQ: |
1013 | usb_mark_last_busy(dev->udev); | ||
974 | if (!timer_pending (&dev->delay)) { | 1014 | if (!timer_pending (&dev->delay)) { |
975 | mod_timer (&dev->delay, | 1015 | mod_timer (&dev->delay, |
976 | jiffies + THROTTLE_JIFFIES); | 1016 | jiffies + THROTTLE_JIFFIES); |
@@ -987,6 +1027,7 @@ static void tx_complete (struct urb *urb) | |||
987 | } | 1027 | } |
988 | } | 1028 | } |
989 | 1029 | ||
1030 | usb_autopm_put_interface_async(dev->intf); | ||
990 | urb->dev = NULL; | 1031 | urb->dev = NULL; |
991 | entry->state = tx_done; | 1032 | entry->state = tx_done; |
992 | defer_bh(dev, skb, &dev->txq); | 1033 | defer_bh(dev, skb, &dev->txq); |
@@ -1057,14 +1098,34 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, | |||
1057 | } | 1098 | } |
1058 | } | 1099 | } |
1059 | 1100 | ||
1060 | spin_lock_irqsave (&dev->txq.lock, flags); | 1101 | spin_lock_irqsave(&dev->txq.lock, flags); |
1102 | retval = usb_autopm_get_interface_async(dev->intf); | ||
1103 | if (retval < 0) { | ||
1104 | spin_unlock_irqrestore(&dev->txq.lock, flags); | ||
1105 | goto drop; | ||
1106 | } | ||
1107 | |||
1108 | #ifdef CONFIG_PM | ||
1109 | /* if this triggers the device is still a sleep */ | ||
1110 | if (test_bit(EVENT_DEV_ASLEEP, &dev->flags)) { | ||
1111 | /* transmission will be done in resume */ | ||
1112 | usb_anchor_urb(urb, &dev->deferred); | ||
1113 | /* no use to process more packets */ | ||
1114 | netif_stop_queue(net); | ||
1115 | spin_unlock_irqrestore(&dev->txq.lock, flags); | ||
1116 | devdbg(dev, "Delaying transmission for resumption"); | ||
1117 | goto deferred; | ||
1118 | } | ||
1119 | #endif | ||
1061 | 1120 | ||
1062 | switch ((retval = usb_submit_urb (urb, GFP_ATOMIC))) { | 1121 | switch ((retval = usb_submit_urb (urb, GFP_ATOMIC))) { |
1063 | case -EPIPE: | 1122 | case -EPIPE: |
1064 | netif_stop_queue (net); | 1123 | netif_stop_queue (net); |
1065 | usbnet_defer_kevent (dev, EVENT_TX_HALT); | 1124 | usbnet_defer_kevent (dev, EVENT_TX_HALT); |
1125 | usb_autopm_put_interface_async(dev->intf); | ||
1066 | break; | 1126 | break; |
1067 | default: | 1127 | default: |
1128 | usb_autopm_put_interface_async(dev->intf); | ||
1068 | if (netif_msg_tx_err (dev)) | 1129 | if (netif_msg_tx_err (dev)) |
1069 | devdbg (dev, "tx: submit urb err %d", retval); | 1130 | devdbg (dev, "tx: submit urb err %d", retval); |
1070 | break; | 1131 | break; |
@@ -1088,6 +1149,9 @@ drop: | |||
1088 | devdbg (dev, "> tx, len %d, type 0x%x", | 1149 | devdbg (dev, "> tx, len %d, type 0x%x", |
1089 | length, skb->protocol); | 1150 | length, skb->protocol); |
1090 | } | 1151 | } |
1152 | #ifdef CONFIG_PM | ||
1153 | deferred: | ||
1154 | #endif | ||
1091 | return NETDEV_TX_OK; | 1155 | return NETDEV_TX_OK; |
1092 | } | 1156 | } |
1093 | EXPORT_SYMBOL_GPL(usbnet_start_xmit); | 1157 | EXPORT_SYMBOL_GPL(usbnet_start_xmit); |
@@ -1126,10 +1190,10 @@ static void usbnet_bh (unsigned long param) | |||
1126 | } | 1190 | } |
1127 | 1191 | ||
1128 | // or are we maybe short a few urbs? | 1192 | // or are we maybe short a few urbs? |
1129 | } else if (netif_running (dev->net) | 1193 | } else if (netif_running (dev->net) && |
1130 | && netif_device_present (dev->net) | 1194 | netif_device_present (dev->net) && |
1131 | && !timer_pending (&dev->delay) | 1195 | !timer_pending (&dev->delay) && |
1132 | && !test_bit (EVENT_RX_HALT, &dev->flags)) { | 1196 | !test_bit (EVENT_RX_HALT, &dev->flags)) { |
1133 | int temp = dev->rxq.qlen; | 1197 | int temp = dev->rxq.qlen; |
1134 | int qlen = RX_QLEN (dev); | 1198 | int qlen = RX_QLEN (dev); |
1135 | 1199 | ||
@@ -1210,6 +1274,14 @@ static const struct net_device_ops usbnet_netdev_ops = { | |||
1210 | 1274 | ||
1211 | // precondition: never called in_interrupt | 1275 | // precondition: never called in_interrupt |
1212 | 1276 | ||
1277 | static struct device_type wlan_type = { | ||
1278 | .name = "wlan", | ||
1279 | }; | ||
1280 | |||
1281 | static struct device_type wwan_type = { | ||
1282 | .name = "wwan", | ||
1283 | }; | ||
1284 | |||
1213 | int | 1285 | int |
1214 | usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | 1286 | usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) |
1215 | { | 1287 | { |
@@ -1255,6 +1327,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
1255 | dev->bh.func = usbnet_bh; | 1327 | dev->bh.func = usbnet_bh; |
1256 | dev->bh.data = (unsigned long) dev; | 1328 | dev->bh.data = (unsigned long) dev; |
1257 | INIT_WORK (&dev->kevent, kevent); | 1329 | INIT_WORK (&dev->kevent, kevent); |
1330 | init_usb_anchor(&dev->deferred); | ||
1258 | dev->delay.function = usbnet_bh; | 1331 | dev->delay.function = usbnet_bh; |
1259 | dev->delay.data = (unsigned long) dev; | 1332 | dev->delay.data = (unsigned long) dev; |
1260 | init_timer (&dev->delay); | 1333 | init_timer (&dev->delay); |
@@ -1289,12 +1362,15 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
1289 | // heuristic: "usb%d" for links we know are two-host, | 1362 | // heuristic: "usb%d" for links we know are two-host, |
1290 | // else "eth%d" when there's reasonable doubt. userspace | 1363 | // else "eth%d" when there's reasonable doubt. userspace |
1291 | // can rename the link if it knows better. | 1364 | // can rename the link if it knows better. |
1292 | if ((dev->driver_info->flags & FLAG_ETHER) != 0 | 1365 | if ((dev->driver_info->flags & FLAG_ETHER) != 0 && |
1293 | && (net->dev_addr [0] & 0x02) == 0) | 1366 | (net->dev_addr [0] & 0x02) == 0) |
1294 | strcpy (net->name, "eth%d"); | 1367 | strcpy (net->name, "eth%d"); |
1295 | /* WLAN devices should always be named "wlan%d" */ | 1368 | /* WLAN devices should always be named "wlan%d" */ |
1296 | if ((dev->driver_info->flags & FLAG_WLAN) != 0) | 1369 | if ((dev->driver_info->flags & FLAG_WLAN) != 0) |
1297 | strcpy(net->name, "wlan%d"); | 1370 | strcpy(net->name, "wlan%d"); |
1371 | /* WWAN devices should always be named "wwan%d" */ | ||
1372 | if ((dev->driver_info->flags & FLAG_WWAN) != 0) | ||
1373 | strcpy(net->name, "wwan%d"); | ||
1298 | 1374 | ||
1299 | /* maybe the remote can't receive an Ethernet MTU */ | 1375 | /* maybe the remote can't receive an Ethernet MTU */ |
1300 | if (net->mtu > (dev->hard_mtu - net->hard_header_len)) | 1376 | if (net->mtu > (dev->hard_mtu - net->hard_header_len)) |
@@ -1322,6 +1398,12 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
1322 | dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); | 1398 | dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); |
1323 | 1399 | ||
1324 | SET_NETDEV_DEV(net, &udev->dev); | 1400 | SET_NETDEV_DEV(net, &udev->dev); |
1401 | |||
1402 | if ((dev->driver_info->flags & FLAG_WLAN) != 0) | ||
1403 | SET_NETDEV_DEVTYPE(net, &wlan_type); | ||
1404 | if ((dev->driver_info->flags & FLAG_WWAN) != 0) | ||
1405 | SET_NETDEV_DEVTYPE(net, &wwan_type); | ||
1406 | |||
1325 | status = register_netdev (net); | 1407 | status = register_netdev (net); |
1326 | if (status) | 1408 | if (status) |
1327 | goto out3; | 1409 | goto out3; |
@@ -1335,9 +1417,11 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
1335 | // ok, it's ready to go. | 1417 | // ok, it's ready to go. |
1336 | usb_set_intfdata (udev, dev); | 1418 | usb_set_intfdata (udev, dev); |
1337 | 1419 | ||
1338 | // start as if the link is up | ||
1339 | netif_device_attach (net); | 1420 | netif_device_attach (net); |
1340 | 1421 | ||
1422 | if (dev->driver_info->flags & FLAG_LINK_INTR) | ||
1423 | netif_carrier_off(net); | ||
1424 | |||
1341 | return 0; | 1425 | return 0; |
1342 | 1426 | ||
1343 | out3: | 1427 | out3: |
@@ -1363,13 +1447,23 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message) | |||
1363 | struct usbnet *dev = usb_get_intfdata(intf); | 1447 | struct usbnet *dev = usb_get_intfdata(intf); |
1364 | 1448 | ||
1365 | if (!dev->suspend_count++) { | 1449 | if (!dev->suspend_count++) { |
1450 | spin_lock_irq(&dev->txq.lock); | ||
1451 | /* don't autosuspend while transmitting */ | ||
1452 | if (dev->txq.qlen && (message.event & PM_EVENT_AUTO)) { | ||
1453 | spin_unlock_irq(&dev->txq.lock); | ||
1454 | return -EBUSY; | ||
1455 | } else { | ||
1456 | set_bit(EVENT_DEV_ASLEEP, &dev->flags); | ||
1457 | spin_unlock_irq(&dev->txq.lock); | ||
1458 | } | ||
1366 | /* | 1459 | /* |
1367 | * accelerate emptying of the rx and queues, to avoid | 1460 | * accelerate emptying of the rx and queues, to avoid |
1368 | * having everything error out. | 1461 | * having everything error out. |
1369 | */ | 1462 | */ |
1370 | netif_device_detach (dev->net); | 1463 | netif_device_detach (dev->net); |
1371 | (void) unlink_urbs (dev, &dev->rxq); | 1464 | usbnet_terminate_urbs(dev); |
1372 | (void) unlink_urbs (dev, &dev->txq); | 1465 | usb_kill_urb(dev->interrupt); |
1466 | |||
1373 | /* | 1467 | /* |
1374 | * reattach so runtime management can use and | 1468 | * reattach so runtime management can use and |
1375 | * wake the device | 1469 | * wake the device |
@@ -1383,10 +1477,34 @@ EXPORT_SYMBOL_GPL(usbnet_suspend); | |||
1383 | int usbnet_resume (struct usb_interface *intf) | 1477 | int usbnet_resume (struct usb_interface *intf) |
1384 | { | 1478 | { |
1385 | struct usbnet *dev = usb_get_intfdata(intf); | 1479 | struct usbnet *dev = usb_get_intfdata(intf); |
1480 | struct sk_buff *skb; | ||
1481 | struct urb *res; | ||
1482 | int retval; | ||
1483 | |||
1484 | if (!--dev->suspend_count) { | ||
1485 | spin_lock_irq(&dev->txq.lock); | ||
1486 | while ((res = usb_get_from_anchor(&dev->deferred))) { | ||
1487 | |||
1488 | printk(KERN_INFO"%s has delayed data\n", __func__); | ||
1489 | skb = (struct sk_buff *)res->context; | ||
1490 | retval = usb_submit_urb(res, GFP_ATOMIC); | ||
1491 | if (retval < 0) { | ||
1492 | dev_kfree_skb_any(skb); | ||
1493 | usb_free_urb(res); | ||
1494 | usb_autopm_put_interface_async(dev->intf); | ||
1495 | } else { | ||
1496 | dev->net->trans_start = jiffies; | ||
1497 | __skb_queue_tail(&dev->txq, skb); | ||
1498 | } | ||
1499 | } | ||
1386 | 1500 | ||
1387 | if (!--dev->suspend_count) | 1501 | smp_mb(); |
1502 | clear_bit(EVENT_DEV_ASLEEP, &dev->flags); | ||
1503 | spin_unlock_irq(&dev->txq.lock); | ||
1504 | if (!(dev->txq.qlen >= TX_QLEN(dev))) | ||
1505 | netif_start_queue(dev->net); | ||
1388 | tasklet_schedule (&dev->bh); | 1506 | tasklet_schedule (&dev->bh); |
1389 | 1507 | } | |
1390 | return 0; | 1508 | return 0; |
1391 | } | 1509 | } |
1392 | EXPORT_SYMBOL_GPL(usbnet_resume); | 1510 | EXPORT_SYMBOL_GPL(usbnet_resume); |