aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2020-02-03 12:41:08 +0100
committerGerd Hoffmann <kraxel@redhat.com>2020-02-12 17:20:31 +0100
commit76d0a9362c6a6a7d88aa18c84c4186c9107ecaef (patch)
tree72177d03eae242347501f69060e319ed907a4f6d /hw
parente18e5501d8ac692d32657a3e1ef545b14e72b730 (diff)
downloadqemu-76d0a9362c6a6a7d88aa18c84c4186c9107ecaef.zip
qemu-76d0a9362c6a6a7d88aa18c84c4186c9107ecaef.tar.gz
qemu-76d0a9362c6a6a7d88aa18c84c4186c9107ecaef.tar.bz2
usb-host: wait for cancel complete
After canceling transfers call into libvirt so it can process the request, and wait for it to complete. Also cancel all pending transfers before exiting qemu. Buglink: https://bugzilla.redhat.com//show_bug.cgi?id=1749745 Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Message-id: 20200203114108.23952-1-kraxel@redhat.com
Diffstat (limited to 'hw')
-rw-r--r--hw/usb/host-libusb.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index 2594700..2ac7a93 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -354,9 +354,7 @@ static USBHostRequest *usb_host_req_alloc(USBHostDevice *s, USBPacket *p,
static void usb_host_req_free(USBHostRequest *r)
{
- if (r->host) {
- QTAILQ_REMOVE(&r->host->requests, r, next);
- }
+ QTAILQ_REMOVE(&r->host->requests, r, next);
libusb_free_transfer(r->xfer);
g_free(r->buffer);
g_free(r);
@@ -468,12 +466,7 @@ static void usb_host_req_abort(USBHostRequest *r)
usb_packet_complete(USB_DEVICE(s), r->p);
}
r->p = NULL;
- }
-
- QTAILQ_REMOVE(&r->host->requests, r, next);
- r->host = NULL;
- if (inflight) {
libusb_cancel_transfer(r->xfer);
}
}
@@ -962,6 +955,13 @@ static void usb_host_abort_xfers(USBHostDevice *s)
QTAILQ_FOREACH_SAFE(r, &s->requests, next, rtmp) {
usb_host_req_abort(r);
}
+
+ while (QTAILQ_FIRST(&s->requests) != NULL) {
+ struct timeval tv;
+ memset(&tv, 0, sizeof(tv));
+ tv.tv_usec = 2500;
+ libusb_handle_events_timeout(ctx, &tv);
+ }
}
static int usb_host_close(USBHostDevice *s)
@@ -1011,6 +1011,7 @@ static void usb_host_exit_notifier(struct Notifier *n, void *data)
USBHostDevice *s = container_of(n, USBHostDevice, exit);
if (s->dh) {
+ usb_host_abort_xfers(s);
usb_host_release_interfaces(s);
libusb_reset_device(s->dh);
usb_host_attach_kernel(s);