Skip to content

Commit 20fbe3a

Browse files
Oliver Neukumdavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 40eea80 commit 20fbe3a

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

drivers/net/usb/cdc_subset.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,34 @@ static int always_connected (struct usbnet *dev)
8585
*
8686
*-------------------------------------------------------------------------*/
8787

88+
static 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+
102+
static int dummy_prereset(struct usb_interface *intf)
103+
{
104+
return 0;
105+
}
106+
107+
static int dummy_postreset(struct usb_interface *intf)
108+
{
109+
return 0;
110+
}
111+
88112
static const struct driver_info ali_m5632_info = {
89113
.description = "ALi M5632",
90114
.flags = FLAG_POINTTOPOINT,
115+
.recover = m5632_recover,
91116
};
92117

93118
#endif
@@ -332,6 +357,8 @@ static struct usb_driver cdc_subset_driver = {
332357
.probe = usbnet_probe,
333358
.suspend = usbnet_suspend,
334359
.resume = usbnet_resume,
360+
.pre_reset = dummy_prereset,
361+
.post_reset = dummy_postreset,
335362
.disconnect = usbnet_disconnect,
336363
.id_table = products,
337364
.disable_hub_initiated_lpm = 1,

drivers/net/usb/usbnet.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,8 +1218,12 @@ void usbnet_tx_timeout (struct net_device *net)
12181218

12191219
unlink_urbs (dev, &dev->txq);
12201220
tasklet_schedule (&dev->bh);
1221-
1222-
// FIXME: device recovery -- reset?
1221+
/* this needs to be handled individually because the generic layer
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);
12231227
}
12241228
EXPORT_SYMBOL_GPL(usbnet_tx_timeout);
12251229

include/linux/usb/usbnet.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ struct driver_info {
148148
struct sk_buff *(*tx_fixup)(struct usbnet *dev,
149149
struct sk_buff *skb, gfp_t flags);
150150

151+
/* recover from timeout */
152+
void (*recover)(struct usbnet *dev);
153+
151154
/* early initialization code, can sleep. This is for minidrivers
152155
* having 'subminidrivers' that need to do extra initialization
153156
* right after minidriver have initialized hardware. */

0 commit comments

Comments
 (0)