From patchwork Sat Nov 17 11:47:15 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 199838 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 74F8A2C0085 for ; Sat, 17 Nov 2012 22:46:28 +1100 (EST) Received: from localhost ([::1]:38608 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TZgqw-0008P6-Lk for incoming@patchwork.ozlabs.org; Sat, 17 Nov 2012 06:46:26 -0500 Received: from eggs.gnu.org ([208.118.235.92]:50335) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TZgq1-00065X-C9 for qemu-devel@nongnu.org; Sat, 17 Nov 2012 06:45:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TZgpy-000652-AA for qemu-devel@nongnu.org; Sat, 17 Nov 2012 06:45:29 -0500 Received: from mx1.redhat.com ([209.132.183.28]:7590) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TZgpy-00064w-13 for qemu-devel@nongnu.org; Sat, 17 Nov 2012 06:45:26 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qAHBjNCN005758 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Sat, 17 Nov 2012 06:45:25 -0500 Received: from shalem.localdomain.com (vpn1-5-33.ams2.redhat.com [10.36.5.33]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id qAHBjJM7009872; Sat, 17 Nov 2012 06:45:22 -0500 From: Hans de Goede To: Gerd Hoffmann Date: Sat, 17 Nov 2012 12:47:15 +0100 Message-Id: <1353152838-26886-3-git-send-email-hdegoede@redhat.com> In-Reply-To: <1353152838-26886-1-git-send-email-hdegoede@redhat.com> References: <1353152838-26886-1-git-send-email-hdegoede@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Hans de Goede , qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH 2/5] usb: Don't allow USB_RET_ASYNC for interrupt packets X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org It is tempting to use USB_RET_ASYNC for interrupt packets, rather then the current NAK + polling approach, but this causes issues for migration, as an async completed packet will not getting written back to guest memory until the next poll time, and if a migration happens in between it will get lost! Make an exception for host devices, because: 1) host-linux actually uses async completion for interrupt endpoints 2) host devices don't migrate anyways Ideally we would convert host-linux.c to handle (input) interrupt endpoints in a buffered manner like it does for isoc endpoints, keeping multiple urbs submitted to ensure the devices timing requirements are met, as well as making its interrupt ep handling the same as other usb-devices. Signed-off-by: Hans de Goede --- hw/usb.h | 1 + hw/usb/core.c | 4 ++++ hw/usb/host-bsd.c | 1 + hw/usb/host-linux.c | 1 + 4 files changed, 7 insertions(+) diff --git a/hw/usb.h b/hw/usb.h index 7d6de69..58f812f 100644 --- a/hw/usb.h +++ b/hw/usb.h @@ -197,6 +197,7 @@ struct USBEndpoint { enum USBDeviceFlags { USB_DEV_FLAG_FULL_PATH, + USB_DEV_FLAG_IS_HOST, }; /* definition of a USB device */ diff --git a/hw/usb/core.c b/hw/usb/core.c index 52b5310..8e360d3 100644 --- a/hw/usb/core.c +++ b/hw/usb/core.c @@ -406,7 +406,11 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p) if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline) { 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 || + (dev->flags & USB_DEV_FLAG_IS_HOST)); usb_packet_set_state(p, USB_PACKET_ASYNC); QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue); } else if (p->status == USB_RET_ADD_TO_QUEUE) { diff --git a/hw/usb/host-bsd.c b/hw/usb/host-bsd.c index 6473e8b..dae0009 100644 --- a/hw/usb/host-bsd.c +++ b/hw/usb/host-bsd.c @@ -292,6 +292,7 @@ static void usb_host_handle_destroy(USBDevice *opaque) static int usb_host_initfn(USBDevice *dev) { + dev->flags |= (1 << USB_DEV_FLAG_IS_HOST); return 0; } diff --git a/hw/usb/host-linux.c b/hw/usb/host-linux.c index aa77b77..bdafb6b 100644 --- a/hw/usb/host-linux.c +++ b/hw/usb/host-linux.c @@ -1476,6 +1476,7 @@ static int usb_host_initfn(USBDevice *dev) { USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev); + dev->flags |= (1 << USB_DEV_FLAG_IS_HOST); dev->auto_attach = 0; s->fd = -1; s->hub_fd = -1;