PERFORCE change 157296 for review

Hans Petter Selasky hselasky at FreeBSD.org
Fri Feb 6 11:45:16 PST 2009


http://perforce.freebsd.org/chv.cgi?CH=157296

Change 157296 by hselasky at 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 */


More information about the p4-projects mailing list