Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

error Proxing a keyboard: ioctl(USB_RAW_IOCTL_EP0_WRITE): Cannot send after transport endpoint shutdown #4

Closed
Alphadan28 opened this issue Oct 17, 2022 · 23 comments · Fixed by #6

Comments

@Alphadan28
Copy link

first of all thanks for sharing your work, I successfuly proxied a ethernet adapter but fails with all HID i have

pi@raspberrypi:~/usb-proxy $ sudo ./usb-proxy --device=fe980000.usb --driver=fe980000.usb --vendor_id=1997 --product_id=2433
Device is: fe980000.usb
Driver is: fe980000.usb
vendor_id is: 6551
product_id is: 9267
Device opened successfully
Start hotplug_monitor thread, thread id(2326)
Setup USB config successfully
Start for EP0, thread id(2324)
event: connect, length: 0
event: control, length: 8
bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0100, wIndex: 0x0000, wLength: 64
type = USB_TYPE_STANDARD
req = USB_REQ_GET_DESCRIPTOR
desc = USB_DT_DEVICE
ep0: transferred 18 bytes (in)
event: control, length: 8
bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0100, wIndex: 0x0000, wLength: 18
type = USB_TYPE_STANDARD
req = USB_REQ_GET_DESCRIPTOR
desc = USB_DT_DEVICE
ep0: transferred 18 bytes (in)
event: control, length: 8
bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0200, wIndex: 0x0000, wLength: 255
type = USB_TYPE_STANDARD
req = USB_REQ_GET_DESCRIPTOR
desc = USB_DT_CONFIG
ioctl(USB_RAW_IOCTL_EP0_WRITE): Cannot send after transport endpoint shutdown

Any idea whats causing this?

@Alphadan28
Copy link
Author

I noticed in this block: ` setup_host_usb_desc();
printf("Setup USB config successfully\n");

int fd = usb_raw_open();
usb_raw_init(fd, USB_SPEED_HIGH, driver, device);
usb_raw_run(fd);

`
that the USB_SPEED_HIGH mode is hard-coded changed that to low speed and seems better at least tries to transfer data but sill the target machine doesn't identifies the device. (this test was made with a mini wireless keyboard i suspect it uses USB LOW SPEED)

@AristoChen
Copy link
Owner

Hi,

Thank you for spending time playing around with this project!

Could you please provide the output of the following command?

  • lsusb -t
  • lsusb -v -d 1997:2433

@Alphadan28
Copy link
Author

the project is unique, and have learn a lot about USB thanks to this project

lsusb -t
/: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=dwc2/1p, 480M
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M < ------------------------- this is the mini keyboard
|__ Port 3: Dev 4, If 0, Class=Human Interface Device, Driver=usbhid, 12M
|__ Port 3: Dev 4, If 1, Class=Human Interface Device, Driver=usbhid, 12M

the mini keyboard shows as 2 devices, I guess the first is a internal hub then the keyboard itself and the touch pad as a mouse.

lsusb -v -d 1997:2433

Bus 001 Device 004: ID 1997:2433 Shenzhen Riitek Technology Co., Ltd wireless mini keyboard with touchpad
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 32
idVendor 0x1997 Shenzhen Riitek Technology Co., Ltd
idProduct 0x2433 wireless mini keyboard with touchpad
bcdDevice 1.10
iManufacturer 1
iProduct 2 mini keyboard
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x003b
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 1 Keyboard
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.01
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 77
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0020 1x 32 bytes
bInterval 8
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 2 Mouse
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.01
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 116
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0020 1x 32 bytes
bInterval 1

@Alphadan28
Copy link
Author

Alphadan28 commented Oct 25, 2022

update: ran it with level 2 verbose and this is the output

