PERFORCE change 126783 for review

Hans Petter Selasky hselasky at FreeBSD.org
Mon Sep 24 12:50:59 PDT 2007


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

Change 126783 by hselasky at hselasky_laptop001 on 2007/09/24 19:50:31

	
	- Small bugfix; "ehci_non_isoc_done()" should terminate scanning of transfer
	  descriptors when a short USB frame is found if "flags_int.short_frames_ok"
	  is not set. "ehci_non_isoc_done_sub()" signals this condition by clearing
	  "xfer->td_transfer_cache" before it returns.
	
	- Remove "xfer->aframes" fixup in case of error for control transfers.
	  Usually one should not rely on "xfer->actlen" nor "xfer->aframes" in case
	  of error except for debugging purposes. This saves some code, and makes
	  the algorithm more straight forward. Already the USB transfer descriptor
	  scanning algorithm is pretty complicated.
	
	- NOTE: The EHCI transfer descriptor scanning model will now be used as an
	  example for the UHCI and OHCI transfer descriptor scanning models. By
	  doing this the code will look 90% the same and consequently understanding
	  it will be easier and less time consuming.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/ehci.c#38 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/ehci.c#38 (text+ko) ====

@@ -1093,7 +1093,7 @@
 
 	    /*
 	     * Verify the status length and subtract
-	     * the remainderfrom "frlengths[]":
+	     * the remainder from "frlengths[]":
 	     */
 	    if (len > td->len) {
 	        /* should not happen */
@@ -1122,20 +1122,27 @@
 
 	    /* Check for transfer error */
 	    if (status & EHCI_QTD_HALTED) {
+		/* the transfer is finished */
 	        td = NULL;
 	        break;
 	    }
 
 	    /* Check for short transfer */
 	    if (len > 0) {
-		td = td->alt_next;
+		if (xfer->flags_int.short_frames_ok) {
+		    /* follow alt next */
+		    td = td->alt_next;
+		} else {
+		    /* the transfer is finished */
+		    td = NULL;
+		}
 		break;
 	    }
 
 	    td = td->obj_next;
 
 	    if (td->alt_next != td_alt_next) {
-		/* we are finished */
+		/* this USB frame is complete */
 		break;
 	    }
 	}
@@ -1177,11 +1184,11 @@
 
 	    status = ehci_non_isoc_done_sub(xfer);
 
-	    if (status & EHCI_QTD_HALTED) {
+	    xfer->aframes = 1;
+
+	    if (xfer->td_transfer_cache == NULL) {
 	        goto done;
 	    }
-
-	    xfer->aframes = 1;
 	}
 
 	while (xfer->aframes != xfer->nframes) {
@@ -1190,26 +1197,19 @@
 		(xfer->frlengths[xfer->aframes] > 0)) {
 
 	        status = ehci_non_isoc_done_sub(xfer);
-
-		if (status & EHCI_QTD_HALTED) {
-		    goto done;
-		}
 	    }
 
 	    xfer->aframes ++;
+
+	    if (xfer->td_transfer_cache == NULL) {
+	        goto done;
+	    }
 	}
 
 	if (xfer->flags_int.control_xfr &&
 	    !xfer->flags_int.control_act) {
 
 	    status = ehci_non_isoc_done_sub(xfer);
-
-	    if (status & EHCI_QTD_HALTED) {
-	        if (xfer->frlengths[xfer->nframes-1] == 0) {
-		    xfer->aframes--;
-		}
-		goto done;
-	    }
 	}
 
  done:


More information about the p4-projects mailing list