aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/orinoco.c
diff options
context:
space:
mode:
authorAndrey Borzenkov <arvidjaar@mail.ru>2008-10-19 04:06:11 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-10-31 19:02:34 -0400
commit4fb30784c720b863203957f76e3fde0d53932746 (patch)
tree9fe63bca9701dcc2a5ee6e6d492e022cbadfb6e5 /drivers/net/wireless/orinoco.c
parent0df6cbb7d8a0a8fea69138e9e463671a8ad99f16 (diff)
orinoco: cache downloadable firmware image in memory for use during resume
If card is using downloadable firmware (like Agere 9.x), firmware has to be reloaded during resume. It is not possible to use request_firmware for that, because tasks are still frozen, so request_firmware will just timeout and fail. So cache firmware image in memory for later reuse in ->resume method. Signed-off-by: Andrey Borzenkov <arvidjaar@mail.ru> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/orinoco.c')
-rw-r--r--drivers/net/wireless/orinoco.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 7bd1559e8711..5a39166e2a0f 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -487,12 +487,17 @@ orinoco_dl_firmware(struct orinoco_private *priv,
487 if (err) 487 if (err)
488 goto free; 488 goto free;
489 489
490 err = request_firmware(&fw_entry, firmware, priv->dev); 490 if (priv->cached_fw)
491 if (err) { 491 fw_entry = priv->cached_fw;
492 printk(KERN_ERR "%s: Cannot find firmware %s\n", 492 else {
493 dev->name, firmware); 493 err = request_firmware(&fw_entry, firmware, priv->dev);
494 err = -ENOENT; 494 if (err) {
495 goto free; 495 printk(KERN_ERR "%s: Cannot find firmware %s\n",
496 dev->name, firmware);
497 err = -ENOENT;
498 goto free;
499 }
500 priv->cached_fw = fw_entry;
496 } 501 }
497 502
498 hdr = (const struct orinoco_fw_header *) fw_entry->data; 503 hdr = (const struct orinoco_fw_header *) fw_entry->data;
@@ -535,7 +540,11 @@ orinoco_dl_firmware(struct orinoco_private *priv,
535 dev->name, hermes_present(hw)); 540 dev->name, hermes_present(hw));
536 541
537abort: 542abort:
538 release_firmware(fw_entry); 543 /* In case of error, assume firmware was bogus and release it */
544 if (err) {
545 priv->cached_fw = NULL;
546 release_firmware(fw_entry);
547 }
539 548
540free: 549free:
541 kfree(pda); 550 kfree(pda);
@@ -3532,6 +3541,8 @@ struct net_device
3532 netif_carrier_off(dev); 3541 netif_carrier_off(dev);
3533 priv->last_linkstatus = 0xffff; 3542 priv->last_linkstatus = 0xffff;
3534 3543
3544 priv->cached_fw = NULL;
3545
3535 return dev; 3546 return dev;
3536} 3547}
3537 3548
@@ -3543,6 +3554,9 @@ void free_orinocodev(struct net_device *dev)
3543 * when we call tasklet_kill it will run one final time, 3554 * when we call tasklet_kill it will run one final time,
3544 * emptying the list */ 3555 * emptying the list */
3545 tasklet_kill(&priv->rx_tasklet); 3556 tasklet_kill(&priv->rx_tasklet);
3557 if (priv->cached_fw)
3558 release_firmware(priv->cached_fw);
3559 priv->cached_fw = NULL;
3546 priv->wpa_ie_len = 0; 3560 priv->wpa_ie_len = 0;
3547 kfree(priv->wpa_ie); 3561 kfree(priv->wpa_ie);
3548 orinoco_mic_free(priv); 3562 orinoco_mic_free(priv);