Device is: fe980000.usb
Driver is: fe980000.usb
vendor_id is: 0x1997
product_id is: 0x2433
verbose_level: 2
5 Devices in list
Target device not found
Device opened successfully
Setup USB config successfully
Start hotplug_monitor thread, thread id(2697)
Start for EP0, thread id(2695)
ep #0:
name: ep1in
addr: 1
type: iso blk int
dir : in ___
maxpacket_limit: 1024
max_streams: 0
ep #1:
name: ep1out
addr: 1
type: iso blk int
dir : ___ out
maxpacket_limit: 1024
max_streams: 0
ep #2:
name: ep2in
addr: 2
type: iso blk int
dir : in ___
maxpacket_limit: 1024
max_streams: 0
ep #3:
name: ep2out
addr: 2
type: iso blk int
dir : ___ out
maxpacket_limit: 1024
max_streams: 0
ep #4:
name: ep3in
addr: 3
type: iso blk int
dir : in ___
maxpacket_limit: 1024
max_streams: 0
ep #5:
name: ep3out
addr: 3
type: iso blk int
dir : ___ out
maxpacket_limit: 1024
max_streams: 0
ep #6:
name: ep4in
addr: 4
type: iso blk int
dir : in ___
maxpacket_limit: 1024
max_streams: 0
ep #7:
name: ep4out
addr: 4
type: iso blk int
dir : ___ out
maxpacket_limit: 1024
max_streams: 0
ep #8:
name: ep5in
addr: 5
type: iso blk int
dir : in ___
maxpacket_limit: 1024
max_streams: 0
ep #9:
name: ep5out
addr: 5
type: iso blk int
dir : ___ out
maxpacket_limit: 1024
max_streams: 0
ep #10:
name: ep6in
addr: 6
type: iso blk int
dir : in ___
maxpacket_limit: 1024
max_streams: 0
ep #11:
name: ep6out
addr: 6
type: iso blk int
dir : ___ out
maxpacket_limit: 1024
max_streams: 0
ep #12:
name: ep7in
addr: 7
type: iso blk int
dir : in ___
maxpacket_limit: 1024
max_streams: 0
ep #13:
name: ep7out
addr: 7
type: iso blk int
dir : ___ out
maxpacket_limit: 1024
max_streams: 0
event: connect, length: 0
event: control, length: 8
bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0100, wIndex: 0x0000, wLength: 64
type = USB_TYPE_STANDARD
req = USB_REQ_GET_DESCRIPTOR
desc = USB_DT_DEVICE
Control transfer succeed
Sending data to EP0(control_in): 12 01 10 01 00 00 00 20 97 19 33 24 10 01 01 02 00 01
ep0: transferred 18 bytes (in)
event: control, length: 8
bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0100, wIndex: 0x0000, wLength: 18
type = USB_TYPE_STANDARD
req = USB_REQ_GET_DESCRIPTOR
desc = USB_DT_DEVICE
Control transfer succeed
Sending data to EP0(control_in): 12 01 10 01 00 00 00 20 97 19 33 24 10 01 01 02 00 01
ep0: transferred 18 bytes (in)
event: control, length: 8
bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0200, wIndex: 0x0000, wLength: 255
type = USB_TYPE_STANDARD
req = USB_REQ_GET_DESCRIPTOR
desc = USB_DT_CONFIG
Control transfer succeed
Sending data to EP0(control_in): 09 02 3b 00 02 01 00 a0 32 09 04 00 00 01 03 01 01 00 09 21 01 01 00 01 22 4d 00 07 05 81 03 20 00 08 09 04 01 00 01 03 01 02 00 09 21 01 01 00 01 22 74 00 07 05 82 03 20 00 01
ioctl(USB_RAW_IOCTL_EP0_WRITE): Cannot send after transport endpoint shutdown

the error comes from proxy.cpp > void ep0_loop(int fd) >rv = usb_raw_ep0_write(fd, (struct usb_raw_ep_io *)&io); //line: 379

seems like somehow host or device closes fd, i been doing tests with USBPCAP and Wireshark and in the capture taken from the target host machine doesn't even get any device request.

would you point me were to look at?

if helps this is the traffic of the device conected directly to the host (no proxy) in PCAP format.
https://www.sendspace.com/file/7pguoa

this is the usb traffic recived in the target host with proxy enabled, only 6 interrupt packets, but no device request or response or anything.
https://www.sendspace.com/file/f5rm2s

@AristoChen
Copy link
Owner

Hi,

Thanks for sharing the info, sorry that I don't have time recently because I am on a business trip in Europe, I will check this out when I am back to my hometown

@Alphadan28
Copy link
Author

don't worry bro, good luck in your travel, I feel this project is unique and has future there are only 2 proxy USB projects with this one included available, just remember to throw a hand to the project when you have time.

@Alphadan28
Copy link
Author

