qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/10] usb queue: usb3 streams, xhci + mtp fixes
@ 2014-05-26  8:46 Gerd Hoffmann
  2014-05-26  8:46 ` [Qemu-devel] [PULL 01/10] xhci: child detach fix Gerd Hoffmann
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2014-05-26  8:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  Hi,

Finally support for usb3 streams is coming.  The depending bits landed
upstream (kernel 3.15, libusbx 1.0.19, usbredir 0.7), time to get the
qemu support upstream too.

This pull also has some xhci and mtp bugfixes.

please pull,
  Gerd

The following changes since commit 178ac111bca16c08a79b2609ebdc75197bea976a:

  Merge remote-tracking branch 'remotes/qmp-unstable/queue/qmp' into staging (2014-05-22 19:04:49 +0100)

are available in the git repository at:


  git://git.kraxel.org/qemu tags/pull-usb-7

for you to fetch changes up to 8d1bd3c901a315d0000b09b495fa9d5b87641bd9:

  usb-host-libusb: Set stream id when submitting bulk-stream transfers (2014-05-26 08:41:07 +0200)

----------------------------------------------------------------
usb: usb3 streams support for usb-host and usb-redir
usb: xhci and mtp bugfixes.

----------------------------------------------------------------
Gerd Hoffmann (6):
      xhci: child detach fix
      xhci: add endpoint cap on express bus only
      xhci: add xhci_get_flag
      usb-mtp: use bool to track MTPObject init status
      usb-mtp: handle lseek failure
      usb-mtp: handle usb_mtp_get_object failure

Hans de Goede (4):
      usb-redir: Add support for bulk streams
      usb-host-libusb: Fill in endpoint max_streams when available
      usb-host-libusb: Add alloc / free streams ops
      usb-host-libusb: Set stream id when submitting bulk-stream transfers

 hw/usb/dev-mtp.c     |  28 +++++++----
 hw/usb/hcd-xhci.c    |  17 +++++--
 hw/usb/host-libusb.c |  83 +++++++++++++++++++++++++++++--
 hw/usb/redirect.c    | 137 +++++++++++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 242 insertions(+), 23 deletions(-)

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

* [Qemu-devel] [PULL 01/10] xhci: child detach fix
  2014-05-26  8:46 [Qemu-devel] [PULL 00/10] usb queue: usb3 streams, xhci + mtp fixes Gerd Hoffmann
@ 2014-05-26  8:46 ` Gerd Hoffmann
  2014-05-26  8:46 ` [Qemu-devel] [PULL 02/10] xhci: add endpoint cap on express bus only Gerd Hoffmann
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2014-05-26  8:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

xhci_child_detach() zaps the wrong slot when unplugging a device
connected via usb-hub:  Instead of the device's slot the slot of the
usb-hub is used.  Fix it.

https://bugzilla.redhat.com/show_bug.cgi?id=1075846

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
---
 hw/usb/hcd-xhci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index ef3177a..6753a42 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -3435,7 +3435,7 @@ static void xhci_child_detach(USBPort *uport, USBDevice *child)
     USBBus *bus = usb_bus_from_device(child);
     XHCIState *xhci = container_of(bus, XHCIState, bus);
 
-    xhci_detach_slot(xhci, uport);
+    xhci_detach_slot(xhci, child->port);
 }
 
 static USBPortOps xhci_uport_ops = {
-- 
1.8.3.1

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

* [Qemu-devel] [PULL 02/10] xhci: add endpoint cap on express bus only
  2014-05-26  8:46 [Qemu-devel] [PULL 00/10] usb queue: usb3 streams, xhci + mtp fixes Gerd Hoffmann
  2014-05-26  8:46 ` [Qemu-devel] [PULL 01/10] xhci: child detach fix Gerd Hoffmann
