aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43legacy/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43legacy/main.c')
-rw-r--r--drivers/net/wireless/b43legacy/main.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 14a5eea2573e..3e612d0a13e8 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2378,8 +2378,10 @@ static int b43legacy_op_tx(struct ieee80211_hw *hw,
2378 } else 2378 } else
2379 err = b43legacy_dma_tx(dev, skb, ctl); 2379 err = b43legacy_dma_tx(dev, skb, ctl);
2380out: 2380out:
2381 if (unlikely(err)) 2381 if (unlikely(err)) {
2382 return NETDEV_TX_BUSY; 2382 /* Drop the packet. */
2383 dev_kfree_skb_any(skb);
2384 }
2383 return NETDEV_TX_OK; 2385 return NETDEV_TX_OK;
2384} 2386}
2385 2387
@@ -3039,7 +3041,6 @@ static void b43legacy_set_pretbtt(struct b43legacy_wldev *dev)
3039/* Locking: wl->mutex */ 3041/* Locking: wl->mutex */
3040static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) 3042static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev)
3041{ 3043{
3042 struct b43legacy_wl *wl = dev->wl;
3043 struct b43legacy_phy *phy = &dev->phy; 3044 struct b43legacy_phy *phy = &dev->phy;
3044 u32 macctl; 3045 u32 macctl;
3045 3046
@@ -3054,12 +3055,6 @@ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev)
3054 macctl |= B43legacy_MACCTL_PSM_JMP0; 3055 macctl |= B43legacy_MACCTL_PSM_JMP0;
3055 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); 3056 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
3056 3057
3057 mutex_unlock(&wl->mutex);
3058 /* Must unlock as it would otherwise deadlock. No races here.
3059 * Cancel possibly pending workqueues. */
3060 cancel_work_sync(&dev->restart_work);
3061 mutex_lock(&wl->mutex);
3062
3063 b43legacy_leds_exit(dev); 3058 b43legacy_leds_exit(dev);
3064 b43legacy_rng_exit(dev->wl); 3059 b43legacy_rng_exit(dev->wl);
3065 b43legacy_pio_free(dev); 3060 b43legacy_pio_free(dev);
@@ -3486,6 +3481,8 @@ static void b43legacy_chip_reset(struct work_struct *work)
3486 } 3481 }
3487 } 3482 }
3488out: 3483out:
3484 if (err)
3485 wl->current_dev = NULL; /* Failed to init the dev. */
3489 mutex_unlock(&wl->mutex); 3486 mutex_unlock(&wl->mutex);
3490 if (err) 3487 if (err)
3491 b43legacyerr(wl, "Controller restart FAILED\n"); 3488 b43legacyerr(wl, "Controller restart FAILED\n");
@@ -3618,9 +3615,11 @@ static void b43legacy_one_core_detach(struct ssb_device *dev)
3618 struct b43legacy_wldev *wldev; 3615 struct b43legacy_wldev *wldev;
3619 struct b43legacy_wl *wl; 3616 struct b43legacy_wl *wl;
3620 3617
3618 /* Do not cancel ieee80211-workqueue based work here.
3619 * See comment in b43legacy_remove(). */
3620
3621 wldev = ssb_get_drvdata(dev); 3621 wldev = ssb_get_drvdata(dev);
3622 wl = wldev->wl; 3622 wl = wldev->wl;
3623 cancel_work_sync(&wldev->restart_work);
3624 b43legacy_debugfs_remove_device(wldev); 3623 b43legacy_debugfs_remove_device(wldev);
3625 b43legacy_wireless_core_detach(wldev); 3624 b43legacy_wireless_core_detach(wldev);
3626 list_del(&wldev->list); 3625 list_del(&wldev->list);
@@ -3789,6 +3788,10 @@ static void b43legacy_remove(struct ssb_device *dev)
3789 struct b43legacy_wl *wl = ssb_get_devtypedata(dev); 3788 struct b43legacy_wl *wl = ssb_get_devtypedata(dev);
3790 struct b43legacy_wldev *wldev = ssb_get_drvdata(dev); 3789 struct b43legacy_wldev *wldev = ssb_get_drvdata(dev);
3791 3790
3791 /* We must cancel any work here before unregistering from ieee80211,
3792 * as the ieee80211 unreg will destroy the workqueue. */
3793 cancel_work_sync(&wldev->restart_work);
3794
3792 B43legacy_WARN_ON(!wl); 3795 B43legacy_WARN_ON(!wl);
3793 if (wl->current_dev == wldev) 3796 if (wl->current_dev == wldev)
3794 ieee80211_unregister_hw(wl->hw); 3797 ieee80211_unregister_hw(wl->hw);