Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb Fix the error check on completion of an xfer. J...
details: https://anonhg.NetBSD.org/src/rev/ef2415e96918
branches: trunk
changeset: 580622:ef2415e96918
user: augustss <augustss%NetBSD.org@localhost>
date: Sun May 01 19:24:39 2005 +0000
description:
Fix the error check on completion of an xfer. Just because the qTD status
field has error bits set doesn't mean there has been an error, unless the
HALTED bit is set as well. The old behaviour could result in a transfer
being considered failed by the software, but a success by the device.
This seems to have affected mostly mass storage devices.
Pointed out by Dan Ellis in kern/29731.
diffstat:
sys/dev/usb/ehci.c | 35 ++++++++++++++++++++++-------------
sys/dev/usb/ehcireg.h | 4 ++--
2 files changed, 24 insertions(+), 15 deletions(-)
diffs (99 lines):
diff -r 9e51a55f4999 -r ef2415e96918 sys/dev/usb/ehci.c
--- a/sys/dev/usb/ehci.c Sun May 01 19:19:25 2005 +0000
+++ b/sys/dev/usb/ehci.c Sun May 01 19:24:39 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ehci.c,v 1.97 2005/05/01 14:21:27 augustss Exp $ */
+/* $NetBSD: ehci.c,v 1.98 2005/05/01 19:24:39 augustss Exp $ */
/*
* Copyright (c) 2004 The NetBSD Foundation, Inc.
@@ -65,7 +65,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.97 2005/05/01 14:21:27 augustss Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.98 2005/05/01 19:24:39 augustss Exp $");
#include "ohci.h"
#include "uhci.h"
@@ -809,10 +809,6 @@
break;
status = nstatus;
- /* halt is ok if descriptor is last, and complete */
- if (sqtd->qtd.qtd_next == EHCI_NULL &&
- EHCI_QTD_GET_BYTES(status) == 0)
- status &= ~EHCI_QTD_HALTED;
if (EHCI_QTD_GET_PID(status) != EHCI_QTD_PID_SETUP)
actlen += sqtd->len - EHCI_QTD_GET_BYTES(status);
}
@@ -840,20 +836,18 @@
UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize);
epipe->nexttoggle ^= pkts_left % 2;
- status &= EHCI_QTD_STATERRS;
DPRINTFN(/*10*/2, ("ehci_idone: len=%d, actlen=%d, status=0x%x\n",
xfer->length, actlen, status));
xfer->actlen = actlen;
- if (status != 0) {
+ if (status & EHCI_QTD_HALTED) {
#ifdef EHCI_DEBUG
char sbuf[128];
bitmask_snprintf((u_int32_t)status,
"\20\7HALTED\6BUFERR\5BABBLE\4XACTERR"
- "\3MISSED", sbuf, sizeof(sbuf));
-
- DPRINTFN((status == EHCI_QTD_HALTED) ? 2 : 0,
- ("ehci_idone: error, addr=%d, endpt=0x%02x, "
+ "\3MISSED\1PINGSTATE", sbuf, sizeof(sbuf));
+
+ DPRINTFN(2, ("ehci_idone: error, addr=%d, endpt=0x%02x, "
"status 0x%s\n",
xfer->pipe->device->address,
xfer->pipe->endpoint->edesc->bEndpointAddress,
@@ -863,10 +857,25 @@
ehci_dump_sqtds(ex->sqtdstart);
}
#endif
- if (status == EHCI_QTD_HALTED)
+ /* low&full speed has an extra error flag */
+ if (EHCI_QH_GET_EPS(epipe->sqh->qh.qh_endp) !=
+ EHCI_QH_SPEED_HIGH)
+ status &= EHCI_QTD_STATERRS | EHCI_QTD_PINGSTATE;
+ else
+ status &= EHCI_QTD_STATERRS;
+ if (status == 0) /* no other errors means a stall */
xfer->status = USBD_STALLED;
else
xfer->status = USBD_IOERROR; /* more info XXX */
+ /* XXX need to reset TT on missed microframe */
+ if (status & EHCI_QTD_MISSEDMICRO) {
+ ehci_softc_t *sc = (ehci_softc_t *)
+ xfer->pipe->device->bus;
+
+ printf("%s: missed microframe, TT reset not "
+ "implemented, hub might be inoperational\n",
+ USBDEVNAME(sc->sc_bus.bdev));
+ }
} else {
xfer->status = USBD_NORMAL_COMPLETION;
}
diff -r 9e51a55f4999 -r ef2415e96918 sys/dev/usb/ehcireg.h
--- a/sys/dev/usb/ehcireg.h Sun May 01 19:19:25 2005 +0000
+++ b/sys/dev/usb/ehcireg.h Sun May 01 19:24:39 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ehcireg.h,v 1.20 2005/03/02 11:37:27 mycroft Exp $ */
+/* $NetBSD: ehcireg.h,v 1.21 2005/05/01 19:24:39 augustss Exp $ */
/*
* Copyright (c) 2001, 2004 The NetBSD Foundation, Inc.
@@ -215,7 +215,7 @@
#define EHCI_QTD_MISSEDMICRO 0x04
#define EHCI_QTD_SPLITXSTATE 0x02
#define EHCI_QTD_PINGSTATE 0x01
-#define EHCI_QTD_STATERRS 0x7c
+#define EHCI_QTD_STATERRS 0x3c
#define EHCI_QTD_GET_PID(x) (((x) >> 8) & 0x3)
#define EHCI_QTD_SET_PID(x) ((x) << 8)
#define EHCI_QTD_PID_OUT 0x0
Home |
Main Index |
Thread Index |
Old Index