qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: USB port claiming / set configuration problems


From: Ben Leslie
Subject: Re: USB port claiming / set configuration problems
Date: Tue, 9 Mar 2021 18:52:54 +1100

On Fri, 5 Mar 2021 at 11:50, Ben Leslie <benno@benno.id.au> wrote:
On Fri, 5 Mar 2021 at 01:31, Gerd Hoffmann <kraxel@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.


For the archives, unfortunately this approach did not work for my use case.
I was able to get something working using the claim port approach, but that
meant going behind the back of libusb, which is obviously not suitable to be
merged, and ends up as a reasonably sizable patch.

I'll see if there is any appetite for adding claim port functionality to libusb
before raising it again here.

Thanks for the feedback and assistance.

Cheers,

Ben




reply via email to

[Prev in Thread] Current Thread [Next in Thread]