diff options
Diffstat (limited to 'drivers/net/usb/usbnet.c')
-rw-r--r-- | drivers/net/usb/usbnet.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 95c41d56631c..9ab439d144ed 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -387,8 +387,12 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) | |||
387 | static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) | 387 | static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) |
388 | { | 388 | { |
389 | if (dev->driver_info->rx_fixup && | 389 | if (dev->driver_info->rx_fixup && |
390 | !dev->driver_info->rx_fixup (dev, skb)) | 390 | !dev->driver_info->rx_fixup (dev, skb)) { |
391 | goto error; | 391 | /* With RX_ASSEMBLE, rx_fixup() must update counters */ |
392 | if (!(dev->driver_info->flags & FLAG_RX_ASSEMBLE)) | ||
393 | dev->net->stats.rx_errors++; | ||
394 | goto done; | ||
395 | } | ||
392 | // else network stack removes extra byte if we forced a short packet | 396 | // else network stack removes extra byte if we forced a short packet |
393 | 397 | ||
394 | if (skb->len) { | 398 | if (skb->len) { |
@@ -401,8 +405,8 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) | |||
401 | } | 405 | } |
402 | 406 | ||
403 | netif_dbg(dev, rx_err, dev->net, "drop\n"); | 407 | netif_dbg(dev, rx_err, dev->net, "drop\n"); |
404 | error: | ||
405 | dev->net->stats.rx_errors++; | 408 | dev->net->stats.rx_errors++; |
409 | done: | ||
406 | skb_queue_tail(&dev->done, skb); | 410 | skb_queue_tail(&dev->done, skb); |
407 | } | 411 | } |
408 | 412 | ||
@@ -641,6 +645,7 @@ int usbnet_stop (struct net_device *net) | |||
641 | struct driver_info *info = dev->driver_info; | 645 | struct driver_info *info = dev->driver_info; |
642 | int retval; | 646 | int retval; |
643 | 647 | ||
648 | clear_bit(EVENT_DEV_OPEN, &dev->flags); | ||
644 | netif_stop_queue (net); | 649 | netif_stop_queue (net); |
645 | 650 | ||
646 | netif_info(dev, ifdown, dev->net, | 651 | netif_info(dev, ifdown, dev->net, |
@@ -732,6 +737,7 @@ int usbnet_open (struct net_device *net) | |||
732 | } | 737 | } |
733 | } | 738 | } |
734 | 739 | ||
740 | set_bit(EVENT_DEV_OPEN, &dev->flags); | ||
735 | netif_start_queue (net); | 741 | netif_start_queue (net); |
736 | netif_info(dev, ifup, dev->net, | 742 | netif_info(dev, ifup, dev->net, |
737 | "open: enable queueing (rx %d, tx %d) mtu %d %s framing\n", | 743 | "open: enable queueing (rx %d, tx %d) mtu %d %s framing\n", |
@@ -1255,6 +1261,9 @@ void usbnet_disconnect (struct usb_interface *intf) | |||
1255 | if (dev->driver_info->unbind) | 1261 | if (dev->driver_info->unbind) |
1256 | dev->driver_info->unbind (dev, intf); | 1262 | dev->driver_info->unbind (dev, intf); |
1257 | 1263 | ||
1264 | usb_kill_urb(dev->interrupt); | ||
1265 | usb_free_urb(dev->interrupt); | ||
1266 | |||
1258 | free_netdev(net); | 1267 | free_netdev(net); |
1259 | usb_put_dev (xdev); | 1268 | usb_put_dev (xdev); |
1260 | } | 1269 | } |
@@ -1376,7 +1385,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
1376 | // else "eth%d" when there's reasonable doubt. userspace | 1385 | // else "eth%d" when there's reasonable doubt. userspace |
1377 | // can rename the link if it knows better. | 1386 | // can rename the link if it knows better. |
1378 | if ((dev->driver_info->flags & FLAG_ETHER) != 0 && | 1387 | if ((dev->driver_info->flags & FLAG_ETHER) != 0 && |
1379 | (net->dev_addr [0] & 0x02) == 0) | 1388 | ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 || |
1389 | (net->dev_addr [0] & 0x02) == 0)) | ||
1380 | strcpy (net->name, "eth%d"); | 1390 | strcpy (net->name, "eth%d"); |
1381 | /* WLAN devices should always be named "wlan%d" */ | 1391 | /* WLAN devices should always be named "wlan%d" */ |
1382 | if ((dev->driver_info->flags & FLAG_WLAN) != 0) | 1392 | if ((dev->driver_info->flags & FLAG_WLAN) != 0) |
@@ -1493,6 +1503,10 @@ int usbnet_resume (struct usb_interface *intf) | |||
1493 | int retval; | 1503 | int retval; |
1494 | 1504 | ||
1495 | if (!--dev->suspend_count) { | 1505 | if (!--dev->suspend_count) { |
1506 | /* resume interrupt URBs */ | ||
1507 | if (dev->interrupt && test_bit(EVENT_DEV_OPEN, &dev->flags)) | ||
1508 | usb_submit_urb(dev->interrupt, GFP_NOIO); | ||
1509 | |||
1496 | spin_lock_irq(&dev->txq.lock); | 1510 | spin_lock_irq(&dev->txq.lock); |
1497 | while ((res = usb_get_from_anchor(&dev->deferred))) { | 1511 | while ((res = usb_get_from_anchor(&dev->deferred))) { |
1498 | 1512 | ||
@@ -1511,9 +1525,12 @@ int usbnet_resume (struct usb_interface *intf) | |||
1511 | smp_mb(); | 1525 | smp_mb(); |
1512 | clear_bit(EVENT_DEV_ASLEEP, &dev->flags); | 1526 | clear_bit(EVENT_DEV_ASLEEP, &dev->flags); |
1513 | spin_unlock_irq(&dev->txq.lock); | 1527 | spin_unlock_irq(&dev->txq.lock); |
1514 | if (!(dev->txq.qlen >= TX_QLEN(dev))) | 1528 | |
1515 | netif_start_queue(dev->net); | 1529 | if (test_bit(EVENT_DEV_OPEN, &dev->flags)) { |
1516 | tasklet_schedule (&dev->bh); | 1530 | if (!(dev->txq.qlen >= TX_QLEN(dev))) |
1531 | netif_start_queue(dev->net); | ||
1532 | tasklet_schedule (&dev->bh); | ||
1533 | } | ||
1517 | } | 1534 | } |
1518 | return 0; | 1535 | return 0; |
1519 | } | 1536 | } |