* [Qemu-devel] [PATCH 1/9] usb: Add max_streams attribute to endpoint info
2013-11-19 13:36 [Qemu-devel] [PATCH 0/9] usb: redirection streams support + small fixes Hans de Goede
@ 2013-11-19 13:36 ` Hans de Goede
2013-11-19 13:36 ` [Qemu-devel] [PATCH 2/9] usb: Add usb_device_alloc/free_streams Hans de Goede
` (9 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Hans de Goede @ 2013-11-19 13:36 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Hans de Goede, qemu-devel
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/usb/core.c | 22 ++++++++++++++++++++++
hw/usb/desc.c | 2 ++
include/hw/usb.h | 3 +++
3 files changed, 27 insertions(+)
diff --git a/hw/usb/core.c b/hw/usb/core.c
index cf59a1a..67ba7d6 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -623,6 +623,7 @@ void usb_ep_reset(USBDevice *dev)
dev->ep_ctl.type = USB_ENDPOINT_XFER_CONTROL;
dev->ep_ctl.ifnum = 0;
dev->ep_ctl.max_packet_size = 64;
+ dev->ep_ctl.max_streams = 0;
dev->ep_ctl.dev = dev;
dev->ep_ctl.pipeline = false;
for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
@@ -636,6 +637,8 @@ void usb_ep_reset(USBDevice *dev)
dev->ep_out[ep].ifnum = USB_INTERFACE_INVALID;
dev->ep_in[ep].max_packet_size = 0;
dev->ep_out[ep].max_packet_size = 0;
+ dev->ep_in[ep].max_streams = 0;
+ dev->ep_out[ep].max_streams = 0;
dev->ep_in[ep].dev = dev;
dev->ep_out[ep].dev = dev;
dev->ep_in[ep].pipeline = false;
@@ -764,6 +767,25 @@ int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep)
return uep->max_packet_size;
}
+void usb_ep_set_max_streams(USBDevice *dev, int pid, int ep, uint8_t raw)
+{
+ struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
+ int MaxStreams;
+
+ MaxStreams = raw & 0x1f;
+ if (MaxStreams) {
+ uep->max_streams = 1 << MaxStreams;
+ } else {
+ uep->max_streams = 0;
+ }
+}
+
+int usb_ep_get_max_streams(USBDevice *dev, int pid, int ep)
+{
+ struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
+ return uep->max_streams;
+}
+
void usb_ep_set_pipeline(USBDevice *dev, int pid, int ep, bool enabled)
{
struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
diff --git a/hw/usb/desc.c b/hw/usb/desc.c
index bf6c522..5dbe754 100644
--- a/hw/usb/desc.c
+++ b/hw/usb/desc.c
@@ -385,6 +385,8 @@ static void usb_desc_ep_init(USBDevice *dev)
usb_ep_set_ifnum(dev, pid, ep, iface->bInterfaceNumber);
usb_ep_set_max_packet_size(dev, pid, ep,
iface->eps[e].wMaxPacketSize);
+ usb_ep_set_max_streams(dev, pid, ep,
+ iface->eps[e].bmAttributes_super);
}
}
}
diff --git a/include/hw/usb.h b/include/hw/usb.h
index a7680d4..e9d96ba 100644
--- a/include/hw/usb.h
+++ b/include/hw/usb.h
@@ -189,6 +189,7 @@ struct USBEndpoint {
uint8_t type;
uint8_t ifnum;
int max_packet_size;
+ int max_streams;
bool pipeline;
bool halted;
USBDevice *dev;
@@ -421,6 +422,8 @@ void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum);
void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep,
uint16_t raw);
int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep);
+void usb_ep_set_max_streams(USBDevice *dev, int pid, int ep, uint8_t raw);
+int usb_ep_get_max_streams(USBDevice *dev, int pid, int ep);
void usb_ep_set_pipeline(USBDevice *dev, int pid, int ep, bool enabled);
void usb_ep_set_halted(USBDevice *dev, int pid, int ep, bool halted);
USBPacket *usb_ep_find_packet_by_id(USBDevice *dev, int pid, int ep,
--
1.8.4.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 2/9] usb: Add usb_device_alloc/free_streams
2013-11-19 13:36 [Qemu-devel] [PATCH 0/9] usb: redirection streams support + small fixes Hans de Goede
2013-11-19 13:36 ` [Qemu-devel] [PATCH 1/9] usb: Add max_streams attribute to endpoint info Hans de Goede
@ 2013-11-19 13:36 ` Hans de Goede
2013-11-19 13:36 ` [Qemu-devel] [PATCH 3/9] xhci: Call usb_device_alloc/free_streams Hans de Goede
` (8 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Hans de Goede @ 2013-11-19 13:36 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Hans de Goede, qemu-devel
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/usb/bus.c | 18 ++++++++++++++++++
include/hw/usb.h | 12 ++++++++++++
2 files changed, 30 insertions(+)
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index ca329be..09848c6 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -203,6 +203,24 @@ void usb_device_ep_stopped(USBDevice *dev, USBEndpoint *ep)
}
}
+int usb_device_alloc_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps,
+ int streams)
+{
+ USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+ if (klass->alloc_streams) {
+ return klass->alloc_streams(dev, eps, nr_eps, streams);
+ }
+ return 0;
+}
+
+void usb_device_free_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps)
+{
+ USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+ if (klass->free_streams) {
+ klass->free_streams(dev, eps, nr_eps);
+ }
+}
+
static int usb_qdev_init(DeviceState *qdev)
{
USBDevice *dev = USB_DEVICE(qdev);
diff --git a/include/hw/usb.h b/include/hw/usb.h
index e9d96ba..0a6ef4a 100644
--- a/include/hw/usb.h
+++ b/include/hw/usb.h
@@ -315,6 +315,14 @@ typedef struct USBDeviceClass {
*/
void (*ep_stopped)(USBDevice *dev, USBEndpoint *ep);
+ /*
+ * Called by the hcd to alloc / free streams on a bulk endpoint.
+ * Optional may be NULL.
+ */
+ int (*alloc_streams)(USBDevice *dev, USBEndpoint **eps, int nr_eps,
+ int streams);
+ void (*free_streams)(USBDevice *dev, USBEndpoint **eps, int nr_eps);
+
const char *product_desc;
const USBDesc *usb_desc;
} USBDeviceClass;
@@ -553,6 +561,10 @@ void usb_device_flush_ep_queue(USBDevice *dev, USBEndpoint *ep);
void usb_device_ep_stopped(USBDevice *dev, USBEndpoint *ep);
+int usb_device_alloc_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps,
+ int streams);
+void usb_device_free_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps);
+
const char *usb_device_get_product_desc(USBDevice *dev);
const USBDesc *usb_device_get_usb_desc(USBDevice *dev);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 3/9] xhci: Call usb_device_alloc/free_streams
2013-11-19 13:36 [Qemu-devel] [PATCH 0/9] usb: redirection streams support + small fixes Hans de Goede
2013-11-19 13:36 ` [Qemu-devel] [PATCH 1/9] usb: Add max_streams attribute to endpoint info Hans de Goede
2013-11-19 13:36 ` [Qemu-devel] [PATCH 2/9] usb: Add usb_device_alloc/free_streams Hans de Goede
@ 2013-11-19 13:36 ` Hans de Goede
2013-11-19 13:36 ` [Qemu-devel] [PATCH 4/9] xhci: Add a few missing checks for disconnected devices Hans de Goede
` (7 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Hans de Goede @ 2013-11-19 13:36 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Hans de Goede, qemu-devel
Note this code is not as KISS as I would like, the reason for this is that
the Linux kernel interface wants streams on eps belonging to one interface
to be allocated in one call. Things will also work if we do this one ep at a
time (as long as all eps support the same amount of streams), but lets stick
to the kernel API.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/usb/hcd-xhci.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 117 insertions(+)
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index d84d510..9368348 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1150,6 +1150,111 @@ static void xhci_free_streams(XHCIEPContext *epctx)
epctx->nr_pstreams = 0;
}
+static int xhci_epmask_to_eps_with_streams(XHCIState *xhci,
+ unsigned int slotid,
+ uint32_t epmask,
+ XHCIEPContext **epctxs,
+ USBEndpoint **eps)
+{
+ XHCISlot *slot;
+ XHCIEPContext *epctx;
+ USBEndpoint *ep;
+ int i, j;
+
+ assert(slotid >= 1 && slotid <= xhci->numslots);
+
+ slot = &xhci->slots[slotid - 1];
+
+ for (i = 2, j = 0; i <= 31; i++) {
+ if (!(epmask & (1 << i))) {
+ continue;
+ }
+
+ epctx = slot->eps[i - 1];
+ ep = xhci_epid_to_usbep(xhci, slotid, i);
+ if (!epctx || !epctx->nr_pstreams || !ep) {
+ continue;
+ }
+
+ if (epctxs) {
+ epctxs[j] = epctx;
+ }
+ eps[j++] = ep;
+ }
+ return j;
+}
+
+static void xhci_free_device_streams(XHCIState *xhci, unsigned int slotid,
+ uint32_t epmask)
+{
+ USBEndpoint *eps[30];
+ int nr_eps;
+
+ nr_eps = xhci_epmask_to_eps_with_streams(xhci, slotid, epmask, NULL, eps);
+ if (nr_eps) {
+ usb_device_free_streams(eps[0]->dev, eps, nr_eps);
+ }
+}
+
+static TRBCCode xhci_alloc_device_streams(XHCIState *xhci, unsigned int slotid,
+ uint32_t epmask)
+{
+ XHCIEPContext *epctxs[30];
+ USBEndpoint *eps[30];
+ int i, r, nr_eps, req_nr_streams, dev_max_streams;
+
+ nr_eps = xhci_epmask_to_eps_with_streams(xhci, slotid, epmask, epctxs,
+ eps);
+ if (nr_eps == 0) {
+ return CC_SUCCESS;
+ }
+
+ req_nr_streams = epctxs[0]->nr_pstreams;
+ dev_max_streams = eps[0]->max_streams;
+
+ for (i = 1; i < nr_eps; i++) {
+ /*
+ * HdG: I don't expect these to ever trigger, but if they do we need
+ * to come up with another solution, ie group identical endpoints
+ * together and make an usb_device_alloc_streams call per group.
+ */
+ if (epctxs[i]->nr_pstreams != req_nr_streams) {
+ FIXME("guest streams config not identical for all eps");
+ return CC_RESOURCE_ERROR;
+ }
+ if (eps[i]->max_streams != dev_max_streams) {
+ FIXME("device streams config not identical for all eps");
+ return CC_RESOURCE_ERROR;
+ }
+ }
+
+ /*
+ * max-streams in both the device descriptor and in the controller is a
+ * power of 2. But stream id 0 is reserved, so if a device can do up to 4
+ * streams the guest will ask for 5 rounded up to the next power of 2 which
+ * becomes 8. For emulated devices usb_device_alloc_streams is a nop.
+ *
+ * For redirected devices however this is an issue, as there we must ask
+ * the real xhci controller to alloc streams, and the host driver for the
+ * real xhci controller will likely disallow allocating more streams then
+ * the device can handle.
+ *
+ * So we limit the requested nr_streams to the maximum number the device
+ * can handle.
+ */
+ if (req_nr_streams > dev_max_streams) {
+ req_nr_streams = dev_max_streams;
+ }
+
+ r = usb_device_alloc_streams(eps[0]->dev, eps, nr_eps, req_nr_streams);
+ if (r != 0) {
+ fprintf(stderr, "xhci: alloc streams failed\n");
+ return CC_RESOURCE_ERROR;
+ }
+
+ return CC_SUCCESS;
+}
+
static XHCIStreamContext *xhci_find_stream(XHCIEPContext *epctx,
unsigned int streamid,
uint32_t *cc_error)
@@ -2313,6 +2418,8 @@ static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid,
return CC_CONTEXT_STATE_ERROR;
}
+ xhci_free_device_streams(xhci, slotid, ictl_ctx[0] | ictl_ctx[1]);
+
for (i = 2; i <= 31; i++) {
if (ictl_ctx[0] & (1<<i)) {
xhci_disable_ep(xhci, slotid, i);
@@ -2334,6 +2441,16 @@ static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid,
}
}
+ res = xhci_alloc_device_streams(xhci, slotid, ictl_ctx[1]);
+ if (res != CC_SUCCESS) {
+ for (i = 2; i <= 31; i++) {
+ if (ictl_ctx[1] & (1 << i)) {
+ xhci_disable_ep(xhci, slotid, i);
+ }
+ }
+ return res;
+ }
+
slot_ctx[3] &= ~(SLOT_STATE_MASK << SLOT_STATE_SHIFT);
slot_ctx[3] |= SLOT_CONFIGURED << SLOT_STATE_SHIFT;
slot_ctx[0] &= ~(SLOT_CONTEXT_ENTRIES_MASK << SLOT_CONTEXT_ENTRIES_SHIFT);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 4/9] xhci: Add a few missing checks for disconnected devices
2013-11-19 13:36 [Qemu-devel] [PATCH 0/9] usb: redirection streams support + small fixes Hans de Goede
` (2 preceding siblings ...)
2013-11-19 13:36 ` [Qemu-devel] [PATCH 3/9] xhci: Call usb_device_alloc/free_streams Hans de Goede
@ 2013-11-19 13:36 ` Hans de Goede
2013-11-19 13:37 ` [Qemu-devel] [PATCH 5/9] usb-host-libusb: Fill in endpoint max_streams when available Hans de Goede
` (6 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Hans de Goede @ 2013-11-19 13:36 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Hans de Goede, qemu-devel
One of the reworks of qemu's usb core made changes to usb-port's disconnect
handling. Now ports with a device will always have a non 0 dev member, but
if the device is not attached (which is possible with usb redirection),
dev->attached will be 0.
So supplement all checks for dev to also check dev->attached, and add an
extra check in a path where a device check was completely missing.
This fixes various crashes (asserts triggering) I've been seeing when xhci
attached usb devices get disconnected at the wrong time.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/usb/hcd-xhci.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 9368348..bafe085 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1600,7 +1600,8 @@ static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigned int slotid,
}
if (!xhci->slots[slotid-1].uport ||
- !xhci->slots[slotid-1].uport->dev) {
+ !xhci->slots[slotid-1].uport->dev ||
+ !xhci->slots[slotid-1].uport->dev->attached) {
return CC_USB_TRANSACTION_ERROR;
}
@@ -2087,6 +2088,14 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
return;
}
+ /* If the device has been detached, but the guest has not noticed this
+ yet the 2 above checks will succeed, but we must NOT continue */
+ if (!xhci->slots[slotid - 1].uport ||
+ !xhci->slots[slotid - 1].uport->dev ||
+ !xhci->slots[slotid - 1].uport->dev->attached) {
+ return;
+ }
+
if (epctx->retry) {
XHCITransfer *xfer = epctx->retry;
@@ -2311,7 +2320,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
trace_usb_xhci_slot_address(slotid, uport->path);
dev = uport->dev;
- if (!dev) {
+ if (!dev || !dev->attached) {
fprintf(stderr, "xhci: port %s not connected\n", uport->path);
return CC_USB_TRANSACTION_ERROR;
}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 5/9] usb-host-libusb: Fill in endpoint max_streams when available
2013-11-19 13:36 [Qemu-devel] [PATCH 0/9] usb: redirection streams support + small fixes Hans de Goede
` (3 preceding siblings ...)
2013-11-19 13:36 ` [Qemu-devel] [PATCH 4/9] xhci: Add a few missing checks for disconnected devices Hans de Goede
@ 2013-11-19 13:37 ` Hans de Goede
2013-11-19 13:37 ` [Qemu-devel] [PATCH 6/9] usb-host-libusb: Add alloc / free streams ops Hans de Goede
` (5 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Hans de Goede @ 2013-11-19 13:37 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Hans de Goede, qemu-devel
Signed-off-by: Hans de Goede <hdegoede@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 fd320cd..0dd60b2 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 >= 0x01000102
+ 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 >= 0x01000102
+ 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.4.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 6/9] usb-host-libusb: Add alloc / free streams ops
2013-11-19 13:36 [Qemu-devel] [PATCH 0/9] usb: redirection streams support + small fixes Hans de Goede
` (4 preceding siblings ...)
2013-11-19 13:37 ` [Qemu-devel] [PATCH 5/9] usb-host-libusb: Fill in endpoint max_streams when available Hans de Goede
@ 2013-11-19 13:37 ` Hans de Goede
2013-11-19 13:37 ` [Qemu-devel] [PATCH 7/9] usb-host-libusb: Set stream id when submitting bulk-stream transfers Hans de Goede
` (4 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Hans de Goede @ 2013-11-19 13:37 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Hans de Goede, qemu-devel
Signed-off-by: Hans de Goede <hdegoede@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 0dd60b2..894875b 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.4.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 7/9] usb-host-libusb: Set stream id when submitting bulk-stream transfers
2013-11-19 13:36 [Qemu-devel] [PATCH 0/9] usb: redirection streams support + small fixes Hans de Goede
` (5 preceding siblings ...)
2013-11-19 13:37 ` [Qemu-devel] [PATCH 6/9] usb-host-libusb: Add alloc / free streams ops Hans de Goede
@ 2013-11-19 13:37 ` Hans de Goede
2013-11-19 13:37 ` [Qemu-devel] [PATCH 8/9] usb-redir: Add support for bulk streams Hans de Goede
` (3 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Hans de Goede @ 2013-11-19 13:37 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Hans de Goede, qemu-devel
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/usb/host-libusb.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index 894875b..3376b96 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -1214,10 +1214,22 @@ 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);
+ return USB_RET_STALL;
+#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.4.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 8/9] usb-redir: Add support for bulk streams
2013-11-19 13:36 [Qemu-devel] [PATCH 0/9] usb: redirection streams support + small fixes Hans de Goede
` (6 preceding siblings ...)
2013-11-19 13:37 ` [Qemu-devel] [PATCH 7/9] usb-host-libusb: Set stream id when submitting bulk-stream transfers Hans de Goede
@ 2013-11-19 13:37 ` Hans de Goede
2013-11-19 13:37 ` [Qemu-devel] [PATCH 9/9] uas: s/ui/iu/ Hans de Goede
` (2 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Hans de Goede @ 2013-11-19 13:37 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Hans de Goede, qemu-devel
Signed-off-by: Hans de Goede <hdegoede@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.4.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH 9/9] uas: s/ui/iu/
2013-11-19 13:36 [Qemu-devel] [PATCH 0/9] usb: redirection streams support + small fixes Hans de Goede
` (7 preceding siblings ...)
2013-11-19 13:37 ` [Qemu-devel] [PATCH 8/9] usb-redir: Add support for bulk streams Hans de Goede
@ 2013-11-19 13:37 ` Hans de Goede
2013-11-20 9:20 ` [Qemu-devel] [PATCH 0/9] usb: redirection streams support + small fixes Gerd Hoffmann
2013-11-21 10:45 ` Gerd Hoffmann
10 siblings, 0 replies; 12+ messages in thread
From: Hans de Goede @ 2013-11-19 13:37 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Hans de Goede, qemu-devel
The various uas data structures are called IU-s, which is short for
Information Unit, rather then UI-s.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/usb/dev-uas.c | 76 ++++++++++++++++++++++++++++----------------------------
1 file changed, 38 insertions(+), 38 deletions(-)
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
index 82a47be..997b715 100644
--- a/hw/usb/dev-uas.c
+++ b/hw/usb/dev-uas.c
@@ -55,7 +55,7 @@ typedef struct {
uint8_t id;
uint8_t reserved;
uint16_t tag;
-} QEMU_PACKED uas_ui_header;
+} QEMU_PACKED uas_iu_header;
typedef struct {
uint8_t prio_taskattr; /* 6:3 priority, 2:0 task attribute */
@@ -65,7 +65,7 @@ typedef struct {
uint64_t lun;
uint8_t cdb[16];
uint8_t add_cdb[];
-} QEMU_PACKED uas_ui_command;
+} QEMU_PACKED uas_iu_command;
typedef struct {
uint16_t status_qualifier;
@@ -73,29 +73,29 @@ typedef struct {
uint8_t reserved[7];
uint16_t sense_length;
uint8_t sense_data[18];
-} QEMU_PACKED uas_ui_sense;
+} QEMU_PACKED uas_iu_sense;
typedef struct {
uint8_t add_response_info[3];
uint8_t response_code;
-} QEMU_PACKED uas_ui_response;
+} QEMU_PACKED uas_iu_response;
typedef struct {
uint8_t function;
uint8_t reserved;
uint16_t task_tag;
uint64_t lun;
-} QEMU_PACKED uas_ui_task_mgmt;
+} QEMU_PACKED uas_iu_task_mgmt;
typedef struct {
- uas_ui_header hdr;
+ uas_iu_header hdr;
union {
- uas_ui_command command;
- uas_ui_sense sense;
- uas_ui_task_mgmt task;
- uas_ui_response response;
+ uas_iu_command command;
+ uas_iu_sense sense;
+ uas_iu_task_mgmt task;
+ uas_iu_response response;
};
-} QEMU_PACKED uas_ui;
+} QEMU_PACKED uas_iu;
/* --------------------------------------------------------------------- */
@@ -145,7 +145,7 @@ struct UASRequest {
struct UASStatus {
uint32_t stream;
- uas_ui status;
+ uas_iu status;
uint32_t length;
QTAILQ_ENTRY(UASStatus) next;
};
@@ -338,7 +338,7 @@ static UASStatus *usb_uas_alloc_status(UASDevice *uas, uint8_t id, uint16_t tag)
st->status.hdr.id = id;
st->status.hdr.tag = cpu_to_be16(tag);
- st->length = sizeof(uas_ui_header);
+ st->length = sizeof(uas_iu_header);
if (uas_using_streams(uas)) {
st->stream = tag;
}
@@ -398,7 +398,7 @@ static void usb_uas_queue_response(UASDevice *uas, uint16_t tag, uint8_t code)
trace_usb_uas_response(uas->dev.addr, tag, code);
st->status.response.response_code = code;
- usb_uas_queue_status(uas, st, sizeof(uas_ui_response));
+ usb_uas_queue_status(uas, st, sizeof(uas_iu_response));
}
static void usb_uas_queue_sense(UASRequest *req, uint8_t status)
@@ -414,7 +414,7 @@ static void usb_uas_queue_sense(UASRequest *req, uint8_t status)
sizeof(st->status.sense.sense_data));
st->status.sense.sense_length = cpu_to_be16(slen);
}
- len = sizeof(uas_ui_sense) - sizeof(st->status.sense.sense_data) + slen;
+ len = sizeof(uas_iu_sense) - sizeof(st->status.sense.sense_data) + slen;
usb_uas_queue_status(req->uas, st, len);
}
@@ -432,7 +432,7 @@ static void usb_uas_queue_fake_sense(UASDevice *uas, uint16_t tag,
st->status.sense.sense_data[12] = sense.asc;
st->status.sense.sense_data[13] = sense.ascq;
slen = 18;
- len = sizeof(uas_ui_sense) - sizeof(st->status.sense.sense_data) + slen;
+ len = sizeof(uas_iu_sense) - sizeof(st->status.sense.sense_data) + slen;
usb_uas_queue_status(uas, st, len);
}
@@ -534,14 +534,14 @@ static void usb_uas_start_next_transfer(UASDevice *uas)
}
}
-static UASRequest *usb_uas_alloc_request(UASDevice *uas, uas_ui *ui)
+static UASRequest *usb_uas_alloc_request(UASDevice *uas, uas_iu *iu)
{
UASRequest *req;
req = g_new0(UASRequest, 1);
req->uas = uas;
- req->tag = be16_to_cpu(ui->hdr.tag);
- req->lun = be64_to_cpu(ui->command.lun);
+ req->tag = be16_to_cpu(iu->hdr.tag);
+ req->lun = be64_to_cpu(iu->command.lun);
req->dev = usb_uas_get_dev(req->uas, req->lun);
return req;
}
@@ -684,11 +684,11 @@ static void usb_uas_cancel_io(USBDevice *dev, USBPacket *p)
assert(!"canceled usb packet not found");
}
-static void usb_uas_command(UASDevice *uas, uas_ui *ui)
+static void usb_uas_command(UASDevice *uas, uas_iu *iu)
{
UASRequest *req;
uint32_t len;
- uint16_t tag = be16_to_cpu(ui->hdr.tag);
+ uint16_t tag = be16_to_cpu(iu->hdr.tag);
if (uas_using_streams(uas) && tag > UAS_MAX_STREAMS) {
goto invalid_tag;
@@ -697,7 +697,7 @@ static void usb_uas_command(UASDevice *uas, uas_ui *ui)
if (req) {
goto overlapped_tag;
}
- req = usb_uas_alloc_request(uas, ui);
+ req = usb_uas_alloc_request(uas, iu);
if (req->dev == NULL) {
goto bad_target;
}
@@ -714,7 +714,7 @@ static void usb_uas_command(UASDevice *uas, uas_ui *ui)
req->req = scsi_req_new(req->dev, req->tag,
usb_uas_get_lun(req->lun),
- ui->command.cdb, req);
+ iu->command.cdb, req);
if (uas->requestlog) {
scsi_req_print(req->req);
}
@@ -738,10 +738,10 @@ bad_target:
g_free(req);
}
-static void usb_uas_task(UASDevice *uas, uas_ui *ui)
+static void usb_uas_task(UASDevice *uas, uas_iu *iu)
{
- uint16_t tag = be16_to_cpu(ui->hdr.tag);
- uint64_t lun64 = be64_to_cpu(ui->task.lun);
+ uint16_t tag = be16_to_cpu(iu->hdr.tag);
+ uint64_t lun64 = be64_to_cpu(iu->task.lun);
SCSIDevice *dev = usb_uas_get_dev(uas, lun64);
int lun = usb_uas_get_lun(lun64);
UASRequest *req;
@@ -750,7 +750,7 @@ static void usb_uas_task(UASDevice *uas, uas_ui *ui)
if (uas_using_streams(uas) && tag > UAS_MAX_STREAMS) {
goto invalid_tag;
}
- req = usb_uas_find_request(uas, be16_to_cpu(ui->hdr.tag));
+ req = usb_uas_find_request(uas, be16_to_cpu(iu->hdr.tag));
if (req) {
goto overlapped_tag;
}
@@ -758,9 +758,9 @@ static void usb_uas_task(UASDevice *uas, uas_ui *ui)
goto incorrect_lun;
}
- switch (ui->task.function) {
+ switch (iu->task.function) {
case UAS_TMF_ABORT_TASK:
- task_tag = be16_to_cpu(ui->task.task_tag);
+ task_tag = be16_to_cpu(iu->task.task_tag);
trace_usb_uas_tmf_abort_task(uas->dev.addr, tag, task_tag);
req = usb_uas_find_request(uas, task_tag);
if (req && req->dev == dev) {
@@ -776,7 +776,7 @@ static void usb_uas_task(UASDevice *uas, uas_ui *ui)
break;
default:
- trace_usb_uas_tmf_unsupported(uas->dev.addr, tag, ui->task.function);
+ trace_usb_uas_tmf_unsupported(uas->dev.addr, tag, iu->task.function);
usb_uas_queue_response(uas, tag, UAS_RC_TMF_NOT_SUPPORTED);
break;
}
@@ -797,25 +797,25 @@ incorrect_lun:
static void usb_uas_handle_data(USBDevice *dev, USBPacket *p)
{
UASDevice *uas = DO_UPCAST(UASDevice, dev, dev);
- uas_ui ui;
+ uas_iu iu;
UASStatus *st;
UASRequest *req;
int length;
switch (p->ep->nr) {
case UAS_PIPE_ID_COMMAND:
- length = MIN(sizeof(ui), p->iov.size);
- usb_packet_copy(p, &ui, length);
- switch (ui.hdr.id) {
+ length = MIN(sizeof(iu), p->iov.size);
+ usb_packet_copy(p, &iu, length);
+ switch (iu.hdr.id) {
case UAS_UI_COMMAND:
- usb_uas_command(uas, &ui);
+ usb_uas_command(uas, &iu);
break;
case UAS_UI_TASK_MGMT:
- usb_uas_task(uas, &ui);
+ usb_uas_task(uas, &iu);
break;
default:
- fprintf(stderr, "%s: unknown command ui: id 0x%x\n",
- __func__, ui.hdr.id);
+ fprintf(stderr, "%s: unknown command iu: id 0x%x\n",
+ __func__, iu.hdr.id);
p->status = USB_RET_STALL;
break;
}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH 0/9] usb: redirection streams support + small fixes
2013-11-19 13:36 [Qemu-devel] [PATCH 0/9] usb: redirection streams support + small fixes Hans de Goede
` (8 preceding siblings ...)
2013-11-19 13:37 ` [Qemu-devel] [PATCH 9/9] uas: s/ui/iu/ Hans de Goede
@ 2013-11-20 9:20 ` Gerd Hoffmann
2013-11-21 10:45 ` Gerd Hoffmann
10 siblings, 0 replies; 12+ messages in thread
From: Gerd Hoffmann @ 2013-11-20 9:20 UTC (permalink / raw)
To: Hans de Goede; +Cc: qemu-devel
On Di, 2013-11-19 at 14:36 +0100, Hans de Goede wrote:
> Hi Gerd,
>
> Here are my outstanding qemu usb patches. Most of them have been send
> before and are just rebases. As before these depend on kernel / libusb
> streams support, which will hopefully go upstream for 3.14 .
Queued thinks up. I think I'll wait with the streams stuff until the
kernel / libusb bits are upstream, the reamining stuff can go earlier.
cheers,
Gerd
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH 0/9] usb: redirection streams support + small fixes
2013-11-19 13:36 [Qemu-devel] [PATCH 0/9] usb: redirection streams support + small fixes Hans de Goede
` (9 preceding siblings ...)
2013-11-20 9:20 ` [Qemu-devel] [PATCH 0/9] usb: redirection streams support + small fixes Gerd Hoffmann
@ 2013-11-21 10:45 ` Gerd Hoffmann
10 siblings, 0 replies; 12+ messages in thread
From: Gerd Hoffmann @ 2013-11-21 10:45 UTC (permalink / raw)
To: Hans de Goede; +Cc: qemu-devel
On Di, 2013-11-19 at 14:36 +0100, Hans de Goede wrote:
> Hi Gerd,
>
> Here are my outstanding qemu usb patches. Most of them have been send
> before and are just rebases. As before these depend on kernel / libusb
> streams support, which will hopefully go upstream for 3.14 .
Dropped usb-host patches (5,6,7). Build fails with old libusbx.
cheers,
Gerd
^ permalink raw reply [flat|nested] 12+ messages in thread