From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KWSrP-0006qr-7v for qemu-devel@nongnu.org; Fri, 22 Aug 2008 05:23:11 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KWSrN-0006p5-UK for qemu-devel@nongnu.org; Fri, 22 Aug 2008 05:23:10 -0400 Received: from [199.232.76.173] (port=57760 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KWSrN-0006oe-J9 for qemu-devel@nongnu.org; Fri, 22 Aug 2008 05:23:09 -0400 Received: from savannah.gnu.org ([199.232.41.3]:35235 helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1KWSrN-00066I-H6 for qemu-devel@nongnu.org; Fri, 22 Aug 2008 05:23:09 -0400 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.63) (envelope-from ) id 1KWSrM-0006is-A5 for qemu-devel@nongnu.org; Fri, 22 Aug 2008 09:23:08 +0000 Received: from aurel32 by cvs.savannah.gnu.org with local (Exim 4.63) (envelope-from ) id 1KWSrL-0006io-RN for qemu-devel@nongnu.org; Fri, 22 Aug 2008 09:23:08 +0000 MIME-Version: 1.0 Errors-To: aurel32 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Aurelien Jarno Message-Id: Date: Fri, 22 Aug 2008 09:23:07 +0000 Subject: [Qemu-devel] [5072] uhci: improved TD matching, working ISOC transfers Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Revision: 5072 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5072 Author: aurel32 Date: 2008-08-22 09:23:06 +0000 (Fri, 22 Aug 2008) Log Message: ----------- uhci: improved TD matching, working ISOC transfers While trying to make VX-3000 camera work on XP under KVM I realized that we do not necessarily have to find original TD address. All we care about is the token which identifies the transfer rather well (direction, endpoint, size, etc). This is especially important for the isochronous transfers because otherwise they are being canceled left and right and we do not make much progress. With this patch all devices that used bulk transfers that I've tried so far continue to work just as well. And now my USB web cammera (isoc transfers) is working well tool. It's not as smooth as native Windows but it's pretty darn smooth. The cool thing is that new USB code (both usb-uhci and usb-linux) is totaly generic and does not need any special logic for ISOC. Signed-off-by: Max Krasnyansky Signed-off-by: Aurelien Jarno Modified Paths: -------------- trunk/hw/usb-uhci.c Modified: trunk/hw/usb-uhci.c =================================================================== --- trunk/hw/usb-uhci.c 2008-08-22 09:03:17 UTC (rev 5071) +++ trunk/hw/usb-uhci.c 2008-08-22 09:23:06 UTC (rev 5072) @@ -265,25 +265,41 @@ static UHCIAsync *uhci_async_find_td(UHCIState *s, uint32_t addr, uint32_t token) { UHCIAsync *async = s->async_pending; + UHCIAsync *match = NULL; + int count = 0; + /* + * We're looking for the best match here. ie both td addr and token. + * Otherwise we return last good match. ie just token. + * It's ok to match just token because it identifies the transaction + * rather well, token includes: device addr, endpoint, size, etc. + * + * Also since we queue async transactions in reverse order by returning + * last good match we restores the order. + * + * It's expected that we wont have a ton of outstanding transactions. + * If we ever do we'd want to optimize this algorithm. + */ + while (async) { - if (async->td == addr) { - if (async->token == token) - return async; + if (async->token == token) { + /* Good match */ + match = async; - /* - * TD was reused for a different transfer. - * Invalidate the original one asap. - */ - if (async->valid > 0) { - async->valid = 0; - dprintf("husb: bad reuse. td 0x%x\n", async->td); + if (async->td == addr) { + /* Best match */ + break; } } async = async->next; + count++; } - return NULL; + + if (count > 64) + fprintf(stderr, "uhci: warning lots of async transactions\n"); + + return match; } static void uhci_attach(USBPort *port1, USBDevice *dev);