From patchwork Tue Nov 6 14:08:20 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: 197484 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 6FEB12C0094 for ; Wed, 7 Nov 2012 01:35:51 +1100 (EST) Received: from localhost ([::1]:56676 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TVjpG-0006yl-Aa for incoming@patchwork.ozlabs.org; Tue, 06 Nov 2012 09:08:22 -0500 Received: from eggs.gnu.org ([208.118.235.92]:40870) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TVjof-0005TP-HD for qemu-devel@nongnu.org; Tue, 06 Nov 2012 09:07:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TVjoZ-00058S-EY for qemu-devel@nongnu.org; Tue, 06 Nov 2012 09:07:45 -0500 Received: from mx1.redhat.com ([209.132.183.28]:57966) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TVjoZ-00058E-6R for qemu-devel@nongnu.org; Tue, 06 Nov 2012 09:07:39 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qA6E7cfj011120 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 6 Nov 2012 09:07:38 -0500 Received: from localhost.localdomain.com (ovpn-112-29.ams2.redhat.com [10.36.112.29]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id qA6E7MeL012920; Tue, 6 Nov 2012 09:07:37 -0500 From: Hans de Goede To: Gerd Hoffmann Date: Tue, 6 Nov 2012 15:08:20 +0100 Message-Id: <1352210901-1923-8-git-send-email-hdegoede@redhat.com> In-Reply-To: <1352210901-1923-1-git-send-email-hdegoede@redhat.com> References: <1352210901-1923-1-git-send-email-hdegoede@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 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 7/8] usb-hid: Move from NAK/polling to async packet handling 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 Signed-off-by: Hans de Goede --- hw/usb/dev-hid.c | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c index aa59ec4..69f89ff 100644 --- a/hw/usb/dev-hid.c +++ b/hw/usb/dev-hid.c @@ -45,6 +45,7 @@ typedef struct USBHIDState { USBDevice dev; USBEndpoint *intr; + USBPacket *async_packet_pending; HIDState hid; } USBHIDState; @@ -357,10 +358,30 @@ static const uint8_t qemu_keyboard_hid_report_descriptor[] = { 0xc0, /* End Collection */ }; +static void usb_data_in_complete(HIDState *hs, USBPacket *p) +{ + uint8_t buf[p->iov.size]; + int len = 0; + + hid_set_next_idle(hs); + if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) { + len = hid_pointer_poll(hs, buf, p->iov.size); + } else if (hs->kind == HID_KEYBOARD) { + len = hid_keyboard_poll(hs, buf, p->iov.size); + } + usb_packet_copy(p, buf, len); +} + static void usb_hid_changed(HIDState *hs) { USBHIDState *us = container_of(hs, USBHIDState, hid); + if (us->async_packet_pending) { + us->async_packet_pending->status = USB_RET_SUCCESS; /* Clear ASYNC */ + usb_data_in_complete(hs, us->async_packet_pending); + usb_packet_complete(&us->dev, us->async_packet_pending); + us->async_packet_pending = NULL; + } usb_wakeup(us->intr); } @@ -455,8 +476,6 @@ static void usb_hid_handle_data(USBDevice *dev, USBPacket *p) { USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev); HIDState *hs = &us->hid; - uint8_t buf[p->iov.size]; - int len = 0; switch (p->pid) { case USB_TOKEN_IN: @@ -465,16 +484,12 @@ static void usb_hid_handle_data(USBDevice *dev, USBPacket *p) hid_pointer_activate(hs); } if (!hid_has_events(hs)) { - p->status = USB_RET_NAK; + assert(us->async_packet_pending == NULL); + us->async_packet_pending = p; + p->status = USB_RET_ASYNC; return; } - hid_set_next_idle(hs); - if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) { - len = hid_pointer_poll(hs, buf, p->iov.size); - } else if (hs->kind == HID_KEYBOARD) { - len = hid_keyboard_poll(hs, buf, p->iov.size); - } - usb_packet_copy(p, buf, len); + usb_data_in_complete(hs, p); } else { goto fail; } @@ -487,6 +502,14 @@ static void usb_hid_handle_data(USBDevice *dev, USBPacket *p) } } +static void usb_hid_cancel_packet(USBDevice *dev, USBPacket *p) +{ + USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev); + + assert(us->async_packet_pending == p); + us->async_packet_pending = NULL; +} + static void usb_hid_handle_destroy(USBDevice *dev) { USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev); @@ -560,6 +583,7 @@ static void usb_hid_class_initfn(ObjectClass *klass, void *data) uc->handle_control = usb_hid_handle_control; uc->handle_data = usb_hid_handle_data; uc->handle_destroy = usb_hid_handle_destroy; + uc->cancel_packet = usb_hid_cancel_packet; } static void usb_tablet_class_initfn(ObjectClass *klass, void *data)