qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: Juergen Gross <jgross@suse.com>
Cc: qemu-devel@nongnu.org, xen-devel@lists.xensource.com,
	kraxel@redhat.com, stefano.stabellini@eu.citrix.com
Subject: Re: [Qemu-devel] [Xen-devel] [Patch V1 2/3] xen/usb: add capability for passing through isoc jobs to host devices
Date: Tue, 15 Sep 2015 15:17:03 -0400	[thread overview]
Message-ID: <20150915191703.GA10141@l.oracle.com> (raw)
In-Reply-To: <1441277113-30693-3-git-send-email-jgross@suse.com>

On Thu, Sep 03, 2015 at 12:45:12PM +0200, Juergen Gross wrote:
> When Xen is using the qemu usb framework for pure passthrough of I/Os
> to host devices the handling of isoc jobs is rather complicated if
> multiple isoc frames are transferred with one call.
> 
> Instead of calling the framework with each frame individually, using
> timers to avoid polling in a loop and sampling all responses to
> construct a sum response for the user, just add a capability to
> use the libusb isoc framework instead. This capability is selected
> via a device specific property.
> 
> When the property is selected the host usb driver will use xen specific

You mean it will use generic callbacks - but call Xen specific code?

> callbacks to signal the end of isoc I/Os. For now these callbacks will
> just be nops, they'll be filled with sensible actions when the xen
> pv-usb backend is being added.

The PV USB backend being in the QEMU driver?

