[PATCH 18/21] HID: smartjoyplus: 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-sjoy.c | 83 +++++++++++++++++++++-----------------------------
 1 file changed, 34 insertions(+), 49 deletions(-)

diff --git a/drivers/hid/hid-sjoy.c b/drivers/hid/hid-sjoy.c
index 963c45113204..193ab2a6146e 100644
--- a/drivers/hid/hid-sjoy.c
+++ b/drivers/hid/hid-sjoy.c
@@ -48,68 +48,56 @@ static int hid_sjoyff_play(struct input_dev *dev, void *data,
 	return 0;
 }
 
-static int sjoyff_init(struct hid_device *hid)
+static int sjoy_input_configured(struct hid_device *hid, struct hid_input *hidinput)
 {
 	struct sjoyff_device *sjoyff;
 	struct hid_report *report;
-	struct hid_input *hidinput;
 	struct list_head *report_list =
 			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
-	struct list_head *report_ptr = report_list;
-	struct input_dev *dev;
+	struct input_dev *dev = hidinput->input;
 	int error;
 
-	if (list_empty(report_list)) {
+	if (!list_is_first(&hidinput->list, &hid->inputs))
+		return 0;
+
+	report = list_first_entry_or_null(report_list, struct hid_report, list);
+	if (!report) {
 		hid_err(hid, "no output reports found\n");
 		return -ENODEV;
 	}
+	if (report->maxfield < 1) {
+		hid_err(hid, "no fields in the report\n");
+		return -ENODEV;
+	}
 
-	list_for_each_entry(hidinput, &hid->inputs, list) {
-		report_ptr = report_ptr->next;
-
-		if (report_ptr == report_list) {
-			hid_err(hid, "required output report is missing\n");
-			return -ENODEV;
-		}
-
-		report = list_entry(report_ptr, struct hid_report, list);
-		if (report->maxfield < 1) {
-			hid_err(hid, "no fields in the report\n");
-			return -ENODEV;
-		}
-
-		if (report->field[0]->report_count < 3) {
-			hid_err(hid, "not enough values in the field\n");
-			return -ENODEV;
-		}
-
-		sjoyff = kzalloc_obj(struct sjoyff_device);
-		if (!sjoyff)
-			return -ENOMEM;
+	if (report->field[0]->report_count < 3) {
+		hid_err(hid, "not enough values in the field\n");
+		return -ENODEV;
+	}
 
-		dev = hidinput->input;
+	sjoyff = kzalloc_obj(struct sjoyff_device);
+	if (!sjoyff)
+		return -ENOMEM;
 
-		set_bit(FF_RUMBLE, dev->ffbit);
+	set_bit(FF_RUMBLE, dev->ffbit);
 
-		sjoyff->report = report;
-		sjoyff->report->field[0]->value[0] = 0x01;
-		sjoyff->report->field[0]->value[1] = 0x00;
-		sjoyff->report->field[0]->value[2] = 0x00;
-		hid_hw_request(hid, sjoyff->report, HID_REQ_SET_REPORT);
+	sjoyff->report = report;
+	sjoyff->report->field[0]->value[0] = 0x01;
+	sjoyff->report->field[0]->value[1] = 0x00;
+	sjoyff->report->field[0]->value[2] = 0x00;
+	hid_hw_request(hid, sjoyff->report, HID_REQ_SET_REPORT);
 
-		error = input_ff_create_memless(dev, sjoyff, hid_sjoyff_play);
-		if (error) {
-			kfree(sjoyff);
-			return error;
-		}
+	error = input_ff_create_memless(dev, sjoyff, hid_sjoyff_play);
+	if (error) {
+		kfree(sjoyff);
+		return error;
 	}
 
-	hid_info(hid, "Force feedback for SmartJoy PLUS PS2/USB adapter\n");
-
 	return 0;
 }
 #else
-static inline int sjoyff_init(struct hid_device *hid)
+static inline int sjoy_input_configured(struct hid_device *hid,
+					struct hid_input *hidinput)
 {
 	return 0;
 }
@@ -124,20 +112,16 @@ static int sjoy_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;
+		return ret;
 	}
 
-	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
+	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
 	if (ret) {
 		hid_err(hdev, "hw start failed\n");
-		goto err;
+		return ret;
 	}
 
-	sjoyff_init(hdev);
-
 	return 0;
-err:
-	return ret;
 }
 
 static const struct hid_device_id sjoy_devices[] = {
@@ -165,6 +149,7 @@ static struct hid_driver sjoy_driver = {
 	.name = "smartjoyplus",
 	.id_table = sjoy_devices,
 	.probe = sjoy_probe,
+	.input_configured = sjoy_input_configured,
 };
 module_hid_driver(sjoy_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.