I think one reason why HID events are done through the
default control pipe is that HID is designed to be able to
express such complex input and output arrangements that there
could easily be more inputs or output than the endpoint number,
which are limited to something like 63 if I recall correctly.
For example, the report descriptor for a keyboard describes
it as an array of buttons with most of those buttons transmitted
in a six byte "array" format (a list of up six keys are presently
down).
I used to think that it was crazy that things like
uninterruptible power supplies were part of the "human input
device" class, but I now realize that the mistake is just in
the naming of this class. The class could have been more
descrively named "hierarchical widgets", because it is very
good at describing devices that consist of groups of inputs
and/or outputs that are related to each other in ways where
it makes sense to associate some kind of label with sets of
them, and a label with some sets of those sets, and so on.
For example, a stereo panel might have volume and graphic
equalizer levers and some other switches in its output panel,
and then it might have a knob and a digital display for its
FM tuner. HID is good at describing things like that (at
least when all of those groupings have been defined in
the appropriate HID "usage tables").
I've said before that I think that general HID is
too complex for the kernel to optimally handle in the
form of in-kernel device drivers. Instead, I would propose
a simple ioctl interface where user level software would
read the HID report descriptors and whatever else they
care about, and then just ask the kernel to send copies
of any HID event whose first byte matches one of the report
ID's that they express and interest in (HID events begin
with a one byte report ID, which indicates which of the
event types described in the report descriptor this event is,
unless there is only one event type available and it's ID is
given as zero, in which case the first byte is omitted).
The reason that we would need a kernel interface,
rather than just using the current devfs code, is because
multiple clients may have interest in different events, or
event the same events, coming from a single endpoint. For
output, however, I think that that could work through the
existing usbdevfs code if multiple clients are allowed to
simultaneously have open the same /dev/bus/nnn/nnn file, which
I think actually is "safe", in the sense that you cannot
accidentally receive a reply from somebody else's command
or lose the reply to yours.
I imagine a user level interface something like this:
struct hid_notify_request {
unsigned char whichevents[32]; /* bitmap 0..255 */
int fd; /* filled in by ioctl */
};
int devicefd = fopen("/proc/bus/usb/001/002");
int notifyfd;
struct hid_notify_request req;
int report_id;
unsigned char eventbuf[100];
memset(&req, 0, sizeof(req));
...various devfs ioctls to read the HID report descriptors,
see the lsusb sources for an example...
...in this case, we determine that we are interested in events
begining with the byte "report_id"...
req.whichevents[report_id/8] |= 1 << (report_id & 7);
ioctl(devicefd, _IOWR(HID_INTEREST_IOCTL, 1,
sizeof(struct hid_notify_request), &req);
do {
result = read(devicefd, &eventbuf, sizeof(eventbuf));
...do something about the event...
} while (result > 0 || (result == -1 && errno == EAGAIN));
Adam J. Richter __ ______________ 4880 Stevens Creek Blvd, Suite 104
[EMAIL PROTECTED] \ / San Jose, California 95129-1034
+1 408 261-6630 | g g d r a s i l United States of America
fax +1 408 261-6631 "Free Software For The Rest Of Us."
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
http://lists.sourceforge.net/lists/listinfo/linux-usb-devel