From: Oliver Neukum <[EMAIL PROTECTED]>

This fixes the issue of drivers claiming multiple interfaces. Operations
are stopped as soon as an interface is suspend and resumed only as
all interfaces have been resumed.

Signed-off-by: Oliver Neukum <[EMAIL PROTECTED]>
Signed-off-by: David Brownell <[EMAIL PROTECTED]>
Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>
---
 drivers/net/usb/usbnet.c |   25 +++++++++++++++----------
 drivers/net/usb/usbnet.h |    1 +
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index f9cd42d..5b16d9a 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1252,20 +1252,23 @@ EXPORT_SYMBOL_GPL(usbnet_probe);
 
 /*-------------------------------------------------------------------------*/
 
-/* FIXME these suspend/resume methods assume non-CDC style
- * devices, with only one interface.
+/*
+ * suspend the whole driver as soon as the first interface is suspended
+ * resume only when the last interface is resumed
  */
 
 int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
 {
        struct usbnet           *dev = usb_get_intfdata(intf);
 
-       /* accelerate emptying of the rx and queues, to avoid
-        * having everything error out.
-        */
-       netif_device_detach (dev->net);
-       (void) unlink_urbs (dev, &dev->rxq);
-       (void) unlink_urbs (dev, &dev->txq);
+       if (!dev->suspend_count++) {
+               /* accelerate emptying of the rx and queues, to avoid
+                * having everything error out.
+                */
+               netif_device_detach (dev->net);
+               (void) unlink_urbs (dev, &dev->rxq);
+               (void) unlink_urbs (dev, &dev->txq);
+       }
        return 0;
 }
 EXPORT_SYMBOL_GPL(usbnet_suspend);
@@ -1274,8 +1277,10 @@ int usbnet_resume (struct usb_interface *intf)
 {
        struct usbnet           *dev = usb_get_intfdata(intf);
 
-       netif_device_attach (dev->net);
-       tasklet_schedule (&dev->bh);
+       if (!--dev->suspend_count) {
+               netif_device_attach (dev->net);
+               tasklet_schedule (&dev->bh);
+       }
        return 0;
 }
 EXPORT_SYMBOL_GPL(usbnet_resume);
diff --git a/drivers/net/usb/usbnet.h b/drivers/net/usb/usbnet.h
index 82db5a8..a3f8b9e 100644
--- a/drivers/net/usb/usbnet.h
+++ b/drivers/net/usb/usbnet.h
@@ -32,6 +32,7 @@ struct usbnet {
        const char              *driver_name;
        wait_queue_head_t       *wait;
        struct mutex            phy_mutex;
+       unsigned char           suspend_count;
 
        /* i/o info: pipes etc */
        unsigned                in, out;
-- 
1.5.1.4


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to