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