diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index f9f7c8a5e091..17de5c88a325 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -587,8 +587,9 @@ static ssize_t wdm_read static int wdm_flush(struct file *file, fl_owner_t id) { struct wdm_device *desc = file->private_data; + int timeout; - wait_event(desc->wait, + timeout = wait_event_timeout(desc->wait, /* * needs both flags. We cannot do with one * because resetting it would cause a race @@ -596,7 +597,14 @@ static int wdm_flush(struct file *file, fl_owner_t id) * a disconnect */ !test_bit(WDM_IN_USE, &desc->flags) || - test_bit(WDM_DISCONNECTING, &desc->flags)); + test_bit(WDM_DISCONNECTING, &desc->flags), + /* pulled out of thin air */ + 30 * HZ); + + if (!timeout) { + usb_kill_urb(desc->command); + return -EIO; + } /* cannot dereference desc->intf if WDM_DISCONNECTING */ if (test_bit(WDM_DISCONNECTING, &desc->flags))