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--