Skip to content

Commit a8da334

Browse files
author
Benjamin Tissoires
committed
Merge branch 'for-6.6/logitech' into for-linus
Various new device ID addition and a couple of HID++ fixes to tackle the last few opened bugs (Nikita Zhandarovich and Benjamin Tissoires)
2 parents a48e760 + 60165ab commit a8da334

File tree

3 files changed

+93
-45
lines changed

3 files changed

+93
-45
lines changed

drivers/hid/hid-ids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,7 @@
867867
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2 0xc534
868868
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 0xc539
869869
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f
870+
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2 0xc547
870871
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a
871872
#define USB_DEVICE_ID_SPACETRAVELLER 0xc623
872873
#define USB_DEVICE_ID_SPACENAVIGATOR 0xc626

drivers/hid/hid-logitech-dj.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,6 +1285,9 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
12851285
* 50 msec should gives enough time to the receiver to be ready.
12861286
*/
12871287
msleep(50);
1288+
1289+
if (retval)
1290+
return retval;
12881291
}
12891292

12901293
/*
@@ -1306,7 +1309,7 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
13061309
buf[5] = 0x09;
13071310
buf[6] = 0x00;
13081311

1309-
hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf,
1312+
retval = hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf,
13101313
HIDPP_REPORT_SHORT_LENGTH, HID_OUTPUT_REPORT,
13111314
HID_REQ_SET_REPORT);
13121315

@@ -1692,11 +1695,12 @@ static int logi_dj_raw_event(struct hid_device *hdev,
16921695
}
16931696
/*
16941697
* Mouse-only receivers send unnumbered mouse data. The 27 MHz
1695-
* receiver uses 6 byte packets, the nano receiver 8 bytes.
1698+
* receiver uses 6 byte packets, the nano receiver 8 bytes,
1699+
* the lightspeed receiver (Pro X Superlight) 13 bytes.
16961700
*/
16971701
if (djrcv_dev->unnumbered_application == HID_GD_MOUSE &&
1698-
size <= 8) {
1699-
u8 mouse_report[9];
1702+
size <= 13){
1703+
u8 mouse_report[14];
17001704

17011705
/* Prepend report id */
17021706
mouse_report[0] = REPORT_TYPE_MOUSE;
@@ -1980,6 +1984,10 @@ static const struct hid_device_id logi_dj_receivers[] = {
19801984
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
19811985
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1),
19821986
.driver_data = recvr_type_gaming_hidpp},
1987+
{ /* Logitech lightspeed receiver (0xc547) */
1988+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1989+
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2),
1990+
.driver_data = recvr_type_gaming_hidpp},
19831991

19841992
{ /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */
19851993
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),

drivers/hid/hid-logitech-hidpp.c