@ 2014-05-26  8:46 ` Gerd Hoffmann
  2014-05-26  8:47 ` [Qemu-devel] [PULL 03/10] xhci: add xhci_get_flag Gerd Hoffmann
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2014-05-26  8:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/hcd-xhci.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 6753a42..a203bc6 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -3594,8 +3594,10 @@ static int usb_xhci_initfn(struct PCIDevice *dev)
                      PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64,
                      &xhci->mem);
 
-    ret = pcie_endpoint_cap_init(dev, 0xa0);
-    assert(ret >= 0);
+    if (pci_bus_is_express(dev->bus)) {
+        ret = pcie_endpoint_cap_init(dev, 0xa0);
+        assert(ret >= 0);
+    }
 
     if (xhci->flags & (1 << XHCI_FLAG_USE_MSI)) {
         msi_init(dev, 0x70, xhci->numintrs, true, false);
-- 
1.8.3.1

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

* [Qemu-devel] [PULL 03/10] xhci: add xhci_get_flag
  2014-05-26  8:46 [Qemu-devel] [PULL 00/10] usb queue: usb3 streams, xhci + mtp fixes Gerd Hoffmann
  2014-05-26  8:46 ` [Qemu-devel] [PULL 01/10] xhci: child detach fix Gerd Hoffmann
  2014-05-26  8:46 ` [Qemu-devel] [PULL 02/10] xhci: add endpoint cap on express bus only Gerd Hoffmann
@ 2014-05-26  8:47 ` Gerd Hoffmann
  2014-05-26  8:47 ` [Qemu-devel] [PULL 04/10] usb-mtp: use bool to track MTPObject init status Gerd Hoffmann
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2014-05-26  8:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/hcd-xhci.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index a203bc6..54dea16 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -621,6 +621,11 @@ static const char *ep_state_name(uint32_t state)
                        ARRAY_SIZE(ep_state_names));
 }
 
+static bool xhci_get_flag(XHCIState *xhci, enum xhci_flags bit)
+{
+    return xhci->flags & (1 << bit);
+}
+
 static uint64_t xhci_mfindex_get(XHCIState *xhci)
 {
     int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
@@ -3599,10 +3604,10 @@ static int usb_xhci_initfn(struct PCIDevice *dev)
         assert(ret >= 0);
     }
 
