summaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/f_acm.c
diff options
context:
space:
mode:
authorDavid Brownell <dbrownell@users.sourceforge.net>2008-11-12 20:35:13 +0100
committerGreg Kroah-Hartman <gregkh@suse.de>2008-11-13 23:45:06 +0100
commite50ae572b33646656fa7037541613834dcadedfb (patch)
tree8b6399e374401dea2ee7e170a39b596c62605f88 /drivers/usb/gadget/f_acm.c
parentUSB: EHCI: fix divide-by-zero bug (diff)
downloadlinux-e50ae572b33646656fa7037541613834dcadedfb.tar.xz
linux-e50ae572b33646656fa7037541613834dcadedfb.zip
USB: gadget: cdc-acm deadlock fix
This fixes a deadlock appearing with some USB peripheral drivers when running CDC ACM gadget code. The newish (2.6.27) CDC ACM event notification mechanism sends messages (IN to the host) which are short enough to fit in most FIFOs. That means that with some peripheral controller drivers (evidently not the ones used to verify the notification code!!) the completion callback can be issued before queue() returns. The deadlock would come because the completion callback and the event-issuing code shared a spinlock. Fix is trivial: drop that lock while queueing the message. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/f_acm.c')
-rw-r--r--drivers/usb/gadget/f_acm.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index 5ee1590b8e9c..c1d34df0b157 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -463,7 +463,11 @@ static int acm_cdc_notify(struct f_acm *acm, u8 type, u16 value,
notify->wLength = cpu_to_le16(length);
memcpy(buf, data, length);
+ /* ep_queue() can complete immediately if it fills the fifo... */
+ spin_unlock(&acm->lock);
status = usb_ep_queue(ep, req, GFP_ATOMIC);
+ spin_lock(&acm->lock);
+
if (status < 0) {
ERROR(acm->port.func.config->cdev,
"acm ttyGS%d can't notify serial state, %d\n",