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 | |
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')
-rw-r--r-- | drivers/net/usb/asix.c | 1 | ||||
-rw-r--r-- | drivers/net/usb/usbnet.c | 30 | ||||
-rw-r--r-- | drivers/net/usb/usbnet.h | 1 |
3 files changed, 27 insertions, 5 deletions
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 6d95cacd5284..61daa096de66 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c | |||
@@ -1474,6 +1474,7 @@ static struct usb_driver asix_driver = { | |||
1474 | .suspend = usbnet_suspend, | 1474 | .suspend = usbnet_suspend, |
1475 | .resume = usbnet_resume, | 1475 | .resume = usbnet_resume, |
1476 | .disconnect = usbnet_disconnect, | 1476 | .disconnect = usbnet_disconnect, |
1477 | .supports_autosuspend = 1, | ||
1477 | }; | 1478 | }; |
1478 | 1479 | ||
1479 | static int __init asix_init(void) | 1480 | static int __init asix_init(void) |
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); |
diff --git a/drivers/net/usb/usbnet.h b/drivers/net/usb/usbnet.h index a6c5820767de..1fae4347e831 100644 --- a/drivers/net/usb/usbnet.h +++ b/drivers/net/usb/usbnet.h | |||
@@ -28,6 +28,7 @@ | |||
28 | struct usbnet { | 28 | struct usbnet { |
29 | /* housekeeping */ | 29 | /* housekeeping */ |
30 | struct usb_device *udev; | 30 | struct usb_device *udev; |
31 | struct usb_interface *intf; | ||
31 | struct driver_info *driver_info; | 32 | struct driver_info *driver_info; |
32 | const char *driver_name; | 33 | const char *driver_name; |
33 | wait_queue_head_t *wait; | 34 | wait_queue_head_t *wait; |