b43legacy: Fix controller restart crash
PATCH 1/1 b43legacy: Fix controller restart crash
This fixes a kernel crash on rmmod, in the case where the controller was restarted before doing the rmmod.
---
Stefano, this is untested. Please test by doing
echo -n 1 >/debug/b43legacy/phy*/restart
rmmod b43legacy
It should not crash anymore at the rmmod (actually the restart should also hang in b43legacy, as it has a deadlock, which this patch also fixes).
drivers/net/wireless/b43legacy/main.c +9 -8
@@ -3035,13 +3035,12 @@ static void b43legacy_set_pretbtt(struct }/* Shutdown a wireless core */ /* 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;B43legacy_WARN_ON (b43legacy_status (dev) > B43legacy_STAT_INITIALIZED);if (b43legacy_status (dev) != B43legacy_STAT_INITIALIZED)return ;
@@ -3050,18 +3049,12 @@ static void b43legacy_wireless_core_exit/* Stop the microcode PSM. */ macctl =b43legacy_read32 (dev, B43legacy_MMIO_MACCTL); macctl &= ~B43legacy_MACCTL_PSM_RUN; 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);b43legacy_dma_free (dev);b43legacy_chip_exit (dev);b43legacy_radio_turn_off (dev,1 );
@@ -3482,12 +3475,14 @@ static void b43legacy_chip_reset(structif (err) {b43legacy_wireless_core_exit (dev); goto out; } } out: +if (err) + wl->current_dev =NULL ;/* Failed to init the dev. */ mutex_unlock (&wl->mutex);if (err)b43legacyerr (wl,"Controller restart FAILED\n" );else b43legacyinfo (wl,"Controller restarted\n" ); }
@@ -3614,15 +3609,17 @@ err_powerdown: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); wl->nr_devs--;ssb_set_drvdata (dev,NULL );kfree (wldev);
@@ -3784,12 +3781,16 @@ err_wireless_exit: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);b43legacy_one_core_detach (dev);
Quoted 5 lines · Michael Buesch
This fixes a kernel crash on rmmod, in the case where the controller was restarted before doing the rmmod.
Signed-off-by Michael Buesch <[email protected]>
Quoted 7 lines
---
Stefano, this is untested. Please test by doing
echo -n 1 >/debug/b43legacy/phy*/restart
rmmod b43legacy
It should not crash anymore at the rmmod (actually the restart should also hang in b43legacy, as it has a deadlock, which this patch also fixes).
Anyone get a chance to test this one?
John
Signature · 2 lines
John W. Linville [email protected]
Quoted 7 lines · John W. Linville
Quoted 5 lines
Stefano, this is untested. Please test by doing
echo -n 1 >/debug/b43legacy/phy*/restart
rmmod b43legacy
It should not crash anymore at the rmmod (actually the restart should also hang in b43legacy, as it has a deadlock, which this patch also fixes).Anyone get a chance to test this one?
Yes, the patch is fine.
Unloading b43legacy hangs without the patch and works properly with the patch.
Signature · 2 lines
Regards, Pavel Roskin