xairy / raw-gadget

USB Raw Gadget — a low-level interface for the Linux USB Gadget subsystem
333 stars 35 forks source link

Logitech wireless mouse AristoChen/usb-proxy proxy pass failed #35

Closed imatespl closed 1 year ago

imatespl commented 1 year ago

hi,I test Logitech wireless mouse which has two interface on oranglepc with armbian linux kernel 5.15.93, use https://github.com/AristoChen/usb-proxy,when SET_IDLE request to interface 1 raw_gadget return stalling,and then the next GET DESCRIPTOR Request HID Report also failed,I try to debug this,it like when the GET DESCRIPTOR Request HID Report on interface 0 complete,the musb-hdrc driver reset the raw_gagdet device, usb-proxy output

event: control, length: 8
  bRequestType: 0x21 (OUT), bRequest: 0x0a, wValue: 0x0000, wIndex: 0x0000, wLength: 0
  type = USB_TYPE_CLASS
  req = unknown = 0xa
ep0: transferred 0 bytes (out)
event: control, length: 8
  bRequestType: 0x81  (IN), bRequest: 0x06, wValue: 0x2200, wIndex: 0x0000, wLength: 123
  type = USB_TYPE_STANDARD
  req = USB_REQ_GET_DESCRIPTOR
  desc = unknown = 0x22
Sending data to EP0(control_in): 05 01 09 06 a1 01 05 07 19 e0 29 e7 15 00 25 01 75 01 95 08 81 02 81 03 95 05 05 08 19 01 29 05 91 02 95 01 75 03 91 01 95 06 75 08 15 00 26 a4 00 05 07 19 00 2a a4 00 81 00 c0
ep0: transferred 59 bytes (in)
event: control, length: 8
  bRequestType: 0x21 (OUT), bRequest: 0x0a, wValue: 0x0000, **wIndex: 0x0001**, wLength: 0
  type = USB_TYPE_CLASS
  req = unknown = 0xa
**ep0: stalling**
event: control, length: 8
  bRequestType: 0x81  (IN), bRequest: 0x06, wValue: 0x2200, **wIndex: 0x0001**, wLength: 241
  type = USB_TYPE_STANDARD
  req = USB_REQ_GET_DESCRIPTOR
  desc = unknown = 0x22
Sending data to EP0(control_in): 05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01 29 10 15 00 25 01 95 10 75 01 81 02 05 01 16 01 f8 26 ff 07 75 0c 95 02 09 30 09 31 81 06 15 81 25 7f 75 08 95 01 09 38 81 06 05 0c 0a 38 02 95 01 81 06 c0 c0 05 0c 09 01 a1 01 85 03 75 10 95 02 15 01 26 8c 02 19 01 2a 8c 02 81 00 c0 05 01 09 80 a1 01 85 04 75 02 95 01 15 01 25 03 09 82 09 81 09 83 81 60 75 06 81 03 c0 06 00 ff 09 01 a1 01 85 10 75 08 95 06 15 00 26 ff 00 09 01 81 00 09 01 91 00 c0 06 00 ff 09 02 a1 01 85 11 75 08 95 13 15 00 26 ff 00 09 02 81 00 09 02 91 00 c0
**ioctl(USB_RAW_IOCTL_EP0_WRITE): Device or resource busy**

dmesg

