summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2008-12-13 01:21:37 +0000
committersam <sam@FreeBSD.org>2008-12-13 01:21:37 +0000
commit9c1fcf4ecd098afcbade2f395ab1fadbbe5b4b76 (patch)
tree644eaeb5764c12410edfb611ec530ca2d197a365 /sys/dev/usb
parenta52a9748d1f9588ffe250473b5be61674d1f1cc6 (diff)
downloadFreeBSD-src-9c1fcf4ecd098afcbade2f395ab1fadbbe5b4b76.zip
FreeBSD-src-9c1fcf4ecd098afcbade2f395ab1fadbbe5b4b76.tar.gz
Merge WIP from p4:
o recognize ixp435 cpu o change memory layout for for ixp4xx to not assume memory is aliases to 0x10000000 (Cambria/ixp435 memory starts at zero) o handle 64 irqs for ixp435 o dual EHCI USB 2.0 controller integral to ixp435 o overhaul NPE code for ixp435 and better MAC+MII naming o updated NPE firmware (including NPE-A image for ixp435/ixp465) o Gateworks Cambria board support: - IDE compact flash - MCU - front panel LED on i2c bus - Octal LED latch Sanity-tested with NFS-root on Avila and Cambria boards. Requires pending boot2 mods for CF-boot on Cambria.
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/ehci.c522
-rw-r--r--sys/dev/usb/ehci_ddb.c255
-rw-r--r--sys/dev/usb/ehci_pci.c4
-rw-r--r--sys/dev/usb/ehcireg.h12
-rw-r--r--sys/dev/usb/ehcivar.h53
-rw-r--r--sys/dev/usb/usbdi.h3
6 files changed, 475 insertions, 374 deletions
diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c
index e9b2cb8..529ba1b 100644
--- a/sys/dev/usb/ehci.c
+++ b/sys/dev/usb/ehci.c
@@ -99,7 +99,6 @@ int ehcidebug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, ehci, CTLFLAG_RW, 0, "USB ehci");
SYSCTL_INT(_hw_usb_ehci, OID_AUTO, debug, CTLFLAG_RW,
&ehcidebug, 0, "ehci debug level");
-#define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f))
#else
#define DPRINTF(x)
#define DPRINTFN(n,x)
@@ -221,34 +220,20 @@ static usbd_status ehci_device_request(usbd_xfer_handle xfer);
static usbd_status ehci_device_setintr(ehci_softc_t *, ehci_soft_qh_t *,
int ival);
-static void ehci_add_qh(ehci_soft_qh_t *, ehci_soft_qh_t *);
+static void ehci_add_qh(ehci_softc_t *, 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_activate_qh(ehci_soft_qh_t *, ehci_soft_qtd_t *);
+static void ehci_activate_qh(ehci_softc_t *sc, 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 *);
static void ehci_abort_xfer(usbd_xfer_handle, usbd_status);
-#ifdef EHCI_DEBUG
-static void ehci_dump_regs(ehci_softc_t *);
-void ehci_dump(void);
-static ehci_softc_t *theehci;
-static void ehci_dump_link(ehci_link_t, int);
-static void ehci_dump_sqtds(ehci_soft_qtd_t *);
-static void ehci_dump_sqtd(ehci_soft_qtd_t *);
-static void ehci_dump_qtd(ehci_qtd_t *);
-static void ehci_dump_sqh(ehci_soft_qh_t *);
-#ifdef notyet
-static void ehci_dump_sitd(struct ehci_soft_itd *);
-static void ehci_dump_itd(struct ehci_soft_itd *);
-#endif
-#ifdef DIAGNOSTIC
-static void ehci_dump_exfer(struct ehci_xfer *);
-#endif
-#endif
+ehci_softc_t *theehci;
-#define EHCI_NULL htole32(EHCI_LINK_TERMINATE)
+#define EHCI_NULL(sc) htohc32(sc, EHCI_LINK_TERMINATE)
#define EHCI_INTR_ENDPT 1
@@ -344,17 +329,26 @@ ehci_hcreset(ehci_softc_t *sc)
* Table 2-9 in the EHCI spec says this will result
* in undefined behavior.
*/
- printf("%s: stop timeout\n",
- device_get_nameunit(sc->sc_bus.bdev));
+ device_printf(sc->sc_bus.bdev, "stop timeout\n");
EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
for (i = 0; i < 100; i++) {
usb_delay_ms(&sc->sc_bus, 1);
hcr = EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_HCRESET;
if (!hcr) {
- if (sc->sc_flags & EHCI_SCFLG_SETMODE)
- EOWRITE4(sc, 0x68, 0x3);
-
+ if (sc->sc_flags & EHCI_SCFLG_SETMODE) {
+ /*
+ * Force USBMODE as requested. Controllers
+ * may have multiple operating modes.
+ */
+ uint32_t usbmode = EOREAD4(sc, EHCI_USBMODE);
+ if (sc->sc_flags & EHCI_SCFLG_SETMODE) {
+ usbmode = (usbmode &~ EHCI_UM_CM) | EHCI_UM_CM_HOST;
+ device_printf(sc->sc_bus.bdev,
+ "set host controller mode\n");
+ }
+ EOWRITE4(sc, EHCI_USBMODE, usbmode);
+ }
return (USBD_NORMAL_COMPLETION);
}
}
@@ -377,10 +371,12 @@ ehci_init(ehci_softc_t *sc)
theehci = sc;
#endif
+ /* NB: must handle byte-order manually before ehci_hcreset */
+
sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
version = EREAD2(sc, EHCI_HCIVERSION);
- printf("%s: EHCI version %x.%x\n", device_get_nameunit(sc->sc_bus.bdev),
+ device_printf(sc->sc_bus.bdev, "EHCI version %x.%x\n",
version >> 8, version & 0xff);
sparams = EREAD4(sc, EHCI_HCSPARAMS);
@@ -435,7 +431,7 @@ ehci_init(ehci_softc_t *sc)
sc->sc_flist = KERNADDR(&sc->sc_fldma, 0);
for (i = 0; i < sc->sc_flsize; i++) {
- sc->sc_flist[i] = EHCI_NULL;
+ sc->sc_flist[i] = EHCI_NULL(sc);
}
EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0));
@@ -450,11 +446,6 @@ ehci_init(ehci_softc_t *sc)
sc->sc_bus.methods = &ehci_bus_methods;
sc->sc_bus.pipe_size = sizeof(struct ehci_pipe);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- sc->sc_powerhook = powerhook_establish(ehci_power, sc);
- sc->sc_shutdownhook = shutdownhook_establish(ehci_shutdown, sc);
-#endif
-
sc->sc_eintrs = EHCI_NORMAL_INTRS;
/*
@@ -476,27 +467,26 @@ ehci_init(ehci_softc_t *sc)
sqh = sc->sc_islots[i].sqh;
if (i == 0) {
/* The last (1ms) QH terminates. */
- sqh->qh.qh_link = EHCI_NULL;
+ sqh->qh.qh_link = EHCI_NULL(sc);
sqh->next = NULL;
} else {
/* Otherwise the next QH has half the poll interval */
sqh->next =
sc->sc_islots[EHCI_IQHIDX(lev - 1, i + 1)].sqh;
- sqh->qh.qh_link = htole32(sqh->next->physaddr |
+ sqh->qh.qh_link = htohc32(sc, sqh->next->physaddr |
EHCI_LINK_QH);
}
- sqh->qh.qh_endp = htole32(EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH));
- sqh->qh.qh_endphub = htole32(EHCI_QH_SET_MULT(1));
- sqh->qh.qh_curqtd = EHCI_NULL;
- sqh->qh.qh_qtd.qtd_next = EHCI_NULL;
- sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
- sqh->qh.qh_qtd.qtd_status = htole32(EHCI_QTD_HALTED);
+ sqh->qh.qh_endp = htohc32(sc, EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH));
+ sqh->qh.qh_endphub = htohc32(sc, EHCI_QH_SET_MULT(1));
+ sqh->qh.qh_curqtd = EHCI_NULL(sc);
+ sqh->qh.qh_qtd.qtd_next = EHCI_NULL(sc);
+ sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL(sc);
+ sqh->qh.qh_qtd.qtd_status = htohc32(sc, EHCI_QTD_HALTED);
}
/* Point the frame list at the last level (128ms). */
for (i = 0; i < sc->sc_flsize; i++) {
- sc->sc_flist[i] = htole32(EHCI_LINK_QH |
- sc->sc_islots[EHCI_IQHIDX(EHCI_IPOLLRATES - 1,
- i)].sqh->physaddr);
+ sc->sc_flist[i] = htohc32(sc, EHCI_LINK_QH |
+ sc->sc_islots[EHCI_IQHIDX(EHCI_IPOLLRATES - 1, i)].sqh->physaddr);
}
/* Allocate dummy QH that starts the async list. */
@@ -507,19 +497,19 @@ ehci_init(ehci_softc_t *sc)
}
/* Fill the QH */
sqh->qh.qh_endp =
- htole32(EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH) | EHCI_QH_HRECL);
+ htohc32(sc, EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH) | EHCI_QH_HRECL);
sqh->qh.qh_link =
- htole32(sqh->physaddr | EHCI_LINK_QH);
- sqh->qh.qh_curqtd = EHCI_NULL;
+ htohc32(sc, sqh->physaddr | EHCI_LINK_QH);
+ sqh->qh.qh_curqtd = EHCI_NULL(sc);
sqh->prev = sqh; /*It's a circular list.. */
sqh->next = sqh;
/* Fill the overlay qTD */
- sqh->qh.qh_qtd.qtd_next = EHCI_NULL;
- sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
- sqh->qh.qh_qtd.qtd_status = htole32(0);
+ sqh->qh.qh_qtd.qtd_next = EHCI_NULL(sc);
+ sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL(sc);
+ sqh->qh.qh_qtd.qtd_status = htohc32(sc, 0);
#ifdef EHCI_DEBUG
if (ehcidebug) {
- ehci_dump_sqh(sqh);
+ ehci_dump_sqh(sc, sqh);
}
#endif
@@ -777,10 +767,10 @@ ehci_check_qh_intr(ehci_softc_t *sc, struct ehci_xfer *ex)
* is a an error somewhere in the middle, or whether there was a
* short packet (SPD and not ACTIVE).
*/
- if (le32toh(lsqtd->qtd.qtd_status) & EHCI_QTD_ACTIVE) {
+ if (hc32toh(sc, lsqtd->qtd.qtd_status) & EHCI_QTD_ACTIVE) {
DPRINTFN(12, ("ehci_check_intr: active ex=%p\n", ex));
for (sqtd = ex->sqtdstart; sqtd != lsqtd; sqtd=sqtd->nextqtd) {
- status = le32toh(sqtd->qtd.qtd_status);
+ status = hc32toh(sc, sqtd->qtd.qtd_status);
/* If there's an active QTD the xfer isn't done. */
if (status & EHCI_QTD_ACTIVE)
break;
@@ -825,7 +815,7 @@ ehci_check_itd_intr(ehci_softc_t *sc, struct ehci_xfer *ex)
* Step 1, check no active transfers in last itd, meaning we're finished
*/
for (i = 0; i < 8; i++) {
- if (le32toh(itd->itd.itd_ctl[i]) & EHCI_ITD_ACTIVE)
+ if (hc32toh(sc, itd->itd.itd_ctl[i]) & EHCI_ITD_ACTIVE)
break;
}
@@ -841,7 +831,7 @@ ehci_check_itd_intr(ehci_softc_t *sc, struct ehci_xfer *ex)
for (itd = ex->itdstart; itd != ex->itdend; itd = itd->xfer_next) {
for (i = 0; i < 8; i++) {
- if (le32toh(itd->itd.itd_ctl[i]) & (EHCI_ITD_BUF_ERR |
+ if (hc32toh(sc, itd->itd.itd_ctl[i]) & (EHCI_ITD_BUF_ERR |
EHCI_ITD_BABBLE | EHCI_ITD_ERROR))
break;
}
@@ -865,6 +855,7 @@ ehci_idone(struct ehci_xfer *ex)
{
usbd_xfer_handle xfer = &ex->xfer;
struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
+ ehci_softc_t *sc = (ehci_softc_t *)epipe->pipe.device->bus;
ehci_soft_qtd_t *sqtd, *lsqtd;
u_int32_t status = 0, nstatus = 0;
ehci_physaddr_t nextphys, altnextphys;
@@ -878,7 +869,7 @@ ehci_idone(struct ehci_xfer *ex)
splx(s);
#ifdef EHCI_DEBUG
printf("ehci_idone: ex is done!\n ");
- ehci_dump_exfer(ex);
+ ehci_dump_exfer(sc, ex);
#else
printf("ehci_idone: ex=%p is done!\n", ex);
#endif
@@ -898,7 +889,7 @@ ehci_idone(struct ehci_xfer *ex)
#ifdef EHCI_DEBUG
DPRINTFN(/*10*/2, ("ehci_idone: xfer=%p, pipe=%p ready\n", xfer, epipe));
if (ehcidebug > 10)
- ehci_dump_sqtds(ex->sqtdstart);
+ ehci_dump_sqtds(sc, ex->sqtdstart);
#endif
/*
@@ -906,14 +897,14 @@ ehci_idone(struct ehci_xfer *ex)
* of the qTDs we are about to free. This is probably only
* necessary if the transfer is marked as HALTED.
*/
- nextphys = EHCI_LINK_ADDR(le32toh(epipe->sqh->qh.qh_qtd.qtd_next));
+ nextphys = EHCI_LINK_ADDR(hc32toh(sc, epipe->sqh->qh.qh_qtd.qtd_next));
altnextphys =
- EHCI_LINK_ADDR(le32toh(epipe->sqh->qh.qh_qtd.qtd_altnext));
+ EHCI_LINK_ADDR(hc32toh(sc, epipe->sqh->qh.qh_qtd.qtd_altnext));
for (sqtd = ex->sqtdstart; sqtd != ex->sqtdend->nextqtd;
sqtd = sqtd->nextqtd) {
if (sqtd->physaddr == nextphys) {
epipe->sqh->qh.qh_qtd.qtd_next =
- htole32(ex->sqtdend->nextqtd->physaddr);
+ htohc32(sc, ex->sqtdend->nextqtd->physaddr);
DPRINTFN(4, ("ehci_idone: updated overlay next ptr\n"));
}
@@ -921,7 +912,7 @@ ehci_idone(struct ehci_xfer *ex)
DPRINTFN(4,
("ehci_idone: updated overlay altnext ptr\n"));
epipe->sqh->qh.qh_qtd.qtd_altnext =
- htole32(ex->sqtdend->nextqtd->physaddr);
+ htohc32(sc, ex->sqtdend->nextqtd->physaddr);
}
}
@@ -964,7 +955,7 @@ ehci_idone(struct ehci_xfer *ex)
if (nframes >= xfer->nframes)
break;
- status = le32toh(itd->itd.itd_ctl[i]);
+ status = hc32toh(sc, itd->itd.itd_ctl[i]);
len = EHCI_ITD_GET_LEN(status);
xfer->frlengths[nframes++] = len;
actlen += len;
@@ -984,7 +975,7 @@ ehci_idone(struct ehci_xfer *ex)
actlen = 0;
for (sqtd = ex->sqtdstart; sqtd != lsqtd->nextqtd;
sqtd =sqtd->nextqtd) {
- nstatus = le32toh(sqtd->qtd.qtd_status);
+ nstatus = hc32toh(sc, sqtd->qtd.qtd_status);
if (nstatus & EHCI_QTD_ACTIVE)
break;
@@ -1001,24 +992,11 @@ ehci_idone(struct ehci_xfer *ex)
"status=0x%x\n", xfer->length, actlen, cerr, status));
xfer->actlen = actlen;
if ((status & EHCI_QTD_HALTED) != 0) {
-#ifdef EHCI_DEBUG
- char sbuf[128];
-
- bitmask_snprintf((u_int32_t)status,
- "\20\7HALTED\6BUFERR\5BABBLE\4XACTERR"
- "\3MISSED\2SPLIT\1PING", sbuf, sizeof(sbuf));
-
DPRINTFN(2,
- ("ehci_idone: error, addr=%d, endpt=0x%02x, "
- "status 0x%s\n",
+ ("ehci_idone: error, addr=%d, endpt=0x%02x, status %b\n",
xfer->pipe->device->address,
xfer->pipe->endpoint->edesc->bEndpointAddress,
- sbuf));
- if (ehcidebug > 2) {
- ehci_dump_sqh(epipe->sqh);
- ehci_dump_sqtds(ex->sqtdstart);
- }
-#endif
+ status, EHCI_QTD_STATUS_BITS));
if ((status & EHCI_QTD_BABBLE) == 0 && cerr > 0)
xfer->status = USBD_STALLED;
else
@@ -1026,6 +1004,12 @@ ehci_idone(struct ehci_xfer *ex)
} else {
xfer->status = USBD_NORMAL_COMPLETION;
}
+#ifdef EHCI_DEBUG
+ if (ehcidebug > 2) {
+ ehci_dump_sqh(sc, epipe->sqh);
+ ehci_dump_sqtds(sc, ex->sqtdstart);
+ }
+#endif
end:
/* XXX transfer_complete memcpys out transfer data (for in endpoints)
* during this call, before methods->done is called: dma sync required
@@ -1102,12 +1086,6 @@ ehci_detach(struct ehci_softc *sc, int flags)
(void) ehci_hcreset(sc);
callout_stop(&sc->sc_tmo_intrlist);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- if (sc->sc_powerhook != NULL)
- powerhook_disestablish(sc->sc_powerhook);
- if (sc->sc_shutdownhook != NULL)
- shutdownhook_disestablish(sc->sc_shutdownhook);
-#endif
usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
usb_freemem(&sc->sc_bus, &sc->sc_fldma);
@@ -1337,6 +1315,7 @@ static void
ehci_device_clear_toggle(usbd_pipe_handle pipe)
{
struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
+ ehci_softc_t *sc = (ehci_softc_t *)epipe->pipe.device->bus;
DPRINTF(("ehci_device_clear_toggle: epipe=%p status=0x%x\n",
epipe, epipe->sqh->qh.qh_qtd.qtd_status));
@@ -1345,9 +1324,9 @@ ehci_device_clear_toggle(usbd_pipe_handle pipe)
usbd_dump_pipe(pipe);
#endif
KASSERT((epipe->sqh->qh.qh_qtd.qtd_status &
- htole32(EHCI_QTD_ACTIVE)) == 0,
+ htohc32(sc, EHCI_QTD_ACTIVE)) == 0,
("ehci_device_clear_toggle: queue active"));
- epipe->sqh->qh.qh_qtd.qtd_status &= htole32(~EHCI_QTD_TOGGLE_MASK);
+ epipe->sqh->qh.qh_qtd.qtd_status &= htohc32(sc, ~EHCI_QTD_TOGGLE_MASK);
}
static void
@@ -1355,178 +1334,6 @@ ehci_noop(usbd_pipe_handle pipe)
{
}
-#ifdef EHCI_DEBUG
-void
-ehci_dump_regs(ehci_softc_t *sc)
-{
- int i;
- printf("cmd=0x%08x, sts=0x%08x, ien=0x%08x\n",
- EOREAD4(sc, EHCI_USBCMD),
- EOREAD4(sc, EHCI_USBSTS),
- EOREAD4(sc, EHCI_USBINTR));
- printf("frindex=0x%08x ctrdsegm=0x%08x periodic=0x%08x async=0x%08x\n",
- EOREAD4(sc, EHCI_FRINDEX),
- EOREAD4(sc, EHCI_CTRLDSSEGMENT),
- EOREAD4(sc, EHCI_PERIODICLISTBASE),
- EOREAD4(sc, EHCI_ASYNCLISTADDR));
- for (i = 1; i <= sc->sc_noport; i++)
- printf("port %d status=0x%08x\n", i,
- EOREAD4(sc, EHCI_PORTSC(i)));
-}
-
-/*
- * Unused function - this is meant to be called from a kernel
- * debugger.
- */
-void
-ehci_dump()
-{
- ehci_dump_regs(theehci);
-}
-
-void
-ehci_dump_link(ehci_link_t link, int type)
-{
- link = le32toh(link);
- printf("0x%08x", link);
- if (link & EHCI_LINK_TERMINATE)
- printf("<T>");
- else {
- printf("<");
- if (type) {
- switch (EHCI_LINK_TYPE(link)) {
- case EHCI_LINK_ITD: printf("ITD"); break;
- case EHCI_LINK_QH: printf("QH"); break;
- case EHCI_LINK_SITD: printf("SITD"); break;
- case EHCI_LINK_FSTN: printf("FSTN"); break;
- }
- }
- printf(">");
- }
-}
-
-void
-ehci_dump_sqtds(ehci_soft_qtd_t *sqtd)
-{
- int i;
- u_int32_t stop;
-
- stop = 0;
- for (i = 0; sqtd && i < 20 && !stop; sqtd = sqtd->nextqtd, i++) {
- ehci_dump_sqtd(sqtd);
- stop = sqtd->qtd.qtd_next & htole32(EHCI_LINK_TERMINATE);
- }
- if (sqtd)
- printf("dump aborted, too many TDs\n");
-}
-
-void
-ehci_dump_sqtd(ehci_soft_qtd_t *sqtd)
-{
- printf("QTD(%p) at 0x%08x:\n", sqtd, sqtd->physaddr);
- ehci_dump_qtd(&sqtd->qtd);
-}
-
-void
-ehci_dump_qtd(ehci_qtd_t *qtd)
-{
- u_int32_t s;
- char sbuf[128];
-
- printf(" next="); ehci_dump_link(qtd->qtd_next, 0);
- printf(" altnext="); ehci_dump_link(qtd->qtd_altnext, 0);
- printf("\n");
- s = le32toh(qtd->qtd_status);
- bitmask_snprintf(EHCI_QTD_GET_STATUS(s),
- "\20\10ACTIVE\7HALTED\6BUFERR\5BABBLE\4XACTERR"
- "\3MISSED\2SPLIT\1PING", sbuf, sizeof(sbuf));
- printf(" status=0x%08x: toggle=%d bytes=0x%x ioc=%d c_page=0x%x\n",
- s, EHCI_QTD_GET_TOGGLE(s), EHCI_QTD_GET_BYTES(s),
- EHCI_QTD_GET_IOC(s), EHCI_QTD_GET_C_PAGE(s));
- printf(" cerr=%d pid=%d stat=0x%s\n", EHCI_QTD_GET_CERR(s),
- EHCI_QTD_GET_PID(s), sbuf);
- for (s = 0; s < 5; s++)
- printf(" buffer[%d]=0x%08x\n", s, le32toh(qtd->qtd_buffer[s]));
-}
-
-void
-ehci_dump_sqh(ehci_soft_qh_t *sqh)
-{
- ehci_qh_t *qh = &sqh->qh;
- u_int32_t endp, endphub;
-
- printf("QH(%p) at 0x%08x:\n", sqh, sqh->physaddr);
- printf(" sqtd=%p inactivesqtd=%p\n", sqh->sqtd, sqh->inactivesqtd);
- printf(" link="); ehci_dump_link(qh->qh_link, 1); printf("\n");
- endp = le32toh(qh->qh_endp);
- printf(" endp=0x%08x\n", endp);
- printf(" addr=0x%02x inact=%d endpt=%d eps=%d dtc=%d hrecl=%d\n",
- EHCI_QH_GET_ADDR(endp), EHCI_QH_GET_INACT(endp),
- EHCI_QH_GET_ENDPT(endp), EHCI_QH_GET_EPS(endp),
- EHCI_QH_GET_DTC(endp), EHCI_QH_GET_HRECL(endp));
- printf(" mpl=0x%x ctl=%d nrl=%d\n",
- EHCI_QH_GET_MPL(endp), EHCI_QH_GET_CTL(endp),
- EHCI_QH_GET_NRL(endp));
- endphub = le32toh(qh->qh_endphub);
- printf(" endphub=0x%08x\n", endphub);
- printf(" smask=0x%02x cmask=0x%02x huba=0x%02x port=%d mult=%d\n",
- EHCI_QH_GET_SMASK(endphub), EHCI_QH_GET_CMASK(endphub),
- EHCI_QH_GET_HUBA(endphub), EHCI_QH_GET_PORT(endphub),
- EHCI_QH_GET_MULT(endphub));
- printf(" curqtd="); ehci_dump_link(qh->qh_curqtd, 0); printf("\n");
- printf("Overlay qTD:\n");
- ehci_dump_qtd(&qh->qh_qtd);
-}
-
-#ifdef notyet
-void
-ehci_dump_itd(struct ehci_soft_itd *itd)
-{
- ehci_isoc_trans_t t;
- ehci_isoc_bufr_ptr_t b, b2, b3;
- int i;
-
- printf("ITD: next phys=%X\n", itd->itd.itd_next);
-
- for (i = 0; i < 8;i++) {
- t = le32toh(itd->itd.itd_ctl[i]);
- printf("ITDctl %d: stat=%X len=%X ioc=%X pg=%X offs=%X\n", i,
- EHCI_ITD_GET_STATUS(t), EHCI_ITD_GET_LEN(t),
- EHCI_ITD_GET_IOC(t), EHCI_ITD_GET_PG(t),
- EHCI_ITD_GET_OFFS(t));
- }
- printf("ITDbufr: ");
- for (i = 0; i < 7; i++)
- printf("%X,", EHCI_ITD_GET_BPTR(le32toh(itd->itd.itd_bufr[i])));
-
- b = le32toh(itd->itd.itd_bufr[0]);
- b2 = le32toh(itd->itd.itd_bufr[1]);
- b3 = le32toh(itd->itd.itd_bufr[2]);
- printf("\nep=%X daddr=%X dir=%d maxpkt=%X multi=%X\n",
- EHCI_ITD_GET_EP(b), EHCI_ITD_GET_DADDR(b), EHCI_ITD_GET_DIR(b2),
- EHCI_ITD_GET_MAXPKT(b2), EHCI_ITD_GET_MULTI(b3));
-}
-
-void
-ehci_dump_sitd(struct ehci_soft_itd *itd)
-{
- printf("SITD %p next=%p prev=%p xfernext=%p physaddr=%X slot=%d\n",
- itd, itd->u.frame_list.next, itd->u.frame_list.prev,
- itd->xfer_next, itd->physaddr, itd->slot);
-}
-#endif
-
-#ifdef DIAGNOSTIC
-void
-ehci_dump_exfer(struct ehci_xfer *ex)
-{
- printf("ehci_dump_exfer: ex=%p sqtdstart=%p end=%p itdstart=%p "
- "end=%p isdone=%d\n", ex, ex->sqtdstart, ex->sqtdend, ex->itdstart,
- ex->itdend, ex->isdone);
-}
-#endif
-#endif
-
usbd_status
ehci_open(usbd_pipe_handle pipe)
{
@@ -1542,8 +1349,8 @@ ehci_open(usbd_pipe_handle pipe)
int ival, speed, naks;
int hshubaddr, hshubport;
- DPRINTFN(1, ("ehci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
- pipe, addr, ed->bEndpointAddress, sc->sc_addr));
+ DPRINTFN(1, ("ehci_open: pipe=%p, xfertype=%d, addr=%d, endpt=%d (%d)\n",
+ pipe, addr, ed->bEndpointAddress, sc->sc_addr, xfertype));
if (dev->myhsport) {
hshubaddr = dev->myhsport->parent->address;
@@ -1595,7 +1402,7 @@ ehci_open(usbd_pipe_handle pipe)
if (sqh == NULL)
goto bad0;
/* qh_link filled when the QH is added */
- sqh->qh.qh_endp = htole32(
+ sqh->qh.qh_endp = htohc32(sc,
EHCI_QH_SET_ADDR(addr) |
EHCI_QH_SET_ENDPT(UE_GET_ADDR(ed->bEndpointAddress)) |
EHCI_QH_SET_EPS(speed) |
@@ -1605,17 +1412,17 @@ ehci_open(usbd_pipe_handle pipe)
EHCI_QH_CTL : 0) |
EHCI_QH_SET_NRL(naks)
);
- sqh->qh.qh_endphub = htole32(
+ sqh->qh.qh_endphub = htohc32(sc,
EHCI_QH_SET_MULT(1) |
EHCI_QH_SET_HUBA(hshubaddr) |
EHCI_QH_SET_PORT(hshubport) |
EHCI_QH_SET_CMASK(0x1c) |
EHCI_QH_SET_SMASK(xfertype == UE_INTERRUPT ? 0x01 : 0)
);
- sqh->qh.qh_curqtd = EHCI_NULL;
+ sqh->qh.qh_curqtd = EHCI_NULL(sc);
/* The overlay qTD was already set up by ehci_alloc_sqh(). */
sqh->qh.qh_qtd.qtd_status =
- htole32(EHCI_QTD_SET_TOGGLE(pipe->endpoint->savedtoggle));
+ htohc32(sc, EHCI_QTD_SET_TOGGLE(pipe->endpoint->savedtoggle));
epipe->sqh = sqh;
} else {
sqh = NULL;
@@ -1633,13 +1440,13 @@ ehci_open(usbd_pipe_handle pipe)
goto bad1;
pipe->methods = &ehci_device_ctrl_methods;
s = splusb();
- ehci_add_qh(sqh, sc->sc_async_head);
+ ehci_add_qh(sc, sqh, sc->sc_async_head);
splx(s);
break;
case UE_BULK:
pipe->methods = &ehci_device_bulk_methods;
s = splusb();
- ehci_add_qh(sqh, sc->sc_async_head);
+ ehci_add_qh(sc, sqh, sc->sc_async_head);
splx(s);
break;
case UE_INTERRUPT:
@@ -1683,7 +1490,7 @@ ehci_open(usbd_pipe_handle pipe)
* If in the intr schedule it may not.
*/
void
-ehci_add_qh(ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
+ehci_add_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
{
SPLUSBCHECK;
@@ -1693,12 +1500,12 @@ ehci_add_qh(ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
head->next = sqh;
if (sqh->next)
sqh->next->prev = sqh;
- head->qh.qh_link = htole32(sqh->physaddr | EHCI_LINK_QH);
+ head->qh.qh_link = htohc32(sc, sqh->physaddr | EHCI_LINK_QH);
#ifdef EHCI_DEBUG
if (ehcidebug > 5) {
printf("ehci_add_qh:\n");
- ehci_dump_sqh(sqh);
+ ehci_dump_sqh(sc, sqh);
}
#endif
}
@@ -1721,9 +1528,9 @@ ehci_rem_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
/* Restart a QH following the addition of a qTD. */
void
-ehci_activate_qh(ehci_soft_qh_t *sqh, ehci_soft_qtd_t *sqtd)
+ehci_activate_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qtd_t *sqtd)
{
- KASSERT((sqtd->qtd.qtd_status & htole32(EHCI_QTD_ACTIVE)) == 0,
+ KASSERT((sqtd->qtd.qtd_status & htohc32(sc, EHCI_QTD_ACTIVE)) == 0,
("ehci_activate_qh: already active"));
/*
@@ -1734,23 +1541,23 @@ ehci_activate_qh(ehci_soft_qh_t *sqh, ehci_soft_qtd_t *sqtd)
*/
if (sqtd == sqh->sqtd) {
/* Check that the hardware is in the state we expect. */
- if (EHCI_LINK_ADDR(le32toh(sqh->qh.qh_qtd.qtd_next)) !=
+ if (EHCI_LINK_ADDR(hc32toh(sc, sqh->qh.qh_qtd.qtd_next)) !=
sqtd->physaddr) {
#ifdef EHCI_DEBUG
printf("ehci_activate_qh: unexpected next ptr\n");
- ehci_dump_sqh(sqh);
- ehci_dump_sqtds(sqh->sqtd);
+ ehci_dump_sqh(sc, sqh);
+ ehci_dump_sqtds(sc, sqh->sqtd);
#endif
- sqh->qh.qh_qtd.qtd_next = htole32(sqtd->physaddr);
- sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
+ sqh->qh.qh_qtd.qtd_next = htohc32(sc, sqtd->physaddr);
+ sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL(sc);
}
/* Ensure the flags are correct. */
- sqh->qh.qh_qtd.qtd_status &= htole32(EHCI_QTD_PINGSTATE |
+ sqh->qh.qh_qtd.qtd_status &= htohc32(sc, EHCI_QTD_PINGSTATE |
EHCI_QTD_TOGGLE_MASK);
}
/* Now activate the qTD. */
- sqtd->qtd.qtd_status |= htole32(EHCI_QTD_ACTIVE);
+ sqtd->qtd.qtd_status |= htohc32(sc, EHCI_QTD_ACTIVE);
}
/*
@@ -2471,16 +2278,16 @@ ehci_alloc_sqh(ehci_softc_t *sc)
sqtd = ehci_alloc_sqtd(sc);
if (sqtd == NULL)
return (NULL);
- sqtd->qtd.qtd_status = htole32(0);
- sqtd->qtd.qtd_next = EHCI_NULL;
- sqtd->qtd.qtd_altnext = EHCI_NULL;
+ sqtd->qtd.qtd_status = htohc32(sc, 0);
+ sqtd->qtd.qtd_next = EHCI_NULL(sc);
+ sqtd->qtd.qtd_altnext = EHCI_NULL(sc);
sqh = sc->sc_freeqhs;
sc->sc_freeqhs = sqh->next;
/* The overlay QTD should begin zeroed. */
- sqh->qh.qh_qtd.qtd_next = htole32(sqtd->physaddr);
- sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
+ sqh->qh.qh_qtd.qtd_next = htohc32(sc, sqtd->physaddr);
+ sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL(sc);
sqh->qh.qh_qtd.qtd_status = 0;
for (i = 0; i < EHCI_QTD_NBUFFERS; i++) {
sqh->qh.qh_qtd.qtd_buffer[i] = 0;
@@ -2534,8 +2341,8 @@ ehci_alloc_sqtd(ehci_softc_t *sc)
s = splusb();
sqtd = sc->sc_freeqtds;
sc->sc_freeqtds = sqtd->nextqtd;
- sqtd->qtd.qtd_next = EHCI_NULL;
- sqtd->qtd.qtd_altnext = EHCI_NULL;
+ sqtd->qtd.qtd_next = EHCI_NULL(sc);
+ sqtd->qtd.qtd_altnext = EHCI_NULL(sc);
sqtd->qtd.qtd_status = 0;
for (i = 0; i < EHCI_QTD_NBUFFERS; i++) {
sqtd->qtd.qtd_buffer[i] = 0;
@@ -2632,7 +2439,7 @@ ehci_alloc_sqtd_chain(struct ehci_pipe *epipe, ehci_softc_t *sc,
segoff = 0;
}
- cur->qtd.qtd_buffer[i] = htole32(dataphys);
+ cur->qtd.qtd_buffer[i] = htohc32(sc, dataphys);
cur->qtd.qtd_buffer_hi[i] = 0;
curlen += pagelen;
@@ -2667,18 +2474,18 @@ ehci_alloc_sqtd_chain(struct ehci_pipe *epipe, ehci_softc_t *sc,
next = ehci_alloc_sqtd(sc);
if (next == NULL)
goto nomem;
- nextphys = htole32(next->physaddr);
+ nextphys = htohc32(sc, next->physaddr);
} else {
next = NULL;
- nextphys = EHCI_NULL;
+ nextphys = EHCI_NULL(sc);
}
cur->nextqtd = next;
cur->qtd.qtd_next = nextphys;
/* Make sure to stop after a short transfer. */
- cur->qtd.qtd_altnext = htole32(newinactive->physaddr);
+ cur->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
cur->qtd.qtd_status =
- htole32(qtdstatus | EHCI_QTD_SET_BYTES(curlen));
+ htohc32(sc, qtdstatus | EHCI_QTD_SET_BYTES(curlen));
cur->xfer = xfer;
cur->len = curlen;
DPRINTFN(10,("ehci_alloc_sqtd_chain: curlen=%d\n", curlen));
@@ -2700,7 +2507,7 @@ ehci_alloc_sqtd_chain(struct ehci_pipe *epipe, ehci_softc_t *sc,
offset += curlen;
cur = next;
}
- cur->qtd.qtd_status |= htole32(EHCI_QTD_IOC);
+ cur->qtd.qtd_status |= htohc32(sc, EHCI_QTD_IOC);
*ep = cur;
DPRINTFN(10,("ehci_alloc_sqtd_chain: return sqtd=%p sqtdend=%p\n",
@@ -2829,7 +2636,7 @@ ehci_close_pipe(usbd_pipe_handle pipe, ehci_soft_qh_t *head)
ehci_rem_qh(sc, sqh, head);
splx(s);
pipe->endpoint->savedtoggle =
- EHCI_QTD_GET_TOGGLE(le32toh(sqh->qh.qh_qtd.qtd_status));
+ EHCI_QTD_GET_TOGGLE(hc32toh(sc, sqh->qh.qh_qtd.qtd_status));
ehci_free_sqh(sc, epipe->sqh);
}
@@ -2938,7 +2745,7 @@ ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
* the aborting xfer. (If there is something past us).
* Hardware and software.
*/
- cur = EHCI_LINK_ADDR(le32toh(sqh->qh.qh_curqtd));
+ cur = EHCI_LINK_ADDR(hc32toh(sc, sqh->qh.qh_curqtd));
hit = 0;
/* If they initially point here. */
@@ -2946,7 +2753,7 @@ ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
/* We will change them to point here */
snext = exfer->sqtdend->nextqtd;
- next = htole32(snext->physaddr);
+ next = htohc32(sc, snext->physaddr);
/*
* Now loop through any qTDs before us and keep track of the pointer
@@ -2955,9 +2762,9 @@ ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
sqtd = sqh->sqtd;
while (sqtd && sqtd != exfer->sqtdstart) {
hit |= (cur == sqtd->physaddr);
- if (EHCI_LINK_ADDR(le32toh(sqtd->qtd.qtd_next)) == us)
+ if (EHCI_LINK_ADDR(hc32toh(sc, sqtd->qtd.qtd_next)) == us)
sqtd->qtd.qtd_next = next;
- if (EHCI_LINK_ADDR(le32toh(sqtd->qtd.qtd_altnext)) == us)
+ if (EHCI_LINK_ADDR(hc32toh(sc, sqtd->qtd.qtd_altnext)) == us)
sqtd->qtd.qtd_altnext = next;
sqtd = sqtd->nextqtd;
}
@@ -2986,17 +2793,17 @@ ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
* that we are removing.
*/
if (hit) {
- sqh->qh.qh_qtd.qtd_next = htole32(snext->physaddr);
- sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
+ sqh->qh.qh_qtd.qtd_next = htohc32(sc, snext->physaddr);
+ sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL(sc);
sqh->qh.qh_qtd.qtd_status &=
- htole32(EHCI_QTD_TOGGLE_MASK);
+ htohc32(sc, EHCI_QTD_TOGGLE_MASK);
for (i = 0; i < EHCI_QTD_NBUFFERS; i++) {
sqh->qh.qh_qtd.qtd_buffer[i] = 0;
sqh->qh.qh_qtd.qtd_buffer_hi[i] = 0;
}
}
}
- ehci_add_qh(sqh, psqh);
+ ehci_add_qh(sc, sqh, psqh);
/*
* Step 5: Execute callback.
*/
@@ -3090,9 +2897,9 @@ ehci_abort_isoc_xfer(usbd_xfer_handle xfer, usbd_status status)
for (itd = exfer->itdstart; itd != NULL; itd = itd->xfer_next) {
for (i = 0; i < 8; i++) {
- trans_status = le32toh(itd->itd.itd_ctl[i]);
+ trans_status = hc32toh(sc, itd->itd.itd_ctl[i]);
trans_status &= ~EHCI_ITD_ACTIVE;
- itd->itd.itd_ctl[i] = htole32(trans_status);
+ itd->itd.itd_ctl[i] = htohc32(sc, trans_status);
}
}
@@ -3269,9 +3076,10 @@ ehci_device_request(usbd_xfer_handle xfer)
err = USBD_NOMEM;
goto bad1;
}
- newinactive->qtd.qtd_status = htole32(0);
- newinactive->qtd.qtd_next = EHCI_NULL;
- newinactive->qtd.qtd_altnext = EHCI_NULL;
+ newinactive->qtd.qtd_status = htohc32(sc, 0);
+ newinactive->qtd.qtd_next = EHCI_NULL(sc);
+ newinactive->qtd.qtd_altnext = EHCI_NULL(sc);
+
stat = ehci_alloc_sqtd(sc);
if (stat == NULL) {
err = USBD_NOMEM;
@@ -3291,10 +3099,10 @@ ehci_device_request(usbd_xfer_handle xfer)
NULL, newinactive, &next, &end);
if (err)
goto bad3;
- end->qtd.qtd_status &= htole32(~EHCI_QTD_IOC);
+ end->qtd.qtd_status &= htohc32(sc, ~EHCI_QTD_IOC);
end->nextqtd = stat;
- end->qtd.qtd_next = htole32(stat->physaddr);
- end->qtd.qtd_altnext = htole32(newinactive->physaddr);
+ end->qtd.qtd_next = htohc32(sc, stat->physaddr);
+ end->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
} else {
next = stat;
}
@@ -3302,21 +3110,21 @@ ehci_device_request(usbd_xfer_handle xfer)
memcpy(KERNADDR(&epipe->u.ctl.reqdma, 0), req, sizeof *req);
/* Clear toggle, and do not activate until complete */
- setup->qtd.qtd_status = htole32(
+ setup->qtd.qtd_status = htohc32(sc,
EHCI_QTD_SET_PID(EHCI_QTD_PID_SETUP) |
EHCI_QTD_SET_CERR(3) |
EHCI_QTD_SET_TOGGLE(0) |
EHCI_QTD_SET_BYTES(sizeof *req)
);
- setup->qtd.qtd_buffer[0] = htole32(DMAADDR(&epipe->u.ctl.reqdma, 0));
+ setup->qtd.qtd_buffer[0] = htohc32(sc, DMAADDR(&epipe->u.ctl.reqdma, 0));
setup->qtd.qtd_buffer_hi[0] = 0;
setup->nextqtd = next;
- setup->qtd.qtd_next = htole32(next->physaddr);
- setup->qtd.qtd_altnext = htole32(newinactive->physaddr);
+ setup->qtd.qtd_next = htohc32(sc, next->physaddr);
+ setup->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
setup->xfer = xfer;
setup->len = sizeof *req;
- stat->qtd.qtd_status = htole32(
+ stat->qtd.qtd_status = htohc32(sc,
EHCI_QTD_ACTIVE |
EHCI_QTD_SET_PID(isread ? EHCI_QTD_PID_OUT : EHCI_QTD_PID_IN) |
EHCI_QTD_SET_CERR(3) |
@@ -3326,16 +3134,16 @@ ehci_device_request(usbd_xfer_handle xfer)
stat->qtd.qtd_buffer[0] = 0; /* XXX not needed? */
stat->qtd.qtd_buffer_hi[0] = 0; /* XXX not needed? */
stat->nextqtd = newinactive;
- stat->qtd.qtd_next = htole32(newinactive->physaddr);
- stat->qtd.qtd_altnext = htole32(newinactive->physaddr);
+ stat->qtd.qtd_next = htohc32(sc, newinactive->physaddr);
+ stat->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
stat->xfer = xfer;
stat->len = 0;
#ifdef EHCI_DEBUG
if (ehcidebug > 5) {
DPRINTF(("ehci_device_request:\n"));
- ehci_dump_sqh(sqh);
- ehci_dump_sqtds(setup);
+ ehci_dump_sqh(sc, sqh);
+ ehci_dump_sqtds(sc, setup);
}
#endif
@@ -3350,7 +3158,7 @@ ehci_device_request(usbd_xfer_handle xfer)
/* Activate the new qTD in the QH list. */
s = splusb();
- ehci_activate_qh(sqh, setup);
+ ehci_activate_qh(sc, sqh, setup);
if (xfer->timeout && !sc->sc_bus.use_polling) {
callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
ehci_timeout, xfer);
@@ -3365,9 +3173,9 @@ ehci_device_request(usbd_xfer_handle xfer)
EOREAD4(sc, EHCI_USBSTS)));
delay(10000);
ehci_dump_regs(sc);
- ehci_dump_sqh(sc->sc_async_head);
- ehci_dump_sqh(sqh);
- ehci_dump_sqtds(setup);
+ ehci_dump_sqh(sc, sc->sc_async_head);
+ ehci_dump_sqh(sc, sqh);
+ ehci_dump_sqtds(sc, setup);
}
#endif
@@ -3441,9 +3249,9 @@ ehci_device_bulk_start(usbd_xfer_handle xfer)
usb_transfer_complete(xfer);
return (err);
}
- newinactive->qtd.qtd_status = htole32(0);
- newinactive->qtd.qtd_next = EHCI_NULL;
- newinactive->qtd.qtd_altnext = EHCI_NULL;
+ newinactive->qtd.qtd_status = htohc32(sc, 0);
+ newinactive->qtd.qtd_next = EHCI_NULL(sc);
+ newinactive->qtd.qtd_altnext = EHCI_NULL(sc);
err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
sqh->inactivesqtd, newinactive, &data, &dataend);
if (err) {
@@ -3454,15 +3262,15 @@ ehci_device_bulk_start(usbd_xfer_handle xfer)
return (err);
}
dataend->nextqtd = newinactive;
- dataend->qtd.qtd_next = htole32(newinactive->physaddr);
- dataend->qtd.qtd_altnext = htole32(newinactive->physaddr);
+ dataend->qtd.qtd_next = htohc32(sc, newinactive->physaddr);
+ dataend->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
sqh->inactivesqtd = newinactive;
#ifdef EHCI_DEBUG
if (ehcidebug > 5) {
DPRINTF(("ehci_device_bulk_start: data(1)\n"));
- ehci_dump_sqh(sqh);
- ehci_dump_sqtds(data);
+ ehci_dump_sqh(sc, sqh);
+ ehci_dump_sqtds(sc, data);
}
#endif
@@ -3477,7 +3285,7 @@ ehci_device_bulk_start(usbd_xfer_handle xfer)
#endif
s = splusb();
- ehci_activate_qh(sqh, data);
+ ehci_activate_qh(sc, sqh, data);
if (xfer->timeout && !sc->sc_bus.use_polling) {
callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
ehci_timeout, xfer);
@@ -3497,8 +3305,8 @@ ehci_device_bulk_start(usbd_xfer_handle xfer)
ehci_dump_sqh(sc->sc_async_head);
#endif
printf("sqh:\n");
- ehci_dump_sqh(sqh);
- ehci_dump_sqtds(data);
+ ehci_dump_sqh(sc, sqh);
+ ehci_dump_sqtds(sc, data);
}
#endif
@@ -3566,7 +3374,7 @@ ehci_device_setintr(ehci_softc_t *sc, ehci_soft_qh_t *sqh, int ival)
sqh->islot = islot;
isp = &sc->sc_islots[islot];
- ehci_add_qh(sqh, isp->sqh);
+ ehci_add_qh(sc, sqh, isp->sqh);
return (USBD_NORMAL_COMPLETION);
}
@@ -3627,9 +3435,9 @@ ehci_device_intr_start(usbd_xfer_handle xfer)
usb_transfer_complete(xfer);
return (err);
}
- newinactive->qtd.qtd_status = htole32(0);
- newinactive->qtd.qtd_next = EHCI_NULL;
- newinactive->qtd.qtd_altnext = EHCI_NULL;
+ newinactive->qtd.qtd_status = htohc32(sc, 0);
+ newinactive->qtd.qtd_next = EHCI_NULL(sc);
+ newinactive->qtd.qtd_altnext = EHCI_NULL(sc);
err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
sqh->inactivesqtd, newinactive, &data, &dataend);
if (err) {
@@ -3639,15 +3447,15 @@ ehci_device_intr_start(usbd_xfer_handle xfer)
return (err);
}
dataend->nextqtd = newinactive;
- dataend->qtd.qtd_next = htole32(newinactive->physaddr);
- dataend->qtd.qtd_altnext = htole32(newinactive->physaddr);
+ dataend->qtd.qtd_next = htohc32(sc, newinactive->physaddr);
+ dataend->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
sqh->inactivesqtd = newinactive;
#ifdef EHCI_DEBUG
if (ehcidebug > 5) {
DPRINTF(("ehci_device_intr_start: data(1)\n"));
- ehci_dump_sqh(sqh);
- ehci_dump_sqtds(data);
+ ehci_dump_sqh(sc, sqh);
+ ehci_dump_sqtds(sc, data);
}
#endif
@@ -3662,7 +3470,7 @@ ehci_device_intr_start(usbd_xfer_handle xfer)
#endif
s = splusb();
- ehci_activate_qh(sqh, data);
+ ehci_activate_qh(sc, sqh, data);
if (xfer->timeout && !sc->sc_bus.use_polling) {
callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
ehci_timeout, xfer);
@@ -3678,8 +3486,8 @@ ehci_device_intr_start(usbd_xfer_handle xfer)
DPRINTF(("ehci_device_intr_start: data(3)\n"));
ehci_dump_regs(sc);
printf("sqh:\n");
- ehci_dump_sqh(sqh);
- ehci_dump_sqtds(data);
+ ehci_dump_sqh(sc, sqh);
+ ehci_dump_sqtds(sc, data);
}
#endif
@@ -3750,9 +3558,9 @@ ehci_device_intr_done(usbd_xfer_handle xfer)
xfer->status = err;
return;
}
- newinactive->qtd.qtd_status = htole32(0);
- newinactive->qtd.qtd_next = EHCI_NULL;
- newinactive->qtd.qtd_altnext = EHCI_NULL;
+ newinactive->qtd.qtd_status = htohc32(sc, 0);
+ newinactive->qtd.qtd_next = EHCI_NULL(sc);
+ newinactive->qtd.qtd_altnext = EHCI_NULL(sc);
err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
sqh->inactivesqtd, newinactive, &data, &dataend);
if (err) {
@@ -3761,8 +3569,8 @@ ehci_device_intr_done(usbd_xfer_handle xfer)
return;
}
dataend->nextqtd = newinactive;
- dataend->qtd.qtd_next = htole32(newinactive->physaddr);
- dataend->qtd.qtd_altnext = htole32(newinactive->physaddr);
+ dataend->qtd.qtd_next = htohc32(sc, newinactive->physaddr);
+ dataend->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
sqh->inactivesqtd = newinactive;
/* Set up interrupt info. */
@@ -3777,7 +3585,7 @@ ehci_device_intr_done(usbd_xfer_handle xfer)
#endif
s = splusb();
- ehci_activate_qh(sqh, data);
+ ehci_activate_qh(sc, sqh, data);
if (xfer->timeout && !sc->sc_bus.use_polling) {
callout_reset(&xfer->timeout_handle,
MS_TO_TICKS(xfer->timeout), ehci_timeout, xfer);
@@ -3911,7 +3719,7 @@ ehci_device_isoc_start(usbd_xfer_handle xfer)
if (prev != NULL) {
prev->itd.itd_next =
- htole32(itd->physaddr | EHCI_LINK_ITD);
+ htohc32(sc, itd->physaddr | EHCI_LINK_ITD);
prev->xfer_next = itd;
} else {
start = itd;
@@ -3933,7 +3741,7 @@ ehci_device_isoc_start(usbd_xfer_handle xfer)
* offset is. Works out how many pages that is.
*/
- itd->itd.itd_ctl[j] = htole32 ( EHCI_ITD_ACTIVE |
+ itd->itd.itd_ctl[j] = htohc32(sc, EHCI_ITD_ACTIVE |
EHCI_ITD_SET_LEN(xfer->frlengths[trans_count]) |
EHCI_ITD_SET_PG(addr) |
EHCI_ITD_SET_OFFS(EHCI_PAGE_OFFSET(DMAADDR(dma_buf,
@@ -3944,7 +3752,7 @@ ehci_device_isoc_start(usbd_xfer_handle xfer)
trans_count++;
if (trans_count >= xfer->nframes) { /*Set IOC*/
- itd->itd.itd_ctl[j] |= htole32(EHCI_ITD_IOC);
+ itd->itd.itd_ctl[j] |= htohc32(sc, EHCI_ITD_IOC);
}
}
@@ -3967,7 +3775,7 @@ ehci_device_isoc_start(usbd_xfer_handle xfer)
int page = DMAADDR(dma_buf, page_offs);
page = EHCI_PAGE(page);
itd->itd.itd_bufr[j] =
- htole32(EHCI_ITD_SET_BPTR(page) | EHCI_LINK_ITD);
+ htohc32(sc, EHCI_ITD_SET_BPTR(page) | EHCI_LINK_ITD);
}
/*
@@ -3975,7 +3783,7 @@ ehci_device_isoc_start(usbd_xfer_handle xfer)
*/
k = epipe->pipe.endpoint->edesc->bEndpointAddress;
- itd->itd.itd_bufr[0] |= htole32(
+ itd->itd.itd_bufr[0] |= htohc32(sc,
EHCI_ITD_SET_EP(UE_GET_ADDR(k)) |
EHCI_ITD_SET_DADDR(epipe->pipe.device->address));
@@ -3983,12 +3791,12 @@ ehci_device_isoc_start(usbd_xfer_handle xfer)
? 1 : 0;
j = UE_GET_SIZE(
UGETW(epipe->pipe.endpoint->edesc->wMaxPacketSize));
- itd->itd.itd_bufr[1] |= htole32(EHCI_ITD_SET_DIR(k) |
+ itd->itd.itd_bufr[1] |= htohc32(sc, EHCI_ITD_SET_DIR(k) |
EHCI_ITD_SET_MAXPKT(UE_GET_SIZE(j)));
/* FIXME: handle invalid trans */
itd->itd.itd_bufr[2] |=
- htole32(EHCI_ITD_SET_MULTI(UE_GET_TRANS(j)+1));
+ htohc32(sc, EHCI_ITD_SET_MULTI(UE_GET_TRANS(j)+1));
prev = itd;
} /* End of frame */
@@ -4034,9 +3842,9 @@ ehci_device_isoc_start(usbd_xfer_handle xfer)
if (itd->itd.itd_next == 0)
/* FIXME: frindex table gets initialized to NULL
* or EHCI_NULL? */
- itd->itd.itd_next = htole32(EHCI_NULL);
+ itd->itd.itd_next = EHCI_NULL(sc);
- sc->sc_flist[frindex] = htole32(EHCI_LINK_ITD | itd->physaddr);
+ sc->sc_flist[frindex] = htohc32(sc, EHCI_LINK_ITD | itd->physaddr);
itd->u.frame_list.next = sc->sc_softitds[frindex];
sc->sc_softitds[frindex] = itd;
diff --git a/sys/dev/usb/ehci_ddb.c b/sys/dev/usb/ehci_ddb.c
new file mode 100644
index 0000000..3ebd130
--- /dev/null
+++ b/sys/dev/usb/ehci_ddb.c
@@ -0,0 +1,255 @@
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/endian.h>
+#include <sys/bus.h>
+#include <sys/lock.h>
+#include <sys/lockmgr.h>
+
+#include <machine/bus.h>
+#include <machine/endian.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h>
+
+#include <dev/usb/ehcireg.h>
+#include <dev/usb/ehcivar.h>
+
+#ifdef DDB
+#include <ddb/ddb.h>
+#include <ddb/db_sym.h>
+#else
+#define db_printf printf
+#endif
+
+extern ehci_softc_t *theehci; /* XXX */
+
+void
+ehci_dump_regs(ehci_softc_t *sc)
+{
+ int i;
+ db_printf("cmd=0x%08x, sts=0x%08x, ien=0x%08x\n",
+ EOREAD4(sc, EHCI_USBCMD),
+ EOREAD4(sc, EHCI_USBSTS),
+ EOREAD4(sc, EHCI_USBINTR));
+ db_printf("frindex=0x%08x ctrdsegm=0x%08x periodic=0x%08x async=0x%08x\n",
+ EOREAD4(sc, EHCI_FRINDEX),
+ EOREAD4(sc, EHCI_CTRLDSSEGMENT),
+ EOREAD4(sc, EHCI_PERIODICLISTBASE),
+ EOREAD4(sc, EHCI_ASYNCLISTADDR));
+ for (i = 1; i <= sc->sc_noport; i++)
+ db_printf("port %d status=0x%08x\n", i,
+ EOREAD4(sc, EHCI_PORTSC(i)));
+}
+
+static void
+ehci_dump_link(ehci_softc_t *sc, ehci_link_t link, int type)
+{
+ link = hc32toh(sc, link);
+ db_printf("0x%08x", link);
+ if (link & EHCI_LINK_TERMINATE)
+ db_printf("<T>");
+ else {
+ db_printf("<");
+ if (type) {
+ switch (EHCI_LINK_TYPE(link)) {
+ case EHCI_LINK_ITD: db_printf("ITD"); break;
+ case EHCI_LINK_QH: db_printf("QH"); break;
+ case EHCI_LINK_SITD: db_printf("SITD"); break;
+ case EHCI_LINK_FSTN: db_printf("FSTN"); break;
+ }
+ }
+ db_printf(">");
+ }
+}
+
+void
+ehci_dump_sqtds(ehci_softc_t *sc, ehci_soft_qtd_t *sqtd)
+{
+ int i;
+ u_int32_t stop;
+
+ stop = 0;
+ for (i = 0; sqtd && i < 20 && !stop; sqtd = sqtd->nextqtd, i++) {
+ ehci_dump_sqtd(sc, sqtd);
+ stop = sqtd->qtd.qtd_next & htohc32(sc, EHCI_LINK_TERMINATE);
+ }
+ if (sqtd)
+ db_printf("dump aborted, too many TDs\n");
+}
+
+void
+ehci_dump_qtd(ehci_softc_t *sc, ehci_qtd_t *qtd)
+{
+ u_int32_t s;
+
+ db_printf(" next="); ehci_dump_link(sc, qtd->qtd_next, 0);
+ db_printf(" altnext="); ehci_dump_link(sc, qtd->qtd_altnext, 0);
+ db_printf("\n");
+ s = hc32toh(sc, qtd->qtd_status);
+ db_printf(" status=0x%08x: toggle=%d bytes=0x%x ioc=%d c_page=0x%x\n",
+ s, EHCI_QTD_GET_TOGGLE(s), EHCI_QTD_GET_BYTES(s),
+ EHCI_QTD_GET_IOC(s), EHCI_QTD_GET_C_PAGE(s));
+ db_printf(" cerr=%d pid=%d stat=%b\n", EHCI_QTD_GET_CERR(s),
+ EHCI_QTD_GET_PID(s),
+ EHCI_QTD_GET_STATUS(s), EHCI_QTD_STATUS_BITS);
+ for (s = 0; s < 5; s++)
+ db_printf(" buffer[%d]=0x%08x\n", s, hc32toh(sc, qtd->qtd_buffer[s]));
+}
+
+void
+ehci_dump_sqtd(ehci_softc_t *sc, ehci_soft_qtd_t *sqtd)
+{
+ db_printf("QTD(%p) at 0x%08x:\n", sqtd, sqtd->physaddr);
+ ehci_dump_qtd(sc, &sqtd->qtd);
+}
+
+void
+ehci_dump_sqh(ehci_softc_t *sc, ehci_soft_qh_t *sqh)
+{
+ ehci_qh_t *qh = &sqh->qh;
+ u_int32_t endp, endphub;
+
+ db_printf("QH(%p) at 0x%08x:\n", sqh, sqh->physaddr);
+ db_printf(" sqtd=%p inactivesqtd=%p\n", sqh->sqtd, sqh->inactivesqtd);
+ db_printf(" link="); ehci_dump_link(sc, qh->qh_link, 1); db_printf("\n");
+ endp = hc32toh(sc, qh->qh_endp);
+ db_printf(" endp=0x%08x\n", endp);
+ db_printf(" addr=0x%02x inact=%d endpt=%d eps=%d dtc=%d hrecl=%d\n",
+ EHCI_QH_GET_ADDR(endp), EHCI_QH_GET_INACT(endp),
+ EHCI_QH_GET_ENDPT(endp), EHCI_QH_GET_EPS(endp),
+ EHCI_QH_GET_DTC(endp), EHCI_QH_GET_HRECL(endp));
+ db_printf(" mpl=0x%x ctl=%d nrl=%d\n",
+ EHCI_QH_GET_MPL(endp), EHCI_QH_GET_CTL(endp),
+ EHCI_QH_GET_NRL(endp));
+ endphub = hc32toh(sc, qh->qh_endphub);
+ db_printf(" endphub=0x%08x\n", endphub);
+ db_printf(" smask=0x%02x cmask=0x%02x huba=0x%02x port=%d mult=%d\n",
+ EHCI_QH_GET_SMASK(endphub), EHCI_QH_GET_CMASK(endphub),
+ EHCI_QH_GET_HUBA(endphub), EHCI_QH_GET_PORT(endphub),
+ EHCI_QH_GET_MULT(endphub));
+ db_printf(" curqtd="); ehci_dump_link(sc, qh->qh_curqtd, 0); db_printf("\n");
+ db_printf("Overlay qTD:\n");
+ ehci_dump_qtd(sc, &qh->qh_qtd);
+}
+
+void
+ehci_dump_itd(ehci_softc_t *sc, struct ehci_soft_itd *itd)
+{
+ ehci_isoc_trans_t t;
+ ehci_isoc_bufr_ptr_t b, b2, b3;
+ int i;
+
+ db_printf("ITD: next phys=%X\n", itd->itd.itd_next);
+
+ for (i = 0; i < 8;i++) {
+ t = hc32toh(sc, itd->itd.itd_ctl[i]);
+ db_printf("ITDctl %d: stat=%X len=%X ioc=%X pg=%X offs=%X\n", i,
+ EHCI_ITD_GET_STATUS(t), EHCI_ITD_GET_LEN(t),
+ EHCI_ITD_GET_IOC(t), EHCI_ITD_GET_PG(t),
+ EHCI_ITD_GET_OFFS(t));
+ }
+ db_printf("ITDbufr: ");
+ for (i = 0; i < 7; i++)
+ db_printf("%X,", EHCI_ITD_GET_BPTR(hc32toh(sc, itd->itd.itd_bufr[i])));
+
+ b = hc32toh(sc, itd->itd.itd_bufr[0]);
+ b2 = hc32toh(sc, itd->itd.itd_bufr[1]);
+ b3 = hc32toh(sc, itd->itd.itd_bufr[2]);
+ db_printf("\nep=%X daddr=%X dir=%d maxpkt=%X multi=%X\n",
+ EHCI_ITD_GET_EP(b), EHCI_ITD_GET_DADDR(b), EHCI_ITD_GET_DIR(b2),
+ EHCI_ITD_GET_MAXPKT(b2), EHCI_ITD_GET_MULTI(b3));
+}
+
+void
+ehci_dump_sitd(ehci_softc_t *sc, struct ehci_soft_itd *itd)
+{
+ db_printf("SITD %p next=%p prev=%p xfernext=%p physaddr=%X slot=%d\n",
+ itd, itd->u.frame_list.next, itd->u.frame_list.prev,
+ itd->xfer_next, itd->physaddr, itd->slot);
+}
+
+void
+ehci_dump_exfer(struct ehci_xfer *ex)
+{
+#ifdef DIAGNOSTIC
+ db_printf("%p: sqtdstart %p end %p itdstart %p end %p isdone %d\n",
+ ex, ex->sqtdstart, ex->sqtdend, ex->itdstart,
+ ex->itdend, ex->isdone);
+#else
+ db_printf("%p: sqtdstart %p end %p itdstart %p end %p\n",
+ ex, ex->sqtdstart, ex->sqtdend, ex->itdstart, ex->itdend);
+#endif
+}
+
+#ifdef DDB
+DB_SHOW_COMMAND(ehci, db_show_ehci)
+{
+ if (!have_addr) {
+ db_printf("usage: show ehci <addr>\n");
+ return;
+ }
+ ehci_dump_regs((ehci_softc_t *) addr);
+}
+
+DB_SHOW_COMMAND(ehci_sqtds, db_show_ehci_sqtds)
+{
+ if (!have_addr) {
+ db_printf("usage: show ehci_sqtds <addr>\n");
+ return;
+ }
+ ehci_dump_sqtds(theehci, (ehci_soft_qtd_t *) addr);
+}
+
+DB_SHOW_COMMAND(ehci_qtd, db_show_ehci_qtd)
+{
+ if (!have_addr) {
+ db_printf("usage: show ehci_qtd <addr>\n");
+ return;
+ }
+ ehci_dump_qtd(theehci, (ehci_qtd_t *) addr);
+}
+
+DB_SHOW_COMMAND(ehci_sqh, db_show_ehci_sqh)
+{
+ if (!have_addr) {
+ db_printf("usage: show ehci_sqh <addr>\n");
+ return;
+ }
+ ehci_dump_sqh(theehci, (ehci_soft_qh_t *) addr);
+}
+
+DB_SHOW_COMMAND(ehci_itd, db_show_ehci_itd)
+{
+ if (!have_addr) {
+ db_printf("usage: show ehci_itd <addr>\n");
+ return;
+ }
+ ehci_dump_itd(theehci, (struct ehci_soft_itd *) addr);
+}
+
+DB_SHOW_COMMAND(ehci_sitd, db_show_ehci_sitd)
+{
+ if (!have_addr) {
+ db_printf("usage: show ehci_sitd <addr>\n");
+ return;
+ }
+ ehci_dump_itd(theehci, (struct ehci_soft_itd *) addr);
+}
+
+DB_SHOW_COMMAND(ehci_xfer, db_show_ehci_xfer)
+{
+ if (!have_addr) {
+ db_printf("usage: show ehci_xfer <addr>\n");
+ return;
+ }
+ ehci_dump_exfer((struct ehci_xfer *) addr);
+}
+#endif /* DDB */
diff --git a/sys/dev/usb/ehci_pci.c b/sys/dev/usb/ehci_pci.c
index 46d8e40..1ae2228 100644
--- a/sys/dev/usb/ehci_pci.c
+++ b/sys/dev/usb/ehci_pci.c
@@ -61,8 +61,10 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/queue.h>
#include <sys/lockmgr.h>
-#include <machine/bus.h>
#include <sys/rman.h>
+#include <sys/endian.h>
+
+#include <machine/bus.h>
#include <machine/resource.h>
#include <dev/pci/pcivar.h>
diff --git a/sys/dev/usb/ehcireg.h b/sys/dev/usb/ehcireg.h
index 071ed7f..3c0f5e7 100644
--- a/sys/dev/usb/ehcireg.h
+++ b/sys/dev/usb/ehcireg.h
@@ -173,6 +173,15 @@
#define EHCI_PS_CS 0x00000001 /* RO connect status */
#define EHCI_PS_CLEAR (EHCI_PS_OCC|EHCI_PS_PEC|EHCI_PS_CSC)
+#define EHCI_USBMODE 0x68 /* RW USB Device mode register */
+#define EHCI_UM_CM 0x00000003 /* R/WO Controller Mode */
+#define EHCI_UM_CM_IDLE 0x0 /* Idle */
+#define EHCI_UM_CM_HOST 0x3 /* Host Controller */
+#define EHCI_UM_ES 0x00000004 /* R/WO Endian Select */
+#define EHCI_UM_ES_LE 0x0 /* Little-endian byte alignment */
+#define EHCI_UM_ES_BE 0x4 /* Big-endian byte alignment */
+#define EHCI_UM_SDIS 0x00000010 /* R/WO Stream Disable Mode */
+
#define EHCI_PORT_RESET_COMPLETE 2 /* ms */
#define EHCI_FLALIGN_ALIGN 0x1000
@@ -279,6 +288,9 @@ typedef struct {
} ehci_qtd_t;
#define EHCI_QTD_ALIGN 32
+#define EHCI_QTD_STATUS_BITS \
+ "\20\10ACTIVE\7HALTED\6BUFERR\5BABBLE\4XACTERR\3MISSED\2SPLIT\1PING"
+
/* Queue Head */
typedef struct {
ehci_link_t qh_link;
diff --git a/sys/dev/usb/ehcivar.h b/sys/dev/usb/ehcivar.h
index 55dd196..bf8fb67 100644
--- a/sys/dev/usb/ehcivar.h
+++ b/sys/dev/usb/ehcivar.h
@@ -125,6 +125,7 @@ struct ehci_soft_islot {
#define EHCI_SCFLG_SETMODE 0x0004 /* set bridge mode again after init (Marvell) */
#define EHCI_SCFLG_FORCESPEED 0x0008 /* force speed (Marvell) */
#define EHCI_SCFLG_NORESTERM 0x0010 /* don't terminate reset sequence (Marvell) */
+#define EHCI_SCFLG_BIGEDESC 0x0020 /* big-endian byte order descriptors */
typedef struct ehci_softc {
struct usbd_bus sc_bus; /* base device */
@@ -132,22 +133,16 @@ typedef struct ehci_softc {
bus_space_tag_t iot;
bus_space_handle_t ioh;
bus_size_t sc_size;
-#if defined(__FreeBSD__)
void *ih;
struct resource *io_res;
struct resource *irq_res;
-#endif
u_int sc_offs; /* offset to operational regs */
char sc_vendor[32]; /* vendor string for root hub */
int sc_id_vendor; /* vendor ID for root hub */
u_int32_t sc_cmd; /* shadow of cmd reg during suspend */
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- void *sc_powerhook; /* cookie from power hook */
- void *sc_shutdownhook; /* cookie from shutdown hook */
-#endif
u_int sc_ncomp;
u_int sc_npcomp;
@@ -156,9 +151,6 @@ typedef struct ehci_softc {
usb_dma_t sc_fldma;
ehci_link_t *sc_flist;
u_int sc_flsize;
-#ifndef __FreeBSD__
- u_int sc_rand; /* XXX need proper intr scheduling */
-#endif
struct ehci_soft_islot sc_islots[EHCI_INTRQHS];
@@ -192,9 +184,6 @@ typedef struct ehci_softc {
struct callout sc_tmo_intrlist;
char sc_dying;
-#if defined(__NetBSD__)
- struct usb_dma_reserve sc_dma_reserve;
-#endif
} ehci_softc_t;
#define EREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (a))
@@ -210,14 +199,48 @@ typedef struct ehci_softc {
#define EOWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x))
#define EOWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x))
+/*
+ * Handle byte order conversion between host and ``host controller''.
+ * Typically the latter is little-endian but some controllers require
+ * big-endian in which case we may need to manually swap.
+ */
+static __inline uint32_t
+htohc32(const struct ehci_softc *sc, const uint32_t v)
+{
+ return sc->sc_flags & EHCI_SCFLG_BIGEDESC ? htobe32(v) : htole32(v);
+}
+
+static __inline uint16_t
+htohc16(const struct ehci_softc *sc, const uint16_t v)
+{
+ return sc->sc_flags & EHCI_SCFLG_BIGEDESC ? htobe16(v) : htole16(v);
+}
+
+static __inline uint32_t
+hc32toh(const struct ehci_softc *sc, const uint32_t v)
+{
+ return sc->sc_flags & EHCI_SCFLG_BIGEDESC ? be32toh(v) : le32toh(v);
+}
+
+static __inline uint16_t
+hc16toh(const struct ehci_softc *sc, const uint16_t v)
+{
+ return sc->sc_flags & EHCI_SCFLG_BIGEDESC ? be16toh(v) : le16toh(v);
+}
+
usbd_status ehci_init(ehci_softc_t *);
int ehci_intr(void *);
int ehci_detach(ehci_softc_t *, int);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-int ehci_activate(device_t, enum devact);
-#endif
void ehci_power(int state, void *priv);
void ehci_shutdown(void *v);
#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
+void ehci_dump_regs(ehci_softc_t *);
+void ehci_dump_sqtds(ehci_softc_t *, ehci_soft_qtd_t *);
+void ehci_dump_qtd(ehci_softc_t *, ehci_qtd_t *);
+void ehci_dump_sqtd(ehci_softc_t *, ehci_soft_qtd_t *);
+void ehci_dump_sqh(ehci_softc_t *, ehci_soft_qh_t *);
+void ehci_dump_itd(ehci_softc_t *, struct ehci_soft_itd *);
+void ehci_dump_sitd(ehci_softc_t *, struct ehci_soft_itd *);
+void ehci_dump_exfer(struct ehci_xfer *);
diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h
index d5bb035..ef59039 100644
--- a/sys/dev/usb/usbdi.h
+++ b/sys/dev/usb/usbdi.h
@@ -256,7 +256,8 @@ struct usb_attach_arg {
#define USBD_SHOW_DEVICE_CLASS 0x1
#define USBD_SHOW_INTERFACE_CLASS 0x2
-int usbd_driver_load(module_t mod, int what, void *arg);
+struct module;
+int usbd_driver_load(struct module *mod, int what, void *arg);
static inline int
usb_get_port(device_t dev)
OpenPOWER on IntegriCloud