Search Linux Wireless

[PATCH 01/11] brcmfmac: use wait_event_timeout for fw control packets over usb.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Hante Meuleman <meuleman@xxxxxxxxxxxx>

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: Arend Van Spriel <arend@xxxxxxxxxxxx>
Signed-off-by: Hante Meuleman <meuleman@xxxxxxxxxxxx>
Signed-off-by: Arend van Spriel <arend@xxxxxxxxxxxx>
---
 drivers/net/wireless/brcm80211/brcmfmac/usb.c |   46 +++++--------------------
 1 file changed, 9 insertions(+), 37 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 5fe6ec7..555ccdd 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -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) {
-- 
1.7.9.5


--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux