summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjørn Mork <bjorn@mork.no>2012-01-16 15:11:57 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-03 09:19:02 -0800
commitf1abac982c49f35615f47ff1f94a8ca5ba962bd8 (patch)
tree472eaf7f2ddc13ef41d0f0baab537564daa5edb5
parent0b4e97269313969faf20f4c341af10d734d6d00d (diff)
USB: cdc-wdm: call wake_up_all to allow driver to shutdown on device removal
commit 62aaf24dc125d7c55c93e313d15611f152b030c7 upstream. wdm_disconnect() waits for the mutex held by wdm_read() before calling wake_up_all(). This causes a deadlock, preventing device removal to complete. Do the wake_up_all() before we start waiting for the locks. Signed-off-by: Bjørn Mork <bjorn@mork.no> Cc: Oliver Neukum <oliver@neukum.org> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/class/cdc-wdm.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index bdfa96d60050..ed4317365fa0 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -786,13 +786,13 @@ static void wdm_disconnect(struct usb_interface *intf)
/* to terminate pending flushes */
clear_bit(WDM_IN_USE, &desc->flags);
spin_unlock_irqrestore(&desc->iuspin, flags);
+ wake_up_all(&desc->wait);
mutex_lock(&desc->rlock);
mutex_lock(&desc->wlock);
kill_urbs(desc);
cancel_work_sync(&desc->rxwork);
mutex_unlock(&desc->wlock);
mutex_unlock(&desc->rlock);
- wake_up_all(&desc->wait);
if (!desc->count)
cleanup(desc);
mutex_unlock(&wdm_mutex);