/*
 * Linux host USB redirector
 *
 * Copyright (c) 2005 Fabrice Bellard
 *
 * Copyright (c) 2008 Max Krasnyansky
 *      Support for host device auto connect & disconnect
 *      Major rewrite to support fully async operation
 *
 * Copyright 2008 TJ <linux@tjworld.net>
 *      Added flexible support for /dev/bus/usb /sys/bus/usb/devices in addition
 *      to the legacy /proc/bus/usb USB device discovery and handling
 *
 * (c) 2012 Gerd Hoffmann <kraxel@redhat.com>
 *      Completely rewritten to use libusb instead of usbfs ioctls.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#ifndef CONFIG_WIN32
#include <poll.h>
#endif
#include <libusb.h>

#include "qapi/error.h"
#include "migration/vmstate.h"
#include "monitor/monitor.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "sysemu/runstate.h"
#include "sysemu/sysemu.h"
#include "trace.h"

#include "hw/qdev-properties.h"
#include "hw/usb.h"

/* ------------------------------------------------------------------------ */

#define TYPE_USB_HOST_DEVICE "usb-host"
#define USB_HOST_DEVICE(obj) \
     OBJECT_CHECK(USBHostDevice, (obj), TYPE_USB_HOST_DEVICE)

typedef struct USBHostDevice USBHostDevice;
typedef struct USBHostRequest USBHostRequest;
typedef struct USBHostIsoXfer USBHostIsoXfer;
typedef struct USBHostIsoRing USBHostIsoRing;

struct USBAutoFilter {
    uint32_t bus_num;
    uint32_t addr;
    char     *port;
    uint32_t vendor_id;
    uint32_t product_id;
};

enum USBHostDeviceOptions {
    USB_HOST_OPT_PIPELINE,
};

struct USBHostDevice {
    USBDevice parent_obj;

    /* properties */
    struct USBAutoFilter             match;
    char                             *hostdevice;
    int32_t                          bootindex;
    uint32_t                         iso_urb_count;
    uint32_t                         iso_urb_frames;
    uint32_t                         options;
    uint32_t                         loglevel;
    bool                             needs_autoscan;
    bool                             allow_one_guest_reset;
    bool                             allow_all_guest_resets;
    bool                             suppress_remote_wake;

    /* state */
    QTAILQ_ENTRY(USBHostDevice)      next;
    int                              seen, errcount;
    int                              bus_num;
    int                              addr;
    char                             port[16];

    int                              hostfd;
    libusb_device                    *dev;
    libusb_device_handle             *dh;
    struct libusb_device_descriptor  ddesc;

    struct {
        bool                         detached;
        bool                         claimed;
    } ifs[USB_MAX_INTERFACES];

    /* callbacks & friends */
    QEMUBH                           *bh_nodev;
    QEMUBH                           *bh_postld;
    bool                             bh_postld_pending;
    Notifier                         exit;

    /* request queues */
    QTAILQ_HEAD(, USBHostRequest)    requests;
    QTAILQ_HEAD(, USBHostIsoRing)    isorings;
};

struct USBHostRequest {
    USBHostDevice                    *host;
    USBPacket                        *p;
    bool                             in;
    struct libusb_transfer           *xfer;
    unsigned char                    *buffer;
    unsigned char                    *cbuf;
    unsigned int                     clen;
    bool                             usb3ep0quirk;
    QTAILQ_ENTRY(USBHostRequest)     next;
};

struct USBHostIsoXfer {
    USBHostIsoRing                   *ring;
    struct libusb_transfer           *xfer;
    bool                             copy_complete;
    unsigned int                     packet;
    QTAILQ_ENTRY(USBHostIsoXfer)     next;
};

struct USBHostIsoRing {
    USBHostDevice                    *host;
    USBEndpoint                      *ep;
    QTAILQ_HEAD(, USBHostIsoXfer)    unused;
    QTAILQ_HEAD(, USBHostIsoXfer)    inflight;
    QTAILQ_HEAD(, USBHostIsoXfer)    copy;
    QTAILQ_ENTRY(USBHostIsoRing)     next;
};

static QTAILQ_HEAD(, USBHostDevice) hostdevs =
    QTAILQ_HEAD_INITIALIZER(hostdevs);

static void usb_host_auto_check(void *unused);
static void usb_host_release_interfaces(USBHostDevice *s);
static void usb_host_nodev(USBHostDevice *s);
static void usb_host_detach_kernel(USBHostDevice *s);
static void usb_host_attach_kernel(USBHostDevice *s);

/* ------------------------------------------------------------------------ */

#ifndef LIBUSB_LOG_LEVEL_WARNING /* older libusb didn't define these */
#define LIBUSB_LOG_LEVEL_WARNING 2
#endif

/* ------------------------------------------------------------------------ */

#define CONTROL_TIMEOUT  10000        /* 10 sec    */
#define BULK_TIMEOUT         0        /* unlimited */
#define INTR_TIMEOUT         0        /* unlimited */

#ifndef LIBUSB_API_VERSION
# define LIBUSB_API_VERSION LIBUSBX_API_VERSION
#endif
#if LIBUSB_API_VERSION >= 0x01000103
# define HAVE_STREAMS 1
#endif

static const char *speed_name[] = {
    [LIBUSB_SPEED_UNKNOWN] = "?",
    [LIBUSB_SPEED_LOW]     = "1.5",
    [LIBUSB_SPEED_FULL]    = "12",
    [LIBUSB_SPEED_HIGH]    = "480",
    [LIBUSB_SPEED_SUPER]   = "5000",
};

static const unsigned int speed_map[] = {
    [LIBUSB_SPEED_LOW]     = USB_SPEED_LOW,
    [LIBUSB_SPEED_FULL]    = USB_SPEED_FULL,
    [LIBUSB_SPEED_HIGH]    = USB_SPEED_HIGH,
    [LIBUSB_SPEED_SUPER]   = USB_SPEED_SUPER,
};

static const unsigned int status_map[] = {
    [LIBUSB_TRANSFER_COMPLETED] = USB_RET_SUCCESS,
    [LIBUSB_TRANSFER_ERROR]     = USB_RET_IOERROR,
    [LIBUSB_TRANSFER_TIMED_OUT] = USB_RET_IOERROR,
    [LIBUSB_TRANSFER_CANCELLED] = USB_RET_IOERROR,
    [LIBUSB_TRANSFER_STALL]     = USB_RET_STALL,
    [LIBUSB_TRANSFER_NO_DEVICE] = USB_RET_NODEV,
    [LIBUSB_TRANSFER_OVERFLOW]  = USB_RET_BABBLE,
};

static const char *err_names[] = {
    [-LIBUSB_ERROR_IO]               = "IO",
    [-LIBUSB_ERROR_INVALID_PARAM]    = "INVALID_PARAM",
    [-LIBUSB_ERROR_ACCESS]           = "ACCESS",
    [-LIBUSB_ERROR_NO_DEVICE]        = "NO_DEVICE",
    [-LIBUSB_ERROR_NOT_FOUND]        = "NOT_FOUND",
    [-LIBUSB_ERROR_BUSY]             = "BUSY",
    [-LIBUSB_ERROR_TIMEOUT]          = "TIMEOUT",
    [-LIBUSB_ERROR_OVERFLOW]         = "OVERFLOW",
    [-LIBUSB_ERROR_PIPE]             = "PIPE",
    [-LIBUSB_ERROR_INTERRUPTED]      = "INTERRUPTED",
    [-LIBUSB_ERROR_NO_MEM]           = "NO_MEM",
    [-LIBUSB_ERROR_NOT_SUPPORTED]    = "NOT_SUPPORTED",
    [-LIBUSB_ERROR_OTHER]            = "OTHER",
};

