Subject: Re: kern/34070: btconfig: SIOCSBTFLAGS: Resource temporarily
To: Iain Hibbert <plunky@rya-online.net>
From: Matthias Drochner <M.Drochner@fz-juelich.de>
List: netbsd-bugs
Date: 11/27/2006 21:18:27
This is a multipart MIME message.

--==_Exmh_12748434162970
Content-Type: text/plain; charset=us-ascii


plunky@rya-online.net said:
> Not that I can suggest masking such a bug by conforming to a hidden
> magic number (I wonder if 16 is a generally used value) 

I think I have a fix which is not too invasive but still
halfway clean: kill the code which tries to compute the
toggle after a short transfer. To fix it to deal with block
alignment would make it even more expensive; reading
the updated toggle from the descriptor is cheaper imho.
The appended patch makes ubt work as far as I could check
without a device.

best regards
Matthias



--==_Exmh_12748434162970
Content-Type: text/plain ; name="ehci.txt"; charset=us-ascii
Content-Description: ehci.txt
Content-Disposition: attachment; filename="ehci.txt"

# 
# 
# patch "sys/dev/usb/ehci.c"
#  from [9719bcf04cebd0079d8570b78d59c267164aa1d1]
#    to [7ae22e8f8c034f1a4b891e85526ec1e137128a51]
# 
============================================================
--- sys/dev/usb/ehci.c	9719bcf04cebd0079d8570b78d59c267164aa1d1
+++ sys/dev/usb/ehci.c	7ae22e8f8c034f1a4b891e85526ec1e137128a51
@@ -773,7 +773,6 @@ ehci_idone(struct ehci_xfer *ex)
 	ehci_soft_qtd_t *sqtd, *lsqtd;
 	u_int32_t status = 0, nstatus = 0;
 	int actlen;
-	uint pkts_left;
 
 	DPRINTFN(/*12*/2, ("ehci_idone: ex=%p\n", ex));
 #ifdef DIAGNOSTIC
@@ -823,10 +822,13 @@ ehci_idone(struct ehci_xfer *ex)
 	 * If there are left over TDs we need to update the toggle.
 	 * The default pipe doesn't need it since control transfers
 	 * start the toggle at 0 every time.
+	 * For a short transfer we need to update the toggle for the missing
+	 * packets within the qTD.
 	 */
-	if (sqtd != lsqtd->nextqtd &&
+	if ((sqtd != lsqtd->nextqtd || EHCI_QTD_GET_BYTES(status)) &&
 	    xfer->pipe->device->default_pipe != xfer->pipe) {
-		printf("ehci_idone: need toggle update status=%08x nstatus=%08x\n", status, nstatus);
+		DPRINTFN(2, ("ehci_idone: need toggle update "
+			     "status=%08x nstatus=%08x\n", status, nstatus));
 #if 0
 		ehci_dump_sqh(epipe->sqh);
 		ehci_dump_sqtds(ex->sqtdstart);
@@ -834,14 +836,6 @@ ehci_idone(struct ehci_xfer *ex)
 		epipe->nexttoggle = EHCI_QTD_GET_TOGGLE(nstatus);
 	}
 
-	/*
-	 * For a short transfer we need to update the toggle for the missing
-	 * packets within the qTD.
-	 */
-	pkts_left = EHCI_QTD_GET_BYTES(status) /
-	    UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize);
-	epipe->nexttoggle ^= pkts_left % 2;
-
 	DPRINTFN(/*10*/2, ("ehci_idone: len=%d, actlen=%d, status=0x%x\n",
 			   xfer->length, actlen, status));
 	xfer->actlen = actlen;

--==_Exmh_12748434162970--