[ 1718.228210] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G        WC  E     5.15.93-sunxi #23.02.2
[ 1718.228238] Hardware name: Allwinner sun8i Family
[ 1718.228257] [<c010cd21>] (unwind_backtrace) from [<c01095f5>] (show_stack+0x11/0x14)
[ 1718.228300] [<c01095f5>] (show_stack) from [<c09e3d59>] (dump_stack_lvl+0x2b/0x34)
[ 1718.228347] [<c09e3d59>] (dump_stack_lvl) from [<c011c4c9>] (__warn+0xad/0xb0)
[ 1718.228392] [<c011c4c9>] (__warn) from [<c09dda4b>] (warn_slowpath_fmt+0x43/0x7c)
[ 1718.228433] [<c09dda4b>] (warn_slowpath_fmt) from [<c0798c77>] (usb_gadget_udc_reset+0xf/0x28)
[ 1718.228477] [<c0798c77>] (usb_gadget_udc_reset) from [<c0797ddb>] (musb_g_reset+0x15f/0x168)
[ 1718.228520] [<c0797ddb>] (musb_g_reset) from [<c07903c5>] (musb_interrupt+0x6f1/0xa64)
[ 1718.228559] [<c07903c5>] (musb_interrupt) from [<bf817721>] (sunxi_musb_interrupt+0x59/0xd0 [sunxi])
[ 1718.228608] [<bf817721>] (sunxi_musb_interrupt [sunxi]) from [<c01685c1>] (__handle_irq_event_percpu+0x41/0x12c)
[ 1718.228663] [<c01685c1>] (__handle_irq_event_percpu) from [<c01686cf>] (handle_irq_event_percpu+0x23/0x4c)
[ 1718.228710] [<c01686cf>] (handle_irq_event_percpu) from [<c0168731>] (handle_irq_event+0x39/0x50)
[ 1718.228755] [<c0168731>] (handle_irq_event) from [<c016bb6f>] (handle_fasteoi_irq+0x67/0xbc)
[ 1718.228799] [<c016bb6f>] (handle_fasteoi_irq) from [<c01680af>] (handle_domain_irq+0x43/0x58)
[ 1718.228839] [<c01680af>] (handle_domain_irq) from [<c05cca3b>] (gic_handle_irq+0x63/0x74)
[ 1718.228882] [<c05cca3b>] (gic_handle_irq) from [<c0100b97>] (__irq_svc+0x57/0x80)
[ 1718.228917] Exception stack(0xc0f01f00 to 0xc0f01f48)
[ 1718.228945] 1f00: 002d9c22 00000000 00000001 c0115601 ffffe000 00000000 c0f05068 00000001
[ 1718.228971] 1f20: c0f04fc8 00000000 c0e9aab0 00000000 c0f05130 c0f01f50 c0106dc7 c0106dc8
[ 1718.228988] 1f40: 600f0033 ffffffff
[ 1718.229003] [<c0100b97>] (__irq_svc) from [<c0106dc8>] (arch_cpu_idle+0x28/0x2c)
[ 1718.229044] [<c0106dc8>] (arch_cpu_idle) from [<c09ef27d>] (default_idle_call+0x29/0x8c)
[ 1718.229084] [<c09ef27d>] (default_idle_call) from [<c0146811>] (do_idle+0x189/0x1cc)
[ 1718.229120] [<c0146811>] (do_idle) from [<c0146ab5>] (cpu_startup_entry+0x19/0x1c)
[ 1718.229155] [<c0146ab5>] (cpu_startup_entry) from [<c0e00f5d>] (start_kernel+0x59f/0x5c6)
[ 1718.229197] ---[ end trace 5cfb5255e5748863 ]---
[ 1718.391880] raw-gadget.0 gadget: fail, wrong direction, dev->ep0_in_pending is 0, dev->ep0_out_pending is 0
[ 1718.393715] raw-gadget.0 gadget: gadget reset
[ 1718.393747] ------------[ cut here ]------------
[ 1718.393757] WARNING: CPU: 0 PID: 0 at drivers/usb/gadget/legacy/raw_gadget.c:388 usb_gadget_udc_reset+0xf/0x28
[ 1718.393800] Modules linked in: raw_gadget(E) hid_logitech_hidpp joydev input_leds hid_logitech_dj rfkill sunrpc lz4hc lz4 sun9i_hdmi_audio sunxi_cir snd_soc_hdmi_codec sun4i_gpadc_iio industrialio sun8i_thermal sunxi_cedrus(C) v4l2_mem2mem videobuf2_dma_contig videobuf2_memops videobuf2_v4l2 videobuf2_common evdev uio_pdrv_genirq uio cpufreq_dt zram sch_fq_codel ramoops pstore_blk reed_solomon pstore_zone ip_tables x_tables autofs4 sy8106a_regulator lima dw_hdmi_i2s_audio dw_hdmi_cec gpu_sched sunxi phy_generic gpio_keys display_connector
[ 1718.394110] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G        WC  E     5.15.93-sunxi #23.02.2
[ 1718.394130] Hardware name: Allwinner sun8i Family
[ 1718.394150] [<c010cd21>] (unwind_backtrace) from [<c01095f5>] (show_stack+0x11/0x14)
[ 1718.394187] [<c01095f5>] (show_stack) from [<c09e3d59>] (dump_stack_lvl+0x2b/0x34)
[ 1718.394224] [<c09e3d59>] (dump_stack_lvl) from [<c011c4c9>] (__warn+0xad/0xb0)
[ 1718.394260] [<c011c4c9>] (__warn) from [<c09dda4b>] (warn_slowpath_fmt+0x43/0x7c)
[ 1718.394291] [<c09dda4b>] (warn_slowpath_fmt) from [<c0798c77>] (usb_gadget_udc_reset+0xf/0x28)
[ 1718.394326] [<c0798c77>] (usb_gadget_udc_reset) from [<c0797ddb>] (musb_g_reset+0x15f/0x168)
[ 1718.394359] [<c0797ddb>] (musb_g_reset) from [<c07903c5>] (musb_interrupt+0x6f1/0xa64)
[ 1718.394389] [<c07903c5>] (musb_interrupt) from [<bf817721>] (sunxi_musb_interrupt+0x59/0xd0 [sunxi])
[ 1718.394424] raw-gadget.0 gadget: gadget disconnected
[ 1718.394444] ------------[ cut here ]------------
[ 1718.394432] [<bf817721>] (sunxi_musb_interrupt [sunxi]) from [<c01685c1>] (__handle_irq_event_percpu+0x41/0x12c)
[ 1718.394452] WARNING: CPU: 2 PID: 1624 at drivers/usb/gadget/legacy/raw_gadget.c:373 usb_gadget_disconnect+0x87/0x90
[ 1718.394485] Modules linked in:
[ 1718.394475] [<c01685c1>] (__handle_irq_event_percpu) from [<c01686cf>] (handle_irq_event_percpu+0x23/0x4c)
[ 1718.394495]  raw_gadget(E) hid_logitech_hidpp joydev input_leds hid_logitech_dj
[ 1718.394511] [<c01686cf>] (handle_irq_event_percpu) from [<c0168731>] (handle_irq_event+0x39/0x50)
[ 1718.394531]  rfkill sunrpc lz4hc lz4 sun9i_hdmi_audio
[ 1718.394546] [<c0168731>] (handle_irq_event) from [<c016bb6f>] (handle_fasteoi_irq+0x67/0xbc)
[ 1718.394563]  sunxi_cir snd_soc_hdmi_codec sun4i_gpadc_iio industrialio sun8i_thermal
[ 1718.394581] [<c016bb6f>] (handle_fasteoi_irq) from [<c01680af>] (handle_domain_irq+0x43/0x58)
[ 1718.394599]  sunxi_cedrus(C) v4l2_mem2mem videobuf2_dma_contig videobuf2_memops
[ 1718.394612] [<c01680af>] (handle_domain_irq) from [<c05cca3b>] (gic_handle_irq+0x63/0x74)
[ 1718.394626]  videobuf2_v4l2
[ 1718.394634]  videobuf2_common evdev uio_pdrv_genirq uio
[ 1718.394651] [<c05cca3b>] (gic_handle_irq) from [<c0100b97>] (__irq_svc+0x57/0x80)
[ 1718.394663]  cpufreq_dt zram sch_fq_codel
[ 1718.394678] Exception stack(0xc0f01f00 to 0xc0f01f48)
[ 1718.394683]  ramoops pstore_blk reed_solomon
[ 1718.394703] 1f00: 002d9e78 00000000 00000001 c0115601 ffffe000 00000000 c0f05068 00000001
[ 1718.394724] 1f20: c0f04fc8 00000000 c0e9aab0 00000000 c0f03d00 c0f01f50 c0106dc7 c0106dc8
[ 1718.394735]  pstore_zone
[ 1718.394738] 1f40: 600b0033 ffffffff
[ 1718.394749]  ip_tables x_tables
[ 1718.394749] [<c0100b97>] (__irq_svc) from [<c0106dc8>] (arch_cpu_idle+0x28/0x2c)
[ 1718.394763]  autofs4 sy8106a_regulator lima dw_hdmi_i2s_audio
[ 1718.394779] [<c0106dc8>] (arch_cpu_idle) from [<c09ef27d>] (default_idle_call+0x29/0x8c)
[ 1718.394792]  dw_hdmi_cec gpu_sched sunxi phy_generic gpio_keys
[ 1718.394813] [<c09ef27d>] (default_idle_call) from [<c0146811>] (do_idle+0x189/0x1cc)
[ 1718.394826]  display_connector
[ 1718.394840] [<c0146811>] (do_idle) from [<c0146ab5>] (cpu_startup_entry+0x19/0x1c)
[ 1718.394868] [<c0146ab5>] (cpu_startup_entry) from [<c0e00f5d>] (start_kernel+0x59f/0x5c6)
[ 1718.394901] ---[ end trace 5cfb5255e5748864 ]---
[ 1718.394902] CPU: 2 PID: 1624 Comm: usb-proxy Tainted: G        WC  E     5.15.93-sunxi #23.02.2
[ 1718.394923] Hardware name: Allwinner sun8i Family
[ 1718.394935] [<c010cd21>] (unwind_backtrace) from [<c01095f5>] (show_stack+0x11/0x14)
[ 1718.394969] [<c01095f5>] (show_stack) from [<c09e3d59>] (dump_stack_lvl+0x2b/0x34)
[ 1718.395002] [<c09e3d59>] (dump_stack_lvl) from [<c011c4c9>] (__warn+0xad/0xb0)
[ 1718.395036] [<c011c4c9>] (__warn) from [<c09dda4b>] (warn_slowpath_fmt+0x43/0x7c)
[ 1718.395066] [<c09dda4b>] (warn_slowpath_fmt) from [<c0798b27>] (usb_gadget_disconnect+0x87/0x90)
[ 1718.395102] [<c0798b27>] (usb_gadget_disconnect) from [<c0799791>] (usb_gadget_remove_driver+0x21/0x90)
[ 1718.395138] [<c0799791>] (usb_gadget_remove_driver) from [<c0799907>] (usb_gadget_unregister_driver+0x73/0x9c)
[ 1718.395174] [<c0799907>] (usb_gadget_unregister_driver) from [<bf970aeb>] (raw_release+0x3f/0xdc [raw_gadget])
[ 1718.395229] [<bf970aeb>] (raw_release [raw_gadget]) from [<c0296993>] (__fput+0x4f/0x1b0)
[ 1718.395272] [<c0296993>] (__fput) from [<c0134785>] (task_work_run+0x7d/0xa0)
[ 1718.395304] [<c0134785>] (task_work_run) from [<c0120825>] (do_exit+0x359/0x86c)
[ 1718.395333] [<c0120825>] (do_exit) from [<c0120deb>] (do_group_exit+0x2f/0x84)
[ 1718.395359] [<c0120deb>] (do_group_exit) from [<c012a29d>] (get_signal+0x159/0x7c4)
[ 1718.395388] [<c012a29d>] (get_signal) from [<c010919d>] (do_work_pending+0x369/0x454)
[ 1718.395415] [<c010919d>] (do_work_pending) from [<c01000c7>] (slow_work_pending+0x9/0x16)
[ 1718.395440] Exception stack(0xc1635fb0 to 0xc1635ff8)
[ 1718.395458] 5fa0:                                     00000000 00000000 b639dc30 b639dc28
[ 1718.395478] 5fc0: 00000000 b639dc80 00000000 00000109 b639e380 00000001 00000000 00000000
[ 1718.395495] 5fe0: 00000109 b639dc18 b6c53a87 b6bedb04 80000030 00000000
[ 1718.395508] ---[ end trace 5cfb5255e5748865 ]---
imatespl commented 1 year ago

