Date: Fri, 6 Feb 2009 19:45:10 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 157296 for review Message-ID: <200902061945.n16JjABv012002@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=157296 Change 157296 by hselasky@hselasky_laptop001 on 2009/02/06 19:44:23 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. Fix by: HPS Reported by: Andrew Thompson Affected files ... .. //depot/projects/usb/src/sys/dev/usb2/controller/ehci2.c#30 edit .. //depot/projects/usb/src/sys/dev/usb2/controller/ohci2.c#27 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb2/controller/ehci2.c#30 (text+ko) ==== @@ -1145,6 +1145,9 @@ 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); @@ -1153,8 +1156,8 @@ 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 */ @@ -1162,7 +1165,7 @@ "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) { ==== //depot/projects/usb/src/sys/dev/usb2/controller/ohci2.c#27 (text+ko) ==== @@ -838,6 +838,9 @@ 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); @@ -861,10 +864,15 @@ 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 */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200902061945.n16JjABv012002>