aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/rtl8712/hal_init.c
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2012-02-05 22:12:26 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-08 17:14:15 -0500
commit8c213fa59199f9673d66970d6940fa093186642f (patch)
treee7357cf1101a7b1451ab4b5c05245c34ad97436a /drivers/staging/rtl8712/hal_init.c
parent737912e11bf5bd4874acc771d8511a6eab891fc5 (diff)
staging: r8712u: Use asynchronous firmware loading
In https://bugs.archlinux.org/task/27996, failure of driver r8712u is reported, with a timeout during module loading due to synchronous loading of the firmware. The code now uses request_firmware_nowait(). Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/rtl8712/hal_init.c')
-rw-r--r--drivers/staging/rtl8712/hal_init.c62
1 files changed, 43 insertions, 19 deletions
diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c
index d0029aa4cd3..cc893c0f5ad 100644
--- a/drivers/staging/rtl8712/hal_init.c
+++ b/drivers/staging/rtl8712/hal_init.c
@@ -42,29 +42,56 @@
42#define FWBUFF_ALIGN_SZ 512 42#define FWBUFF_ALIGN_SZ 512
43#define MAX_DUMP_FWSZ 49152 /*default = 49152 (48k)*/ 43#define MAX_DUMP_FWSZ 49152 /*default = 49152 (48k)*/
44 44
45static u32 rtl871x_open_fw(struct _adapter *padapter, void **pphfwfile_hdl, 45static void rtl871x_load_fw_cb(const struct firmware *firmware, void *context)
46 const u8 **ppmappedfw)
47{ 46{
47 struct _adapter *padapter = context;
48
49 complete(&padapter->rtl8712_fw_ready);
50 if (!firmware) {
51 struct usb_device *udev = padapter->dvobjpriv.pusbdev;
52 struct usb_interface *pusb_intf = padapter->pusb_intf;
53 printk(KERN_ERR "r8712u: Firmware request failed\n");
54 padapter->fw_found = false;
55 usb_put_dev(udev);
56 usb_set_intfdata(pusb_intf, NULL);
57 return;
58 }
59 padapter->fw = firmware;
60 padapter->fw_found = true;
61 /* firmware available - start netdev */
62 register_netdev(padapter->pnetdev);
63}
64
65static const char firmware_file[] = "rtlwifi/rtl8712u.bin";
66
67int rtl871x_load_fw(struct _adapter *padapter)
68{
69 struct device *dev = &padapter->dvobjpriv.pusbdev->dev;
48 int rc; 70 int rc;
49 const char firmware_file[] = "rtlwifi/rtl8712u.bin";
50 const struct firmware **praw = (const struct firmware **)
51 (pphfwfile_hdl);
52 struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)
53 (&padapter->dvobjpriv);
54 struct usb_device *pusbdev = pdvobjpriv->pusbdev;
55 71
72 init_completion(&padapter->rtl8712_fw_ready);
56 printk(KERN_INFO "r8712u: Loading firmware from \"%s\"\n", 73 printk(KERN_INFO "r8712u: Loading firmware from \"%s\"\n",
57 firmware_file); 74 firmware_file);
58 rc = request_firmware(praw, firmware_file, &pusbdev->dev); 75 rc = request_firmware_nowait(THIS_MODULE, 1, firmware_file, dev,
59 if (rc < 0) { 76 GFP_KERNEL, padapter, rtl871x_load_fw_cb);
60 printk(KERN_ERR "r8712u: Unable to load firmware\n"); 77 if (rc)
61 printk(KERN_ERR "r8712u: Install latest linux-firmware\n"); 78 printk(KERN_ERR "r8712u: Firmware request error %d\n", rc);
79 return rc;
80}
81MODULE_FIRMWARE("rtlwifi/rtl8712u.bin");
82
83static u32 rtl871x_open_fw(struct _adapter *padapter, const u8 **ppmappedfw)
84{
85 const struct firmware **praw = &padapter->fw;
86
87 if (padapter->fw->size > 200000) {
88 printk(KERN_ERR "r8172u: Badfw->size of %d\n",
89 (int)padapter->fw->size);
62 return 0; 90 return 0;
63 } 91 }
64 *ppmappedfw = (u8 *)((*praw)->data); 92 *ppmappedfw = (u8 *)((*praw)->data);
65 return (*praw)->size; 93 return (*praw)->size;
66} 94}
67MODULE_FIRMWARE("rtlwifi/rtl8712u.bin");
68 95
69static void fill_fwpriv(struct _adapter *padapter, struct fw_priv *pfwpriv) 96static void fill_fwpriv(struct _adapter *padapter, struct fw_priv *pfwpriv)
70{ 97{
@@ -142,18 +169,17 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter)
142 uint dump_imem_sz, imem_sz, dump_emem_sz, emem_sz; /* max = 49152; */ 169 uint dump_imem_sz, imem_sz, dump_emem_sz, emem_sz; /* max = 49152; */
143 struct fw_hdr fwhdr; 170 struct fw_hdr fwhdr;
144 u32 ulfilelength; /* FW file size */ 171 u32 ulfilelength; /* FW file size */
145 void *phfwfile_hdl = NULL;
146 const u8 *pmappedfw = NULL; 172 const u8 *pmappedfw = NULL;
147 u8 *ptmpchar = NULL, *ppayload, *ptr; 173 u8 *ptmpchar = NULL, *ppayload, *ptr;
148 struct tx_desc *ptx_desc; 174 struct tx_desc *ptx_desc;
149 u32 txdscp_sz = sizeof(struct tx_desc); 175 u32 txdscp_sz = sizeof(struct tx_desc);
150 u8 ret = _FAIL; 176 u8 ret = _FAIL;
151 177
152 ulfilelength = rtl871x_open_fw(padapter, &phfwfile_hdl, &pmappedfw); 178 ulfilelength = rtl871x_open_fw(padapter, &pmappedfw);
153 if (pmappedfw && (ulfilelength > 0)) { 179 if (pmappedfw && (ulfilelength > 0)) {
154 update_fwhdr(&fwhdr, pmappedfw); 180 update_fwhdr(&fwhdr, pmappedfw);
155 if (chk_fwhdr(&fwhdr, ulfilelength) == _FAIL) 181 if (chk_fwhdr(&fwhdr, ulfilelength) == _FAIL)
156 goto firmware_rel; 182 return ret;
157 fill_fwpriv(padapter, &fwhdr.fwpriv); 183 fill_fwpriv(padapter, &fwhdr.fwpriv);
158 /* firmware check ok */ 184 /* firmware check ok */
159 maxlen = (fwhdr.img_IMEM_size > fwhdr.img_SRAM_size) ? 185 maxlen = (fwhdr.img_IMEM_size > fwhdr.img_SRAM_size) ?
@@ -161,7 +187,7 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter)
161 maxlen += txdscp_sz; 187 maxlen += txdscp_sz;
162 ptmpchar = _malloc(maxlen + FWBUFF_ALIGN_SZ); 188 ptmpchar = _malloc(maxlen + FWBUFF_ALIGN_SZ);
163 if (ptmpchar == NULL) 189 if (ptmpchar == NULL)
164 goto firmware_rel; 190 return ret;
165 191
166 ptx_desc = (struct tx_desc *)(ptmpchar + FWBUFF_ALIGN_SZ - 192 ptx_desc = (struct tx_desc *)(ptmpchar + FWBUFF_ALIGN_SZ -
167 ((addr_t)(ptmpchar) & (FWBUFF_ALIGN_SZ - 1))); 193 ((addr_t)(ptmpchar) & (FWBUFF_ALIGN_SZ - 1)));
@@ -297,8 +323,6 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter)
297 323
298exit_fail: 324exit_fail:
299 kfree(ptmpchar); 325 kfree(ptmpchar);
300firmware_rel:
301 release_firmware((struct firmware *)phfwfile_hdl);
302 return ret; 326 return ret;
303} 327}
304 328