From owner-svn-src-user@FreeBSD.ORG Fri Feb 6 22:40:16 2009 Return-Path: <owner-svn-src-user@FreeBSD.ORG> Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2DDB0106566B; Fri, 6 Feb 2009 22:40:16 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 023E98FC1F; Fri, 6 Feb 2009 22:40:16 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n16MeF06073341; Fri, 6 Feb 2009 22:40:15 GMT (envelope-from thompsa@svn.freebsd.org) Received: (from thompsa@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n16MeFAZ073339; Fri, 6 Feb 2009 22:40:15 GMT (envelope-from thompsa@svn.freebsd.org) Message-Id: <200902062240.n16MeFAZ073339@svn.freebsd.org> From: Andrew Thompson <thompsa@FreeBSD.org> Date: Fri, 6 Feb 2009 22:40:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r188252 - user/thompsa/usb/sys/dev/usb2/controller X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" <svn-src-user.freebsd.org> List-Unsubscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-user>, <mailto:svn-src-user-request@freebsd.org?subject=unsubscribe> List-Archive: <http://lists.freebsd.org/pipermail/svn-src-user> List-Post: <mailto:svn-src-user@freebsd.org> List-Help: <mailto:svn-src-user-request@freebsd.org?subject=help> List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-user>, <mailto:svn-src-user-request@freebsd.org?subject=subscribe> X-List-Received-Date: Fri, 06 Feb 2009 22:40:16 -0000 Author: thompsa Date: Fri Feb 6 22:40:15 2009 New Revision: 188252 URL: http://svn.freebsd.org/changeset/base/188252 Log: Fix OHCI and EHCI counting bug when multiple TD's are involved in a short USB transfer and a short packet happens on the non-last TD in the USB transfer frame. Submitted by: Hans Petter Selasky Modified: user/thompsa/usb/sys/dev/usb2/controller/ehci2.c user/thompsa/usb/sys/dev/usb2/controller/ohci2.c Modified: user/thompsa/usb/sys/dev/usb2/controller/ehci2.c ============================================================================== --- user/thompsa/usb/sys/dev/usb2/controller/ehci2.c Fri Feb 6 22:24:03 2009 (r188251) +++ user/thompsa/usb/sys/dev/usb2/controller/ehci2.c Fri Feb 6 22:40:15 2009 (r188252) @@ -1144,6 +1144,9 @@ ehci_non_isoc_done_sub(struct usb2_xfer td = xfer->td_transfer_cache; td_alt_next = td->alt_next; + if (xfer->aframes != xfer->nframes) { + xfer->frlengths[xfer->aframes] = 0; + } while (1) { usb2_pc_cpu_invalidate(td->page_cache); @@ -1152,8 +1155,8 @@ ehci_non_isoc_done_sub(struct usb2_xfer len = EHCI_QTD_GET_BYTES(status); /* - * Verify the status length and subtract - * the remainder from "frlengths[]": + * Verify the status length and + * add the length to "frlengths[]": */ if (len > td->len) { /* should not happen */ @@ -1161,7 +1164,7 @@ ehci_non_isoc_done_sub(struct usb2_xfer "0x%04x/0x%04x bytes\n", len, td->len); status |= EHCI_QTD_HALTED; } else if (xfer->aframes != xfer->nframes) { - xfer->frlengths[xfer->aframes] -= len; + xfer->frlengths[xfer->aframes] += td->len - len; } /* Check for last transfer */ if (((void *)td) == xfer->td_transfer_last) { Modified: user/thompsa/usb/sys/dev/usb2/controller/ohci2.c ============================================================================== --- user/thompsa/usb/sys/dev/usb2/controller/ohci2.c Fri Feb 6 22:24:03 2009 (r188251) +++ user/thompsa/usb/sys/dev/usb2/controller/ohci2.c Fri Feb 6 22:40:15 2009 (r188252) @@ -836,6 +836,9 @@ ohci_non_isoc_done_sub(struct usb2_xfer td_alt_next = td->alt_next; td_flags = 0; + if (xfer->aframes != xfer->nframes) { + xfer->frlengths[xfer->aframes] = 0; + } while (1) { usb2_pc_cpu_invalidate(td->page_cache); @@ -859,10 +862,15 @@ ohci_non_isoc_done_sub(struct usb2_xfer cc = OHCI_CC_STALL; } else if (xfer->aframes != xfer->nframes) { /* - * subtract remaining length from - * "frlengths[]" + * Sum up total transfer length + * in "frlengths[]": */ - xfer->frlengths[xfer->aframes] -= temp; + xfer->frlengths[xfer->aframes] += td->len - temp; + } + } else{ + if (xfer->aframes != xfer->nframes) { + /* transfer was complete */ + xfer->frlengths[xfer->aframes] += td->len; } } /* Check for last transfer */