Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb Improve error handling. Mostly from FreeBSD.
details: https://anonhg.NetBSD.org/src/rev/2229cd0fd8d1
branches: trunk
changeset: 473000:2229cd0fd8d1
user: augustss <augustss%NetBSD.org@localhost>
date: Sun May 16 11:43:32 1999 +0000
description:
Improve error handling. Mostly from FreeBSD.
diffstat:
sys/dev/usb/uhci.c | 66 +++++++++++++++++++++++++++---------------------------
1 files changed, 33 insertions(+), 33 deletions(-)
diffs (184 lines):
diff -r 268effec2d1b -r 2229cd0fd8d1 sys/dev/usb/uhci.c
--- a/sys/dev/usb/uhci.c Sun May 16 08:33:47 1999 +0000
+++ b/sys/dev/usb/uhci.c Sun May 16 11:43:32 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uhci.c,v 1.25 1999/04/03 19:00:43 augustss Exp $ */
+/* $NetBSD: uhci.c,v 1.26 1999/05/16 11:43:32 augustss Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -389,7 +389,7 @@
uhci_dumpregs(sc)
uhci_softc_t *sc;
{
- printf("%s; regs: cmd=%04x, sts=%04x, intr=%04x, frnum=%04x, "
+ printf("%s regs: cmd=%04x, sts=%04x, intr=%04x, frnum=%04x, "
"flbase=%08x, sof=%04x, portsc1=%04x, portsc2=%04x\n",
USBDEVNAME(sc->sc_bus.bdev),
UREAD2(sc, UHCI_CMD),
@@ -408,8 +408,8 @@
uhci_dump_td(p)
uhci_soft_td_t *p;
{
- printf("TD(%p) at %08lx = link=0x%08lx st=0x%08lx tok=0x%08lx "
- "buf=0x%08lx\n",
+ printf("TD(%p) at %08lx = link=0x%08lx status=0x%08lx "
+ "token=0x%08lx buffer=0x%08lx\n",
p, (long)p->physaddr,
(long)p->td->td_link,
(long)p->td->td_status,
@@ -728,7 +728,11 @@
return;
}
#endif
- /* If the last TD is still active the whole transfer probably is. */
+ /*
+ * If the last TD is still active we need to check whether there
+ * is a an error somewhere in the middle, or whether there was a
+ * short packet (SPD and not ACTIVE).
+ */
if (lstd->td->td_status & UHCI_TD_ACTIVE) {
DPRINTFN(15, ("uhci_check_intr: active ii=%p\n", ii));
for (std = ii->stdstart; std != lstd; std = std->td->link.std){
@@ -743,10 +747,10 @@
return;
}
done:
+ usb_untimeout(uhci_timeout, ii, ii->timeout_handle);
upipe = (struct uhci_pipe *)ii->reqh->pipe;
upipe->pipe.endpoint->toggle = upipe->newtoggle;
uhci_ii_done(ii, 0);
- usb_untimeout(uhci_timeout, ii, ii->timeout_handle);
}
void
@@ -756,8 +760,8 @@
{
usbd_request_handle reqh = ii->reqh;
uhci_soft_td_t *std;
- u_int32_t tst;
- int len, status, attr;
+ u_int32_t status;
+ int actlen;
DPRINTFN(10, ("uhci_ii_done: ii=%p ready %d\n", ii, timo));
@@ -765,8 +769,8 @@
{
int s = splhigh();
if (ii->isdone) {
+ splx(s);
printf("uhci_ii_done: is done!\n");
- splx(s);
return;
}
ii->isdone = 1;
@@ -774,25 +778,21 @@
}
#endif
- /* The transfer is done, compute length and status. */
+ /* The transfer is done, compute actual length and status. */
/* XXX Should stop at first inactive to get toggle right. */
/* XXX Is this correct for control xfers? */
- for (len = status = 0, std = ii->stdstart;
- std != 0;
- std = std->td->link.std) {
- tst = std->td->td_status;
- status |= tst;
-#ifdef USB_DEBUG
- if ((tst & UHCI_TD_ERROR) && uhcidebug) {
- printf("uhci_ii_done: intr error TD:\n");
- uhci_dump_td(std);
- }
-#endif
+ actlen = 0;
+ for (std = ii->stdstart; std; std = std->td->link.std) {
+ status = std->td->td_status;
+ if (status & UHCI_TD_ACTIVE)
+ break;
if (UHCI_TD_GET_PID(std->td->td_token) != UHCI_TD_PID_SETUP)
- len += UHCI_TD_GET_ACTLEN(tst);
+ actlen += UHCI_TD_GET_ACTLEN(status);
}
status &= UHCI_TD_ERROR;
- DPRINTFN(10, ("uhci_check_intr: len=%d, status=0x%x\n", len, status));
+ DPRINTFN(10, ("uhci_check_intr: actlen=%d, status=0x%x\n",
+ actlen, status));
+ reqh->actlen = actlen;
if (status != 0) {
DPRINTFN(-1+(status==UHCI_TD_STALLED),
("uhci_ii_done: error, addr=%d, endpt=0x%02x, "
@@ -806,10 +806,8 @@
reqh->status = USBD_STALLED;
else
reqh->status = USBD_IOERROR; /* more info XXX */
- reqh->actlen = 0;
} else {
reqh->status = USBD_NORMAL_COMPLETION;
- reqh->actlen = len;
}
if (timo) {
/* We got a timeout. Make sure transaction is not active. */
@@ -820,8 +818,7 @@
}
DPRINTFN(5, ("uhci_ii_done: calling handler ii=%p\n", ii));
- attr = reqh->pipe->endpoint->edesc->bmAttributes;
- switch (attr & UE_XFERTYPE) {
+ switch (reqh->pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE) {
case UE_CONTROL:
uhci_ctrl_done(ii);
usb_start_next(reqh->pipe);
@@ -871,15 +868,14 @@
usbd_request_handle reqh;
{
int timo = reqh->timeout;
- int usecs;
uhci_intr_info_t *ii;
- DPRINTFN(10,("uhci_waitintr: timeout = %ds\n", timo));
+ DPRINTFN(10,("uhci_waitintr: timeout = %dms\n", timo));
reqh->status = USBD_IN_PROGRESS;
- for (usecs = timo * 1000000 / hz; usecs > 0; usecs -= 1000) {
+ for (; timo >= 0; timo--) {
usb_delay_ms(&sc->sc_bus, 1);
- DPRINTFN(10,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS)));
+ DPRINTFN(20,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS)));
if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) {
uhci_intr(sc);
if (reqh->status != USBD_IN_PROGRESS)
@@ -1111,7 +1107,7 @@
int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
DPRINTFN(15, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%d ls=%d "
- "spd=%d\n", addr, endpt, len,
+ "spd=%d\n", addr, UE_GET_ADDR(endpt), len,
upipe->pipe.device->lowspeed, spd));
if (len == 0) {
*sp = *ep = 0;
@@ -1131,7 +1127,7 @@
lastp = 0;
lastlink = UHCI_PTR_T;
ntd--;
- status = UHCI_TD_SET_ERRCNT(2) | UHCI_TD_ACTIVE;
+ status = UHCI_TD_SET_ERRCNT(3) | UHCI_TD_ACTIVE;
if (upipe->pipe.device->lowspeed)
status |= UHCI_TD_LS;
if (spd)
@@ -1262,6 +1258,9 @@
}
#endif
+ if (sc->sc_bus.use_polling)
+ uhci_waitintr(sc, reqh);
+
return (USBD_IN_PROGRESS);
ret2:
@@ -2618,3 +2617,4 @@
usb_untimeout(uhci_timo, pipe->intrreqh, pipe->intrreqh->timo_handle);
DPRINTF(("uhci_root_intr_close\n"));
}
+
Home |
Main Index |
Thread Index |
Old Index