Commit 70398a59 authored by Hante Meuleman's avatar Hante Meuleman Committed by John W. Linville
Browse files

brcmfmac: use wait_event_timeout for fw control packets over usb.



firmware control packets over usb are async acked. This is
awaited for by using interruptible wait. This can be
interrupted by signal which results in undesirable behavior.
Instead wait_event_timeout is used.
Reviewed-by: default avatarArend Van Spriel <arend@broadcom.com>
Signed-off-by: default avatarHante Meuleman <meuleman@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 2d838bb6
......@@ -160,40 +160,17 @@ static struct brcmf_usbdev_info *brcmf_usb_get_businfo(struct device *dev)
return brcmf_usb_get_buspub(dev)->devinfo;
}
static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo,
uint *condition, bool *pending)
static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo)
{
DECLARE_WAITQUEUE(wait, current);
int timeout = IOCTL_RESP_TIMEOUT;
/* Convert timeout in millsecond to jiffies */
timeout = msecs_to_jiffies(timeout);
/* Wait until control frame is available */
add_wait_queue(&devinfo->ioctl_resp_wait, &wait);
set_current_state(TASK_INTERRUPTIBLE);
smp_mb();
while (!(*condition) && (!signal_pending(current) && timeout)) {
timeout = schedule_timeout(timeout);
/* Wait until control frame is available */
smp_mb();
}
if (signal_pending(current))
*pending = true;
set_current_state(TASK_RUNNING);
remove_wait_queue(&devinfo->ioctl_resp_wait, &wait);
return timeout;
return wait_event_timeout(devinfo->ioctl_resp_wait,
devinfo->ctl_completed,
msecs_to_jiffies(IOCTL_RESP_TIMEOUT));
}
static int brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo)
static void brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo)
{
if (waitqueue_active(&devinfo->ioctl_resp_wait))
wake_up_interruptible(&devinfo->ioctl_resp_wait);
return 0;
wake_up(&devinfo->ioctl_resp_wait);
}
static void
......@@ -322,7 +299,6 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len)
{
int err = 0;
int timeout = 0;
bool pending;
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
......@@ -340,9 +316,7 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len)
clear_bit(0, &devinfo->ctl_op);
return err;
}
timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
&pending);
timeout = brcmf_usb_ioctl_resp_wait(devinfo);
clear_bit(0, &devinfo->ctl_op);
if (!timeout) {
brcmf_dbg(ERROR, "Txctl wait timed out\n");
......@@ -355,7 +329,6 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
{
int err = 0;
int timeout = 0;
bool pending;
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
......@@ -365,15 +338,14 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
if (test_and_set_bit(0, &devinfo->ctl_op))
return -EIO;
devinfo->ctl_completed = false;
err = brcmf_usb_recv_ctl(devinfo, buf, len);
if (err) {
brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len);
clear_bit(0, &devinfo->ctl_op);
return err;
}
devinfo->ctl_completed = false;
timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
&pending);
timeout = brcmf_usb_ioctl_resp_wait(devinfo);
err = devinfo->ctl_urb_status;
clear_bit(0, &devinfo->ctl_op);
if (!timeout) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment