All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] usb-host: workaround libusb bug
@ 2020-08-24 11:00 Gerd Hoffmann
  2020-09-01 14:05 ` Alex Bennée
  0 siblings, 1 reply; 7+ messages in thread
From: Gerd Hoffmann @ 2020-08-24 11:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

libusb_get_device_speed() does not work for
libusb_wrap_sys_device() devices in v1.0.23.

Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1871090
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/host-libusb.c | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index c474551d8456..77f1eaa5fe9e 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -39,6 +39,11 @@
 #endif
 #include <libusb.h>
 
+#ifdef CONFIG_LINUX
+#include <sys/ioctl.h>
+#include <linux/usbdevice_fs.h>
+#endif
+
 #include "qapi/error.h"
 #include "migration/vmstate.h"
 #include "monitor/monitor.h"
@@ -885,6 +890,7 @@ static void usb_host_ep_update(USBHostDevice *s)
 static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd)
 {
     USBDevice *udev = USB_DEVICE(s);
+    int libusb_speed;
     int bus_num = 0;
     int addr = 0;
     int rc;
@@ -935,7 +941,36 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd)
     usb_ep_init(udev);
     usb_host_ep_update(s);
 
-    udev->speed     = speed_map[libusb_get_device_speed(dev)];
+    libusb_speed = libusb_get_device_speed(dev);
+#ifdef CONFIG_LINUX
+    if (hostfd && libusb_speed == 0) {
+        /*
+         * Workaround libusb bug: libusb_get_device_speed() does not
+         * work for libusb_wrap_sys_device() devices in v1.0.23.
+         *
+         * Speeds are defined in linux/usb/ch9.h, file not included
+         * due to name conflicts.
+         */
+        int rc = ioctl(hostfd, USBDEVFS_GET_SPEED, NULL);
+        switch(rc) {
+        case 1: /* low */
+            libusb_speed = LIBUSB_SPEED_LOW;
+            break;
+        case 2: /* full */
+            libusb_speed = LIBUSB_SPEED_FULL;
+            break;
+        case 3: /* high */
+        case 4: /* wireless */
+            libusb_speed = LIBUSB_SPEED_HIGH;
+            break;
+        case 5: /* super */
+        case 6: /* super plus */
+            libusb_speed = LIBUSB_SPEED_SUPER;
+            break;
+        }
+    }
+#endif
+    udev->speed = speed_map[libusb_speed];
     usb_host_speed_compat(s);
 
     if (s->ddesc.iProduct) {
-- 
2.27.0



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] usb-host: workaround libusb bug
  2020-08-24 11:00 [PATCH] usb-host: workaround libusb bug Gerd Hoffmann
@ 2020-09-01 14:05 ` Alex Bennée
  2020-09-02  8:09   ` Gerd Hoffmann
  0 siblings, 1 reply; 7+ messages in thread
From: Alex Bennée @ 2020-09-01 14:05 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel


Gerd Hoffmann <kraxel@redhat.com> writes:

> libusb_get_device_speed() does not work for
> libusb_wrap_sys_device() devices in v1.0.23.
>
> Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1871090
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  hw/usb/host-libusb.c | 37 ++++++++++++++++++++++++++++++++++++-
>  1 file changed, 36 insertions(+), 1 deletion(-)
>
> diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
> index c474551d8456..77f1eaa5fe9e 100644
> --- a/hw/usb/host-libusb.c
> +++ b/hw/usb/host-libusb.c
> @@ -39,6 +39,11 @@
>  #endif
>  #include <libusb.h>
>  
> +#ifdef CONFIG_LINUX
> +#include <sys/ioctl.h>
> +#include <linux/usbdevice_fs.h>
> +#endif
> +
>  #include "qapi/error.h"
>  #include "migration/vmstate.h"
>  #include "monitor/monitor.h"
> @@ -885,6 +890,7 @@ static void usb_host_ep_update(USBHostDevice *s)
>  static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd)
>  {
>      USBDevice *udev = USB_DEVICE(s);
> +    int libusb_speed;
>      int bus_num = 0;
>      int addr = 0;
>      int rc;
> @@ -935,7 +941,36 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd)
>      usb_ep_init(udev);
>      usb_host_ep_update(s);
>  
> -    udev->speed     = speed_map[libusb_get_device_speed(dev)];
> +    libusb_speed = libusb_get_device_speed(dev);
> +#ifdef CONFIG_LINUX
> +    if (hostfd && libusb_speed == 0) {
> +        /*
> +         * Workaround libusb bug: libusb_get_device_speed() does not
> +         * work for libusb_wrap_sys_device() devices in v1.0.23.
> +         *
> +         * Speeds are defined in linux/usb/ch9.h, file not included
> +         * due to name conflicts.
> +         */
> +        int rc = ioctl(hostfd, USBDEVFS_GET_SPEED, NULL);

This (further) breaks a bunch of the Travis jobs - I assume because libusb doesn't
always have this symbol:

  Compiling C object libcommon.fa.p/hw_input_vhost-user-input.c.o

  ../hw/usb/host-libusb.c: In function ‘usb_host_open’:

  ../hw/usb/host-libusb.c:954:32: error: ‘USBDEVFS_GET_SPEED’ undeclared (first use in this function)

  int rc = ioctl(hostfd, USBDEVFS_GET_SPEED, NULL);

  ^

  ../hw/usb/host-libusb.c:954:32: note: each undeclared identifier is reported only once for each function it appears in

  Makefile.ninja:961: recipe for target 'libcommon.fa.p/hw_usb_host-libusb.c.o' failed

  make: *** [libcommon.fa.p/hw_usb_host-libusb.c.o] Error 1

  make: *** Waiting for unfinished jobs....

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] usb-host: workaround libusb bug
  2020-09-01 14:05 ` Alex Bennée
