aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Neukum <oneukum@suse.de>2014-07-28 04:12:34 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-29 15:22:15 -0400
commit20fbe3ae990fd54fc7d1f889d61958bc8b38f254 (patch)
tree06f6b9af9f77b65c1bbd92cf1da3e3b64266c6e3
parent40eea803c6b2cfaab092f053248cbeab3f368412 (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>
-rw-r--r--drivers/net/usb/cdc_subset.c27
-rw-r--r--drivers/net/usb/usbnet.c8
-rw-r--r--include/linux/usb/usbnet.h3
3 files changed, 36 insertions, 2 deletions
diff --git a/drivers/net/usb/cdc_subset.c b/drivers/net/usb/cdc_subset.c
index 91f0919fe278..3ef411efd86e 100644
--- a/drivers/net/usb/cdc_subset.c
+++ b/drivers/net/usb/cdc_subset.c
@@ -85,9 +85,34 @@ 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
102static int dummy_prereset(struct usb_interface *intf)
103{
104 return 0;
105}
106
107static int dummy_postreset(struct usb_interface *intf)
108{
109 return 0;
110}
111
88static const struct driver_info ali_m5632_info = { 112static const struct driver_info ali_m5632_info = {
89 .description = "ALi M5632", 113 .description = "ALi M5632",
90 .flags = FLAG_POINTTOPOINT, 114 .flags = FLAG_POINTTOPOINT,
115 .recover = m5632_recover,
91}; 116};
92 117
93#endif 118#endif
@@ -332,6 +357,8 @@ static struct usb_driver cdc_subset_driver = {
332 .probe = usbnet_probe, 357 .probe = usbnet_probe,
333 .suspend = usbnet_suspend, 358 .suspend = usbnet_suspend,
334 .resume = usbnet_resume, 359 .resume = usbnet_resume,
360 .pre_reset = dummy_prereset,
361 .post_reset = dummy_postreset,
335 .disconnect = usbnet_disconnect, 362 .disconnect = usbnet_disconnect,
336 .id_table = products, 363 .id_table = products,
337 .disable_hub_initiated_lpm = 1, 364 .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
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 0662e98fef72..26088feb6608 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -148,6 +148,9 @@ struct driver_info {
148 struct sk_buff *(*tx_fixup)(struct usbnet *dev, 148 struct sk_buff *(*tx_fixup)(struct usbnet *dev,
149 struct sk_buff *skb, gfp_t flags); 149 struct sk_buff *skb, gfp_t flags);
150 150
151 /* recover from timeout */
152 void (*recover)(struct usbnet *dev);
153
151 /* early initialization code, can sleep. This is for minidrivers 154 /* early initialization code, can sleep. This is for minidrivers
152 * having 'subminidrivers' that need to do extra initialization 155 * having 'subminidrivers' that need to do extra initialization
153 * right after minidriver have initialized hardware. */ 156 * right after minidriver have initialized hardware. */