USB: cdc-wdm: call wake_up_all to allow driver to shutdown on device removal
authorBjørn Mork <bjorn@mork.no>
Mon, 16 Jan 2012 14:11:57 +0000 (15:11 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 24 Jan 2012 20:18:25 +0000 (12:18 -0800)
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@suse.de>
drivers/usb/class/cdc-wdm.c

index 023d271..07aa676 100644 (file)
@@ -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);