update:
The problem happens when the descriptor to send by this function: usb_raw_ep0_write is bigger than the max packet size for EP0
In this particular case with the mini keyboard the device responds with usb.bMaxPacketSize0=32 (sniffed from windows with USBPCAP) and the descriptor usb_raw_ep0_write is trying to send is 59 bytes when this condition happens:

Configuration descriptor > usb.bMaxPacketSize0

we get this error: ioctl(USB_RAW_IOCTL_EP0_WRITE): Cannot send after transport endpoint shutdown it feels like the endpoint is expecting the configuration descriptor in 2 parts one of the full packet size and other with the rest but when it tries to send all the 59 at once it fails. i tested with other devices and this issue repeats when such conditions meet.

all devices that work on high speed have 64 bytes in ep0, haven't found a device that fails for having a configuration descriptor bigger than 64bytes but I'm guessing it could happen too.

but most high speed devices pass this part then fail somewhere else but I'm trying to solve this issue first but i lack of the knowledge YET to complete this.

@AristoChen
Copy link
Owner

Hi,

May I know where did you get the mini keyboard? I am thinking that if it is not too expensive, I might buy one to debug this issue

For the bMaxPacketSize0 that you mentioned, maybe you can try to manually set this value higher

.bMaxPacketSize0 = device_device_desc.bMaxPacketSize0,

BTW, I am not a USB expert as well, and AFAIK there are some buggy USB devices that might require special driver to work, or possibly need to setup some USB quirks in kernel module, which means that this project might not be able to handle that special case

@Alphadan28
Copy link
Author

this is the mini keyboard:
https://www.amazon.es/Rii-K12-Mini-touchpad-inoxidable/dp/B00ZCFTT00/

but may be you don't need to buy it, I can run any tests for you and provide logs or pcaps.

My mouse has a issue that looked like the same problem but now i made deeper tests.

The mouse is a death adder V2 which has a bMaxPacketSize0 of 64 bytes but its configuration descriptor is 84 bytes but in this case it manages to send the descriptor even though is bigger than the bMaxPacketSize0.

so after running it with verbose level 2:
event: control, length: 8
bRequestType: 0x21 (OUT), bRequest: 0x09, wValue: 0x0300, wIndex: 0x0000, wLength: 90
type = USB_TYPE_CLASS
req = unknown = 0x9
Sending data to EP0(control_out): 00 1f 00 00 00 08 0f 03 00 00 00 00 00 00 00 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fb 00
Control transfer succeed
ep0: transferred 90 bytes (out)

it seems to be sending the descriptor without problem...

but crashes only after I move the mouse

in this case crashes when trying to send a interrupt with the movement data:

EP81(int_in): enqueued 8 bytes to queue
Sending data to EP81(int_in): 00 fe 00 00 fe ff 00 00
ioctl(USB_RAW_IOCTL_EP_WRITE): Cannot send after transport endpoint shutdown.

now this makes me wonder if the problem is the size of the descriptor or if is something else because in this case the descriptor is also bigger than the bMaxPacketSize0 but it sends the descriptor.

.bMaxPacketSize0 = device_device_desc.bMaxPacketSize0, about this line i tried that already harcoded it to 64 bytes and also hardcoded usb.bcdDevice = 0x0200 but it gives the same result.

I made this test because this project: https://github.com/nesto-software/USBProxy manages to proxy that mini keyboard just fine but that project fails with every other device I have, it uses GadgetFS instead of Raw Gadget, Proxied using that project to see whats different and how it sends the descriptor and what I found in the pcap was that the mini keyboard shows in the device descriptor MaxPacketSize0 = 64 which is weird because that device conected directly reports its MaxPacketSize0 = 32 and also usb.bcdDevice = 0x0200 instead of usb.bcdDevice = 0x0110 (which is its original value) its like that other proxy somehow changes these values.

This problems are interesting every time I get a hypothesis it always results in something else after few days.

@xairy
Copy link
Contributor

xairy commented Nov 4, 2022

@Alphadan28 Could you change USB_SPEED_HIGH to USB_SPEED_FULL in the arguments of usb_raw_init and see if that makes any difference (for the device that fails because of bMaxPacketSize0 being 32)?

@Alphadan28
Copy link
Author

