linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] orinoco: reload firmware on resume
@ 2008-10-11 14:16 Andrey Borzenkov
  2008-10-11 14:21 ` [PATCH 2/2] orinoco: cache downloadable firmware image in memory for use during resume Andrey Borzenkov
  2008-10-11 17:42 ` [PATCH 1/2] orinoco: reload firmware on resume Dave
  0 siblings, 2 replies; 10+ messages in thread
From: Andrey Borzenkov @ 2008-10-11 14:16 UTC (permalink / raw)
  To: orinoco-devel, linux-wireless

[-- Attachment #1: Type: text/plain, Size: 1305 bytes --]

On resume card state is likely lost so we have to reload firmware
again.

Signed-off-by: Andrey Borzenkov <arvidjaar@mail.ru>

---

This is non-functional without second patch. Currently you simply
have no way to load request firmware from user space in ->resume.

 drivers/net/wireless/orinoco.c |   13 ++++++-------
 1 files changed, 6 insertions(+), 7 deletions(-)


diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 1f9dcc4..76c480b 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -2298,9 +2298,14 @@ int orinoco_reinit_firmware(struct net_device *dev)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	struct hermes *hw = &priv->hw;
-	int err;
+	int err = 0;
 
 	err = hermes_init(hw);
+	if (priv->do_fw_download && !err) {
+		err = orinoco_download(priv);
+		if (err)
+			priv->do_fw_download = 0;
+	}
 	if (!err)
 		err = orinoco_allocate_fid(dev);
 
@@ -2926,12 +2931,6 @@ static void orinoco_reset(struct work_struct *work)
 		}
 	}
 
-	if (priv->do_fw_download) {
-		err = orinoco_download(priv);
-		if (err)
-			priv->do_fw_download = 0;
-	}
-
 	err = orinoco_reinit_firmware(dev);
 	if (err) {
 		printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply related	[flat|nested] 10+ messages in thread
* [PATCH 2/2] orinoco: cache downloadable firmware image in memory for use during resume
@ 2008-10-26  8:29 Andrey Borzenkov
  0 siblings, 0 replies; 10+ messages in thread
From: Andrey Borzenkov @ 2008-10-26  8:29 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel

[-- Attachment #1: Type: text/plain, Size: 3459 bytes --]

From: Andrey Borzenkov <arvidjaar@mail.ru>
Date: Sun, 19 Oct 2008 12:06:11 +0400
Subject: [PATCH 2/2] 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>
---

This version transparently works both with external and built-in firmware.
In case of built in extra overhead is one "struct firmware".

spectrum_cs has used delayed work to reset card after resume. After
reading multiple discussions on lkml I got impression, that this is
unreliable - there is no way to sycnronize delayed task with unfreezing
of user space.

 drivers/net/wireless/orinoco.c |   28 +++++++++++++++++++++-------
 drivers/net/wireless/orinoco.h |    5 +++++
 2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 860803e..653306f 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -487,12 +487,17 @@ 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)
+		fw_entry = priv->cached_fw;
+	else {
+		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 = fw_entry;
 	}
 
 	hdr = (const struct orinoco_fw_header *) fw_entry->data;
@@ -535,7 +540,11 @@ orinoco_dl_firmware(struct orinoco_private *priv,
 	       dev->name, hermes_present(hw));
 
 abort:
-	release_firmware(fw_entry);
+	/* In case of error, assume firmware was bogus and release it */
+	if (err) {
+		priv->cached_fw = NULL;
+		release_firmware(fw_entry);
+	}
 
 free:
 	kfree(pda);
@@ -3534,6 +3543,8 @@ struct net_device
 	netif_carrier_off(dev);
 	priv->last_linkstatus = 0xffff;
 
+	priv->cached_fw = NULL;
+
 	return dev;
 }
 
@@ -3545,6 +3556,9 @@ 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);
+	if (priv->cached_fw)
+		release_firmware(priv->cached_fw);
+	priv->cached_fw = NULL;
 	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..8c29538 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -66,6 +66,8 @@ struct orinoco_rx_data {
 	struct list_head list;
 };
 
+struct firmware;
+
 struct orinoco_private {
 	void *card;	/* Pointer to card dependent structure */
 	struct device *dev;
@@ -164,6 +166,9 @@ struct orinoco_private {
 	unsigned int wpa_enabled:1;
 	unsigned int tkip_cm_active:1;
 	unsigned int key_mgmt:3;
+
+	/* Cached in memory firmware to use in ->resume */
+	const struct firmware *cached_fw;
 };
 
 #ifdef ORINOCO_DEBUG
-- 
1.6.0.2


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2008-10-26  8:29 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-11 14:16 [PATCH 1/2] orinoco: reload firmware on resume Andrey Borzenkov
2008-10-11 14:21 ` [PATCH 2/2] orinoco: cache downloadable firmware image in memory for use during resume Andrey Borzenkov
2008-10-11 17:59   ` 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

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).