diff options
author | Oliver Neukum <oneukum@suse.de> | 2007-04-30 04:37:44 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-05-23 02:45:48 -0400 |
commit | 36433127ae7a842482ba857f5ad3c431817a9542 (patch) | |
tree | 447195ec8d717269380287e454ddb0c11c336ec5 /drivers/net/usb | |
parent | 741ec4e6d0b7780d29a63f908d6d21df425be365 (diff) |
USB: address FIXME in usbnet w.r.t drivers claiming multiple interfaces
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 <oneukum@suse.de>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/net/usb')
-rw-r--r-- | drivers/net/usb/usbnet.c | 25 | ||||
-rw-r--r-- | 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 f9cd42d058b0..5b16d9a1269a 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -1252,20 +1252,23 @@ EXPORT_SYMBOL_GPL(usbnet_probe); | |||
1252 | 1252 | ||
1253 | /*-------------------------------------------------------------------------*/ | 1253 | /*-------------------------------------------------------------------------*/ |
1254 | 1254 | ||
1255 | /* FIXME these suspend/resume methods assume non-CDC style | 1255 | /* |
1256 | * devices, with only one interface. | 1256 | * suspend the whole driver as soon as the first interface is suspended |
1257 | * resume only when the last interface is resumed | ||
1257 | */ | 1258 | */ |
1258 | 1259 | ||
1259 | int usbnet_suspend (struct usb_interface *intf, pm_message_t message) | 1260 | int usbnet_suspend (struct usb_interface *intf, pm_message_t message) |
1260 | { | 1261 | { |
1261 | struct usbnet *dev = usb_get_intfdata(intf); | 1262 | struct usbnet *dev = usb_get_intfdata(intf); |
1262 | 1263 | ||
1263 | /* accelerate emptying of the rx and queues, to avoid | 1264 | if (!dev->suspend_count++) { |
1264 | * having everything error out. | 1265 | /* accelerate emptying of the rx and queues, to avoid |
1265 | */ | 1266 | * having everything error out. |
1266 | netif_device_detach (dev->net); | 1267 | */ |
1267 | (void) unlink_urbs (dev, &dev->rxq); | 1268 | netif_device_detach (dev->net); |
1268 | (void) unlink_urbs (dev, &dev->txq); | 1269 | (void) unlink_urbs (dev, &dev->rxq); |
1270 | (void) unlink_urbs (dev, &dev->txq); | ||
1271 | } | ||
1269 | return 0; | 1272 | return 0; |
1270 | } | 1273 | } |
1271 | EXPORT_SYMBOL_GPL(usbnet_suspend); | 1274 | EXPORT_SYMBOL_GPL(usbnet_suspend); |
@@ -1274,8 +1277,10 @@ int usbnet_resume (struct usb_interface *intf) | |||
1274 | { | 1277 | { |
1275 | struct usbnet *dev = usb_get_intfdata(intf); | 1278 | struct usbnet *dev = usb_get_intfdata(intf); |
1276 | 1279 | ||
1277 | netif_device_attach (dev->net); | 1280 | if (!--dev->suspend_count) { |
1278 | tasklet_schedule (&dev->bh); | 1281 | netif_device_attach (dev->net); |
1282 | tasklet_schedule (&dev->bh); | ||
1283 | } | ||
1279 | return 0; | 1284 | return 0; |
1280 | } | 1285 | } |
1281 | EXPORT_SYMBOL_GPL(usbnet_resume); | 1286 | EXPORT_SYMBOL_GPL(usbnet_resume); |
diff --git a/drivers/net/usb/usbnet.h b/drivers/net/usb/usbnet.h index 82db5a8e528e..a3f8b9e7bc00 100644 --- a/drivers/net/usb/usbnet.h +++ b/drivers/net/usb/usbnet.h | |||
@@ -32,6 +32,7 @@ struct usbnet { | |||
32 | const char *driver_name; | 32 | const char *driver_name; |
33 | wait_queue_head_t *wait; | 33 | wait_queue_head_t *wait; |
34 | struct mutex phy_mutex; | 34 | struct mutex phy_mutex; |
35 | unsigned char suspend_count; | ||
35 | 36 | ||
36 | /* i/o info: pipes etc */ | 37 | /* i/o info: pipes etc */ |
37 | unsigned in, out; | 38 | unsigned in, out; |