Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dcd9006b authored by Benjamin Tissoires's avatar Benjamin Tissoires Committed by Jiri Kosina
Browse files

HID: logitech-dj: do not directly call hid_output_raw_report() during probe

hid_output_raw_report() makes a direct call to usb_control_msg(). However,
some USB3 boards have shown that the usb device is not ready during the
.probe(). This blocks the entire usb device, and the paired mice, keyboards
are not functional. The dmesg output is the following:

[   11.912287] logitech-djreceiver 0003:046D:C52B.0003: hiddev0,hidraw0: USB HID v1.11 Device [Logitech USB Receiver] on usb-0000:00:14.0-2/input2
[   11.912537] logitech-djreceiver 0003:046D:C52B.0003: logi_dj_probe:logi_dj_recv_query_paired_devices error:-32
[   11.912636] logitech-djreceiver: probe of 0003:046D:C52B.0003 failed with error -32

Relying on the scheduled call to usbhid_submit_report() fixes the problem.

related bugs:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1072082
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1039143
https://bugzilla.redhat.com/show_bug.cgi?id=840391
https://bugzilla.kernel.org/show_bug.cgi?id=49781



Reported-and-tested-by: default avatarBob Bowles <bobjohnbowles@gmail.com>
Signed-off-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 48a732df
Loading
Loading
Loading
Loading
+14 −8
Original line number Original line Diff line number Diff line
@@ -459,19 +459,25 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev,
				    struct dj_report *dj_report)
				    struct dj_report *dj_report)
{
{
	struct hid_device *hdev = djrcv_dev->hdev;
	struct hid_device *hdev = djrcv_dev->hdev;
	int sent_bytes;
	struct hid_report *report;
	struct hid_report_enum *output_report_enum;
	u8 *data = (u8 *)(&dj_report->device_index);
	int i;


	if (!hdev->hid_output_raw_report) {
	output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
		dev_err(&hdev->dev, "%s:"
	report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
			"hid_output_raw_report is null\n", __func__);

	if (!report) {
		dev_err(&hdev->dev, "%s: unable to find dj report\n", __func__);
		return -ENODEV;
		return -ENODEV;
	}
	}


	sent_bytes = hdev->hid_output_raw_report(hdev, (u8 *) dj_report,
	for (i = 0; i < report->field[0]->report_count; i++)
						 sizeof(struct dj_report),
		report->field[0]->value[i] = data[i];
						 HID_OUTPUT_REPORT);

	usbhid_submit_report(hdev, report, USB_DIR_OUT);


	return (sent_bytes < 0) ? sent_bytes : 0;
	return 0;
}
}


static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)