mirror of
https://github.com/torvalds/linux.git
synced 2024-12-26 21:02:19 +00:00
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>
This commit is contained in:
parent
06ebb06d49
commit
dbcdd4d58c
@ -85,14 +85,28 @@ static int always_connected (struct usbnet *dev)
|
|||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------*/
|
*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void m5632_recover(struct usbnet *dev)
|
||||||
|
{
|
||||||
|
struct usb_device *udev = dev->udev;
|
||||||
|
struct usb_interface *intf = dev->intf;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = usb_lock_device_for_reset(udev, intf);
|
||||||
|
if (r < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
usb_reset_device(udev);
|
||||||
|
usb_unlock_device(udev);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct driver_info ali_m5632_info = {
|
static const struct driver_info ali_m5632_info = {
|
||||||
.description = "ALi M5632",
|
.description = "ALi M5632",
|
||||||
.flags = FLAG_POINTTOPOINT,
|
.flags = FLAG_POINTTOPOINT,
|
||||||
|
.recover = m5632_recover,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_USB_AN2720
|
#ifdef CONFIG_USB_AN2720
|
||||||
#define HAVE_HARDWARE
|
#define HAVE_HARDWARE
|
||||||
|
|
||||||
@ -326,12 +340,23 @@ static const struct usb_device_id products [] = {
|
|||||||
MODULE_DEVICE_TABLE(usb, products);
|
MODULE_DEVICE_TABLE(usb, products);
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static int dummy_prereset(struct usb_interface *intf)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dummy_postreset(struct usb_interface *intf)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct usb_driver cdc_subset_driver = {
|
static struct usb_driver cdc_subset_driver = {
|
||||||
.name = "cdc_subset",
|
.name = "cdc_subset",
|
||||||
.probe = usbnet_probe,
|
.probe = usbnet_probe,
|
||||||
.suspend = usbnet_suspend,
|
.suspend = usbnet_suspend,
|
||||||
.resume = usbnet_resume,
|
.resume = usbnet_resume,
|
||||||
|
.pre_reset = dummy_prereset,
|
||||||
|
.post_reset = dummy_postreset,
|
||||||
.disconnect = usbnet_disconnect,
|
.disconnect = usbnet_disconnect,
|
||||||
.id_table = products,
|
.id_table = products,
|
||||||
.disable_hub_initiated_lpm = 1,
|
.disable_hub_initiated_lpm = 1,
|
||||||
|
@ -1218,8 +1218,12 @@ void usbnet_tx_timeout (struct net_device *net)
|
|||||||
|
|
||||||
unlink_urbs (dev, &dev->txq);
|
unlink_urbs (dev, &dev->txq);
|
||||||
tasklet_schedule (&dev->bh);
|
tasklet_schedule (&dev->bh);
|
||||||
|
/* this needs to be handled individually because the generic layer
|
||||||
// FIXME: device recovery -- reset?
|
* doesn't know what is sufficient and could not restore private
|
||||||
|
* information if a remedy of an unconditional reset were used.
|
||||||
|
*/
|
||||||
|
if (dev->driver_info->recover)
|
||||||
|
(dev->driver_info->recover)(dev);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(usbnet_tx_timeout);
|
EXPORT_SYMBOL_GPL(usbnet_tx_timeout);
|
||||||
|
|
||||||
|
@ -148,6 +148,9 @@ struct driver_info {
|
|||||||
struct sk_buff *(*tx_fixup)(struct usbnet *dev,
|
struct sk_buff *(*tx_fixup)(struct usbnet *dev,
|
||||||
struct sk_buff *skb, gfp_t flags);
|
struct sk_buff *skb, gfp_t flags);
|
||||||
|
|
||||||
|
/* recover from timeout */
|
||||||
|
void (*recover)(struct usbnet *dev);
|
||||||
|
|
||||||
/* early initialization code, can sleep. This is for minidrivers
|
/* early initialization code, can sleep. This is for minidrivers
|
||||||
* having 'subminidrivers' that need to do extra initialization
|
* having 'subminidrivers' that need to do extra initialization
|
||||||
* right after minidriver have initialized hardware. */
|
* right after minidriver have initialized hardware. */
|
||||||
|
Loading…
Reference in New Issue
Block a user