diff options
| author | Alexey Khoroshilov <khoroshilov@ispras.ru> | 2013-07-23 16:20:17 -0400 |
|---|---|---|
| committer | Felipe Balbi <balbi@ti.com> | 2013-09-17 11:38:48 -0400 |
| commit | 2389df458b9e8222ef54fbb6e7023ead84b87a5c (patch) | |
| tree | 7af474c2118894f586b67aebd494fa3d216e844f | |
| parent | 272b98c6455f00884f0350f775c5342358ebb73f (diff) | |
usb: gadget: mv_u3d_core: fix violation of locking discipline in mv_u3d_ep_disable()
mv_u3d_nuke() expects to be calles with ep->u3d->lock held,
because mv_u3d_done() does. But mv_u3d_ep_disable() calls it
without lock that can lead to unpleasant consequences.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
Signed-off-by: Felipe Balbi <balbi@ti.com>
| -rw-r--r-- | drivers/usb/gadget/mv_u3d_core.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/usb/gadget/mv_u3d_core.c b/drivers/usb/gadget/mv_u3d_core.c index bbb6e98c4384..561b30efb8ee 100644 --- a/drivers/usb/gadget/mv_u3d_core.c +++ b/drivers/usb/gadget/mv_u3d_core.c | |||
| @@ -645,6 +645,7 @@ static int mv_u3d_ep_disable(struct usb_ep *_ep) | |||
| 645 | struct mv_u3d_ep *ep; | 645 | struct mv_u3d_ep *ep; |
| 646 | struct mv_u3d_ep_context *ep_context; | 646 | struct mv_u3d_ep_context *ep_context; |
| 647 | u32 epxcr, direction; | 647 | u32 epxcr, direction; |
| 648 | unsigned long flags; | ||
| 648 | 649 | ||
| 649 | if (!_ep) | 650 | if (!_ep) |
| 650 | return -EINVAL; | 651 | return -EINVAL; |
| @@ -661,7 +662,9 @@ static int mv_u3d_ep_disable(struct usb_ep *_ep) | |||
| 661 | direction = mv_u3d_ep_dir(ep); | 662 | direction = mv_u3d_ep_dir(ep); |
| 662 | 663 | ||
| 663 | /* nuke all pending requests (does flush) */ | 664 | /* nuke all pending requests (does flush) */ |
| 665 | spin_lock_irqsave(&u3d->lock, flags); | ||
| 664 | mv_u3d_nuke(ep, -ESHUTDOWN); | 666 | mv_u3d_nuke(ep, -ESHUTDOWN); |
| 667 | spin_unlock_irqrestore(&u3d->lock, flags); | ||
| 665 | 668 | ||
| 666 | /* Disable the endpoint for Rx or Tx and reset the endpoint type */ | 669 | /* Disable the endpoint for Rx or Tx and reset the endpoint type */ |
| 667 | if (direction == MV_U3D_EP_DIR_OUT) { | 670 | if (direction == MV_U3D_EP_DIR_OUT) { |
