[PATCH 15/21] HID: thrustmaster: move FF initialization to .input_configured()

Dmitry Torokhov <[email protected]>
Newsgroups org.kernel.vger.linux-kernel,org.kernel.vger.linux-doc,org.kernel.vger.linux-input
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-tmff.c | 47 ++++++++++++++---------------------------------
 1 file changed, 14 insertions(+), 33 deletions(-)

diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c
index 423f395d01ac..0ed152e0dba9 100644
--- a/drivers/hid/hid-tmff.c
+++ b/drivers/hid/hid-tmff.c
@@ -115,22 +115,25 @@ static int tmff_play(struct input_dev *dev, void *data,
 	return 0;
 }
 
-static int tmff_init(struct hid_device *hid, const signed short *ff_bits)
+static int tm_input_configured(struct hid_device *hid, struct hid_input *hidinput)
 {
 	struct tmff_device *tmff;
 	struct hid_report *report;
 	struct list_head *report_list;
-	struct hid_input *hidinput;
-	struct input_dev *input_dev;
+	struct input_dev *input_dev = hidinput->input;
+	const struct hid_device_id *id;
+	const signed short *ff_bits;
 	int error;
 	int i;
 
-	if (list_empty(&hid->inputs)) {
-		hid_err(hid, "no inputs found\n");
+	if (!list_is_first(&hidinput->list, &hid->inputs))
+		return 0;
+
+	id = hid_match_device(hid, hid->driver);
+	if (!id)
 		return -ENODEV;
-	}
-	hidinput = list_entry(hid->inputs.next, struct hid_input, list);
-	input_dev = hidinput->input;
+
+	ff_bits = (void *)id->driver_data;
 
 	tmff = kzalloc_obj(struct tmff_device);
 	if (!tmff)
@@ -204,35 +207,13 @@ static int tmff_init(struct hid_device *hid, const signed short *ff_bits)
 	return error;
 }
 #else
-static inline int tmff_init(struct hid_device *hid, const signed short *ff_bits)
+static inline int tm_input_configured(struct hid_device *hid,
+				      struct hid_input *hidinput)
 {
 	return 0;
 }
 #endif
 
-static int tm_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
-	int ret;
-
-	ret = hid_parse(hdev);
-	if (ret) {
-		hid_err(hdev, "parse failed\n");
-		goto err;
-	}
-
-	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
-	if (ret) {
-		hid_err(hdev, "hw start failed\n");
-		goto err;
-	}
-
-	tmff_init(hdev, (void *)id->driver_data);
-
-	return 0;
-err:
-	return ret;
-}
-
 static const struct hid_device_id tm_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300),
 		.driver_data = (unsigned long)ff_rumble },
@@ -261,7 +242,7 @@ MODULE_DEVICE_TABLE(hid, tm_devices);
 static struct hid_driver tm_driver = {
 	.name = "thrustmaster",
 	.id_table = tm_devices,
-	.probe = tm_probe,
+	.input_configured = tm_input_configured,
 };
 module_hid_driver(tm_driver);
 

-- 
2.55.0.629.g250fe7f194-goog
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.