@@ -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+ */
344372static 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+ */
376411static 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