Sorry, is the libusb mode the error, event: control, length: 8 bRequestType: 0x21 (OUT), bRequest: 0x0a, wValue: 0x0000, **wIndex: 0x0001**, wLength: 0 type = USB_TYPE_CLASS req = unknown = 0xa **ep0: stalling** this is make the raw_gaget device halt,and then next request failed, this code result is -1 https://github.com/AristoChen/usb-proxy/blob/6aecd455b2ef3d6734ab92105ca00c01464d4030/proxy.cpp#L490

xairy commented 1 year ago

Please try https://github.com/AristoChen/usb-proxy/pull/6.

imatespl commented 1 year ago

ooh! very thanks, i will try it

imatespl commented 1 year ago

hi @xairy I test the code https://github.com/AristoChen/usb-proxy/pull/6, there two issues.

  1. my mouse is a low speed device, and it response the MaxPageSize0 is 0x08, it should change the MaxPackageSize0 0x40, 0x08 make the raw_gadget which use device musb-hdrc.4.auto dead loop,
  2. ignore usb_raw_ep0_stall when SET_IDLE request to interface 1,it like in linux don't support this request, in proxy.cpp:499 event: control, length: 8 bRequestType: 0x21 (OUT), bRequest: 0x0a, wValue: 0x0000, wIndex: 0x0001, wLength: 0 type = USB_TYPE_CLASS req = unknown = 0xa ep0: stalling I add this code in ep0_loop
--- a/proxy.cpp
+++ b/proxy.cpp
@@ -368,6 +368,12 @@ void ep0_loop(int fd) {
                                                break;
                                        }
                                }
+                               if ((event.ctrl.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD &&
+                                       event.ctrl.bRequest == USB_REQ_GET_DESCRIPTOR &&
+                                       (event.ctrl.wValue >> 8) == USB_DT_DEVICE) {
+                                       struct usb_device_descriptor* pdata = (struct usb_device_descriptor*)&io.data;
+                                       pdata->bMaxPacketSize0 = 64;
+                               }

                                if (verbose_level >= 2)
                                        printData(io, 0x00, "control", "in");
@@ -495,7 +501,14 @@ void ep0_loop(int fd) {
                                        printf("ep0: transferred %d bytes (out)\n", rv);
                                }
                                else {
-                                       usb_raw_ep0_stall(fd);
+                                       if (event.ctrl.bRequestType == 0x21
+                                               && event.ctrl.bRequest == 0x0a
+                                               && event.ctrl.wIndex != 0) {
+                                               continue;
+                                       }
+                                       else {
+                                               usb_raw_ep0_stall(fd);
+                                       }
                                }
                        }
                }