On Tue, 5 Jun 2018, Andrey Konovalov wrote:

> On Mon, Jun 4, 2018 at 9:37 PM, Alan Stern <st...@rowland.harvard.edu> wrote:
> > On Mon, 4 Jun 2018, Andrey Konovalov wrote:
> 
> Hi, Alan!

Hi!

> [...]
> 
> >> The perfect solution would be to have something like /dev/tun for USB,
> >> where you can write USB packets and the kernel would synchronously
> >> process them. I'm not sure whether this is possible (highly
> >> asynchronous USB core subsystem architecture + all communication is
> >> initiated by the host).
> >
> > gadgetfs is a little like that already, except of course that the
> > processing is not synchronous.
> 
> Yes, I started with GadgetFS initially, but actually ended up writing
> my own interface that provides userspace interface to the gadget API
> instead. Once I figure out what exactly I need from it, it might be a
> good idea to merge it with GadgetFS as some special mode. Or not, not
> sure yet.

What do you need that's different from what gadgetfs provides?

> > Another aspect of this would be fuzzing USB host controller drivers.
> > In theory you could start doing this now, although you would have to
> > use a real UDC instead of dummy-hcd.  However, this may create more
> > complications that you want to deal with at the moment.
> 
> Could you elaborate on this? AFAIU the dummy device contains both a
> virtual UDC and a virtual HCD that are connected to each other and
> allow to plug a gadget device into usb core within the kernel. How do
> you test a driver for an actual host controller? Is there a way to
> connect a dummy UDC with an actual HCD?

You can't connect a dummy UDC to an actual HCD.  But you can connect an 
actual UDC to an actual HCD -- people do it all the time.

Normally the UDC and the HCD reside on separate computers.  For
example, mobile devices typically have UDCs, and you can connect them
to PCs.  But there is also UDC hardware available for Linux on Intel
systems, so you can have the UDC and the HCD in the same computer if
that's what you want.  Or two separate PCs, both running Linux.  Or 
even a Linux PC gadget connected to a Windows or OS X host!

...

> The main question is: suppose we started a test program that emulates
> a virtual USB device. How do we know that the test is over?

That depends on what you are testing.

>  Once all
> the hub events are processed we can tell that the device is probably
> either connected successfully or failed to connect. But then the
> device driver can start it's own thread for example or register a
> timer that does more work with the device.

Right.  For example, usb-storage uses a work-queue routine for SCSI
scanning when a new device is probed.  And in that routine, the SCSI
layer often delegates some of the scanning work to async helper
threads, depending on the how the system is configured.

>  There are probably some
> ways to tell what the device driver does at this moment for some
> standard USB classes.

Yes, I imagine so.  But it will be different for each driver.

> I guess I'll start with a timeout for now, until I figure out how to
> properly collect coverage.

That's probably the best thing to do.

...

> > In fact, dummy-hcd is capable of creating more than one virtual root
> > hub (see the "num" module parameter), so in theory you could run
> > multiple tests at the same time.  I don't think this capability has
> > been tested very much.
> 
> OK, that's nice. I just tried it and it kind of works, but there are two 
> issues:
> 
> 1. There's a hardcoded limit on the maximum number of virtual UDCs
> (#define MAX_NUM_UDC 2). Increasing this parameters seems to work just
> fine.
> 
> 2. All the virtual UDCs get the same name "dummy_udc". And since the
> process of UDC lookup to bind a gadget driver is based on the UDC name
> (see usb_gadget_probe_driver()), we can't bind different gadget
> drivers to different UDCs (and therefore connect to different hubs).

That can be changed pretty easily.  For virtual UDCs beyond the first, 
we could append "-2", "-3", and so on to the "dummy_udc" name, for 
example.

> >> Basically we need a way to run a test program (that connects a USB
> >> device and works with it from userspace for example) and then destroy
> >> all the accumulated state before running the next test.
> >
> > You can do that with dummy-hcd simply by removing the USB gadget
> > (closing the gadgetfs files, for example).
> 
> Do I understand correctly that calling usb_gadget_unregister_driver()
> should get rid of all of the device state? (That's what gadgetfs seems
> to do when you close the file).

It should.  If it doesn't, there's a bug in the UDC driver or UDC core.

> > If you want to be extra
> > thorough, unload the gadget driver and dummy-hcd modules after the end
> > of the test, and then reload them before starting the next test.  That
> > should get rid of any important state.
> 
> What state is kept if we don't reload the module?

There shouldn't be anything important.  Perhaps just some trivial
leftovers (like the old connection speed) which will be reset when a
new gadget driver is loaded.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to