aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorOliver Neukum <oneukum@suse.de>2014-08-01 08:01:51 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-02 18:44:18 -0400
commitdbcdd4d58c7230bea3157d56d6ef77c493b3865b (patch)
tree461928882c98e191e56cfe24bc430bbd3f5a8962 /drivers/net
parent06ebb06d49486676272a3c030bfeef4bd969a8e6 (diff)
cdc_subset: deal with a device that needs reset for timeout
This device needs to be reset to recover from a timeout. Unfortunately this can be handled only at the level of the subdrivers. Signed-off-by: Oliver Neukum <oneukum@suse.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/usb/cdc_subset.c27
-rw-r--r--drivers/net/usb/usbnet.c8
2 files changed, 32 insertions, 3 deletions
diff --git a/drivers/net/usb/cdc_subset.c b/drivers/net/usb/cdc_subset.c
index 91f0919fe278..6ea98cff2d3b 100644
--- a/drivers/net/usb/cdc_subset.c
+++ b/drivers/net/usb/cdc_subset.c
@@ -85,14 +85,28 @@ static int always_connected (struct usbnet *dev)
85 * 85 *
86 *-------------------------------------------------------------------------*/ 86 *-------------------------------------------------------------------------*/
87 87
88static void m5632_recover(struct usbnet *dev)
89{
90 struct usb_device *udev = dev->udev;
91 struct usb_interface *intf = dev->intf;
92 int r;
93
94 r = usb_lock_device_for_reset(udev, intf);
95 if (r < 0)
96 return;
97
98 usb_reset_device(udev);
99 usb_unlock_device(udev);
100}
101
88static const struct driver_info ali_m5632_info = { 102static const struct driver_info ali_m5632_info = {
89 .description = "ALi M5632", 103 .description = "ALi M5632",
90 .flags = FLAG_POINTTOPOINT, 104 .flags = FLAG_POINTTOPOINT,
105 .recover = m5632_recover,
91}; 106};
92 107
93#endif 108#endif
94 109
95
96#ifdef CONFIG_USB_AN2720 110#ifdef CONFIG_USB_AN2720
97#define HAVE_HARDWARE 111#define HAVE_HARDWARE
98 112
@@ -326,12 +340,23 @@ static const struct usb_device_id products [] = {
326MODULE_DEVICE_TABLE(usb, products); 340MODULE_DEVICE_TABLE(usb, products);
327 341
328/*-------------------------------------------------------------------------*/ 342/*-------------------------------------------------------------------------*/
343static int dummy_prereset(struct usb_interface *intf)
344{
345 return 0;
346}
347
348static int dummy_postreset(struct usb_interface *intf)
349{
350 return 0;
351}
329 352
330static struct usb_driver cdc_subset_driver = { 353static struct usb_driver cdc_subset_driver = {
331 .name = "cdc_subset", 354 .name = "cdc_subset",
332 .probe = usbnet_probe, 355 .probe = usbnet_probe,
333 .suspend = usbnet_suspend, 356 .suspend = usbnet_suspend,
334 .resume = usbnet_resume, 357 .resume = usbnet_resume,
358 .pre_reset = dummy_prereset,
359 .post_reset = dummy_postreset,
335 .disconnect = usbnet_disconnect, 360 .disconnect = usbnet_disconnect,
336 .id_table = products, 361 .id_table = products,
337 .disable_hub_initiated_lpm = 1, 362 .disable_hub_initiated_lpm = 1,
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index f9e96c427558..5173821a9575 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1218,8 +1218,12 @@ void usbnet_tx_timeout (struct net_device *net)
1218 1218
1219 unlink_urbs (dev, &dev->txq); 1219 unlink_urbs (dev, &dev->txq);
1220 tasklet_schedule (&dev->bh); 1220 tasklet_schedule (&dev->bh);
1221 1221 /* this needs to be handled individually because the generic layer
1222 // FIXME: device recovery -- reset? 1222 * doesn't know what is sufficient and could not restore private
1223 * information if a remedy of an unconditional reset were used.
1224 */
1225 if (dev->driver_info->recover)
1226 (dev->driver_info->recover)(dev);
1223} 1227}
1224EXPORT_SYMBOL_GPL(usbnet_tx_timeout); 1228EXPORT_SYMBOL_GPL(usbnet_tx_timeout);
1225 1229