aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/usb/usbnet.c33
-rw-r--r--include/linux/usb/usbnet.h2
2 files changed, 20 insertions, 15 deletions
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index dd10d5817d2a..f9e96c427558 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -752,14 +752,12 @@ EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs);
752// precondition: never called in_interrupt 752// precondition: never called in_interrupt
753static void usbnet_terminate_urbs(struct usbnet *dev) 753static void usbnet_terminate_urbs(struct usbnet *dev)
754{ 754{
755 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup);
756 DECLARE_WAITQUEUE(wait, current); 755 DECLARE_WAITQUEUE(wait, current);
757 int temp; 756 int temp;
758 757
759 /* ensure there are no more active urbs */ 758 /* ensure there are no more active urbs */
760 add_wait_queue(&unlink_wakeup, &wait); 759 add_wait_queue(&dev->wait, &wait);
761 set_current_state(TASK_UNINTERRUPTIBLE); 760 set_current_state(TASK_UNINTERRUPTIBLE);
762 dev->wait = &unlink_wakeup;
763 temp = unlink_urbs(dev, &dev->txq) + 761 temp = unlink_urbs(dev, &dev->txq) +
764 unlink_urbs(dev, &dev->rxq); 762 unlink_urbs(dev, &dev->rxq);
765 763
@@ -773,15 +771,14 @@ static void usbnet_terminate_urbs(struct usbnet *dev)
773 "waited for %d urb completions\n", temp); 771 "waited for %d urb completions\n", temp);
774 } 772 }
775 set_current_state(TASK_RUNNING); 773 set_current_state(TASK_RUNNING);
776 dev->wait = NULL; 774 remove_wait_queue(&dev->wait, &wait);
777 remove_wait_queue(&unlink_wakeup, &wait);
778} 775}
779 776
780int usbnet_stop (struct net_device *net) 777int usbnet_stop (struct net_device *net)
781{ 778{
782 struct usbnet *dev = netdev_priv(net); 779 struct usbnet *dev = netdev_priv(net);
783 struct driver_info *info = dev->driver_info; 780 struct driver_info *info = dev->driver_info;
784 int retval; 781 int retval, pm;
785 782
786 clear_bit(EVENT_DEV_OPEN, &dev->flags); 783 clear_bit(EVENT_DEV_OPEN, &dev->flags);
787 netif_stop_queue (net); 784 netif_stop_queue (net);
@@ -791,6 +788,8 @@ int usbnet_stop (struct net_device *net)
791 net->stats.rx_packets, net->stats.tx_packets, 788 net->stats.rx_packets, net->stats.tx_packets,
792 net->stats.rx_errors, net->stats.tx_errors); 789 net->stats.rx_errors, net->stats.tx_errors);
793 790
791 /* to not race resume */
792 pm = usb_autopm_get_interface(dev->intf);
794 /* allow minidriver to stop correctly (wireless devices to turn off 793 /* allow minidriver to stop correctly (wireless devices to turn off
795 * radio etc) */ 794 * radio etc) */
796 if (info->stop) { 795 if (info->stop) {
@@ -817,6 +816,9 @@ int usbnet_stop (struct net_device *net)
817 dev->flags = 0; 816 dev->flags = 0;
818 del_timer_sync (&dev->delay); 817 del_timer_sync (&dev->delay);
819 tasklet_kill (&dev->bh); 818 tasklet_kill (&dev->bh);
819 if (!pm)
820 usb_autopm_put_interface(dev->intf);
821
820 if (info->manage_power && 822 if (info->manage_power &&
821 !test_and_clear_bit(EVENT_NO_RUNTIME_PM, &dev->flags)) 823 !test_and_clear_bit(EVENT_NO_RUNTIME_PM, &dev->flags))
822 info->manage_power(dev, 0); 824 info->manage_power(dev, 0);
@@ -1437,11 +1439,12 @@ static void usbnet_bh (unsigned long param)
1437 /* restart RX again after disabling due to high error rate */ 1439 /* restart RX again after disabling due to high error rate */
1438 clear_bit(EVENT_RX_KILL, &dev->flags); 1440 clear_bit(EVENT_RX_KILL, &dev->flags);
1439 1441
1440 // waiting for all pending urbs to complete? 1442 /* waiting for all pending urbs to complete?
1441 if (dev->wait) { 1443 * only then can we forgo submitting anew
1442 if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) { 1444 */
1443 wake_up (dev->wait); 1445 if (waitqueue_active(&dev->wait)) {
1444 } 1446 if (dev->txq.qlen + dev->rxq.qlen + dev->done.qlen == 0)
1447 wake_up_all(&dev->wait);
1445 1448
1446 // or are we maybe short a few urbs? 1449 // or are we maybe short a few urbs?
1447 } else if (netif_running (dev->net) && 1450 } else if (netif_running (dev->net) &&
@@ -1580,6 +1583,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
1580 dev->driver_name = name; 1583 dev->driver_name = name;
1581 dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV 1584 dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV
1582 | NETIF_MSG_PROBE | NETIF_MSG_LINK); 1585 | NETIF_MSG_PROBE | NETIF_MSG_LINK);
1586 init_waitqueue_head(&dev->wait);
1583 skb_queue_head_init (&dev->rxq); 1587 skb_queue_head_init (&dev->rxq);
1584 skb_queue_head_init (&dev->txq); 1588 skb_queue_head_init (&dev->txq);
1585 skb_queue_head_init (&dev->done); 1589 skb_queue_head_init (&dev->done);
@@ -1791,9 +1795,10 @@ int usbnet_resume (struct usb_interface *intf)
1791 spin_unlock_irq(&dev->txq.lock); 1795 spin_unlock_irq(&dev->txq.lock);
1792 1796
1793 if (test_bit(EVENT_DEV_OPEN, &dev->flags)) { 1797 if (test_bit(EVENT_DEV_OPEN, &dev->flags)) {
1794 /* handle remote wakeup ASAP */ 1798 /* handle remote wakeup ASAP
1795 if (!dev->wait && 1799 * we cannot race against stop
1796 netif_device_present(dev->net) && 1800 */
1801 if (netif_device_present(dev->net) &&
1797 !timer_pending(&dev->delay) && 1802 !timer_pending(&dev->delay) &&
1798 !test_bit(EVENT_RX_HALT, &dev->flags)) 1803 !test_bit(EVENT_RX_HALT, &dev->flags))
1799 rx_alloc_submit(dev, GFP_NOIO); 1804 rx_alloc_submit(dev, GFP_NOIO);
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index e303eef94dd5..0662e98fef72 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -30,7 +30,7 @@ struct usbnet {
30 struct driver_info *driver_info; 30 struct driver_info *driver_info;
31 const char *driver_name; 31 const char *driver_name;
32 void *driver_priv; 32 void *driver_priv;
33 wait_queue_head_t *wait; 33 wait_queue_head_t wait;
34 struct mutex phy_mutex; 34 struct mutex phy_mutex;
35 unsigned char suspend_count; 35 unsigned char suspend_count;
36 unsigned char pkt_cnt, pkt_err; 36 unsigned char pkt_cnt, pkt_err;