-    if (xhci->flags & (1 << XHCI_FLAG_USE_MSI)) {
+    if (xhci_get_flag(xhci, XHCI_FLAG_USE_MSI)) {
         msi_init(dev, 0x70, xhci->numintrs, true, false);
     }
-    if (xhci->flags & (1 << XHCI_FLAG_USE_MSI_X)) {
+    if (xhci_get_flag(xhci, XHCI_FLAG_USE_MSI_X)) {
         msix_init(dev, xhci->numintrs,
                   &xhci->mem, 0, OFF_MSIX_TABLE,
                   &xhci->mem, 0, OFF_MSIX_PBA,
-- 
1.8.3.1

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

* [Qemu-devel] [PULL 04/10] usb-mtp: use bool to track MTPObject init status
  2014-05-26  8:46 [Qemu-devel] [PULL 00/10] usb queue: usb3 streams, xhci + mtp fixes Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2014-05-26  8:47 ` [Qemu-devel] [PULL 03/10] xhci: add xhci_get_flag Gerd Hoffmann
@ 2014-05-26  8:47 ` Gerd Hoffmann
  2014-05-26  8:47 ` [Qemu-devel] [PULL 05/10] usb-mtp: handle lseek failure Gerd Hoffmann
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2014-05-26  8:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Dr. David Alan Gilbert

Stop setting nchildren to -1.  Use separate bool variable to track
whenever we've already fetched the child objects instead.

Also make nchildren unsigned.

Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/dev-mtp.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index 943f930..c2750e4 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -109,7 +109,8 @@ struct MTPObject {
     struct stat  stat;
     MTPObject    *parent;
     MTPObject    **children;
-    int32_t      nchildren;
+    uint32_t     nchildren;
+    bool         have_children;
     QTAILQ_ENTRY(MTPObject) next;
 };
 
@@ -273,7 +274,6 @@ static MTPObject *usb_mtp_object_alloc(MTPState *s, uint32_t handle,
     o->handle = handle;
     o->parent = parent;
     o->name = g_strdup(name);
-    o->nchildren = -1;
     if (parent == NULL) {
         o->path = g_strdup(name);
     } else {
@@ -340,7 +340,11 @@ static void usb_mtp_object_readdir(MTPState *s, MTPObject *o)
     struct dirent *entry;
     DIR *dir;
 
-    o->nchildren = 0;
+    if (o->have_children) {
+        return;
+    }
+    o->have_children = true;
+
     dir = opendir(o->path);
     if (!dir) {
         return;
@@ -789,9 +793,7 @@ static void usb_mtp_command(MTPState *s, MTPControl *c)
                                  c->trans, 0, 0, 0);
             return;
         }
-        if (o->nchildren == -1) {
-            usb_mtp_object_readdir(s, o);
-        }
+        usb_mtp_object_readdir(s, o);
         if (c->code == CMD_GET_NUM_OBJECTS) {
             trace_usb_mtp_op_get_num_objects(s->dev.addr, o->handle, o->path);
             nres = 1;
-- 
1.8.3.1

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

* [Qemu-devel] [PULL 05/10] usb-mtp: handle lseek failure
  2014-05-26  8:46 [Qemu-devel] [PULL 00/10] usb queue: usb3 streams, xhci + mtp fixes Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2014-05-26  8:47 ` [Qemu-devel] [PULL 04/10] usb-mtp: use bool to track MTPObject init status Gerd Hoffmann
@ 2014-05-26  8:47 ` Gerd Hoffmann
  2014-05-26  8:47 ` [Qemu-devel] [PULL 06/10] usb-mtp: handle usb_mtp_get_object failure Gerd Hoffmann
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2014-05-26  8:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Dr. David Alan Gilbert

Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/dev-mtp.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index c2750e4..a95298b 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -702,7 +702,10 @@ static MTPData *usb_mtp_get_partial_object(MTPState *s, MTPControl *c,
     if (offset > o->stat.st_size) {
         offset = o->stat.st_size;
     }
-    lseek(d->fd, offset, SEEK_SET);
+    if (lseek(d->fd, offset, SEEK_SET) < 0) {
+        usb_mtp_data_free(d);
+        return NULL;
+    }
 
     d->length = c->argv[2];
     if (d->length > o->stat.st_size - offset) {
-- 
1.8.3.1

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

* [Qemu-devel] [PULL 06/10] usb-mtp: handle usb_mtp_get_object failure
  2014-05-26  8:46 [Qemu-devel] [PULL 00/10] usb queue: usb3 streams, xhci + mtp fixes Gerd Hoffmann
                   ` (4 preceding siblings ...)
  2014-05-26  8:47 ` [Qemu-devel] [PULL 05/10] usb-mtp: handle lseek failure Gerd Hoffmann
@ 2014-05-26  8:47 ` Gerd Hoffmann
  2014-05-26  8:47 ` [Qemu-devel] [PULL 07/10] usb-redir: Add support for bulk streams Gerd Hoffmann
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2014-05-26  8:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Dr. David Alan Gilbert

Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/dev-mtp.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index a95298b..380b465 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -46,6 +46,7 @@ enum mtp_code {
 
     /* response codes */
     RES_OK                         = 0x2001,
+    RES_GENERAL_ERROR              = 0x2002,
     RES_SESSION_NOT_OPEN           = 0x2003,
     RES_INVALID_TRANSACTION_ID     = 0x2004,
     RES_OPERATION_NOT_SUPPORTED    = 0x2005,
@@ -828,7 +829,9 @@ static void usb_mtp_command(MTPState *s, MTPControl *c)
         }
         data_in = usb_mtp_get_object(s, c, o);
         if (NULL == data_in) {
-            fprintf(stderr, "%s: TODO: handle error\n", __func__);
+            usb_mtp_queue_result(s, RES_GENERAL_ERROR,
+                                 c->trans, 0, 0, 0);
+            return;
         }
         break;
     case CMD_GET_PARTIAL_OBJECT:
@@ -845,7 +848,9 @@ static void usb_mtp_command(MTPState *s, MTPControl *c)
         }
         data_in = usb_mtp_get_partial_object(s, c, o);
         if (NULL == data_in) {
-            fprintf(stderr, "%s: TODO: handle error\n", __func__);
+            usb_mtp_queue_result(s, RES_GENERAL_ERROR,
+                                 c->trans, 0, 0, 0);
+            return;
         }
         nres = 1;
         res0 = data_in->length;
-- 
1.8.3.1

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

* [Qemu-devel] [PULL 07/10] usb-redir: Add support for bulk streams
  2014-05-26  8:46 [Qemu-devel] [PULL 00/10] usb queue: usb3 streams, xhci + mtp fixes Gerd Hoffmann
                   ` (5 preceding siblings ...)
  2014-05-26  8:47 ` [Qemu-devel] [PULL 06/10] usb-mtp: handle usb_mtp_get_object failure Gerd Hoffmann
@ 2014-05-26  8:47 ` Gerd Hoffmann
  2014-05-26  8:47 ` [Qemu-devel] [PULL 08/10] usb-host-libusb: Fill in endpoint max_streams when available Gerd Hoffmann
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2014-05-26  8:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Hans de Goede, Gerd Hoffmann

From: Hans de Goede <hdegoede@redhat.com>

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/redirect.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 132 insertions(+), 5 deletions(-)

diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 287a505..4c6187b 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -50,6 +50,10 @@
                        ((i) & 0x10) ? USB_TOKEN_IN : USB_TOKEN_OUT, \
                        (i) & 0x0f))
 
+#ifndef USBREDIR_VERSION /* This is not defined in older usbredir versions */
+#define USBREDIR_VERSION 0
+#endif
+
 typedef struct USBRedirDevice USBRedirDevice;
 
 /* Struct to hold buffered packets */
@@ -68,6 +72,7 @@ struct endp_data {
     uint8_t interval;
     uint8_t interface; /* bInterfaceNumber this ep belongs to */
     uint16_t max_packet_size; /* In bytes, not wMaxPacketSize format !! */
+    uint32_t max_streams;
     uint8_t iso_started;
     uint8_t iso_error; /* For reporting iso errors to the HC */
     uint8_t interrupt_started;
@@ -106,8 +111,9 @@ struct USBRedirDevice {
     int read_buf_size;
     /* Active chardev-watch-tag */
     guint watch;
-    /* For async handling of close */
+    /* For async handling of close / reject */
     QEMUBH *chardev_close_bh;
+    QEMUBH *device_reject_bh;
     /* To delay the usb attach in case of quick chardev close + open */
     QEMUTimer *attach_timer;
     int64_t next_attach_time;
@@ -780,11 +786,12 @@ static void usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
         dev->endpoint[EP2I(ep)].bulk_receiving_enabled = 0;
     }
 
-    DPRINTF("bulk-out ep %02X len %zd id %"PRIu64"\n", ep, size, p->id);
+    DPRINTF("bulk-out ep %02X stream %u len %zd id %"PRIu64"\n",
+            ep, p->stream, size, p->id);
 
     bulk_packet.endpoint  = ep;
     bulk_packet.length    = size;
-    bulk_packet.stream_id = 0;
+    bulk_packet.stream_id = p->stream;
     bulk_packet.length_high = size >> 16;
     assert(bulk_packet.length_high == 0 ||
            usbredirparser_peer_has_cap(dev->parser,
@@ -1091,6 +1098,66 @@ static void usbredir_handle_control(USBDevice *udev, USBPacket *p,
     p->status = USB_RET_ASYNC;
 }
 
+static int usbredir_alloc_streams(USBDevice *udev, USBEndpoint **eps,
+                                  int nr_eps, int streams)
+{
+    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
+#if USBREDIR_VERSION >= 0x000700
+    struct usb_redir_alloc_bulk_streams_header alloc_streams;
+    int i;
+
+    if (!usbredirparser_peer_has_cap(dev->parser,
+                                     usb_redir_cap_bulk_streams)) {
+        ERROR("peer does not support streams\n");
+        goto reject;
+    }
+
+    if (streams == 0) {
+        ERROR("request to allocate 0 streams\n");
+        return -1;
+    }
+
+    alloc_streams.no_streams = streams;
+    alloc_streams.endpoints = 0;
+    for (i = 0; i < nr_eps; i++) {
+        alloc_streams.endpoints |= 1 << USBEP2I(eps[i]);
+    }
+    usbredirparser_send_alloc_bulk_streams(dev->parser, 0, &alloc_streams);
+    usbredirparser_do_write(dev->parser);
+
+    return 0;
+#else
+    ERROR("usbredir_alloc_streams not implemented\n");
+    goto reject;
+#endif
+reject:
+    ERROR("streams are not available, disconnecting\n");
+    qemu_bh_schedule(dev->device_reject_bh);
+    return -1;
+}
+
+static void usbredir_free_streams(USBDevice *udev, USBEndpoint **eps,
+                                  int nr_eps)
+{
+#if USBREDIR_VERSION >= 0x000700
+    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
+    struct usb_redir_free_bulk_streams_header free_streams;
+    int i;
+
+    if (!usbredirparser_peer_has_cap(dev->parser,
+                                     usb_redir_cap_bulk_streams)) {
+        return;
+    }
+
+    free_streams.endpoints = 0;
+    for (i = 0; i < nr_eps; i++) {
+        free_streams.endpoints |= 1 << USBEP2I(eps[i]);
+    }
+    usbredirparser_send_free_bulk_streams(dev->parser, 0, &free_streams);
+    usbredirparser_do_write(dev->parser);
+#endif
+}
+
 /*
  * Close events can be triggered by usbredirparser_do_write which gets called
  * from within the USBDevice data / control packet callbacks and doing a
@@ -1102,6 +1169,7 @@ static void usbredir_chardev_close_bh(void *opaque)
 {
     USBRedirDevice *dev = opaque;
 
+    qemu_bh_cancel(dev->device_reject_bh);
     usbredir_device_disconnect(dev);
 
     if (dev->parser) {
@@ -1153,6 +1221,9 @@ static void usbredir_create_parser(USBRedirDevice *dev)
     usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids);
     usbredirparser_caps_set_cap(caps, usb_redir_cap_32bits_bulk_length);
     usbredirparser_caps_set_cap(caps, usb_redir_cap_bulk_receiving);
+#if USBREDIR_VERSION >= 0x000700
+    usbredirparser_caps_set_cap(caps, usb_redir_cap_bulk_streams);
+#endif
 
     if (runstate_check(RUN_STATE_INMIGRATE)) {
         flags |= usbredirparser_fl_no_hello;
@@ -1171,6 +1242,17 @@ static void usbredir_reject_device(USBRedirDevice *dev)
     }
 }
 
+/*
+ * We may need to reject the device when the hcd calls alloc_streams, doing
+ * an usb_detach from within a hcd call is not a good idea, hence this bh.
+ */
+static void usbredir_device_reject_bh(void *opaque)
+{
+    USBRedirDevice *dev = opaque;
+
+    usbredir_reject_device(dev);
+}
+
 static void usbredir_do_attach(void *opaque)
 {
     USBRedirDevice *dev = opaque;
@@ -1297,6 +1379,7 @@ static int usbredir_initfn(USBDevice *udev)
     }
 
     dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev);
+    dev->device_reject_bh = qemu_bh_new(usbredir_device_reject_bh, dev);
     dev->attach_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, usbredir_do_attach, dev);
 
     packet_id_queue_init(&dev->cancelled, dev, "cancelled");
@@ -1337,6 +1420,7 @@ static void usbredir_handle_destroy(USBDevice *udev)
     dev->cs = NULL;
     /* Note must be done after qemu_chr_close, as that causes a close event */
     qemu_bh_delete(dev->chardev_close_bh);
+    qemu_bh_delete(dev->device_reject_bh);
 
     timer_del(dev->attach_timer);
     timer_free(dev->attach_timer);
@@ -1628,6 +1712,7 @@ static void usbredir_setup_usb_eps(USBRedirDevice *dev)
         usb_ep->type = dev->endpoint[i].type;
         usb_ep->ifnum = dev->endpoint[i].interface;
         usb_ep->max_packet_size = dev->endpoint[i].max_packet_size;
+        usb_ep->max_streams = dev->endpoint[i].max_streams;
         usbredir_set_pipeline(dev, usb_ep);
     }
 }
@@ -1646,6 +1731,12 @@ static void usbredir_ep_info(void *priv,
                                      usb_redir_cap_ep_info_max_packet_size)) {
             dev->endpoint[i].max_packet_size = ep_info->max_packet_size[i];
         }
+#if USBREDIR_VERSION >= 0x000700
+        if (usbredirparser_peer_has_cap(dev->parser,
+                                        usb_redir_cap_bulk_streams)) {
+            dev->endpoint[i].max_streams = ep_info->max_streams[i];
+        }
+#endif
         switch (dev->endpoint[i].type) {
         case usb_redir_type_invalid:
             break;
@@ -1779,6 +1870,20 @@ static void usbredir_interrupt_receiving_status(void *priv, uint64_t id,
 static void usbredir_bulk_streams_status(void *priv, uint64_t id,
     struct usb_redir_bulk_streams_status_header *bulk_streams_status)
 {
+#if USBREDIR_VERSION >= 0x000700
+    USBRedirDevice *dev = priv;
+
+    if (bulk_streams_status->status == usb_redir_success) {
+        DPRINTF("bulk streams status %d eps %08x\n",
+                bulk_streams_status->status, bulk_streams_status->endpoints);
+    } else {
+        ERROR("bulk streams %s failed status %d eps %08x\n",
+              (bulk_streams_status->no_streams == 0) ? "free" : "alloc",
+              bulk_streams_status->status, bulk_streams_status->endpoints);
+        ERROR("usb-redir-host does not provide streams, disconnecting\n");
+        usbredir_reject_device(dev);
+    }
+#endif
 }
 
 static void usbredir_bulk_receiving_status(void *priv, uint64_t id,
@@ -1850,8 +1955,8 @@ static void usbredir_bulk_packet(void *priv, uint64_t id,
     int len = (bulk_packet->length_high << 16) | bulk_packet->length;
     USBPacket *p;
 
-    DPRINTF("bulk-in status %d ep %02X len %d id %"PRIu64"\n",
-            bulk_packet->status, ep, len, id);
+    DPRINTF("bulk-in status %d ep %02X stream %u len %d id %"PRIu64"\n",
+            bulk_packet->status, ep, bulk_packet->stream_id, len, id);
 
     p = usbredir_find_packet_by_id(dev, ep, id);
     if (p) {
@@ -2165,6 +2270,23 @@ static bool usbredir_bulk_receiving_needed(void *priv)
     return endp->bulk_receiving_started;
 }
 
+static const VMStateDescription usbredir_stream_vmstate = {
+    .name = "usb-redir-ep/stream-state",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(max_streams, struct endp_data),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static bool usbredir_stream_needed(void *priv)
+{
+    struct endp_data *endp = priv;
+
+    return endp->max_streams;
+}
+
 static const VMStateDescription usbredir_ep_vmstate = {
     .name = "usb-redir-ep",
     .version_id = 1,
@@ -2197,6 +2319,9 @@ static const VMStateDescription usbredir_ep_vmstate = {
             .vmsd = &usbredir_bulk_receiving_vmstate,
             .needed = usbredir_bulk_receiving_needed,
         }, {
+            .vmsd = &usbredir_stream_vmstate,
+            .needed = usbredir_stream_needed,
+        }, {
             /* empty */
         }
     }
@@ -2361,6 +2486,8 @@ static void usbredir_class_initfn(ObjectClass *klass, void *data)
     uc->handle_control = usbredir_handle_control;
     uc->flush_ep_queue = usbredir_flush_ep_queue;
     uc->ep_stopped     = usbredir_ep_stopped;
+    uc->alloc_streams  = usbredir_alloc_streams;
+    uc->free_streams   = usbredir_free_streams;
     dc->vmsd           = &usbredir_vmstate;
     dc->props          = usbredir_properties;
     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
-- 
1.8.3.1

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

* [Qemu-devel] [PULL 08/10] usb-host-libusb: Fill in endpoint max_streams when available
  2014-05-26  8:46 [Qemu-devel] [PULL 00/10] usb queue: usb3 streams, xhci + mtp fixes Gerd Hoffmann
                   ` (6 preceding siblings ...)
  2014-05-26  8:47 ` [Qemu-devel] [PULL 07/10] usb-redir: Add support for bulk streams Gerd Hoffmann
@ 2014-05-26  8:47 ` Gerd Hoffmann
  2014-05-26  8:47 ` [Qemu-devel] [PULL 09/10] usb-host-libusb: Add alloc / free streams ops Gerd Hoffmann
  2014-05-26  8:47 ` [Qemu-devel] [PULL 10/10] usb-host-libusb: Set stream id when submitting bulk-stream transfers Gerd Hoffmann
  9 siblings, 0 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2014-05-26  8:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Hans de Goede, Gerd Hoffmann

From: Hans de Goede <hdegoede@redhat.com>

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/host-libusb.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index 57bed09..3fdbd93 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -720,6 +720,9 @@ static void usb_host_ep_update(USBHostDevice *s)
     struct libusb_config_descriptor *conf;
     const struct libusb_interface_descriptor *intf;
     const struct libusb_endpoint_descriptor *endp;
+#if LIBUSBX_API_VERSION >= 0x01000103
+    struct libusb_ss_endpoint_companion_descriptor *endp_ss_comp;
+#endif
     uint8_t devep, type;
     int pid, ep;
     int rc, i, e;
@@ -765,6 +768,15 @@ static void usb_host_ep_update(USBHostDevice *s)
             usb_ep_set_type(udev, pid, ep, type);
             usb_ep_set_ifnum(udev, pid, ep, i);
             usb_ep_set_halted(udev, pid, ep, 0);
+#if LIBUSBX_API_VERSION >= 0x01000103
+            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
         }
     }
 
-- 
1.8.3.1

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

* [Qemu-devel] [PULL 09/10] usb-host-libusb: Add alloc / free streams ops
  2014-05-26  8:46 [Qemu-devel] [PULL 00/10] usb queue: usb3 streams, xhci + mtp fixes Gerd Hoffmann
                   ` (7 preceding siblings ...)
  2014-05-26  8:47 ` [Qemu-devel] [PULL 08/10] usb-host-libusb: Fill in endpoint max_streams when available Gerd Hoffmann
@ 2014-05-26  8:47 ` Gerd Hoffmann
  2014-05-26  8:47 ` [Qemu-devel] [PULL 10/10] usb-host-libusb: Set stream id when submitting bulk-stream transfers Gerd Hoffmann
  9 siblings, 0 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2014-05-26  8:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Hans de Goede, Gerd Hoffmann

From: Hans de Goede <hdegoede@redhat.com>

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/host-libusb.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index 3fdbd93..401eb74 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -1280,6 +1280,54 @@ static void usb_host_handle_reset(USBDevice *udev)
     }
 }
 
+static int usb_host_alloc_streams(USBDevice *udev, USBEndpoint **eps,
+                                  int nr_eps, int streams)
+{
+#if LIBUSBX_API_VERSION >= 0x01000103
+    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) {
+        fprintf(stderr,
+            "libusb_alloc_streams: got less streams then requested %d < %d\n",
+            rc, streams);
+    }
+
+    return (rc == streams) ? 0 : -1;
+#else
+    fprintf(stderr, "libusb_alloc_streams: error not implemented\n");
+    return -1;
+#endif
+}
+
+static void usb_host_free_streams(USBDevice *udev, USBEndpoint **eps,
+                                  int nr_eps)
+{
+#if LIBUSBX_API_VERSION >= 0x01000103
+    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
@@ -1361,6 +1409,8 @@ static void usb_host_class_initfn(ObjectClass *klass, void *data)
     uc->handle_reset   = usb_host_handle_reset;
     uc->handle_destroy = usb_host_handle_destroy;
     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;
     dc->props = usb_host_dev_properties;
     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
-- 
1.8.3.1

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

* [Qemu-devel] [PULL 10/10] usb-host-libusb: Set stream id when submitting bulk-stream transfers
  2014-05-26  8:46 [Qemu-devel] [PULL 00/10] usb queue: usb3 streams, xhci + mtp fixes Gerd Hoffmann
                   ` (8 preceding siblings ...)
  2014-05-26  8:47 ` [Qemu-devel] [PULL 09/10] usb-host-libusb: Add alloc / free streams ops Gerd Hoffmann
@ 2014-05-26  8:47 ` Gerd Hoffmann
  9 siblings, 0 replies; 11+ messages in thread
From: Gerd Hoffmann @ 2014-05-26  8:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Hans de Goede, Gerd Hoffmann

From: Hans de Goede <hdegoede@redhat.com>

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/host-libusb.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index 401eb74..8007d1d 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -1214,10 +1214,23 @@ static void usb_host_handle_data(USBDevice *udev, USBPacket *p)
             usb_packet_copy(p, r->buffer, size);
         }
         ep = p->ep->nr | (r->in ? USB_DIR_IN : 0);
-        libusb_fill_bulk_transfer(r->xfer, s->dh, ep,
-                                  r->buffer, size,
-                                  usb_host_req_complete_data, r,
-                                  BULK_TIMEOUT);
+        if (p->stream) {
+#if LIBUSBX_API_VERSION >= 0x01000103
+            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);
-- 
1.8.3.1

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

end of thread, other threads:[~2014-05-26  8:47 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-26  8:46 [Qemu-devel] [PULL 00/10] usb queue: usb3 streams, xhci + mtp fixes Gerd Hoffmann
2014-05-26  8:46 ` [Qemu-devel] [PULL 01/10] xhci: child detach fix Gerd Hoffmann
2014-05-26  8:46 ` [Qemu-devel] [PULL 02/10] xhci: add endpoint cap on express bus only Gerd Hoffmann
2014-05-26  8:47 ` [Qemu-devel] [PULL 03/10] xhci: add xhci_get_flag Gerd Hoffmann
2014-05-26  8:47 ` [Qemu-devel] [PULL 04/10] usb-mtp: use bool to track MTPObject init status Gerd Hoffmann
2014-05-26  8:47 ` [Qemu-devel] [PULL 05/10] usb-mtp: handle lseek failure Gerd Hoffmann
2014-05-26  8:47 ` [Qemu-devel] [PULL 06/10] usb-mtp: handle usb_mtp_get_object failure Gerd Hoffmann
2014-05-26  8:47 ` [Qemu-devel] [PULL 07/10] usb-redir: Add support for bulk streams Gerd Hoffmann
2014-05-26  8:47 ` [Qemu-devel] [PULL 08/10] usb-host-libusb: Fill in endpoint max_streams when available Gerd Hoffmann
2014-05-26  8:47 ` [Qemu-devel] [PULL 09/10] usb-host-libusb: Add alloc / free streams ops Gerd Hoffmann
2014-05-26  8:47 ` [Qemu-devel] [PULL 10/10] usb-host-libusb: Set stream id when submitting bulk-stream transfers Gerd Hoffmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).