From: Tomasz Pakuła Date: Wed, 13 Aug 2025 20:09:55 +0000 (+0200) Subject: HID: pidff: Simplify HID field/usage searching logic X-Git-Tag: v6.18-rc1~81^2~5^2~11 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b974b372a9b0aa409ccf05dae8a267d4486f37b4;p=thirdparty%2Fkernel%2Flinux.git HID: pidff: Simplify HID field/usage searching logic Some deduplication and splitting into separate functions. This is now way easier to comprehend and parse mentally. Signed-off-by: Tomasz Pakuła Signed-off-by: Jiri Kosina --- diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c index c88442a087f1..2e8eac944be0 100644 --- a/drivers/hid/usbhid/hid-pidff.c +++ b/drivers/hid/usbhid/hid-pidff.c @@ -939,6 +939,43 @@ static void pidff_set_autocenter(struct input_dev *dev, u16 magnitude) pidff_autocenter(dev->ff->private, magnitude); } +/* + * Find specific usage in a given hid_field + */ +static int pidff_find_usage(struct hid_field *fld, unsigned int usage_code) +{ + for (int i = 0; i < fld->maxusage; i++) { + if (fld->usage[i].hid == usage_code) + return i; + } + return -1; +} + +/* + * Find hid_field with a specific usage. Return the usage index as well + */ +static int pidff_find_field_with_usage(int *usage_index, + struct hid_report *report, + unsigned int usage_code) +{ + for (int i = 0; i < report->maxfield; i++) { + struct hid_field *fld = report->field[i]; + + if (fld->maxusage != fld->report_count) { + pr_debug("maxusage and report_count do not match, skipping\n"); + continue; + } + + int index = pidff_find_usage(fld, usage_code); + + if (index >= 0) { + *usage_index = index; + return i; + } + } + return -1; +} + /* * Find fields from a report and fill a pidff_usage */ @@ -946,46 +983,38 @@ static int pidff_find_fields(struct pidff_usage *usage, const u8 *table, struct hid_report *report, int count, int strict, u32 *quirks) { + const u8 block_offset = pidff_set_condition[PID_PARAM_BLOCK_OFFSET]; + const u8 delay = pidff_set_effect[PID_START_DELAY]; + if (!report) { pr_debug("%s, null report\n", __func__); return -1; } - int i, j, k, found; + for (int i = 0; i < count; i++) { + int index; + int found = pidff_find_field_with_usage(&index, report, + HID_UP_PID | table[i]); - for (k = 0; k < count; k++) { - found = 0; - for (i = 0; i < report->maxfield; i++) { - if (report->field[i]->maxusage != - report->field[i]->report_count) { - pr_debug("maxusage and report_count do not match, skipping\n"); - continue; - } - for (j = 0; j < report->field[i]->maxusage; j++) { - if (report->field[i]->usage[j].hid == - (HID_UP_PID | table[k])) { - pr_debug("found %d at %d->%d\n", - k, i, j); - usage[k].field = report->field[i]; - usage[k].value = - &report->field[i]->value[j]; - found = 1; - break; - } - } - if (found) - break; + if (found >= 0) { + pr_debug("found %d at %d->%d\n", i, found, index); + usage[i].field = report->field[found]; + usage[i].value = &report->field[found]->value[index]; + continue; } - if (!found && table[k] == pidff_set_effect[PID_START_DELAY]) { + + if (table[i] == delay) { pr_debug("Delay field not found, but that's OK\n"); pr_debug("Setting MISSING_DELAY quirk\n"); *quirks |= HID_PIDFF_QUIRK_MISSING_DELAY; - } else if (!found && table[k] == pidff_set_condition[PID_PARAM_BLOCK_OFFSET]) { + + } else if (table[i] == block_offset) { pr_debug("PBO field not found, but that's OK\n"); pr_debug("Setting MISSING_PBO quirk\n"); *quirks |= HID_PIDFF_QUIRK_MISSING_PBO; - } else if (!found && strict) { - pr_debug("failed to locate %d\n", k); + + } else if (strict) { + pr_debug("failed to locate %d\n", i); return -1; } } @@ -1054,9 +1083,7 @@ static void pidff_find_reports(struct hid_device *hid, int report_type, */ static int pidff_reports_ok(struct pidff_device *pidff) { - int i; - - for (i = 0; i < PID_REQUIRED_REPORTS; i++) { + for (int i = 0; i < PID_REQUIRED_REPORTS; i++) { if (!pidff->reports[i]) { hid_dbg(pidff->hid, "%d missing\n", i); return 0; @@ -1077,9 +1104,7 @@ static struct hid_field *pidff_find_special_field(struct hid_report *report, return NULL; } - int i; - - for (i = 0; i < report->maxfield; i++) { + for (int i = 0; i < report->maxfield; i++) { if (report->field[i]->logical == (HID_UP_PID | usage) && report->field[i]->report_count > 0) { if (!enforce_min || @@ -1099,18 +1124,12 @@ static struct hid_field *pidff_find_special_field(struct hid_report *report, static int pidff_find_special_keys(int *keys, struct hid_field *fld, const u8 *usagetable, int count) { - - int i, j; int found = 0; - for (i = 0; i < count; i++) { - for (j = 0; j < fld->maxusage; j++) { - if (fld->usage[j].hid == (HID_UP_PID | usagetable[i])) { - keys[i] = j + 1; - found++; - break; - } - } + for (int i = 0; i < count; i++) { + keys[i] = pidff_find_usage(fld, HID_UP_PID | usagetable[i]) + 1; + if (keys[i]) + found++; } return found; }