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

USB Gadget implementation #12

Open
nickray opened this issue May 13, 2019 · 15 comments
Open

USB Gadget implementation #12

nickray opened this issue May 13, 2019 · 15 comments
Labels
enhancement New feature or request

Comments

@nickray
Copy link
Contributor

nickray commented May 13, 2019

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

@mvirkkunen
Copy link
Collaborator

mvirkkunen commented May 13, 2019

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
Copy link
Collaborator

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...

@nickray
Copy link
Contributor Author

nickray commented May 23, 2019

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 :)

@mvirkkunen mvirkkunen changed the title Request: USB Gadget implementation USB Gadget implementation Feb 6, 2020
@mvirkkunen mvirkkunen added the enhancement New feature or request label Feb 6, 2020
@mvirkkunen
Copy link
Collaborator

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
Copy link
Collaborator

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
Copy link
Collaborator

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

@ryan-summers
Copy link
Member

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.

@ianrrees
Copy link
Contributor

ianrrees commented Aug 4, 2022

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.

@ryan-summers
Copy link
Member

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.

@ianrrees
Copy link
Contributor

ianrrees commented Aug 6, 2022

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.

@ryan-summers
Copy link
Member

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.

@mvirkkunen
Copy link
Collaborator

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

@ianrrees
Copy link
Contributor

ianrrees commented Aug 8, 2022

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.

@mbyzhang
Copy link

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/

@ianrrees
Copy link
Contributor

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!.

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

No branches or pull requests

5 participants