Subject: Re: port-evbmips/31912: Au1500 OHCI doesn't work when CPU is little
To: None <port-evbmips-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: Garrett D'Amore <garrett_damore@tadpole.com>
List: netbsd-bugs
Date: 11/10/2005 02:32:03
The following reply was made to PR port-evbmips/31912; it has been noted by GNATS.
From: "Garrett D'Amore" <garrett_damore@tadpole.com>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: port-evbmips/31912: Au1500 OHCI doesn't work when CPU is little
endian...
Date: Wed, 09 Nov 2005 18:31:04 -0800
This is a multi-part message in MIME format.
--------------090500010703050906020405
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
gnats-admin@netbsd.org wrote:
>Thank you very much for your problem report.
>It has the internal identification `port-evbmips/31912'.
>The individual assigned to look at your
>report is: port-evbmips-maintainer.
>
>
>
>>Category: port-evbmips
>>Responsible: port-evbmips-maintainer
>>Synopsis: Au1500 OHCI doesn't work when CPU is little endian...
>>Arrival-Date: Tue Oct 25 01:33:01 +0000 2005
>>
>>
I've verified a set of patches, which seems to work. Note that in order
for me to make these verifications, I had to also fix PR kern/32032, so
it might be useful to look at that. (I have not yet had any success
with USB mass storage at all on this platform owing to what I believe
are problems with the disklabel code, and don't have very many other
devices I can verify with. The USB parallel port driver is also
particularly fragile, from what I've seen.)
Attached are my latest fixes for this, which are designed to be
maximally efficient, while not requiring any configuration support in
the kernel config file. (Basically, no need for OHCI_DYNAMIC_ENDIAN
anymore.) I'd like to see these changes get integrated at the earliest
convenience.
--------------090500010703050906020405
Content-Type: text/plain;
name="diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="diff"
Index: sys/dev/usb/ohci.c
===================================================================
RCS file: /net/projects/meteor/cvs/netbsd/src/sys/dev/usb/ohci.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ohci.c
--- sys/dev/usb/ohci.c 9 Nov 2005 14:17:30 -0000 1.1.1.1
+++ sys/dev/usb/ohci.c 10 Nov 2005 02:29:36 -0000
@@ -106,20 +106,17 @@
#define DPRINTFN(n,x)
#endif
-/*
- * The OHCI controller is little endian, so on big endian machines
- * the data stored in memory needs to be swapped.
- */
-#if defined(__FreeBSD__) || defined(__OpenBSD__)
#if BYTE_ORDER == BIG_ENDIAN
-#define htole32(x) (bswap32(x))
-#define le32toh(x) (bswap32(x))
+#define SWAP_ENDIAN OHCI_LITTLE_ENDIAN
#else
-#define htole32(x) (x)
-#define le32toh(x) (x)
-#endif
+#define SWAP_ENDIAN OHCI_BIG_ENDIAN
#endif
+#define O16TOH(val) (sc->sc_endian == SWAP_ENDIAN ? bswap16(val) : val)
+#define O32TOH(val) (sc->sc_endian == SWAP_ENDIAN ? bswap32(val) : val)
+#define HTOO16(val) O16TOH(val)
+#define HTOO32(val) O32TOH(val)
+
struct ohci_pipe;
Static ohci_soft_ed_t *ohci_alloc_sed(ohci_softc_t *);
@@ -148,7 +145,9 @@
Static void ohci_rhsc(ohci_softc_t *, usbd_xfer_handle);
Static usbd_status ohci_device_request(usbd_xfer_handle xfer);
-Static void ohci_add_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
+Static void ohci_add_ed(ohci_softc_t *, ohci_soft_ed_t *,
+ ohci_soft_ed_t *);
+
Static void ohci_rem_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
Static void ohci_hash_add_td(ohci_softc_t *, ohci_soft_td_t *);
Static void ohci_hash_rem_td(ohci_softc_t *, ohci_soft_td_t *);
@@ -219,11 +218,11 @@
#ifdef OHCI_DEBUG
Static void ohci_dumpregs(ohci_softc_t *);
-Static void ohci_dump_tds(ohci_soft_td_t *);
-Static void ohci_dump_td(ohci_soft_td_t *);
-Static void ohci_dump_ed(ohci_soft_ed_t *);
-Static void ohci_dump_itd(ohci_soft_itd_t *);
-Static void ohci_dump_itds(ohci_soft_itd_t *);
+Static void ohci_dump_tds(ohci_softc_t *, ohci_soft_td_t *);
+Static void ohci_dump_td(ohci_softc_t *, ohci_soft_td_t *);
+Static void ohci_dump_ed(ohci_softc_t *, ohci_soft_ed_t *);
+Static void ohci_dump_itd(ohci_softc_t *, ohci_soft_itd_t *);
+Static void ohci_dump_itds(ohci_softc_t *, ohci_soft_itd_t *);
#endif
#define OBARR(sc) bus_space_barrier((sc)->iot, (sc)->ioh, 0, (sc)->sc_size, \
@@ -493,7 +492,7 @@
cur = sp;
dataphys = DMAADDR(dma, 0);
dataphysend = OHCI_PAGE(dataphys + len - 1);
- tdflags = htole32(
+ tdflags = HTOO32(
(rd ? OHCI_TD_IN : OHCI_TD_OUT) |
(flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) |
OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY | OHCI_TD_NOINTR);
@@ -526,10 +525,10 @@
len -= curlen;
cur->td.td_flags = tdflags;
- cur->td.td_cbp = htole32(dataphys);
+ cur->td.td_cbp = HTOO32(dataphys);
cur->nexttd = next;
- cur->td.td_nexttd = htole32(next->physaddr);
- cur->td.td_be = htole32(dataphys + curlen - 1);
+ cur->td.td_nexttd = HTOO32(next->physaddr);
+ cur->td.td_be = HTOO32(dataphys + curlen - 1);
cur->len = curlen;
cur->flags = OHCI_ADD_LEN;
cur->xfer = xfer;
@@ -553,7 +552,7 @@
cur->td.td_flags = tdflags;
cur->td.td_cbp = 0; /* indicate 0 length packet */
cur->nexttd = next;
- cur->td.td_nexttd = htole32(next->physaddr);
+ cur->td.td_nexttd = HTOO32(next->physaddr);
cur->td.td_be = ~0;
cur->len = 0;
cur->flags = 0;
@@ -702,7 +701,7 @@
err = USBD_NOMEM;
goto bad1;
}
- sc->sc_ctrl_head->ed.ed_flags |= htole32(OHCI_ED_SKIP);
+ sc->sc_ctrl_head->ed.ed_flags |= HTOO32(OHCI_ED_SKIP);
/* Allocate dummy ED that starts the bulk list. */
sc->sc_bulk_head = ohci_alloc_sed(sc);
@@ -710,7 +709,7 @@
err = USBD_NOMEM;
goto bad2;
}
- sc->sc_bulk_head->ed.ed_flags |= htole32(OHCI_ED_SKIP);
+ sc->sc_bulk_head->ed.ed_flags |= HTOO32(OHCI_ED_SKIP);
/* Allocate dummy ED that starts the isochronous list. */
sc->sc_isoc_head = ohci_alloc_sed(sc);
@@ -718,7 +717,7 @@
err = USBD_NOMEM;
goto bad3;
}
- sc->sc_isoc_head->ed.ed_flags |= htole32(OHCI_ED_SKIP);
+ sc->sc_isoc_head->ed.ed_flags |= HTOO32(OHCI_ED_SKIP);
/* Allocate all the dummy EDs that make up the interrupt tree. */
for (i = 0; i < OHCI_NO_EDS; i++) {
@@ -731,13 +730,13 @@
}
/* All ED fields are set to 0. */
sc->sc_eds[i] = sed;
- sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
+ sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP);
if (i != 0)
psed = sc->sc_eds[(i-1) / 2];
else
psed= sc->sc_isoc_head;
sed->next = psed;
- sed->ed.ed_nexted = htole32(psed->physaddr);
+ sed->ed.ed_nexted = HTOO32(psed->physaddr);
}
/*
* Fill HCCA interrupt table. The bit reversal is to get
@@ -745,16 +744,16 @@
*/
for (i = 0; i < OHCI_NO_INTRS; i++)
sc->sc_hcca->hcca_interrupt_table[revbits[i]] =
- htole32(sc->sc_eds[OHCI_NO_EDS-OHCI_NO_INTRS+i]->physaddr);
+ HTOO32(sc->sc_eds[OHCI_NO_EDS-OHCI_NO_INTRS+i]->physaddr);
#ifdef OHCI_DEBUG
if (ohcidebug > 15) {
for (i = 0; i < OHCI_NO_EDS; i++) {
printf("ed#%d ", i);
- ohci_dump_ed(sc->sc_eds[i]);
+ ohci_dump_ed(sc, sc->sc_eds[i]);
}
printf("iso ");
- ohci_dump_ed(sc->sc_isoc_head);
+ ohci_dump_ed(sc, sc->sc_isoc_head);
}
#endif
@@ -1102,8 +1101,8 @@
OREAD4(sc, OHCI_RH_PORT_STATUS(1)),
OREAD4(sc, OHCI_RH_PORT_STATUS(2))));
DPRINTF((" HCCA: frame_number=0x%04x done_head=0x%08x\n",
- le32toh(sc->sc_hcca->hcca_frame_number),
- le32toh(sc->sc_hcca->hcca_done_head)));
+ O32TOH(sc->sc_hcca->hcca_frame_number),
+ O32TOH(sc->sc_hcca->hcca_done_head)));
}
#endif
@@ -1262,7 +1261,7 @@
sc->sc_bus.intr_context++;
s = splhardusb();
- done = le32toh(sc->sc_hcca->hcca_done_head) & ~OHCI_DONE_INTRS;
+ done = O32TOH(sc->sc_hcca->hcca_done_head) & ~OHCI_DONE_INTRS;
sc->sc_hcca->hcca_done_head = 0;
OWRITE4(sc, OHCI_INTERRUPT_STATUS, OHCI_WDH);
sc->sc_eintrs |= OHCI_WDH;
@@ -1274,7 +1273,7 @@
std = ohci_hash_find_td(sc, done);
if (std != NULL) {
std->dnext = sdone;
- done = le32toh(std->td.td_nexttd);
+ done = O32TOH(std->td.td_nexttd);
sdone = std;
DPRINTFN(10,("add TD %p\n", std));
continue;
@@ -1282,7 +1281,7 @@
sitd = ohci_hash_find_itd(sc, done);
if (sitd != NULL) {
sitd->dnext = sidone;
- done = le32toh(sitd->itd.itd_nextitd);
+ done = O32TOH(sitd->itd.itd_nextitd);
sidone = sitd;
DPRINTFN(5,("add ITD %p\n", sitd));
continue;
@@ -1295,7 +1294,7 @@
#ifdef OHCI_DEBUG
if (ohcidebug > 10) {
DPRINTF(("ohci_process_done: TD done:\n"));
- ohci_dump_tds(sdone);
+ ohci_dump_tds(sc, sdone);
}
#endif
@@ -1324,14 +1323,14 @@
len = std->len;
if (std->td.td_cbp != 0)
- len -= le32toh(std->td.td_be) -
- le32toh(std->td.td_cbp) + 1;
+ len -= O32TOH(std->td.td_be) -
+ O32TOH(std->td.td_cbp) + 1;
DPRINTFN(10, ("ohci_process_done: len=%d, flags=0x%x\n", len,
std->flags));
if (std->flags & OHCI_ADD_LEN)
xfer->actlen += len;
- cc = OHCI_TD_GET_CC(le32toh(std->td.td_flags));
+ cc = OHCI_TD_GET_CC(O32TOH(std->td.td_flags));
if (cc == OHCI_CC_NO_ERROR) {
if (std->flags & OHCI_CALL_DONE) {
xfer->status = USBD_NORMAL_COMPLETION;
@@ -1350,8 +1349,8 @@
opipe = (struct ohci_pipe *)xfer->pipe;
DPRINTFN(15,("ohci_process_done: error cc=%d (%s)\n",
- OHCI_TD_GET_CC(le32toh(std->td.td_flags)),
- ohci_cc_strs[OHCI_TD_GET_CC(le32toh(std->td.td_flags))]));
+ OHCI_TD_GET_CC(O32TOH(std->td.td_flags)),
+ ohci_cc_strs[OHCI_TD_GET_CC(O32TOH(std->td.td_flags))]));
/* remove TDs */
for (p = std; p->xfer == xfer; p = n) {
@@ -1360,7 +1359,7 @@
}
/* clear halt */
- opipe->sed->ed.ed_headp = htole32(p->physaddr);
+ opipe->sed->ed.ed_headp = HTOO32(p->physaddr);
OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
if (cc == OHCI_CC_STALL)
@@ -1376,7 +1375,7 @@
#ifdef OHCI_DEBUG
if (ohcidebug > 10) {
DPRINTF(("ohci_softintr: ITD done:\n"));
- ohci_dump_itds(sidone);
+ ohci_dump_itds(sc, sidone);
}
#endif
@@ -1411,17 +1410,17 @@
for (i = 0, sitd = xfer->hcpriv;;
sitd = next) {
next = sitd->nextitd;
- if (OHCI_ITD_GET_CC(le32toh(sitd->
+ if (OHCI_ITD_GET_CC(O32TOH(sitd->
itd.itd_flags)) != OHCI_CC_NO_ERROR)
xfer->status = USBD_IOERROR;
/* For input, update frlengths with actual */
/* XXX anything necessary for output? */
if (uedir == UE_DIR_IN &&
xfer->status == USBD_NORMAL_COMPLETION) {
- iframes = OHCI_ITD_GET_FC(le32toh(
+ iframes = OHCI_ITD_GET_FC(O32TOH(
sitd->itd.itd_flags));
for (j = 0; j < iframes; i++, j++) {
- len = le16toh(sitd->
+ len = O16TOH(sitd->
itd.itd_offset[j]);
if ((OHCI_ITD_PSW_GET_CC(len) &
OHCI_CC_NOT_ACCESSED_MASK)
@@ -1493,15 +1492,15 @@
}
tail->xfer = NULL;
- data->td.td_flags = htole32(
+ data->td.td_flags = HTOO32(
OHCI_TD_IN | OHCI_TD_NOCC |
OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY);
if (xfer->flags & USBD_SHORT_XFER_OK)
- data->td.td_flags |= htole32(OHCI_TD_R);
- data->td.td_cbp = htole32(DMAADDR(&xfer->dmabuf, 0));
+ data->td.td_flags |= HTOO32(OHCI_TD_R);
+ data->td.td_cbp = HTOO32(DMAADDR(&xfer->dmabuf, 0));
data->nexttd = tail;
- data->td.td_nexttd = htole32(tail->physaddr);
- data->td.td_be = htole32(le32toh(data->td.td_cbp) +
+ data->td.td_nexttd = HTOO32(tail->physaddr);
+ data->td.td_be = HTOO32(O32TOH(data->td.td_cbp) +
xfer->length - 1);
data->len = xfer->length;
data->xfer = xfer;
@@ -1509,7 +1508,7 @@
xfer->hcpriv = data;
xfer->actlen = 0;
- sed->ed.ed_tailp = htole32(tail->physaddr);
+ sed->ed.ed_tailp = HTOO32(tail->physaddr);
opipe->tail.td = tail;
}
}
@@ -1663,8 +1662,8 @@
during the setup of the control pipe in usbd_new_device(). */
/* XXX This only needs to be done once, but it's too early in open. */
/* XXXX Should not touch ED here! */
- sed->ed.ed_flags = htole32(
- (le32toh(sed->ed.ed_flags) & ~(OHCI_ED_ADDRMASK | OHCI_ED_MAXPMASK)) |
+ sed->ed.ed_flags = HTOO32(
+ (O32TOH(sed->ed.ed_flags) & ~(OHCI_ED_ADDRMASK | OHCI_ED_MAXPMASK)) |
OHCI_ED_SET_FA(addr) |
OHCI_ED_SET_MAXP(UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize)));
@@ -1680,29 +1679,29 @@
if (err)
goto bad3;
/* Start toggle at 1 and then use the carried toggle. */
- std->td.td_flags &= htole32(~OHCI_TD_TOGGLE_MASK);
- std->td.td_flags |= htole32(OHCI_TD_TOGGLE_1);
+ std->td.td_flags &= HTOO32(~OHCI_TD_TOGGLE_MASK);
+ std->td.td_flags |= HTOO32(OHCI_TD_TOGGLE_1);
}
memcpy(KERNADDR(&opipe->u.ctl.reqdma, 0), req, sizeof *req);
- setup->td.td_flags = htole32(OHCI_TD_SETUP | OHCI_TD_NOCC |
+ setup->td.td_flags = HTOO32(OHCI_TD_SETUP | OHCI_TD_NOCC |
OHCI_TD_TOGGLE_0 | OHCI_TD_NOINTR);
- setup->td.td_cbp = htole32(DMAADDR(&opipe->u.ctl.reqdma, 0));
+ setup->td.td_cbp = HTOO32(DMAADDR(&opipe->u.ctl.reqdma, 0));
setup->nexttd = next;
- setup->td.td_nexttd = htole32(next->physaddr);
- setup->td.td_be = htole32(le32toh(setup->td.td_cbp) + sizeof *req - 1);
+ setup->td.td_nexttd = HTOO32(next->physaddr);
+ setup->td.td_be = HTOO32(O32TOH(setup->td.td_cbp) + sizeof *req - 1);
setup->len = 0;
setup->xfer = xfer;
setup->flags = 0;
xfer->hcpriv = setup;
- stat->td.td_flags = htole32(
+ stat->td.td_flags = HTOO32(
(isread ? OHCI_TD_OUT : OHCI_TD_IN) |
OHCI_TD_NOCC | OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DI(1));
stat->td.td_cbp = 0;
stat->nexttd = tail;
- stat->td.td_nexttd = htole32(tail->physaddr);
+ stat->td.td_nexttd = HTOO32(tail->physaddr);
stat->td.td_be = 0;
stat->flags = OHCI_CALL_DONE;
stat->len = 0;
@@ -1711,14 +1710,14 @@
#ifdef OHCI_DEBUG
if (ohcidebug > 5) {
DPRINTF(("ohci_device_request:\n"));
- ohci_dump_ed(sed);
- ohci_dump_tds(setup);
+ ohci_dump_ed(sc, sed);
+ ohci_dump_tds(sc, setup);
}
#endif
/* Insert ED in schedule */
s = splusb();
- sed->ed.ed_tailp = htole32(tail->physaddr);
+ sed->ed.ed_tailp = HTOO32(tail->physaddr);
opipe->tail.td = tail;
OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
if (xfer->timeout && !sc->sc_bus.use_polling) {
@@ -1734,10 +1733,10 @@
OREAD4(sc, OHCI_COMMAND_STATUS)));
ohci_dumpregs(sc);
printf("ctrl head:\n");
- ohci_dump_ed(sc->sc_ctrl_head);
+ ohci_dump_ed(sc, sc->sc_ctrl_head);
printf("sed:\n");
- ohci_dump_ed(sed);
- ohci_dump_tds(setup);
+ ohci_dump_ed(sc, sed);
+ ohci_dump_tds(sc, setup);
}
#endif
@@ -1755,7 +1754,7 @@
* Add an ED to the schedule. Called at splusb().
*/
void
-ohci_add_ed(ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
+ohci_add_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
{
DPRINTFN(8,("ohci_add_ed: sed=%p head=%p\n", sed, head));
@@ -1763,7 +1762,7 @@
sed->next = head->next;
sed->ed.ed_nexted = head->ed.ed_nexted;
head->next = sed;
- head->ed.ed_nexted = htole32(sed->physaddr);
+ head->ed.ed_nexted = HTOO32(sed->physaddr);
}
/*
@@ -1904,80 +1903,80 @@
#ifdef OHCI_DEBUG
void
-ohci_dump_tds(ohci_soft_td_t *std)
+ohci_dump_tds(ohci_softc_t *sc, ohci_soft_td_t *std)
{
for (; std; std = std->nexttd)
- ohci_dump_td(std);
+ ohci_dump_td(sc, std);
}
void
-ohci_dump_td(ohci_soft_td_t *std)
+ohci_dump_td(ohci_softc_t *sc, ohci_soft_td_t *std)
{
char sbuf[128];
- bitmask_snprintf((u_int32_t)le32toh(std->td.td_flags),
+ bitmask_snprintf((u_int32_t)O32TOH(std->td.td_flags),
"\20\23R\24OUT\25IN\31TOG1\32SETTOGGLE",
sbuf, sizeof(sbuf));
printf("TD(%p) at %08lx: %s delay=%d ec=%d cc=%d\ncbp=0x%08lx "
"nexttd=0x%08lx be=0x%08lx\n",
std, (u_long)std->physaddr, sbuf,
- OHCI_TD_GET_DI(le32toh(std->td.td_flags)),
- OHCI_TD_GET_EC(le32toh(std->td.td_flags)),
- OHCI_TD_GET_CC(le32toh(std->td.td_flags)),
- (u_long)le32toh(std->td.td_cbp),
- (u_long)le32toh(std->td.td_nexttd),
- (u_long)le32toh(std->td.td_be));
+ OHCI_TD_GET_DI(O32TOH(std->td.td_flags)),
+ OHCI_TD_GET_EC(O32TOH(std->td.td_flags)),
+ OHCI_TD_GET_CC(O32TOH(std->td.td_flags)),
+ (u_long)O32TOH(std->td.td_cbp),
+ (u_long)O32TOH(std->td.td_nexttd),
+ (u_long)O32TOH(std->td.td_be));
}
void
-ohci_dump_itd(ohci_soft_itd_t *sitd)
+ohci_dump_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
{
int i;
printf("ITD(%p) at %08lx: sf=%d di=%d fc=%d cc=%d\n"
"bp0=0x%08lx next=0x%08lx be=0x%08lx\n",
sitd, (u_long)sitd->physaddr,
- OHCI_ITD_GET_SF(le32toh(sitd->itd.itd_flags)),
- OHCI_ITD_GET_DI(le32toh(sitd->itd.itd_flags)),
- OHCI_ITD_GET_FC(le32toh(sitd->itd.itd_flags)),
- OHCI_ITD_GET_CC(le32toh(sitd->itd.itd_flags)),
- (u_long)le32toh(sitd->itd.itd_bp0),
- (u_long)le32toh(sitd->itd.itd_nextitd),
- (u_long)le32toh(sitd->itd.itd_be));
+ OHCI_ITD_GET_SF(O32TOH(sitd->itd.itd_flags)),
+ OHCI_ITD_GET_DI(O32TOH(sitd->itd.itd_flags)),
+ OHCI_ITD_GET_FC(O32TOH(sitd->itd.itd_flags)),
+ OHCI_ITD_GET_CC(O32TOH(sitd->itd.itd_flags)),
+ (u_long)O32TOH(sitd->itd.itd_bp0),
+ (u_long)O32TOH(sitd->itd.itd_nextitd),
+ (u_long)O32TOH(sitd->itd.itd_be));
for (i = 0; i < OHCI_ITD_NOFFSET; i++)
printf("offs[%d]=0x%04x ", i,
- (u_int)le16toh(sitd->itd.itd_offset[i]));
+ (u_int)O16TOH(sitd->itd.itd_offset[i]));
printf("\n");
}
void
-ohci_dump_itds(ohci_soft_itd_t *sitd)
+ohci_dump_itds(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
{
for (; sitd; sitd = sitd->nextitd)
- ohci_dump_itd(sitd);
+ ohci_dump_itd(sc, sitd);
}
void
-ohci_dump_ed(ohci_soft_ed_t *sed)
+ohci_dump_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed)
{
char sbuf[128], sbuf2[128];
- bitmask_snprintf((u_int32_t)le32toh(sed->ed.ed_flags),
+ bitmask_snprintf((u_int32_t)O32TOH(sed->ed.ed_flags),
"\20\14OUT\15IN\16LOWSPEED\17SKIP\20ISO",
sbuf, sizeof(sbuf));
- bitmask_snprintf((u_int32_t)le32toh(sed->ed.ed_headp),
+ bitmask_snprintf((u_int32_t)O32TOH(sed->ed.ed_headp),
"\20\1HALT\2CARRY", sbuf2, sizeof(sbuf2));
printf("ED(%p) at 0x%08lx: addr=%d endpt=%d maxp=%d flags=%s\ntailp=0x%08lx "
"headflags=%s headp=0x%08lx nexted=0x%08lx\n",
sed, (u_long)sed->physaddr,
- OHCI_ED_GET_FA(le32toh(sed->ed.ed_flags)),
- OHCI_ED_GET_EN(le32toh(sed->ed.ed_flags)),
- OHCI_ED_GET_MAXP(le32toh(sed->ed.ed_flags)), sbuf,
- (u_long)le32toh(sed->ed.ed_tailp), sbuf2,
- (u_long)le32toh(sed->ed.ed_headp),
- (u_long)le32toh(sed->ed.ed_nexted));
+ OHCI_ED_GET_FA(O32TOH(sed->ed.ed_flags)),
+ OHCI_ED_GET_EN(O32TOH(sed->ed.ed_flags)),
+ OHCI_ED_GET_MAXP(O32TOH(sed->ed.ed_flags)), sbuf,
+ (u_long)O32TOH(sed->ed.ed_tailp), sbuf2,
+ (u_long)O32TOH(sed->ed.ed_headp),
+ (u_long)O32TOH(sed->ed.ed_nexted));
}
#endif
@@ -2043,13 +2042,13 @@
tdphys = std->physaddr;
fmt = OHCI_ED_FORMAT_GEN | OHCI_ED_DIR_TD;
}
- sed->ed.ed_flags = htole32(
+ sed->ed.ed_flags = HTOO32(
OHCI_ED_SET_FA(addr) |
OHCI_ED_SET_EN(UE_GET_ADDR(ed->bEndpointAddress)) |
(dev->speed == USB_SPEED_LOW ? OHCI_ED_SPEED : 0) |
fmt |
OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize)));
- sed->ed.ed_headp = sed->ed.ed_tailp = htole32(tdphys);
+ sed->ed.ed_headp = sed->ed.ed_tailp = HTOO32(tdphys);
switch (xfertype) {
case UE_CONTROL:
@@ -2060,7 +2059,7 @@
if (err)
goto bad;
s = splusb();
- ohci_add_ed(sed, sc->sc_ctrl_head);
+ ohci_add_ed(sc, sed, sc->sc_ctrl_head);
splx(s);
break;
case UE_INTERRUPT:
@@ -2075,7 +2074,7 @@
case UE_BULK:
pipe->methods = &ohci_device_bulk_methods;
s = splusb();
- ohci_add_ed(sed, sc->sc_bulk_head);
+ ohci_add_ed(sc, sed, sc->sc_bulk_head);
splx(s);
break;
}
@@ -2107,27 +2106,27 @@
s = splusb();
#ifdef DIAGNOSTIC
- sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
- if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
- (le32toh(sed->ed.ed_headp) & OHCI_HEADMASK)) {
+ sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP);
+ if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
+ (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK)) {
ohci_soft_td_t *std;
- std = ohci_hash_find_td(sc, le32toh(sed->ed.ed_headp));
+ std = ohci_hash_find_td(sc, O32TOH(sed->ed.ed_headp));
printf("ohci_close_pipe: pipe not empty sed=%p hd=0x%x "
"tl=0x%x pipe=%p, std=%p\n", sed,
- (int)le32toh(sed->ed.ed_headp),
- (int)le32toh(sed->ed.ed_tailp),
+ (int)O32TOH(sed->ed.ed_headp),
+ (int)O32TOH(sed->ed.ed_tailp),
pipe, std);
#ifdef USB_DEBUG
usbd_dump_pipe(&opipe->pipe);
#endif
#ifdef OHCI_DEBUG
- ohci_dump_ed(sed);
+ ohci_dump_ed(sc, sed);
if (std)
- ohci_dump_td(std);
+ ohci_dump_td(sc, std);
#endif
usb_delay_ms(&sc->sc_bus, 2);
- if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
- (le32toh(sed->ed.ed_headp) & OHCI_HEADMASK))
+ if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
+ (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK))
printf("ohci_close_pipe: pipe still not empty\n");
}
#endif
@@ -2201,7 +2200,7 @@
usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer);
splx(s);
DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed));
- sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* force hardware skip */
+ sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); /* force hardware skip */
/*
* Step 2: Wait until we know hardware has finished any possible
@@ -2239,11 +2238,11 @@
#ifdef OHCI_DEBUG
if (ohcidebug > 1) {
DPRINTF(("ohci_abort_xfer: sed=\n"));
- ohci_dump_ed(sed);
- ohci_dump_tds(p);
+ ohci_dump_ed(sc, sed);
+ ohci_dump_tds(sc, p);
}
#endif
- headp = le32toh(sed->ed.ed_headp) & OHCI_HEADMASK;
+ headp = O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK;
hit = 0;
for (; p->xfer == xfer; p = n) {
hit |= headp == p->physaddr;
@@ -2253,8 +2252,8 @@
/* Zap headp register if hardware pointed inside the xfer. */
if (hit) {
DPRINTFN(1,("ohci_abort_xfer: set hd=0x%08x, tl=0x%08x\n",
- (int)p->physaddr, (int)le32toh(sed->ed.ed_tailp)));
- sed->ed.ed_headp = htole32(p->physaddr); /* unlink TDs */
+ (int)p->physaddr, (int)O32TOH(sed->ed.ed_tailp)));
+ sed->ed.ed_headp = HTOO32(p->physaddr); /* unlink TDs */
} else {
DPRINTFN(1,("ohci_abort_xfer: no hit\n"));
}
@@ -2262,7 +2261,7 @@
/*
* Step 4: Turn on hardware again.
*/
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); /* remove hardware skip */
+ sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); /* remove hardware skip */
/*
* Step 5: Execute callback.
@@ -2818,8 +2817,9 @@
ohci_device_clear_toggle(usbd_pipe_handle pipe)
{
struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
+ ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
- opipe->sed->ed.ed_headp &= htole32(~OHCI_TOGGLECARRY);
+ opipe->sed->ed.ed_headp &= HTOO32(~OHCI_TOGGLECARRY);
}
Static void
@@ -2877,8 +2877,8 @@
opipe->u.bulk.length = len;
/* Update device address */
- sed->ed.ed_flags = htole32(
- (le32toh(sed->ed.ed_flags) & ~OHCI_ED_ADDRMASK) |
+ sed->ed.ed_flags = HTOO32(
+ (O32TOH(sed->ed.ed_flags) & ~OHCI_ED_ADDRMASK) |
OHCI_ED_SET_FA(addr));
/* Allocate a chain of new TDs (including a new tail). */
@@ -2886,8 +2886,8 @@
err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer,
data, &tail);
/* We want interrupt at the end of the transfer. */
- tail->td.td_flags &= htole32(~OHCI_TD_INTR_MASK);
- tail->td.td_flags |= htole32(OHCI_TD_SET_DI(1));
+ tail->td.td_flags &= HTOO32(~OHCI_TD_INTR_MASK);
+ tail->td.td_flags |= HTOO32(OHCI_TD_SET_DI(1));
tail->flags |= OHCI_CALL_DONE;
tail = tail->nexttd; /* point at sentinel */
if (err)
@@ -2898,15 +2898,15 @@
DPRINTFN(4,("ohci_device_bulk_start: ed_flags=0x%08x td_flags=0x%08x "
"td_cbp=0x%08x td_be=0x%08x\n",
- (int)le32toh(sed->ed.ed_flags),
- (int)le32toh(data->td.td_flags),
- (int)le32toh(data->td.td_cbp),
- (int)le32toh(data->td.td_be)));
+ (int)O32TOH(sed->ed.ed_flags),
+ (int)O32TOH(data->td.td_flags),
+ (int)O32TOH(data->td.td_cbp),
+ (int)O32TOH(data->td.td_be)));
#ifdef OHCI_DEBUG
if (ohcidebug > 5) {
- ohci_dump_ed(sed);
- ohci_dump_tds(data);
+ ohci_dump_ed(sc, sed);
+ ohci_dump_tds(sc, data);
}
#endif
@@ -2915,9 +2915,9 @@
for (tdp = data; tdp != tail; tdp = tdp->nexttd) {
tdp->xfer = xfer;
}
- sed->ed.ed_tailp = htole32(tail->physaddr);
+ sed->ed.ed_tailp = HTOO32(tail->physaddr);
opipe->tail.td = tail;
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
+ sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP);
OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
if (xfer->timeout && !sc->sc_bus.use_polling) {
usb_callout(xfer->timeout_handle, mstohz(xfer->timeout),
@@ -2930,8 +2930,8 @@
delay(10000);
DPRINTF(("ohci_device_intr_transfer: status=%x\n",
OREAD4(sc, OHCI_COMMAND_STATUS)));
- ohci_dump_ed(sed);
- ohci_dump_tds(data);
+ ohci_dump_ed(sc, sed);
+ ohci_dump_tds(sc, data);
}
#endif
@@ -3009,16 +3009,16 @@
return (USBD_NOMEM);
tail->xfer = NULL;
- data->td.td_flags = htole32(
+ data->td.td_flags = HTOO32(
isread ? OHCI_TD_IN : OHCI_TD_OUT |
OHCI_TD_NOCC |
OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY);
if (xfer->flags & USBD_SHORT_XFER_OK)
- data->td.td_flags |= htole32(OHCI_TD_R);
- data->td.td_cbp = htole32(DMAADDR(&xfer->dmabuf, 0));
+ data->td.td_flags |= HTOO32(OHCI_TD_R);
+ data->td.td_cbp = HTOO32(DMAADDR(&xfer->dmabuf, 0));
data->nexttd = tail;
- data->td.td_nexttd = htole32(tail->physaddr);
- data->td.td_be = htole32(le32toh(data->td.td_cbp) + len - 1);
+ data->td.td_nexttd = HTOO32(tail->physaddr);
+ data->td.td_be = HTOO32(O32TOH(data->td.td_cbp) + len - 1);
data->len = len;
data->xfer = xfer;
data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
@@ -3027,16 +3027,16 @@
#ifdef OHCI_DEBUG
if (ohcidebug > 5) {
DPRINTF(("ohci_device_intr_transfer:\n"));
- ohci_dump_ed(sed);
- ohci_dump_tds(data);
+ ohci_dump_ed(sc, sed);
+ ohci_dump_tds(sc, data);
}
#endif
/* Insert ED in schedule */
s = splusb();
- sed->ed.ed_tailp = htole32(tail->physaddr);
+ sed->ed.ed_tailp = HTOO32(tail->physaddr);
opipe->tail.td = tail;
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
+ sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP);
#if 0
/*
@@ -3048,8 +3048,8 @@
usb_delay_ms(&sc->sc_bus, 5);
DPRINTF(("ohci_device_intr_transfer: status=%x\n",
OREAD4(sc, OHCI_COMMAND_STATUS)));
- ohci_dump_ed(sed);
- ohci_dump_tds(data);
+ ohci_dump_ed(sc, sed);
+ ohci_dump_tds(sc, data);
}
#endif
splx(s);
@@ -3083,9 +3083,9 @@
DPRINTFN(1,("ohci_device_intr_close: pipe=%p nslots=%d pos=%d\n",
pipe, nslots, pos));
s = splusb();
- sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
- if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
- (le32toh(sed->ed.ed_headp) & OHCI_HEADMASK))
+ sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP);
+ if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
+ (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK))
usb_delay_ms(&sc->sc_bus, 2);
for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next)
@@ -3155,7 +3155,7 @@
sed->next = hsed->next;
sed->ed.ed_nexted = hsed->ed.ed_nexted;
hsed->next = sed;
- hsed->ed.ed_nexted = htole32(sed->physaddr);
+ hsed->ed.ed_nexted = HTOO32(sed->physaddr);
splx(s);
for (j = 0; j < nslots; j++)
@@ -3217,7 +3217,7 @@
if (iso->next == -1) {
/* Not in use yet, schedule it a few frames ahead. */
- iso->next = le32toh(sc->sc_hcca->hcca_frame_number) + 5;
+ iso->next = O32TOH(sc->sc_hcca->hcca_frame_number) + 5;
DPRINTFN(2,("ohci_device_isoc_enter: start next=%d\n",
iso->next));
}
@@ -3243,15 +3243,15 @@
}
/* Fill current ITD */
- sitd->itd.itd_flags = htole32(
+ sitd->itd.itd_flags = HTOO32(
OHCI_ITD_NOCC |
OHCI_ITD_SET_SF(iso->next) |
OHCI_ITD_SET_DI(6) | /* delay intr a little */
OHCI_ITD_SET_FC(ncur));
- sitd->itd.itd_bp0 = htole32(bp0);
+ sitd->itd.itd_bp0 = HTOO32(bp0);
sitd->nextitd = nsitd;
- sitd->itd.itd_nextitd = htole32(nsitd->physaddr);
- sitd->itd.itd_be = htole32(bp0 + offs - 1);
+ sitd->itd.itd_nextitd = HTOO32(nsitd->physaddr);
+ sitd->itd.itd_be = HTOO32(bp0 + offs - 1);
sitd->xfer = xfer;
sitd->flags = 0;
@@ -3260,7 +3260,7 @@
bp0 = OHCI_PAGE(buf + offs);
ncur = 0;
}
- sitd->itd.itd_offset[ncur] = htole16(OHCI_ITD_MK_OFFS(offs));
+ sitd->itd.itd_offset[ncur] = HTOO16(OHCI_ITD_MK_OFFS(offs));
offs = noffs;
}
nsitd = ohci_alloc_sitd(sc);
@@ -3271,15 +3271,15 @@
return;
}
/* Fixup last used ITD */
- sitd->itd.itd_flags = htole32(
+ sitd->itd.itd_flags = HTOO32(
OHCI_ITD_NOCC |
OHCI_ITD_SET_SF(iso->next) |
OHCI_ITD_SET_DI(0) |
OHCI_ITD_SET_FC(ncur));
- sitd->itd.itd_bp0 = htole32(bp0);
+ sitd->itd.itd_bp0 = HTOO32(bp0);
sitd->nextitd = nsitd;
- sitd->itd.itd_nextitd = htole32(nsitd->physaddr);
- sitd->itd.itd_be = htole32(bp0 + offs - 1);
+ sitd->itd.itd_nextitd = HTOO32(nsitd->physaddr);
+ sitd->itd.itd_be = HTOO32(bp0 + offs - 1);
sitd->xfer = xfer;
sitd->flags = OHCI_CALL_DONE;
@@ -3293,25 +3293,25 @@
#ifdef OHCI_DEBUG
if (ohcidebug > 5) {
DPRINTF(("ohci_device_isoc_enter: frame=%d\n",
- le32toh(sc->sc_hcca->hcca_frame_number)));
- ohci_dump_itds(xfer->hcpriv);
- ohci_dump_ed(sed);
+ O32TOH(sc->sc_hcca->hcca_frame_number)));
+ ohci_dump_itds(sc, xfer->hcpriv);
+ ohci_dump_ed(sc, sed);
}
#endif
s = splusb();
- sed->ed.ed_tailp = htole32(nsitd->physaddr);
+ sed->ed.ed_tailp = HTOO32(nsitd->physaddr);
opipe->tail.itd = nsitd;
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
+ sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP);
splx(s);
#ifdef OHCI_DEBUG
if (ohcidebug > 5) {
delay(150000);
DPRINTF(("ohci_device_isoc_enter: after frame=%d\n",
- le32toh(sc->sc_hcca->hcca_frame_number)));
- ohci_dump_itds(xfer->hcpriv);
- ohci_dump_ed(sed);
+ O32TOH(sc->sc_hcca->hcca_frame_number)));
+ ohci_dump_itds(sc, xfer->hcpriv);
+ ohci_dump_ed(sc, sed);
}
#endif
}
@@ -3362,7 +3362,7 @@
xfer->status = USBD_CANCELLED;
sed = opipe->sed;
- sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* force hardware skip */
+ sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); /* force hardware skip */
sitd = xfer->hcpriv;
#ifdef DIAGNOSTIC
@@ -3388,8 +3388,8 @@
/* Run callback. */
usb_transfer_complete(xfer);
- sed->ed.ed_headp = htole32(sitd->physaddr); /* unlink TDs */
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); /* remove hardware skip */
+ sed->ed.ed_headp = HTOO32(sitd->physaddr); /* unlink TDs */
+ sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); /* remove hardware skip */
splx(s);
}
@@ -3412,7 +3412,7 @@
iso->inuse = 0;
s = splusb();
- ohci_add_ed(opipe->sed, sc->sc_isoc_head);
+ ohci_add_ed(sc, opipe->sed, sc->sc_isoc_head);
splx(s);
return (USBD_NORMAL_COMPLETION);
Index: sys/dev/usb/ohcivar.h
===================================================================
RCS file: /net/projects/meteor/cvs/netbsd/src/sys/dev/usb/ohcivar.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ohcivar.h
--- sys/dev/usb/ohcivar.h 9 Nov 2005 14:17:30 -0000 1.1.1.1
+++ sys/dev/usb/ohcivar.h 10 Nov 2005 02:29:36 -0000
@@ -106,6 +106,11 @@
u_int8_t sc_addr; /* device address */
u_int8_t sc_conf; /* device configuration */
+ int sc_endian;
+#define OHCI_LITTLE_ENDIAN 0 /* typical (uninitialized default) */
+#define OHCI_BIG_ENDIAN 1 /* big endian OHCI? never seen it */
+#define OHCI_HOST_ENDIAN 2 /* if OHCI always matches CPU */
+
#ifdef USB_USE_SOFTINTR
char sc_softwake;
#endif /* USB_USE_SOFTINTR */
Index: sys/arch/mips/alchemy/dev/ohci_aubus.c
===================================================================
RCS file: /net/projects/meteor/cvs/netbsd/src/sys/arch/mips/alchemy/dev/ohci_aubus.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ohci_aubus.c
--- sys/arch/mips/alchemy/dev/ohci_aubus.c 9 Nov 2005 14:17:20 -0000 1.1.1.1
+++ sys/arch/mips/alchemy/dev/ohci_aubus.c 10 Nov 2005 02:29:36 -0000
@@ -144,6 +144,8 @@
sc->sc_bus.bdev.dv_xname);
}
+ sc->sc_endian = OHCI_HOST_ENDIAN;
+
if (x)
r = ohci_init(sc);
if (r != USBD_NORMAL_COMPLETION) {
--------------090500010703050906020405--