static libusb_context *ctx;
static uint32_t loglevel;

#ifndef CONFIG_WIN32

static void usb_host_handle_fd(void *opaque)
{
    struct timeval tv = { 0, 0 };
    libusb_handle_events_timeout(ctx, &tv);
}

static void usb_host_add_fd(int fd, short events, void *user_data)
{
    qemu_set_fd_handler(fd,
                        (events & POLLIN)  ? usb_host_handle_fd : NULL,
                        (events & POLLOUT) ? usb_host_handle_fd : NULL,
                        ctx);
}

static void usb_host_del_fd(int fd, void *user_data)
{
    qemu_set_fd_handler(fd, NULL, NULL, NULL);
}

#endif /* !CONFIG_WIN32 */

static int usb_host_init(void)
{
#ifndef CONFIG_WIN32
    const struct libusb_pollfd **poll;
#endif
    int rc;

    if (ctx) {
        return 0;
    }
    rc = libusb_init(&ctx);
    if (rc != 0) {
        return -1;
    }
#if LIBUSB_API_VERSION >= 0x01000106
    libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, loglevel);
#else
    libusb_set_debug(ctx, loglevel);
#endif
#ifdef CONFIG_WIN32
    /* FIXME: add support for Windows. */
#else
    libusb_set_pollfd_notifiers(ctx, usb_host_add_fd,
                                usb_host_del_fd,
                                ctx);
    poll = libusb_get_pollfds(ctx);
    if (poll) {
        int i;
        for (i = 0; poll[i] != NULL; i++) {
            usb_host_add_fd(poll[i]->fd, poll[i]->events, ctx);
        }
    }
    free(poll);
#endif
    return 0;
}

static int usb_host_get_port(libusb_device *dev, char *port, size_t len)
{
    uint8_t path[7];
    size_t off;
    int rc, i;

#if LIBUSB_API_VERSION >= 0x01000102
    rc = libusb_get_port_numbers(dev, path, 7);
#else
    rc = libusb_get_port_path(ctx, dev, path, 7);
#endif
    if (rc < 0) {
        return 0;
    }
    off = snprintf(port, len, "%d", path[0]);
    for (i = 1; i < rc; i++) {
        off += snprintf(port+off, len-off, ".%d", path[i]);
    }
    return off;
}

static void usb_host_libusb_error(const char *func, int rc)
{
    const char *errname;

    if (rc >= 0) {
        return;
    }

    if (-rc < ARRAY_SIZE(err_names) && err_names[-rc]) {
        errname = err_names[-rc];
    } else {
        errname = "?";
    }
    error_report("%s: %d [%s]", func, rc, errname);
}

/* ------------------------------------------------------------------------ */

static bool usb_host_use_combining(USBEndpoint *ep)
{
    int type;

    if (!ep->pipeline) {
        return false;
    }
    if (ep->pid != USB_TOKEN_IN) {
        return false;
    }
    type = usb_ep_get_type(ep->dev, ep->pid, ep->nr);
    if (type != USB_ENDPOINT_XFER_BULK) {
        return false;
    }
    return true;
}

/* ------------------------------------------------------------------------ */

static USBHostRequest *usb_host_req_alloc(USBHostDevice *s, USBPacket *p,
                                          bool in, size_t bufsize)
{
    USBHostRequest *r = g_new0(USBHostRequest, 1);

    r->host = s;
    r->p = p;
    r->in = in;
    r->xfer = libusb_alloc_transfer(0);
    if (bufsize) {
        r->buffer = g_malloc(bufsize);
    }
    QTAILQ_INSERT_TAIL(&s->requests, r, next);
    return r;
}

static void usb_host_req_free(USBHostRequest *r)
{
    QTAILQ_REMOVE(&r->host->requests, r, next);
    libusb_free_transfer(r->xfer);
    g_free(r->buffer);
    g_free(r);
}

static USBHostRequest *usb_host_req_find(USBHostDevice *s, USBPacket *p)
{
    USBHostRequest *r;

    QTAILQ_FOREACH(r, &s->requests, next) {
        if (r->p == p) {
            return r;
        }
    }
    return NULL;
}

static void LIBUSB_CALL usb_host_req_complete_ctrl(struct libusb_transfer *xfer)
{
    USBHostRequest *r = xfer->user_data;
    USBHostDevice  *s = r->host;
    bool disconnect = (xfer->status == LIBUSB_TRANSFER_NO_DEVICE);

    if (r->p == NULL) {
        goto out; /* request was canceled */
    }

    r->p->status = status_map[xfer->status];
    r->p->actual_length = xfer->actual_length;
    if (r->in && xfer->actual_length) {
        USBDevice *udev = USB_DEVICE(s);
        struct libusb_config_descriptor *conf = (void *)r->cbuf;
        memcpy(r->cbuf, r->buffer + 8, xfer->actual_length);

        /* Fix up USB-3 ep0 maxpacket size to allow superspeed connected devices
         * to work redirected to a not superspeed capable hcd */
        if (r->usb3ep0quirk && xfer->actual_length >= 18 &&
            r->cbuf[7] == 9) {
            r->cbuf[7] = 64;
        }
        /*
         *If this is GET_DESCRIPTOR request for configuration descriptor,
         * remove 'remote wakeup' flag from it to prevent idle power down
         * in Windows guest
         */
        if (s->suppress_remote_wake &&
            udev->setup_buf[0] == USB_DIR_IN &&
            udev->setup_buf[1] == USB_REQ_GET_DESCRIPTOR &&
            udev->setup_buf[3] == USB_DT_CONFIG && udev->setup_buf[2] == 0 &&
            xfer->actual_length >
                offsetof(struct libusb_config_descriptor, bmAttributes) &&
            (conf->bmAttributes & USB_CFG_ATT_WAKEUP)) {
                trace_usb_host_remote_wakeup_removed(s->bus_num, s->addr);
                conf->bmAttributes &= ~USB_CFG_ATT_WAKEUP;
        }
    }
    trace_usb_host_req_complete(s->bus_num, s->addr, r->p,
                                r->p->status, r->p->actual_length);
    usb_generic_async_ctrl_complete(USB_DEVICE(s), r->p);

out:
    usb_host_req_free(r);
    if (disconnect) {
        usb_host_nodev(s);
    }
}

static void LIBUSB_CALL usb_host_req_complete_data(struct libusb_transfer *xfer)
{
    USBHostRequest *r = xfer->user_data;
    USBHostDevice  *s = r->host;
    bool disconnect = (xfer->status == LIBUSB_TRANSFER_NO_DEVICE);

    if (r->p == NULL) {
        goto out; /* request was canceled */
    }

    r->p->status = status_map[xfer->status];
    if (r->in && xfer->actual_length) {
        usb_packet_copy(r->p, r->buffer, xfer->actual_length);
    }
    trace_usb_host_req_complete(s->bus_num, s->addr, r->p,
                                r->p->status, r->p->actual_length);
    if (usb_host_use_combining(r->p->ep)) {
        usb_combined_input_packet_complete(USB_DEVICE(s), r->p);
    } else {
        usb_packet_complete(USB_DEVICE(s), r->p);
    }

out:
    usb_host_req_free(r);
    if (disconnect) {
        usb_host_nodev(s);
    }
}

static void usb_host_req_abort(USBHostRequest *r)
{
    USBHostDevice  *s = r->host;
    bool inflight = (r->p && r->p->state == USB_PACKET_ASYNC);

    if (inflight) {
        r->p->status = USB_RET_NODEV;
        trace_usb_host_req_complete(s->bus_num, s->addr, r->p,
                                    r->p->status, r->p->actual_length);
        if (r->p->ep->nr == 0) {
            usb_generic_async_ctrl_complete(USB_DEVICE(s), r->p);
        } else {
            usb_packet_complete(USB_DEVICE(s), r->p);
        }
        r->p = NULL;

        libusb_cancel_transfer(r->xfer);
    }
}

/* ------------------------------------------------------------------------ */

static void LIBUSB_CALL
usb_host_req_complete_iso(struct libusb_transfer *transfer)
{
    USBHostIsoXfer *xfer = transfer->user_data;

    if (!xfer) {
        /* USBHostIsoXfer released while inflight */
        g_free(transfer->buffer);
        libusb_free_transfer(transfer);
        return;
    }

    QTAILQ_REMOVE(&xfer->ring->inflight, xfer, next);
    if (QTAILQ_EMPTY(&xfer->ring->inflight)) {
        USBHostDevice *s = xfer->ring->host;
        trace_usb_host_iso_stop(s->bus_num, s->addr, xfer->ring->ep->nr);
    }
    if (xfer->ring->ep->pid == USB_TOKEN_IN) {
        QTAILQ_INSERT_TAIL(&xfer->ring->copy, xfer, next);
        usb_wakeup(xfer->ring->ep, 0);
    } else {
        QTAILQ_INSERT_TAIL(&xfer->ring->unused, xfer, next);
    }
}

static USBHostIsoRing *usb_host_iso_alloc(USBHostDevice *s, USBEndpoint *ep)
{
    USBHostIsoRing *ring = g_new0(USBHostIsoRing, 1);
    USBHostIsoXfer *xfer;
    /* FIXME: check interval (for now assume one xfer per frame) */
    int packets = s->iso_urb_frames;
    int i;

    ring->host = s;
    ring->ep = ep;
    QTAILQ_INIT(&ring->unused);
    QTAILQ_INIT(&ring->inflight);
    QTAILQ_INIT(&ring->copy);
    QTAILQ_INSERT_TAIL(&s->isorings, ring, next);

    for (i = 0; i < s->iso_urb_count; i++) {
        xfer = g_new0(USBHostIsoXfer, 1);
        xfer->ring = ring;
        xfer->xfer = libusb_alloc_transfer(packets);
        xfer->xfer->dev_handle = s->dh;
        xfer->xfer->type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS;

        xfer->xfer->endpoint = ring->ep->nr;
        if (ring->ep->pid == USB_TOKEN_IN) {
            xfer->xfer->endpoint |= USB_DIR_IN;
        }
        xfer->xfer->callback = usb_host_req_complete_iso;
        xfer->xfer->user_data = xfer;

        xfer->xfer->num_iso_packets = packets;
        xfer->xfer->length = ring->ep->max_packet_size * packets;
        xfer->xfer->buffer = g_malloc0(xfer->xfer->length);

        QTAILQ_INSERT_TAIL(&ring->unused, xfer, next);
    }

    return ring;
}

static USBHostIsoRing *usb_host_iso_find(USBHostDevice *s, USBEndpoint *ep)
{
    USBHostIsoRing *ring;

    QTAILQ_FOREACH(ring, &s->isorings, next) {
        if (ring->ep == ep) {
            return ring;
        }
    }
    return NULL;
}

static void usb_host_iso_reset_xfer(USBHostIsoXfer *xfer)
{
    libusb_set_iso_packet_lengths(xfer->xfer,
                                  xfer->ring->ep->max_packet_size);
    xfer->packet = 0;
    xfer->copy_complete = false;
}

static void usb_host_iso_free_xfer(USBHostIsoXfer *xfer, bool inflight)
{
    if (inflight) {
        xfer->xfer->user_data = NULL;
    } else {
        g_free(xfer->xfer->buffer);
        libusb_free_transfer(xfer->xfer);
    }
    g_free(xfer);
}

static void usb_host_iso_free(USBHostIsoRing *ring)
{
    USBHostIsoXfer *xfer;

    while ((xfer = QTAILQ_FIRST(&ring->inflight)) != NULL) {
        QTAILQ_REMOVE(&ring->inflight, xfer, next);
        usb_host_iso_free_xfer(xfer, true);
    }
    while ((xfer = QTAILQ_FIRST(&ring->unused)) != NULL) {
        QTAILQ_REMOVE(&ring->unused, xfer, next);
        usb_host_iso_free_xfer(xfer, false);
    }
    while ((xfer = QTAILQ_FIRST(&ring->copy)) != NULL) {
        QTAILQ_REMOVE(&ring->copy, xfer, next);
        usb_host_iso_free_xfer(xfer, false);
    }

    QTAILQ_REMOVE(&ring->host->isorings, ring, next);
    g_free(ring);
}

static void usb_host_iso_free_all(USBHostDevice *s)
{
    USBHostIsoRing *ring;

    while ((ring = QTAILQ_FIRST(&s->isorings)) != NULL) {
        usb_host_iso_free(ring);
    }
}

static bool usb_host_iso_data_copy(USBHostIsoXfer *xfer, USBPacket *p)
{
    unsigned int psize;
    unsigned char *buf;

    buf = libusb_get_iso_packet_buffer_simple(xfer->xfer, xfer->packet);
    if (p->pid == USB_TOKEN_OUT) {
        psize = p->iov.size;
        if (psize > xfer->ring->ep->max_packet_size) {
            /* should not happen (guest bug) */
            psize = xfer->ring->ep->max_packet_size;
        }
        xfer->xfer->iso_packet_desc[xfer->packet].length = psize;
    } else {
        psize = xfer->xfer->iso_packet_desc[xfer->packet].actual_length;
        if (psize > p->iov.size) {
            /* should not happen (guest bug) */
            psize = p->iov.size;
        }
    }
    usb_packet_copy(p, buf, psize);
    xfer->packet++;
    xfer->copy_complete = (xfer->packet == xfer->xfer->num_iso_packets);
    return xfer->copy_complete;
}

static void usb_host_iso_data_in(USBHostDevice *s, USBPacket *p)
{
    USBHostIsoRing *ring;
    USBHostIsoXfer *xfer;
    bool disconnect = false;
    int rc;

    ring = usb_host_iso_find(s, p->ep);
    if (ring == NULL) {
        ring = usb_host_iso_alloc(s, p->ep);
    }

    /* copy data to guest */
    xfer = QTAILQ_FIRST(&ring->copy);
    if (xfer != NULL) {
        if (usb_host_iso_data_copy(xfer, p)) {
            QTAILQ_REMOVE(&ring->copy, xfer, next);
            QTAILQ_INSERT_TAIL(&ring->unused, xfer, next);
        }
    }

    /* submit empty bufs to host */
    while ((xfer = QTAILQ_FIRST(&ring->unused)) != NULL) {
        QTAILQ_REMOVE(&ring->unused, xfer, next);
        usb_host_iso_reset_xfer(xfer);
        rc = libusb_submit_transfer(xfer->xfer);
        if (rc != 0) {
            usb_host_libusb_error("libusb_submit_transfer [iso]", rc);
            QTAILQ_INSERT_TAIL(&ring->unused, xfer, next);
            if (rc == LIBUSB_ERROR_NO_DEVICE) {
                disconnect = true;
            }
            break;
        }
        if (QTAILQ_EMPTY(&ring->inflight)) {
            trace_usb_host_iso_start(s->bus_num, s->addr, p->ep->nr);
        }
        QTAILQ_INSERT_TAIL(&ring->inflight, xfer, next);
    }

    if (disconnect) {
        usb_host_nodev(s);
    }
}

static void usb_host_iso_data_out(USBHostDevice *s, USBPacket *p)
{
    USBHostIsoRing *ring;
    USBHostIsoXfer *xfer;
    bool disconnect = false;
    int rc, filled = 0;

    ring = usb_host_iso_find(s, p->ep);
    if (ring == NULL) {
        ring = usb_host_iso_alloc(s, p->ep);
    }

    /* copy data from guest */
    xfer = QTAILQ_FIRST(&ring->copy);
    while (xfer != NULL && xfer->copy_complete) {
        filled++;
        xfer = QTAILQ_NEXT(xfer, next);
    }
    if (xfer == NULL) {
        xfer = QTAILQ_FIRST(&ring->unused);
        if (xfer == NULL) {
            trace_usb_host_iso_out_of_bufs(s->bus_num, s->addr, p->ep->nr);
            return;
        }
        QTAILQ_REMOVE(&ring->unused, xfer, next);
        usb_host_iso_reset_xfer(xfer);
        QTAILQ_INSERT_TAIL(&ring->copy, xfer, next);
    }
    usb_host_iso_data_copy(xfer, p);

    if (QTAILQ_EMPTY(&ring->inflight)) {
        /* wait until half of our buffers are filled
           before kicking the iso out stream */
        if (filled*2 < s->iso_urb_count) {
            return;
        }
    }

    /* submit filled bufs to host */
    while ((xfer = QTAILQ_FIRST(&ring->copy)) != NULL &&
           xfer->copy_complete) {
        QTAILQ_REMOVE(&ring->copy, xfer, next);
        rc = libusb_submit_transfer(xfer->xfer);
        if (rc != 0) {
            usb_host_libusb_error("libusb_submit_transfer [iso]", rc);
            QTAILQ_INSERT_TAIL(&ring->unused, xfer, next);
            if (rc == LIBUSB_ERROR_NO_DEVICE) {
                disconnect = true;
            }
            break;
        }
        if (QTAILQ_EMPTY(&ring->inflight)) {
            trace_usb_host_iso_start(s->bus_num, s->addr, p->ep->nr);
        }
        QTAILQ_INSERT_TAIL(&ring->inflight, xfer, next);
    }

    if (disconnect) {
        usb_host_nodev(s);
    }
}

/* ------------------------------------------------------------------------ */

static void usb_host_speed_compat(USBHostDevice *s)
{
    USBDevice *udev = USB_DEVICE(s);
    struct libusb_config_descriptor *conf;
    const struct libusb_interface_descriptor *intf;
    const struct libusb_endpoint_descriptor *endp;
#ifdef HAVE_STREAMS
    struct libusb_ss_endpoint_companion_descriptor *endp_ss_comp;
#endif
    bool compat_high = true;
    bool compat_full = true;
    uint8_t type;
    int rc, c, i, a, e;

    for (c = 0;; c++) {
        rc = libusb_get_config_descriptor(s->dev, c, &conf);
        if (rc != 0) {
            break;
        }
        for (i = 0; i < conf->bNumInterfaces; i++) {
            for (a = 0; a < conf->interface[i].num_altsetting; a++) {
                intf = &conf->interface[i].altsetting[a];
                for (e = 0; e < intf->bNumEndpoints; e++) {
                    endp = &intf->endpoint[e];
                    type = endp->bmAttributes & 0x3;
                    switch (type) {
                    case 0x01: /* ISO */
                        compat_full = false;
                        compat_high = false;
                        break;
                    case 0x02: /* BULK */
#ifdef HAVE_STREAMS
                        rc = libusb_get_ss_endpoint_companion_descriptor
                            (ctx, endp, &endp_ss_comp);
                        if (rc == LIBUSB_SUCCESS) {
                            int streams = endp_ss_comp->bmAttributes & 0x1f;
                            if (streams) {
                                compat_full = false;
                                compat_high = false;
                            }
                            libusb_free_ss_endpoint_companion_descriptor
                                (endp_ss_comp);
                        }
#endif
                        break;
                    case 0x03: /* INTERRUPT */
                        if (endp->wMaxPacketSize > 64) {
                            compat_full = false;
                        }
                        if (endp->wMaxPacketSize > 1024) {
                            compat_high = false;
                        }
                        break;
                    }
                }
            }
        }
        libusb_free_config_descriptor(conf);
    }

    udev->speedmask = (1 << udev->speed);
    if (udev->speed == USB_SPEED_SUPER && compat_high) {
        udev->speedmask |= USB_SPEED_MASK_HIGH;
    }
    if (udev->speed == USB_SPEED_SUPER && compat_full) {
        udev->speedmask |= USB_SPEED_MASK_FULL;
    }
    if (udev->speed == USB_SPEED_HIGH && compat_full) {
        udev->speedmask |= USB_SPEED_MASK_FULL;
    }
}

static void usb_host_ep_update(USBHostDevice *s)
{
    static const char *tname[] = {
        [USB_ENDPOINT_XFER_CONTROL] = "control",
        [USB_ENDPOINT_XFER_ISOC]    = "isoc",
        [USB_ENDPOINT_XFER_BULK]    = "bulk",
        [USB_ENDPOINT_XFER_INT]     = "int",
    };
    USBDevice *udev = USB_DEVICE(s);
    struct libusb_config_descriptor *conf;
    const struct libusb_interface_descriptor *intf;
    const struct libusb_endpoint_descriptor *endp;
#ifdef HAVE_STREAMS
    struct libusb_ss_endpoint_companion_descriptor *endp_ss_comp;
#endif
    uint8_t devep, type;
    int pid, ep;
    int rc, i, e;

    usb_ep_reset(udev);
    rc = libusb_get_active_config_descriptor(s->dev, &conf);
    if (rc != 0) {
        return;
    }
    trace_usb_host_parse_config(s->bus_num, s->addr,
                                conf->bConfigurationValue, true);

    for (i = 0; i < conf->bNumInterfaces; i++) {
        assert(udev->altsetting[i] < conf->interface[i].num_altsetting);
        intf = &conf->interface[i].altsetting[udev->altsetting[i]];
        trace_usb_host_parse_interface(s->bus_num, s->addr,
                                       intf->bInterfaceNumber,
                                       intf->bAlternateSetting, true);
        for (e = 0; e < intf->bNumEndpoints; e++) {
            endp = &intf->endpoint[e];

            devep = endp->bEndpointAddress;
            pid = (devep & USB_DIR_IN) ? USB_TOKEN_IN : USB_TOKEN_OUT;
            ep = devep & 0xf;
            type = endp->bmAttributes & 0x3;

            if (ep == 0) {
                trace_usb_host_parse_error(s->bus_num, s->addr,
                                           "invalid endpoint address");
                return;
            }
            if (usb_ep_get_type(udev, pid, ep) != USB_ENDPOINT_XFER_INVALID) {
                trace_usb_host_parse_error(s->bus_num, s->addr,
                                           "duplicate endpoint address");
                return;
            }

            trace_usb_host_parse_endpoint(s->bus_num, s->addr, ep,
                                          (devep & USB_DIR_IN) ? "in" : "out",
                                          tname[type], true);
            usb_ep_set_max_packet_size(udev, pid, ep,
                                       endp->wMaxPacketSize);
            usb_ep_set_type(udev, pid, ep, type);
            usb_ep_set_ifnum(udev, pid, ep, i);
            usb_ep_set_halted(udev, pid, ep, 0);
#ifdef HAVE_STREAMS
            if (type == LIBUSB_TRANSFER_TYPE_BULK &&
                    libusb_get_ss_endpoint_companion_descriptor(ctx, endp,
                        &endp_ss_comp) == LIBUSB_SUCCESS) {
                usb_ep_set_max_streams(udev, pid, ep,
                                       endp_ss_comp->bmAttributes);
                libusb_free_ss_endpoint_companion_descriptor(endp_ss_comp);
            }
#endif
        }
    }

    libusb_free_config_descriptor(conf);
}

static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd)
{
    USBDevice *udev = USB_DEVICE(s);
    int bus_num = 0;
    int addr = 0;
    int rc;
    Error *local_err = NULL;

    if (s->bh_postld_pending) {
        return -1;
    }
    if (s->dh != NULL) {
        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);
        if (rc != 0) {
            goto fail;
        }
    } else {
#if LIBUSB_API_VERSION >= 0x01000107 && !defined(CONFIG_WIN32)
        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->bus_num = bus_num;
    s->addr    = addr;

    usb_host_detach_kernel(s);

    libusb_get_device_descriptor(dev, &s->ddesc);
    usb_host_get_port(s->dev, s->port, sizeof(s->port));

    usb_ep_init(udev);
    usb_host_ep_update(s);

    udev->speed     = speed_map[libusb_get_device_speed(dev)];
    usb_host_speed_compat(s);

    if (s->ddesc.iProduct) {
        libusb_get_string_descriptor_ascii(s->dh, s->ddesc.iProduct,
                                           (unsigned char *)udev->product_desc,
                                           sizeof(udev->product_desc));
    } else {
        snprintf(udev->product_desc, sizeof(udev->product_desc),
                 "host:%d.%d", bus_num, addr);
    }

    usb_device_attach(udev, &local_err);
    if (local_err) {
        error_report_err(local_err);
        goto fail;
    }

    trace_usb_host_open_success(bus_num, addr);
    return 0;

fail:
    trace_usb_host_open_failure(bus_num, addr);
    if (s->dh != NULL) {
        usb_host_release_interfaces(s);
        libusb_reset_device(s->dh);
        usb_host_attach_kernel(s);
        libusb_close(s->dh);
        s->dh = NULL;
        s->dev = NULL;
    }
    return -1;
}

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);
    }

    while (QTAILQ_FIRST(&s->requests) != NULL) {
        struct timeval tv;
        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;
        }
    }
}

static int usb_host_close(USBHostDevice *s)
{
    USBDevice *udev = USB_DEVICE(s);

    if (s->dh == NULL) {
        return -1;
    }

    trace_usb_host_close(s->bus_num, s->addr);

    usb_host_abort_xfers(s);
    usb_host_iso_free_all(s);

    if (udev->attached) {
        usb_device_detach(udev);
    }

    usb_host_release_interfaces(s);
    libusb_reset_device(s->dh);
    usb_host_attach_kernel(s);
    libusb_close(s->dh);
    s->dh = NULL;
    s->dev = NULL;

    if (s->hostfd != -1) {
        close(s->hostfd);
        s->hostfd = -1;
    }

    usb_host_auto_check(NULL);
    return 0;
}

static void usb_host_nodev_bh(void *opaque)
{
    USBHostDevice *s = opaque;
    usb_host_close(s);
}

static void usb_host_nodev(USBHostDevice *s)
{
    if (!s->bh_nodev) {
        s->bh_nodev = qemu_bh_new(usb_host_nodev_bh, s);
    }
    qemu_bh_schedule(s->bh_nodev);
}

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);
        libusb_close(s->dh);
    }
}

static libusb_device *usb_host_find_ref(int bus, int addr)
{
    libusb_device **devs = NULL;
    libusb_device *ret = NULL;
    int i, n;

    n = libusb_get_device_list(ctx, &devs);
    for (i = 0; i < n; i++) {
        if (libusb_get_bus_number(devs[i]) == bus &&
            libusb_get_device_address(devs[i]) == addr) {
            ret = libusb_ref_device(devs[i]);
            break;
        }
    }
    libusb_free_device_list(devs, 1);
    return ret;
}

static void usb_host_realize(USBDevice *udev, Error **errp)
{
    USBHostDevice *s = USB_HOST_DEVICE(udev);
    libusb_device *ldev;
    int rc;

    if (usb_host_init() != 0) {
        error_setg(errp, "failed to init libusb");
        return;
    }
    if (s->match.vendor_id > 0xffff) {
        error_setg(errp, "vendorid out of range");
        return;
    }
    if (s->match.product_id > 0xffff) {
        error_setg(errp, "productid out of range");
        return;
    }
    if (s->match.addr > 127) {
        error_setg(errp, "hostaddr out of range");
        return;
    }

    loglevel = s->loglevel;
    udev->flags |= (1 << USB_DEV_FLAG_IS_HOST);
    udev->auto_attach = 0;
    QTAILQ_INIT(&s->requests);
    QTAILQ_INIT(&s->isorings);
    s->hostfd = -1;

#if LIBUSB_API_VERSION >= 0x01000107 && !defined(CONFIG_WIN32)
    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 &&
        !s->match.vendor_id &&
        !s->match.product_id &&
        !s->match.port) {
        s->needs_autoscan = false;
        ldev = usb_host_find_ref(s->match.bus_num,
                                 s->match.addr);
        if (!ldev) {
            error_setg(errp, "failed to find host usb device %d:%d",
                       s->match.bus_num, s->match.addr);
            return;
        }
        rc = usb_host_open(s, ldev, 0);
        libusb_unref_device(ldev);
        if (rc < 0) {
            error_setg(errp, "failed to open host usb device %d:%d",
                       s->match.bus_num, s->match.addr);
            return;
        }
    } else {
        s->needs_autoscan = true;
        QTAILQ_INSERT_TAIL(&hostdevs, s, next);
        usb_host_auto_check(NULL);
    }

    s->exit.notify = usb_host_exit_notifier;
    qemu_add_exit_notifier(&s->exit);
}

static void usb_host_instance_init(Object *obj)
{
    USBDevice *udev = USB_DEVICE(obj);
    USBHostDevice *s = USB_HOST_DEVICE(udev);

    device_add_bootindex_property(obj, &s->bootindex,
                                  "bootindex", NULL,
                                  &udev->qdev);
}

static void usb_host_unrealize(USBDevice *udev)
{
    USBHostDevice *s = USB_HOST_DEVICE(udev);

    qemu_remove_exit_notifier(&s->exit);
    if (s->needs_autoscan) {
        QTAILQ_REMOVE(&hostdevs, s, next);
    }
    usb_host_close(s);
}

static void usb_host_cancel_packet(USBDevice *udev, USBPacket *p)
{
    USBHostDevice *s = USB_HOST_DEVICE(udev);
    USBHostRequest *r;

    if (p->combined) {
        usb_combined_packet_cancel(udev, p);
        return;
    }

    trace_usb_host_req_canceled(s->bus_num, s->addr, p);

    r = usb_host_req_find(s, p);
    if (r && r->p) {
        r->p = NULL; /* mark as dead */
        libusb_cancel_transfer(r->xfer);
    }
}

