net: usb: Define waitqueue head as static global variable

usbnet_terminate_urbs() defines waitqueue head as local variable.
There is a possibility that wake_up is called on this queue head
in workqueue context and usbnet_terminate_urbs() already returned
or dev->wait pointer becomes NULL while calling wake_up() from
workqueue context. Hence call wake_up() using waitqueue head
defined as static global variable.

Change-Id: I672460533d25589912a847acad2df01f193a120d
CRs-Fixed: 388724
Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
Signed-off-by: Neha Pandey <nehap@codeaurora.org>
This commit is contained in:
Hemant Kumar 2012-08-15 16:57:00 -07:00 committed by Stephen Boyd
parent 9a9df70ee9
commit aa77957e31

View file

@ -88,6 +88,8 @@ static const char driver_name [] = "usbnet";
static struct workqueue_struct *usbnet_wq;
static DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup);
/* use ethtool to change the level for any given device */
static int msg_level = -1;
module_param (msg_level, int, 0);
@ -660,7 +662,6 @@ EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs);
// precondition: never called in_interrupt
static void usbnet_terminate_urbs(struct usbnet *dev)
{
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup);
DECLARE_WAITQUEUE(wait, current);
int temp;
@ -1236,7 +1237,7 @@ static void usbnet_bh (unsigned long param)
// waiting for all pending urbs to complete?
if (dev->wait) {
if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) {
wake_up (dev->wait);
wake_up(&unlink_wakeup);
}
// or are we maybe short a few urbs?