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;
 };
 