@ 2020-09-02  8:09   ` Gerd Hoffmann
  2020-09-02 14:31     ` Alex Bennée
  0 siblings, 1 reply; 7+ messages in thread
From: Gerd Hoffmann @ 2020-09-02  8:09 UTC (permalink / raw)
  To: Alex Bennée; +Cc: qemu-devel

> > +#include <linux/usbdevice_fs.h>

> > +        int rc = ioctl(hostfd, USBDEVFS_GET_SPEED, NULL);
> 
> This (further) breaks a bunch of the Travis jobs - I assume because libusb doesn't
> always have this symbol:
> 
>   ../hw/usb/host-libusb.c:954:32: error: ‘USBDEVFS_GET_SPEED’ undeclared (first use in this function)

It isn't libusb, it is the kernel (linux/usbdevice_fs.h).

/me checks git ...
Added in 4.13, so available for quite a while.
I guess that is the prehistoric ubuntu version travis has?

Given that we only need that workaround with rather new libusb versions
(which have libusb_wrap_sys_device() support) which most likely isn't
present in that old ubuntu version we can probably just do this:

diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index 08604f787fdf..c25102f3aca1 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -942,7 +942,7 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd)
     usb_host_ep_update(s);
 
     libusb_speed = libusb_get_device_speed(dev);
