summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>2025-02-11 15:35:08 +0100
committerJiri Kosina <jkosina@suse.com>2025-02-11 23:15:32 +0100
commit1f650dcec32d22deb1d6db12300a2b98483099a9 (patch)
tree50a889c9f6bb1c8465a3ae5368d00d37a6ef957c
parent2c2afb50b50f10818f5b0bebed66ea1d5e1293a6 (diff)
HID: pidff: Make sure to fetch pool before checking SIMULTANEOUS_MAX
As noted by Anssi some 20 years ago, pool report is sometimes messed up. This worked fine on many devices but casued oops on VRS DirectForce PRO. Here, we're making sure pool report is refetched before trying to access any of it's fields. While loop was replaced with a for loop + exit conditions were moved aroud to decrease the possibility of creating an infinite loop scenario. Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
-rw-r--r--drivers/hid/usbhid/hid-pidff.c29
1 files changed, 13 insertions, 16 deletions
diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c
index f23381b6e344..503f643b59ca 100644
--- a/drivers/hid/usbhid/hid-pidff.c
+++ b/drivers/hid/usbhid/hid-pidff.c
@@ -604,28 +604,25 @@ static void pidff_reset(struct pidff_device *pidff)
}
/*
- * Refetch pool report
+ * Fetch pool report
*/
static void pidff_fetch_pool(struct pidff_device *pidff)
{
- if (!pidff->pool[PID_SIMULTANEOUS_MAX].value)
- return;
+ int i;
+ struct hid_device *hid = pidff->hid;
- int i = 0;
- while (pidff->pool[PID_SIMULTANEOUS_MAX].value[0] < 2) {
- hid_dbg(pidff->hid, "pid_pool requested again\n");
- hid_hw_request(pidff->hid, pidff->reports[PID_POOL],
- HID_REQ_GET_REPORT);
- hid_hw_wait(pidff->hid);
+ /* Repeat if PID_SIMULTANEOUS_MAX < 2 to make sure it's correct */
+ for(i = 0; i < 20; i++) {
+ hid_hw_request(hid, pidff->reports[PID_POOL], HID_REQ_GET_REPORT);
+ hid_hw_wait(hid);
- /* break after 20 tries with SIMULTANEOUS_MAX < 2 */
- if (i++ > 20) {
- hid_warn(pidff->hid,
- "device reports %d simultaneous effects\n",
- pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
- break;
- }
+ if (!pidff->pool[PID_SIMULTANEOUS_MAX].value)
+ return;
+ if (pidff->pool[PID_SIMULTANEOUS_MAX].value[0] >= 2)
+ return;
}
+ hid_warn(hid, "device reports %d simultaneous effects\n",
+ pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
}
/*