ChangeSet 1.1303.2.1, 2003/06/05 01:12:30-07:00, bcollins@debian.org [PATCH] USB: fix keyboard leds > Ben, it looks like your patch broke something for USB keyboards, any > idea? Yep, my patch killed hid-input from scanning HID_OUTPUT_REPORT's. Fixed with this patch for 2.5.70+bk. I'll send one for 2.4.x in a few minutes. drivers/usb/input/hid-input.c | 97 +++++++++++++++++++++--------------------- drivers/usb/input/hid.h | 3 - 2 files changed, 51 insertions(+), 49 deletions(-) diff -Nru a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c --- a/drivers/usb/input/hid-input.c Thu Jun 5 13:45:14 2003 +++ b/drivers/usb/input/hid-input.c Thu Jun 5 13:45:14 2003 @@ -70,8 +70,11 @@ hidinput = list_entry(lh, struct hid_input, list); - for (i = 0; i < hidinput->maxfield; i++) - if (hidinput->fields[i] == field) + if (! hidinput->report) + continue; + + for (i = 0; i < hidinput->report->maxfield; i++) + if (hidinput->report->field[i] == field) return &hidinput->input; } @@ -527,7 +530,7 @@ struct hid_report *report; struct list_head *list; struct hid_input *hidinput = NULL; - int i, j; + int i, j, k; INIT_LIST_HEAD(&hid->inputs); @@ -539,57 +542,57 @@ if (i == hid->maxcollection) return -1; - report_enum = hid->report_enum + HID_INPUT_REPORT; - list = report_enum->report_list.next; - while (list != &report_enum->report_list) { - report = (struct hid_report *) list; + for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) { + report_enum = hid->report_enum + k; + list = report_enum->report_list.next; + while (list != &report_enum->report_list) { + report = (struct hid_report *) list; - if (!report->maxfield) - continue; + if (!report->maxfield) + continue; - if (!hidinput) { - hidinput = kmalloc(sizeof(*hidinput), GFP_KERNEL); if (!hidinput) { - err("Out of memory during hid input probe"); - return -1; - } - memset(hidinput, 0, sizeof(*hidinput)); - - list_add_tail(&hidinput->list, &hid->inputs); + hidinput = kmalloc(sizeof(*hidinput), GFP_KERNEL); + if (!hidinput) { + err("Out of memory during hid input probe"); + return -1; + } + memset(hidinput, 0, sizeof(*hidinput)); - hidinput->input.private = hid; - hidinput->input.event = hidinput_input_event; - hidinput->input.open = hidinput_open; - hidinput->input.close = hidinput_close; - - hidinput->input.name = hid->name; - hidinput->input.phys = hid->phys; - hidinput->input.uniq = hid->uniq; - hidinput->input.id.bustype = BUS_USB; - hidinput->input.id.vendor = dev->descriptor.idVendor; - hidinput->input.id.product = dev->descriptor.idProduct; - hidinput->input.id.version = dev->descriptor.bcdDevice; - } + list_add_tail(&hidinput->list, &hid->inputs); - for (i = 0; i < report->maxfield; i++) - for (j = 0; j < report->field[i]->maxusage; j++) - hidinput_configure_usage(hidinput, report->field[i], - report->field[i]->usage + j); - - if (hid->quirks & HID_QUIRK_MULTI_INPUT) { - /* This will leave hidinput NULL, so that it - * allocates another one if we have more inputs on - * the same interface. Some devices (e.g. Happ's - * UGCI) cram a lot of unrelated inputs into the - * same interface. */ - hidinput->fields = report->field; - hidinput->maxfield = report->maxfield; + hidinput->input.private = hid; + hidinput->input.event = hidinput_input_event; + hidinput->input.open = hidinput_open; + hidinput->input.close = hidinput_close; + + hidinput->input.name = hid->name; + hidinput->input.phys = hid->phys; + hidinput->input.uniq = hid->uniq; + hidinput->input.id.bustype = BUS_USB; + hidinput->input.id.vendor = dev->descriptor.idVendor; + hidinput->input.id.product = dev->descriptor.idProduct; + hidinput->input.id.version = dev->descriptor.bcdDevice; + } + + for (i = 0; i < report->maxfield; i++) + for (j = 0; j < report->field[i]->maxusage; j++) + hidinput_configure_usage(hidinput, report->field[i], + report->field[i]->usage + j); + + if (hid->quirks & HID_QUIRK_MULTI_INPUT) { + /* This will leave hidinput NULL, so that it + * allocates another one if we have more inputs on + * the same interface. Some devices (e.g. Happ's + * UGCI) cram a lot of unrelated inputs into the + * same interface. */ + hidinput->report = report; + input_register_device(&hidinput->input); + hidinput = NULL; + } - input_register_device(&hidinput->input); - hidinput = NULL; + list = list->next; } - - list = list->next; } /* This only gets called when we are a single-input (most of the diff -Nru a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h --- a/drivers/usb/input/hid.h Thu Jun 5 13:45:14 2003 +++ b/drivers/usb/input/hid.h Thu Jun 5 13:45:14 2003 @@ -324,8 +324,7 @@ struct hid_input { struct list_head list; - struct hid_field **fields; - int maxfield; + struct hid_report *report; struct input_dev input; };