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/01/2005 23:27:02
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: Tue, 01 Nov 2005 15:26:38 -0800
This is a multi-part message in MIME format.
--------------060305020807000701010801
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
>>
>>
Attached find my diffs. I've conditionalized this so that you have to
define OHCI_DYNAMIC_ENDIAN to get run-time support for this. I've also
generalized it so that if someone ever runs into a device that is always
big-endian, regardless of the host processor, then that will work too.
(The OHCI spec makes no reference to byte ordering, as far as I can
tell, so this is legal.)
Note that since these changes are in general purpose USB code, it is
quite likely that the port-evbmips category is not the best place.
I've not done any timing analysis, but since everything is inlined where
possible, I'd expect it to be pretty good.
Also, I wonder if similar changes are going to be required for EHCI to
support the Au1200 board, which has USB 2.0 on it. I've not got one,
nor have I the interest to follow up, but it does bear thinking about.
--------------060305020807000701010801
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 29 Sep 2005 16:49:54 -0000 1.1.1.1
+++ sys/dev/usb/ohci.c 1 Nov 2005 23:22:12 -0000
@@ -120,6 +120,28 @@
#endif
#endif
+/*
+ * Well, the above comment isn't quite right. On some machines the OHCI
+ * controller may have different endianness, and on those machines we may
+ * need to support multiple OHCI controllers with different endiannesses.
+ * So this adds run-time support for that.
+ */
+#ifdef OHCI_DYNAMIC_ENDIAN
+Static uint32_t ohci_dev32toh(ohci_softc_t *sc, uint32_t);
+Static uint32_t ohci_htodev32(ohci_softc_t *sc, uint32_t);
+Static __inline uint16_t ohci_dev16toh(ohci_softc_t *sc, uint16_t);
+Static __inline uint16_t ohci_htodev16(ohci_softc_t *sc, uint16_t);
+#define O32TOH(val) ohci_dev32toh(sc, val)
+#define HTOO32(val) ohci_htodev32(sc, val)
+#define O16TOH(val) ohci_dev16toh(sc, val)
+#define HTOO16(val) ohci_htodev16(sc, val)
+#else
+#define O32TOH(val) le32toh(val)
+#define HTOO32(val) htole32(val)
+#define O16TOH(val) le16toh(val)
+#define HTOO16(val) htole16(val)
+#endif
+
struct ohci_pipe;
Static ohci_soft_ed_t *ohci_alloc_sed(ohci_softc_t *);
@@ -148,7 +170,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 +243,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 +517,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 +550,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 +577,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 +726,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 +734,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 +742,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 +755,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 +769,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 +1126,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 +1286,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 +1298,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 +1306,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 +1319,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 +1348,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 +1374,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 +1384,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 +1400,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 +1435,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 +1517,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 +1533,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 +1687,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 +1704,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 +1735,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 +1758,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 +1779,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 +1787,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 +1928,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 +2067,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 +2084,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 +2099,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 +2131,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 +2225,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 +2263,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 +2277,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 +2286,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 +2842,11 @@
ohci_device_clear_toggle(usbd_pipe_handle pipe)
{
struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
+#ifdef OHCI_DYNAMIC_ENDIAN
+ ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
+#endif
- opipe->sed->ed.ed_headp &= htole32(~OHCI_TOGGLECARRY);
+ opipe->sed->ed.ed_headp &= HTOO32(~OHCI_TOGGLECARRY);
}
Static void
@@ -2877,8 +2904,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 +2913,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 +2925,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 +2942,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 +2957,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 +3036,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 +3054,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 +3075,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 +3110,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 +3182,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 +3244,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 +3270,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 +3287,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 +3298,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 +3320,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 +3389,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 +3415,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 +3439,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);
@@ -3431,3 +3458,70 @@
#endif
ohci_free_sitd(sc, opipe->tail.itd);
}
+
+#ifdef OHCI_DYNAMIC_ENDIAN
+uint32_t
+ohci_htodev32(ohci_softc_t *sc, uint32_t val)
+{
+ switch (sc->sc_endian) {
+ default:
+ case OHCI_LITTLE_ENDIAN:
+ return (htole32(val));
+
+ case OHCI_BIG_ENDIAN:
+ return (htobe32(val));
+
+ case OHCI_HOST_ENDIAN:
+ return (val);
+ }
+}
+
+uint32_t
+ohci_dev32toh(ohci_softc_t *sc, uint32_t val)
+{
+ switch (sc->sc_endian) {
+ default:
+ case OHCI_LITTLE_ENDIAN:
+ return (le32toh(val));
+
+ case OHCI_BIG_ENDIAN:
+ return (be32toh(val));
+
+ case OHCI_HOST_ENDIAN:
+ return (val);
+ }
+}
+
+uint16_t
+ohci_htodev16(ohci_softc_t *sc, uint16_t val)
+{
+ switch (sc->sc_endian) {
+ case OHCI_LITTLE_ENDIAN:
+ return (htole16(val));
+
+ case OHCI_BIG_ENDIAN:
+ return (htobe16(val));
+
+ case OHCI_HOST_ENDIAN:
+ default:
+ return (val);
+ }
+}
+
+uint16_t
+ohci_dev16toh(ohci_softc_t *sc, uint16_t val)
+{
+ switch (sc->sc_endian) {
+ case OHCI_LITTLE_ENDIAN:
+ return (le16toh(val));
+
+ case OHCI_BIG_ENDIAN:
+ return (be16toh(val));
+
+ case OHCI_HOST_ENDIAN:
+ default:
+ return (val);
+ }
+}
+
+#endif /* OHCI_DYNAMIC_ENDIAN */
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 29 Sep 2005 16:49:54 -0000 1.1.1.1
+++ sys/dev/usb/ohcivar.h 1 Nov 2005 23:22:12 -0000
@@ -106,6 +106,13 @@
u_int8_t sc_addr; /* device address */
u_int8_t sc_conf; /* device configuration */
+#ifdef OHCI_DYNAMIC_ENDIAN
+ int sc_endian;
+#define OHCI_LITTLE_ENDIAN 0 /* typical (uninitialized default) */
+#define OHCI_BIG_ENDIAN 1 /* do any of these exist? */
+#define OHCI_HOST_ENDIAN 2 /* if controller always matches CPU */
+#endif
+
#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 29 Sep 2005 16:42:46 -0000 1.1.1.1
+++ sys/arch/mips/alchemy/dev/ohci_aubus.c 1 Nov 2005 23:22:12 -0000
@@ -64,6 +64,12 @@
static int ohci_aubus_match(struct device *, struct cfdata *, void *);
static void ohci_aubus_attach(struct device *, struct device *, void *);
+struct ohci_aubus_softc {
+ ohci_softc_t sc_ohci;
+ bus_addr_t sc_usbh; /* offset of USBH_ENABLE register */
+};
+
+
CFATTACH_DECL(ohci_aubus, sizeof (ohci_softc_t),
ohci_aubus_match, ohci_aubus_attach, NULL, NULL);
@@ -81,7 +87,8 @@
void
ohci_aubus_attach(struct device *parent, struct device *self, void *aux)
{
- ohci_softc_t *sc = (ohci_softc_t *)self;
+ struct ohci_aubus_softc *ausc = (struct ohci_aubus_softc *)self;
+ ohci_softc_t *sc;
void *ih;
usbd_status r;
uint32_t x, tmp;
@@ -89,15 +96,21 @@
r = 0;
- sc->sc_size = USBH_SIZE;
+ sc = &ausc->sc_ohci;
+
+ sc->sc_size = aa->aa_addrs[1];
sc->iot = aa->aa_st;
sc->sc_bus.dmatag = (bus_dma_tag_t)aa->aa_dt;
- if (bus_space_map(sc->iot, USBH_BASE, USBH_SIZE, 0, &sc->ioh)) {
+ if (bus_space_map(sc->iot, aa->aa_addrs[0], sc->sc_size,
+ 0, &sc->ioh)) {
printf("%s: Unable to map USBH registers\n",
sc->sc_bus.bdev.dv_xname);
return;
}
+
+ ausc->sc_usbh = aa->aa_addrs[2];
+
/*
* Enable the USB Host controller here.
* As per 7.2 in the Au1500 manual:
@@ -107,26 +120,31 @@
* (3) Clear HCFS in OHCI_CONTROL.
* (4) Wait for RD bit to be set.
*/
- x = bus_space_read_4(sc->iot, sc->ioh, USBH_ENABLE);
+ x = bus_space_read_4(sc->iot, sc->ioh, ausc->sc_usbh);
x |= UE_CE;
- bus_space_write_4(sc->iot, sc->ioh, USBH_ENABLE, x);
+ bus_space_write_4(sc->iot, sc->ioh, ausc->sc_usbh, x);
delay(10);
x |= UE_E;
+ x |= UE_C;
#ifdef __MIPSEB__
x |= UE_BE;
#endif
- bus_space_write_4(sc->iot, sc->ioh, USBH_ENABLE, x);
+ printf("writing USB enable %x\n", x);
+
+ bus_space_write_4(sc->iot, sc->ioh, ausc->sc_usbh, x);
delay(10);
+#if 0
x = bus_space_read_4(sc->iot, sc->ioh, OHCI_CONTROL);
x &= ~(OHCI_HCFS_MASK);
bus_space_write_4(sc->iot, sc->ioh, OHCI_CONTROL, x);
delay(10);
+#endif
/* Need to read USBH_ENABLE twice in succession according to
* au1500 Errata #7.
*/
for (x = 100; x; x--) {
- bus_space_read_4(sc->iot, sc->ioh, USBH_ENABLE);
- tmp = bus_space_read_4(sc->iot, sc->ioh, USBH_ENABLE);
+ bus_space_read_4(sc->iot, sc->ioh, ausc->sc_usbh);
+ tmp = bus_space_read_4(sc->iot, sc->ioh, ausc->sc_usbh);
if (tmp&UE_RD)
break;
delay(1000);
@@ -144,6 +162,8 @@
sc->sc_bus.bdev.dv_xname);
}
+ sc->sc_endian = OHCI_HOST_ENDIAN;
+
if (x)
r = ohci_init(sc);
if (r != USBD_NORMAL_COMPLETION) {
Index: sys/arch/mips/conf/files.alchemy
===================================================================
RCS file: /net/projects/meteor/cvs/netbsd/src/sys/arch/mips/conf/files.alchemy,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 files.alchemy
--- sys/arch/mips/conf/files.alchemy 29 Sep 2005 16:42:46 -0000 1.1.1.1
+++ sys/arch/mips/conf/files.alchemy 1 Nov 2005 23:22:12 -0000
@@ -29,6 +29,7 @@
file arch/mips/alchemy/dev/if_aumac.c aumac
# On-chip OHCI USB controller
+options OHCI_DYNAMIC_ENDIAN
attach ohci at aubus with ohci_aubus
file arch/mips/alchemy/dev/ohci_aubus.c ohci
--------------060305020807000701010801--