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) { |