Commit 25b365ac authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[PATCH] USB: better locking in hcd_endpoint_disable()

You'll recall there was a change to the locking in that code after
it was submitted.  This is a better fix to that issue.

"Obviously correct", though I've not run with this in ages.
parent d09b23c5
......@@ -1293,7 +1293,8 @@ static void hcd_endpoint_disable (struct usb_device *udev, int endpoint)
}
/* then kill any current requests */
spin_lock_irqsave (&hcd_data_lock, flags);
local_irq_save (flags);
spin_lock (&hcd_data_lock);
list_for_each_entry (urb, &dev->urb_list, urb_list) {
int tmp = urb->pipe;
......@@ -1311,13 +1312,13 @@ static void hcd_endpoint_disable (struct usb_device *udev, int endpoint)
if (urb->status != -EINPROGRESS)
continue;
usb_get_urb (urb);
spin_unlock_irqrestore (&hcd_data_lock, flags);
spin_unlock (&hcd_data_lock);
spin_lock_irqsave (&urb->lock, flags);
spin_lock (&urb->lock);
tmp = urb->status;
if (tmp == -EINPROGRESS)
urb->status = -ESHUTDOWN;
spin_unlock_irqrestore (&urb->lock, flags);
spin_unlock (&urb->lock);
/* kick hcd unless it's already returning this */
if (tmp == -EINPROGRESS) {
......@@ -1340,7 +1341,8 @@ static void hcd_endpoint_disable (struct usb_device *udev, int endpoint)
/* list contents may have changed */
goto rescan;
}
spin_unlock_irqrestore (&hcd_data_lock, flags);
spin_unlock (&hcd_data_lock);
local_irq_restore (flags);
/* synchronize with the hardware, so old configuration state
* clears out immediately (and will be freed).
......
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