Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

b43legacy: Fix controller restart crash

This fixes a kernel crash on rmmod, in the case where the controller
was restarted before doing the rmmod.

Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Michael Buesch and committed by
John W. Linville
48e6c51b 7dccf1f4

+9 -8
+9 -8
drivers/net/wireless/b43legacy/main.c
··· 3039 3039 /* Locking: wl->mutex */ 3040 3040 static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) 3041 3041 { 3042 - struct b43legacy_wl *wl = dev->wl; 3043 3042 struct b43legacy_phy *phy = &dev->phy; 3044 3043 u32 macctl; 3045 3044 ··· 3052 3053 macctl &= ~B43legacy_MACCTL_PSM_RUN; 3053 3054 macctl |= B43legacy_MACCTL_PSM_JMP0; 3054 3055 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); 3055 - 3056 - mutex_unlock(&wl->mutex); 3057 - /* Must unlock as it would otherwise deadlock. No races here. 3058 - * Cancel possibly pending workqueues. */ 3059 - cancel_work_sync(&dev->restart_work); 3060 - mutex_lock(&wl->mutex); 3061 3056 3062 3057 b43legacy_leds_exit(dev); 3063 3058 b43legacy_rng_exit(dev->wl); ··· 3479 3486 } 3480 3487 } 3481 3488 out: 3489 + if (err) 3490 + wl->current_dev = NULL; /* Failed to init the dev. */ 3482 3491 mutex_unlock(&wl->mutex); 3483 3492 if (err) 3484 3493 b43legacyerr(wl, "Controller restart FAILED\n"); ··· 3613 3618 struct b43legacy_wldev *wldev; 3614 3619 struct b43legacy_wl *wl; 3615 3620 3621 + /* Do not cancel ieee80211-workqueue based work here. 3622 + * See comment in b43legacy_remove(). */ 3623 + 3616 3624 wldev = ssb_get_drvdata(dev); 3617 3625 wl = wldev->wl; 3618 - cancel_work_sync(&wldev->restart_work); 3619 3626 b43legacy_debugfs_remove_device(wldev); 3620 3627 b43legacy_wireless_core_detach(wldev); 3621 3628 list_del(&wldev->list); ··· 3785 3788 { 3786 3789 struct b43legacy_wl *wl = ssb_get_devtypedata(dev); 3787 3790 struct b43legacy_wldev *wldev = ssb_get_drvdata(dev); 3791 + 3792 + /* We must cancel any work here before unregistering from ieee80211, 3793 + * as the ieee80211 unreg will destroy the workqueue. */ 3794 + cancel_work_sync(&wldev->restart_work); 3788 3795 3789 3796 B43legacy_WARN_ON(!wl); 3790 3797 if (wl->current_dev == wldev)