From: "Tomasz Pakuła" <tomasz.pakula.oficjalny@gmail.com>
To: jikos@kernel.org, bentiss@kernel.org
Cc: oleg@makarenk.ooo, linux-input@vger.kernel.org
Subject: [PATCH v2 07/17] HID: pidff: Simplify HID field/usage searching logic
Date: Wed, 13 Aug 2025 22:09:55 +0200 [thread overview]
Message-ID: <20250813201005.17819-8-tomasz.pakula.oficjalny@gmail.com> (raw)
In-Reply-To: <20250813201005.17819-1-tomasz.pakula.oficjalny@gmail.com>
Some deduplication and splitting into separate functions. This is now
way easier to comprehend and parse mentally.
Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>
---
drivers/hid/usbhid/hid-pidff.c | 105 +++++++++++++++++++--------------
1 file changed, 62 insertions(+), 43 deletions(-)
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;
}
--
2.50.1
next prev parent reply other threads:[~2025-08-13 20:10 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-13 20:09 [PATCH v2 00/17] Further hid-pidff improvements and fixes Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 01/17] HID: pidff: Use direction fix only for conditional effects Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 02/17] HID: pidff: Remove unhelpful pidff_set_actuators helper Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 03/17] HID: pidff: Remove unneeded debug Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 04/17] HID: pidff: Use ARRAY_SIZE macro instead of sizeof Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 05/17] HID: pidff: Treat PID_REQUIRED_REPORTS as count, not max Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 06/17] HID: pidff: Better quirk assigment when searching for fields Tomasz Pakuła
2025-08-13 20:09 ` Tomasz Pakuła [this message]
2025-08-13 20:09 ` [PATCH v2 08/17] HID: pidff: Add support for AXES_ENABLE field Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 09/17] HID: pidff: Update debug messages Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 10/17] HID: pidff: Rework pidff_upload_effect Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 11/17] HID: pidff: Separate check for infinite duration Tomasz Pakuła
2025-08-13 20:10 ` [PATCH v2 12/17] HID: pidff: PERMISSIVE_CONTROL quirk autodetection Tomasz Pakuła
2025-08-13 20:10 ` [PATCH v2 13/17] HID: pidff: Remove Anssi's email address from info msg Tomasz Pakuła
2025-08-13 20:10 ` [PATCH v2 14/17] HID: pidff: Define all cardinal directions Tomasz Pakuła
2025-08-13 20:10 ` [PATCH v2 15/17] HID: pidff: clang-format pass Tomasz Pakuła
2025-08-13 20:10 ` [PATCH v2 16/17] HID: universal-pidff: " Tomasz Pakuła
2025-08-13 20:10 ` [PATCH v2 17/17] HID: pidff: Reduce PID_EFFECT_OPERATION spam Tomasz Pakuła
2025-08-15 14:01 ` [PATCH v2 00/17] Further hid-pidff improvements and fixes Jiri Kosina
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250813201005.17819-8-tomasz.pakula.oficjalny@gmail.com \
--to=tomasz.pakula.oficjalny@gmail.com \
--cc=bentiss@kernel.org \
--cc=jikos@kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=oleg@makarenk.ooo \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).