From 79ac186da1ffd968dd8b0ac05364f5dc973f4365 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 7 Nov 2019 15:28:55 +0100 Subject: USB: chaoskey: fix error case of a timeout commit 92aa5986f4f7b5a8bf282ca0f50967f4326559f5 upstream. In case of a timeout or if a signal aborts a read communication with the device needs to be ended lest we overwrite an active URB the next time we do IO to the device, as the URB may still be active. Signed-off-by: Oliver Neukum Cc: stable Link: https://lore.kernel.org/r/20191107142856.16774-1-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/chaoskey.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c index eb0795c5ff7a..3a701c1e9e75 100644 --- a/drivers/usb/misc/chaoskey.c +++ b/drivers/usb/misc/chaoskey.c @@ -396,13 +396,17 @@ static int _chaoskey_fill(struct chaoskey *dev) !dev->reading, (started ? NAK_TIMEOUT : ALEA_FIRST_TIMEOUT) ); - if (result < 0) + if (result < 0) { + usb_kill_urb(dev->urb); goto out; + } - if (result == 0) + if (result == 0) { result = -ETIMEDOUT; - else + usb_kill_urb(dev->urb); + } else { result = dev->valid; + } out: /* Let the device go back to sleep eventually */ usb_autopm_put_interface(dev->interface); @@ -538,7 +542,21 @@ static int chaoskey_suspend(struct usb_interface *interface, static int chaoskey_resume(struct usb_interface *interface) { + struct chaoskey *dev; + struct usb_device *udev = interface_to_usbdev(interface); + usb_dbg(interface, "resume"); + dev = usb_get_intfdata(interface); + + /* + * We may have lost power. + * In that case the device that needs a long time + * for the first requests needs an extended timeout + * again + */ + if (le16_to_cpu(udev->descriptor.idVendor) == ALEA_VENDOR_ID) + dev->reads_started = false; + return 0; } #else -- cgit v1.2.3