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
					
				
			
		
					 2 changed files with 23 additions and 13 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Larry Finger
				Larry Finger