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