]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
USB: chaoskey: fix error case of a timeout
authorOliver Neukum <oneukum@suse.com>
Thu, 7 Nov 2019 14:28:55 +0000 (15:28 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 11 Nov 2019 13:29:39 +0000 (14:29 +0100)
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 <oneukum@suse.de>
Cc: stable <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20191107142856.16774-1-oneukum@suse.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/misc/chaoskey.c

index 34e6cd6f40d3005fbda6dc428be6c7e19fccf6bb..87067c3d6109b966fb7a35be4e0ed6da9f15c9af 100644 (file)
@@ -384,13 +384,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);
@@ -526,7 +530,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