b43legacy: Load firmware from work queue instead of from probe routine
Recent changes in udev are causing problems for drivers that load firmware from the probe routine. As b43legacy has such a structure, it must be changed. As this driver loads 3 or 4 firmware files, changing to the asynchronous routine request_firmware_nowait() would be complicated. In this implementation, the probe routine starts a work queue that calls the firmware loading routines. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
843dc6644b
commit
a3ea2c76b1
@ -581,6 +581,9 @@ struct b43legacy_wl {
|
|||||||
struct mutex mutex; /* locks wireless core state */
|
struct mutex mutex; /* locks wireless core state */
|
||||||
spinlock_t leds_lock; /* lock for leds */
|
spinlock_t leds_lock; /* lock for leds */
|
||||||
|
|
||||||
|
/* firmware loading work */
|
||||||
|
struct work_struct firmware_load;
|
||||||
|
|
||||||
/* We can only have one operating interface (802.11 core)
|
/* We can only have one operating interface (802.11 core)
|
||||||
* at a time. General information about this interface follows.
|
* at a time. General information about this interface follows.
|
||||||
*/
|
*/
|
||||||
|
@ -1557,8 +1557,15 @@ err_format:
|
|||||||
return -EPROTO;
|
return -EPROTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int b43legacy_request_firmware(struct b43legacy_wldev *dev)
|
static int b43legacy_one_core_attach(struct ssb_device *dev,
|
||||||
|
struct b43legacy_wl *wl);
|
||||||
|
static void b43legacy_one_core_detach(struct ssb_device *dev);
|
||||||
|
|
||||||
|
static void b43legacy_request_firmware(struct work_struct *work)
|
||||||
{
|
{
|
||||||
|
struct b43legacy_wl *wl = container_of(work,
|
||||||
|
struct b43legacy_wl, firmware_load);
|
||||||
|
struct b43legacy_wldev *dev = wl->current_dev;
|
||||||
struct b43legacy_firmware *fw = &dev->fw;
|
struct b43legacy_firmware *fw = &dev->fw;
|
||||||
const u8 rev = dev->dev->id.revision;
|
const u8 rev = dev->dev->id.revision;
|
||||||
const char *filename;
|
const char *filename;
|
||||||
@ -1624,8 +1631,14 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev)
|
|||||||
if (err)
|
if (err)
|
||||||
goto err_load;
|
goto err_load;
|
||||||
}
|
}
|
||||||
|
err = ieee80211_register_hw(wl->hw);
|
||||||
|
if (err)
|
||||||
|
goto err_one_core_detach;
|
||||||
|
return;
|
||||||
|
|
||||||
return 0;
|
err_one_core_detach:
|
||||||
|
b43legacy_one_core_detach(dev->dev);
|
||||||
|
goto error;
|
||||||
|
|
||||||
err_load:
|
err_load:
|
||||||
b43legacy_print_fw_helptext(dev->wl);
|
b43legacy_print_fw_helptext(dev->wl);
|
||||||
@ -1639,7 +1652,7 @@ err_no_initvals:
|
|||||||
|
|
||||||
error:
|
error:
|
||||||
b43legacy_release_firmware(dev);
|
b43legacy_release_firmware(dev);
|
||||||
return err;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
|
static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
|
||||||
@ -2153,9 +2166,6 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev)
|
|||||||
macctl |= B43legacy_MACCTL_INFRA;
|
macctl |= B43legacy_MACCTL_INFRA;
|
||||||
b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
|
b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
|
||||||
|
|
||||||
err = b43legacy_request_firmware(dev);
|
|
||||||
if (err)
|
|
||||||
goto out;
|
|
||||||
err = b43legacy_upload_microcode(dev);
|
err = b43legacy_upload_microcode(dev);
|
||||||
if (err)
|
if (err)
|
||||||
goto out; /* firmware is released later */
|
goto out; /* firmware is released later */
|
||||||
@ -3860,17 +3870,13 @@ static int b43legacy_probe(struct ssb_device *dev,
|
|||||||
if (err)
|
if (err)
|
||||||
goto err_wireless_exit;
|
goto err_wireless_exit;
|
||||||
|
|
||||||
if (first) {
|
/* setup and start work to load firmware */
|
||||||
err = ieee80211_register_hw(wl->hw);
|
INIT_WORK(&wl->firmware_load, b43legacy_request_firmware);
|
||||||
if (err)
|
schedule_work(&wl->firmware_load);
|
||||||
goto err_one_core_detach;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err_one_core_detach:
|
|
||||||
b43legacy_one_core_detach(dev);
|
|
||||||
err_wireless_exit:
|
err_wireless_exit:
|
||||||
if (first)
|
if (first)
|
||||||
b43legacy_wireless_exit(dev, wl);
|
b43legacy_wireless_exit(dev, wl);
|
||||||
@ -3885,6 +3891,7 @@ static void b43legacy_remove(struct ssb_device *dev)
|
|||||||
/* We must cancel any work here before unregistering from ieee80211,
|
/* We must cancel any work here before unregistering from ieee80211,
|
||||||
* as the ieee80211 unreg will destroy the workqueue. */
|
* as the ieee80211 unreg will destroy the workqueue. */
|
||||||
cancel_work_sync(&wldev->restart_work);
|
cancel_work_sync(&wldev->restart_work);
|
||||||
|
cancel_work_sync(&wl->firmware_load);
|
||||||
|
|
||||||
B43legacy_WARN_ON(!wl);
|
B43legacy_WARN_ON(!wl);
|
||||||
if (wl->current_dev == wldev)
|
if (wl->current_dev == wldev)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user