Setting the WDM_READ bit in wdm_disconnect() is useless, as wdm_disconnect() won't be called at all as long as wdm_read() is blocking waiting for this bit. Use wait_event_interruptible_timeout for blocking reads to allow the USB subsystem to call wdm_disconnect, and thereby allow a blocking read to complete on device removal. Without this, a blocking read will prevent a device from being removed. Signed-off-by: Bjørn Mork <bjorn@xxxxxxx> --- drivers/usb/class/cdc-wdm.c | 19 +++++++++++-------- 1 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 023d271..88fee93 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -419,14 +419,18 @@ retry: } rv = 0; } else { - rv = wait_event_interruptible(desc->wait, - test_bit(WDM_READ, &desc->flags)); - } +wait: + rv = wait_event_interruptible_timeout(desc->wait, + test_bit(WDM_READ, &desc->flags), 100); + /* may have happened while we slept */ + if (test_bit(WDM_DISCONNECTING, &desc->flags)) { + rv = -ENODEV; + goto err; + } - /* may have happened while we slept */ - if (test_bit(WDM_DISCONNECTING, &desc->flags)) { - rv = -ENODEV; - goto err; + /* timed out? */ + if (!rv) + goto wait; } usb_mark_last_busy(interface_to_usbdev(desc->intf)); if (rv < 0) { @@ -782,7 +786,6 @@ static void wdm_disconnect(struct usb_interface *intf) /* the spinlock makes sure no new urbs are generated in the callbacks */ spin_lock_irqsave(&desc->iuspin, flags); set_bit(WDM_DISCONNECTING, &desc->flags); - set_bit(WDM_READ, &desc->flags); /* to terminate pending flushes */ clear_bit(WDM_IN_USE, &desc->flags); spin_unlock_irqrestore(&desc->iuspin, flags); -- 1.7.8.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html