Loading drivers/net/usb/usbnet.c +33 −16 Original line number Diff line number Diff line Loading @@ -89,7 +89,8 @@ static u8 node_id [ETH_ALEN]; static const char driver_name [] = "usbnet"; struct workqueue_struct *usbnet_wq; static struct workqueue_struct *usbnet_wq; /* use ethtool to change the level for any given device */ static int msg_level = -1; module_param (msg_level, int, 0); Loading Loading @@ -403,7 +404,7 @@ unlock_and_schedule: if (skb_defer_rx_timestamp(skb)) return; status = netif_rx (skb); status = netif_rx_ni(skb); if (status != NET_RX_SUCCESS) netif_dbg(dev, rx_err, dev->net, "netif_rx status %d\n", status); Loading Loading @@ -500,7 +501,7 @@ static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb, spin_lock(&dev->done.lock); __skb_queue_tail(&dev->done, skb); if (dev->done.qlen == 1) tasklet_schedule(&dev->bh); queue_work(usbnet_wq, &dev->bh_w); spin_unlock_irqrestore(&dev->done.lock, flags); return old_state; } Loading Loading @@ -579,7 +580,7 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) default: netif_dbg(dev, rx_err, dev->net, "rx submit, %d\n", retval); tasklet_schedule (&dev->bh); queue_work(usbnet_wq, &dev->bh_w); break; case 0: __usbnet_queue_skb(&dev->rxq, skb, rx_start); Loading Loading @@ -745,7 +746,7 @@ void usbnet_resume_rx(struct usbnet *dev) num++; } tasklet_schedule(&dev->bh); queue_work(usbnet_wq, &dev->bh_w); netif_dbg(dev, rx_status, dev->net, "paused rx queue disabled, %d skbs requeued\n", num); Loading Loading @@ -814,7 +815,7 @@ void usbnet_unlink_rx_urbs(struct usbnet *dev) { if (netif_running(dev->net)) { (void) unlink_urbs (dev, &dev->rxq); tasklet_schedule(&dev->bh); queue_work(usbnet_wq, &dev->bh_w); } } EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs); Loading Loading @@ -887,7 +888,7 @@ int usbnet_stop (struct net_device *net) */ dev->flags = 0; del_timer_sync (&dev->delay); tasklet_kill (&dev->bh); cancel_work_sync(&dev->bh_w); if (!pm) usb_autopm_put_interface(dev->intf); Loading Loading @@ -972,7 +973,7 @@ int usbnet_open (struct net_device *net) clear_bit(EVENT_RX_KILL, &dev->flags); // delay posting reads until we're fully open tasklet_schedule (&dev->bh); queue_work(usbnet_wq, &dev->bh_w); if (info->manage_power) { retval = info->manage_power(dev, 1); if (retval < 0) { Loading Loading @@ -1114,7 +1115,7 @@ static void __handle_link_change(struct usbnet *dev) */ } else { /* submitting URBs for reading packets */ tasklet_schedule(&dev->bh); queue_work(usbnet_wq, &dev->bh_w); } /* hard_mtu or rx_urb_size may change during link change */ Loading Loading @@ -1187,7 +1188,7 @@ fail_halt: status); } else { clear_bit (EVENT_RX_HALT, &dev->flags); tasklet_schedule (&dev->bh); queue_work(usbnet_wq, &dev->bh_w); } } Loading @@ -1212,7 +1213,7 @@ fail_halt: usb_autopm_put_interface(dev->intf); fail_lowmem: if (resched) tasklet_schedule (&dev->bh); queue_work(usbnet_wq, &dev->bh_w); } } Loading Loading @@ -1308,13 +1309,14 @@ void usbnet_tx_timeout (struct net_device *net) struct usbnet *dev = netdev_priv(net); unlink_urbs (dev, &dev->txq); tasklet_schedule (&dev->bh); queue_work(usbnet_wq, &dev->bh_w); /* this needs to be handled individually because the generic layer * doesn't know what is sufficient and could not restore private * information if a remedy of an unconditional reset were used. */ if (dev->driver_info->recover) (dev->driver_info->recover)(dev); } EXPORT_SYMBOL_GPL(usbnet_tx_timeout); Loading Loading @@ -1572,13 +1574,21 @@ static void usbnet_bh (unsigned long param) "rxqlen %d --> %d\n", temp, dev->rxq.qlen); if (dev->rxq.qlen < RX_QLEN(dev)) tasklet_schedule (&dev->bh); queue_work(usbnet_wq, &dev->bh_w); } if (!enable_ipa_bridge && dev->txq.qlen < TX_QLEN(dev)) netif_wake_queue (dev->net); } } static void usbnet_bh_w(struct work_struct *work) { struct usbnet *dev = container_of(work, struct usbnet, bh_w); unsigned long param = (unsigned long)dev; usbnet_bh(param); } /*------------------------------------------------------------------------- * Loading Loading @@ -2065,8 +2075,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) skb_queue_head_init (&dev->txq); skb_queue_head_init (&dev->done); skb_queue_head_init(&dev->rxq_pause); dev->bh.func = usbnet_bh; dev->bh.data = (unsigned long) dev; INIT_WORK(&dev->bh_w, usbnet_bh_w); INIT_WORK (&dev->kevent, kevent); init_usb_anchor(&dev->deferred); dev->delay.function = usbnet_bh; Loading Loading @@ -2347,7 +2356,7 @@ int usbnet_resume (struct usb_interface *intf) if (!(dev->txq.qlen >= TX_QLEN(dev))) netif_tx_wake_all_queues(dev->net); tasklet_schedule (&dev->bh); queue_work(usbnet_wq, &dev->bh_w); } } Loading Loading @@ -2599,12 +2608,20 @@ static int __init usbnet_init(void) FIELD_SIZEOF(struct sk_buff, cb) < sizeof(struct skb_data)); eth_random_addr(node_id); usbnet_wq = create_singlethread_workqueue("usbnet"); if (!usbnet_wq) { pr_err("%s: Unable to create workqueue:usbnet\n", __func__); return -ENOMEM; } return 0; } module_init(usbnet_init); static void __exit usbnet_exit(void) { destroy_workqueue(usbnet_wq); } module_exit(usbnet_exit); Loading include/linux/usb/usbnet.h +1 −1 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ struct usbnet { unsigned interrupt_count; struct mutex interrupt_mutex; struct usb_anchor deferred; struct tasklet_struct bh; struct work_struct bh_w; struct work_struct kevent; unsigned long flags; Loading Loading
drivers/net/usb/usbnet.c +33 −16 Original line number Diff line number Diff line Loading @@ -89,7 +89,8 @@ static u8 node_id [ETH_ALEN]; static const char driver_name [] = "usbnet"; struct workqueue_struct *usbnet_wq; static struct workqueue_struct *usbnet_wq; /* use ethtool to change the level for any given device */ static int msg_level = -1; module_param (msg_level, int, 0); Loading Loading @@ -403,7 +404,7 @@ unlock_and_schedule: if (skb_defer_rx_timestamp(skb)) return; status = netif_rx (skb); status = netif_rx_ni(skb); if (status != NET_RX_SUCCESS) netif_dbg(dev, rx_err, dev->net, "netif_rx status %d\n", status); Loading Loading @@ -500,7 +501,7 @@ static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb, spin_lock(&dev->done.lock); __skb_queue_tail(&dev->done, skb); if (dev->done.qlen == 1) tasklet_schedule(&dev->bh); queue_work(usbnet_wq, &dev->bh_w); spin_unlock_irqrestore(&dev->done.lock, flags); return old_state; } Loading Loading @@ -579,7 +580,7 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) default: netif_dbg(dev, rx_err, dev->net, "rx submit, %d\n", retval); tasklet_schedule (&dev->bh); queue_work(usbnet_wq, &dev->bh_w); break; case 0: __usbnet_queue_skb(&dev->rxq, skb, rx_start); Loading Loading @@ -745,7 +746,7 @@ void usbnet_resume_rx(struct usbnet *dev) num++; } tasklet_schedule(&dev->bh); queue_work(usbnet_wq, &dev->bh_w); netif_dbg(dev, rx_status, dev->net, "paused rx queue disabled, %d skbs requeued\n", num); Loading Loading @@ -814,7 +815,7 @@ void usbnet_unlink_rx_urbs(struct usbnet *dev) { if (netif_running(dev->net)) { (void) unlink_urbs (dev, &dev->rxq); tasklet_schedule(&dev->bh); queue_work(usbnet_wq, &dev->bh_w); } } EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs); Loading Loading @@ -887,7 +888,7 @@ int usbnet_stop (struct net_device *net) */ dev->flags = 0; del_timer_sync (&dev->delay); tasklet_kill (&dev->bh); cancel_work_sync(&dev->bh_w); if (!pm) usb_autopm_put_interface(dev->intf); Loading Loading @@ -972,7 +973,7 @@ int usbnet_open (struct net_device *net) clear_bit(EVENT_RX_KILL, &dev->flags); // delay posting reads until we're fully open tasklet_schedule (&dev->bh); queue_work(usbnet_wq, &dev->bh_w); if (info->manage_power) { retval = info->manage_power(dev, 1); if (retval < 0) { Loading Loading @@ -1114,7 +1115,7 @@ static void __handle_link_change(struct usbnet *dev) */ } else { /* submitting URBs for reading packets */ tasklet_schedule(&dev->bh); queue_work(usbnet_wq, &dev->bh_w); } /* hard_mtu or rx_urb_size may change during link change */ Loading Loading @@ -1187,7 +1188,7 @@ fail_halt: status); } else { clear_bit (EVENT_RX_HALT, &dev->flags); tasklet_schedule (&dev->bh); queue_work(usbnet_wq, &dev->bh_w); } } Loading @@ -1212,7 +1213,7 @@ fail_halt: usb_autopm_put_interface(dev->intf); fail_lowmem: if (resched) tasklet_schedule (&dev->bh); queue_work(usbnet_wq, &dev->bh_w); } } Loading Loading @@ -1308,13 +1309,14 @@ void usbnet_tx_timeout (struct net_device *net) struct usbnet *dev = netdev_priv(net); unlink_urbs (dev, &dev->txq); tasklet_schedule (&dev->bh); queue_work(usbnet_wq, &dev->bh_w); /* this needs to be handled individually because the generic layer * doesn't know what is sufficient and could not restore private * information if a remedy of an unconditional reset were used. */ if (dev->driver_info->recover) (dev->driver_info->recover)(dev); } EXPORT_SYMBOL_GPL(usbnet_tx_timeout); Loading Loading @@ -1572,13 +1574,21 @@ static void usbnet_bh (unsigned long param) "rxqlen %d --> %d\n", temp, dev->rxq.qlen); if (dev->rxq.qlen < RX_QLEN(dev)) tasklet_schedule (&dev->bh); queue_work(usbnet_wq, &dev->bh_w); } if (!enable_ipa_bridge && dev->txq.qlen < TX_QLEN(dev)) netif_wake_queue (dev->net); } } static void usbnet_bh_w(struct work_struct *work) { struct usbnet *dev = container_of(work, struct usbnet, bh_w); unsigned long param = (unsigned long)dev; usbnet_bh(param); } /*------------------------------------------------------------------------- * Loading Loading @@ -2065,8 +2075,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) skb_queue_head_init (&dev->txq); skb_queue_head_init (&dev->done); skb_queue_head_init(&dev->rxq_pause); dev->bh.func = usbnet_bh; dev->bh.data = (unsigned long) dev; INIT_WORK(&dev->bh_w, usbnet_bh_w); INIT_WORK (&dev->kevent, kevent); init_usb_anchor(&dev->deferred); dev->delay.function = usbnet_bh; Loading Loading @@ -2347,7 +2356,7 @@ int usbnet_resume (struct usb_interface *intf) if (!(dev->txq.qlen >= TX_QLEN(dev))) netif_tx_wake_all_queues(dev->net); tasklet_schedule (&dev->bh); queue_work(usbnet_wq, &dev->bh_w); } } Loading Loading @@ -2599,12 +2608,20 @@ static int __init usbnet_init(void) FIELD_SIZEOF(struct sk_buff, cb) < sizeof(struct skb_data)); eth_random_addr(node_id); usbnet_wq = create_singlethread_workqueue("usbnet"); if (!usbnet_wq) { pr_err("%s: Unable to create workqueue:usbnet\n", __func__); return -ENOMEM; } return 0; } module_init(usbnet_init); static void __exit usbnet_exit(void) { destroy_workqueue(usbnet_wq); } module_exit(usbnet_exit); Loading
include/linux/usb/usbnet.h +1 −1 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ struct usbnet { unsigned interrupt_count; struct mutex interrupt_mutex; struct usb_anchor deferred; struct tasklet_struct bh; struct work_struct bh_w; struct work_struct kevent; unsigned long flags; Loading