Lines changed: 80 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ struct hidpp_device {
228228
#define HIDPP20_ERROR_INVALID_ARGS 0x02
229229
#define HIDPP20_ERROR_OUT_OF_RANGE 0x03
230230
#define HIDPP20_ERROR_HW_ERROR 0x04
231-
#define HIDPP20_ERROR_LOGITECH_INTERNAL 0x05
231+
#define HIDPP20_ERROR_NOT_ALLOWED 0x05
232232
#define HIDPP20_ERROR_INVALID_FEATURE_INDEX 0x06
233233
#define HIDPP20_ERROR_INVALID_FUNCTION_ID 0x07
234234
#define HIDPP20_ERROR_BUSY 0x08
@@ -275,21 +275,22 @@ static int __hidpp_send_report(struct hid_device *hdev,
275275
}
276276

277277
/*
278-
* hidpp_send_message_sync() returns 0 in case of success, and something else
279-
* in case of a failure.
280-
* - If ' something else' is positive, that means that an error has been raised
281-
* by the protocol itself.
282-
* - If ' something else' is negative, that means that we had a classic error
283-
* (-ENOMEM, -EPIPE, etc...)
278+
* Effectively send the message to the device, waiting for its answer.
279+
*
280+
* Must be called with hidpp->send_mutex locked
281+
*
282+
* Same return protocol than hidpp_send_message_sync():
283+
* - success on 0
284+
* - negative error means transport error
285+
* - positive value means protocol error
284286
*/
285-
static int hidpp_send_message_sync(struct hidpp_device *hidpp,
287+
static int __do_hidpp_send_message_sync(struct hidpp_device *hidpp,
286288
struct hidpp_report *message,
287289
struct hidpp_report *response)
288290
{
289-
int ret = -1;
290-
int max_retries = 3;
291+
int ret;
291292

292-
mutex_lock(&hidpp->send_mutex);
293+
__must_hold(&hidpp->send_mutex);
293294

294295
hidpp->send_receive_buf = response;
295296
hidpp->answer_available = false;
@@ -300,47 +301,74 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp,
300301
*/
301302
*response = *message;
302303

303-
for (; max_retries != 0 && ret; max_retries--) {
304-
ret = __hidpp_send_report(hidpp->hid_dev, message);
304+
ret = __hidpp_send_report(hidpp->hid_dev, message);
305+
if (ret) {
306+
dbg_hid("__hidpp_send_report returned err: %d\n", ret);
307+
memset(response, 0, sizeof(struct hidpp_report));
308+
return ret;
309+
}
305310

306-
if (ret) {
307-
dbg_hid("__hidpp_send_report returned err: %d\n", ret);
308-
memset(response, 0, sizeof(struct hidpp_report));
309-
break;
310-
}
311+
if (!wait_event_timeout(hidpp->wait, hidpp->answer_available,
312+
5*HZ)) {
313+
dbg_hid("%s:timeout waiting for response\n", __func__);
314+
memset(response, 0, sizeof(struct hidpp_report));
315+
return -ETIMEDOUT;
316+
}
311317

312-
if (!wait_event_timeout(hidpp->wait, hidpp->answer_available,
313-
5*HZ)) {
314-
dbg_hid("%s:timeout waiting for response\n", __func__);
315-
memset(response, 0, sizeof(struct hidpp_report));
316-
ret = -ETIMEDOUT;
317-
break;
318-
}
318+
if (response->report_id == REPORT_ID_HIDPP_SHORT &&
319+
response->rap.sub_id == HIDPP_ERROR) {
320+
ret = response->rap.params[1];
321+
dbg_hid("%s:got hidpp error %02X\n", __func__, ret);
322+
return ret;
323+
}
319324

320-
if (response->report_id == REPORT_ID_HIDPP_SHORT &&
321-
response->rap.sub_id == HIDPP_ERROR) {
322-
ret = response->rap.params[1];
323-
dbg_hid("%s:got hidpp error %02X\n", __func__, ret);
325+
if ((response->report_id == REPORT_ID_HIDPP_LONG ||
326+
response->report_id == REPORT_ID_HIDPP_VERY_LONG) &&
327+
response->fap.feature_index == HIDPP20_ERROR) {
328+
ret = response->fap.params[1];
329+
dbg_hid("%s:got hidpp 2.0 error %02X\n", __func__, ret);
330+
return ret;
331+
}
332+
333+
return 0;
334+
}
335+
336+
/*
337+
* hidpp_send_message_sync() returns 0 in case of success, and something else
338+
* in case of a failure.
339+
*
340+
* See __do_hidpp_send_message_sync() for a detailed explanation of the returned
341+
* value.
342+
*/
343+
static int hidpp_send_message_sync(struct hidpp_device *hidpp,
344+
struct hidpp_report *message,
345+
struct hidpp_report *response)
346+
{
347+
int ret;
348+
int max_retries = 3;
349+
350+
mutex_lock(&hidpp->send_mutex);
351+
352+
do {
353+
ret = __do_hidpp_send_message_sync(hidpp, message, response);
354+
if (ret != HIDPP20_ERROR_BUSY)
324355
break;
325-
}
326356

327-
if ((response->report_id == REPORT_ID_HIDPP_LONG ||
328-
response->report_id == REPORT_ID_HIDPP_VERY_LONG) &&
329-
response->fap.feature_index == HIDPP20_ERROR) {
330-
ret = response->fap.params[1];
331-
if (ret != HIDPP20_ERROR_BUSY) {
332-
dbg_hid("%s:got hidpp 2.0 error %02X\n", __func__, ret);
333-
break;
334-
}
335-
dbg_hid("%s:got busy hidpp 2.0 error %02X, retrying\n", __func__, ret);
336-
}
337-
}
357+
dbg_hid("%s:got busy hidpp 2.0 error %02X, retrying\n", __func__, ret);
358+
} while (--max_retries);
338359

339360
mutex_unlock(&hidpp->send_mutex);
340361
return ret;
341362

342363
}
343364

365+
/*
366+
* hidpp_send_fap_command_sync() returns 0 in case of success, and something else
367+
* in case of a failure.
368+
*
369+
* See __do_hidpp_send_message_sync() for a detailed explanation of the returned
370+
* value.
371+
*/
344372
static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp,
345373
u8 feat_index, u8 funcindex_clientid, u8 *params, int param_count,
346374
struct hidpp_report *response)
@@ -373,6 +401,13 @@ static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp,
373401
return ret;
374402
}
375403

404+
/*
405+
* hidpp_send_rap_command_sync() returns 0 in case of success, and something else
406+
* in case of a failure.
407+
*
408+
* See __do_hidpp_send_message_sync() for a detailed explanation of the returned
409+
* value.
410+
*/
376411
static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev,
377412
u8 report_id, u8 sub_id, u8 reg_address, u8 *params, int param_count,
378413
struct hidpp_report *response)
@@ -4620,6 +4655,8 @@ static const struct hid_device_id hidpp_devices[] = {
46204655
.driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS },
46214656
{ /* Logitech G Pro Gaming Mouse over USB */
46224657
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC088) },
4658+
{ /* Logitech G Pro X Superlight Gaming Mouse over USB */
4659+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC094) },
46234660

46244661
{ /* G935 Gaming Headset */
46254662
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0x0a87),
@@ -4647,6 +4684,8 @@ static const struct hid_device_id hidpp_devices[] = {
46474684
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb02a) },
46484685
{ /* MX Master 3 mouse over Bluetooth */
46494686
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb023) },
4687+
{ /* MX Anywhere 3 mouse over Bluetooth */
4688+
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb025) },
46504689
{ /* MX Master 3S mouse over Bluetooth */
46514690
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb034) },
46524691
{}

0 commit comments

Comments
 (0)