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