From mboxrd@z Thu Jan 1 00:00:00 1970 From: Max Krasnyansky Subject: [PATCH] uhci: Fixed length handling for SETUP and OUT tokens Date: Fri, 22 Aug 2008 05:54:31 +0000 Message-ID: <1219384471-6335-1-git-send-email-maxk@kernel.org> Cc: kvm@vger.kernel.org, aurelien@aurel32.net, Max Krasnyansky To: anthony@codemonkey.ws, qemu-devel@nongnu.org Return-path: Received: from hera.kernel.org ([140.211.167.34]:44663 "EHLO hera.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752427AbYHVFyv (ORCPT ); Fri, 22 Aug 2008 01:54:51 -0400 Sender: kvm-owner@vger.kernel.org List-ID: Fixes regression reported agains Linux 2.6.18. Looks like XP and newer Linux kernels are less sensitive to length returned for control transfers. Signed-off-by: Max Krasnyansky --- hw/usb-uhci.c | 19 ++++++++++--------- 1 files changed, 10 insertions(+), 9 deletions(-) diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c index 0714520..86b4696 100644 --- a/hw/usb-uhci.c +++ b/hw/usb-uhci.c @@ -651,7 +651,7 @@ static int uhci_broadcast_packet(UHCIState *s, USBPacket *p) dprintf("uhci: packet enter. pid %s addr 0x%02x ep %d len %d\n", pid2str(p->pid), p->devaddr, p->devep, p->len); - if (p->pid == USB_TOKEN_OUT) + if (p->pid == USB_TOKEN_OUT || p->pid == USB_TOKEN_SETUP) dump_data(p->data, p->len); ret = USB_RET_NODEV; @@ -771,7 +771,7 @@ out: static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *int_mask) { UHCIAsync *async; - int len = 0, max_len, ret = 0; + int len = 0, max_len; uint8_t pid; /* Is active ? */ @@ -814,12 +814,13 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in case USB_TOKEN_OUT: case USB_TOKEN_SETUP: cpu_physical_memory_read(td->buffer, async->buffer, max_len); - ret = uhci_broadcast_packet(s, &async->packet); - len = max_len; + len = uhci_broadcast_packet(s, &async->packet); + if (len >= 0) + len = max_len; break; case USB_TOKEN_IN: - ret = uhci_broadcast_packet(s, &async->packet); + len = uhci_broadcast_packet(s, &async->packet); break; default: @@ -830,17 +831,17 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in return -1; } - if (ret == USB_RET_ASYNC) { + if (len == USB_RET_ASYNC) { uhci_async_link(s, async); return 2; } - async->packet.len = ret; + async->packet.len = len; done: - ret = uhci_complete_td(s, td, async, int_mask); + len = uhci_complete_td(s, td, async, int_mask); uhci_async_free(s, async); - return ret; + return len; } static void uhci_async_complete(USBPacket *packet, void *opaque) -- 1.5.5.1