On Fri, 5 Mar 2021 at 01:31, Gerd Hoffmann <kra...@redhat.com> wrote:

>   Hi,
>
> > Would adding support to host-libusb to use these
> > ioctl to claim the port be beneficial?
>
> I don't feel like side-stepping libusb.  That is asking for trouble
> because usbdevfs might behave differently then and confuse libusb.
>
> So, if anything, libusb would need support that, then qemu can use it.
>
> > Based on a simple test program and
> > hardware USB traces for a device connected to a 'claimed' port the kernel
> > does indeed leave the device in an unconfigured state. (Although it still
> > performs some basic control transfers to gather descriptor, and strangely
> > seems to in this case make an explicit SET CONFIGURATION transfer, but
> sets
> > configuration to zero, rather than an actual configuration, which, at
> least
> > for the devices I was able to test with, avoided the problems of calling
> > SET CONFIGURATION (1) twice).
>
> We could try that too (set config to zero first, then set the config we
> actually want) and see if that works better.
>

This approach seems to work well, and let's me just use libusb, which is a
plus.

It seems I had actually misdiagnosed (or only partially diagnosed) the issue
with my 'problem devices'. It turned out that setting *any* valid
configuration
twice in a row causes problems for the device! So, for example, if the
current
configuration was set to 1, and then set configuration 2 was called that
would
also cause problems. I guess that drivers on other systems ensured that
such a sequence never occurred.

I reverted bfe44898848614cfcb3a269bc965afbe1f0f331c and made this change:

--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -955,6 +955,11 @@ static int usb_host_open(USBHostDevice *s,
libusb_device *dev, int hostfd)

     usb_host_detach_kernel(s);

+    rc = libusb_set_configuration(s->dh, 0);
+    if (rc != 0) {
+        goto fail;
+    }
+
     libusb_get_device_descriptor(dev, &s->ddesc);
     usb_host_get_port(s->dev, s->port, sizeof(s->port));

This appears to work for my use cases. (Although I still have more testing
to do).

In terms of the transaction on the wire, this is not quite as good as the
'claim port'
approach. Specifically, with the claim port after setting address and
getting some
basic descriptors the kernel will explicitly set configuration to zero and
not perform
any more transactions. Without the 'claim port' the kernel appears to
configure to
the first configuration and then read a few more descriptors. For my test
cases
at least this doesn't appear to be problematic, but I thought it was worth
calling
out the differences. Of course the great benefit of this approach is that
it uses
existing libusb functionality.

Cheers,

Ben

Reply via email to