[PATCH 08/21] HID: gaff: 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() with HID_CONNECT_DEFAULT. 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-gaff.c | 53 ++++++++++----------------------------------------
 1 file changed, 10 insertions(+), 43 deletions(-)

diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c
index 8b99686b63df..ec793a179b47 100644
--- a/drivers/hid/hid-gaff.c
+++ b/drivers/hid/hid-gaff.c
@@ -60,32 +60,23 @@ static int hid_gaff_play(struct input_dev *dev, void *data,
 	return 0;
 }
 
-static int gaff_init(struct hid_device *hid)
+static int gaff_input_configured(struct hid_device *hid, struct hid_input *hidinput)
 {
 	struct gaff_device *gaff;
 	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(&hid->inputs)) {
-		hid_err(hid, "no inputs found\n");
-		return -ENODEV;
-	}
-	hidinput = list_entry(hid->inputs.next, struct hid_input, list);
-	dev = hidinput->input;
+	if (!list_is_first(&hidinput->list, &hid->inputs))
+		return 0;
 
-	if (list_empty(report_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;
 	}
-
-	report_ptr = report_ptr->next;
-
-	report = list_entry(report_ptr, struct hid_report, list);
 	if (report->maxfield < 1) {
 		hid_err(hid, "no fields in the report\n");
 		return -ENODEV;
@@ -100,6 +91,7 @@ static int gaff_init(struct hid_device *hid)
 	if (!gaff)
 		return -ENOMEM;
 
+	gaff->report = report;
 	set_bit(FF_RUMBLE, dev->ffbit);
 
 	error = input_ff_create_memless(dev, gaff, hid_gaff_play);
@@ -108,7 +100,6 @@ static int gaff_init(struct hid_device *hid)
 		return error;
 	}
 
-	gaff->report = report;
 	gaff->report->field[0]->value[0] = 0x51;
 	gaff->report->field[0]->value[1] = 0x00;
 	gaff->report->field[0]->value[2] = 0x00;
@@ -125,37 +116,13 @@ static int gaff_init(struct hid_device *hid)
 	return 0;
 }
 #else
-static inline int gaff_init(struct hid_device *hdev)
+static inline int gaff_input_configured(struct hid_device *hdev,
+					struct hid_input *hidinput)
 {
 	return 0;
 }
 #endif
 
-static int ga_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
-	int ret;
-
-	dev_dbg(&hdev->dev, "Greenasia HID hardware probe...");
-
-	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;
-	}
-
-	gaff_init(hdev);
-
-	return 0;
-err:
-	return ret;
-}
-
 static const struct hid_device_id ga_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012),  },
 	{ }
@@ -165,7 +132,7 @@ MODULE_DEVICE_TABLE(hid, ga_devices);
 static struct hid_driver ga_driver = {
 	.name = "greenasia",
 	.id_table = ga_devices,
-	.probe = ga_probe,
+	.input_configured = gaff_input_configured,
 };
 module_hid_driver(ga_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.