aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorEugeny S. Mints <emints@ru.mvista.com>2006-09-02 06:59:19 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-09-27 14:58:56 -0400
commit80f8af0c59385b41564a3ae670f94a1b4caa43b2 (patch)
treec2721898c3db66f743639a8446d72c48ebd11950 /drivers/usb/gadget
parent0e3c8c26c7013b9d34929857598fd86ff1c22a6c (diff)
USB: usb serial gadget smp related bug
Adjust dev->dev_lock spinlock lock/unlock calls to be safe for SMP case. Otherwise the following sequence may lead to a deadlock in SMP case: gs_send()->usb_ep_queue() ->(in case a request is satisfied immediatly) gs_write_complete() for ex for pxa2xx_udc.c: usb_ep_queue()->pxa2xx_ep_queue()->write_fifo()->done()->gs_write_complete() (through req.complete pointer) Signed-off-by: Eugeny S. Mints <emints@ru.mvista.com> Acked-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/serial.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index e762aa19ab0a..b893e3118e1b 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -1120,12 +1120,15 @@ static int gs_send(struct gs_dev *dev)
1120gs_debug_level(3, "gs_send: len=%d, 0x%2.2x 0x%2.2x 0x%2.2x ...\n", len, *((unsigned char *)req->buf), *((unsigned char *)req->buf+1), *((unsigned char *)req->buf+2)); 1120gs_debug_level(3, "gs_send: len=%d, 0x%2.2x 0x%2.2x 0x%2.2x ...\n", len, *((unsigned char *)req->buf), *((unsigned char *)req->buf+1), *((unsigned char *)req->buf+2));
1121 list_del(&req_entry->re_entry); 1121 list_del(&req_entry->re_entry);
1122 req->length = len; 1122 req->length = len;
1123 spin_unlock_irqrestore(&dev->dev_lock, flags);
1123 if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) { 1124 if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
1124 printk(KERN_ERR 1125 printk(KERN_ERR
1125 "gs_send: cannot queue read request, ret=%d\n", 1126 "gs_send: cannot queue read request, ret=%d\n",
1126 ret); 1127 ret);
1128 spin_lock_irqsave(&dev->dev_lock, flags);
1127 break; 1129 break;
1128 } 1130 }
1131 spin_lock_irqsave(&dev->dev_lock, flags);
1129 } else { 1132 } else {
1130 break; 1133 break;
1131 } 1134 }