xairy / raw-gadget Goto Github PK
View Code? Open in Web Editor NEWUSB Raw Gadget — a low-level interface for the Linux USB Gadget subsystem
USB Raw Gadget — a low-level interface for the Linux USB Gadget subsystem
root@orangepipc:~/usb-proxy# lsusb
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 006 Device 004: ID 2ce3:9563 Generic EMV Smartcard Reader
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 009 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
root@orangepipc:~/usb-proxy# lsusb -v -d 2ce3:9563
Bus 006 Device 004: ID 2ce3:9563 Generic EMV Smartcard Reader
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.01
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x2ce3
idProduct 0x9563
bcdDevice 1.20
iManufacturer 1 Generic
iProduct 2 EMV Smartcard Reader
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x005d
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 50mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 11 Chip/SmartCard
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
ChipCard Interface Descriptor:
bLength 54
bDescriptorType 33
bcdCCID 1.10 (Warning: Only accurate for version 1.0)
nMaxSlotIndex 0
bVoltageSupport 7 5.0V 3.0V 1.8V
dwProtocols 3 T=0 T=1
dwDefaultClock 4000
dwMaxiumumClock 12000
bNumClockSupported 3
dwDataRate 10753 bps
dwMaxDataRate 688172 bps
bNumDataRatesSupp. 95
dwMaxIFSD 254
dwSyncProtocols 00000007 2-wire 3-wire I2C
dwMechanical 00000000
dwFeatures 000404BE
Auto configuration based on ATR
Auto activation on insert
Auto voltage selection
Auto clock change
Auto baud rate change
Auto PPS made by CCID
Auto IFSD exchange
Short and extended APDU level exchange
dwMaxCCIDMsgLen 272
bClassGetResponse echo
bClassEnvelope echo
wlcdLayout none
bPINSupport 0
bMaxCCIDBusySlots 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0004 1x 4 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0010 1x 16 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0010 1x 16 bytes
bInterval 0
Binary Object Store Descriptor:
bLength 5
bDescriptorType 15
wTotalLength 0x000c
bNumDeviceCaps 1
USB 2.0 Extension Device Capability:
bLength 7
bDescriptorType 16
bDevCapabilityType 2
bmAttributes 0x00000000
(Missing must-be-set LPM bit!)
Device Status: 0x0000
(Bus Powered)
root@orangepipc:~/usb-proxy# ./usbbr --device=musb-hdrc.4.auto --driver=musb-hdrc -vv
Device is: musb-hdrc.4.auto
Driver is: musb-hdrc
vendor_id is: -1
product_id is: -1
Device opened successfully
Setup USB config successfully
Start hotplug_monitor thread, thread id(5635)
Start for EP0, thread id(5622)
ep #0:
name: ep1in
addr: 1
type: iso blk int
dir : in ___
maxpacket_limit: 512
max_streams: 0
ep #1:
name: ep1out
addr: 1
type: iso blk int
dir : ___ out
maxpacket_limit: 512
max_streams: 0
ep #2:
name: ep2in
addr: 2
type: iso blk int
dir : in ___
maxpacket_limit: 512
max_streams: 0
ep #3:
name: ep2out
addr: 2
type: iso blk int
dir : ___ out
maxpacket_limit: 512
max_streams: 0
ep #4:
name: ep3in
addr: 3
type: iso blk int
dir : in ___
maxpacket_limit: 512
max_streams: 0
ep #5:
name: ep3out
addr: 3
type: iso blk int
dir : ___ out
maxpacket_limit: 512
max_streams: 0
ep #6:
name: ep4in
addr: 4
type: iso blk int
dir : in ___
maxpacket_limit: 512
max_streams: 0
ep #7:
name: ep4out
addr: 4
type: iso blk int
dir : ___ out
maxpacket_limit: 512
max_streams: 0
event: connect, length: 0
libusb: error [udev_hotplug_event] ignoring udev action change
libusb: error [usbi_get_context] API misuse! Using non-default context as implicit default.
libusb: error [udev_hotplug_event] ignoring udev action change
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 01 02 00 00 00 40 e3 2c 63 95 20 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 01 02 00 00 00 40 e3 2c 63 95 20 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 5d 00 01 01 00 a0 19 09 04 00 00 03 0b 00 00 00 36 21 10 01 00 07 03 00 00 00 a0 0f 00 00 e0 2e 00 00 03 01 2a 00 00 2c 80 0a 00 5f fe 00 00 00 07 00 00 00 00 00 00 00 be 04 04 00 10 01 00 00 ff ff 00 00 00 01 07 05 81 03 04 00 01 07 05 02 02 10 00 00 07 05 83 02 10 00 00
ep0: transferred 93 bytes (in)
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 01 02 00 00 00 40 e3 2c 63 95 20 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 01 02 00 00 00 40 e3 2c 63 95 20 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 5d 00 01 01 00 a0 19 09 04 00 00 03 0b 00 00 00 36 21 10 01 00 07 03 00 00 00 a0 0f 00 00 e0 2e 00 00 03 01 2a 00 00 2c 80 0a 00 5f fe 00 00 00 07 00 00 00 00 00 00 00 be 04 04 00 10 01 00 00 ff ff 00 00 00 01 07 05 81 03 04 00 01 07 05 02 02 10 00 00 07 05 83 02 10 00 00
ep0: transferred 93 bytes (in)
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 01 02 00 00 00 40 e3 2c 63 95 20 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 01 02 00 00 00 40 e3 2c 63 95 20 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 5d 00 01 01 00 a0 19 09 04 00 00 03 0b 00 00 00 36 21 10 01 00 07 03 00 00 00 a0 0f 00 00 e0 2e 00 00 03 01 2a 00 00 2c 80 0a 00 5f fe 00 00 00 07 00 00 00 00 00 00 00 be 04 04 00 10 01 00 00 ff ff 00 00 00 01 07 05 81 03 04 00 01 07 05 02 02 10 00 00 07 05 83 02 10 00 00
ep0: transferred 93 bytes (in)
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 01 02 00 00 00 40 e3 2c 63 95 20 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 01 02 00 00 00 40 e3 2c 63 95 20 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 5d 00 01 01 00 a0 19 09 04 00 00 03 0b 00 00 00 36 21 10 01 00 07 03 00 00 00 a0 0f 00 00 e0 2e 00 00 03 01 2a 00 00 2c 80 0a 00 5f fe 00 00 00 07 00 00 00 00 00 00 00 be 04 04 00 10 01 00 00 ff ff 00 00 00 01 07 05 81 03 04 00 01 07 05 02 02 10 00 00 07 05 83 02 10 00 00
##4. This two file is pcap capture from orangepc and windows
orangepc pcap
windows pcap
Just a wild idea to write a program that will parse and replay a PCAP file with Raw Gadget.
Hi,
I'm having the hardest time to get my Raspi Zero to show up as a USB.
I found a couple of blogs pointing towards this github so I figured I'd try to install dummy_hcd
since it is in fact missing in my system.
I had some cpp issues with fallthrough, so now I've updated to the latest version of CPP.
If I now run make like this to make sure it uses the correct cpp version:
# #!/bin/bash
dir=$(pwd);
install_dir="/home/●●●●●/install/";
mod_dir="/lib/modules/$(uname -r)";
cpp_dir="/opt/gcc-10.1.0/bin";
echo -e "\nBaking dummy_hcd";
sudo ln -s "$mod_dir" "./build";
cd "${install_dir}/git/raw-gadget/dummy_hcd";
sudo make CC="${cpp_dir}/gcc-10.1" CPP="${cpp_dir}/g++-10.1" CXX="${cpp_dir}/g++-10.1" LD="${cpp_dir}/g++-10.1";
cd "${mod_dir}/build";
sudo "./insmod.sh";
cd "$dir";
I still get the following error:
make -C /lib/modules/4.19.97+/build M=/usr/src/linux-headers-4.19.97+/dummy_hcd SUBDIRS=/usr/src/linux-headers-4.19.97+/dummy_hcd modules
make[1]: Entering directory '/usr/src/linux-headers-4.19.97+'
CC [M] /usr/src/linux-headers-4.19.97+/dummy_hcd/dummy_hcd.o
/usr/src/linux-headers-4.19.97+/dummy_hcd/dummy_hcd.c: In function ‘dummy_enable’:
/usr/src/linux-headers-4.19.97+/dummy_hcd/dummy_hcd.c:556:4: error: ‘fallthrough’ undeclared (first use in this function)
556 | fallthrough;
| ^~~~~~~~~~~
/usr/src/linux-headers-4.19.97+/dummy_hcd/dummy_hcd.c:556:4: note: each undeclared identifier is reported only once for each function it appears in
/usr/src/linux-headers-4.19.97+/dummy_hcd/dummy_hcd.c: In function ‘dummy_timer’:
/usr/src/linux-headers-4.19.97+/dummy_hcd/dummy_hcd.c:1971:4: error: ‘fallthrough’ undeclared (first use in this function)
1971 | fallthrough;
| ^~~~~~~~~~~
/usr/src/linux-headers-4.19.97+/dummy_hcd/dummy_hcd.c: In function ‘dummy_hub_control’:
/usr/src/linux-headers-4.19.97+/dummy_hcd/dummy_hcd.c:2148:4: error: ‘fallthrough’ undeclared (first use in this function)
2148 | fallthrough;
| ^~~~~~~~~~~
make[2]: *** [scripts/Makefile.build:310: /usr/src/linux-headers-4.19.97+/dummy_hcd/dummy_hcd.o] Error 1
make[1]: *** [Makefile:1522: _module_/usr/src/linux-headers-4.19.97+/dummy_hcd] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.19.97+'
make: *** [Makefile:7: default] Error 2
Do you have any suggestions on what I can try to debug this some more?
As a part of this repository, provide instructions for setting up various popular single-board computers (Raspberry Pi, etc.) in the USB device mode with Raw Gadget.
Hi everyone!
I built the project under 6.2.0-rc3-meson64. When launching the keyboard from the example, lsusb sees both the vendor and the product name just fine. But dmesg does not determine the vendor, and the product and serial number is defined as "x". Maybe someone can suggest a way to solve the problem?
USB/IP provides a usbip-vudc
module, which acts as a virtual UDC. In combination with usbip-vhci
, this might prove as an alternative to Dummy HCD/UDC that supports isochronous transfers (which Raw Gadget does not really support yet).
One of the issues I recently had was that it's not actually possible for any of the current Linux usb gadgets to set "iInterface". This is wired to a specific value based upon the gadget driver and is not exposed in configFS. Because of its commonality across all the function drivers, this is a problematic amount of work to fix.
Can this raw-gadget be used to side step that issue?
Thanks.
Is it possible to add an ioctl to get status/clear fifo for an endpoint? Essentially passing these functions through
int usb_ep_fifo_status(struct usb_ep *ep);
void usb_ep_fifo_flush(struct usb_ep *ep);
Each example has copy-pasted definitions of wrappers and helpers for Raw Gadget ioctls. Provide a common header file with these definitions.
Hi,
the following error message will appear if trying to compile raw-gadget
kernel module after update.sh
is executed
$ make
make -C /lib/modules/5.10.60/build M=/root/raw-gadget/raw_gadget SUBDIRS=/root/raw-gadget/raw_gadget modules
make[1]: Entering directory '/usr/src/linux-source'
CC [M] /root/raw-gadget/raw_gadget/raw_gadget.o
/root/raw-gadget/raw_gadget/raw_gadget.c: In function ‘raw_ioctl_run’:
/root/raw-gadget/raw_gadget/raw_gadget.c:546:8: error: implicit declaration of function ‘usb_gadget_register_driver’; did you mean ‘usb_gadget_unregister_driver’? [-Werror=implicit-function-declaration]
546 | ret = usb_gadget_register_driver(&dev->driver);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
| usb_gadget_unregister_driver
cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:280: /root/raw-gadget/raw_gadget/raw_gadget.o] Error 1
make[1]: *** [Makefile:1824: /root/raw-gadget/raw_gadget] Error 2
make[1]: Leaving directory '/usr/src/linux-source'
make: *** [Makefile:7: default] Error 2
looks like this patch is causing the issue, usb_gadget_probe_driver()
was renamed to usb_gadget_register_driver()
, the following patch works fine with my SBC with 5.10.60
kernel version.
diff --git a/raw_gadget/update.sh b/raw_gadget/update.sh
index 6ffcb66..c363e12 100755
--- a/raw_gadget/update.sh
+++ b/raw_gadget/update.sh
@@ -9,4 +9,12 @@ BRANCH=usb-next
wget $REPO/drivers/usb/gadget/legacy/raw_gadget.c?h=$BRANCH -O raw_gadget.c
wget $REPO/include/uapi/linux/usb/raw_gadget.h?h=$BRANCH -O raw_gadget.h
+
+HEADER_FILE=/lib/modules/"$(uname -r)"/build/include/linux/usb/gadget.h
+if [[ $(grep -c "usb_gadget_probe_driver(" < "$HEADER_FILE") -ne 0 ]]
+then
+ echo "Replacing from usb_gadget_register_driver() to usb_gadget_probe_driver()"
+ sed -i 's/usb_gadget_register_driver/usb_gadget_probe_driver/g' raw_gadget.c
+fi
+
git apply ./include.patch
Hi,
When I make this folder I got this message from dmesg screen and I did not find a solution.
udc dummy_udc.0: failed to start g_mass_storage: -2
Module has invalid ELF structures
Not a bug in Raw Gadget but still related to its usage.
dwc2 calls the gadget driver's ->disconnect()
callback when the port to which the device is connected gets reset by
the host (via SET_FEATURE
/PORT_RESET
). It should call ->reset()
instead.
Asked kernel maintainers about getting this fixed, see here.
Check whether Raw Gadget works on OpenStick and add instructions for setting it up (see #51).
OpenStick is a USB LTE modem that can be reflashed with a custom Linux-based OS. See the related links.
The Gadget subsystem provides information about the capabilities of the UDC hardware. It might be useful to expose this information via Raw Gadget ioctls.
hi,@xairy,
I test the Logitech webcam, that can not proxy with AristoChen/usb-proxy, because the webcam have 4 interface and each interface has multi altsettings, and some altsettings has no endpoints, then I start usb-proxy, when I click windows 11 webcam preview , the windows driver will send set altsetting control packet to webcam, and then usb-proxy will terminate_eps
and restart process thread process_eps
, then the raw-gadget ioctl enable returnioctl(USB_RAW_IOCTL_EP_ENABLE): Device or resource busy
https://github.com/AristoChen/usb-proxy/blob/c681f1238371fae331482f7d300a4652586d0dd3/proxy.cpp#L474-L482
this line cause the issues
https://github.com/AristoChen/usb-proxy/blob/c681f1238371fae331482f7d300a4652586d0dd3/proxy.cpp#L267
the log is like this, first not start any thread for this zero endpoint altsetting, then terminate any thing and start thread for altsetting has endpoint when the windows driver send control message change altsetting
Activating 1 endpoints on interface 0
int_in: addr = 3, ep = #4
Creating thread for EP83
Start reading thread for EP83, thread id(1849)
process_eps done
Start writing thread for EP83, thread id(1850)
Activating 0 endpoints on interface 1
process_eps done
Activating 0 endpoints on interface 2
process_eps done
Activating 0 endpoints on interface 3
process_eps done
ep0: transferred 26 bytes (out)
event: control, length: 8
bRequestType: 0x01 (OUT), bRequest: 0x0b, wValue: 0x000a, wIndex: 0x0001, wLength: 0
type = USB_TYPE_STANDARD
req = USB_REQ_SET_INTERFACE
Changing interface/altsetting
Activating 1 endpoints on interface 1
ioctl(USB_RAW_IOCTL_EP_ENABLE): Device or resource busy
I also change the code bypass the zero endpoint altsetting, then first start thread will failed, the issues is same, ioctl(USB_RAW_IOCTL_EP_ENABLE): Device or resource busy
Creating thread for EP83
Start reading thread for EP83, thread id(4029)
process_eps done
Start writing thread for EP83, thread id(4030)
Activating 1 endpoints on interface 1
ioctl(USB_RAW_IOCTL_EP_ENABLE): Device or resource busy
The device is c922 Pro Stream Webcam
The windows 11 driver is Logitech 2021/4/27 1.4.40.0
The usb-proxy run on orangepi pc use the driver is musb-hdrc and device is musb-hdrc.4.auto
See attachment for details
lsusb-output.txt
usb-proxy-console-log.txt
Proxying USB devices proves to be an effective way to test Raw Gadget features.
A few ideas for testing Raw Gadget via proxying:
Provide a simple in-repo proxy that supports all of the features Raw Gadget currently exposes. This proxy can evolve alongside with the new Raw Gadget features added to the dev
branch. External proxies can rely on this implementation as a guideline or directly reuse it.
Implement automatic virtual testing of Raw Gadget based on proxying the existing functions of the composite framework via Dummy HCD/UDC and USB/IP.
Document instructions for manual testing of Raw Gadget with various physical devices, hardware UDCs, and both Linux and Windows hosts.
Also see the TODOs in the existing Raw Gadget testing tooling.
The error is reproduced for both the master and dev branches, and for the module from the dev branch it is not possible to run the printer and keyboard example application, but a proxy device is successfully created using the usb_proxy application.
master:
$ sudo ./keyboard
...
ioctl(USB_RAW_IOCTL_EP_WRITE): Cannot send after transport endpoint shutdown
$ sudo ./printer
...
ioctl(USB_RAW_IOCTL_EP_READ): Cannot send after transport endpoint shutdown
ioctl(USB_RAW_IOCTL_EP_WRITE): Cannot send after transport endpoint shutdown
usbredir (example printer):
$ sudo usbredirect --device 0525:a4a8 --as 127.0.0.1:4000 --verbose 5
(usbredirect:12580): usbredirect-ERROR **: 20:22:46.937: usbredirhost: error resetting device: LIBUSB_ERROR_NOT_FOUND
Ловушка трассировки/останова
=====================================================================
dev:
$ sudo ./keyboard
ep #0:
name: ep1in-bulk
addr: 1
type: ___ blk ___
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #1:
name: ep2out-bulk
addr: 2
type: ___ blk ___
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #2:
name: ep5in-int
addr: 5
type: ___ ___ int
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #3:
name: ep6in-bulk
addr: 6
type: ___ blk ___
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #4:
name: ep7out-bulk
addr: 7
type: ___ blk ___
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #5:
name: ep10in-int
addr: 10
type: ___ ___ int
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #6:
name: ep11in-bulk
addr: 11
type: ___ blk ___
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #7:
name: ep12out-bulk
addr: 12
type: ___ blk ___
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #8:
name: ep15in-int
addr: 15
type: ___ ___ int
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #9:
name: ep1out-bulk
addr: 1
type: ___ blk ___
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #10:
name: ep2in-bulk
addr: 2
type: ___ blk ___
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #11:
name: ep-aout
addr: 255
type: ___ blk int
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #12:
name: ep-bin
addr: 255
type: ___ blk int
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #13:
name: ep-cout
addr: 255
type: ___ blk int
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #14:
name: ep-dout
addr: 255
type: ___ blk int
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #15:
name: ep-ein
addr: 255
type: ___ blk int
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #16:
name: ep-fout
addr: 255
type: ___ blk int
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #17:
name: ep-gin
addr: 255
type: ___ blk int
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #18:
name: ep-hout
addr: 255
type: ___ blk int
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #19:
name: ep-iout
addr: 255
type: ___ blk int
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #20:
name: ep-jin
addr: 255
type: ___ blk int
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #21:
name: ep-kout
addr: 255
type: ___ blk int
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #22:
name: ep-lin
addr: 255
type: ___ blk int
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #23:
name: ep-mout
addr: 255
type: ___ blk int
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
int_in: addr = 5
fail: unknown event
$ sudo ./printer
ep #0:
name: ep1in-bulk
addr: 1
type: ___ blk ___
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #1:
name: ep2out-bulk
addr: 2
type: ___ blk ___
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #2:
name: ep5in-int
addr: 5
type: ___ ___ int
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #3:
name: ep6in-bulk
addr: 6
type: ___ blk ___
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #4:
name: ep7out-bulk
addr: 7
type: ___ blk ___
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #5:
name: ep10in-int
addr: 10
type: ___ ___ int
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #6:
name: ep11in-bulk
addr: 11
type: ___ blk ___
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #7:
name: ep12out-bulk
addr: 12
type: ___ blk ___
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #8:
name: ep15in-int
addr: 15
type: ___ ___ int
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #9:
name: ep1out-bulk
addr: 1
type: ___ blk ___
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #10:
name: ep2in-bulk
addr: 2
type: ___ blk ___
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #11:
name: ep-aout
addr: 255
type: ___ blk int
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #12:
name: ep-bin
addr: 255
type: ___ blk int
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #13:
name: ep-cout
addr: 255
type: ___ blk int
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #14:
name: ep-dout
addr: 255
type: ___ blk int
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #15:
name: ep-ein
addr: 255
type: ___ blk int
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #16:
name: ep-fout
addr: 255
type: ___ blk int
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #17:
name: ep-gin
addr: 255
type: ___ blk int
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #18:
name: ep-hout
addr: 255
type: ___ blk int
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #19:
name: ep-iout
addr: 255
type: ___ blk int
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #20:
name: ep-jin
addr: 255
type: ___ blk int
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #21:
name: ep-kout
addr: 255
type: ___ blk int
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
ep #22:
name: ep-lin
addr: 255
type: ___ blk int
dir : in ___
maxpacket_limit: 65535
max_streams: 16
ep #23:
name: ep-mout
addr: 255
type: ___ blk int
dir : ___ out
maxpacket_limit: 65535
max_streams: 16
bulk_out: addr = 2
bulk_in: addr = 1
fail: unknown event
usb-proxy:
$ lsusb
...
Bus 002 Device 004: ID 0bda:0129 Realtek Semiconductor Corp. RTS5129 Card Reader Controller
...
$ sudo ./usb-proxy --vendor_id=0bda --product_id=0129
...
ep0: transferred 0 bytes (out)
EP1(bulk_out): read 16 bytes from host
EP82(bulk_in): wrote 4 bytes to host
EP1(bulk_out): read 16 bytes from host
EP82(bulk_in): wrote 4 bytes to host
EP1(bulk_out): read 16 bytes from host
EP82(bulk_in): wrote 4 bytes to host
EP1(bulk_out): read 24 bytes from host
EP1(bulk_out): read 32 bytes from host
EP1(bulk_out): read 12 bytes from host
EP1(bulk_out): read 24 bytes from host
new proxy-usb device:
$ lsusb
Bus 001 Device 003: ID 0bda:0129 Realtek Semiconductor Corp. RTS5129 Card Reader Controller
...
(continue) $ sudo ./usb-proxy --vendor_id=0bda --product_id=0129
...
ioctl(USB_RAW_IOCTL_EP_READ): Cannot send after transport endpoint shutdown
ioctl(USB_RAW_IOCTL_EP_WRITE): Cannot send after transport endpoint shutdown
Hi
I am exploring the raw gadget driver for masss storage with dummy_hcd driver.
I am getting the raw data in user space for mass storage with dummy_hcd. I want to pass that data to target pc using OTG gadget driver.
is there any way to use these raw usb as bridge between them?
and can we read/wright directly to pendrive or sd card with raw driver?
if you have any example for these can you please point me. any help will be appreciable.
Thanks
Hi
I tested raw-gadget
with RPi 4, and when the test case 13(bulk, ep halt set/clear) was executed, there will be an error, sometimes it is ioctl(USB_RAW_IOCTL_EP_WRITE): Operation now in progress
, and sometimes it is ioctl(USB_RAW_IOCTL_EP_READ): Operation now in progress
seems that there is something interrupting the down_interruptible()
function in line 94 of raw-gadget.c
, which cause it return -EINTR
then I edited the gadget.c
like this, simply just retry if error occured.
diff --git a/tests/gadget.c b/tests/gadget.c
index 449cbba..779eb50 100644
--- a/tests/gadget.c
+++ b/tests/gadget.c
@@ -170,18 +170,20 @@ int usb_raw_ep_enable(int fd, struct usb_endpoint_descriptor *desc) {
int usb_raw_ep_read(int fd, struct usb_raw_ep_io *io) {
int rv = ioctl(fd, USB_RAW_IOCTL_EP_READ, io);
- if (rv < 0) {
+ while (rv < 0) {
perror("ioctl(USB_RAW_IOCTL_EP_READ)");
- exit(EXIT_FAILURE);
+ rv = ioctl(fd, USB_RAW_IOCTL_EP_READ, io);
+ //exit(EXIT_FAILURE);
}
return rv;
}
int usb_raw_ep_write(int fd, struct usb_raw_ep_io *io) {
int rv = ioctl(fd, USB_RAW_IOCTL_EP_WRITE, io);
- if (rv < 0) {
+ while (rv < 0) {
perror("ioctl(USB_RAW_IOCTL_EP_WRITE)");
- exit(EXIT_FAILURE);
+ rv = ioctl(fd, USB_RAW_IOCTL_EP_WRITE, io);
+ //exit(EXIT_FAILURE);
}
return rv;
}
RPi 4 is able to pass the run_test.py
after this modification
The question is: should I just add the test result for RPi 4 that tested with the above modification? or should I also modify the ioctl mechanism in gadget.c
like the above?
During endpoint operations, Raw Gadget allows providing a USB_RAW_IO_FLAGS_ZERO
flag, which sets the zero
flag on the submitted USB request.
We need to:
Figure out if the USB_RAW_IO_FLAGS_ZERO
is useful being exposed to userspace and remove it if not. For reference: how zero
is used in GadgetFS.
Possibly add other request flags supported by the gadget subsystem. For reference: is_last
in f_tcm.c, no_interrupt
in uvc_video.c.
Is there any way to initiate a connect/disconnect in raw-gadget?
Здравствуйте.
Подскажите, пожалуйста, в чём может быть проблема?
Запускаю Ваш пример https://github.com/xairy/raw-gadget/blob/master/examples/keyboard.c, но операция ioctl(fd, USB_RAW_IOCTL_RUN, 0)
возвращает -1, в консоль выводится сообщение ioctl(USB_RAW_IOCTL_RUN): No such device
.
Спасибо.
Hello.
Can you tell me what the problem might be?
Running your example https://github.com/xairy/raw-gadget/blob/master/examples/keyboard.c, but the ioctl(fd, USB_RAW_IOCTL_RUN, 0)
operation returns -1, and the message ioctl(USB_RAW_IOCTL_RUN): No such device
is output to the console.
Thanks.
$ uname -a
Linux ants-H110M-S2H 5.3.0-46-generic #38~18.04.1-Ubuntu SMP Tue Mar 31 04:17:56 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
$ lsmod | grep raw_gadget
raw_gadget 24576 0
udc_core 57344 1 raw_gadget
$ lsb_release -a
No LSB modules are available.
Distributor ID: LinuxMint
Description: Linux Mint 19.3 Tricia
Release: 19.3
Codename: tricia
ioctl_ep_read does not update the length field.
It only copies back to user space the data buffer and not the header with the length field
ret = copy_to_user((void __user *)(value + sizeof(io)), data, length);
Same for ioctl_ep0_read
I have a thread for ep0_loop and another for ep_int_in_loop, apparently I can't write when EVENT_FETCH
is blocking, is there a way to timeout the fetch, so I can write something in between?
EDIT: I figure I could implement a timeout manually, but I'm stuck at cancelling the ioctl call ="(
Hi everyone!
I built the project under 6.2.0-rc3-meson64. When launching the keyboard from the example, lsusb sees both the vendor and the product name just fine. But dmesg does not determine the vendor, and the product and serial number is defined as "x". Maybe someone can suggest a way to solve the problem?
Hi,
I'm trying to create a usb device gadget with the Microchip linux-at91 kernel. I want to use it with a physicall usb controller and have replaced the driver_name
and device_name
to atmel_usba_udc
and 500000.gadget
respectively. I am not sure if I have the correct driver_name
but I found it in /sys/class/udc/500000.gadget/device/uvent
displaying DRIVER=atmel_usba_udc
.
I am running the keyboard example code which works well with the dummy_hcd module. However, when I try to use it with the microchip usb controller, I get the following logging message:
event: connect, length: 0
event: control, length: 8
bRequestType: 0x80 (IN), bRequest: 0x6, wValue: 0x100, wIndex: 0x0, wLength: 64
type = USB_TYPE_STANDARD
req = USB_REQ_GET_DESCRIPTOR
descriptor = USB_DT_DEVICE
event: control, length: 8
bRequestType: 0x80 (IN), bRequest: 0x6, wValue: 0x100, wIndex: 0x0, wLength: 18
type = USB_TYPE_STANDARD
req = USB_REQ_GET_DESCRIPTOR
descriptor = USB_DT_DEVICE
ioctl(USB_RAW_IOCTL_EP0_WRITE): Connection reset by peer
which indicates a write failure with a USB_REQ_GET_DESCRIPTOR
request with type USB_DT_DEVICE
.
Even though Raw Gadget does allow enabling isochronous endpoints, those most likely do not work properly. Implementing proper support for isochronous transfers requires deep investigation of what kind of Raw Gadget changes are required.
A non-exhaustive list of potentially required changes:
frame_number
for completed requests.This issue is also mentioned in the kernel documentation.
Hi, I've tested on Raspberry PI 4 and BeagleBone Black (using the usb-proxy project) and on both there seems to be an issue with data from host to device.
It seems that when we get data from the host, it could contain more than just one packet (up to info.eps[i].limits.maxpacket_limit) which aside from the weird behavior on the actual device, it may also get lost when sent back to the device.
Any chance this can be tuned to only process one message at a time?
On Raspberry PI 4 the behavior is worse as it transfers 1024 bytes at a time most of the time and sometimes it gets blocked for a second with no transfer at all but the Raspberry PI is somewhat known to exhibit USB issues (I see 11 packets of 1024 bytes transferred in a timeframe of 2 seconds and no packets are going the other way which blocks the use of the device).
The transfers from device to host don't show any issue and they respect the expected message size.
Thanks in advance for any feedback
The Gadget subsystem defines a number of Gadget API functions. While some of them look specific to the Composite Gadget framework, other seem quite generic.
It might be useful to expose the generic API functions via Raw Gadget ioctls. At this point, only usb_gadget_vbus_draw
is exposed.
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 ]---
Hi,
Orange Pi PC have endpoints from ep1-ep4 for both in and out direction, and if we try to use raw_ioctl_ep_enable() for ep5in, it will return -EBUSY here
raw-gadget/raw_gadget/raw_gadget.c
Line 819 in f74b1c2
I guess it will be more intuitive if we return some other errno(such as -EINVAL)? Cuz -EBUSY sounds like EP5in is not available now, but might be available in the future
Here is the patch
diff --git a/raw_gadget/raw_gadget.c b/raw_gadget/raw_gadget.c
index 1378d6c..d5acc67 100644
--- a/raw_gadget/raw_gadget.c
+++ b/raw_gadget/raw_gadget.c
@@ -758,6 +758,7 @@ static int raw_ioctl_ep_enable(struct raw_dev *dev, unsigned long value)
unsigned long flags;
struct usb_endpoint_descriptor *desc;
struct raw_ep *ep;
+ bool ep_num_matched = false;
desc = memdup_user((void __user *)value, sizeof(*desc));
if (IS_ERR(desc))
@@ -792,6 +793,7 @@ static int raw_ioctl_ep_enable(struct raw_dev *dev, unsigned long value)
if (ep->addr != usb_endpoint_num(desc) &&
ep->addr != USB_RAW_EP_ADDR_ANY)
continue;
+ ep_num_matched = true;
if (!usb_gadget_ep_match_desc(dev->gadget, ep->ep, desc, NULL))
continue;
ep->ep->desc = desc;
@@ -815,6 +817,12 @@ static int raw_ioctl_ep_enable(struct raw_dev *dev, unsigned long value)
goto out_unlock;
}
+ if (!ep_num_matched) {
+ dev_dbg(&dev->gadget->dev, "fail, no proper ep address available\n");
+ ret = -EINVAL;
+ goto out_free;
+ }
+
dev_dbg(&dev->gadget->dev, "fail, no gadget endpoints available\n");
ret = -EBUSY;
Device:
$ sudo ./keyboard
event: connect, length: 0
event: control, length: 8
bRequestType: 0x80 (IN), bRequest: 0x6, wValue: 0x100, wIndex: 0x0, wLength: 8
type = USB_TYPE_STANDARD
req = USB_REQ_GET_DESCRIPTOR
descriptor = USB_DT_DEVICE
ioctl(USB_RAW_IOCTL_EP0_WRITE): Protocol error
Host:
Apr 9 19:03:57 host kernel: [ 2858.561124] usb 4-2.4.4: new SuperSpeed USB device number 7 using xhci_hcd
Apr 9 19:04:02 host kernel: [ 2863.596761] usb 4-2.4.4: device descriptor read/8, error -110
Apr 9 19:04:03 host kernel: [ 2863.704532] usb 4-2.4.4: new SuperSpeed USB device number 7 using xhci_hcd
Right now, every Raw Gadget endpoint read/write ioctl submits a USB request and waits until its completion. This is done deliberately to assist with coverage-guided fuzzing by having a single syscall fully process a single USB request.
However, for other use cases, we might want to have a non-blocking operation mode, where Raw Gadget would not wait until the completion of each USB request. The original blocking mode must still be kept in the implementation.
This issue is also mentioned in the kernel documentation.
hi,@xairy I have a atm cardreader,which is a hid device, and I use usb-proxy proxy to windows 10 , windows 10 need send URB_INTERRUPT OUT to atm cardreader, to drive motor rotation,but the endpoint 0x02 can not received any data,ep0 and
0x81 work good,it may usb_raw_ep_read(fd, (struct usb_raw_ep_io *)&io);
can not work with URB_INTERRUPT OUT? I test on
raspberrypi4 and orangepi pc. thank you very much.
first of all thanks for sharing your amazing work.
I'm trying to send a configuration descriptor which has a size of 59 bytes to a device which has bMaxPacketSize0 of 32 bytes.
if i try to send the full 59 bytes i get this
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
whats the right way to send this descriptor to that device is this possible using raw gadget or where can i get info about this.
A couple of clean-ups to investigate:
ep->dev
on ep
allocation.ep0_status
and ep_status
through dev
, get from req
instead.I don't remember why I didn't address those when upstreaming Raw Gadget.
Unify checks in assign_ep_address
in examples with the ones in usb_gadget_ep_match_desc.
Hi
I ran into issue nix-rust/nix#781 when working on using this from Rust. The issue seems to be that raw_ioctl_run
is declared as IO (i.e. "none"), but still checks that the passed value is zero:
raw-gadget/raw_gadget/raw_gadget.c
Lines 501 to 502 in 1e150b7
Could this check be removed?
USB specifications demand specific behavior with regards to the USB power management when the device is suspended, resumed, or disconnected. Raw Gadget examples should follow these requirements. The Composite Gadget framework implementation can be used as a reference: suspend, resume, disconnect.
Implementing this requires exposing more Gadget API functions via Raw Gadget ioctls, see #40.
Hi.
After implementing my proxy( https://github.com/patryk4815/usb-proxy ) I tried to debug why "sometime" my code fails with proxying mass storage.
It was really "random" (only occurs when transferring really large files), so after hours of debugging my code, it looks like the error is your module :(
ftrace from kernel:
usb_proxy-5634 [000] ..... 35373.583990: usb_ep_queue+0x4/0xc8 <-raw_process_ep_io+0x164/0x4d0 [raw_gadget]
usb_proxy-5634 [001] ..... 35373.584716: usb_ep_queue+0x4/0xc8 <-raw_process_ep_io+0x164/0x4d0 [raw_gadget]
usb_proxy-5634 [002] ..... 35373.585358: usb_ep_queue+0x4/0xc8 <-raw_process_ep_io+0x164/0x4d0 [raw_gadget]
usb_proxy-5634 [000] ..... 35373.585993: usb_ep_queue+0x4/0xc8 <-raw_process_ep_io+0x164/0x4d0 [raw_gadget]
usb_proxy-5634 [000] ..... 35373.586636: usb_ep_queue+0x4/0xc8 <-raw_process_ep_io+0x164/0x4d0 [raw_gadget]
usb_proxy-5634 [002] ..... 35373.587320: usb_ep_queue+0x4/0xc8 <-raw_process_ep_io+0x164/0x4d0 [raw_gadget]
usb_proxy-5634 [002] ..... 35373.587994: usb_ep_queue+0x4/0xc8 <-raw_process_ep_io+0x164/0x4d0 [raw_gadget]
usb_proxy-5634 [003] ..... 35373.588683: usb_ep_queue+0x4/0xc8 <-raw_process_ep_io+0x164/0x4d0 [raw_gadget]
usb_proxy-5634 [003] ..... 35373.589416: usb_ep_queue+0x4/0xc8 <-raw_process_ep_io+0x164/0x4d0 [raw_gadget]
usb_proxy-5634 [003] ..... 35373.590023: usb_ep_queue+0x4/0xc8 <-raw_process_ep_io+0x164/0x4d0 [raw_gadget]
usb_proxy-5634 [003] ..... 35373.590693: usb_ep_queue+0x4/0xc8 <-raw_process_ep_io+0x164/0x4d0 [raw_gadget]
usb_proxy-5634 [003] ..... 35373.591659: usb_ep_queue+0x4/0xc8 <-raw_process_ep_io+0x164/0x4d0 [raw_gadget]
usb_proxy-5634 [003] ..... 35373.591701: usb_ep_dequeue+0x4/0xa8 <-raw_process_ep_io+0x198/0x4d0 [raw_gadget]
usb_proxy-5634 [003] ..... 35373.591740: usb_ep_queue+0x4/0xc8 <-raw_process_ep_io+0x164/0x4d0 [raw_gadget]
call time:
3) + 23.000 us | usb_ep_queue();
3) * 14819.81 us | usb_ep_dequeue();
3) 9.352 us | usb_ep_queue();
dmesg:
kernel: raw-gadget.0 gadget: wait interrupted
kernel: dwc2 fe980000.usb: dwc2_hsotg_ep_sethalt(ep 00000000fe7f0a9a ep2in, 0)
kernel: dwc2 fe980000.usb: dwc2_hsotg_ep_sethalt(ep 00000000cf063d4c ep1out, 0)
kernel: raw-gadget.0 gadget: event fetching interrupted
After some time it randomly get usb_ep_dequeue
.
So i looked into raw-gadget
code.
https://github.com/xairy/raw-gadget/blob/master/raw_gadget/raw_gadget.c#L1044
ret = usb_ep_queue(ep->ep, ep->req, GFP_KERNEL);
if (ret) {
dev_err(&dev->gadget->dev,
"fail, usb_ep_queue returned %d\n", ret);
spin_lock_irqsave(&dev->lock, flags);
dev->state = STATE_DEV_FAILED;
// MISSING "ret = -EBUSY"?
goto out_done;
}
ret = wait_for_completion_interruptible(&done);
if (ret) {
dev_dbg(&dev->gadget->dev, "wait interrupted\n");
usb_ep_dequeue(ep->ep, ep->req);
wait_for_completion(&done);
spin_lock_irqsave(&dev->lock, flags);
// MISSING "ret = -EINTR"?
goto out_done;
}
I think there is missing ret = -EINTR
. Not sure.
But from USB_RAW_IOCTL_EP_WRITE
or USB_RAW_IOCTL_EP_READ
i should get response about "error" right?
Now im getting "good" length writted/readed.
Instructions for running syzkaller reproducers with Raspberry Pi Zero W are outdated.
Update the instructions and potentially move to the Raw Gadget repo.
Related to #51.
The dwc3 UDC driver handles setup requests with wLength == 0
in an unusual way, see the details here.
We need to either fix dwc3 or make Raw Gadget support the way dwc3 works.
Hi,
I'm trying to run /examples/printer.c to see how the bulk tranfer are handled by raw-gadget, but it doesn't work. After entering usb_raw_ep_read
in bulk_out thread, the following ioctl will never return (or the thread being killed maybe)
int rv = ioctl(fd, USB_RAW_IOCTL_EP_READ, io);
After I adding some debug info in raw-gadget, I find that in raw_ioctl_ep_read
, return value of raw_process_ep_io
is set to -512. It's the ERESTARTSYS
error but I don't really understand what that means.
ret = raw_process_ep_io(dev, &io, data, false);
Then it returns from raw_ioctl
and the printer gets stuck in ep0_loop. The same happens in bulk_in thread too.
Here is the kernel verison, and the file system is just a stretch.img constructed by syzkaller script.
root@syzkaller:~# uname -a
Linux syzkaller 6.1.0-rc7-00190-g97ee9d1c1696-dirty #8 SMP PREEMPT_DYNAMIC Sun Dec 4 14:26:16 CET 2022 x86_64 GNU/Linux
Any idea what's going on and how can I fix this? Thanks.
For the IOCTLs of the raw-gadget
module that do not accept any data (e.g. raw_ioctl_run
), the value
argument of the IOCTL call is uninitialized (variadic arg to ioctl()
) and should not be read.
This causes issue when using cross-language bindings to IOCTL into the raw-gadget
driver, such as using nix
from Rust, which intentionally omits any variadic arguments to ioctl since the call requires no data. This causes these functions to spuriously EINVAL as an error code.
I added some logging to the raw_ioctl_run()
and was noticing that value
was taking on random, uninitialized values and causing the call to emit an error.
It should be possible to use Raw Gadget as a backend for Facedancer. At least for UDCs with configurable (direction and transfer type) gadget endpoints.
Currently attempting to run https://github.com/xairy/Facedancer/tree/rawgadget (rubber-ducky.py) on the latest raw-gadget dev branch and receiving the following error, thoughts?
Traceback (most recent call last):
File "/home/jack/Facedancer/rubber-ducky.py", line 37, in <module>
main(device, type_letters())
File "/home/jack/Facedancer/facedancer/devices/__init__.py", line 51, in default_main
device.emulate(*coroutines)
File "/home/jack/Facedancer/facedancer/future/device.py", line 172, in emulate
self.connect()
File "/home/jack/Facedancer/facedancer/future/device.py", line 124, in connect
self.backend = FacedancerUSBApp()
^^^^^^^^^^^^^^^^^^
File "/home/jack/Facedancer/facedancer/core.py", line 23, in FacedancerUSBApp
return FacedancerApp.autodetect(verbose, quirks)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/jack/Facedancer/facedancer/core.py", line 54, in autodetect
return subclass(verbose=verbose, quirks=quirks)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/jack/Facedancer/facedancer/backends/rawgadget.py", line 345, in __init__
super().__init__(device, verbose)
File "/home/jack/Facedancer/facedancer/core.py", line 98, in __init__
self.init_commands()
File "/home/jack/Facedancer/facedancer/backends/rawgadget.py", line 352, in init_commands
self.api.set_timeout(usb_raw_timeout_type.USB_RAW_TIMEOUT_EVENT_FETCH, 0, 20)
File "/home/jack/Facedancer/facedancer/backends/rawgadget.py", line 281, in set_timeout
RawGadgetRequests.USB_RAW_IOCTL_SET_TIMEOUT(self.fd, arg)
File "/home/jack/Facedancer/facedancer/backends/rawgadget.py", line 172, in fn
rv = fcntl.ioctl(fd, req, arg, True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 22] Invalid argument
sys:1: RuntimeWarning: coroutine 'type_letters' was never awaited
Hi @xairy ,
Your RAW GADGET module seems very useful. However, it's quite difficult to use it inside an Android device (without rooting it). Then I ask if you feel it's possible to have some Android API to access to low level gadget functions.
Regards.
The keyboard example provides an uninitialized response of length of 1 to a HID_REQ_SET_REPORT
request. I vaguely recall that the length of 1 might have to do with emulating keyboards for Mac. Nevertheless, the data should be initialized.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.