[PATCH 17/21] HID: mayflash: move FF initialization to .input_configured()
Dmitry Torokhov <[email protected]> Mon, 03 Aug 2026 11:46:42 -0700
| Newsgroups | org.kernel.vger.linux-input,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> --- drivers/hid/hid-mf.c | 77 ++++++++++++++++++---------------------------------- 1 file changed, 27 insertions(+), 50 deletions(-) diff --git a/drivers/hid/hid-mf.c b/drivers/hid/hid-mf.c index 6ff54a1ec697..136e8b41d5f4 100644 --- a/drivers/hid/hid-mf.c +++ b/drivers/hid/hid-mf.c @@ -54,61 +54,45 @@ static int mf_play(struct input_dev *dev, void *data, struct ff_effect *effect) return 0; } -static int mf_init(struct hid_device *hid) +static int mf_input_configured(struct hid_device *hid, struct hid_input *hidinput) { struct mf_device *mf; - struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; - - struct list_head *report_ptr; struct hid_report *report; - - struct list_head *input_ptr = &hid->inputs; - struct hid_input *input; - - struct input_dev *dev; - + struct input_dev *dev = hidinput->input; int error; - /* Setup each of the four inputs */ - list_for_each(report_ptr, report_list) { - report = list_entry(report_ptr, struct hid_report, list); + if (!list_is_first(&hidinput->list, &hid->inputs)) + return 0; - if (report->maxfield < 1 || report->field[0]->report_count < 2) { - hid_err(hid, "Invalid report, this should never happen!\n"); - return -ENODEV; - } - - if (list_is_last(input_ptr, &hid->inputs)) { - hid_err(hid, "Missing input, this should never happen!\n"); - return -ENODEV; - } - - input_ptr = input_ptr->next; - input = list_entry(input_ptr, struct hid_input, list); + report = list_first_entry_or_null(report_list, struct hid_report, list); + if (!report) { + hid_err(hid, "no output reports found\n"); + return -ENODEV; + } - mf = kzalloc_obj(struct mf_device); - if (!mf) - return -ENOMEM; + if (report->maxfield < 1 || report->field[0]->report_count < 2) { + hid_err(hid, "Invalid report, this should never happen!\n"); + return -ENODEV; + } - dev = input->input; - set_bit(FF_RUMBLE, dev->ffbit); + mf = kzalloc_obj(struct mf_device); + if (!mf) + return -ENOMEM; - error = input_ff_create_memless(dev, mf, mf_play); - if (error) { - kfree(mf); - return error; - } + mf->report = report; + set_bit(FF_RUMBLE, dev->ffbit); - mf->report = report; - mf->report->field[0]->value[0] = 0x00; - mf->report->field[0]->value[1] = 0x00; - hid_hw_request(hid, mf->report, HID_REQ_SET_REPORT); + error = input_ff_create_memless(dev, mf, mf_play); + if (error) { + kfree(mf); + return error; } - hid_info(hid, "Force feedback for HJZ Mayflash game controller " - "adapters by Marcel Hasler <[email protected]>\n"); + mf->report->field[0]->value[0] = 0x00; + mf->report->field[0]->value[1] = 0x00; + hid_hw_request(hid, mf->report, HID_REQ_SET_REPORT); return 0; } @@ -128,22 +112,14 @@ static int mf_probe(struct hid_device *hid, const struct hid_device_id *id) return error; } - error = hid_hw_start(hid, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); + error = hid_hw_start(hid, HID_CONNECT_DEFAULT); if (error) { hid_err(hid, "HID hw start failed\n"); return error; } - error = mf_init(hid); - if (error) { - hid_err(hid, "Force feedback init failed.\n"); - hid_hw_stop(hid); - return error; - } - return 0; } - static const struct hid_device_id mf_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3), .driver_data = HID_QUIRK_MULTI_INPUT }, @@ -163,6 +139,7 @@ static struct hid_driver mf_driver = { .name = "hid_mf", .id_table = mf_devices, .probe = mf_probe, + .input_configured = mf_input_configured, }; module_hid_driver(mf_driver); -- 2.55.0.629.g250fe7f194-goog