HID: microsoft: move FF initialization to .input_configured()

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@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
This commit is contained in:
Dmitry Torokhov
2026-08-03 11:46:38 -07:00
committed by Jiri Kosina
parent 2636afdf4a
commit 1cfc77a64b

View File

@@ -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,