static void usb_host_detach_kernel(USBHostDevice *s)
{
    struct libusb_config_descriptor *conf;
    int rc, i;

    rc = libusb_get_active_config_descriptor(s->dev, &conf);
    if (rc != 0) {
        return;
    }
    for (i = 0; i < USB_MAX_INTERFACES; i++) {
        rc = libusb_kernel_driver_active(s->dh, i);
        usb_host_libusb_error("libusb_kernel_driver_active", rc);
        if (rc != 1) {
            if (rc == 0) {
                s->ifs[i].detached = true;
            }
            continue;
        }
        trace_usb_host_detach_kernel(s->bus_num, s->addr, i);
        rc = libusb_detach_kernel_driver(s->dh, i);
        usb_host_libusb_error("libusb_detach_kernel_driver", rc);
        s->ifs[i].detached = true;
    }
    libusb_free_config_descriptor(conf);
}

static void usb_host_attach_kernel(USBHostDevice *s)
{
    struct libusb_config_descriptor *conf;
    int rc, i;

    rc = libusb_get_active_config_descriptor(s->dev, &conf);
    if (rc != 0) {
        return;
    }
    for (i = 0; i < USB_MAX_INTERFACES; i++) {
        if (!s->ifs[i].detached) {
            continue;
        }
        trace_usb_host_attach_kernel(s->bus_num, s->addr, i);
        libusb_attach_kernel_driver(s->dh, i);
        s->ifs[i].detached = false;
    }
    libusb_free_config_descriptor(conf);
}

static int usb_host_claim_interfaces(USBHostDevice *s, int configuration)
{
    USBDevice *udev = USB_DEVICE(s);
    struct libusb_config_descriptor *conf;
    int rc, i, claimed;

    for (i = 0; i < USB_MAX_INTERFACES; i++) {
        udev->altsetting[i] = 0;
    }
    udev->ninterfaces   = 0;
    udev->configuration = 0;

    usb_host_detach_kernel(s);

    rc = libusb_get_active_config_descriptor(s->dev, &conf);
    if (rc != 0) {
        if (rc == LIBUSB_ERROR_NOT_FOUND) {
            /* address state - ignore */
            return USB_RET_SUCCESS;
        }
        return USB_RET_STALL;
    }

    claimed = 0;
    for (i = 0; i < USB_MAX_INTERFACES; i++) {
        trace_usb_host_claim_interface(s->bus_num, s->addr, configuration, i);
        rc = libusb_claim_interface(s->dh, i);
        if (rc == 0) {
            s->ifs[i].claimed = true;
            if (++claimed == conf->bNumInterfaces) {
                break;
            }
        }
    }
    if (claimed != conf->bNumInterfaces) {
        return USB_RET_STALL;
    }

    udev->ninterfaces   = conf->bNumInterfaces;
    udev->configuration = configuration;

    libusb_free_config_descriptor(conf);
    return USB_RET_SUCCESS;
}

static void usb_host_release_interfaces(USBHostDevice *s)
{
    int i, rc;

    for (i = 0; i < USB_MAX_INTERFACES; i++) {
        if (!s->ifs[i].claimed) {
            continue;
        }
        trace_usb_host_release_interface(s->bus_num, s->addr, i);
        rc = libusb_release_interface(s->dh, i);
        usb_host_libusb_error("libusb_release_interface", rc);
        s->ifs[i].claimed = false;
    }
}

static void usb_host_set_address(USBHostDevice *s, int addr)
{
    USBDevice *udev = USB_DEVICE(s);

    trace_usb_host_set_address(s->bus_num, s->addr, addr);
    udev->addr = addr;
}

static void usb_host_set_config(USBHostDevice *s, int config, USBPacket *p)
{
    int rc = 0;

    trace_usb_host_set_config(s->bus_num, s->addr, config);

    usb_host_release_interfaces(s);
    if (s->ddesc.bNumConfigurations != 1) {
        rc = libusb_set_configuration(s->dh, config);
        if (rc != 0) {
            usb_host_libusb_error("libusb_set_configuration", rc);
            p->status = USB_RET_STALL;
            if (rc == LIBUSB_ERROR_NO_DEVICE) {
                usb_host_nodev(s);
            }
            return;
        }
    }
    p->status = usb_host_claim_interfaces(s, config);
    if (p->status != USB_RET_SUCCESS) {
        return;
    }
    usb_host_ep_update(s);
}

static void usb_host_set_interface(USBHostDevice *s, int iface, int alt,
                                   USBPacket *p)
{
    USBDevice *udev = USB_DEVICE(s);
    int rc;

    trace_usb_host_set_interface(s->bus_num, s->addr, iface, alt);

    usb_host_iso_free_all(s);

    if (iface >= USB_MAX_INTERFACES) {
        p->status = USB_RET_STALL;
        return;
    }

    rc = libusb_set_interface_alt_setting(s->dh, iface, alt);
    if (rc != 0) {
        usb_host_libusb_error("libusb_set_interface_alt_setting", rc);
        p->status = USB_RET_STALL;
        if (rc == LIBUSB_ERROR_NO_DEVICE) {
            usb_host_nodev(s);
        }
        return;
    }

    udev->altsetting[iface] = alt;
    usb_host_ep_update(s);
}

static void usb_host_handle_control(USBDevice *udev, USBPacket *p,
                                    int request, int value, int index,
                                    int length, uint8_t *data)
{
    USBHostDevice *s = USB_HOST_DEVICE(udev);
    USBHostRequest *r;
    int rc;

    trace_usb_host_req_control(s->bus_num, s->addr, p, request, value, index);

    if (s->dh == NULL) {
        p->status = USB_RET_NODEV;
        trace_usb_host_req_emulated(s->bus_num, s->addr, p, p->status);
        return;
    }

    switch (request) {
    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
        usb_host_set_address(s, value);
        trace_usb_host_req_emulated(s->bus_num, s->addr, p, p->status);
        return;

    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
        usb_host_set_config(s, value & 0xff, p);
        trace_usb_host_req_emulated(s->bus_num, s->addr, p, p->status);
        return;

    case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
        usb_host_set_interface(s, index, value, p);
        trace_usb_host_req_emulated(s->bus_num, s->addr, p, p->status);
        return;

    case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
        if (value == 0) { /* clear halt */
            int pid = (index & USB_DIR_IN) ? USB_TOKEN_IN : USB_TOKEN_OUT;
            libusb_clear_halt(s->dh, index);
            usb_ep_set_halted(udev, pid, index & 0x0f, 0);
            trace_usb_host_req_emulated(s->bus_num, s->addr, p, p->status);
            return;
        }
    }

    r = usb_host_req_alloc(s, p, (request >> 8) & USB_DIR_IN, length + 8);
    r->cbuf = data;
    r->clen = length;
    memcpy(r->buffer, udev->setup_buf, 8);
    if (!r->in) {
        memcpy(r->buffer + 8, r->cbuf, r->clen);
    }

    /* Fix up USB-3 ep0 maxpacket size to allow superspeed connected devices
     * to work redirected to a not superspeed capable hcd */
    if ((udev->speedmask & USB_SPEED_MASK_SUPER) &&
        !(udev->port->speedmask & USB_SPEED_MASK_SUPER) &&
        request == 0x8006 && value == 0x100 && index == 0) {
        r->usb3ep0quirk = true;
    }

    libusb_fill_control_transfer(r->xfer, s->dh, r->buffer,
                                 usb_host_req_complete_ctrl, r,
                                 CONTROL_TIMEOUT);
    rc = libusb_submit_transfer(r->xfer);
    if (rc != 0) {
        p->status = USB_RET_NODEV;
        trace_usb_host_req_complete(s->bus_num, s->addr, p,
                                    p->status, p->actual_length);
        if (rc == LIBUSB_ERROR_NO_DEVICE) {
            usb_host_nodev(s);
        }
        return;
    }

    p->status = USB_RET_ASYNC;
}