-#ifdef CONFIG_LINUX
+#if LIBUSB_API_VERSION >= 0x01000107 && defined(CONFIG_LINUX)
     if (hostfd && libusb_speed == 0) {
         /*
          * Workaround libusb bug: libusb_get_device_speed() does not



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] usb-host: workaround libusb bug
  2020-09-02  8:09   ` Gerd Hoffmann
@ 2020-09-02 14:31     ` Alex Bennée
  2020-09-03  5:33       ` Gerd Hoffmann
  0 siblings, 1 reply; 7+ messages in thread
From: Alex Bennée @ 2020-09-02 14:31 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel


Gerd Hoffmann <kraxel@redhat.com> writes:

>> > +#include <linux/usbdevice_fs.h>
>
>> > +        int rc = ioctl(hostfd, USBDEVFS_GET_SPEED, NULL);
>> 
>> This (further) breaks a bunch of the Travis jobs - I assume because libusb doesn't
>> always have this symbol:
>> 
>>   ../hw/usb/host-libusb.c:954:32: error: ‘USBDEVFS_GET_SPEED’ undeclared (first use in this function)
>
> It isn't libusb, it is the kernel (linux/usbdevice_fs.h).
>
> /me checks git ...
> Added in 4.13, so available for quite a while.
> I guess that is the prehistoric ubuntu version travis has?
>
> Given that we only need that workaround with rather new libusb versions
> (which have libusb_wrap_sys_device() support) which most likely isn't
> present in that old ubuntu version we can probably just do this:
>
> diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
> index 08604f787fdf..c25102f3aca1 100644
> --- a/hw/usb/host-libusb.c
> +++ b/hw/usb/host-libusb.c
> @@ -942,7 +942,7 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd)
>      usb_host_ep_update(s);
>  
>      libusb_speed = libusb_get_device_speed(dev);
> -#ifdef CONFIG_LINUX
> +#if LIBUSB_API_VERSION >= 0x01000107 && defined(CONFIG_LINUX)
>      if (hostfd && libusb_speed == 0) {
>          /*
>           * Workaround libusb bug: libusb_get_device_speed() does not

That works. Do you want to include that in your next PR or send a patch
for me to include in my testing/next PR?

In the meantime:

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] usb-host: workaround libusb bug
  2020-09-02 14:31     ` Alex Bennée
@ 2020-09-03  5:33       ` Gerd Hoffmann
  0 siblings, 0 replies; 7+ messages in thread
From: Gerd Hoffmann @ 2020-09-03  5:33 UTC (permalink / raw)
  To: Alex Bennée; +Cc: qemu-devel

On Wed, Sep 02, 2020 at 03:31:46PM +0100, Alex Bennée wrote:
> 
> Gerd Hoffmann <kraxel@redhat.com> writes:
> 
> >> > +#include <linux/usbdevice_fs.h>
> >
> >> > +        int rc = ioctl(hostfd, USBDEVFS_GET_SPEED, NULL);
> >> 
> >> This (further) breaks a bunch of the Travis jobs - I assume because libusb doesn't
> >> always have this symbol:
> >> 
> >>   ../hw/usb/host-libusb.c:954:32: error: ‘USBDEVFS_GET_SPEED’ undeclared (first use in this function)
> >
> > It isn't libusb, it is the kernel (linux/usbdevice_fs.h).
> >
> > /me checks git ...
> > Added in 4.13, so available for quite a while.
> > I guess that is the prehistoric ubuntu version travis has?
> >
> > Given that we only need that workaround with rather new libusb versions
> > (which have libusb_wrap_sys_device() support) which most likely isn't
> > present in that old ubuntu version we can probably just do this:
> >
> > diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
> > index 08604f787fdf..c25102f3aca1 100644
> > --- a/hw/usb/host-libusb.c
> > +++ b/hw/usb/host-libusb.c
> > @@ -942,7 +942,7 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd)
> >      usb_host_ep_update(s);
> >  
> >      libusb_speed = libusb_get_device_speed(dev);
> > -#ifdef CONFIG_LINUX
> > +#if LIBUSB_API_VERSION >= 0x01000107 && defined(CONFIG_LINUX)
> >      if (hostfd && libusb_speed == 0) {
> >          /*
> >           * Workaround libusb bug: libusb_get_device_speed() does not
> 
> That works. Do you want to include that in your next PR or send a patch
> for me to include in my testing/next PR?

Patch is on the list already:
https://patchwork.ozlabs.org/project/qemu-devel/patch/20200902081445.3291-1-kraxel@redhat.com/

Feel free to include it in testing pull.

take care,
  Gerd



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] usb-host: workaround libusb bug
  2020-05-29  7:22 Gerd Hoffmann
@ 2020-05-29 11:43 ` BALATON Zoltan
  0 siblings, 0 replies; 7+ messages in thread
From: BALATON Zoltan @ 2020-05-29 11:43 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

On Fri, 29 May 2020, Gerd Hoffmann wrote:
> libusb seems to no allways call the completion callback for requests

Typo: not always call.

Regards,
BALATON Zoltan

> canceled (which it is supposed to do according to the docs).  So add
> a limit to avoid qemu waiting forever.
>
> Tested-by: BALATON Zoltan <balaton@eik.bme.hu>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> hw/usb/host-libusb.c | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
>
> diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
> index e28441379d99..094010d5f849 100644
> --- a/hw/usb/host-libusb.c
> +++ b/hw/usb/host-libusb.c
> @@ -951,6 +951,7 @@ fail:
> static void usb_host_abort_xfers(USBHostDevice *s)
> {
>     USBHostRequest *r, *rtmp;
> +    int limit = 100;
>
>     QTAILQ_FOREACH_SAFE(r, &s->requests, next, rtmp) {
>         usb_host_req_abort(r);
> @@ -961,6 +962,19 @@ static void usb_host_abort_xfers(USBHostDevice *s)
>         memset(&tv, 0, sizeof(tv));
>         tv.tv_usec = 2500;
>         libusb_handle_events_timeout(ctx, &tv);
> +        if (--limit == 0) {
> +            /*
> +             * Don't wait forever for libusb calling the complete
> +             * callback (which will unlink and free the request).
> +             *
> +             * Leaking memory here, to make sure libusb will not
> +             * access memory which we have released already.
> +             */
> +            QTAILQ_FOREACH_SAFE(r, &s->requests, next, rtmp) {
> +                QTAILQ_REMOVE(&s->requests, r, next);
> +            }
> +            return;
> +        }
>     }
> }
>
>


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH] usb-host: workaround libusb bug
@ 2020-05-29  7:22 Gerd Hoffmann
  2020-05-29 11:43 ` BALATON Zoltan
  0 siblings, 1 reply; 7+ messages in thread
From: Gerd Hoffmann @ 2020-05-29  7:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

libusb seems to no allways call the completion callback for requests
canceled (which it is supposed to do according to the docs).  So add
a limit to avoid qemu waiting forever.

Tested-by: BALATON Zoltan <balaton@eik.bme.hu>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/host-libusb.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index e28441379d99..094010d5f849 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -951,6 +951,7 @@ fail:
 static void usb_host_abort_xfers(USBHostDevice *s)
 {
     USBHostRequest *r, *rtmp;
+    int limit = 100;
 
     QTAILQ_FOREACH_SAFE(r, &s->requests, next, rtmp) {
         usb_host_req_abort(r);
@@ -961,6 +962,19 @@ static void usb_host_abort_xfers(USBHostDevice *s)
         memset(&tv, 0, sizeof(tv));
         tv.tv_usec = 2500;
         libusb_handle_events_timeout(ctx, &tv);
+        if (--limit == 0) {
+            /*
+             * Don't wait forever for libusb calling the complete
+             * callback (which will unlink and free the request).
+             *
+             * Leaking memory here, to make sure libusb will not
+             * access memory which we have released already.
+             */
+            QTAILQ_FOREACH_SAFE(r, &s->requests, next, rtmp) {
+                QTAILQ_REMOVE(&s->requests, r, next);
+            }
+            return;
+        }
     }
 }
 
-- 
2.18.4



^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-09-03  5:33 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-24 11:00 [PATCH] usb-host: workaround libusb bug Gerd Hoffmann
2020-09-01 14:05 ` Alex Bennée
2020-09-02  8:09   ` Gerd Hoffmann
2020-09-02 14:31     ` Alex Bennée
2020-09-03  5:33       ` Gerd Hoffmann
  -- strict thread matches above, loose matches on Subject: below --
2020-05-29  7:22 Gerd Hoffmann
2020-05-29 11:43 ` BALATON Zoltan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.