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

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
...@@ -601,21 +601,25 @@ int usbnet_stop (struct net_device *net) ...@@ -601,21 +601,25 @@ int usbnet_stop (struct net_device *net)
info->description); info->description);
} }
// ensure there are no more active urbs if (!(info->flags & FLAG_AVOID_UNLINK_URBS)) {
add_wait_queue (&unlink_wakeup, &wait); /* ensure there are no more active urbs */
add_wait_queue(&unlink_wakeup, &wait);
dev->wait = &unlink_wakeup; 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) while (!skb_queue_empty(&dev->rxq)
&& !skb_queue_empty(&dev->txq) && !skb_queue_empty(&dev->txq)
&& !skb_queue_empty(&dev->done)) { && !skb_queue_empty(&dev->done)) {
msleep(UNLINK_TIMEOUT_MS); msleep(UNLINK_TIMEOUT_MS);
if (netif_msg_ifdown (dev)) if (netif_msg_ifdown(dev))
devdbg (dev, "waited for %d urb completions", temp); devdbg(dev, "waited for %d urb completions",
temp);
} }
dev->wait = NULL; dev->wait = NULL;
remove_wait_queue (&unlink_wakeup, &wait); remove_wait_queue(&unlink_wakeup, &wait);
}
usb_kill_urb(dev->interrupt); usb_kill_urb(dev->interrupt);
......
...@@ -2513,7 +2513,8 @@ static int rndis_wlan_stop(struct usbnet *usbdev) ...@@ -2513,7 +2513,8 @@ static int rndis_wlan_stop(struct usbnet *usbdev)
static const struct driver_info bcm4320b_info = { static const struct driver_info bcm4320b_info = {
.description = "Wireless RNDIS device, BCM4320b based", .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, .bind = rndis_wlan_bind,
.unbind = rndis_wlan_unbind, .unbind = rndis_wlan_unbind,
.status = rndis_status, .status = rndis_status,
...@@ -2527,7 +2528,8 @@ static const struct driver_info bcm4320b_info = { ...@@ -2527,7 +2528,8 @@ static const struct driver_info bcm4320b_info = {
static const struct driver_info bcm4320a_info = { static const struct driver_info bcm4320a_info = {
.description = "Wireless RNDIS device, BCM4320a based", .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, .bind = rndis_wlan_bind,
.unbind = rndis_wlan_unbind, .unbind = rndis_wlan_unbind,
.status = rndis_status, .status = rndis_status,
...@@ -2541,7 +2543,8 @@ static const struct driver_info bcm4320a_info = { ...@@ -2541,7 +2543,8 @@ static const struct driver_info bcm4320a_info = {
static const struct driver_info rndis_wlan_info = { static const struct driver_info rndis_wlan_info = {
.description = "Wireless RNDIS device", .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, .bind = rndis_wlan_bind,
.unbind = rndis_wlan_unbind, .unbind = rndis_wlan_unbind,
.status = rndis_status, .status = rndis_status,
......
...@@ -86,6 +86,7 @@ struct driver_info { ...@@ -86,6 +86,7 @@ struct driver_info {
#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */ #define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */
#define FLAG_WLAN 0x0080 /* use "wlan%d" names */ #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 */ /* init device ... can sleep, or cause probe() failure */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment