Date: Mon, 24 Sep 2007 19:50:58 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 126783 for review Message-ID: <200709241950.l8OJowC6002507@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=126783 Change 126783 by hselasky@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200709241950.l8OJowC6002507>