aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb
diff options
context:
space:
mode:
authorOliver Neukum <oneukum@suse.de>2007-08-03 07:52:19 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:50:40 -0400
commita11a6544c0bf6c0871f2379ad0c5ad0210691e73 (patch)
treee594e06eaae9c931305f257d3bffa27f3982b292 /drivers/net/usb
parentbc7f75fa97884d41efbfde1397b621fefb2550b4 (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.c1
-rw-r--r--drivers/net/usb/usbnet.c30
-rw-r--r--drivers/net/usb/usbnet.h1
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
1479static int __init asix_init(void) 1480static 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)
603static int usbnet_open (struct net_device *net) 604static 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;
662done: 674done:
675 usb_autopm_put_interface(dev->intf);
676done_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}
1291EXPORT_SYMBOL_GPL(usbnet_resume); 1311EXPORT_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 @@
28struct usbnet { 28struct 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;