[PATCH] usb/core/devio.c:tolerate wrong direction flag in control endpoints

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

USB devio rejects control messages when the index does not have the
direction bit set correctly.
This breaks windows apps in KVM -- and might be overly strict according
to my reading of USB HID spec.
Attached patch makes the kernel tolerant against it and makes the app
work for me.

More details in the patch header.

USB experts: Please review this and judge whether this is correct,
applies more generically,
or maybe needs to be special cased (only for USB HID devices?) or
implemented as quirk
or module/kernel parameter.

Once in the final form, this *might* be stable material.

Please keep me in copy for the discussion, my participation on LKML is
mostly reading summaries
from Jonathan and Thorsten these days, unfortunately.

-- 
Kurt Garloff <kurt@xxxxxxxxxx>
Cologne, Germany

commit bc1e4e1ae1d5a4f9b2d263f22c651dd5ba4f8ff9
Author: Kurt Garloff <kurt@xxxxxxxxxx>
Date:   Sun Sep 22 11:54:59 2013 +0200

    From: Kurt Garloff <kurt@xxxxxxxxxx>
    Subject: Tolerate wrong direction bit endpoint index for control messages
    Signed-off-by: Kurt Garloff <kurt@xxxxxxxxxx>
    
    Trying to read data from the Pegasus Technologies NoteTaker (0e20:0101)
    [1] with the Windows App (EasyNote) works natively but fails when
    WIndows is running under KVM (and the USB device handed to KVM).
    
    The reason is a USB control message
     usb 4-2.2: control urb: bRequestType=22 bRequest=09 wValue=0200 wIndex=0001 wLength=0008
    This goes to endpoint 1 (wIndex), however, the endpoint is an input
    endpoint and thus enumerated 0x81.
    
    The kernel thus rejects the IO and thus we see the failure.
    
    Apparently, Linux is more strict here than Windows ... we can't change
    the Win app easily, so that's a problem.
    
    However, the app might not even be buggy here.  Browsing the USB HID
    spec, there's a note that the bit for direction is ignored for control
    endpoints ... so Linux might be overly strict?
    
    With attached patch, everything works.
     usb 4-2.2: check_ctrlrecip: process 13073 (qemu-kvm) requesting ep 01 but needs 81 (or 00)
    
    Notes:
    - I have not checked whether the ignorance of the direction bit for
      control endpoints only applies to USB HID devices, thus I have not
      special-cased depending on the device type.
    - We do output a warning into the kernel log, as this might still be
      caused by an application error.
    - We don't risk sending to a wrong endpoint, as there can't be two
      endpoints with same index and just different direction.
    - I suspect this will mostly affect apps in virtual environments; as on
      Linux the apps would have been adapted to the stricter handling of the
      kernel. I have done that for mine[2], although delaying the release by
      two years ....
    
    [1} http://www.pegatech.com/
    [2] https://sourceforge.net/projects/notetakerpen/

diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index c2f62a3..8acbc2f 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -623,6 +623,19 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype,
 	switch (requesttype & USB_RECIP_MASK) {
 	case USB_RECIP_ENDPOINT:
 		ret = findintfep(ps->dev, index);
+		if (ret < 0) {
+			/* OK, give it a second try -- user might have confused
+			 * direction -- this happens from virtualized win apps 
+			 * e.g. -- warn, but be graceful */
+			ret = findintfep(ps->dev, index ^ 0x80);
+			if (ret >= 0)
+				dev_info(&ps->dev->dev , 
+					"%s: process %i (%s) requesting ep %02x but needs %02x (or 00)\n",
+					__func__, 
+					task_pid_nr(current),
+					current->comm,
+				       	index, index ^ 0x80);
+		}
 		if (ret >= 0)
 			ret = checkintf(ps, ret);
 		break;

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux