mirror of https://github.com/xemu-project/xemu.git
usb-host: add hostdevice property, workaround libusb bug
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABCgAGBQJe6fTJAAoJEEy22O7T6HE4Rw8QAMXXrDb2+Ay7nduQkusrl/K5 e43CiNw3yRB0uKv/HLyU5fkIQTG5lNfFDej92RH+SaI8Jox+y8pjxYoFs+ltZWQg d0UsBwycTdcyt54k6fOiNbR15eyXVJrQRTmt1tWNV6bnqOfczLQr6P3GrxS45/2+ fNHvZ1BAdxpWaJQBlQk/r+d27iSfG4aD/8ECD5m7h6K/5WhIvJibJ0/R3Rl3LK9o ci7Qq5KXXzO3Xk/mzOpf8z8erO4qvHBGvdHnY4Vn3lWwOM278U6jkXdzr+VGqQ86 dM38lqke2GiEe8xlqxdLdhgv0GltpRD0sswvC1qy+bjX7T8LcD7P+WMRQgmRNKUx j3wgGJAGVSdCA+n1VXtraZCBuZNkDW9otuA8r9D2/kOXKZr+kPaDLNHm1+wl5Chx UTC9ddq9weEc2g4UcDXGiAqsLDYAJxqDmCcAWNwTVB9HlVo575pOYx1Yg57EScFj 2i1ohciHMUfm42bqso7OvHmZan4+zP0rKm7lkHVdlANHwz4TVXA5NpeAixcwoqJj 7W3w23Nz0+wJJXJkCFqiqNExh/Rgriax4TGYVk3mMwo16nVw5bSvy544LKTRYn2L xflxmVxUw8Z8aFaeGkX+ODpeoCULCQ680X6slM4y79/sb8a4KStPeTZVvqk037mK lL9p3sENME+IeyTGZnsO =vOPa -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/usb-20200617-pull-request' into staging usb-host: add hostdevice property, workaround libusb bug # gpg: Signature made Wed 17 Jun 2020 11:47:37 BST # gpg: using RSA key 4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full] # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full] # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full] # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/usb-20200617-pull-request: usb-host: workaround libusb bug usb: add hostdevice property to usb-host Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
26bf4a2921
|
@ -80,6 +80,7 @@ struct USBHostDevice {
|
||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
struct USBAutoFilter match;
|
struct USBAutoFilter match;
|
||||||
|
char *hostdevice;
|
||||||
int32_t bootindex;
|
int32_t bootindex;
|
||||||
uint32_t iso_urb_count;
|
uint32_t iso_urb_count;
|
||||||
uint32_t iso_urb_frames;
|
uint32_t iso_urb_frames;
|
||||||
|
@ -97,6 +98,7 @@ struct USBHostDevice {
|
||||||
int addr;
|
int addr;
|
||||||
char port[16];
|
char port[16];
|
||||||
|
|
||||||
|
int hostfd;
|
||||||
libusb_device *dev;
|
libusb_device *dev;
|
||||||
libusb_device_handle *dh;
|
libusb_device_handle *dh;
|
||||||
struct libusb_device_descriptor ddesc;
|
struct libusb_device_descriptor ddesc;
|
||||||
|
@ -880,27 +882,46 @@ static void usb_host_ep_update(USBHostDevice *s)
|
||||||
libusb_free_config_descriptor(conf);
|
libusb_free_config_descriptor(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int usb_host_open(USBHostDevice *s, libusb_device *dev)
|
static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd)
|
||||||
{
|
{
|
||||||
USBDevice *udev = USB_DEVICE(s);
|
USBDevice *udev = USB_DEVICE(s);
|
||||||
int bus_num = libusb_get_bus_number(dev);
|
int bus_num = 0;
|
||||||
int addr = libusb_get_device_address(dev);
|
int addr = 0;
|
||||||
int rc;
|
int rc;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
if (s->bh_postld_pending) {
|
if (s->bh_postld_pending) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_usb_host_open_started(bus_num, addr);
|
|
||||||
|
|
||||||
if (s->dh != NULL) {
|
if (s->dh != NULL) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dev) {
|
||||||
|
bus_num = libusb_get_bus_number(dev);
|
||||||
|
addr = libusb_get_device_address(dev);
|
||||||
|
trace_usb_host_open_started(bus_num, addr);
|
||||||
|
|
||||||
rc = libusb_open(dev, &s->dh);
|
rc = libusb_open(dev, &s->dh);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
#if LIBUSB_API_VERSION >= 0x01000107
|
||||||
|
trace_usb_host_open_hostfd(hostfd);
|
||||||
|
|
||||||
|
rc = libusb_wrap_sys_device(ctx, hostfd, &s->dh);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
s->hostfd = hostfd;
|
||||||
|
dev = libusb_get_device(s->dh);
|
||||||
|
bus_num = libusb_get_bus_number(dev);
|
||||||
|
addr = libusb_get_device_address(dev);
|
||||||
|
#else
|
||||||
|
g_assert_not_reached();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
s->dev = dev;
|
s->dev = dev;
|
||||||
s->bus_num = bus_num;
|
s->bus_num = bus_num;
|
||||||
|
@ -951,6 +972,7 @@ fail:
|
||||||
static void usb_host_abort_xfers(USBHostDevice *s)
|
static void usb_host_abort_xfers(USBHostDevice *s)
|
||||||
{
|
{
|
||||||
USBHostRequest *r, *rtmp;
|
USBHostRequest *r, *rtmp;
|
||||||
|
int limit = 100;
|
||||||
|
|
||||||
QTAILQ_FOREACH_SAFE(r, &s->requests, next, rtmp) {
|
QTAILQ_FOREACH_SAFE(r, &s->requests, next, rtmp) {
|
||||||
usb_host_req_abort(r);
|
usb_host_req_abort(r);
|
||||||
|
@ -961,6 +983,19 @@ static void usb_host_abort_xfers(USBHostDevice *s)
|
||||||
memset(&tv, 0, sizeof(tv));
|
memset(&tv, 0, sizeof(tv));
|
||||||
tv.tv_usec = 2500;
|
tv.tv_usec = 2500;
|
||||||
libusb_handle_events_timeout(ctx, &tv);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -988,6 +1023,11 @@ static int usb_host_close(USBHostDevice *s)
|
||||||
s->dh = NULL;
|
s->dh = NULL;
|
||||||
s->dev = NULL;
|
s->dev = NULL;
|
||||||
|
|
||||||
|
if (s->hostfd != -1) {
|
||||||
|
close(s->hostfd);
|
||||||
|
s->hostfd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
usb_host_auto_check(NULL);
|
usb_host_auto_check(NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1025,9 +1065,6 @@ static libusb_device *usb_host_find_ref(int bus, int addr)
|
||||||
libusb_device *ret = NULL;
|
libusb_device *ret = NULL;
|
||||||
int i, n;
|
int i, n;
|
||||||
|
|
||||||
if (usb_host_init() != 0) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
n = libusb_get_device_list(ctx, &devs);
|
n = libusb_get_device_list(ctx, &devs);
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
if (libusb_get_bus_number(devs[i]) == bus &&
|
if (libusb_get_bus_number(devs[i]) == bus &&
|
||||||
|
@ -1046,6 +1083,10 @@ static void usb_host_realize(USBDevice *udev, Error **errp)
|
||||||
libusb_device *ldev;
|
libusb_device *ldev;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (usb_host_init() != 0) {
|
||||||
|
error_setg(errp, "failed to init libusb");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (s->match.vendor_id > 0xffff) {
|
if (s->match.vendor_id > 0xffff) {
|
||||||
error_setg(errp, "vendorid out of range");
|
error_setg(errp, "vendorid out of range");
|
||||||
return;
|
return;
|
||||||
|
@ -1064,7 +1105,24 @@ static void usb_host_realize(USBDevice *udev, Error **errp)
|
||||||
udev->auto_attach = 0;
|
udev->auto_attach = 0;
|
||||||
QTAILQ_INIT(&s->requests);
|
QTAILQ_INIT(&s->requests);
|
||||||
QTAILQ_INIT(&s->isorings);
|
QTAILQ_INIT(&s->isorings);
|
||||||
|
s->hostfd = -1;
|
||||||
|
|
||||||
|
#if LIBUSB_API_VERSION >= 0x01000107
|
||||||
|
if (s->hostdevice) {
|
||||||
|
int fd;
|
||||||
|
s->needs_autoscan = false;
|
||||||
|
fd = qemu_open(s->hostdevice, O_RDWR);
|
||||||
|
if (fd < 0) {
|
||||||
|
error_setg_errno(errp, errno, "failed to open %s", s->hostdevice);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rc = usb_host_open(s, NULL, fd);
|
||||||
|
if (rc < 0) {
|
||||||
|
error_setg(errp, "failed to open host usb device %s", s->hostdevice);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
if (s->match.addr && s->match.bus_num &&
|
if (s->match.addr && s->match.bus_num &&
|
||||||
!s->match.vendor_id &&
|
!s->match.vendor_id &&
|
||||||
!s->match.product_id &&
|
!s->match.product_id &&
|
||||||
|
@ -1077,7 +1135,7 @@ static void usb_host_realize(USBDevice *udev, Error **errp)
|
||||||
s->match.bus_num, s->match.addr);
|
s->match.bus_num, s->match.addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rc = usb_host_open(s, ldev);
|
rc = usb_host_open(s, ldev, 0);
|
||||||
libusb_unref_device(ldev);
|
libusb_unref_device(ldev);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
error_setg(errp, "failed to open host usb device %d:%d",
|
error_setg(errp, "failed to open host usb device %d:%d",
|
||||||
|
@ -1605,6 +1663,9 @@ static Property usb_host_dev_properties[] = {
|
||||||
DEFINE_PROP_STRING("hostport", USBHostDevice, match.port),
|
DEFINE_PROP_STRING("hostport", USBHostDevice, match.port),
|
||||||
DEFINE_PROP_UINT32("vendorid", USBHostDevice, match.vendor_id, 0),
|
DEFINE_PROP_UINT32("vendorid", USBHostDevice, match.vendor_id, 0),
|
||||||
DEFINE_PROP_UINT32("productid", USBHostDevice, match.product_id, 0),
|
DEFINE_PROP_UINT32("productid", USBHostDevice, match.product_id, 0),
|
||||||
|
#if LIBUSB_API_VERSION >= 0x01000107
|
||||||
|
DEFINE_PROP_STRING("hostdevice", USBHostDevice, hostdevice),
|
||||||
|
#endif
|
||||||
DEFINE_PROP_UINT32("isobufs", USBHostDevice, iso_urb_count, 4),
|
DEFINE_PROP_UINT32("isobufs", USBHostDevice, iso_urb_count, 4),
|
||||||
DEFINE_PROP_UINT32("isobsize", USBHostDevice, iso_urb_frames, 32),
|
DEFINE_PROP_UINT32("isobsize", USBHostDevice, iso_urb_frames, 32),
|
||||||
DEFINE_PROP_BOOL("guest-reset", USBHostDevice,
|
DEFINE_PROP_BOOL("guest-reset", USBHostDevice,
|
||||||
|
@ -1723,7 +1784,7 @@ static void usb_host_auto_check(void *unused)
|
||||||
if (s->dh != NULL) {
|
if (s->dh != NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (usb_host_open(s, devs[i]) < 0) {
|
if (usb_host_open(s, devs[i], 0) < 0) {
|
||||||
s->errcount++;
|
s->errcount++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -291,6 +291,7 @@ usb_mtp_file_monitor_event(int dev, const char *path, const char *s) "dev %d, pa
|
||||||
|
|
||||||
# host-libusb.c
|
# host-libusb.c
|
||||||
usb_host_open_started(int bus, int addr) "dev %d:%d"
|
usb_host_open_started(int bus, int addr) "dev %d:%d"
|
||||||
|
usb_host_open_hostfd(int hostfd) "hostfd %d"
|
||||||
usb_host_open_success(int bus, int addr) "dev %d:%d"
|
usb_host_open_success(int bus, int addr) "dev %d:%d"
|
||||||
usb_host_open_failure(int bus, int addr) "dev %d:%d"
|
usb_host_open_failure(int bus, int addr) "dev %d:%d"
|
||||||
usb_host_close(int bus, int addr) "dev %d:%d"
|
usb_host_close(int bus, int addr) "dev %d:%d"
|
||||||
|
|
Loading…
Reference in New Issue