From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:60877) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S5GYx-0005gA-Qm for qemu-devel@nongnu.org; Wed, 07 Mar 2012 08:06:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S5GYb-0008G9-9m for qemu-devel@nongnu.org; Wed, 07 Mar 2012 08:05:51 -0500 Received: from mx1.redhat.com ([209.132.183.28]:54669) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S5GYb-0008F8-24 for qemu-devel@nongnu.org; Wed, 07 Mar 2012 08:05:29 -0500 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q27D5Rut003688 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 7 Mar 2012 08:05:27 -0500 From: Gerd Hoffmann Date: Wed, 7 Mar 2012 14:05:16 +0100 Message-Id: <1331125520-13467-17-git-send-email-kraxel@redhat.com> In-Reply-To: <1331125520-13467-1-git-send-email-kraxel@redhat.com> References: <1331125520-13467-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PATCH 16/20] usb: add pipelining option to usb endpoints List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Gerd Hoffmann With this patch applied USB drivers can enable pipelining per endpoint. With pipelining enabled the usb core will continue submitting packets even when there are still async transfers in flight instead of passing them on one by one. Signed-off-by: Gerd Hoffmann --- hw/usb.c | 11 ++++++++++- hw/usb.h | 2 ++ 2 files changed, 12 insertions(+), 1 deletions(-) diff --git a/hw/usb.c b/hw/usb.c index fc41d62..800d912 100644 --- a/hw/usb.c +++ b/hw/usb.c @@ -323,7 +323,7 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p) assert(p->state == USB_PACKET_SETUP); assert(p->ep != NULL); - if (QTAILQ_EMPTY(&p->ep->queue)) { + if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline) { ret = usb_process_one(p); if (ret == USB_RET_ASYNC) { usb_packet_set_state(p, USB_PACKET_ASYNC); @@ -468,6 +468,7 @@ void usb_ep_init(USBDevice *dev) dev->ep_ctl.type = USB_ENDPOINT_XFER_CONTROL; dev->ep_ctl.ifnum = 0; dev->ep_ctl.dev = dev; + dev->ep_ctl.pipeline = false; QTAILQ_INIT(&dev->ep_ctl.queue); for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) { dev->ep_in[ep].nr = ep + 1; @@ -480,6 +481,8 @@ void usb_ep_init(USBDevice *dev) dev->ep_out[ep].ifnum = 0; dev->ep_in[ep].dev = dev; dev->ep_out[ep].dev = dev; + dev->ep_in[ep].pipeline = false; + dev->ep_out[ep].pipeline = false; QTAILQ_INIT(&dev->ep_in[ep].queue); QTAILQ_INIT(&dev->ep_out[ep].queue); } @@ -593,3 +596,9 @@ int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep) struct USBEndpoint *uep = usb_ep_get(dev, pid, ep); return uep->max_packet_size; } + +void usb_ep_set_pipeline(USBDevice *dev, int pid, int ep, bool enabled) +{ + struct USBEndpoint *uep = usb_ep_get(dev, pid, ep); + uep->pipeline = enabled; +} diff --git a/hw/usb.h b/hw/usb.h index 1a30ebb..f6df0ad 100644 --- a/hw/usb.h +++ b/hw/usb.h @@ -177,6 +177,7 @@ struct USBEndpoint { uint8_t type; uint8_t ifnum; int max_packet_size; + bool pipeline; USBDevice *dev; QTAILQ_HEAD(, USBPacket) queue; }; @@ -364,6 +365,7 @@ 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_pipeline(USBDevice *dev, int pid, int ep, bool enabled); void usb_attach(USBPort *port); void usb_detach(USBPort *port); -- 1.7.1