>> Or could I simply pass the intf pointer from usb_hid_configure()
>> to hid_parse_report() and there assign it to device->intf so it can
>> be dereferenced later?
>
> Passing the interface to parse_report() sounds simplest.
Ok, I went for that solution, and it seems to work for me (although
most dbg statements are not hit yet (luckily :-).
>> I'm completely new in this area, so I'm really clueless, and any
>> clarifications or hint/tips are very much appreciated. I'd very much
>> like to know wether I'm on the right track here ;-)
>
> Looks like it so far. Maybe Vojtech will have some additional
> suggestions.
Any suggestions are still very welcome, for now I've attached the
diffs for hid-core.c and hid-input.c. I rebuilt my kernel with it,
and indeed I get better debug output:
Mar 14 16:28:13 ws1 kernel: usbhid 2-3.2.4:1.1: input irq status -32 received
Mar 14 16:28:13 ws1 kernel: usbhid 2-3.1.2:1.1: input irq status -71 received
Mar 14 16:28:15 ws1 kernel: usbhid 2-3.2.4:1.1: input irq status -32 received
Mar 14 16:28:15 ws1 kernel: usbhid 2-3.1.2:1.1: input irq status -32 received
Mar 14 16:28:15 ws1 kernel: usbhid 2-3.2.4:1.1: input irq status -71 received
Mar 14 16:28:15 ws1 kernel: usbhid 2-3.1.2:1.1: input irq status -71 received
Mar 14 16:28:15 ws1 kernel: usbhid 2-3.2.4:1.0: input irq status -32 received
Mar 14 16:28:17 ws1 kernel: usbhid 2-3.2.4:1.0: input irq status -71 received
Which seems to point to my 2 chesen usb to ps/2 devices.
'lsusb -v' shows this about one of the devices (managed to get the new
version installed :-):
Bus 002 Device 012: ID 0a81:0205 Chesen Electronics Corp.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x0a81 Chesen Electronics Corp.
idProduct 0x0205
bcdDevice 0.10
iManufacturer 1 CHESEN
iProduct 2 PS2 to USB Converter
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 59
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 2 PS2 to USB Converter
bmAttributes 0xa0
Remote Wakeup
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Devices
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 1 Keyboard
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 64
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Devices
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 2 Mouse
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 148
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10
Anything I can do to remedy this?
Warm regards,
Mark.
--- bak/hid-core.c 2005-03-13 22:14:28.000000000 +0100
+++ hid-core.c 2005-03-14 15:01:52.000000000 +0100
@@ -84,7 +84,7 @@
struct hid_field *field;
if (report->maxfield == HID_MAX_FIELDS) {
- dbg("too many fields in report");
+ dev_dbg(&report->device->intf->dev, "too many fields in report\n");
return NULL;
}
@@ -115,7 +115,7 @@
usage = parser->local.usage[0];
if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) {
- dbg("collection stack overflow");
+ dev_dbg(&parser->device->intf->dev, "collection stack overflow\n");
return -1;
}
@@ -124,7 +124,7 @@
parser->device->collection_size * 2,
GFP_KERNEL);
if (collection == NULL) {
- dbg("failed to reallocate collection array");
+ dev_dbg(&parser->device->intf->dev, "failed to reallocate collection array\n");
return -1;
}
memcpy(collection, parser->device->collection,
@@ -160,7 +160,7 @@
static int close_collection(struct hid_parser *parser)
{
if (!parser->collection_stack_ptr) {
- dbg("collection stack underflow");
+ dev_dbg(&parser->device->intf->dev, "collection stack underflow\n");
return -1;
}
parser->collection_stack_ptr--;
@@ -188,7 +188,7 @@
static int hid_add_usage(struct hid_parser *parser, unsigned usage)
{
if (parser->local.usage_index >= HID_MAX_USAGES) {
- dbg("usage index exceeded");
+ dev_dbg(&parser->device->intf->dev, "usage index exceeded\n");
return -1;
}
parser->local.usage[parser->local.usage_index] = usage;
@@ -212,12 +212,12 @@
int i;
if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) {
- dbg("hid_register_report failed");
+ dev_dbg(&parser->device->intf->dev, "hid_register_report failed\n");
return -1;
}
if (parser->global.logical_maximum < parser->global.logical_minimum) {
- dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum);
+ dev_dbg(&parser->device->intf->dev, "logical range invalid %d %d\n", parser->global.logical_minimum, parser->global.logical_maximum);
return -1;
}
@@ -295,7 +295,7 @@
case HID_GLOBAL_ITEM_TAG_PUSH:
if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) {
- dbg("global enviroment stack overflow");
+ dev_dbg(&parser->device->intf->dev, "global enviroment stack overflow\n");
return -1;
}
@@ -306,7 +306,7 @@
case HID_GLOBAL_ITEM_TAG_POP:
if (!parser->global_stack_ptr) {
- dbg("global enviroment stack underflow");
+ dev_dbg(&parser->device->intf->dev,"global enviroment stack underflow\n");
return -1;
}
@@ -350,27 +350,27 @@
case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
if ((parser->global.report_size = item_udata(item)) > 32) {
- dbg("invalid report_size %d", parser->global.report_size);
+ dev_dbg(&parser->device->intf->dev,"invalid report_size %d\n", parser->global.report_size);
return -1;
}
return 0;
case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) {
- dbg("invalid report_count %d", parser->global.report_count);
+ dev_dbg(&parser->device->intf->dev,"invalid report_count %d\n", parser->global.report_count);
return -1;
}
return 0;
case HID_GLOBAL_ITEM_TAG_REPORT_ID:
if ((parser->global.report_id = item_udata(item)) == 0) {
- dbg("report_id 0 is invalid");
+ dev_dbg(&parser->device->intf->dev,"report_id 0 is invalid\n");
return -1;
}
return 0;
default:
- dbg("unknown global tag 0x%x", item->tag);
+ dev_dbg(&parser->device->intf->dev, "unknown global tag 0x%x\n", item->tag);
return -1;
}
}
@@ -385,7 +385,7 @@
unsigned n;
if (item->size == 0) {
- dbg("item data expected for local item");
+ dev_dbg(&parser->device->intf->dev,"item data expected for local item\n");
return -1;
}
@@ -403,14 +403,14 @@
* items and the first delimiter set.
*/
if (parser->local.delimiter_depth != 0) {
- dbg("nested delimiters");
+ dev_dbg(&parser->device->intf->dev,"nested delimiters\n");
return -1;
}
parser->local.delimiter_depth++;
parser->local.delimiter_branch++;
} else {
if (parser->local.delimiter_depth < 1) {
- dbg("bogus close delimiter");
+ dev_dbg(&parser->device->intf->dev,"bogus close delimiter\n");
return -1;
}
parser->local.delimiter_depth--;
@@ -420,7 +420,7 @@
case HID_LOCAL_ITEM_TAG_USAGE:
if (parser->local.delimiter_branch > 1) {
- dbg("alternative usage ignored");
+ dev_dbg(&parser->device->intf->dev, "alternative usage ignored\n");
return 0;
}
@@ -432,7 +432,7 @@
case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
if (parser->local.delimiter_branch > 1) {
- dbg("alternative usage ignored");
+ dev_dbg(&parser->device->intf->dev, "alternative usage ignored\n");
return 0;
}
@@ -445,7 +445,7 @@
case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
if (parser->local.delimiter_branch > 1) {
- dbg("alternative usage ignored");
+ dev_dbg(&parser->device->intf->dev, "alternative usage ignored\n");
return 0;
}
@@ -454,14 +454,14 @@
for (n = parser->local.usage_minimum; n <= data; n++)
if (hid_add_usage(parser, n)) {
- dbg("hid_add_usage failed\n");
+ dev_dbg(&parser->device->intf->dev, "hid_add_usage failed\n\n");
return -1;
}
return 0;
default:
- dbg("unknown local item tag 0x%x", item->tag);
+ dev_dbg(&parser->device->intf->dev, "unknown local item tag 0x%x\n", item->tag);
return 0;
}
return 0;
@@ -495,7 +495,7 @@
ret = hid_add_field(parser, HID_FEATURE_REPORT, data);
break;
default:
- dbg("unknown main item tag 0x%x", item->tag);
+ dev_dbg(&parser->device->intf->dev, "unknown main item tag 0x%x\n", item->tag);
ret = 0;
}
@@ -510,7 +510,7 @@
static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item)
{
- dbg("reserved item type, tag 0x%x", item->tag);
+ dev_dbg(&parser->device->intf->dev, "reserved item type, tag 0x%x\n", item->tag);
return 0;
}
@@ -627,7 +627,7 @@
* enumerated, fields are attached to these reports.
*/
-static struct hid_device *hid_parse_report(__u8 *start, unsigned size)
+static struct hid_device *hid_parse_report(struct usb_interface *intf, __u8 *start, unsigned size)
{
struct hid_device *device;
struct hid_parser *parser;
@@ -665,6 +665,7 @@
}
memcpy(device->rdesc, start, size);
device->rsize = size;
+ device->intf = intf;
if (!(parser = kmalloc(sizeof(struct hid_parser), GFP_KERNEL))) {
kfree(device->rdesc);
@@ -679,7 +680,7 @@
while ((start = fetch_item(start, end, &item)) != NULL) {
if (item.format != HID_ITEM_FORMAT_SHORT) {
- dbg("unexpected long global item");
+ dev_dbg(&intf->dev,"unexpected long global item\n");
kfree(device->collection);
hid_free_device(device);
kfree(parser);
@@ -687,7 +688,7 @@
}
if (dispatch_type[item.type](parser, &item)) {
- dbg("item %u %u %u %u parsing failed\n",
+ dev_dbg(&intf->dev,"item %u %u %u %u parsing failed\n\n",
item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag);
kfree(device->collection);
hid_free_device(device);
@@ -697,14 +698,14 @@
if (start == end) {
if (parser->collection_stack_ptr) {
- dbg("unbalanced collection at end of report description");
+ dev_dbg(&intf->dev, "unbalanced collection at end of report description\n");
kfree(device->collection);
hid_free_device(device);
kfree(parser);
return NULL;
}
if (parser->local.delimiter_depth) {
- dbg("unbalanced delimiter at end of report description");
+ dev_dbg(&intf->dev,"unbalanced delimiter at end of report description\n");
kfree(device->collection);
hid_free_device(device);
kfree(parser);
@@ -715,7 +716,7 @@
}
}
- dbg("item fetching failed at offset %d\n", (int)(end - start));
+ dev_dbg(&intf->dev, "item fetching failed at offset %d\n\n", (int)(end - start));
kfree(device->collection);
hid_free_device(device);
kfree(parser);
@@ -862,7 +863,7 @@
int n, size;
if (!len) {
- dbg("empty report");
+ dev_dbg(&hid->intf->dev, "empty report\n");
return -1;
}
@@ -887,14 +888,14 @@
#endif
if (!(report = report_enum->report_id_hash[n])) {
- dbg("undefined report_id %d received", n);
+ dev_dbg(&hid->intf->dev, "undefined report_id %d received\n", n);
return -1;
}
size = ((report->size - 1) >> 3) + 1;
if (len < size) {
- dbg("report %d is too short, (%d < %d)", report->id, len, size);
+ dev_dbg(&hid->intf->dev,"report %d is too short, (%d < %d)\n", report->id, len, size);
return -1;
}
@@ -932,12 +933,12 @@
case -ETIMEDOUT: /* NAK */
break;
default: /* error */
- warn("input irq status %d received", urb->status);
+ dev_warn(&hid->intf->dev, "input irq status %d received\n", urb->status);
}
status = usb_submit_urb(urb, SLAB_ATOMIC);
if (status)
- err("can't resubmit intr, %s-%s/input%d, status %d",
+ dev_err(&hid->intf->dev, "can't resubmit intr, %s-%s/input%d, status %d\n",
hid->dev->bus->bus_name, hid->dev->devpath,
hid->ifnum, status);
}
@@ -989,13 +990,13 @@
hid_dump_input(field->usage + offset, value);
if (offset >= field->report_count) {
- dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count);
+ dev_dbg(field->hidinput->input.dev, "offset (%d) exceeds report_count (%d)\n", offset, field->report_count);
hid_dump_field(field, 8);
return -1;
}
if (field->logical_minimum < 0) {
if (value != snto32(s32ton(value, size), size)) {
- dbg("value %d is out of range", value);
+ dev_dbg(field->hidinput->input.dev, "value %d is out of range\n", value);
return -1;
}
}
@@ -1071,10 +1072,10 @@
hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
hid->urbout->dev = hid->dev;
- dbg("submitting out urb");
+ dev_dbg(&hid->intf->dev, "submitting out urb\n");
if (usb_submit_urb(hid->urbout, GFP_ATOMIC)) {
- err("usb_submit_urb(out) failed");
+ dev_err(&hid->intf->dev, "usb_submit_urb(out) failed\n");
return -1;
}
@@ -1117,12 +1118,12 @@
hid->cr->wIndex = cpu_to_le16(hid->ifnum);
hid->cr->wLength = cpu_to_le16(len);
- dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u",
+ dev_dbg(&hid->intf->dev, "submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
hid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
hid->cr->wValue, hid->cr->wIndex, hid->cr->wLength);
if (usb_submit_urb(hid->urbctrl, GFP_ATOMIC)) {
- err("usb_submit_urb(ctrl) failed");
+ dev_err(&hid->intf->dev, "usb_submit_urb(ctrl) failed\n");
return -1;
}
@@ -1148,7 +1149,7 @@
case -ENOENT:
break;
default: /* error */
- warn("output irq status %d received", urb->status);
+ dev_warn(&hid->intf->dev, "output irq status %d received\n", urb->status);
}
spin_lock_irqsave(&hid->outlock, flags);
@@ -1196,7 +1197,7 @@
case -EPIPE: /* report not available */
break;
default: /* error */
- warn("ctrl urb status %d received", urb->status);
+ dev_warn(&hid->intf->dev, "ctrl urb status %d received\n", urb->status);
}
if (unplug)
@@ -1232,7 +1233,7 @@
if ((head = (hid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == hid->outtail) {
spin_unlock_irqrestore(&hid->outlock, flags);
- warn("output queue full");
+ dev_warn(&hid->intf->dev, "output queue full\n");
return;
}
@@ -1251,7 +1252,7 @@
if ((head = (hid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == hid->ctrltail) {
spin_unlock_irqrestore(&hid->ctrllock, flags);
- warn("control queue full");
+ dev_warn(&hid->intf->dev, "control queue full\n");
return;
}
@@ -1284,7 +1285,7 @@
remove_wait_queue(&hid->wait, &wait);
if (!timeout) {
- dbg("timeout waiting for ctrl or out queue to clear");
+ dev_dbg(&hid->intf->dev, "timeout waiting for ctrl or out queue to clear\n");
return -1;
}
@@ -1386,7 +1387,7 @@
}
if (err)
- warn("timeout initializing reports\n");
+ dev_warn(&hid->intf->dev, "timeout initializing reports\n\n");
report_enum = hid->report_enum + HID_INPUT_REPORT;
list = report_enum->report_list.next;
@@ -1635,7 +1636,7 @@
if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->desc.bNumEndpoints) ||
usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
- dbg("class descriptor not present\n");
+ dev_dbg(&intf->dev,"class descriptor not present\n\n");
return NULL;
}
@@ -1644,17 +1645,17 @@
rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
- dbg("weird size of report descriptor (%u)", rsize);
+ dev_dbg(&intf->dev, "weird size of report descriptor (%u)\n", rsize);
return NULL;
}
if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) {
- dbg("couldn't allocate rdesc memory");
+ dev_dbg(&intf->dev, "couldn't allocate rdesc memory\n");
return NULL;
}
if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) {
- dbg("reading report descriptor failed");
+ dev_dbg(&intf->dev, "reading report descriptor failed\n");
kfree(rdesc);
return NULL;
}
@@ -1666,8 +1667,8 @@
printk("\n");
#endif
- if (!(hid = hid_parse_report(rdesc, n))) {
- dbg("parsing report descriptor failed");
+ if (!(hid = hid_parse_report(intf, rdesc, n))) {
+ dev_dbg(&intf->dev, "parsing report descriptor failed\n");
kfree(rdesc);
return NULL;
}
@@ -1719,7 +1720,7 @@
}
if (!hid->urbin) {
- err("couldn't find an input interrupt endpoint");
+ dev_err(&intf->dev, "couldn't find an input interrupt endpoint\n");
goto fail;
}
@@ -1817,7 +1818,7 @@
int i;
char *c;
- dbg("HID probe called for ifnum %d",
+ dev_dbg(&intf->dev, "HID probe called for ifnum %d\n",
intf->altsetting->desc.bInterfaceNumber);
if (!(hid = usb_hid_configure(intf)))
--- bak/hid-input.c 2005-03-14 12:52:10.000000000 +0100
+++ hid-input.c 2005-03-14 15:09:40.000000000 +0100
@@ -454,12 +454,12 @@
if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */
input->ff_effects_max = value;
- dbg("Maximum Effects - %d",input->ff_effects_max);
+ dev_dbg(&hid->intf->dev, "Maximum Effects - %d\n",input->ff_effects_max);
return;
}
if (usage->hid == (HID_UP_PID | 0x7fUL)) {
- dbg("PID Pool Report\n");
+ dev_dbg(&hid->intf->dev, "PID Pool Report\n\n");
return;
}