static void usb_host_handle_data(USBDevice *udev, USBPacket *p)
{
    USBHostDevice *s = USB_HOST_DEVICE(udev);
    USBHostRequest *r;
    size_t size;
    int ep, rc;

    if (usb_host_use_combining(p->ep) && p->state == USB_PACKET_SETUP) {
        p->status = USB_RET_ADD_TO_QUEUE;
        return;
    }

    trace_usb_host_req_data(s->bus_num, s->addr, p,
                            p->pid == USB_TOKEN_IN,
                            p->ep->nr, p->iov.size);

    if (s->dh == NULL) {
        p->status = USB_RET_NODEV;
        trace_usb_host_req_emulated(s->bus_num, s->addr, p, p->status);
        return;
    }
    if (p->ep->halted) {
        p->status = USB_RET_STALL;
        trace_usb_host_req_emulated(s->bus_num, s->addr, p, p->status);
        return;
    }

    switch (usb_ep_get_type(udev, p->pid, p->ep->nr)) {
    case USB_ENDPOINT_XFER_BULK:
        size = usb_packet_size(p);
        r = usb_host_req_alloc(s, p, p->pid == USB_TOKEN_IN, size);
        if (!r->in) {
            usb_packet_copy(p, r->buffer, size);
        }
        ep = p->ep->nr | (r->in ? USB_DIR_IN : 0);
        if (p->stream) {
#ifdef HAVE_STREAMS
            libusb_fill_bulk_stream_transfer(r->xfer, s->dh, ep, p->stream,
                                             r->buffer, size,
                                             usb_host_req_complete_data, r,
                                             BULK_TIMEOUT);
#else
            usb_host_req_free(r);
            p->status = USB_RET_STALL;
            return;
#endif
        } else {
            libusb_fill_bulk_transfer(r->xfer, s->dh, ep,
                                      r->buffer, size,
                                      usb_host_req_complete_data, r,
                                      BULK_TIMEOUT);
        }
        break;
    case USB_ENDPOINT_XFER_INT:
        r = usb_host_req_alloc(s, p, p->pid == USB_TOKEN_IN, p->iov.size);
        if (!r->in) {
            usb_packet_copy(p, r->buffer, p->iov.size);
        }
        ep = p->ep->nr | (r->in ? USB_DIR_IN : 0);
        libusb_fill_interrupt_transfer(r->xfer, s->dh, ep,
                                       r->buffer, p->iov.size,
                                       usb_host_req_complete_data, r,
                                       INTR_TIMEOUT);
        break;
    case USB_ENDPOINT_XFER_ISOC:
        if (p->pid == USB_TOKEN_IN) {
            usb_host_iso_data_in(s, p);
        } else {
            usb_host_iso_data_out(s, p);
        }
        trace_usb_host_req_complete(s->bus_num, s->addr, p,
                                    p->status, p->actual_length);
        return;
    default:
        p->status = USB_RET_STALL;
        trace_usb_host_req_complete(s->bus_num, s->addr, p,
                                    p->status, p->actual_length);
        return;
    }

    rc = libusb_submit_transfer(r->xfer);
    if (rc != 0) {
        p->status = USB_RET_NODEV;
        trace_usb_host_req_complete(s->bus_num, s->addr, p,
                                    p->status, p->actual_length);
        if (rc == LIBUSB_ERROR_NO_DEVICE) {
            usb_host_nodev(s);
        }
        return;
    }

    p->status = USB_RET_ASYNC;
}

static void usb_host_flush_ep_queue(USBDevice *dev, USBEndpoint *ep)
{
    if (usb_host_use_combining(ep)) {
        usb_ep_combine_input_packets(ep);
    }
}

static void usb_host_handle_reset(USBDevice *udev)
{
    USBHostDevice *s = USB_HOST_DEVICE(udev);
    int rc;

    if (!s->allow_one_guest_reset && !s->allow_all_guest_resets) {
        return;
    }
    if (!s->allow_all_guest_resets && udev->addr == 0) {
        return;
    }

    trace_usb_host_reset(s->bus_num, s->addr);

    rc = libusb_reset_device(s->dh);
    if (rc != 0) {
        usb_host_nodev(s);
    }
}

static int usb_host_alloc_streams(USBDevice *udev, USBEndpoint **eps,
                                  int nr_eps, int streams)
{
#ifdef HAVE_STREAMS
    USBHostDevice *s = USB_HOST_DEVICE(udev);
    unsigned char endpoints[30];
    int i, rc;

    for (i = 0; i < nr_eps; i++) {
        endpoints[i] = eps[i]->nr;
        if (eps[i]->pid == USB_TOKEN_IN) {
            endpoints[i] |= 0x80;
        }
    }
    rc = libusb_alloc_streams(s->dh, streams, endpoints, nr_eps);
    if (rc < 0) {
        usb_host_libusb_error("libusb_alloc_streams", rc);
    } else if (rc != streams) {
        error_report("libusb_alloc_streams: got less streams "
                     "then requested %d < %d", rc, streams);
    }

    return (rc == streams) ? 0 : -1;
#else
    error_report("libusb_alloc_streams: error not implemented");
    return -1;
#endif
}

static void usb_host_free_streams(USBDevice *udev, USBEndpoint **eps,
                                  int nr_eps)
{
#ifdef HAVE_STREAMS
    USBHostDevice *s = USB_HOST_DEVICE(udev);
    unsigned char endpoints[30];
    int i;

    for (i = 0; i < nr_eps; i++) {
        endpoints[i] = eps[i]->nr;
        if (eps[i]->pid == USB_TOKEN_IN) {
            endpoints[i] |= 0x80;
        }
    }
    libusb_free_streams(s->dh, endpoints, nr_eps);
#endif
}

/*
 * This is *NOT* about restoring state.  We have absolutely no idea
 * what state the host device is in at the moment and whenever it is
 * still present in the first place.  Attemping to contine where we
 * left off is impossible.
 *
 * What we are going to do here is emulate a surprise removal of
 * the usb device passed through, then kick host scan so the device
 * will get re-attached (and re-initialized by the guest) in case it
 * is still present.
 *
 * As the device removal will change the state of other devices (usb
 * host controller, most likely interrupt controller too) we have to
 * wait with it until *all* vmstate is loaded.  Thus post_load just
 * kicks a bottom half which then does the actual work.
 */
static void usb_host_post_load_bh(void *opaque)
{
    USBHostDevice *dev = opaque;
    USBDevice *udev = USB_DEVICE(dev);

    if (dev->dh != NULL) {
        usb_host_close(dev);
    }
    if (udev->attached) {
        usb_device_detach(udev);
    }
    dev->bh_postld_pending = false;
    usb_host_auto_check(NULL);
}

static int usb_host_post_load(void *opaque, int version_id)
{
    USBHostDevice *dev = opaque;

    if (!dev->bh_postld) {
        dev->bh_postld = qemu_bh_new(usb_host_post_load_bh, dev);
    }
    qemu_bh_schedule(dev->bh_postld);
    dev->bh_postld_pending = true;
    return 0;
}

static const VMStateDescription vmstate_usb_host = {
    .name = "usb-host",
    .version_id = 1,
    .minimum_version_id = 1,
    .post_load = usb_host_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_USB_DEVICE(parent_obj, USBHostDevice),
        VMSTATE_END_OF_LIST()
    }
};

