Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 20fbe3ae authored by Oliver Neukum's avatar Oliver Neukum Committed by David S. Miller
Browse files

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: default avatarOliver Neukum <oneukum@suse.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 40eea803
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -85,9 +85,34 @@ 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 int dummy_prereset(struct usb_interface *intf)
{
	return 0;
}

static int dummy_postreset(struct usb_interface *intf)
{
	return 0;
}

static const struct driver_info	ali_m5632_info = {
	.description =	"ALi M5632",
	.flags       = FLAG_POINTTOPOINT,
	.recover     = m5632_recover,
};

#endif
@@ -332,6 +357,8 @@ static struct usb_driver cdc_subset_driver = {
	.probe =	usbnet_probe,
	.suspend =	usbnet_suspend,
	.resume =	usbnet_resume,
	.pre_reset =	dummy_prereset,
	.post_reset =	dummy_postreset,
	.disconnect =	usbnet_disconnect,
	.id_table =	products,
	.disable_hub_initiated_lpm = 1,
+6 −2
Original line number Diff line number Diff line
@@ -1218,8 +1218,12 @@ void usbnet_tx_timeout (struct net_device *net)

	unlink_urbs (dev, &dev->txq);
	tasklet_schedule (&dev->bh);

	// FIXME: device recovery -- reset?
	/* this needs to be handled individually because the generic layer
	 * 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);

+3 −0
Original line number Diff line number Diff line
@@ -148,6 +148,9 @@ struct driver_info {
	struct sk_buff	*(*tx_fixup)(struct usbnet *dev,
				struct sk_buff *skb, gfp_t flags);

	/* recover from timeout */
	void	(*recover)(struct usbnet *dev);

	/* early initialization code, can sleep. This is for minidrivers
	 * having 'subminidrivers' that need to do extra initialization
	 * right after minidriver have initialized hardware. */