[PATCH 13/21] HID: microsoft: move FF initialization to .input_configured()
From: Dmitry Torokhov
Date: Mon Aug 03 2026 - 15:12:43 EST
The driver currently initializes force-feedback in its probe() function
after calling hid_hw_start(). This is racy as the input device is
already registered and visible to userspace at that point.
Move the FF initialization to the .input_configured() callback to ensure
the device is fully prepared before registration.
Assisted-by: Gemini:gemini-3.1-pro
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx>
---
drivers/hid/hid-microsoft.c | 38 ++++++++------------------------------
1 file changed, 8 insertions(+), 30 deletions(-)
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 18ac21c0bcb2..a7d3493a6141 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -323,22 +323,17 @@ static int ms_play_effect(struct input_dev *dev, void *data,
return 0;
}
-static int ms_init_ff(struct hid_device *hdev)
+static int ms_input_configured(struct hid_device *hdev, struct hid_input *hidinput)
{
- struct hid_input *hidinput;
- struct input_dev *input_dev;
struct ms_data *ms = hid_get_drvdata(hdev);
-
- if (list_empty(&hdev->inputs)) {
- hid_err(hdev, "no inputs found\n");
- return -ENODEV;
- }
- hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
- input_dev = hidinput->input;
+ struct input_dev *input_dev = hidinput->input;
if (!(ms->quirks & MS_QUIRK_FF))
return 0;
+ if (!list_is_first(&hidinput->list, &hdev->inputs))
+ return 0;
+
ms->hdev = hdev;
INIT_WORK(&ms->ff_worker, ms_ff_worker);
@@ -352,16 +347,6 @@ static int ms_init_ff(struct hid_device *hdev)
return input_ff_create_memless(input_dev, NULL, ms_play_effect);
}
-static void ms_remove_ff(struct hid_device *hdev)
-{
- struct ms_data *ms = hid_get_drvdata(hdev);
-
- if (!(ms->quirks & MS_QUIRK_FF))
- return;
-
- cancel_work_sync(&ms->ff_worker);
-}
-
static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
unsigned long quirks = id->driver_data;
@@ -385,29 +370,21 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret = hid_parse(hdev);
if (ret) {
hid_err(hdev, "parse failed\n");
- goto err_free;
+ return ret;
}
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ((quirks & MS_HIDINPUT) ?
HID_CONNECT_HIDINPUT_FORCE : 0));
if (ret) {
hid_err(hdev, "hw start failed\n");
- goto err_free;
+ return ret;
}
- ret = ms_init_ff(hdev);
- if (ret)
- hid_err(hdev, "could not initialize ff, continuing anyway");
-
return 0;
-err_free:
- return ret;
}
-
static void ms_remove(struct hid_device *hdev)
{
hid_hw_stop(hdev);
- ms_remove_ff(hdev);
}
static const struct hid_device_id ms_devices[] = {
@@ -469,6 +446,7 @@ static struct hid_driver ms_driver = {
.report_fixup = ms_report_fixup,
.input_mapping = ms_input_mapping,
.input_mapped = ms_input_mapped,
+ .input_configured = ms_input_configured,
.event = ms_event,
.probe = ms_probe,
.remove = ms_remove,
--
2.55.0.629.g250fe7f194-goog