Hi
I was trying to enumerate HID functionality of a device (in python) and
was stuck on this for almost a day, until I RTFS'd.
I did this:
# for all reports (report_info)
ioctl(fd, HIDIOCGREPORTINFO, &report_info)
for field in range(report_info.num_fields):
field_info.report_type = report_info.report_type
field_info.report_id = report_info.report_id
field_info.field_index = field
ioctl(fd, HIDIOCGFIELDINFO, &field_info)
for usage in range(field_info.maxusage):
usage_ref.report_type = field_info.report_type
usage_ref.report_id = field_info.report_id
usage_ref.field_index = field_info.field_index
usage_ref.usage_index = usage
ioctl(fd, HIDIOCGUCODE, &...)
And this barfed and barfed and barfed until I downloaded hid.c example,
converted that to python, which worked and finally figured out that
ioctl HIDIOCGFIELDINFO overwrites field_info member with something
weird, here's snippet from kernel source:
hiddev.c (2.6.1):
static int hiddev_ioctl(...)
...
case HIDIOCGFIELDINFO:
....
field = report->field[finfo.field_index];
memset(&finfo, 0, sizeof(finfo));
finfo.report_type = rinfo.report_type;
finfo.report_id = rinfo.report_id;
finfo.field_index = field->report_count - 1;
finfo.maxusage = field->maxusage;
...
if (copy_to_user((void *) arg, &finfo, sizeof(finfo)))
Now can anyone tell me, why would this ioctl change my field_index to
something seemingly unrelated?
I couldn't see any other references to report_count in the same file, so
is it a mistake or is it needed elsewhere in the kernel?
Is it a bug or a feature?
I understand there is a simple workaround for my case, used in hid.c
example - use field variable from outer loop instead of field_index in
the clobbered structure, that works.
What if I were to go through field info's in some other way, for
example, through REPORT_ID_FIRST/REPORT_ID_NEXT flags? I guess wouldn't
have any way to recover proper field_index anymore.
Thanks,
Dima Tisnek
--
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