aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/net/wireless/orinoco.c28
-rw-r--r--drivers/net/wireless/orinoco.h5
2 files changed, 26 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);
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
index 981570bd3b9d..8c2953834923 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -66,6 +66,8 @@ struct orinoco_rx_data {
66 struct list_head list; 66 struct list_head list;
67}; 67};
68 68
69struct firmware;
70
69struct orinoco_private { 71struct orinoco_private {
70 void *card; /* Pointer to card dependent structure */ 72 void *card; /* Pointer to card dependent structure */
71 struct device *dev; 73 struct device *dev;
@@ -164,6 +166,9 @@ struct orinoco_private {
164 unsigned int wpa_enabled:1; 166 unsigned int wpa_enabled:1;
165 unsigned int tkip_cm_active:1; 167 unsigned int tkip_cm_active:1;
166 unsigned int key_mgmt:3; 168 unsigned int key_mgmt:3;
169
170 /* Cached in memory firmware to use in ->resume */
171 const struct firmware *cached_fw;
167}; 172};
168 173
169#ifdef ORINOCO_DEBUG 174#ifdef ORINOCO_DEBUG