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

Commit 1487cd5e authored by Jussi Kivilinna's avatar Jussi Kivilinna Committed by John W. Linville
Browse files

usbnet: allow "minidriver" to prevent urb unlinking on usbnet_stop



rndis_wlan devices freeze after running usbnet_stop several times. It appears
that firmware freezes in state where it does not respond to any RNDIS commands
and device have to be physically unplugged/replugged. This patch lets
minidrivers to disable unlink_urbs on usbnet_stop through new info flag.

Signed-off-by: default avatarJussi Kivilinna <jussi.kivilinna@mbnet.fi>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent e40cbdac
Loading
Loading
Loading
Loading
+18 −14
Original line number Diff line number Diff line
@@ -601,21 +601,25 @@ int usbnet_stop (struct net_device *net)
				info->description);
	}

	// ensure there are no more active urbs
	if (!(info->flags & FLAG_AVOID_UNLINK_URBS)) {
		/* ensure there are no more active urbs */
		add_wait_queue(&unlink_wakeup, &wait);
		dev->wait = &unlink_wakeup;
	temp = unlink_urbs (dev, &dev->txq) + unlink_urbs (dev, &dev->rxq);
		temp = unlink_urbs(dev, &dev->txq) +
			unlink_urbs(dev, &dev->rxq);

	// maybe wait for deletions to finish.
		/* maybe wait for deletions to finish. */
		while (!skb_queue_empty(&dev->rxq)
				&& !skb_queue_empty(&dev->txq)
				&& !skb_queue_empty(&dev->done)) {
			msleep(UNLINK_TIMEOUT_MS);
			if (netif_msg_ifdown(dev))
			devdbg (dev, "waited for %d urb completions", temp);
				devdbg(dev, "waited for %d urb completions",
					temp);
		}
		dev->wait = NULL;
		remove_wait_queue(&unlink_wakeup, &wait);
	}

	usb_kill_urb(dev->interrupt);

+6 −3
Original line number Diff line number Diff line
@@ -2513,7 +2513,8 @@ static int rndis_wlan_stop(struct usbnet *usbdev)

static const struct driver_info	bcm4320b_info = {
	.description =	"Wireless RNDIS device, BCM4320b based",
	.flags =	FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
	.flags =	FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT |
				FLAG_AVOID_UNLINK_URBS,
	.bind =		rndis_wlan_bind,
	.unbind =	rndis_wlan_unbind,
	.status =	rndis_status,
@@ -2527,7 +2528,8 @@ static const struct driver_info bcm4320b_info = {

static const struct driver_info	bcm4320a_info = {
	.description =	"Wireless RNDIS device, BCM4320a based",
	.flags =	FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
	.flags =	FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT |
				FLAG_AVOID_UNLINK_URBS,
	.bind =		rndis_wlan_bind,
	.unbind =	rndis_wlan_unbind,
	.status =	rndis_status,
@@ -2541,7 +2543,8 @@ static const struct driver_info bcm4320a_info = {

static const struct driver_info rndis_wlan_info = {
	.description =	"Wireless RNDIS device",
	.flags =	FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
	.flags =	FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT |
				FLAG_AVOID_UNLINK_URBS,
	.bind =		rndis_wlan_bind,
	.unbind =	rndis_wlan_unbind,
	.status =	rndis_status,
+1 −0
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ struct driver_info {

#define FLAG_FRAMING_AX 0x0040		/* AX88772/178 packets */
#define FLAG_WLAN	0x0080		/* use "wlan%d" names */
#define FLAG_AVOID_UNLINK_URBS 0x0100	/* don't unlink urbs at usbnet_stop() */


	/* init device ... can sleep, or cause probe() failure */