static Property usb_host_dev_properties[] = {
    DEFINE_PROP_UINT32("hostbus",  USBHostDevice, match.bus_num,    0),
    DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr,       0),
    DEFINE_PROP_STRING("hostport", USBHostDevice, match.port),
    DEFINE_PROP_UINT32("vendorid",  USBHostDevice, match.vendor_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("isobsize", USBHostDevice, iso_urb_frames,   32),
    DEFINE_PROP_BOOL("guest-reset", USBHostDevice,
                     allow_one_guest_reset, true),
    DEFINE_PROP_BOOL("guest-resets-all", USBHostDevice,
                     allow_all_guest_resets, false),
    DEFINE_PROP_UINT32("loglevel",  USBHostDevice, loglevel,
                       LIBUSB_LOG_LEVEL_WARNING),
    DEFINE_PROP_BIT("pipeline",    USBHostDevice, options,
                    USB_HOST_OPT_PIPELINE, true),
    DEFINE_PROP_BOOL("suppress-remote-wake", USBHostDevice,
                     suppress_remote_wake, true),
    DEFINE_PROP_END_OF_LIST(),
};

static void usb_host_class_initfn(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);

    uc->realize        = usb_host_realize;
    uc->product_desc   = "USB Host Device";
    uc->cancel_packet  = usb_host_cancel_packet;
    uc->handle_data    = usb_host_handle_data;
    uc->handle_control = usb_host_handle_control;
    uc->handle_reset   = usb_host_handle_reset;
    uc->unrealize      = usb_host_unrealize;
    uc->flush_ep_queue = usb_host_flush_ep_queue;
    uc->alloc_streams  = usb_host_alloc_streams;
    uc->free_streams   = usb_host_free_streams;
    dc->vmsd = &vmstate_usb_host;
    device_class_set_props(dc, usb_host_dev_properties);
    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
}

static TypeInfo usb_host_dev_info = {
    .name          = TYPE_USB_HOST_DEVICE,
    .parent        = TYPE_USB_DEVICE,
    .instance_size = sizeof(USBHostDevice),
    .class_init    = usb_host_class_initfn,
    .instance_init = usb_host_instance_init,
};

static void usb_host_register_types(void)
{
    type_register_static(&usb_host_dev_info);
}

type_init(usb_host_register_types)

/* ------------------------------------------------------------------------ */

static QEMUTimer *usb_auto_timer;
static VMChangeStateEntry *usb_vmstate;

static void usb_host_vm_state(void *unused, int running, RunState state)
{
    if (running) {
        usb_host_auto_check(unused);
    }
}

static void usb_host_auto_check(void *unused)
{
    struct USBHostDevice *s;
    struct USBAutoFilter *f;
    libusb_device **devs = NULL;
    struct libusb_device_descriptor ddesc;
    int unconnected = 0;
    int i, n;

    if (usb_host_init() != 0) {
        return;
    }

    if (runstate_is_running()) {
        n = libusb_get_device_list(ctx, &devs);
        for (i = 0; i < n; i++) {
            if (libusb_get_device_descriptor(devs[i], &ddesc) != 0) {
                continue;
            }
            if (ddesc.bDeviceClass == LIBUSB_CLASS_HUB) {
                continue;
            }
            QTAILQ_FOREACH(s, &hostdevs, next) {
                f = &s->match;
                if (f->bus_num > 0 &&
                    f->bus_num != libusb_get_bus_number(devs[i])) {
                    continue;
                }
                if (f->addr > 0 &&
                    f->addr != libusb_get_device_address(devs[i])) {
                    continue;
                }
                if (f->port != NULL) {
                    char port[16] = "-";
                    usb_host_get_port(devs[i], port, sizeof(port));
                    if (strcmp(f->port, port) != 0) {
                        continue;
                    }
                }
                if (f->vendor_id > 0 &&
                    f->vendor_id != ddesc.idVendor) {
                    continue;
                }
                if (f->product_id > 0 &&
                    f->product_id != ddesc.idProduct) {
                    continue;
                }

                /* We got a match */
                s->seen++;
                if (s->errcount >= 3) {
                    continue;
                }
                if (s->dh != NULL) {
                    continue;
                }
                if (usb_host_open(s, devs[i], 0) < 0) {
                    s->errcount++;
                    continue;
                }
                break;
            }
        }
        libusb_free_device_list(devs, 1);

        QTAILQ_FOREACH(s, &hostdevs, next) {
            if (s->dh == NULL) {
                unconnected++;
            }
            if (s->seen == 0) {
                if (s->dh) {
                    usb_host_close(s);
                }
                s->errcount = 0;
            }
            s->seen = 0;
        }

#if 0
        if (unconnected == 0) {
            /* nothing to watch */
            if (usb_auto_timer) {
                timer_del(usb_auto_timer);
                trace_usb_host_auto_scan_disabled();
            }
            return;
        }
#endif
    }

    if (!usb_vmstate) {
        usb_vmstate = qemu_add_vm_change_state_handler(usb_host_vm_state, NULL);
    }
    if (!usb_auto_timer) {
        usb_auto_timer = timer_new_ms(QEMU_CLOCK_REALTIME, usb_host_auto_check, NULL);
        if (!usb_auto_timer) {
            return;
        }
        trace_usb_host_auto_scan_enabled();
    }
    timer_mod(usb_auto_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 2000);
}

/**
 * Check whether USB host device has a USB mass storage SCSI interface
 */
bool usb_host_dev_is_scsi_storage(USBDevice *ud)
{
    USBHostDevice *uhd = USB_HOST_DEVICE(ud);
    struct libusb_config_descriptor *conf;
    const struct libusb_interface_descriptor *intf;
    bool is_scsi_storage = false;
    int i;

    if (!uhd || libusb_get_active_config_descriptor(uhd->dev, &conf) != 0) {
        return false;
    }

    for (i = 0; i < conf->bNumInterfaces; i++) {
        intf = &conf->interface[i].altsetting[ud->altsetting[i]];
        if (intf->bInterfaceClass == LIBUSB_CLASS_MASS_STORAGE &&
            intf->bInterfaceSubClass == 6) {                 /* 6 means SCSI */
            is_scsi_storage = true;
            break;
        }
    }

    libusb_free_config_descriptor(conf);

    return is_scsi_storage;
}

void hmp_info_usbhost(Monitor *mon, const QDict *qdict)
{
    libusb_device **devs = NULL;
    struct libusb_device_descriptor ddesc;
    char port[16];
    int i, n;

    if (usb_host_init() != 0) {
        return;
    }

    n = libusb_get_device_list(ctx, &devs);
    for (i = 0; i < n; i++) {
        if (libusb_get_device_descriptor(devs[i], &ddesc) != 0) {
            continue;
        }
        if (ddesc.bDeviceClass == LIBUSB_CLASS_HUB) {
            continue;
        }
        usb_host_get_port(devs[i], port, sizeof(port));
        monitor_printf(mon, "  Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
                       libusb_get_bus_number(devs[i]),
                       libusb_get_device_address(devs[i]),
                       port,
                       speed_name[libusb_get_device_speed(devs[i])]);
        monitor_printf(mon, "    Class %02x:", ddesc.bDeviceClass);
        monitor_printf(mon, " USB device %04x:%04x",
                       ddesc.idVendor, ddesc.idProduct);
        if (ddesc.iProduct) {
            libusb_device_handle *handle;
            if (libusb_open(devs[i], &handle) == 0) {
                unsigned char name[64] = "";
                libusb_get_string_descriptor_ascii(handle,
                                                   ddesc.iProduct,
                                                   name, sizeof(name));
                libusb_close(handle);
                monitor_printf(mon, ", %s", name);
            }
        }
        monitor_printf(mon, "\n");
    }
    libusb_free_device_list(devs, 1);
}
