usb-device icon indicating copy to clipboard operation
usb-device copied to clipboard

USB Gadget implementation

Open nickray opened this issue 5 years ago • 15 comments

Would be great to wrap the USB Gadget API for Linux for testing purposes. Maybe more a request for the eventual USB Class crates.

nickray avatar May 13 '19 15:05 nickray

I actually took a look at the USB gadget API (especially gadgetfs since that doesn't require an extra kernel driver) some time ago to see if it would be possible to make a driver for it. It seems to be slightly "higher level" than what this crate expects, but it may be possible to make it behave like a lower level driver with some hacks. I don't currently have any hardware that supports the gadget API to test on, so I haven't looked into it in a lot of detail though.

At the very least it would be a good data point to see how universal the UsbBus trait is.

mvirkkunen avatar May 13 '19 18:05 mvirkkunen

Judging just by this example gadgetfs is a bit of a mess:

http://www.linux-usb.org/gadget/usb.c

Seems like none of the drivers agree about the device names, endpoint names or endpoint addresses. I want to know who thought of this API...

mvirkkunen avatar May 23 '19 15:05 mvirkkunen

I think the current buzzword is configfs, https://elinux.org/images/e/ef/USB_Gadget_Configfs_API_0.pdf

Besides, the worse the API, the more of an improvement a nice Rust API can make :)

nickray avatar May 23 '19 17:05 nickray

https://patchwork.kernel.org/patch/11332299/

Looks like Linux might be getting a new "USB Raw Gadget" system in the future, primarily meant for debugging/fuzzing apparently, but this looks like something that would be reasonable to implement for usb-device.

mvirkkunen avatar Feb 11 '20 09:02 mvirkkunen

I wonder if something like a Raspberry Pi Zero or something else commonly available would support this. Would be interesting to try the "USB raw gadget" system. Have to get around to buying the hardware though I suppose...

mvirkkunen avatar Apr 08 '20 11:04 mvirkkunen

Found myself some hardware so I'll take a look at these gadget APIs when I have some time!

mvirkkunen avatar Apr 30 '20 10:04 mvirkkunen

I actually poked around at the raw gadget API recently and was trying to wire usb-device up to it to get integration testing running via CI, but I similarly hit some issues where even raw-gadget is somewhat higher level than this driver. Sending data in packets seems to confuse raw-gadget, as it expects the full descriptor reads, etc.

ryan-summers avatar May 23 '22 09:05 ryan-summers

Is the thinking that the gadget API might be used on one VM to host the usb-device implementation, and tested from another VM? That would be cool - I'd love a way to verify that a USB device passes tests against a Windows host for example.

I wonder if it might be worth looking at QEMU's USB implementation.

ianrrees avatar Aug 04 '22 23:08 ianrrees

I was looking into using raw-gadget as a way to emulate a USB device (running usb-device) to have it enumerate under linux. I had it mostly implemented, but I ran into trouble because raw-gadget is still a higher level interface than what we're interested in. Specifically, I believe that raw-gadget expected to be provided entire descriptors when polling the bus, but in the current implementation of usb-device, we send the MTU size of data, and a descriptor may be spread across many MTUs. This caused hangups in raw-gadget because it expected the full descriptor and would error out otherwise.

ryan-summers avatar Aug 05 '22 09:08 ryan-summers

Ah, so that sounds like implementing a usb-device gadget probably doesn't make sense at the moment. I haven't really studied the endpoint trait branch, wonder if the situation might be different over there.

Is the idea that the gadget implementation would be in a virtual machine or real hardware (something like a Raspberry Pi)? If there's a way to make a VM provide a USB device like that, it could be very useful for testing.

ianrrees avatar Aug 06 '22 08:08 ianrrees

The idea was that the gadget would not be hardware (it would be a software module that talks through some /dev/raw-gadget file descriptor, but I wouldn't call it a virtual machine). The intent here is to make tests runable on any machine without hardware I believe.

ryan-summers avatar Aug 08 '22 08:08 ryan-summers

But then again the gadget could also be hardware, and you could implement your own USB devices on Linux! Two birds with one stone.

mvirkkunen avatar Aug 08 '22 15:08 mvirkkunen

Yeah, I think a Linux Gadget driver would be great, for sure. And, I think with there being such cheap, small, powerful embedded systems, there could be a lot of interesting use cases for one.

But, I don't quite understand how a usb-device Gadget driver would facilitate testing usb-device without any hardware. My understanding is that Gadget is a Linux framework that makes a USB controller present a USB device, rather than the typical USB host. Is there some way to loopback USB in a Linux system? I guess if you had a machine with multiple USB controllers, a Gadget driver could manage one of them, and a cable could be plugged between it and a regular host controller (I've got loads of recent work experience with A-A cables if that's helpful ;) ).

Edit to add: an implicit assumption in my question is that the hardwareless test would need to run on a stock Linux, so it could be used in a typical CI environment.

ianrrees avatar Aug 08 '22 21:08 ianrrees

Yeah, I think a Linux Gadget driver would be great, for sure. And, I think with there being such cheap, small, powerful embedded systems, there could be a lot of interesting use cases for one.

But, I don't quite understand how a usb-device Gadget driver would facilitate testing usb-device without any hardware. My understanding is that Gadget is a Linux framework that makes a USB controller present a USB device, rather than the typical USB host. Is there some way to loopback USB in a Linux system? I guess if you had a machine with multiple USB controllers, a Gadget driver could manage one of them, and a cable could be plugged between it and a regular host controller (I've got loads of recent work experience with A-A cables if that's helpful ;) ).

Edit to add: an implicit assumption in my question is that the hardwareless test would need to run on a stock Linux, so it could be used in a typical CI environment.

Check this: https://www.collabora.com/news-and-blog/blog/2019/06/24/using-dummy-hcd/

mbyzhang avatar Dec 26 '22 21:12 mbyzhang

Thanks @mbyzhang - that dummy_hcd driver looks very useful indeed!

I came to this thread initially through work on iscochronous support, and see this in the current dummy_hcd driver * Note: The emulation does not include isochronous transfers!.

ianrrees avatar Mar 22 '23 03:03 ianrrees