aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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