mirror of https://gitee.com/openkylin/linux.git
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: Jussi Kivilinna <jussi.kivilinna@mbnet.fi> Cc: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
e40cbdac06
commit
1487cd5e76
|
@ -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 */
|
||||||
dev->wait = &unlink_wakeup;
|
add_wait_queue(&unlink_wakeup, &wait);
|
||||||
temp = unlink_urbs (dev, &dev->txq) + unlink_urbs (dev, &dev->rxq);
|
dev->wait = &unlink_wakeup;
|
||||||
|
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;
|
||||||
|
remove_wait_queue(&unlink_wakeup, &wait);
|
||||||
}
|
}
|
||||||
dev->wait = NULL;
|
|
||||||
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)
|
||||||
|
|
||||||
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 = {
|
||||||
|
|
||||||
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 = {
|
||||||
|
|
||||||
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 {
|
||||||
|
|
||||||
#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 */
|
||||||
|
|
Loading…
Reference in New Issue