sure this is the result: connecting as USB_SPEED_FULL instead of USB_SPEED_HIGH

Device is: fe980000.usb
Driver is: fe980000.usb
vendor_id is: 6551
product_id is: 9267
Device opened successfully
Start hotplug_monitor thread, thread id(2631)
Setup USB config successfully
Start for EP0, thread id(2629)
event: connect, length: 0
event: control, length: 8
bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0100, wIndex: 0x0000, wLength: 64
type = USB_TYPE_STANDARD
req = USB_REQ_GET_DESCRIPTOR
desc = USB_DT_DEVICE
ep0: transferred 18 bytes (in)
event: control, length: 8
bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0100, wIndex: 0x0000, wLength: 18
type = USB_TYPE_STANDARD
req = USB_REQ_GET_DESCRIPTOR
desc = USB_DT_DEVICE
ep0: transferred 18 bytes (in)
event: control, length: 8
bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0200, wIndex: 0x0000, wLength: 255
type = USB_TYPE_STANDARD
req = USB_REQ_GET_DESCRIPTOR
desc = USB_DT_CONFIG
ioctl(USB_RAW_IOCTL_EP0_WRITE): Cannot send after transport endpoint shutdown

and dmesg output:

[ 3458.920575] hwmon hwmon1: Undervoltage detected!
[ 3467.240672] hwmon hwmon1: Voltage normalised
[ 3471.400790] hwmon hwmon1: Undervoltage detected!
[ 3483.880773] hwmon hwmon1: Voltage normalised
[ 3603.254003] dwc2 fe980000.usb: bound driver raw-gadget.0
[ 3603.433015] dwc2 fe980000.usb: new device is full-speed
[ 3603.487987] dwc2 fe980000.usb: new device is full-speed
[ 3603.522760] dwc2 fe980000.usb: new address 45
[ 3604.042229] raw-gadget.0 gadget: Gadget Disconect
[ 3604.047030] dwc2 fe980000.usb: new device is full-speed
[ 3604.047062] raw-gadget.0 gadget: Gadget Disconect

@xairy
Copy link
Contributor

xairy commented Dec 9, 2022

Alphadan28, could you please try proxying the device with the Dummy HCD controller instead of dwc2 (you need to build and load dummy_hcd from the Raw Gadget repository and provide no --device/driver arguments to USB-Proxy)? And if it fails, could you please share the PCAP of the USB traffic?

@xairy
Copy link
Contributor

xairy commented Dec 9, 2022

And also, could you apply the following patch to raw_gadget.c and share dmesg output (there will be a lot of WARNINGs printed, please include them all):

diff --git a/raw_gadget/raw_gadget.c b/raw_gadget/raw_gadget.c
index 5eedee5..d79b690 100644
--- a/raw_gadget/raw_gadget.c
+++ b/raw_gadget/raw_gadget.c
@@ -7,6 +7,8 @@
  * Author: Andrey Konovalov <andreyknvl@gmail.com>
  */
 
+#define DEBUG
+
 #include <linux/compiler.h>
 #include <linux/ctype.h>
 #include <linux/debugfs.h>
@@ -365,10 +367,26 @@ out:
 }
 
 /* These are currently unused but present in case UDC driver requires them. */
-static void gadget_disconnect(struct usb_gadget *gadget) { }
-static void gadget_suspend(struct usb_gadget *gadget) { }
-static void gadget_resume(struct usb_gadget *gadget) { }
-static void gadget_reset(struct usb_gadget *gadget) { }
+static void gadget_disconnect(struct usb_gadget *gadget)
+{
+       dev_dbg(&gadget->dev, "gadget disconnected\n");
+       WARN_ON(1);
+}
+static void gadget_suspend(struct usb_gadget *gadget)
+{
+       dev_dbg(&gadget->dev, "gadget suspended\n");
+       WARN_ON(1);
+}
+static void gadget_resume(struct usb_gadget *gadget)
+{
+       dev_dbg(&gadget->dev, "gadget resumed\n");
+       WARN_ON(1);
+}
+static void gadget_reset(struct usb_gadget *gadget)
+{
+       dev_dbg(&gadget->dev, "gadget reset\n");
+       WARN_ON(1);
+}
 
 /*----------------------------------------------------------------------*/
 

@xairy
Copy link
Contributor