But this patch by itself will avoid some complex code right?
> 
> Signed-off-by: Juergen Gross <jgross@suse.com>
> ---
>  hw/usb/core.c                | 11 ++++++----
>  hw/usb/host-libusb.c         | 51 ++++++++++++++++++++++++++++++++++++++------
>  include/hw/xen/xen_backend.h |  3 +++
>  3 files changed, 55 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/usb/core.c b/hw/usb/core.c
> index cf34755..ed2255c 100644
> --- a/hw/usb/core.c
> +++ b/hw/usb/core.c
> @@ -427,10 +427,13 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p)
>      if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline || p->stream) {
>          usb_process_one(p);
>          if (p->status == USB_RET_ASYNC) {
> -            /* hcd drivers cannot handle async for isoc */
> -            assert(p->ep->type != USB_ENDPOINT_XFER_ISOC);
> -            /* using async for interrupt packets breaks migration */
> -            assert(p->ep->type != USB_ENDPOINT_XFER_INT ||
> +            /*
> +             * hcd drivers cannot handle async for isoc.
> +             * Using async for interrupt packets breaks migration.
> +             * Host devices are okay in any case.
> +             */
> +            assert((p->ep->type != USB_ENDPOINT_XFER_ISOC &&
> +                    p->ep->type != USB_ENDPOINT_XFER_INT) ||
>                     (dev->flags & (1 << USB_DEV_FLAG_IS_HOST)));
>              usb_packet_set_state(p, USB_PACKET_ASYNC);
>              QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
> diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
> index a5f9dab..ce644c3 100644
> --- a/hw/usb/host-libusb.c
> +++ b/hw/usb/host-libusb.c
> @@ -42,6 +42,7 @@
>  #include "trace.h"
>  
>  #include "hw/usb.h"
> +#include "hw/xen/xen_backend.h"
>  
>  /* ------------------------------------------------------------------------ */
>  
> @@ -64,6 +65,7 @@ struct USBAutoFilter {
>  
>  enum USBHostDeviceOptions {
>      USB_HOST_OPT_PIPELINE,
> +    USB_HOST_XEN_ISO_PASSTHROUGH,
>  };
>  
>  struct USBHostDevice {
> @@ -152,6 +154,7 @@ static void usb_host_attach_kernel(USBHostDevice *s);
>  #define CONTROL_TIMEOUT  10000        /* 10 sec    */
>  #define BULK_TIMEOUT         0        /* unlimited */
>  #define INTR_TIMEOUT         0        /* unlimited */
> +#define ISO_TIMEOUT          0        /* unlimited */
>  
>  #if LIBUSBX_API_VERSION >= 0x01000103
>  # define HAVE_STREAMS 1
> @@ -306,14 +309,14 @@ static bool usb_host_use_combining(USBEndpoint *ep)
>  /* ------------------------------------------------------------------------ */
>  
>  static USBHostRequest *usb_host_req_alloc(USBHostDevice *s, USBPacket *p,
> -                                          bool in, size_t bufsize)
> +                                          bool in, size_t bufsize, int packets)
>  {
>      USBHostRequest *r = g_new0(USBHostRequest, 1);
>  
>      r->host = s;
>      r->p = p;
>      r->in = in;
> -    r->xfer = libusb_alloc_transfer(0);
> +    r->xfer = libusb_alloc_transfer(packets);
>      if (bufsize) {
>          r->buffer = g_malloc(bufsize);
>      }
> @@ -376,6 +379,29 @@ out:
>      }
>  }
>  
> +static void usb_host_req_complete_iso_xen(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];
> +    trace_usb_host_req_complete(s->bus_num, s->addr, r->p,
> +                                r->p->status, r->p->actual_length);
> +    /* copying of buffer is done in complete callback of xen */
> +    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_complete_data(struct libusb_transfer *xfer)
>  {
>      USBHostRequest *r = xfer->user_data;
> @@ -1226,7 +1252,7 @@ static void usb_host_handle_control(USBDevice *udev, USBPacket *p,
>          }
>      }
>  
> -    r = usb_host_req_alloc(s, p, (request >> 8) & USB_DIR_IN, length + 8);
> +    r = usb_host_req_alloc(s, p, (request >> 8) & USB_DIR_IN, length + 8, 0);
>      r->cbuf = data;
>      r->clen = length;
>      memcpy(r->buffer, udev->setup_buf, 8);
> @@ -1264,7 +1290,7 @@ static void usb_host_handle_data(USBDevice *udev, USBPacket *p)
>      USBHostDevice *s = USB_HOST_DEVICE(udev);
>      USBHostRequest *r;
>      size_t size;
> -    int ep, rc;
> +    int ep, rc, packets;
>  
>      if (usb_host_use_combining(p->ep) && p->state == USB_PACKET_SETUP) {
>          p->status = USB_RET_ADD_TO_QUEUE;
> @@ -1289,7 +1315,7 @@ static void usb_host_handle_data(USBDevice *udev, USBPacket *p)
>      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);
> +        r = usb_host_req_alloc(s, p, p->pid == USB_TOKEN_IN, size, 0);
>          if (!r->in) {
>              usb_packet_copy(p, r->buffer, size);
>          }
> @@ -1313,7 +1339,7 @@ static void usb_host_handle_data(USBDevice *udev, USBPacket *p)
>          }
>          break;
>      case USB_ENDPOINT_XFER_INT:
> -        r = usb_host_req_alloc(s, p, p->pid == USB_TOKEN_IN, p->iov.size);
> +        r = usb_host_req_alloc(s, p, p->pid == USB_TOKEN_IN, p->iov.size, 0);
>          if (!r->in) {
>              usb_packet_copy(p, r->buffer, p->iov.size);
>          }
> @@ -1324,6 +1350,17 @@ static void usb_host_handle_data(USBDevice *udev, USBPacket *p)
>                                         INTR_TIMEOUT);
>          break;
>      case USB_ENDPOINT_XFER_ISOC:
> +        if (s->options & (1 << USB_HOST_XEN_ISO_PASSTHROUGH)) {
> +            packets = usbback_get_packets(p);
> +            r = usb_host_req_alloc(s, p, p->pid == USB_TOKEN_IN, p->iov.size,
> +                                   packets);
> +            ep = p->ep->nr | (r->in ? USB_DIR_IN : 0);
> +            libusb_fill_iso_transfer(r->xfer, s->dh, ep, r->buffer, p->iov.size,
> +                                     packets, usb_host_req_complete_iso_xen, r,
> +                                     ISO_TIMEOUT);
> +            usbback_set_iso_desc(p, r->xfer);
> +            break;
> +        }
>          if (p->pid == USB_TOKEN_IN) {
>              usb_host_iso_data_in(s, p);
>          } else {
> @@ -1484,6 +1521,8 @@ static Property usb_host_dev_properties[] = {
>                         LIBUSB_LOG_LEVEL_WARNING),
>      DEFINE_PROP_BIT("pipeline",    USBHostDevice, options,
>                      USB_HOST_OPT_PIPELINE, true),
> +    DEFINE_PROP_BIT("xen-iso-passthrough", USBHostDevice, options,
> +                    USB_HOST_XEN_ISO_PASSTHROUGH, false),
>      DEFINE_PROP_END_OF_LIST(),
>  };
>  
> diff --git a/include/hw/xen/xen_backend.h b/include/hw/xen/xen_backend.h
> index 911ba6d..f194aae 100644
> --- a/include/hw/xen/xen_backend.h
> +++ b/include/hw/xen/xen_backend.h
> @@ -55,6 +55,9 @@ struct XenDevice {
>  
>  /* ------------------------------------------------------------- */
>  
> +#define usbback_get_packets(p) 0
> +#define usbback_set_iso_desc(p, xfer)
> +
>  /* variables */
>  extern XenXC xen_xc;
>  extern struct xs_handle *xenstore;
> -- 
> 2.1.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

  parent reply	other threads:[~2015-09-15 19:17 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-03 10:45 [Qemu-devel] [Patch V1 0/3] usb, xen: add pvUSB backend Juergen Gross
2015-09-03 10:45 ` [Qemu-devel] [Patch V1 1/3] xen: introduce dummy system device Juergen Gross
2015-09-07 15:29   ` Stefano Stabellini
2015-09-09 11:01     ` [Qemu-devel] [Xen-devel] " Juergen Gross
2015-09-03 10:45 ` [Qemu-devel] [Patch V1 2/3] xen/usb: add capability for passing through isoc jobs to host devices Juergen Gross
2015-09-04 13:25   ` Gerd Hoffmann
2015-09-09 11:37     ` Juergen Gross
2015-09-09 12:01       ` Gerd Hoffmann
2015-09-09 13:10         ` Juergen Gross
2015-09-09 14:43           ` Gerd Hoffmann
2015-09-15 19:17   ` Konrad Rzeszutek Wilk [this message]
2015-09-03 10:45 ` [Qemu-devel] [Patch V1 3/3] xen: add pvUSB backend Juergen Gross
2015-09-07 17:38   ` Stefano Stabellini
2015-09-09 11:22     ` [Qemu-devel] [Xen-devel] " Juergen Gross
2015-09-09 13:13       ` Stefano Stabellini
2015-10-27 18:54   ` Konrad Rzeszutek Wilk
2016-03-07 12:43     ` Juergen Gross

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150915191703.GA10141@l.oracle.com \
    --to=konrad.wilk@oracle.com \
    --cc=jgross@suse.com \
    --cc=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).