aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/pxa27x_udc.h
diff options
context:
space:
mode:
authorRobert Jarzmik <robert.jarzmik@free.fr>2010-01-27 12:38:03 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-02 17:54:47 -0500
commit5e23e90f33888769ffe253663cc5f3ea0bb6da49 (patch)
tree9a59d36fdaaecea5eb7fa2d39c655032dc6920a2 /drivers/usb/gadget/pxa27x_udc.h
parentfb088e335d78f866be2e56eac6d500112a96aa11 (diff)
USB: pxa27x_udc: Fix deadlocks on request queueing
As reported by Antonio, there are cases where the ep->lock can be taken twice, triggering a deadlock. The typical sequence is : irq_handler \ -> gadget.complete() \ -> pxa27x_udc.pxa_ep_queue() : ep->lock is taken \ -> gadget.complete() \ -> pxa27x_udc.pxa_ep_queue() : ep->lock is taken ==> *deadlock* The patch fixes this by : - releasing the lock each time gadget.complete() is called - adding a check in handle_ep() to detect a recursive call, in which case the function becomes on no-op. The patch is still not good enough for ep0. For this unique endpoint, another well thought over patch will be needed. Reported-by: Antonio Ospite <ospite@studenti.unina.it> Tested-by: Antonio Ospite <ospite@studenti.unina.it> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> Cc: David Brownell <dbrownell@users.sourceforge.net> Cc: Eric Miao <eric.y.miao@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/pxa27x_udc.h')
-rw-r--r--drivers/usb/gadget/pxa27x_udc.h6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h
index e25225e26586..ff61e4866e8a 100644
--- a/drivers/usb/gadget/pxa27x_udc.h
+++ b/drivers/usb/gadget/pxa27x_udc.h
@@ -318,6 +318,11 @@ struct udc_usb_ep {
318 * @queue: requests queue 318 * @queue: requests queue
319 * @lock: lock to pxa_ep data (queues and stats) 319 * @lock: lock to pxa_ep data (queues and stats)
320 * @enabled: true when endpoint enabled (not stopped by gadget layer) 320 * @enabled: true when endpoint enabled (not stopped by gadget layer)
321 * @in_handle_ep: number of recursions of handle_ep() function
322 * Prevents deadlocks or infinite recursions of types :
323 * irq->handle_ep()->req_done()->req.complete()->pxa_ep_queue()->handle_ep()
324 * or
325 * pxa_ep_queue()->handle_ep()->req_done()->req.complete()->pxa_ep_queue()
321 * @idx: endpoint index (1 => epA, 2 => epB, ..., 24 => epX) 326 * @idx: endpoint index (1 => epA, 2 => epB, ..., 24 => epX)
322 * @name: endpoint name (for trace/debug purpose) 327 * @name: endpoint name (for trace/debug purpose)
323 * @dir_in: 1 if IN endpoint, 0 if OUT endpoint 328 * @dir_in: 1 if IN endpoint, 0 if OUT endpoint
@@ -346,6 +351,7 @@ struct pxa_ep {
346 spinlock_t lock; /* Protects this structure */ 351 spinlock_t lock; /* Protects this structure */
347 /* (queues, stats) */ 352 /* (queues, stats) */
348 unsigned enabled:1; 353 unsigned enabled:1;
354 unsigned in_handle_ep:1;
349 355
350 unsigned idx:5; 356 unsigned idx:5;
351 char *name; 357 char *name;