xairy commented Dec 23, 2022

I got the K12+ keyboard, and it's being proxied perfectly with Dummy HCD. So I suspect the issue is either with the dwc2 driver or with Raw Gadget. I don't have a full-size Raspberry Pie to debug further, but I'll try to get my hands on one.

@KernelKrusha
Copy link

This project https://github.com/patryk4815/usb-proxy manages to proxy my logitech mouse without issues. This usb-proxy project results in the error described above.

@RandomOnlineName
Copy link

I have experienced the same issue with a wireless mouse & keyboard. It works perfectly with dummy driver but not with the project by patryk4815. I ran the patch above. dmesg.
This was done on kernel 5.15.89, rasbarian (bullseye), Raspberry Pi 4B.

@imatespl
Copy link

imatespl commented Apr 26, 2023

I have this issue too,with a wireless mouse. on orangepipc,I change the MaxPackageSize0,and change connect_device

        //result = libusb_set_auto_detach_kernel_driver(dev_handle, 1);
        //if (result != LIBUSB_SUCCESS) {
        //      fprintf(stderr, "libusb_set_auto_detach_kernel_driver() failed: %s\n",
        //                      libusb_strerror((libusb_error)result));
        //      return result;
        //}
        for (int i = 0; i < device_device_desc.bNumConfigurations; i++) {
                for (int j = 0; j < device_config_desc[i]->bNumInterfaces; j++) {
                         if(libusb_detach_kernel_driver(dev_handle, j) == 0)
                                 fprintf(stdout, "detach devivce ok interface is %d\n", j);
                }
        }

when ctrl event set interface 1, control_request failed

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 output has a gadget raw-gadget.0 gadget: fail, wrong direction

[ 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
[ 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 ]---

xairy added a commit to xairy/usb-proxy that referenced this issue May 6, 2023
Current code assumes that only one interface is active at a time.
This is not correct: all interfaces of a chosen cofiguration are
active simultaneously.

Fixes AristoChen#4.
@imatespl
Copy link

Very thanks, I also make my mouse work, but i think @xairy code is good, i will test the code. i have a ic card reader, which have a bEndpointAddress 0x85, but raw_gadget use driver musb-hdrc max bEndpointAddress 0x84, this make raw_gadget ep addr enable failed in process_eps
ep->thread_info.ep_num = usb_raw_ep_enable(fd, &ep->thread_info.endpoint);

Is there a good solution?

@AristoChen
Copy link
Owner

Hi @imatespl, thanks for confirm that the fix works for you! could you please open another issue to discuss your question? we may discuss there further, because I think it is not related to this issue

Just a quick reply to your question, I guess your hardware only support endopoints address from 0x01 to 0x04, and from 0x81 to 0x84. Your IC card reader uses 0x85, which may not be supported on your hardware. There may be 2 solutions

  1. Use other hardware that supports address 0x85, such as raspberry pi 4, or IIRC, Bananapi M1 should support as well
  2. Previously, I was planning to allow users to manually mapping endpoint addresses to some other addresses by themselves if this issue happen, but I don't have a plan to implement it in near future, and IMO it is highly possible that the driver from the host may not be able to work normally since the address is different.

@imatespl
Copy link

imatespl commented May 11, 2023

very thanks,I will open a new issue,my ic card reader have three endpoints, 0x01 0x82 0x85, I hard code map 0x85 to 0x81, in usb_raw_ep_enable(fd, &ep->thread_info.endpoint), and injection USB_DT_CONFIG response set 0x85 to 0x81, it work good

@imatespl
Copy link

imatespl commented May 11, 2023

I test @xairy #6, and should change the MaxPackageSize0 from 0x08 to 0x40, 0x08 make the raw_gadget which use device musb-hdrc.4.auto dead loop, and ignore usb_raw_ep0_stall when SET_IDLE request to interface 1, it like in linux libusb 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

index e3dbd57..d703445 100644
--- 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);
+                                       }
                                }
                        }
                }

@AristoChen
Copy link
Owner

AristoChen commented May 11, 2023

Hi @imatespl , thanks for reviewing the code! if the issue you have mentioned is introduced by #6, could you please leave a comment there instead of here? I think it will be easier for us to discuss the code changes in a single place, thanks!

@imatespl
Copy link

Ok, I add to #6, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants