[PATCH 07/29] USB: address FIXME in usbnet w.r.t drivers claiming multiple interfaces

Greg Kroah-Hartman <[email protected]>
Newsgroups gmane.linux.usb.devel
Message-ID <[email protected]>
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/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.