From: Andrey Borzenkov <arvidjaar@mail.ru>
To: orinoco-devel@lists.sourceforge.net
Cc: linux-wireless@vger.kernel.org
Subject: [PATCH 2/2] orinoco: cache downloadable firmware image in memory for use during resume
Date: Sat, 11 Oct 2008 18:21:33 +0400 [thread overview]
Message-ID: <200810111821.34045.arvidjaar@mail.ru> (raw)
In-Reply-To: <200810111816.26370.arvidjaar@mail.ru>
[-- Attachment #1: Type: text/plain, Size: 4170 bytes --]
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>
---
Unfortunately this is the only way to do it given current infrastructure.
I think that extra memory cost (~60kb) does not warrant anything more
sophisticated - even if this is possible. Also users not using dowloadable
firmware won't be penalized at all.
drivers/net/wireless/orinoco.c | 42 ++++++++++++++++++++++++++++++----------
drivers/net/wireless/orinoco.h | 4 ++++
2 files changed, 35 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 76c480b..204b2a6 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -487,15 +487,25 @@ orinoco_dl_firmware(struct orinoco_private *priv,
if (err)
goto free;
- err = request_firmware(&fw_entry, firmware, priv->dev);
- if (err) {
- printk(KERN_ERR "%s: Cannot find firmware %s\n",
- dev->name, firmware);
- err = -ENOENT;
- goto free;
+ if (!priv->cached_fw_data) {
+ err = request_firmware(&fw_entry, firmware, priv->dev);
+ if (err) {
+ printk(KERN_ERR "%s: Cannot find firmware %s\n",
+ dev->name, firmware);
+ err = -ENOENT;
+ goto free;
+ }
+ priv->cached_fw_size = fw_entry->size;
+ priv->cached_fw_data = kmemdup(fw_entry->data, fw_entry->size,
+ GFP_KERNEL);
+ release_firmware(fw_entry);
+ if (!priv->cached_fw_data) {
+ err = -ENOMEM;
+ goto abort;
+ }
}
- hdr = (const struct orinoco_fw_header *) fw_entry->data;
+ hdr = (const struct orinoco_fw_header *) priv->cached_fw_data;
/* Enable aux port to allow programming */
err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point));
@@ -504,10 +514,10 @@ orinoco_dl_firmware(struct orinoco_private *priv,
goto abort;
/* Program data */
- first_block = (fw_entry->data +
+ first_block = (priv->cached_fw_data +
le16_to_cpu(hdr->headersize) +
le32_to_cpu(hdr->block_offset));
- end = fw_entry->data + fw_entry->size;
+ end = priv->cached_fw_data + priv->cached_fw_size;
err = hermes_program(hw, first_block, end);
printk(KERN_DEBUG "%s: Program returned %d\n", dev->name, err);
@@ -515,7 +525,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
goto abort;
/* Update production data */
- first_block = (fw_entry->data +
+ first_block = (priv->cached_fw_data +
le16_to_cpu(hdr->headersize) +
le32_to_cpu(hdr->pdr_offset));
@@ -535,7 +545,13 @@ orinoco_dl_firmware(struct orinoco_private *priv,
dev->name, hermes_present(hw));
abort:
- release_firmware(fw_entry);
+
+ /* If downloading failed, destroy cached copy */
+ if (err) {
+ priv->cached_fw_size = 0;
+ kfree(priv->cached_fw_data);
+ priv->cached_fw_data = NULL;
+ }
free:
kfree(pda);
@@ -3534,6 +3550,9 @@ struct net_device
netif_carrier_off(dev);
priv->last_linkstatus = 0xffff;
+ priv->cached_fw_size = 0;
+ priv->cached_fw_data = NULL;
+
return dev;
}
@@ -3545,6 +3564,7 @@ void free_orinocodev(struct net_device *dev)
* when we call tasklet_kill it will run one final time,
* emptying the list */
tasklet_kill(&priv->rx_tasklet);
+ kfree(priv->cached_fw_data);
priv->wpa_ie_len = 0;
kfree(priv->wpa_ie);
orinoco_mic_free(priv);
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
index 981570b..403fff8 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -164,6 +164,10 @@ struct orinoco_private {
unsigned int wpa_enabled:1;
unsigned int tkip_cm_active:1;
unsigned int key_mgmt:3;
+
+ /* Cached firmware to use in ->resume */
+ u8 *cached_fw_data;
+ size_t cached_fw_size;
};
#ifdef ORINOCO_DEBUG
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
next prev parent reply other threads:[~2008-10-11 14:21 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-11 14:16 [PATCH 1/2] orinoco: reload firmware on resume Andrey Borzenkov
2008-10-11 14:21 ` Andrey Borzenkov [this message]
2008-10-11 17:59 ` [PATCH 2/2] orinoco: cache downloadable firmware image in memory for use during resume Dave
2008-10-12 17:42 ` Andrey Borzenkov
2008-10-11 17:42 ` [PATCH 1/2] orinoco: reload firmware on resume Dave
2008-10-11 18:34 ` Andrey Borzenkov
2008-10-12 12:36 ` Andrey Borzenkov
2008-10-15 19:31 ` Dave
2008-10-22 18:26 ` John W. Linville
-- strict thread matches above, loose matches on Subject: below --
2008-10-26 8:29 [PATCH 2/2] orinoco: cache downloadable firmware image in memory for use during resume Andrey Borzenkov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200810111821.34045.arvidjaar@mail.ru \
--to=arvidjaar@mail.ru \
--cc=linux-wireless@vger.kernel.org \
--cc=orinoco-devel@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).