提交 4f82f5c8 编写于 作者: D David Woodhouse 提交者: David S. Miller

libertas: switch to a waitqueue and timer for handling USB firmware load

No need to busy-wait, even if we did have a 100ms delay in the loop.
This makes it easier to support the new 'firmware ready' event which is
in the new firmware, too.
Signed-off-by: NDavid Woodhouse <dwmw2@infradead.org>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 c8ba39d0
...@@ -113,7 +113,18 @@ static void if_usb_set_boot2_ver(struct lbs_private *priv) ...@@ -113,7 +113,18 @@ static void if_usb_set_boot2_ver(struct lbs_private *priv)
lbs_deb_usb("Setting boot2 version failed\n"); lbs_deb_usb("Setting boot2 version failed\n");
} }
void if_usb_fw_timeo(unsigned long priv)
{
struct usb_card_rec *cardp = (void *)priv;
if (cardp->fwdnldover) {
lbs_deb_usb("Download complete, no event. Assuming success\n");
} else {
lbs_pr_err("Download timed out\n");
cardp->surprise_removed = 1;
}
wake_up(&cardp->fw_wq);
}
/** /**
* @brief sets the configuration values * @brief sets the configuration values
* @param ifnum interface number * @param ifnum interface number
...@@ -138,6 +149,9 @@ static int if_usb_probe(struct usb_interface *intf, ...@@ -138,6 +149,9 @@ static int if_usb_probe(struct usb_interface *intf,
goto error; goto error;
} }
setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp);
init_waitqueue_head(&cardp->fw_wq);
cardp->udev = udev; cardp->udev = udev;
iface_desc = intf->cur_altsetting; iface_desc = intf->cur_altsetting;
...@@ -296,7 +310,7 @@ static void if_usb_disconnect(struct usb_interface *intf) ...@@ -296,7 +310,7 @@ static void if_usb_disconnect(struct usb_interface *intf)
* @param priv pointer to struct lbs_private * @param priv pointer to struct lbs_private
* @return 0 * @return 0
*/ */
static int if_prog_firmware(struct usb_card_rec *cardp) static int if_usb_send_fw_pkt(struct usb_card_rec *cardp)
{ {
struct FWData *fwdata; struct FWData *fwdata;
struct fwheader *fwheader; struct fwheader *fwheader;
...@@ -566,19 +580,21 @@ static void if_usb_receive_fwload(struct urb *urb) ...@@ -566,19 +580,21 @@ static void if_usb_receive_fwload(struct urb *urb)
kfree_skb(skb); kfree_skb(skb);
/* reschedule timer for 200ms hence */
mod_timer(&cardp->fw_timeout, jiffies + (HZ/5));
if (cardp->fwfinalblk) { if (cardp->fwfinalblk) {
cardp->fwdnldover = 1; cardp->fwdnldover = 1;
goto exit; goto exit;
} }
if_prog_firmware(cardp); if_usb_send_fw_pkt(cardp);
if_usb_submit_rx_urb_fwload(cardp); if_usb_submit_rx_urb_fwload(cardp);
exit: exit:
kfree(syncfwheader); kfree(syncfwheader);
return; return;
} }
#define MRVDRV_MIN_PKT_LEN 30 #define MRVDRV_MIN_PKT_LEN 30
...@@ -911,15 +927,13 @@ static int if_usb_prog_firmware(struct usb_card_rec *cardp) ...@@ -911,15 +927,13 @@ static int if_usb_prog_firmware(struct usb_card_rec *cardp)
cardp->totalbytes = 0; cardp->totalbytes = 0;
cardp->fwfinalblk = 0; cardp->fwfinalblk = 0;
if_prog_firmware(cardp); /* Send the first firmware packet... */
if_usb_send_fw_pkt(cardp);
do { /* ... and wait for the process to complete */
lbs_deb_usbd(&cardp->udev->dev,"Wlan sched timeout\n"); wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover);
i++;
msleep_interruptible(100); del_timer_sync(&cardp->fw_timeout);
if (cardp->surprise_removed || i >= 20)
break;
} while (!cardp->fwdnldover);
if (!cardp->fwdnldover) { if (!cardp->fwdnldover) {
lbs_pr_info("failed to load fw, resetting device!\n"); lbs_pr_info("failed to load fw, resetting device!\n");
......
#ifndef _LBS_IF_USB_H #ifndef _LBS_IF_USB_H
#define _LBS_IF_USB_H #define _LBS_IF_USB_H
#include <linux/wait.h>
#include <linux/timer.h>
/** /**
* This file contains definition for USB interface. * This file contains definition for USB interface.
*/ */
...@@ -56,6 +59,8 @@ struct usb_card_rec { ...@@ -56,6 +59,8 @@ struct usb_card_rec {
u8 bulk_out_endpointAddr; u8 bulk_out_endpointAddr;
const struct firmware *fw; const struct firmware *fw;
struct timer_list fw_timeout;
wait_queue_head_t fw_wq;
u8 CRC_OK; u8 CRC_OK;
u32 fwseqnum; u32 fwseqnum;
u32 lastseqnum; u32 lastseqnum;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册