Question: Efficient IO to USB HID device with spurious zero byte IN packets

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

 



Hi All,

I have currently developed a user-mode application that talks to a
third-party USB device.  Existing software for the device is Windows
only and proprietary.  My application works correctly, and it appears
(from using a hardware USB analyser) that I am talking to the device
correctly.  My concern is that the application 'feels' extremely
inefficient, and I would like to know if anyone can suggest a more
elegant approach.

The Device:
The device is a USB powered HID device, but maybe not the most
compliant device ever written (some missing descriptors etc).  It has
two endpoints (excluding control) 0x81 interrupt in, and 0x02
interrupt out.  I am only concerned with problems *reading* reports
from the device.  The IN endpoint has a max packet size of 64 bytes.
bInterval is 1 (i.e. 1 report every millisecond).  Although the device
says it is a HID device, it is only using HID as a transport for
opaque data (i.e. I am pretty sure it doesnt even have descriptors for
the reports).

The Problem:
The problem is that the device sends zero byte IN packets instead of
NAKs.  In other words, when there is data to send, it will send a full
64 byte IN packet, and the rest of the time it will send a zero byte
IN packet.  This means that the USB susbsystem feels obliged to tell
my application that a zero byte packet was received.  I know why, in
general, it has to treat any short packet like this, and I am not
proposing to change this behaviour.  I see this behaviour with libusb
and raw ioctls.

Current Approach:
At the moment, when the application starts I submit N (say 20) IN USB
IRPS.  As the device sends IN packets, they either have data or no
data.  My application basically 'spins' by recycling the IRPs, and
extracting any data that has arrived.  Like I say, it works, but it
just feels ugly (not to mention uses CPU and keeps jumping from
kernel<->userland).  I have the luxury of being able to treat this as
an interesting problem and try to see if I can find an elegant
solution, but I really need some help from people who know the Linux
USB architecture.

What Wont Work:
I dont think I can get high level HID reports because the device does
not respond with all descriptors, and so dmesg shows
[594015.753598] usbhid: timeout initializing reports
[594015.755345] hiddev97hidraw0: USB HID v1.01 Device [XXX] on
usb-0000:00:1d.0-2.2
I could dig further into this, but I am fairly sure the actual
firmware on the device is not compliant with the USB HID spec.

What I Want:
I want a user mode application that can block in user space and read
reports (64 bytes at a time) without having to worry about those
spurious zero byte packets.  Ideally, I want to do this without making
any kernel modifications.  Obviously, I cannot modify the firmware on
the USB device, so I have to live with that 'as-is'.

Strategy 1:
Is there any kind of flag that I have missed on the USB IRPS that
would say 'by the way, just ignore a zero byte packet'.

Strategy 2:
Is there a different type of user-mode IO I should be using?

Strategy 3:
What are the files /dev/usbdevX.Yep81 etc for?  Which driver creates
them?  Do they provide any kind of interface for actually reading
data, or are they signalling/control files.

Strategy 4:
What are the files /dev/usb/hiddevX etc for?  Which driver creates
them?  Do they provide any kind of interface for actually reading
data, or are they signalling/control files.

Strategy 5:
Is there any kind of a 'quirk' that I can set which tells the USB
subsystem 'this particular device sends lots of zero byte packets that
should be ignored completely'.

Strategy 6:
Surely there has to be a 'nice' way of doing this?  Any ideas?

Finally:
If the answer is no to the above strategies, is there a consensus of
whether this functionality (#1 or #5) makes sense to be added to the
kernel.  I haven't done Linux kernel development before, but I would
feel pretty confident tackling this if someone gave me a pointer in
the right direction.

Thanks for your time,

Glen Harris.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

  Powered by Linux