]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/wireless/b43legacy/main.c
Merge branch 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-omap-h63xx.git] / drivers / net / wireless / b43legacy / main.c
index ef829ee8ffd47f3bd538c74964de21425d056a3f..3e612d0a13e8fc927c766c09507067a0d009a988 100644 (file)
@@ -1720,7 +1720,7 @@ static int b43legacy_write_initvals(struct b43legacy_wldev *dev,
                                goto err_format;
                        array_size -= sizeof(iv->data.d32);
 
-                       value = be32_to_cpu(get_unaligned(&iv->data.d32));
+                       value = get_unaligned_be32(&iv->data.d32);
                        b43legacy_write32(dev, offset, value);
 
                        iv = (const struct b43legacy_iv *)((const uint8_t *)iv +
@@ -2378,8 +2378,10 @@ static int b43legacy_op_tx(struct ieee80211_hw *hw,
        } else
                err = b43legacy_dma_tx(dev, skb, ctl);
 out:
-       if (unlikely(err))
-               return NETDEV_TX_BUSY;
+       if (unlikely(err)) {
+               /* Drop the packet. */
+               dev_kfree_skb_any(skb);
+       }
        return NETDEV_TX_OK;
 }
 
@@ -3039,7 +3041,6 @@ static void b43legacy_set_pretbtt(struct b43legacy_wldev *dev)
 /* Locking: wl->mutex */
 static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev)
 {
-       struct b43legacy_wl *wl = dev->wl;
        struct b43legacy_phy *phy = &dev->phy;
        u32 macctl;
 
@@ -3054,12 +3055,6 @@ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev)
        macctl |= B43legacy_MACCTL_PSM_JMP0;
        b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
 
-       mutex_unlock(&wl->mutex);
-       /* Must unlock as it would otherwise deadlock. No races here.
-        * Cancel possibly pending workqueues. */
-       cancel_work_sync(&dev->restart_work);
-       mutex_lock(&wl->mutex);
-
        b43legacy_leds_exit(dev);
        b43legacy_rng_exit(dev->wl);
        b43legacy_pio_free(dev);
@@ -3486,6 +3481,8 @@ static void b43legacy_chip_reset(struct work_struct *work)
                }
        }
 out:
+       if (err)
+               wl->current_dev = NULL; /* Failed to init the dev. */
        mutex_unlock(&wl->mutex);
        if (err)
                b43legacyerr(wl, "Controller restart FAILED\n");
@@ -3618,9 +3615,11 @@ static void b43legacy_one_core_detach(struct ssb_device *dev)
        struct b43legacy_wldev *wldev;
        struct b43legacy_wl *wl;
 
+       /* Do not cancel ieee80211-workqueue based work here.
+        * See comment in b43legacy_remove(). */
+
        wldev = ssb_get_drvdata(dev);
        wl = wldev->wl;
-       cancel_work_sync(&wldev->restart_work);
        b43legacy_debugfs_remove_device(wldev);
        b43legacy_wireless_core_detach(wldev);
        list_del(&wldev->list);
@@ -3789,6 +3788,10 @@ static void b43legacy_remove(struct ssb_device *dev)
        struct b43legacy_wl *wl = ssb_get_devtypedata(dev);
        struct b43legacy_wldev *wldev = ssb_get_drvdata(dev);
 
+       /* We must cancel any work here before unregistering from ieee80211,
+        * as the ieee80211 unreg will destroy the workqueue. */
+       cancel_work_sync(&wldev->restart_work);
+
        B43legacy_WARN_ON(!wl);
        if (wl->current_dev == wldev)
                ieee80211_unregister_hw(wl->hw);