Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/usb Follow a safer protocol when updating the QH.



details:   https://anonhg.NetBSD.org/src/rev/bf5f657302a3
branches:  trunk
changeset: 517927:bf5f657302a3
user:      augustss <augustss%NetBSD.org@localhost>
date:      Wed Nov 21 16:05:13 2001 +0000

description:
Follow a safer protocol when updating the QH.
The EHCI driver isn't really working properly, but now the SCSI driver
correctly identifies my CD-RW drive! :-)

diffstat:

 sys/dev/usb/ehci.c |  53 +++++++++++++++++++++++++++++++++++------------------
 1 files changed, 35 insertions(+), 18 deletions(-)

diffs (162 lines):

diff -r 67d274b3cf0b -r bf5f657302a3 sys/dev/usb/ehci.c
--- a/sys/dev/usb/ehci.c        Wed Nov 21 15:48:37 2001 +0000
+++ b/sys/dev/usb/ehci.c        Wed Nov 21 16:05:13 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ehci.c,v 1.22 2001/11/21 14:00:12 augustss Exp $       */
+/*     $NetBSD: ehci.c,v 1.23 2001/11/21 16:05:13 augustss Exp $       */
 
 /*
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -47,7 +47,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.22 2001/11/21 14:00:12 augustss Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.23 2001/11/21 16:05:13 augustss Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -187,6 +187,7 @@
 Static void            ehci_add_qh(ehci_soft_qh_t *, ehci_soft_qh_t *);
 Static void            ehci_rem_qh(ehci_softc_t *, ehci_soft_qh_t *,
                                    ehci_soft_qh_t *);
+Static void            ehci_set_qh_qtd(ehci_soft_qh_t *, ehci_soft_qtd_t *);
 Static void            ehci_sync_hc(ehci_softc_t *);
 
 Static void            ehci_close_pipe(usbd_pipe_handle, ehci_soft_qh_t *);
@@ -677,8 +678,7 @@
        }
 
 #ifdef EHCI_DEBUG
-       DPRINTFN(10, ("ehci_idone: ex=%p, xfer=%p, pipe=%p ready\n",
-                     ex, xfer, epipe));
+       DPRINTFN(/*10*/2, ("ehci_idone: xfer=%p, pipe=%p ready\n", xfer, epipe));
        if (ehcidebug > 10)
                ehci_dump_sqtds(ex->sqtdstart);
 #endif
@@ -704,7 +704,7 @@
        }
 
        status &= EHCI_QTD_STATERRS;
-       DPRINTFN(/*10*/2, ("ehci_idone: len=%d actlen=%d, status=0x%x\n",
+       DPRINTFN(/*10*/2, ("ehci_idone: len=%d, actlen=%d, status=0x%x\n",
                           xfer->length, actlen, status));
        xfer->actlen = actlen;
        if (status != 0) {
@@ -712,8 +712,8 @@
                char sbuf[128];
 
                bitmask_snprintf((u_int32_t)status,
-                                "\20\2MISSEDMICRO\3XACT\4BABBLE\5BABBLE"
-                                "\6HALTED",
+                                "\20\3MISSEDMICRO\4XACT\5BABBLE\6BABBLE"
+                                "\7HALTED",
                                 sbuf, sizeof(sbuf));
 
                DPRINTFN((status == EHCI_QTD_HALTED)*/*10*/2,
@@ -722,8 +722,11 @@
                          xfer->pipe->device->address,
                          xfer->pipe->endpoint->edesc->bEndpointAddress,
                          sbuf));
+               if (ehcidebug > 2) {
+                       ehci_dump_sqh(epipe->sqh);
+                       ehci_dump_sqtds(ex->sqtdstart);
+               }
 #endif
-
                if (status == EHCI_QTD_HALTED)
                        xfer->status = USBD_STALLED;
                else
@@ -987,7 +990,8 @@
 {
        struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
 
-       DPRINTF(("ehci_device_clear_toggle: epipe=%p\n", epipe));
+       DPRINTF(("ehci_device_clear_toggle: epipe=%p status=0x%x\n",
+                epipe, epipe->sqh->qh.qh_qtd.qtd_status));
 #ifdef USB_DEBUG
        if (ehcidebug)
                usbd_dump_pipe(pipe);
@@ -1260,6 +1264,18 @@
        ehci_sync_hc(sc);
 }
 
+void
+ehci_set_qh_qtd(ehci_soft_qh_t *sqh, ehci_soft_qtd_t *sqtd)
+{
+       /* Halt while we are messing. */
+       sqh->qh.qh_qtd.qtd_status |= htole32(EHCI_QTD_HALTED);
+       sqh->qh.qh_curqtd = 0;
+       sqh->qh.qh_qtd.qtd_next = htole32(sqtd->physaddr);
+       sqh->sqtd = sqtd;
+       /* Keep toggle, clear the rest, including length. */
+       sqh->qh.qh_qtd.qtd_status &= htole32(EHCI_QTD_TOGGLE);
+}
+
 /*
  * Ensure that the HC has released all references to the QH.  We do this
  * by asking for a Async Advance Doorbell interrupt and then we wait for
@@ -2423,7 +2439,7 @@
        stat->len = 0;
 
 #ifdef EHCI_DEBUG
-       if (ehcidebug > 2) {
+       if (ehcidebug > 5) {
                DPRINTF(("ehci_device_request:\n"));
                ehci_dump_sqh(sqh);
                ehci_dump_sqtds(setup);
@@ -2441,9 +2457,7 @@
 
        /* Insert qTD in QH list. */
        s = splusb();
-       sqh->qh.qh_curqtd = 0;
-       sqh->qh.qh_qtd.qtd_next = htole32(setup->physaddr);
-       sqh->sqtd = setup;
+       ehci_set_qh_qtd(sqh, setup);
        if (xfer->timeout && !sc->sc_bus.use_polling) {
                 usb_callout(xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
                            ehci_timeout, xfer);
@@ -2454,9 +2468,9 @@
 
 #ifdef EHCI_DEBUG
        if (ehcidebug > 10) {
-               delay(10000);
                DPRINTF(("ehci_device_request: status=%x\n",
                         EOREAD4(sc, EHCI_USBSTS)));
+               delay(10000);
                ehci_dump_regs(sc);
                ehci_dump_sqh(sc->sc_async_head);
                ehci_dump_sqh(sqh);
@@ -2528,8 +2542,9 @@
                return (err);
 
 #ifdef EHCI_DEBUG
-       if (ehcidebug > 8) {
+       if (ehcidebug > 5) {
                DPRINTF(("ehci_device_bulk_transfer: data(1)\n"));
+               ehci_dump_sqh(sqh);
                ehci_dump_sqtds(data);
        }
 #endif
@@ -2545,9 +2560,7 @@
 #endif
 
        s = splusb();
-       sqh->qh.qh_curqtd = 0;
-       sqh->qh.qh_qtd.qtd_next = htole32(data->physaddr);
-       sqh->sqtd = data;
+       ehci_set_qh_qtd(sqh, data);
        if (xfer->timeout && !sc->sc_bus.use_polling) {
                usb_callout(xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
                            ehci_timeout, xfer);
@@ -2559,6 +2572,10 @@
 #ifdef EHCI_DEBUG
        if (ehcidebug > 10) {
                DPRINTF(("ehci_device_bulk_transfer: data(2)\n"));
+               delay(10000);
+               ehci_dump_regs(sc);
+               ehci_dump_sqh(sc->sc_async_head);
+               ehci_dump_sqh(sqh);
                ehci_dump_sqtds(data);
        }
 #endif



Home | Main Index | Thread Index | Old Index