Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: misc: usbtest: add fix for driver hang

In sg_timeout(), req->status is set to "-ETIMEDOUT" before calling
into usb_sg_cancel(). usb_sg_cancel() will do nothing and return
directly if req->status has been set to a non-zero value. This will
cause driver hang whenever transfer time out is triggered.

This patch fixes this issue. It could be backported to stable kernel
with version later than v3.15.

Cc: stable@vger.kernel.org # 3.15+
Cc: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Suggested-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Lu Baolu and committed by
Greg Kroah-Hartman
53958751 224f6e40

+4 -3
+4 -3
drivers/usb/misc/usbtest.c
··· 585 585 { 586 586 struct usb_sg_request *req = (struct usb_sg_request *) _req; 587 587 588 - req->status = -ETIMEDOUT; 589 588 usb_sg_cancel(req); 590 589 } 591 590 ··· 615 616 mod_timer(&sg_timer, jiffies + 616 617 msecs_to_jiffies(SIMPLE_IO_TIMEOUT)); 617 618 usb_sg_wait(req); 618 - del_timer_sync(&sg_timer); 619 - retval = req->status; 619 + if (!del_timer_sync(&sg_timer)) 620 + retval = -ETIMEDOUT; 621 + else 622 + retval = req->status; 620 623 621 624 /* FIXME check resulting data pattern */ 622 625