diff options
author | Hante Meuleman <meuleman@broadcom.com> | 2012-09-27 08:17:47 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-09-28 13:54:07 -0400 |
commit | 70398a59297965d4af1a0022660bb103dfa59c42 (patch) | |
tree | de81f9168717b00868f8188def8a2e6982d9b881 /drivers/net/wireless | |
parent | 2d838bb608e2d1f6cb4280e76748cb812dc822e7 (diff) |
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: Arend Van Spriel <arend@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/usb.c | 46 |
1 files changed, 9 insertions, 37 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 5fe6ec7f838e..555ccdd12210 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) | |||
160 | return brcmf_usb_get_buspub(dev)->devinfo; | 160 | return brcmf_usb_get_buspub(dev)->devinfo; |
161 | } | 161 | } |
162 | 162 | ||
163 | static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo, | 163 | static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo) |
164 | uint *condition, bool *pending) | ||
165 | { | 164 | { |
166 | DECLARE_WAITQUEUE(wait, current); | 165 | return wait_event_timeout(devinfo->ioctl_resp_wait, |
167 | int timeout = IOCTL_RESP_TIMEOUT; | 166 | devinfo->ctl_completed, |
168 | 167 | msecs_to_jiffies(IOCTL_RESP_TIMEOUT)); | |
169 | /* Convert timeout in millsecond to jiffies */ | ||
170 | timeout = msecs_to_jiffies(timeout); | ||
171 | /* Wait until control frame is available */ | ||
172 | add_wait_queue(&devinfo->ioctl_resp_wait, &wait); | ||
173 | set_current_state(TASK_INTERRUPTIBLE); | ||
174 | |||
175 | smp_mb(); | ||
176 | while (!(*condition) && (!signal_pending(current) && timeout)) { | ||
177 | timeout = schedule_timeout(timeout); | ||
178 | /* Wait until control frame is available */ | ||
179 | smp_mb(); | ||
180 | } | ||
181 | |||
182 | if (signal_pending(current)) | ||
183 | *pending = true; | ||
184 | |||
185 | set_current_state(TASK_RUNNING); | ||
186 | remove_wait_queue(&devinfo->ioctl_resp_wait, &wait); | ||
187 | |||
188 | return timeout; | ||
189 | } | 168 | } |
190 | 169 | ||
191 | static int brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo) | 170 | static void brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo) |
192 | { | 171 | { |
193 | if (waitqueue_active(&devinfo->ioctl_resp_wait)) | 172 | if (waitqueue_active(&devinfo->ioctl_resp_wait)) |
194 | wake_up_interruptible(&devinfo->ioctl_resp_wait); | 173 | wake_up(&devinfo->ioctl_resp_wait); |
195 | |||
196 | return 0; | ||
197 | } | 174 | } |
198 | 175 | ||
199 | static void | 176 | static void |
@@ -322,7 +299,6 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len) | |||
322 | { | 299 | { |
323 | int err = 0; | 300 | int err = 0; |
324 | int timeout = 0; | 301 | int timeout = 0; |
325 | bool pending; | ||
326 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); | 302 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); |
327 | 303 | ||
328 | if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { | 304 | 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) | |||
340 | clear_bit(0, &devinfo->ctl_op); | 316 | clear_bit(0, &devinfo->ctl_op); |
341 | return err; | 317 | return err; |
342 | } | 318 | } |
343 | 319 | timeout = brcmf_usb_ioctl_resp_wait(devinfo); | |
344 | timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed, | ||
345 | &pending); | ||
346 | clear_bit(0, &devinfo->ctl_op); | 320 | clear_bit(0, &devinfo->ctl_op); |
347 | if (!timeout) { | 321 | if (!timeout) { |
348 | brcmf_dbg(ERROR, "Txctl wait timed out\n"); | 322 | 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) | |||
355 | { | 329 | { |
356 | int err = 0; | 330 | int err = 0; |
357 | int timeout = 0; | 331 | int timeout = 0; |
358 | bool pending; | ||
359 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); | 332 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); |
360 | 333 | ||
361 | if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { | 334 | 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) | |||
365 | if (test_and_set_bit(0, &devinfo->ctl_op)) | 338 | if (test_and_set_bit(0, &devinfo->ctl_op)) |
366 | return -EIO; | 339 | return -EIO; |
367 | 340 | ||
341 | devinfo->ctl_completed = false; | ||
368 | err = brcmf_usb_recv_ctl(devinfo, buf, len); | 342 | err = brcmf_usb_recv_ctl(devinfo, buf, len); |
369 | if (err) { | 343 | if (err) { |
370 | brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len); | 344 | brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len); |
371 | clear_bit(0, &devinfo->ctl_op); | 345 | clear_bit(0, &devinfo->ctl_op); |
372 | return err; | 346 | return err; |
373 | } | 347 | } |
374 | devinfo->ctl_completed = false; | 348 | timeout = brcmf_usb_ioctl_resp_wait(devinfo); |
375 | timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed, | ||
376 | &pending); | ||
377 | err = devinfo->ctl_urb_status; | 349 | err = devinfo->ctl_urb_status; |
378 | clear_bit(0, &devinfo->ctl_op); | 350 | clear_bit(0, &devinfo->ctl_op); |
379 | if (!timeout) { | 351 | if (!timeout) { |