diff options
author | Oliver Neukum <oneukum@suse.de> | 2007-08-03 07:52:19 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:50:40 -0400 |
commit | a11a6544c0bf6c0871f2379ad0c5ad0210691e73 (patch) | |
tree | e594e06eaae9c931305f257d3bffa27f3982b292 /drivers/net/usb/usbnet.c | |
parent | bc7f75fa97884d41efbfde1397b621fefb2550b4 (diff) |
support for USB autosuspend in the asix driver
this implements support for USB autosuspend in the asix USB ethernet
driver.
Signed-off-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/usb/usbnet.c')
-rw-r--r-- | drivers/net/usb/usbnet.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 37bf4f2c0a44..3034d1aea376 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -590,6 +590,7 @@ static int usbnet_stop (struct net_device *net) | |||
590 | dev->flags = 0; | 590 | dev->flags = 0; |
591 | del_timer_sync (&dev->delay); | 591 | del_timer_sync (&dev->delay); |
592 | tasklet_kill (&dev->bh); | 592 | tasklet_kill (&dev->bh); |
593 | usb_autopm_put_interface(dev->intf); | ||
593 | 594 | ||
594 | return 0; | 595 | return 0; |
595 | } | 596 | } |
@@ -603,9 +604,19 @@ static int usbnet_stop (struct net_device *net) | |||
603 | static int usbnet_open (struct net_device *net) | 604 | static int usbnet_open (struct net_device *net) |
604 | { | 605 | { |
605 | struct usbnet *dev = netdev_priv(net); | 606 | struct usbnet *dev = netdev_priv(net); |
606 | int retval = 0; | 607 | int retval; |
607 | struct driver_info *info = dev->driver_info; | 608 | struct driver_info *info = dev->driver_info; |
608 | 609 | ||
610 | if ((retval = usb_autopm_get_interface(dev->intf)) < 0) { | ||
611 | if (netif_msg_ifup (dev)) | ||
612 | devinfo (dev, | ||
613 | "resumption fail (%d) usbnet usb-%s-%s, %s", | ||
614 | retval, | ||
615 | dev->udev->bus->bus_name, dev->udev->devpath, | ||
616 | info->description); | ||
617 | goto done_nopm; | ||
618 | } | ||
619 | |||
609 | // put into "known safe" state | 620 | // put into "known safe" state |
610 | if (info->reset && (retval = info->reset (dev)) < 0) { | 621 | if (info->reset && (retval = info->reset (dev)) < 0) { |
611 | if (netif_msg_ifup (dev)) | 622 | if (netif_msg_ifup (dev)) |
@@ -659,7 +670,10 @@ static int usbnet_open (struct net_device *net) | |||
659 | 670 | ||
660 | // delay posting reads until we're fully open | 671 | // delay posting reads until we're fully open |
661 | tasklet_schedule (&dev->bh); | 672 | tasklet_schedule (&dev->bh); |
673 | return retval; | ||
662 | done: | 674 | done: |
675 | usb_autopm_put_interface(dev->intf); | ||
676 | done_nopm: | ||
663 | return retval; | 677 | return retval; |
664 | } | 678 | } |
665 | 679 | ||
@@ -1143,6 +1157,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
1143 | 1157 | ||
1144 | dev = netdev_priv(net); | 1158 | dev = netdev_priv(net); |
1145 | dev->udev = xdev; | 1159 | dev->udev = xdev; |
1160 | dev->intf = udev; | ||
1146 | dev->driver_info = info; | 1161 | dev->driver_info = info; |
1147 | dev->driver_name = name; | 1162 | dev->driver_name = name; |
1148 | dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV | 1163 | dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV |
@@ -1267,12 +1282,18 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message) | |||
1267 | struct usbnet *dev = usb_get_intfdata(intf); | 1282 | struct usbnet *dev = usb_get_intfdata(intf); |
1268 | 1283 | ||
1269 | if (!dev->suspend_count++) { | 1284 | if (!dev->suspend_count++) { |
1270 | /* accelerate emptying of the rx and queues, to avoid | 1285 | /* |
1286 | * accelerate emptying of the rx and queues, to avoid | ||
1271 | * having everything error out. | 1287 | * having everything error out. |
1272 | */ | 1288 | */ |
1273 | netif_device_detach (dev->net); | 1289 | netif_device_detach (dev->net); |
1274 | (void) unlink_urbs (dev, &dev->rxq); | 1290 | (void) unlink_urbs (dev, &dev->rxq); |
1275 | (void) unlink_urbs (dev, &dev->txq); | 1291 | (void) unlink_urbs (dev, &dev->txq); |
1292 | /* | ||
1293 | * reattach so runtime management can use and | ||
1294 | * wake the device | ||
1295 | */ | ||
1296 | netif_device_attach (dev->net); | ||
1276 | } | 1297 | } |
1277 | return 0; | 1298 | return 0; |
1278 | } | 1299 | } |
@@ -1282,10 +1303,9 @@ int usbnet_resume (struct usb_interface *intf) | |||
1282 | { | 1303 | { |
1283 | struct usbnet *dev = usb_get_intfdata(intf); | 1304 | struct usbnet *dev = usb_get_intfdata(intf); |
1284 | 1305 | ||
1285 | if (!--dev->suspend_count) { | 1306 | if (!--dev->suspend_count) |
1286 | netif_device_attach (dev->net); | ||
1287 | tasklet_schedule (&dev->bh); | 1307 | tasklet_schedule (&dev->bh); |
1288 | } | 1308 | |
1289 | return 0; | 1309 | return 0; |
1290 | } | 1310 | } |
1291 | EXPORT_SYMBOL_GPL(usbnet_resume); | 1311 | EXPORT_SYMBOL_GPL(usbnet_resume); |