libertas: resend initial boot command in case of non-response
Marcelo Tosatti
mtosatti at redhat.unroutablecom
Sun Dec 24 04:30:49 EST 2006
Commit: cad10c43037fc9688a7d69aaf83e9e5746ecf8bc
Parent: 261e40bb213130e55969e5df01180ede8fa12051
commit cad10c43037fc9688a7d69aaf83e9e5746ecf8bc
Author: Marcelo Tosatti <mtosatti at redhat.com>
AuthorDate: Sat Dec 23 20:31:51 2006 -0200
Commit: Marcelo Tosatti <mtosatti at redhat.com>
CommitDate: Sat Dec 23 20:31:51 2006 -0200
libertas: resend initial boot command in case of non-response
Workaround unknown problem in which the command is "lost" in the USB
bus. Appears to be specific to the Geode.
Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
---
drivers/net/wireless/libertas/if_bootcmd.c | 12 +------
drivers/net/wireless/libertas/if_usb.c | 51 ++++++++++++++++++++++++----
drivers/net/wireless/libertas/if_usb.h | 2 +
3 files changed, 45 insertions(+), 20 deletions(-)
diff --git a/drivers/net/wireless/libertas/if_bootcmd.c b/drivers/net/wireless/libertas/if_bootcmd.c
index 435d30d..87393e7 100644
--- a/drivers/net/wireless/libertas/if_bootcmd.c
+++ b/drivers/net/wireless/libertas/if_bootcmd.c
@@ -55,8 +55,8 @@ extern struct BootCMDStr sBootCMD;
*/
int if_usb_issue_boot_command(wlan_private *priv, int iValue)
{
- int i = 0;
struct usb_card_rec *cardp = priv->wlan_dev.card;
+ int i;
/* Prepare Command */
sBootCMD.u32MagicNumber = BOOT_CMD_MAGIC_NUMBER;
@@ -66,17 +66,7 @@ int if_usb_issue_boot_command(wlan_priva
memcpy(cardp->bulk_out_buffer, &sBootCMD, sizeof(struct BootCMDStr));
/* Issue Command */
- cardp->BootCMDACK = 0;
- i = 0;
usb_tx_block(priv, cardp->bulk_out_buffer, sizeof(struct BootCMDStr));
- /* Wait for the Reault */
- do {
- i ++;
- msleep_interruptible(100);
- if (priv->adapter->SurpriseRemoved || i>=20)
- break;
- } while (!cardp->BootCMDACK);
-
return WLAN_STATUS_SUCCESS;
}
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 3c979b2..d88c675 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -112,7 +112,6 @@ static void if_usb_write_bulk_callback(s
wlan_private *priv = (wlan_private *) (urb->context);
wlan_adapter *adapter = priv->adapter;
struct net_device *dev = priv->wlan_dev.netdev;
- struct usb_card_rec *cardp = priv->wlan_dev.card;
/* handle the transmission complete validations */
@@ -131,8 +130,6 @@ static void if_usb_write_bulk_callback(s
netif_wake_queue(dev);
}
- cardp->BootCMDACK = 1;
-
return;
}
@@ -453,6 +450,7 @@ rx_ret:
return ret;
}
+struct BootCMDRespStr bootcmdresp;
static void if_usb_receive_fwload(struct urb *urb)
{
@@ -470,6 +468,30 @@ static void if_usb_receive_fwload(struct
return;
}
+ if (cardp->BootCMDResp == 0) {
+ memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET,
+ sizeof(bootcmdresp));
+ if (bootcmdresp.u32MagicNumber != BOOT_CMD_MAGIC_NUMBER) {
+ printk(KERN_INFO
+ "boot cmd response wrong magic number (0x%x)\n",
+ bootcmdresp.u32MagicNumber);
+ } else if (bootcmdresp.u8CMD_Tag != BOOT_CMD_FW_BY_USB) {
+ printk(KERN_INFO
+ "boot cmd response cmd_tag error (%d)\n",
+ bootcmdresp.u8CMD_Tag);
+ } else if (bootcmdresp.u8Result != BOOT_CMD_RESP_OK) {
+ printk(KERN_INFO
+ "boot cmd response result error (%d)\n",
+ bootcmdresp.u8Result);
+ } else {
+ cardp->BootCMDResp = 1;
+ dprintk(1, "Received valid boot command response\n");
+ }
+ kfree_skb(skb);
+ if_usb_submit_rx_urb_fwload(priv);
+ return;
+ }
+
SyncFWHeader = kmalloc(sizeof(struct FWSyncHeader), GFP_ATOMIC);
if (!SyncFWHeader) {
dprintk(1, "Failure to allocate SyncFWHeader\n");
@@ -875,17 +897,30 @@ int libertas_sbi_prog_firmware(wlan_priv
ENTER();
-#ifdef SUPPORT_BOOT_COMMAND
- /* Issue Boot command = 1, Boot from Download-FW */
- if_usb_issue_boot_command(priv, BOOT_CMD_FW_BY_USB);
-#endif
-
if (if_usb_submit_rx_urb_fwload(priv) < 0) {
dprintk(1, "URB submission is failed\n");
LEAVE();
return WLAN_STATUS_FAILURE;
}
+#ifdef SUPPORT_BOOT_COMMAND
+ cardp->BootCMDResp = 0;
+ do {
+ int j = 0;
+ i++;
+ /* Issue Boot command = 1, Boot from Download-FW */
+ if_usb_issue_boot_command(priv, BOOT_CMD_FW_BY_USB);
+ /* wait for command response */
+ do {
+ j++;
+ msleep_interruptible(100);
+ } while (cardp->BootCMDResp == 0 && j < 10);
+ } while (cardp->BootCMDResp == 0 && i < 5);
+
+ if (cardp->BootCMDResp == 0)
+ return WLAN_STATUS_FAILURE;
+#endif
+
restart:
i = 0;
priv->adapter->fw_ready = 0;
diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h
index c938baa..6e7d836 100644
--- a/drivers/net/wireless/libertas/if_usb.h
+++ b/drivers/net/wireless/libertas/if_usb.h
@@ -90,7 +90,7 @@ struct usb_card_rec {
u8 rx_urb_recall;
- u8 BootCMDACK;
+ u8 BootCMDResp;
};
typedef void *(*usb_notifier_fn_add) (struct usb_card_rec *);
More information about the Commits-kernel
mailing list