diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c index b8af7b2bf634..0734bc922638 100644 --- a/sys/dev/usb/ehci.c +++ b/sys/dev/usb/ehci.c @@ -558,20 +558,21 @@ 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; sqh->next = NULL; } else { /* Otherwise the next QH has half the poll interval */ sqh->next = sc->sc_islots[(i + 1) / 2 - 1].sqh; - sqh->qh.qh_link = htole32(sqh->next->physaddr | + sqh->qh->qh_link = htole32(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 = 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->sqtd = NULL; usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); @@ -596,16 +597,16 @@ ehci_init(ehci_softc_t *sc) goto bad1; } /* Fill the QH */ - sqh->qh.qh_endp = + sqh->qh->qh_endp = htole32(EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH) | EHCI_QH_HRECL); - sqh->qh.qh_link = + sqh->qh->qh_link = htole32(sqh->physaddr | EHCI_LINK_QH); - sqh->qh.qh_curqtd = EHCI_NULL; + sqh->qh->qh_curqtd = EHCI_NULL; sqh->next = NULL; /* 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(EHCI_QTD_HALTED); + 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->sqtd = NULL; usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); @@ -895,12 +896,12 @@ ehci_check_qh_intr(ehci_softc_t *sc, struct ehci_xfer *ex, ex_completeq_t *cq) */ usb_syncmem(&lsqtd->dma, lsqtd->offs + offsetof(ehci_qtd_t, qtd_status), - sizeof(lsqtd->qtd.qtd_status), + sizeof(lsqtd->qtd->qtd_status), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - status = le32toh(lsqtd->qtd.qtd_status); + status = le32toh(lsqtd->qtd->qtd_status); usb_syncmem(&lsqtd->dma, lsqtd->offs + offsetof(ehci_qtd_t, qtd_status), - sizeof(lsqtd->qtd.qtd_status), BUS_DMASYNC_PREREAD); + sizeof(lsqtd->qtd->qtd_status), BUS_DMASYNC_PREREAD); if (status & EHCI_QTD_ACTIVE) { DPRINTFN(10, "active ex=%#jx", (uintptr_t)ex, 0, 0, 0); @@ -908,12 +909,12 @@ ehci_check_qh_intr(ehci_softc_t *sc, struct ehci_xfer *ex, ex_completeq_t *cq) for (sqtd = fsqtd; sqtd != lsqtd; sqtd = sqtd->nextqtd) { usb_syncmem(&sqtd->dma, sqtd->offs + offsetof(ehci_qtd_t, qtd_status), - sizeof(sqtd->qtd.qtd_status), + sizeof(sqtd->qtd->qtd_status), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - status = le32toh(sqtd->qtd.qtd_status); + status = le32toh(sqtd->qtd->qtd_status); usb_syncmem(&sqtd->dma, sqtd->offs + offsetof(ehci_qtd_t, qtd_status), - sizeof(sqtd->qtd.qtd_status), BUS_DMASYNC_PREREAD); + sizeof(sqtd->qtd->qtd_status), BUS_DMASYNC_PREREAD); /* If there's an active QTD the xfer isn't done. */ if (status & EHCI_QTD_ACTIVE) break; @@ -973,11 +974,11 @@ ehci_check_itd_intr(ehci_softc_t *sc, struct ehci_xfer *ex, ex_completeq_t *cq) */ usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_ctl), - sizeof(itd->itd.itd_ctl), + sizeof(itd->itd->itd_ctl), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); for (i = 0; i < EHCI_ITD_NUFRAMES; i++) { - if (le32toh(itd->itd.itd_ctl[i]) & EHCI_ITD_ACTIVE) + if (le32toh(itd->itd->itd_ctl[i]) & EHCI_ITD_ACTIVE) break; } @@ -986,7 +987,7 @@ ehci_check_itd_intr(ehci_softc_t *sc, struct ehci_xfer *ex, ex_completeq_t *cq) } usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_ctl), - sizeof(itd->itd.itd_ctl), BUS_DMASYNC_PREREAD); + sizeof(itd->itd->itd_ctl), BUS_DMASYNC_PREREAD); DPRINTFN(10, "ex %#jx itd %#jx still active", (uintptr_t)ex, (uintptr_t)ex->ex_itdstart, 0, 0); @@ -1018,13 +1019,13 @@ ehci_check_sitd_intr(ehci_softc_t *sc, struct ehci_xfer *ex, ex_completeq_t *cq) */ usb_syncmem(&sitd->dma, sitd->offs + offsetof(ehci_sitd_t, sitd_trans), - sizeof(sitd->sitd.sitd_trans), + sizeof(sitd->sitd->sitd_trans), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - bool active = ((le32toh(sitd->sitd.sitd_trans) & EHCI_SITD_ACTIVE) != 0); + bool active = ((le32toh(sitd->sitd->sitd_trans) & EHCI_SITD_ACTIVE) != 0); usb_syncmem(&sitd->dma, sitd->offs + offsetof(ehci_sitd_t, sitd_trans), - sizeof(sitd->sitd.sitd_trans), BUS_DMASYNC_PREREAD); + sizeof(sitd->sitd->sitd_trans), BUS_DMASYNC_PREREAD); if (active) return; @@ -1092,7 +1093,7 @@ ehci_idone(struct ehci_xfer *ex, ex_completeq_t *cq) for (itd = ex->ex_itdstart; itd != NULL; itd = itd->xfer_next) { usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t,itd_ctl), - sizeof(itd->itd.itd_ctl), + sizeof(itd->itd->itd_ctl), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); for (i = 0; i < EHCI_ITD_NUFRAMES; i += uframes) { @@ -1106,7 +1107,7 @@ ehci_idone(struct ehci_xfer *ex, ex_completeq_t *cq) if (nframes >= xfer->ux_nframes) break; - status = le32toh(itd->itd.itd_ctl[i]); + status = le32toh(itd->itd->itd_ctl[i]); len = EHCI_ITD_GET_LEN(status); if (EHCI_ITD_GET_STATUS(status) != 0) len = 0; /*No valid data on error*/ @@ -1116,7 +1117,7 @@ ehci_idone(struct ehci_xfer *ex, ex_completeq_t *cq) } usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t,itd_ctl), - sizeof(itd->itd.itd_ctl), BUS_DMASYNC_PREREAD); + sizeof(itd->itd->itd_ctl), BUS_DMASYNC_PREREAD); if (nframes >= xfer->ux_nframes) break; @@ -1136,7 +1137,7 @@ ehci_idone(struct ehci_xfer *ex, ex_completeq_t *cq) sitd = sitd->xfer_next) { usb_syncmem(&sitd->dma, sitd->offs + offsetof(ehci_sitd_t, sitd_trans), - sizeof(sitd->sitd.sitd_trans), + sizeof(sitd->sitd->sitd_trans), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); /* @@ -1149,10 +1150,10 @@ ehci_idone(struct ehci_xfer *ex, ex_completeq_t *cq) if (nframes >= xfer->ux_nframes) break; - status = le32toh(sitd->sitd.sitd_trans); + status = le32toh(sitd->sitd->sitd_trans); usb_syncmem(&sitd->dma, sitd->offs + offsetof(ehci_sitd_t, sitd_trans), - sizeof(sitd->sitd.sitd_trans), BUS_DMASYNC_PREREAD); + sizeof(sitd->sitd->sitd_trans), BUS_DMASYNC_PREREAD); len = EHCI_SITD_GET_LEN(status); if (status & (EHCI_SITD_ERR|EHCI_SITD_BUFERR| @@ -1197,7 +1198,7 @@ ehci_idone(struct ehci_xfer *ex, ex_completeq_t *cq) for (sqtd = fsqtd; sqtd != lsqtd->nextqtd; sqtd = sqtd->nextqtd) { usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(sqtd->qtd), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - nstatus = le32toh(sqtd->qtd.qtd_status); + nstatus = le32toh(sqtd->qtd->qtd_status); usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(sqtd->qtd), BUS_DMASYNC_PREREAD); if (nstatus & EHCI_QTD_ACTIVE) @@ -1256,7 +1257,7 @@ ehci_idone(struct ehci_xfer *ex, ex_completeq_t *cq) DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); #endif /* low&full speed has an extra error flag */ - if (EHCI_QH_GET_EPS(epipe->sqh->qh.qh_endp) != + if (EHCI_QH_GET_EPS(epipe->sqh->qh->qh_endp) != EHCI_QH_SPEED_HIGH) status &= EHCI_QTD_STATERRS | EHCI_QTD_PINGSTATE; else @@ -1526,7 +1527,7 @@ ehci_allocx(struct usbd_bus *bus, unsigned int nframes) xfer = pool_cache_get(sc->sc_xferpool, PR_WAITOK); if (xfer != NULL) { - memset(xfer, 0, sizeof(struct ehci_xfer)); + memset(xfer, 0, sizeof(*xfer)); #ifdef DIAGNOSTIC struct ehci_xfer *ex = EHCI_XFER2EXFER(xfer); @@ -1579,7 +1580,7 @@ ehci_device_clear_toggle(struct usbd_pipe *pipe) EHCIHIST_FUNC(); EHCIHIST_CALLED(); DPRINTF("epipe=%#jx status=0x%08jx", (uintptr_t)epipe, - epipe->sqh->qh.qh_qtd.qtd_status, 0, 0); + epipe->sqh->qh->qh_qtd.qtd_status, 0, 0); #ifdef EHCI_DEBUG if (ehcidebug) usbd_dump_pipe(pipe); @@ -1671,7 +1672,7 @@ ehci_dump_sqtds(ehci_soft_qtd_t *sqtd) sqtd->offs + offsetof(ehci_qtd_t, qtd_next), sizeof(sqtd->qtd), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - stop = sqtd->qtd.qtd_next & htole32(EHCI_LINK_TERMINATE); + stop = sqtd->qtd->qtd_next & htole32(EHCI_LINK_TERMINATE); usb_syncmem(&sqtd->dma, sqtd->offs + offsetof(ehci_qtd_t, qtd_next), sizeof(sqtd->qtd), BUS_DMASYNC_PREREAD); @@ -1690,7 +1691,7 @@ ehci_dump_sqtd(ehci_soft_qtd_t *sqtd) DPRINTFN(10, "QTD(%#jx) at 0x%08jx:", (uintptr_t)sqtd, sqtd->physaddr, 0, 0); - ehci_dump_qtd(&sqtd->qtd); + ehci_dump_qtd(sqtd->qtd); usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(sqtd->qtd), BUS_DMASYNC_PREREAD); @@ -1737,7 +1738,7 @@ ehci_dump_qtd(ehci_qtd_t *qtd) Static void ehci_dump_sqh(ehci_soft_qh_t *sqh) { - ehci_qh_t *qh = &sqh->qh; + ehci_qh_t *qh = sqh->qh; ehci_link_t link; uint32_t endp, endphub; EHCIHIST_FUNC(); EHCIHIST_CALLED(); @@ -1791,7 +1792,7 @@ ehci_dump_itds(ehci_soft_itd_t *itd) itd->offs + offsetof(ehci_itd_t, itd_next), sizeof(itd->itd), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - stop = itd->itd.itd_next & htole32(EHCI_LINK_TERMINATE); + stop = itd->itd->itd_next & htole32(EHCI_LINK_TERMINATE); usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_next), sizeof(itd->itd), BUS_DMASYNC_PREREAD); @@ -1809,10 +1810,10 @@ ehci_dump_itd(struct ehci_soft_itd *itd) EHCIHIST_FUNC(); EHCIHIST_CALLED(); - DPRINTF("ITD: next phys = %#jx", itd->itd.itd_next, 0, 0, 0); + DPRINTF("ITD: next phys = %#jx", itd->itd->itd_next, 0, 0, 0); for (i = 0; i < EHCI_ITD_NUFRAMES; i++) { - t = le32toh(itd->itd.itd_ctl[i]); + t = le32toh(itd->itd->itd_ctl[i]); DPRINTF("ITDctl %jd: stat = %jx len = %jx", i, EHCI_ITD_GET_STATUS(t), EHCI_ITD_GET_LEN(t), 0); DPRINTF(" ioc = %jx pg = %jx offs = %jx", @@ -1822,11 +1823,11 @@ ehci_dump_itd(struct ehci_soft_itd *itd) DPRINTF("ITDbufr: ", 0, 0, 0, 0); for (i = 0; i < EHCI_ITD_NBUFFERS; i++) DPRINTF(" %jx", - EHCI_ITD_GET_BPTR(le32toh(itd->itd.itd_bufr[i])), 0, 0, 0); + EHCI_ITD_GET_BPTR(le32toh(itd->itd->itd_bufr[i])), 0, 0, 0); - b = le32toh(itd->itd.itd_bufr[0]); - b2 = le32toh(itd->itd.itd_bufr[1]); - b3 = le32toh(itd->itd.itd_bufr[2]); + b = le32toh(itd->itd->itd_bufr[0]); + b2 = le32toh(itd->itd->itd_bufr[1]); + b3 = le32toh(itd->itd->itd_bufr[2]); DPRINTF(" ep = %jx daddr = %jx dir = %jd", EHCI_ITD_GET_EP(b), EHCI_ITD_GET_DADDR(b), EHCI_ITD_GET_DIR(b2), 0); DPRINTF(" maxpkt = %jx multi = %jx", @@ -1967,7 +1968,7 @@ ehci_open(struct usbd_pipe *pipe) if (sqh == NULL) return USBD_NOMEM; /* qh_link filled when the QH is added */ - sqh->qh.qh_endp = htole32( + sqh->qh->qh_endp = htole32( EHCI_QH_SET_ADDR(addr) | EHCI_QH_SET_ENDPT(UE_GET_ADDR(ed->bEndpointAddress)) | EHCI_QH_SET_EPS(speed) | @@ -1977,22 +1978,22 @@ ehci_open(struct usbd_pipe *pipe) EHCI_QH_CTL : 0) | EHCI_QH_SET_NRL(naks) ); - sqh->qh.qh_endphub = htole32( + sqh->qh->qh_endphub = htole32( EHCI_QH_SET_MULT(1) | EHCI_QH_SET_SMASK(xfertype == UE_INTERRUPT ? 0x02 : 0) ); if (speed != EHCI_QH_SPEED_HIGH) - sqh->qh.qh_endphub |= htole32( + sqh->qh->qh_endphub |= htole32( EHCI_QH_SET_PORT(hshubport) | EHCI_QH_SET_HUBA(hshubaddr) | (xfertype == UE_INTERRUPT ? EHCI_QH_SET_CMASK(0x08) : 0) ); - sqh->qh.qh_curqtd = EHCI_NULL; + sqh->qh->qh_curqtd = EHCI_NULL; /* 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; + sqh->qh->qh_qtd.qtd_altnext = EHCI_NULL; + sqh->qh->qh_qtd.qtd_status = htole32(0); usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); @@ -2090,19 +2091,19 @@ ehci_add_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head) EHCIHIST_FUNC(); EHCIHIST_CALLED(); usb_syncmem(&head->dma, head->offs + offsetof(ehci_qh_t, qh_link), - sizeof(head->qh.qh_link), BUS_DMASYNC_POSTWRITE); + sizeof(head->qh->qh_link), BUS_DMASYNC_POSTWRITE); sqh->next = head->next; - sqh->qh.qh_link = head->qh.qh_link; + sqh->qh->qh_link = head->qh->qh_link; usb_syncmem(&sqh->dma, sqh->offs + offsetof(ehci_qh_t, qh_link), - sizeof(sqh->qh.qh_link), BUS_DMASYNC_PREWRITE); + sizeof(sqh->qh->qh_link), BUS_DMASYNC_PREWRITE); head->next = sqh; - head->qh.qh_link = htole32(sqh->physaddr | EHCI_LINK_QH); + head->qh->qh_link = htole32(sqh->physaddr | EHCI_LINK_QH); usb_syncmem(&head->dma, head->offs + offsetof(ehci_qh_t, qh_link), - sizeof(head->qh.qh_link), BUS_DMASYNC_PREWRITE); + sizeof(head->qh->qh_link), BUS_DMASYNC_PREWRITE); #ifdef EHCI_DEBUG DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); @@ -2127,11 +2128,11 @@ ehci_rem_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head) if (p == NULL) panic("ehci_rem_qh: ED not found"); usb_syncmem(&sqh->dma, sqh->offs + offsetof(ehci_qh_t, qh_link), - sizeof(sqh->qh.qh_link), BUS_DMASYNC_POSTWRITE); + sizeof(sqh->qh->qh_link), BUS_DMASYNC_POSTWRITE); p->next = sqh->next; - p->qh.qh_link = sqh->qh.qh_link; + p->qh->qh_link = sqh->qh->qh_link; usb_syncmem(&p->dma, p->offs + offsetof(ehci_qh_t, qh_link), - sizeof(p->qh.qh_link), BUS_DMASYNC_PREWRITE); + sizeof(p->qh->qh_link), BUS_DMASYNC_PREWRITE); ehci_sync_hc(sc); } @@ -2145,29 +2146,29 @@ ehci_set_qh_qtd(ehci_soft_qh_t *sqh, ehci_soft_qtd_t *sqtd) /* Save toggle bit and ping status. */ usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - status = sqh->qh.qh_qtd.qtd_status & + status = sqh->qh->qh_qtd.qtd_status & htole32(EHCI_QTD_TOGGLE_MASK | EHCI_QTD_SET_STATUS(EHCI_QTD_PINGSTATE)); /* Set HALTED to make hw leave it alone. */ - sqh->qh.qh_qtd.qtd_status = + sqh->qh->qh_qtd.qtd_status = htole32(EHCI_QTD_SET_STATUS(EHCI_QTD_HALTED)); usb_syncmem(&sqh->dma, sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status), - sizeof(sqh->qh.qh_qtd.qtd_status), + sizeof(sqh->qh->qh_qtd.qtd_status), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - sqh->qh.qh_curqtd = 0; - sqh->qh.qh_qtd.qtd_next = htole32(sqtd->physaddr); - sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL; + sqh->qh->qh_curqtd = 0; + sqh->qh->qh_qtd.qtd_next = htole32(sqtd->physaddr); + sqh->qh->qh_qtd.qtd_altnext = EHCI_NULL; for (i = 0; i < EHCI_QTD_NBUFFERS; i++) - sqh->qh.qh_qtd.qtd_buffer[i] = 0; + sqh->qh->qh_qtd.qtd_buffer[i] = 0; sqh->sqtd = sqtd; usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); /* Set !HALTED && !ACTIVE to start execution, preserve some fields */ - sqh->qh.qh_qtd.qtd_status = status; + sqh->qh->qh_qtd.qtd_status = status; usb_syncmem(&sqh->dma, sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status), - sizeof(sqh->qh.qh_qtd.qtd_status), + sizeof(sqh->qh->qh_qtd.qtd_status), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } @@ -2221,7 +2222,7 @@ ehci_remove_itd_chain(ehci_softc_t *sc, struct ehci_soft_itd *itd) /* Unlink itd from hardware chain, or frame array */ if (prev == NULL) { /* We're at the table head */ sc->sc_softitds[itd->slot] = itd->frame_list.next; - sc->sc_flist[itd->slot] = itd->itd.itd_next; + sc->sc_flist[itd->slot] = itd->itd->itd_next; usb_syncmem(&sc->sc_fldma, sizeof(ehci_link_t) * itd->slot, sizeof(ehci_link_t), @@ -2231,10 +2232,10 @@ ehci_remove_itd_chain(ehci_softc_t *sc, struct ehci_soft_itd *itd) itd->frame_list.next->frame_list.prev = NULL; } else { /* XXX this part is untested... */ - prev->itd.itd_next = itd->itd.itd_next; + prev->itd->itd_next = itd->itd->itd_next; usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_next), - sizeof(itd->itd.itd_next), BUS_DMASYNC_PREWRITE); + sizeof(itd->itd->itd_next), BUS_DMASYNC_PREWRITE); prev->frame_list.next = itd->frame_list.next; if (itd->frame_list.next != NULL) @@ -2269,7 +2270,7 @@ ehci_remove_sitd_chain(ehci_softc_t *sc, struct ehci_soft_sitd *sitd) /* Unlink sitd from hardware chain, or frame array */ if (prev == NULL) { /* We're at the table head */ sc->sc_softsitds[sitd->slot] = sitd->frame_list.next; - sc->sc_flist[sitd->slot] = sitd->sitd.sitd_next; + sc->sc_flist[sitd->slot] = sitd->sitd->sitd_next; usb_syncmem(&sc->sc_fldma, sizeof(ehci_link_t) * sitd->slot, sizeof(ehci_link_t), @@ -2279,10 +2280,10 @@ ehci_remove_sitd_chain(ehci_softc_t *sc, struct ehci_soft_sitd *sitd) sitd->frame_list.next->frame_list.prev = NULL; } else { /* XXX this part is untested... */ - prev->sitd.sitd_next = sitd->sitd.sitd_next; + prev->sitd->sitd_next = sitd->sitd->sitd_next; usb_syncmem(&sitd->dma, sitd->offs + offsetof(ehci_sitd_t, sitd_next), - sizeof(sitd->sitd.sitd_next), BUS_DMASYNC_PREWRITE); + sizeof(sitd->sitd->sitd_next), BUS_DMASYNC_PREWRITE); prev->frame_list.next = sitd->frame_list.next; if (sitd->frame_list.next != NULL) @@ -2803,8 +2804,8 @@ ehci_alloc_sqh(ehci_softc_t *sc) DPRINTF("allocating chunk", 0, 0, 0, 0); mutex_exit(&sc->sc_lock); - err = usb_allocmem(&sc->sc_bus, EHCI_SQH_SIZE * EHCI_SQH_CHUNK, - EHCI_PAGE_SIZE, USBMALLOC_COHERENT, &dma); + err = usb_allocmem(&sc->sc_bus, EHCI_QH_SIZE * EHCI_QH_CHUNK, + EHCI_PAGE_SIZE, 0 /* !USBMALLOC_COHERENT */, &dma); #ifdef EHCI_DEBUG if (err) printf("ehci_alloc_sqh: usb_allocmem()=%d\n", err); @@ -2812,10 +2813,16 @@ ehci_alloc_sqh(ehci_softc_t *sc) if (err) return NULL; + ehci_soft_qh_t *sqhs = + kmem_zalloc(sizeof(*sqh) * EHCI_QH_CHUNK, KM_SLEEP); + mutex_enter(&sc->sc_lock); - for (i = 0; i < EHCI_SQH_CHUNK; i++) { - offs = i * EHCI_SQH_SIZE; - sqh = KERNADDR(&dma, offs); + for (i = 0; i < EHCI_QH_CHUNK; i++) { + sqh = &sqhs[i]; + + offs = i * EHCI_QH_SIZE; + + sqh->qh = KERNADDR(&dma, offs); sqh->physaddr = DMAADDR(&dma, offs); sqh->dma = dma; sqh->offs = offs; @@ -2827,7 +2834,7 @@ ehci_alloc_sqh(ehci_softc_t *sc) sc->sc_freeqhs = sqh->next; mutex_exit(&sc->sc_lock); - memset(&sqh->qh, 0, sizeof(ehci_qh_t)); + memset(sqh->qh, 0, sizeof(*sqh->qh)); sqh->next = NULL; return sqh; } @@ -2855,10 +2862,8 @@ ehci_alloc_sqtd(ehci_softc_t *sc) DPRINTF("allocating chunk", 0, 0, 0, 0); mutex_exit(&sc->sc_lock); - int err = usb_allocmem(&sc->sc_bus, - EHCI_SQTD_SIZE*EHCI_SQTD_CHUNK, - EHCI_PAGE_SIZE, USBMALLOC_COHERENT, - &dma); + int err = usb_allocmem(&sc->sc_bus, EHCI_QTD_SIZE * EHCI_QTD_CHUNK, + EHCI_PAGE_SIZE, USBMALLOC_COHERENT, &dma); #ifdef EHCI_DEBUG if (err) printf("ehci_alloc_sqtd: usb_allocmem()=%d\n", err); @@ -2866,10 +2871,16 @@ ehci_alloc_sqtd(ehci_softc_t *sc) if (err) goto done; + ehci_soft_qtd_t *sqtds = + kmem_zalloc(sizeof(*sqtd) * EHCI_QTD_CHUNK, KM_SLEEP); + mutex_enter(&sc->sc_lock); - for (i = 0; i < EHCI_SQTD_CHUNK; i++) { - offs = i * EHCI_SQTD_SIZE; - sqtd = KERNADDR(&dma, offs); + for (i = 0; i < EHCI_QTD_CHUNK; i++) { + offs = i * EHCI_QTD_SIZE; + + sqtd = &sqtds[i]; + + sqtd->qtd = KERNADDR(&dma, offs); sqtd->physaddr = DMAADDR(&dma, offs); sqtd->dma = dma; sqtd->offs = offs; @@ -2883,7 +2894,7 @@ ehci_alloc_sqtd(ehci_softc_t *sc) sc->sc_freeqtds = sqtd->nextqtd; mutex_exit(&sc->sc_lock); - memset(&sqtd->qtd, 0, sizeof(ehci_qtd_t)); + memset(sqtd->qtd, 0, sizeof(*sqtd->qtd)); sqtd->nextqtd = NULL; sqtd->xfer = NULL; @@ -2970,8 +2981,8 @@ ehci_append_sqtd(ehci_soft_qtd_t *sqtd, ehci_soft_qtd_t *prev) { if (prev) { prev->nextqtd = sqtd; - prev->qtd.qtd_next = htole32(sqtd->physaddr); - prev->qtd.qtd_altnext = prev->qtd.qtd_next; + prev->qtd->qtd_next = htole32(sqtd->physaddr); + prev->qtd->qtd_altnext = prev->qtd->qtd_next; usb_syncmem(&prev->dma, prev->offs, sizeof(prev->qtd), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); } @@ -3029,8 +3040,8 @@ ehci_reset_sqtd_chain(ehci_softc_t *sc, struct usbd_xfer *xfer, curoffs, 0); /* Fill the qTD */ - sqtd->qtd.qtd_next = sqtd->qtd.qtd_altnext = EHCI_NULL; - sqtd->qtd.qtd_status = htole32( + sqtd->qtd->qtd_next = sqtd->qtd->qtd_altnext = EHCI_NULL; + sqtd->qtd->qtd_status = htole32( qtdstatus | EHCI_QTD_SET_BYTES(curlen) | EHCI_QTD_SET_TOGGLE(tog)); @@ -3042,15 +3053,15 @@ ehci_reset_sqtd_chain(ehci_softc_t *sc, struct usbd_xfer *xfer, for (size_t i = 0; i < pages; i++) { paddr_t a = EHCI_PAGE(DMAADDR(dma, pageoffs + i * EHCI_PAGE_SIZE)); - sqtd->qtd.qtd_buffer[i] = htole32(BUS_ADDR_LO32(a)); - sqtd->qtd.qtd_buffer_hi[i] = htole32(BUS_ADDR_HI32(a)); + sqtd->qtd->qtd_buffer[i] = htole32(BUS_ADDR_LO32(a)); + sqtd->qtd->qtd_buffer_hi[i] = htole32(BUS_ADDR_HI32(a)); DPRINTF(" buffer[%jd/%jd] 0x%08jx 0x%08jx", i, pages, - le32toh(sqtd->qtd.qtd_buffer_hi[i]), - le32toh(sqtd->qtd.qtd_buffer[i])); + le32toh(sqtd->qtd->qtd_buffer_hi[i]), + le32toh(sqtd->qtd->qtd_buffer[i])); } /* First buffer pointer requires a page offset to start at */ - sqtd->qtd.qtd_buffer[0] |= htole32(va_offs); + sqtd->qtd->qtd_buffer[0] |= htole32(va_offs); usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(sqtd->qtd), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); @@ -3081,9 +3092,9 @@ ehci_reset_sqtd_chain(ehci_softc_t *sc, struct usbd_xfer *xfer, exfer->ex_nsqtd); prev = sqtd; sqtd = exfer->ex_sqtds[j++]; - memset(&sqtd->qtd, 0, sizeof(sqtd->qtd)); - sqtd->qtd.qtd_next = sqtd->qtd.qtd_altnext = EHCI_NULL; - sqtd->qtd.qtd_status = htole32( + memset(sqtd->qtd, 0, sizeof(*sqtd->qtd)); + sqtd->qtd->qtd_next = sqtd->qtd->qtd_altnext = EHCI_NULL; + sqtd->qtd->qtd_status = htole32( qtdstatus | EHCI_QTD_SET_BYTES(0) | EHCI_QTD_SET_TOGGLE(tog)); @@ -3120,11 +3131,18 @@ ehci_alloc_itd(ehci_softc_t *sc) DPRINTF("alloc returned %jd", err, 0, 0, 0); return NULL; } + + struct ehci_soft_itd *itds = + kmem_alloc(sizeof(*itd) * EHCI_ITD_CHUNK, KM_SLEEP); + mutex_enter(&sc->sc_lock); for (int i = 0; i < EHCI_ITD_CHUNK; i++) { + itd = &itds[i]; + int offs = i * EHCI_ITD_SIZE; - itd = KERNADDR(&dma, offs); + + itd->itd = KERNADDR(&dma, offs); itd->physaddr = DMAADDR(&dma, offs); itd->dma = dma; itd->offs = offs; @@ -3136,7 +3154,7 @@ ehci_alloc_itd(ehci_softc_t *sc) itd = freeitd; LIST_REMOVE(itd, free_list); mutex_exit(&sc->sc_lock); - memset(&itd->itd, 0, sizeof(ehci_itd_t)); + memset(itd->itd, 0, sizeof(*itd->itd)); itd->frame_list.next = NULL; itd->frame_list.prev = NULL; @@ -3160,7 +3178,7 @@ ehci_alloc_sitd(ehci_softc_t *sc) if (freesitd == NULL) { DPRINTF("allocating chunk", 0, 0, 0, 0); mutex_exit(&sc->sc_lock); - int err = usb_allocmem(&sc->sc_bus, EHCI_SITD_SIZE * EHCI_SITD_CHUNK, + int err = usb_allocmem(&sc->sc_bus, EHCI_ITD_SIZE * EHCI_ITD_CHUNK, EHCI_PAGE_SIZE, USBMALLOC_COHERENT, &dma); if (err) { @@ -3168,9 +3186,13 @@ ehci_alloc_sitd(ehci_softc_t *sc) 0); return NULL; } + struct ehci_soft_sitd *sitds = + kmem_alloc(sizeof(*sitd) * EHCI_SITD_CHUNK, KM_SLEEP); mutex_enter(&sc->sc_lock); for (i = 0; i < EHCI_SITD_CHUNK; i++) { + sitd = &sitds[i]; + offs = i * EHCI_SITD_SIZE; sitd = KERNADDR(&dma, offs); sitd->physaddr = DMAADDR(&dma, offs); @@ -3185,7 +3207,7 @@ ehci_alloc_sitd(ehci_softc_t *sc) LIST_REMOVE(sitd, free_list); mutex_exit(&sc->sc_lock); - memset(&sitd->sitd, 0, sizeof(ehci_sitd_t)); + memset(sitd->sitd, 0, sizeof(*sitd->sitd)); sitd->frame_list.next = NULL; sitd->frame_list.prev = NULL; @@ -3256,13 +3278,13 @@ ehci_abortx(struct usbd_xfer *xfer) usb_syncmem(&sqh->dma, sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status), - sizeof(sqh->qh.qh_qtd.qtd_status), + sizeof(sqh->qh->qh_qtd.qtd_status), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - qhstatus = sqh->qh.qh_qtd.qtd_status; - sqh->qh.qh_qtd.qtd_status = qhstatus | htole32(EHCI_QTD_HALTED); + qhstatus = sqh->qh->qh_qtd.qtd_status; + sqh->qh->qh_qtd.qtd_status = qhstatus | htole32(EHCI_QTD_HALTED); usb_syncmem(&sqh->dma, sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status), - sizeof(sqh->qh.qh_qtd.qtd_status), + sizeof(sqh->qh->qh_qtd.qtd_status), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); if (exfer->ex_type == EX_CTRL) { @@ -3275,12 +3297,12 @@ ehci_abortx(struct usbd_xfer *xfer) for (sqtd = fsqtd; ; sqtd = sqtd->nextqtd) { usb_syncmem(&sqtd->dma, sqtd->offs + offsetof(ehci_qtd_t, qtd_status), - sizeof(sqtd->qtd.qtd_status), + sizeof(sqtd->qtd->qtd_status), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - sqtd->qtd.qtd_status |= htole32(EHCI_QTD_HALTED); + sqtd->qtd->qtd_status |= htole32(EHCI_QTD_HALTED); usb_syncmem(&sqtd->dma, sqtd->offs + offsetof(ehci_qtd_t, qtd_status), - sizeof(sqtd->qtd.qtd_status), + sizeof(sqtd->qtd->qtd_status), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); if (sqtd == lsqtd) break; @@ -3302,9 +3324,9 @@ ehci_abortx(struct usbd_xfer *xfer) usb_syncmem(&sqh->dma, sqh->offs + offsetof(ehci_qh_t, qh_curqtd), - sizeof(sqh->qh.qh_curqtd), + sizeof(sqh->qh->qh_curqtd), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - cur = EHCI_LINK_ADDR(le32toh(sqh->qh.qh_curqtd)); + cur = EHCI_LINK_ADDR(le32toh(sqh->qh->qh_curqtd)); hit = 0; for (sqtd = fsqtd; ; sqtd = sqtd->nextqtd) { hit |= cur == sqtd->physaddr; @@ -3315,21 +3337,21 @@ ehci_abortx(struct usbd_xfer *xfer) /* Zap curqtd register if hardware pointed inside the xfer. */ if (hit && sqtd != NULL) { DPRINTF("cur=0x%08jx", sqtd->physaddr, 0, 0, 0); - sqh->qh.qh_curqtd = htole32(sqtd->physaddr); /* unlink qTDs */ + sqh->qh->qh_curqtd = htole32(sqtd->physaddr); /* unlink qTDs */ usb_syncmem(&sqh->dma, sqh->offs + offsetof(ehci_qh_t, qh_curqtd), - sizeof(sqh->qh.qh_curqtd), + sizeof(sqh->qh->qh_curqtd), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - sqh->qh.qh_qtd.qtd_status = qhstatus; + sqh->qh->qh_qtd.qtd_status = qhstatus; usb_syncmem(&sqh->dma, sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status), - sizeof(sqh->qh.qh_qtd.qtd_status), + sizeof(sqh->qh->qh_qtd.qtd_status), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } else { DPRINTF("no hit", 0, 0, 0, 0); usb_syncmem(&sqh->dma, sqh->offs + offsetof(ehci_qh_t, qh_curqtd), - sizeof(sqh->qh.qh_curqtd), + sizeof(sqh->qh->qh_curqtd), BUS_DMASYNC_PREREAD); } @@ -3404,18 +3426,18 @@ ehci_abort_isoc_xfer(struct usbd_xfer *xfer, usbd_status status) itd = itd->xfer_next) { usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_ctl), - sizeof(itd->itd.itd_ctl), + sizeof(itd->itd->itd_ctl), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); for (i = 0; i < 8; i++) { - trans_status = le32toh(itd->itd.itd_ctl[i]); + trans_status = le32toh(itd->itd->itd_ctl[i]); trans_status &= ~EHCI_ITD_ACTIVE; - itd->itd.itd_ctl[i] = htole32(trans_status); + itd->itd->itd_ctl[i] = htole32(trans_status); } usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_ctl), - sizeof(itd->itd.itd_ctl), + sizeof(itd->itd->itd_ctl), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } } else { @@ -3423,16 +3445,16 @@ ehci_abort_isoc_xfer(struct usbd_xfer *xfer, usbd_status status) sitd = sitd->xfer_next) { usb_syncmem(&sitd->dma, sitd->offs + offsetof(ehci_sitd_t, sitd_buffer), - sizeof(sitd->sitd.sitd_buffer), + sizeof(sitd->sitd->sitd_buffer), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - trans_status = le32toh(sitd->sitd.sitd_trans); + trans_status = le32toh(sitd->sitd->sitd_trans); trans_status &= ~EHCI_SITD_ACTIVE; - sitd->sitd.sitd_trans = htole32(trans_status); + sitd->sitd->sitd_trans = htole32(trans_status); usb_syncmem(&sitd->dma, sitd->offs + offsetof(ehci_sitd_t, sitd_buffer), - sizeof(sitd->sitd.sitd_buffer), + sizeof(sitd->sitd->sitd_buffer), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } } @@ -3488,28 +3510,28 @@ ehci_device_ctrl_init(struct usbd_xfer *xfer) } /* Clear toggle */ - setup->qtd.qtd_status = htole32( + setup->qtd->qtd_status = htole32( EHCI_QTD_SET_PID(EHCI_QTD_PID_SETUP) | EHCI_QTD_SET_TOGGLE(0) | EHCI_QTD_SET_BYTES(sizeof(*req)) ); const bus_addr_t ba = DMAADDR(&epipe->ctrl.reqdma, 0); - setup->qtd.qtd_buffer[0] = htole32(BUS_ADDR_LO32(ba)); - setup->qtd.qtd_buffer_hi[0] = htole32(BUS_ADDR_HI32(ba)); - setup->qtd.qtd_next = setup->qtd.qtd_altnext = htole32(next->physaddr); + setup->qtd->qtd_buffer[0] = htole32(BUS_ADDR_LO32(ba)); + setup->qtd->qtd_buffer_hi[0] = htole32(BUS_ADDR_HI32(ba)); + setup->qtd->qtd_next = setup->qtd->qtd_altnext = htole32(next->physaddr); setup->nextqtd = next; setup->xfer = xfer; setup->len = sizeof(*req); - status->qtd.qtd_status = htole32( + status->qtd->qtd_status = htole32( EHCI_QTD_SET_PID(isread ? EHCI_QTD_PID_OUT : EHCI_QTD_PID_IN) | EHCI_QTD_SET_TOGGLE(1) | EHCI_QTD_IOC ); - status->qtd.qtd_buffer[0] = 0; - status->qtd.qtd_buffer_hi[0] = 0; - status->qtd.qtd_next = status->qtd.qtd_altnext = EHCI_NULL; + status->qtd->qtd_buffer[0] = 0; + status->qtd->qtd_buffer_hi[0] = 0; + status->qtd->qtd_next = status->qtd->qtd_altnext = EHCI_NULL; status->nextqtd = NULL; status->xfer = xfer; status->len = 0; @@ -3586,14 +3608,14 @@ ehci_device_ctrl_start(struct usbd_xfer *xfer) sqh = epipe->sqh; - KASSERTMSG(EHCI_QH_GET_ADDR(le32toh(sqh->qh.qh_endp)) == epipe->pipe.up_dev->ud_addr, + KASSERTMSG(EHCI_QH_GET_ADDR(le32toh(sqh->qh->qh_endp)) == epipe->pipe.up_dev->ud_addr, "address QH %" __PRIuBIT " pipe %d\n", - EHCI_QH_GET_ADDR(le32toh(sqh->qh.qh_endp)), + EHCI_QH_GET_ADDR(le32toh(sqh->qh->qh_endp)), epipe->pipe.up_dev->ud_addr); - KASSERTMSG(EHCI_QH_GET_MPL(le32toh(sqh->qh.qh_endp)) == + KASSERTMSG(EHCI_QH_GET_MPL(le32toh(sqh->qh->qh_endp)) == UGETW(epipe->pipe.up_endpoint->ue_edesc->wMaxPacketSize), "MPS QH %" __PRIuBIT " pipe %d\n", - EHCI_QH_GET_MPL(le32toh(sqh->qh.qh_endp)), + EHCI_QH_GET_MPL(le32toh(sqh->qh->qh_endp)), UGETW(epipe->pipe.up_endpoint->ue_edesc->wMaxPacketSize)); setup = exfer->ex_setup; @@ -3609,13 +3631,13 @@ ehci_device_ctrl_start(struct usbd_xfer *xfer) usb_syncmem(&epipe->ctrl.reqdma, 0, sizeof(*req), BUS_DMASYNC_PREWRITE); /* Clear toggle */ - setup->qtd.qtd_status &= ~htole32( + setup->qtd->qtd_status &= ~htole32( EHCI_QTD_STATUS_MASK | EHCI_QTD_BYTES_MASK | EHCI_QTD_TOGGLE_MASK | EHCI_QTD_CERR_MASK ); - setup->qtd.qtd_status |= htole32( + setup->qtd->qtd_status |= htole32( EHCI_QTD_ACTIVE | EHCI_QTD_SET_CERR(3) | EHCI_QTD_SET_TOGGLE(0) | @@ -3623,18 +3645,18 @@ ehci_device_ctrl_start(struct usbd_xfer *xfer) ); const bus_addr_t ba = DMAADDR(&epipe->ctrl.reqdma, 0); - setup->qtd.qtd_buffer[0] = htole32(BUS_ADDR_LO32(ba)); - setup->qtd.qtd_buffer_hi[0] = htole32(BUS_ADDR_HI32(ba)); + setup->qtd->qtd_buffer[0] = htole32(BUS_ADDR_LO32(ba)); + setup->qtd->qtd_buffer_hi[0] = htole32(BUS_ADDR_HI32(ba)); next = status; - status->qtd.qtd_status &= ~htole32( + status->qtd->qtd_status &= ~htole32( EHCI_QTD_STATUS_MASK | EHCI_QTD_PID_MASK | EHCI_QTD_BYTES_MASK | EHCI_QTD_TOGGLE_MASK | EHCI_QTD_CERR_MASK ); - status->qtd.qtd_status |= htole32( + status->qtd->qtd_status |= htole32( EHCI_QTD_ACTIVE | EHCI_QTD_SET_PID(isread ? EHCI_QTD_PID_OUT : EHCI_QTD_PID_IN) | EHCI_QTD_SET_CERR(3) | @@ -3642,7 +3664,7 @@ ehci_device_ctrl_start(struct usbd_xfer *xfer) EHCI_QTD_SET_BYTES(0) | EHCI_QTD_IOC ); - KASSERT(status->qtd.qtd_status & htole32(EHCI_QTD_TOGGLE_MASK)); + KASSERT(status->qtd->qtd_status & htole32(EHCI_QTD_TOGGLE_MASK)); KASSERT(exfer->ex_isdone); #ifdef DIAGNOSTIC @@ -3659,7 +3681,7 @@ ehci_device_ctrl_start(struct usbd_xfer *xfer) KASSERTMSG(next != NULL, "Failed memory allocation"); ehci_reset_sqtd_chain(sc, xfer, len, isread, &toggle, &end); end->nextqtd = status; - end->qtd.qtd_next = end->qtd.qtd_altnext = + end->qtd->qtd_next = end->qtd->qtd_altnext = htole32(status->physaddr); usb_syncmem(&end->dma, end->offs, sizeof(end->qtd), @@ -3670,7 +3692,7 @@ ehci_device_ctrl_start(struct usbd_xfer *xfer) } setup->nextqtd = next; - setup->qtd.qtd_next = setup->qtd.qtd_altnext = htole32(next->physaddr); + setup->qtd->qtd_next = setup->qtd->qtd_altnext = htole32(next->physaddr); usb_syncmem(&setup->dma, setup->offs, sizeof(setup->qtd), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); @@ -3678,7 +3700,7 @@ ehci_device_ctrl_start(struct usbd_xfer *xfer) usb_syncmem(&status->dma, status->offs, sizeof(status->qtd), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - KASSERT(status->qtd.qtd_status & htole32(EHCI_QTD_TOGGLE_MASK)); + KASSERT(status->qtd->qtd_status & htole32(EHCI_QTD_TOGGLE_MASK)); #ifdef EHCI_DEBUG DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); @@ -3875,7 +3897,7 @@ ehci_device_bulk_start(struct usbd_xfer *xfer) ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end); exfer->ex_sqtdend = end; - end->qtd.qtd_status |= htole32(EHCI_QTD_IOC); + end->qtd->qtd_status |= htole32(EHCI_QTD_IOC); usb_syncmem(&end->dma, end->offs, sizeof(end->qtd), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); @@ -4090,7 +4112,7 @@ ehci_device_intr_start(struct usbd_xfer *xfer) ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end); - end->qtd.qtd_status |= htole32(EHCI_QTD_IOC); + end->qtd->qtd_status |= htole32(EHCI_QTD_IOC); usb_syncmem(&end->dma, end->offs, sizeof(end->qtd), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); exfer->ex_sqtdend = end; @@ -4241,17 +4263,17 @@ ehci_device_fs_isoc_init(struct usbd_xfer *xfer) k = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; dir = UE_GET_DIR(k) ? 1 : 0; - sitd->sitd.sitd_endp = + sitd->sitd->sitd_endp = htole32(EHCI_SITD_SET_ENDPT(UE_GET_ADDR(k)) | EHCI_SITD_SET_DADDR(dev->ud_addr) | EHCI_SITD_SET_PORT(dev->ud_myhsport->up_portno) | EHCI_SITD_SET_HUBA(huba) | EHCI_SITD_SET_DIR(dir)); - sitd->sitd.sitd_back = htole32(EHCI_LINK_TERMINATE); + sitd->sitd->sitd_back = htole32(EHCI_LINK_TERMINATE); } /* End of frame */ - sitd->sitd.sitd_trans |= htole32(EHCI_SITD_IOC); + sitd->sitd->sitd_trans |= htole32(EHCI_SITD_IOC); stop = sitd; stop->xfer_next = NULL; @@ -4347,15 +4369,15 @@ ehci_device_fs_isoc_transfer(struct usbd_xfer *xfer) KASSERT(sitd != NULL); KASSERT(xfer->ux_frlengths[i] <= 0x3ff); - sitd->sitd.sitd_trans = htole32(EHCI_SITD_ACTIVE | + sitd->sitd->sitd_trans = htole32(EHCI_SITD_ACTIVE | EHCI_SITD_SET_LEN(xfer->ux_frlengths[i])); /* Set page0 index and offset - TP and T-offset are set below */ - sitd->sitd.sitd_buffer[0] = htole32(DMAADDR(dma_buf, offs)); + sitd->sitd->sitd_buffer[0] = htole32(DMAADDR(dma_buf, offs)); offs += xfer->ux_frlengths[i]; - sitd->sitd.sitd_buffer[1] = + sitd->sitd->sitd_buffer[1] = htole32(EHCI_SITD_SET_BPTR(DMAADDR(dma_buf, offs - 1))); u_int huba __diagused = dev->ud_myhsport->up_parent->ud_addr; @@ -4370,13 +4392,13 @@ ehci_device_fs_isoc_transfer(struct usbd_xfer *xfer) k = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; dir = UE_GET_DIR(k) ? 1 : 0; - KASSERT(sitd->sitd.sitd_endp == htole32( + KASSERT(sitd->sitd->sitd_endp == htole32( EHCI_SITD_SET_ENDPT(UE_GET_ADDR(k)) | EHCI_SITD_SET_DADDR(dev->ud_addr) | EHCI_SITD_SET_PORT(dev->ud_myhsport->up_portno) | EHCI_SITD_SET_HUBA(huba) | EHCI_SITD_SET_DIR(dir))); - KASSERT(sitd->sitd.sitd_back == htole32(EHCI_LINK_TERMINATE)); + KASSERT(sitd->sitd->sitd_back == htole32(EHCI_LINK_TERMINATE)); uint8_t sa = 0; uint8_t sb = 0; @@ -4394,7 +4416,7 @@ ehci_device_fs_isoc_transfer(struct usbd_xfer *xfer) temp |= tlen; /* T-count = [1..6] */ temp |= 8; /* TP = Begin */ } - sitd->sitd.sitd_buffer[1] |= htole32(temp); + sitd->sitd->sitd_buffer[1] |= htole32(temp); tlen += sa; @@ -4414,7 +4436,7 @@ ehci_device_fs_isoc_transfer(struct usbd_xfer *xfer) sb = 0xfc; } - sitd->sitd.sitd_sched = htole32( + sitd->sitd->sitd_sched = htole32( EHCI_SITD_SET_SMASK(sa) | EHCI_SITD_SET_CMASK(sb) ); @@ -4424,10 +4446,10 @@ ehci_device_fs_isoc_transfer(struct usbd_xfer *xfer) } /* End of frame */ sitd = exfer->ex_sitdend; - sitd->sitd.sitd_trans |= htole32(EHCI_SITD_IOC); + sitd->sitd->sitd_trans |= htole32(EHCI_SITD_IOC); usb_syncmem(&sitd->dma, sitd->offs + offsetof(ehci_sitd_t, sitd_trans), - sizeof(sitd->sitd.sitd_trans), + sizeof(sitd->sitd->sitd_trans), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); if (xfer->ux_length) @@ -4467,13 +4489,13 @@ ehci_device_fs_isoc_transfer(struct usbd_xfer *xfer) sizeof(ehci_link_t), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - sitd->sitd.sitd_next = sc->sc_flist[frindex]; - if (sitd->sitd.sitd_next == 0) + sitd->sitd->sitd_next = sc->sc_flist[frindex]; + if (sitd->sitd->sitd_next == 0) /* * FIXME: frindex table gets initialized to NULL * or EHCI_NULL? */ - sitd->sitd.sitd_next = EHCI_NULL; + sitd->sitd->sitd_next = EHCI_NULL; usb_syncmem(&sitd->dma, sitd->offs + offsetof(ehci_sitd_t, sitd_next), @@ -4593,7 +4615,7 @@ ehci_device_isoc_init(struct usbd_xfer *xfer) if (prev != NULL) { /* Maybe not as it's updated by the scheduling? */ - prev->itd.itd_next = + prev->itd->itd_next = htole32(itd->physaddr | EHCI_LINK_ITD); prev->xfer_next = itd; @@ -4605,19 +4627,19 @@ ehci_device_isoc_init(struct usbd_xfer *xfer) * Other special values */ k = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; - itd->itd.itd_bufr[0] = htole32( + itd->itd->itd_bufr[0] = htole32( EHCI_ITD_SET_EP(UE_GET_ADDR(k)) | EHCI_ITD_SET_DADDR(epipe->pipe.up_dev->ud_addr)); k = (UE_GET_DIR(epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress)) ? 1 : 0; j = UGETW(epipe->pipe.up_endpoint->ue_edesc->wMaxPacketSize); - itd->itd.itd_bufr[1] |= htole32( + itd->itd->itd_bufr[1] |= htole32( EHCI_ITD_SET_DIR(k) | EHCI_ITD_SET_MAXPKT(UE_GET_SIZE(j))); /* FIXME: handle invalid trans - should be done in openpipe */ - itd->itd.itd_bufr[2] |= + itd->itd->itd_bufr[2] |= htole32(EHCI_ITD_SET_MULTI(UE_GET_TRANS(j)+1)); } /* End of frame */ @@ -4732,11 +4754,11 @@ ehci_device_isoc_transfer(struct usbd_xfer *xfer) int froffs = offs; if (prev != NULL) { - prev->itd.itd_next = + prev->itd->itd_next = htole32(itd->physaddr | EHCI_LINK_ITD); usb_syncmem(&prev->dma, prev->offs + offsetof(ehci_itd_t, itd_next), - sizeof(prev->itd.itd_next), BUS_DMASYNC_POSTWRITE); + sizeof(prev->itd->itd_next), BUS_DMASYNC_POSTWRITE); prev->xfer_next = itd; } @@ -4757,7 +4779,7 @@ ehci_device_isoc_transfer(struct usbd_xfer *xfer) * offset is. Works out how many pages that is. */ - itd->itd.itd_ctl[j] = htole32 ( EHCI_ITD_ACTIVE | + itd->itd->itd_ctl[j] = htole32 ( EHCI_ITD_ACTIVE | EHCI_ITD_SET_LEN(xfer->ux_frlengths[trans_count]) | EHCI_ITD_SET_PG(addr) | EHCI_ITD_SET_OFFS(EHCI_PAGE_OFFSET(DMAADDR(dma_buf,offs)))); @@ -4766,7 +4788,7 @@ ehci_device_isoc_transfer(struct usbd_xfer *xfer) trans_count++; if (trans_count >= xfer->ux_nframes) { /*Set IOC*/ - itd->itd.itd_ctl[j] |= htole32(EHCI_ITD_IOC); + itd->itd->itd_ctl[j] |= htole32(EHCI_ITD_IOC); break; } } @@ -4789,25 +4811,25 @@ ehci_device_isoc_transfer(struct usbd_xfer *xfer) uint64_t page = DMAADDR(dma_buf, page_offs); page = EHCI_PAGE(page); - itd->itd.itd_bufr[j] = htole32(EHCI_ITD_SET_BPTR(page)); - itd->itd.itd_bufr_hi[j] = htole32(page >> 32); + itd->itd->itd_bufr[j] = htole32(EHCI_ITD_SET_BPTR(page)); + itd->itd->itd_bufr_hi[j] = htole32(page >> 32); } /* * Other special values */ int k = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; - itd->itd.itd_bufr[0] |= htole32(EHCI_ITD_SET_EP(UE_GET_ADDR(k)) | + itd->itd->itd_bufr[0] |= htole32(EHCI_ITD_SET_EP(UE_GET_ADDR(k)) | EHCI_ITD_SET_DADDR(epipe->pipe.up_dev->ud_addr)); k = (UE_GET_DIR(epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress)) ? 1 : 0; j = UGETW(epipe->pipe.up_endpoint->ue_edesc->wMaxPacketSize); - itd->itd.itd_bufr[1] |= htole32(EHCI_ITD_SET_DIR(k) | + itd->itd->itd_bufr[1] |= htole32(EHCI_ITD_SET_DIR(k) | EHCI_ITD_SET_MAXPKT(UE_GET_SIZE(j))); /* FIXME: handle invalid trans */ - itd->itd.itd_bufr[2] |= + itd->itd->itd_bufr[2] |= htole32(EHCI_ITD_SET_MULTI(UE_GET_TRANS(j)+1)); usb_syncmem(&itd->dma, itd->offs, sizeof(ehci_itd_t), @@ -4857,17 +4879,17 @@ ehci_device_isoc_transfer(struct usbd_xfer *xfer) sizeof(ehci_link_t), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - itd->itd.itd_next = sc->sc_flist[frindex]; - if (itd->itd.itd_next == 0) + itd->itd->itd_next = sc->sc_flist[frindex]; + if (itd->itd->itd_next == 0) /* * FIXME: frindex table gets initialized to NULL * or EHCI_NULL? */ - itd->itd.itd_next = EHCI_NULL; + itd->itd->itd_next = EHCI_NULL; usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_next), - sizeof(itd->itd.itd_next), + sizeof(itd->itd->itd_next), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); sc->sc_flist[frindex] = htole32(EHCI_LINK_ITD | itd->physaddr); diff --git a/sys/dev/usb/ehcireg.h b/sys/dev/usb/ehcireg.h index 6bca149e00f9..e0378590f401 100644 --- a/sys/dev/usb/ehcireg.h +++ b/sys/dev/usb/ehcireg.h @@ -248,7 +248,10 @@ typedef struct { #define EHCI_ITD_SET_MULTI(x) __SHIFTIN((x), EHCI_ITD_MULTI_MASK) volatile ehci_isoc_bufr_ptr_t itd_bufr_hi[EHCI_ITD_NBUFFERS]; } ehci_itd_t; -#define EHCI_ITD_ALIGN 32 +#define EHCI_ITD_ALIGN 32 +#define EHCI_ITD_ALLOC_ALIGN MAX(EHCI_ITD_ALIGN, CACHE_LINE_SIZE) +#define EHCI_ITD_SIZE (roundup(sizeof(ehci_itd_t), EHCI_ITD_ALLOC_ALIGN)) +#define EHCI_ITD_CHUNK (EHCI_PAGE_SIZE / EHCI_ITD_SIZE) /* Split Transaction Isochronous Transfer Descriptor */ typedef struct { @@ -339,7 +342,11 @@ typedef struct { volatile ehci_physaddr_t qtd_buffer[EHCI_QTD_NBUFFERS]; volatile ehci_physaddr_t qtd_buffer_hi[EHCI_QTD_NBUFFERS]; } ehci_qtd_t; -#define EHCI_QTD_ALIGN 32 +#define EHCI_QTD_ALIGN 32 +#define EHCI_QTD_ALLOC_ALIGN MAX(EHCI_QTD_ALIGN, CACHE_LINE_SIZE) +#define EHCI_QTD_SIZE (roundup(sizeof(ehci_qtd_t), EHCI_QTD_ALLOC_ALIGN)) +#define EHCI_QTD_CHUNK (EHCI_PAGE_SIZE / EHCI_QTD_SIZE) + /* Queue Head */ typedef struct { @@ -391,6 +398,9 @@ typedef struct { ehci_qtd_t qh_qtd; } ehci_qh_t; #define EHCI_QH_ALIGN 32 +#define EHCI_QH_ALLOC_ALIGN MAX(EHCI_QH_ALIGN, CACHE_LINE_SIZE) +#define EHCI_QH_SIZE (roundup(sizeof(ehci_qh_t), EHCI_QH_ALLOC_ALIGN)) +#define EHCI_QH_CHUNK (EHCI_PAGE_SIZE / EHCI_QH_SIZE) /* Periodic Frame Span Traversal Node */ typedef struct { diff --git a/sys/dev/usb/ehcivar.h b/sys/dev/usb/ehcivar.h index f585bee80498..502c3b33a173 100644 --- a/sys/dev/usb/ehcivar.h +++ b/sys/dev/usb/ehcivar.h @@ -35,7 +35,7 @@ #include typedef struct ehci_soft_qtd { - ehci_qtd_t qtd; + ehci_qtd_t *qtd; struct ehci_soft_qtd *nextqtd; /* mirrors nextqtd in TD */ ehci_physaddr_t physaddr; /* qTD's physical address */ usb_dma_t dma; /* qTD's DMA infos */ @@ -43,12 +43,9 @@ typedef struct ehci_soft_qtd { struct usbd_xfer *xfer; /* xfer back pointer */ uint16_t len; } ehci_soft_qtd_t; -#define EHCI_SQTD_ALIGN MAX(EHCI_QTD_ALIGN, CACHE_LINE_SIZE) -#define EHCI_SQTD_SIZE (roundup(sizeof(struct ehci_soft_qtd), EHCI_SQTD_ALIGN)) -#define EHCI_SQTD_CHUNK (EHCI_PAGE_SIZE / EHCI_SQTD_SIZE) typedef struct ehci_soft_qh { - ehci_qh_t qh; + ehci_qh_t *qh; struct ehci_soft_qh *next; struct ehci_soft_qtd *sqtd; ehci_physaddr_t physaddr; @@ -56,13 +53,11 @@ typedef struct ehci_soft_qh { int offs; /* QH's offset in usb_dma_t */ int islot; } ehci_soft_qh_t; -#define EHCI_SQH_SIZE (roundup(sizeof(struct ehci_soft_qh), EHCI_QH_ALIGN)) -#define EHCI_SQH_CHUNK (EHCI_PAGE_SIZE / EHCI_SQH_SIZE) typedef struct ehci_soft_itd { union { - ehci_itd_t itd; - ehci_sitd_t sitd; + ehci_itd_t *itd; + ehci_sitd_t *sitd; }; union { struct { @@ -80,8 +75,6 @@ typedef struct ehci_soft_itd { int slot; struct timeval t; /* store free time */ } ehci_soft_itd_t; -#define EHCI_ITD_SIZE (roundup(sizeof(struct ehci_soft_itd), EHCI_ITD_ALIGN)) -#define EHCI_ITD_CHUNK (EHCI_PAGE_SIZE / EHCI_ITD_SIZE) #define ehci_soft_sitd_t ehci_soft_itd_t #define ehci_soft_sitd ehci_soft_itd diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c index ea8f726da37e..5342ef7718ab 100644 --- a/sys/dev/usb/ohci.c +++ b/sys/dev/usb/ohci.c @@ -409,15 +409,20 @@ ohci_alloc_sed(ohci_softc_t *sc) DPRINTFN(2, "allocating chunk", 0, 0, 0, 0); mutex_exit(&sc->sc_lock); - int err = usb_allocmem(&sc->sc_bus, OHCI_SED_SIZE * OHCI_SED_CHUNK, + int err = usb_allocmem(&sc->sc_bus, OHCI_ED_SIZE * OHCI_ED_CHUNK, OHCI_ED_ALIGN, 0 /*!USBMALLOC_COHERENT*/, &dma); if (err) return NULL; + ohci_soft_ed_t *seds = + kmem_alloc(sizeof(*sed) * OHCI_ED_CHUNK, KM_SLEEP); + mutex_enter(&sc->sc_lock); - for (i = 0; i < OHCI_SED_CHUNK; i++) { - offs = i * OHCI_SED_SIZE; - sed = KERNADDR(&dma, offs); + for (i = 0; i < OHCI_ED_CHUNK; i++) { + sed = &seds[i]; + + offs = i * OHCI_ED_SIZE; + sed->ed = KERNADDR(&dma, offs); sed->physaddr = DMAADDR(&dma, offs); sed->dma = dma; sed->offs = offs; @@ -429,7 +434,7 @@ ohci_alloc_sed(ohci_softc_t *sc) sc->sc_freeeds = sed->next; mutex_exit(&sc->sc_lock); - memset(&sed->ed, 0, sizeof(ohci_ed_t)); + memset(sed->ed, 0, sizeof(*sed->ed)); sed->next = 0; return sed; } @@ -467,19 +472,25 @@ ohci_alloc_std(ohci_softc_t *sc) DPRINTFN(2, "allocating chunk", 0, 0, 0, 0); mutex_exit(&sc->sc_lock); - int err = usb_allocmem(&sc->sc_bus, OHCI_STD_SIZE * OHCI_STD_CHUNK, + int err = usb_allocmem(&sc->sc_bus, OHCI_TD_SIZE * OHCI_TD_CHUNK, OHCI_TD_ALIGN, USBMALLOC_COHERENT, &dma); if (err) return NULL; + ohci_soft_td_t *stds = + kmem_alloc(sizeof(*std) * OHCI_TD_CHUNK, KM_SLEEP); + mutex_enter(&sc->sc_lock); - for (i = 0; i < OHCI_STD_CHUNK; i++) { - offs = i * OHCI_STD_SIZE; - std = KERNADDR(&dma, offs); + for (i = 0; i < OHCI_TD_CHUNK; i++) { + std = &stds[i]; + offs = i * OHCI_TD_SIZE; + + std->td = KERNADDR(&dma, offs); std->physaddr = DMAADDR(&dma, offs); std->dma = dma; std->offs = offs; std->nexttd = sc->sc_freetds; + sc->sc_freetds = std; } } @@ -488,7 +499,7 @@ ohci_alloc_std(ohci_softc_t *sc) sc->sc_freetds = std->nexttd; mutex_exit(&sc->sc_lock); - memset(&std->td, 0, sizeof(ohci_td_t)); + memset(std->td, 0, sizeof(*std->td)); std->nexttd = NULL; std->xfer = NULL; std->held = NULL; @@ -651,10 +662,10 @@ ohci_reset_std_chain(ohci_softc_t *sc, struct usbd_xfer *xfer, DPRINTFN(4, "sdataphys=0x%08jx edataphys=0x%08jx " "len=%jd curlen=%jd", sdataphys, edataphys, len, curlen); - cur->td.td_flags = tdflags; - cur->td.td_cbp = HTOO32(sdataphys); - cur->td.td_be = HTOO32(edataphys); - cur->td.td_nexttd = (next != NULL) ? HTOO32(next->physaddr) : 0; + cur->td->td_flags = tdflags; + cur->td->td_cbp = HTOO32(sdataphys); + cur->td->td_be = HTOO32(edataphys); + cur->td->td_nexttd = (next != NULL) ? HTOO32(next->physaddr) : 0; cur->nexttd = next; cur->len = curlen; cur->flags = OHCI_ADD_LEN; @@ -673,7 +684,7 @@ ohci_reset_std_chain(ohci_softc_t *sc, struct usbd_xfer *xfer, cur = next; } } - cur->td.td_flags |= + cur->td->td_flags |= HTOO32(xfer->ux_flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0); if (!rd && @@ -688,10 +699,10 @@ ohci_reset_std_chain(ohci_softc_t *sc, struct usbd_xfer *xfer, KASSERT(next != NULL); cur = next; - cur->td.td_flags = tdflags; - cur->td.td_cbp = 0; /* indicate 0 length packet */ - cur->td.td_nexttd = 0; - cur->td.td_be = ~0; + cur->td->td_flags = tdflags; + cur->td->td_cbp = 0; /* indicate 0 length packet */ + cur->td->td_nexttd = 0; + cur->td->td_be = ~0; cur->nexttd = NULL; cur->len = 0; cur->flags = 0; @@ -719,18 +730,25 @@ ohci_alloc_sitd(ohci_softc_t *sc) DPRINTFN(2, "allocating chunk", 0, 0, 0, 0); mutex_exit(&sc->sc_lock); - int err = usb_allocmem(&sc->sc_bus, OHCI_SITD_SIZE * OHCI_SITD_CHUNK, + int err = usb_allocmem(&sc->sc_bus, OHCI_ITD_SIZE * OHCI_ITD_CHUNK, OHCI_ITD_ALIGN, USBMALLOC_COHERENT, &dma); if (err) return NULL; + + ohci_soft_itd_t *sitds = + kmem_alloc(sizeof(*sitd) * OHCI_ITD_CHUNK, KM_SLEEP); + mutex_enter(&sc->sc_lock); - for (i = 0; i < OHCI_SITD_CHUNK; i++) { - offs = i * OHCI_SITD_SIZE; - sitd = KERNADDR(&dma, offs); + for (i = 0; i < OHCI_ITD_CHUNK; i++) { + sitd = &sitds[i]; + offs = i * OHCI_ITD_SIZE; + + sitd->itd = KERNADDR(&dma, offs); sitd->physaddr = DMAADDR(&dma, offs); sitd->dma = dma; sitd->offs = offs; sitd->nextitd = sc->sc_freeitds; + sc->sc_freeitds = sitd; } } @@ -739,7 +757,7 @@ ohci_alloc_sitd(ohci_softc_t *sc) sc->sc_freeitds = sitd->nextitd; mutex_exit(&sc->sc_lock); - memset(&sitd->itd, 0, sizeof(ohci_itd_t)); + memset(sitd->itd, 0, sizeof(*sitd->itd)); sitd->nextitd = NULL; sitd->xfer = NULL; @@ -843,7 +861,7 @@ ohci_init(ohci_softc_t *sc) err = ENOMEM; goto bad1; } - sc->sc_ctrl_head->ed.ed_flags |= HTOO32(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); @@ -851,7 +869,7 @@ ohci_init(ohci_softc_t *sc) err = ENOMEM; goto bad2; } - sc->sc_bulk_head->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); + sc->sc_bulk_head->ed->ed_flags |= HTOO32(OHCI_ED_SKIP); usb_syncmem(&sc->sc_bulk_head->dma, sc->sc_bulk_head->offs, sizeof(sc->sc_bulk_head->ed), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); @@ -862,7 +880,7 @@ ohci_init(ohci_softc_t *sc) err = ENOMEM; goto bad3; } - sc->sc_isoc_head->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); + sc->sc_isoc_head->ed->ed_flags |= HTOO32(OHCI_ED_SKIP); usb_syncmem(&sc->sc_isoc_head->dma, sc->sc_isoc_head->offs, sizeof(sc->sc_isoc_head->ed), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); @@ -878,13 +896,13 @@ ohci_init(ohci_softc_t *sc) } /* All ED fields are set to 0. */ sc->sc_eds[i] = sed; - sed->ed.ed_flags |= HTOO32(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 = HTOO32(psed->physaddr); + sed->ed->ed_nexted = HTOO32(psed->physaddr); usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } @@ -1469,7 +1487,7 @@ ohci_softintr(void *v) usb_syncmem(&std->dma, std->offs, sizeof(std->td), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); std->dnext = sdone; - done = O32TOH(std->td.td_nexttd); + done = O32TOH(std->td->td_nexttd); sdone = std; DPRINTFN(10, "add TD %#jx", (uintptr_t)std, 0, 0, 0); continue; @@ -1479,7 +1497,7 @@ ohci_softintr(void *v) usb_syncmem(&sitd->dma, sitd->offs, sizeof(sitd->itd), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); sitd->dnext = sidone; - done = O32TOH(sitd->itd.itd_nextitd); + done = O32TOH(sitd->itd->itd_nextitd); sidone = sitd; DPRINTFN(5, "add ITD %#jx", (uintptr_t)sitd, 0, 0, 0); continue; @@ -1532,14 +1550,14 @@ ohci_softintr(void *v) continue; len = std->len; - if (std->td.td_cbp != 0) - len -= O32TOH(std->td.td_be) - - O32TOH(std->td.td_cbp) + 1; + if (std->td->td_cbp != 0) + len -= O32TOH(std->td->td_be) - + O32TOH(std->td->td_cbp) + 1; DPRINTFN(10, "len=%jd, flags=%#jx", len, std->flags, 0, 0); if (std->flags & OHCI_ADD_LEN) xfer->ux_actlen += len; - cc = OHCI_TD_GET_CC(O32TOH(std->td.td_flags)); + cc = OHCI_TD_GET_CC(O32TOH(std->td->td_flags)); if (cc == OHCI_CC_NO_ERROR) { ohci_hash_rem_td(sc, std); if (std->flags & OHCI_CALL_DONE) { @@ -1566,11 +1584,11 @@ ohci_softintr(void *v) ohci_soft_ed_t *sed = opipe->sed; /* clear halt and TD chain, preserving toggle carry */ - sed->ed.ed_headp = HTOO32(p->physaddr | - (O32TOH(sed->ed.ed_headp) & OHCI_TOGGLECARRY)); + sed->ed->ed_headp = HTOO32(p->physaddr | + (O32TOH(sed->ed->ed_headp) & OHCI_TOGGLECARRY)); usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_headp), - sizeof(sed->ed.ed_headp), + sizeof(sed->ed->ed_headp), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF); @@ -1626,17 +1644,17 @@ ohci_softintr(void *v) sitd = next) { next = sitd->nextitd; if (OHCI_ITD_GET_CC(O32TOH(sitd-> - itd.itd_flags)) != OHCI_CC_NO_ERROR) + itd->itd_flags)) != OHCI_CC_NO_ERROR) xfer->ux_status = USBD_IOERROR; /* For input, update frlengths with actual */ /* XXX anything necessary for output? */ if (uedir == UE_DIR_IN && xfer->ux_status == USBD_NORMAL_COMPLETION) { iframes = OHCI_ITD_GET_FC(O32TOH( - sitd->itd.itd_flags)); + sitd->itd->itd_flags)); for (j = 0; j < iframes; i++, j++) { len = O16TOH(sitd-> - itd.itd_offset[j]); + itd->itd_offset[j]); if ((OHCI_ITD_PSW_GET_CC(len) & OHCI_CC_NOT_ACCESSED_MASK) == OHCI_CC_NOT_ACCESSED) @@ -1822,17 +1840,17 @@ ohci_add_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed, ohci_soft_ed_t *head) KASSERT(mutex_owned(&sc->sc_lock)); usb_syncmem(&head->dma, head->offs + offsetof(ohci_ed_t, ed_nexted), - sizeof(head->ed.ed_nexted), + sizeof(head->ed->ed_nexted), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); sed->next = head->next; - sed->ed.ed_nexted = head->ed.ed_nexted; + sed->ed->ed_nexted = head->ed->ed_nexted; usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_nexted), - sizeof(sed->ed.ed_nexted), + sizeof(sed->ed->ed_nexted), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); head->next = sed; - head->ed.ed_nexted = HTOO32(sed->physaddr); + head->ed->ed_nexted = HTOO32(sed->physaddr); usb_syncmem(&head->dma, head->offs + offsetof(ohci_ed_t, ed_nexted), - sizeof(head->ed.ed_nexted), + sizeof(head->ed->ed_nexted), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } @@ -1852,12 +1870,12 @@ ohci_rem_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed, ohci_soft_ed_t *head) KASSERT(p != NULL); usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_nexted), - sizeof(sed->ed.ed_nexted), + sizeof(sed->ed->ed_nexted), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); p->next = sed->next; - p->ed.ed_nexted = sed->ed.ed_nexted; + p->ed->ed_nexted = sed->ed->ed_nexted; usb_syncmem(&p->dma, p->offs + offsetof(ohci_ed_t, ed_nexted), - sizeof(p->ed.ed_nexted), + sizeof(p->ed->ed_nexted), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } @@ -1971,7 +1989,7 @@ ohci_dump_td(ohci_softc_t *sc, ohci_soft_td_t *std) usb_syncmem(&std->dma, std->offs, sizeof(std->td), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - uint32_t flags = O32TOH(std->td.td_flags); + uint32_t flags = O32TOH(std->td->td_flags); DPRINTF("TD(%#jx) at 0x%08jx:", (uintptr_t)std, std->physaddr, 0, 0); DPRINTF(" round=%jd DP=%jx DI=%jx T=%jx", !!(flags & OHCI_TD_R), @@ -1981,9 +1999,9 @@ ohci_dump_td(ohci_softc_t *sc, ohci_soft_td_t *std) DPRINTF(" EC=%jd CC=%jd", OHCI_TD_GET_EC(flags), OHCI_TD_GET_CC(flags), 0, 0); DPRINTF(" td_cbp=0x%08jx td_nexttd=0x%08jx td_be=0x%08jx", - (u_long)O32TOH(std->td.td_cbp), - (u_long)O32TOH(std->td.td_nexttd), - (u_long)O32TOH(std->td.td_be), 0); + (u_long)O32TOH(std->td->td_cbp), + (u_long)O32TOH(std->td->td_nexttd), + (u_long)O32TOH(std->td->td_be), 0); } void @@ -1994,28 +2012,28 @@ ohci_dump_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd) usb_syncmem(&sitd->dma, sitd->offs, sizeof(sitd->itd), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - uint32_t flags = O32TOH(sitd->itd.itd_flags); + uint32_t flags = O32TOH(sitd->itd->itd_flags); DPRINTF("ITD(%#jx) at 0x%08jx", (uintptr_t)sitd, sitd->physaddr, 0, 0); DPRINTF(" sf=%jd di=%jd fc=%jd cc=%jd", OHCI_ITD_GET_SF(flags), OHCI_ITD_GET_DI(flags), OHCI_ITD_GET_FC(flags), OHCI_ITD_GET_CC(flags)); DPRINTF(" bp0=0x%08jx next=0x%08jx be=0x%08jx", - O32TOH(sitd->itd.itd_bp0), - O32TOH(sitd->itd.itd_nextitd), - O32TOH(sitd->itd.itd_be), 0); + O32TOH(sitd->itd->itd_bp0), + O32TOH(sitd->itd->itd_nextitd), + O32TOH(sitd->itd->itd_be), 0); CTASSERT(OHCI_ITD_NOFFSET == 8); DPRINTF(" offs[0] = 0x%04jx offs[1] = 0x%04jx " "offs[2] = 0x%04jx offs[3] = 0x%04jx", - O16TOH(sitd->itd.itd_offset[0]), - O16TOH(sitd->itd.itd_offset[1]), - O16TOH(sitd->itd.itd_offset[2]), - O16TOH(sitd->itd.itd_offset[3])); + O16TOH(sitd->itd->itd_offset[0]), + O16TOH(sitd->itd->itd_offset[1]), + O16TOH(sitd->itd->itd_offset[2]), + O16TOH(sitd->itd->itd_offset[3])); DPRINTF(" offs[4] = 0x%04jx offs[5] = 0x%04jx " "offs[6] = 0x%04jx offs[7] = 0x%04jx", - O16TOH(sitd->itd.itd_offset[4]), - O16TOH(sitd->itd.itd_offset[5]), - O16TOH(sitd->itd.itd_offset[6]), - O16TOH(sitd->itd.itd_offset[7])); + O16TOH(sitd->itd->itd_offset[4]), + O16TOH(sitd->itd->itd_offset[5]), + O16TOH(sitd->itd->itd_offset[6]), + O16TOH(sitd->itd->itd_offset[7])); } void @@ -2033,7 +2051,7 @@ ohci_dump_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed) usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - uint32_t flags = O32TOH(sed->ed.ed_flags); + uint32_t flags = O32TOH(sed->ed->ed_flags); DPRINTF("ED(%#jx) at 0x%08jx:", (uintptr_t)sed, sed->physaddr, 0, 0); DPRINTF(" addr=%jd endpt=%jd maxp=%jd", OHCI_ED_GET_FA(flags), @@ -2045,12 +2063,12 @@ ohci_dump_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed) __SHIFTOUT(flags, OHCI_ED_SPEED), __SHIFTOUT(flags, OHCI_ED_SKIP), OHCI_ED_GET_FORMAT(flags)); - DPRINTF(" tailp=0x%08jx", (u_long)O32TOH(sed->ed.ed_tailp), + DPRINTF(" tailp=0x%08jx", (u_long)O32TOH(sed->ed->ed_tailp), 0, 0, 0); DPRINTF(" headp=0x%08jx nexted=0x%08jx halted=%jd carry=%jd", - O32TOH(sed->ed.ed_headp), O32TOH(sed->ed.ed_nexted), - !!(O32TOH(sed->ed.ed_headp) & OHCI_HALTED), - !!(O32TOH(sed->ed.ed_headp) & OHCI_TOGGLECARRY)); + O32TOH(sed->ed->ed_headp), O32TOH(sed->ed->ed_nexted), + !!(O32TOH(sed->ed->ed_headp) & OHCI_HALTED), + !!(O32TOH(sed->ed->ed_headp) & OHCI_TOGGLECARRY)); } #endif @@ -2125,15 +2143,15 @@ ohci_open(struct usbd_pipe *pipe) OHCI_ED_SET_FORMAT(OHCI_ED_FORMAT_GEN) | OHCI_ED_SET_DIR(OHCI_ED_DIR_TD); } - sed->ed.ed_flags = HTOO32( + sed->ed->ed_flags = HTOO32( OHCI_ED_SET_FA(addr) | OHCI_ED_SET_EN(UE_GET_ADDR(ed->bEndpointAddress)) | (dev->ud_speed == USB_SPEED_LOW ? OHCI_ED_SPEED : 0) | fmt | OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize))); - sed->ed.ed_headp = HTOO32(tdphys | + sed->ed->ed_headp = HTOO32(tdphys | (pipe->up_endpoint->ue_toggle ? OHCI_TOGGLECARRY : 0)); - sed->ed.ed_tailp = HTOO32(tdphys); + sed->ed->ed_tailp = HTOO32(tdphys); usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); @@ -2197,15 +2215,15 @@ ohci_close_pipe(struct usbd_pipe *pipe, ohci_soft_ed_t *head) KASSERT(mutex_owned(&sc->sc_lock)); #ifdef DIAGNOSTIC - sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); - if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) != - (O32TOH(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, O32TOH(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=%#x " "tl=%#x pipe=%p, std=%p\n", sed, - (int)O32TOH(sed->ed.ed_headp), - (int)O32TOH(sed->ed.ed_tailp), + (int)O32TOH(sed->ed->ed_headp), + (int)O32TOH(sed->ed->ed_tailp), pipe, std); #ifdef OHCI_DEBUG usbd_dump_pipe(&opipe->pipe); @@ -2214,8 +2232,8 @@ ohci_close_pipe(struct usbd_pipe *pipe, ohci_soft_ed_t *head) ohci_dump_td(sc, std); #endif usb_delay_ms(&sc->sc_bus, 2); - if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) != - (O32TOH(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 @@ -2223,7 +2241,7 @@ ohci_close_pipe(struct usbd_pipe *pipe, ohci_soft_ed_t *head) /* Make sure the host controller is not touching this ED */ usb_delay_ms(&sc->sc_bus, 1); pipe->up_endpoint->ue_toggle = - (O32TOH(sed->ed.ed_headp) & OHCI_TOGGLECARRY) ? 1 : 0; + (O32TOH(sed->ed->ed_headp) & OHCI_TOGGLECARRY) ? 1 : 0; ohci_free_sed_locked(sc, opipe->sed); } @@ -2276,15 +2294,15 @@ ohci_abortx(struct usbd_xfer *xfer) */ DPRINTFN(1, "stop ed=%#jx", (uintptr_t)sed, 0, 0, 0); usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), - sizeof(sed->ed.ed_flags), + sizeof(sed->ed->ed_flags), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - if (!(sed->ed.ed_flags & OHCI_HALTED)) { + if (!(sed->ed->ed_flags & OHCI_HALTED)) { /* force hardware skip */ DPRINTFN(1, "pausing ed=%#jx", (uintptr_t)sed, 0, 0, 0); - sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); + sed->ed->ed_flags |= HTOO32(OHCI_ED_SKIP); usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), - sizeof(sed->ed.ed_flags), + sizeof(sed->ed->ed_flags), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); DPRINTFN(10, "SF %#jx xfer %#jx", (uintptr_t)sc, @@ -2347,13 +2365,13 @@ ohci_abortx(struct usbd_xfer *xfer) #define OHCI_CC_ACCESSED_P(x) \ (((x) & OHCI_CC_NOT_ACCESSED_MASK) != OHCI_CC_NOT_ACCESSED) - headp = O32TOH(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; n = p->nexttd; - int cc = OHCI_TD_GET_CC(O32TOH(p->td.td_flags)); + int cc = OHCI_TD_GET_CC(O32TOH(p->td->td_flags)); if (!OHCI_CC_ACCESSED_P(cc)) { ohci_hash_rem_td(sc, p); continue; @@ -2387,13 +2405,13 @@ ohci_abortx(struct usbd_xfer *xfer) /* Zap headp register if hardware pointed inside the xfer. */ if (hit) { DPRINTFN(1, "set hd=0x%08jx, tl=0x%08jx", (int)p->physaddr, - (int)O32TOH(sed->ed.ed_tailp), 0, 0); + (int)O32TOH(sed->ed->ed_tailp), 0, 0); /* unlink TDs, preserving toggle carry */ - sed->ed.ed_headp = HTOO32(p->physaddr | - (O32TOH(sed->ed.ed_headp) & OHCI_TOGGLECARRY)); + sed->ed->ed_headp = HTOO32(p->physaddr | + (O32TOH(sed->ed->ed_headp) & OHCI_TOGGLECARRY)); usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_headp), - sizeof(sed->ed.ed_headp), + sizeof(sed->ed->ed_headp), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } else { DPRINTFN(1, "no hit", 0, 0, 0, 0); @@ -2403,11 +2421,11 @@ ohci_abortx(struct usbd_xfer *xfer) * HC Step 4: Turn on hardware again. */ usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), - sizeof(sed->ed.ed_flags), + sizeof(sed->ed->ed_flags), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); /* remove hardware skip */ + sed->ed->ed_flags &= HTOO32(~OHCI_ED_SKIP); /* remove hardware skip */ usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), - sizeof(sed->ed.ed_flags), + sizeof(sed->ed->ed_flags), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); /* @@ -2844,13 +2862,13 @@ ohci_device_ctrl_start(struct usbd_xfer *xfer) DPRINTFN(10, "xfer=%#jx new tail=%#jx held at %#jx", (uintptr_t)ox, (uintptr_t)tail, (uintptr_t)tail->held, 0); - KASSERTMSG(OHCI_ED_GET_FA(O32TOH(sed->ed.ed_flags)) == dev->ud_addr, + KASSERTMSG(OHCI_ED_GET_FA(O32TOH(sed->ed->ed_flags)) == dev->ud_addr, "address ED %" __PRIuBITS " pipe %d\n", - OHCI_ED_GET_FA(O32TOH(sed->ed.ed_flags)), dev->ud_addr); - KASSERTMSG(OHCI_ED_GET_MAXP(O32TOH(sed->ed.ed_flags)) == + OHCI_ED_GET_FA(O32TOH(sed->ed->ed_flags)), dev->ud_addr); + KASSERTMSG(OHCI_ED_GET_MAXP(O32TOH(sed->ed->ed_flags)) == UGETW(opipe->pipe.up_endpoint->ue_edesc->wMaxPacketSize), "MPL ED %" __PRIuBITS " pipe %d\n", - OHCI_ED_GET_MAXP(O32TOH(sed->ed.ed_flags)), + OHCI_ED_GET_MAXP(O32TOH(sed->ed->ed_flags)), UGETW(opipe->pipe.up_endpoint->ue_edesc->wMaxPacketSize)); /* next will point to data if len != 0 */ @@ -2864,7 +2882,7 @@ ohci_device_ctrl_start(struct usbd_xfer *xfer) next = ox->ox_stds[0]; ohci_reset_std_chain(sc, xfer, len, isread, next, &end); - end->td.td_nexttd = HTOO32(stat->physaddr); + end->td->td_nexttd = HTOO32(stat->physaddr); end->nexttd = stat; usb_syncmem(&end->dma, end->offs, sizeof(end->td), @@ -2874,11 +2892,11 @@ ohci_device_ctrl_start(struct usbd_xfer *xfer) isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); std = ox->ox_stds[0]; /* Start toggle at 1 and then use the carried toggle. */ - std->td.td_flags &= HTOO32(~OHCI_TD_TOGGLE_MASK); - std->td.td_flags |= HTOO32(OHCI_TD_SET_TOGGLE(OHCI_TD_TOGGLE_1)); + std->td->td_flags &= HTOO32(~OHCI_TD_TOGGLE_MASK); + std->td->td_flags |= HTOO32(OHCI_TD_SET_TOGGLE(OHCI_TD_TOGGLE_1)); usb_syncmem(&std->dma, std->offs + offsetof(ohci_td_t, td_flags), - sizeof(std->td.td_flags), + sizeof(std->td->td_flags), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } @@ -2891,15 +2909,15 @@ ohci_device_ctrl_start(struct usbd_xfer *xfer) memcpy(KERNADDR(&opipe->ctrl.reqdma, 0), req, sizeof(*req)); usb_syncmem(&opipe->ctrl.reqdma, 0, sizeof(*req), BUS_DMASYNC_PREWRITE); - setup->td.td_flags = HTOO32( + setup->td->td_flags = HTOO32( OHCI_TD_SET_DP(OHCI_TD_DP_SETUP) | OHCI_TD_SET_CC(OHCI_TD_NOCC) | OHCI_TD_SET_TOGGLE(OHCI_TD_TOGGLE_0) | OHCI_TD_SET_DI(OHCI_TD_NOINTR) ); - setup->td.td_cbp = HTOO32(DMAADDR(&opipe->ctrl.reqdma, 0)); - setup->td.td_nexttd = HTOO32(next->physaddr); - setup->td.td_be = HTOO32(O32TOH(setup->td.td_cbp) + sizeof(*req) - 1); + setup->td->td_cbp = HTOO32(DMAADDR(&opipe->ctrl.reqdma, 0)); + setup->td->td_nexttd = HTOO32(next->physaddr); + setup->td->td_be = HTOO32(O32TOH(setup->td->td_cbp) + sizeof(*req) - 1); setup->nexttd = next; setup->len = 0; setup->xfer = xfer; @@ -2910,15 +2928,15 @@ ohci_device_ctrl_start(struct usbd_xfer *xfer) usb_syncmem(&setup->dma, setup->offs, sizeof(setup->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - stat->td.td_flags = HTOO32( + stat->td->td_flags = HTOO32( OHCI_TD_SET_DP(isread ? OHCI_TD_DP_OUT : OHCI_TD_DP_IN) | OHCI_TD_SET_CC(OHCI_TD_NOCC) | OHCI_TD_SET_TOGGLE(OHCI_TD_TOGGLE_1) | OHCI_TD_SET_DI(1) ); - stat->td.td_cbp = 0; - stat->td.td_nexttd = HTOO32(tail->physaddr); - stat->td.td_be = 0; + stat->td->td_cbp = 0; + stat->td->td_nexttd = HTOO32(tail->physaddr); + stat->td->td_be = 0; stat->nexttd = tail; stat->flags = OHCI_CALL_DONE; stat->len = 0; @@ -2928,7 +2946,7 @@ ohci_device_ctrl_start(struct usbd_xfer *xfer) usb_syncmem(&stat->dma, stat->offs, sizeof(stat->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - memset(&tail->td, 0, sizeof(tail->td)); + memset(tail->td, 0, sizeof(*tail->td)); tail->nexttd = NULL; tail->xfer = NULL; @@ -2945,10 +2963,10 @@ ohci_device_ctrl_start(struct usbd_xfer *xfer) #endif /* Insert ED in schedule */ - sed->ed.ed_tailp = HTOO32(tail->physaddr); + sed->ed->ed_tailp = HTOO32(tail->physaddr); usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_tailp), - sizeof(sed->ed.ed_tailp), + sizeof(sed->ed->ed_tailp), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF); usbd_xfer_schedule_timeout(xfer); @@ -3000,7 +3018,7 @@ ohci_device_clear_toggle(struct usbd_pipe *pipe) struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(pipe); ohci_softc_t *sc = OHCI_PIPE2SC(pipe); - opipe->sed->ed.ed_headp &= HTOO32(~OHCI_TOGGLECARRY); + opipe->sed->ed->ed_headp &= HTOO32(~OHCI_TOGGLECARRY); } Static void @@ -3121,7 +3139,7 @@ ohci_device_bulk_start(struct usbd_xfer *xfer) /* point at sentinel */ tail = opipe->tail.td; - memset(&tail->td, 0, sizeof(tail->td)); + memset(tail->td, 0, sizeof(*tail->td)); tail->held = &opipe->tail.td; tail->nexttd = NULL; tail->xfer = NULL; @@ -3136,9 +3154,9 @@ ohci_device_bulk_start(struct usbd_xfer *xfer) KASSERT(opipe->tail.td == tail); /* We want interrupt at the end of the transfer. */ - last->td.td_flags &= HTOO32(~OHCI_TD_DI_MASK); - last->td.td_flags |= HTOO32(OHCI_TD_SET_DI(1)); - last->td.td_nexttd = HTOO32(tail->physaddr); + last->td->td_flags &= HTOO32(~OHCI_TD_DI_MASK); + last->td->td_flags |= HTOO32(OHCI_TD_SET_DI(1)); + last->td->td_nexttd = HTOO32(tail->physaddr); last->nexttd = tail; last->flags |= OHCI_CALL_DONE; usb_syncmem(&last->dma, last->offs, sizeof(last->td), @@ -3146,10 +3164,10 @@ ohci_device_bulk_start(struct usbd_xfer *xfer) DPRINTFN(4, "ed_flags=0x%08jx td_flags=0x%08jx " "td_cbp=0x%08jx td_be=0x%08jx", - (int)O32TOH(sed->ed.ed_flags), - (int)O32TOH(data->td.td_flags), - (int)O32TOH(data->td.td_cbp), - (int)O32TOH(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 DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); @@ -3166,8 +3184,8 @@ ohci_device_bulk_start(struct usbd_xfer *xfer) } usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - sed->ed.ed_tailp = HTOO32(tail->physaddr); - sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); + sed->ed->ed_tailp = HTOO32(tail->physaddr); + sed->ed->ed_flags &= HTOO32(~OHCI_ED_SKIP); usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF); @@ -3326,7 +3344,7 @@ ohci_device_intr_start(struct usbd_xfer *xfer) /* point at sentinel */ tail = opipe->tail.td; - memset(&tail->td, 0, sizeof(tail->td)); + memset(tail->td, 0, sizeof(*tail->td)); tail->held = &opipe->tail.td; tail->nexttd = NULL; tail->xfer = NULL; @@ -3341,10 +3359,10 @@ ohci_device_intr_start(struct usbd_xfer *xfer) KASSERT(opipe->tail.td == tail); /* We want interrupt at the end of the transfer. */ - last->td.td_flags &= HTOO32(~OHCI_TD_DI_MASK); - last->td.td_flags |= HTOO32(OHCI_TD_SET_DI(1)); + last->td->td_flags &= HTOO32(~OHCI_TD_DI_MASK); + last->td->td_flags |= HTOO32(OHCI_TD_SET_DI(1)); - last->td.td_nexttd = HTOO32(tail->physaddr); + last->td->td_nexttd = HTOO32(tail->physaddr); last->nexttd = tail; last->flags |= OHCI_CALL_DONE; usb_syncmem(&last->dma, last->offs, sizeof(last->td), @@ -3362,8 +3380,8 @@ ohci_device_intr_start(struct usbd_xfer *xfer) /* Insert ED in schedule */ usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - sed->ed.ed_tailp = HTOO32(tail->physaddr); - sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); + sed->ed->ed_tailp = HTOO32(tail->physaddr); + sed->ed->ed_flags &= HTOO32(~OHCI_ED_SKIP); usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); @@ -3404,21 +3422,21 @@ ohci_device_intr_close(struct usbd_pipe *pipe) pos, 0); usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); + sed->ed->ed_flags |= HTOO32(OHCI_ED_SKIP); usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), - sizeof(sed->ed.ed_flags), + sizeof(sed->ed->ed_flags), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) != - (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK)) + if ((O32TOH(sed->ed->ed_tailp) & OHCI_HEADMASK) != + (O32TOH(sed->ed->ed_headp) & OHCI_HEADMASK)) usb_delay_ms_locked(&sc->sc_bus, 2, &sc->sc_lock); for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next) continue; KASSERT(p); p->next = sed->next; - p->ed.ed_nexted = sed->ed.ed_nexted; + p->ed->ed_nexted = sed->ed->ed_nexted; usb_syncmem(&p->dma, p->offs + offsetof(ohci_ed_t, ed_nexted), - sizeof(p->ed.ed_nexted), + sizeof(p->ed->ed_nexted), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); for (j = 0; j < nslots; j++) @@ -3478,16 +3496,16 @@ ohci_device_setintr(ohci_softc_t *sc, struct ohci_pipe *opipe, int ival) hsed = sc->sc_eds[best]; sed->next = hsed->next; usb_syncmem(&hsed->dma, hsed->offs + offsetof(ohci_ed_t, ed_flags), - sizeof(hsed->ed.ed_flags), + sizeof(hsed->ed->ed_flags), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - sed->ed.ed_nexted = hsed->ed.ed_nexted; + sed->ed->ed_nexted = hsed->ed->ed_nexted; usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), - sizeof(sed->ed.ed_flags), + sizeof(sed->ed->ed_flags), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); hsed->next = sed; - hsed->ed.ed_nexted = HTOO32(sed->physaddr); + hsed->ed->ed_nexted = HTOO32(sed->physaddr); usb_syncmem(&hsed->dma, hsed->offs + offsetof(ohci_ed_t, ed_flags), - sizeof(hsed->ed.ed_flags), + sizeof(hsed->ed->ed_flags), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); mutex_exit(&sc->sc_lock); @@ -3688,15 +3706,15 @@ ohci_device_isoc_enter(struct usbd_xfer *xfer) KASSERT(j < ox->ox_nsitd); /* Fill current ITD */ - sitd->itd.itd_flags = HTOO32( + sitd->itd->itd_flags = HTOO32( OHCI_ITD_SET_CC(OHCI_ITD_NOCC) | OHCI_ITD_SET_SF(isoc->next) | OHCI_ITD_SET_DI(6) | /* delay intr a little */ OHCI_ITD_SET_FC(ncur) ); - sitd->itd.itd_bp0 = HTOO32(bp0); - sitd->itd.itd_nextitd = HTOO32(nsitd->physaddr); - sitd->itd.itd_be = HTOO32(end); + sitd->itd->itd_bp0 = HTOO32(bp0); + sitd->itd->itd_nextitd = HTOO32(nsitd->physaddr); + sitd->itd->itd_be = HTOO32(end); sitd->nextitd = nsitd; sitd->xfer = xfer; sitd->flags = 0; @@ -3712,7 +3730,7 @@ ohci_device_isoc_enter(struct usbd_xfer *xfer) bp0 = bp1 = OHCI_PAGE(buf); ncur = 0; } - sitd->itd.itd_offset[ncur] = HTOO16(OHCI_ITD_MK_OFFS(offs)); + sitd->itd->itd_offset[ncur] = HTOO16(OHCI_ITD_MK_OFFS(offs)); end = nend; offs = noffs; } @@ -3720,7 +3738,7 @@ ohci_device_isoc_enter(struct usbd_xfer *xfer) /* point at sentinel */ tail = opipe->tail.itd; - memset(&tail->itd, 0, sizeof(tail->itd)); + memset(tail->itd, 0, sizeof(*tail->itd)); tail->held = &opipe->tail.itd; tail->nextitd = NULL; tail->xfer = NULL; @@ -3728,15 +3746,15 @@ ohci_device_isoc_enter(struct usbd_xfer *xfer) BUS_DMASYNC_PREWRITE); /* Fixup last used ITD */ - sitd->itd.itd_flags = HTOO32( + sitd->itd->itd_flags = HTOO32( OHCI_ITD_SET_CC(OHCI_ITD_NOCC) | OHCI_ITD_SET_SF(isoc->next) | OHCI_ITD_SET_DI(0) | OHCI_ITD_SET_FC(ncur) ); - sitd->itd.itd_bp0 = HTOO32(bp0); - sitd->itd.itd_nextitd = HTOO32(tail->physaddr); - sitd->itd.itd_be = HTOO32(end); + sitd->itd->itd_bp0 = HTOO32(bp0); + sitd->itd->itd_nextitd = HTOO32(tail->physaddr); + sitd->itd->itd_be = HTOO32(end); sitd->nextitd = tail; sitd->xfer = xfer; sitd->flags = OHCI_CALL_DONE; @@ -3769,10 +3787,10 @@ ohci_device_isoc_enter(struct usbd_xfer *xfer) usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - sed->ed.ed_tailp = HTOO32(tail->physaddr); - sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); + sed->ed->ed_tailp = HTOO32(tail->physaddr); + sed->ed->ed_flags &= HTOO32(~OHCI_ED_SKIP); usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), - sizeof(sed->ed.ed_flags), + sizeof(sed->ed->ed_flags), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); mutex_exit(&sc->sc_lock); } @@ -3803,9 +3821,9 @@ ohci_device_isoc_abort(struct usbd_xfer *xfer) sed = opipe->sed; usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); /* force hardware skip */ + sed->ed->ed_flags |= HTOO32(OHCI_ED_SKIP); /* force hardware skip */ usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), - sizeof(sed->ed.ed_flags), + sizeof(sed->ed->ed_flags), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); sitd = xfer->ux_hcpriv; @@ -3825,8 +3843,8 @@ ohci_device_isoc_abort(struct usbd_xfer *xfer) /* Run callback. */ usb_transfer_complete(xfer); - sed->ed.ed_headp = HTOO32(sitd->physaddr); /* unlink TDs */ - sed->ed.ed_flags &= HTOO32(~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 */ usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); diff --git a/sys/dev/usb/ohcireg.h b/sys/dev/usb/ohcireg.h index 8cea85bd54bf..57920fc7eaf5 100644 --- a/sys/dev/usb/ohcireg.h +++ b/sys/dev/usb/ohcireg.h @@ -185,7 +185,11 @@ typedef struct { volatile ohci_physaddr_t ed_nexted; } ohci_ed_t; /* #define OHCI_ED_SIZE 16 */ -#define OHCI_ED_ALIGN 16 +#define OHCI_ED_ALIGN 16 +#define OHCI_ED_ALLOC_ALIGN MAX(OHCI_ED_ALIGN, CACHE_LINE_SIZE) +#define OHCI_ED_SIZE (roundup(sizeof(ohci_ed_t), OHCI_ED_ALLOC_ALIGN)) +#define OHCI_ED_CHUNK (PAGE_SIZE / OHCI_ED_SIZE) + typedef struct { volatile uint32_t td_flags; @@ -220,6 +224,10 @@ typedef struct { } ohci_td_t; /* #define OHCI_TD_SIZE 16 */ #define OHCI_TD_ALIGN 16 +#define OHCI_TD_ALLOC_ALIGN MAX(OHCI_TD_ALIGN, CACHE_LINE_SIZE) +#define OHCI_TD_SIZE (roundup(sizeof(ohci_td_t), OHCI_TD_ALLOC_ALIGN)) +#define OHCI_TD_CHUNK (PAGE_SIZE / OHCI_TD_SIZE) + #define OHCI_ITD_NOFFSET 8 typedef struct { @@ -252,6 +260,9 @@ typedef struct { } ohci_itd_t; /* #define OHCI_ITD_SIZE 32 */ #define OHCI_ITD_ALIGN 32 +#define OHCI_ITD_ALLOC_ALIGN MAX(OHCI_ITD_ALIGN, CACHE_LINE_SIZE) +#define OHCI_ITD_SIZE (roundup(sizeof(ohci_itd_t), OHCI_ITD_ALLOC_ALIGN)) +#define OHCI_ITD_CHUNK (PAGE_SIZE / OHCI_ITD_SIZE) #define OHCI_CC_NO_ERROR 0 diff --git a/sys/dev/usb/ohcivar.h b/sys/dev/usb/ohcivar.h index 112a049a215d..11193738e11e 100644 --- a/sys/dev/usb/ohcivar.h +++ b/sys/dev/usb/ohcivar.h @@ -36,18 +36,16 @@ #include typedef struct ohci_soft_ed { - ohci_ed_t ed; + ohci_ed_t *ed; struct ohci_soft_ed *next; ohci_physaddr_t physaddr; usb_dma_t dma; int offs; } ohci_soft_ed_t; -#define OHCI_SED_SIZE (roundup(sizeof(struct ohci_soft_ed), OHCI_ED_ALIGN)) -#define OHCI_SED_CHUNK 128 typedef struct ohci_soft_td { - ohci_td_t td; + ohci_td_t *td; struct ohci_soft_td *nexttd; /* mirrors nexttd in TD */ struct ohci_soft_td *dnext; /* next in done list */ struct ohci_soft_td **held; /* where the ref to this std is held */ @@ -61,12 +59,12 @@ typedef struct ohci_soft_td { #define OHCI_CALL_DONE 0x0001 #define OHCI_ADD_LEN 0x0002 } ohci_soft_td_t; -#define OHCI_STD_SIZE (roundup(sizeof(struct ohci_soft_td), OHCI_TD_ALIGN)) -#define OHCI_STD_CHUNK 128 +// #define OHCI_STD_SIZE (roundup(sizeof(struct ohci_soft_td), OHCI_TD_ALIGN)) +// #define OHCI_STD_CHUNK 128 typedef struct ohci_soft_itd { - ohci_itd_t itd; + ohci_itd_t *itd; struct ohci_soft_itd *nextitd; /* mirrors nexttd in ITD */ struct ohci_soft_itd *dnext; /* next in done list */ struct ohci_soft_itd **held; /* where the ref to this sitd is held */ @@ -78,8 +76,8 @@ typedef struct ohci_soft_itd { uint16_t flags; bool isdone; /* used only when DIAGNOSTIC is defined */ } ohci_soft_itd_t; -#define OHCI_SITD_SIZE (roundup(sizeof(struct ohci_soft_itd), OHCI_ITD_ALIGN)) -#define OHCI_SITD_CHUNK 64 +// #define OHCI_SITD_SIZE (roundup(sizeof(struct ohci_soft_itd), OHCI_ITD_ALIGN)) +// #define OHCI_SITD_CHUNK 64 #define OHCI_NO_EDS (2*OHCI_NO_INTRS-1) diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index 8d9167b1df09..45324577e072 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -411,9 +411,9 @@ uhci_find_prev_qh(uhci_soft_qh_t *pqh, uhci_soft_qh_t *sqh) #if defined(DIAGNOSTIC) || defined(UHCI_DEBUG) usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(pqh->qh.qh_hlink), + sizeof(pqh->qh->qh_hlink), BUS_DMASYNC_POSTWRITE); - if (le32toh(pqh->qh.qh_hlink) & UHCI_PTR_T) { + if (le32toh(pqh->qh->qh_hlink) & UHCI_PTR_T) { printf("%s: QH not found\n", __func__); return NULL; } @@ -477,10 +477,10 @@ uhci_init(uhci_softc_t *sc) if (std == NULL) return ENOMEM; std->link.std = NULL; - std->td.td_link = htole32(UHCI_PTR_T); - std->td.td_status = htole32(0); /* inactive */ - std->td.td_token = htole32(0); - std->td.td_buffer = htole32(0); + std->td->td_link = htole32(UHCI_PTR_T); + std->td->td_status = htole32(0); /* inactive */ + std->td->td_token = htole32(0); + std->td->td_buffer = htole32(0); usb_syncmem(&std->dma, std->offs, sizeof(std->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); @@ -489,9 +489,9 @@ uhci_init(uhci_softc_t *sc) if (lsqh == NULL) goto fail1; lsqh->hlink = NULL; - lsqh->qh.qh_hlink = htole32(UHCI_PTR_T); /* end of QH chain */ + lsqh->qh->qh_hlink = htole32(UHCI_PTR_T); /* end of QH chain */ lsqh->elink = std; - lsqh->qh.qh_elink = htole32(std->physaddr | UHCI_PTR_TD); + lsqh->qh->qh_elink = htole32(std->physaddr | UHCI_PTR_TD); sc->sc_last_qh = lsqh; usb_syncmem(&lsqh->dma, lsqh->offs, sizeof(lsqh->qh), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); @@ -501,9 +501,9 @@ uhci_init(uhci_softc_t *sc) if (bsqh == NULL) goto fail2; bsqh->hlink = lsqh; - bsqh->qh.qh_hlink = htole32(lsqh->physaddr | UHCI_PTR_QH); + bsqh->qh->qh_hlink = htole32(lsqh->physaddr | UHCI_PTR_QH); bsqh->elink = NULL; - bsqh->qh.qh_elink = htole32(UHCI_PTR_T); + bsqh->qh->qh_elink = htole32(UHCI_PTR_T); sc->sc_bulk_start = sc->sc_bulk_end = bsqh; usb_syncmem(&bsqh->dma, bsqh->offs, sizeof(bsqh->qh), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); @@ -513,9 +513,9 @@ uhci_init(uhci_softc_t *sc) if (chsqh == NULL) goto fail3; chsqh->hlink = bsqh; - chsqh->qh.qh_hlink = htole32(bsqh->physaddr | UHCI_PTR_QH); + chsqh->qh->qh_hlink = htole32(bsqh->physaddr | UHCI_PTR_QH); chsqh->elink = NULL; - chsqh->qh.qh_elink = htole32(UHCI_PTR_T); + chsqh->qh->qh_elink = htole32(UHCI_PTR_T); sc->sc_hctl_start = sc->sc_hctl_end = chsqh; usb_syncmem(&chsqh->dma, chsqh->offs, sizeof(chsqh->qh), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); @@ -525,9 +525,9 @@ uhci_init(uhci_softc_t *sc) if (clsqh == NULL) goto fail4; clsqh->hlink = chsqh; - clsqh->qh.qh_hlink = htole32(chsqh->physaddr | UHCI_PTR_QH); + clsqh->qh->qh_hlink = htole32(chsqh->physaddr | UHCI_PTR_QH); clsqh->elink = NULL; - clsqh->qh.qh_elink = htole32(UHCI_PTR_T); + clsqh->qh->qh_elink = htole32(UHCI_PTR_T); sc->sc_lctl_start = sc->sc_lctl_end = clsqh; usb_syncmem(&clsqh->dma, clsqh->offs, sizeof(clsqh->qh), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); @@ -543,16 +543,16 @@ uhci_init(uhci_softc_t *sc) if (std == NULL || sqh == NULL) return USBD_NOMEM; std->link.sqh = sqh; - std->td.td_link = htole32(sqh->physaddr | UHCI_PTR_QH); - std->td.td_status = htole32(UHCI_TD_IOS); /* iso, inactive */ - std->td.td_token = htole32(0); - std->td.td_buffer = htole32(0); + std->td->td_link = htole32(sqh->physaddr | UHCI_PTR_QH); + std->td->td_status = htole32(UHCI_TD_IOS); /* iso, inactive */ + std->td->td_token = htole32(0); + std->td->td_buffer = htole32(0); usb_syncmem(&std->dma, std->offs, sizeof(std->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); sqh->hlink = clsqh; - sqh->qh.qh_hlink = htole32(clsqh->physaddr | UHCI_PTR_QH); + sqh->qh->qh_hlink = htole32(clsqh->physaddr | UHCI_PTR_QH); sqh->elink = NULL; - sqh->qh.qh_elink = htole32(UHCI_PTR_T); + sqh->qh->qh_elink = htole32(UHCI_PTR_T); usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); sc->sc_vframes[i].htd = std; @@ -815,34 +815,34 @@ uhci_dump_td(uhci_soft_td_t *p) DPRINTF("TD(%#jx) at 0x%08jx", (uintptr_t)p, p->physaddr, 0, 0); DPRINTF(" link=0x%08jx status=0x%08jx " "token=0x%08x buffer=0x%08x", - le32toh(p->td.td_link), - le32toh(p->td.td_status), - le32toh(p->td.td_token), - le32toh(p->td.td_buffer)); + le32toh(p->td->td_link), + le32toh(p->td->td_status), + le32toh(p->td->td_token), + le32toh(p->td->td_buffer)); DPRINTF("bitstuff=%jd crcto =%jd nak =%jd babble =%jd", - !!(le32toh(p->td.td_status) & UHCI_TD_BITSTUFF), - !!(le32toh(p->td.td_status) & UHCI_TD_CRCTO), - !!(le32toh(p->td.td_status) & UHCI_TD_NAK), - !!(le32toh(p->td.td_status) & UHCI_TD_BABBLE)); + !!(le32toh(p->td->td_status) & UHCI_TD_BITSTUFF), + !!(le32toh(p->td->td_status) & UHCI_TD_CRCTO), + !!(le32toh(p->td->td_status) & UHCI_TD_NAK), + !!(le32toh(p->td->td_status) & UHCI_TD_BABBLE)); DPRINTF("dbuffer =%jd stalled =%jd active =%jd ioc =%jd", - !!(le32toh(p->td.td_status) & UHCI_TD_DBUFFER), - !!(le32toh(p->td.td_status) & UHCI_TD_STALLED), - !!(le32toh(p->td.td_status) & UHCI_TD_ACTIVE), - !!(le32toh(p->td.td_status) & UHCI_TD_IOC)); + !!(le32toh(p->td->td_status) & UHCI_TD_DBUFFER), + !!(le32toh(p->td->td_status) & UHCI_TD_STALLED), + !!(le32toh(p->td->td_status) & UHCI_TD_ACTIVE), + !!(le32toh(p->td->td_status) & UHCI_TD_IOC)); DPRINTF("ios =%jd ls =%jd spd =%jd", - !!(le32toh(p->td.td_status) & UHCI_TD_IOS), - !!(le32toh(p->td.td_status) & UHCI_TD_LS), - !!(le32toh(p->td.td_status) & UHCI_TD_SPD), 0); + !!(le32toh(p->td->td_status) & UHCI_TD_IOS), + !!(le32toh(p->td->td_status) & UHCI_TD_LS), + !!(le32toh(p->td->td_status) & UHCI_TD_SPD), 0); DPRINTF("errcnt =%d actlen =%d pid=%02x", - UHCI_TD_GET_ERRCNT(le32toh(p->td.td_status)), - UHCI_TD_GET_ACTLEN(le32toh(p->td.td_status)), - UHCI_TD_GET_PID(le32toh(p->td.td_token)), 0); + UHCI_TD_GET_ERRCNT(le32toh(p->td->td_status)), + UHCI_TD_GET_ACTLEN(le32toh(p->td->td_status)), + UHCI_TD_GET_PID(le32toh(p->td->td_token)), 0); DPRINTF("addr=%jd endpt=%jd D=%jd maxlen=%jd,", - UHCI_TD_GET_DEVADDR(le32toh(p->td.td_token)), - UHCI_TD_GET_ENDPT(le32toh(p->td.td_token)), - UHCI_TD_GET_DT(le32toh(p->td.td_token)), - UHCI_TD_GET_MAXLEN(le32toh(p->td.td_token))); + UHCI_TD_GET_DEVADDR(le32toh(p->td->td_token)), + UHCI_TD_GET_ENDPT(le32toh(p->td->td_token)), + UHCI_TD_GET_DT(le32toh(p->td->td_token)), + UHCI_TD_GET_MAXLEN(le32toh(p->td->td_token))); } void @@ -854,8 +854,8 @@ uhci_dump_qh(uhci_soft_qh_t *sqh) BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); DPRINTF("QH(%#jx) at 0x%08jx: hlink=%08jx elink=%08jx", (uintptr_t)sqh, - (int)sqh->physaddr, le32toh(sqh->qh.qh_hlink), - le32toh(sqh->qh.qh_elink)); + (int)sqh->physaddr, le32toh(sqh->qh->qh_hlink), + le32toh(sqh->qh->qh_elink)); usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREREAD); } @@ -902,13 +902,13 @@ uhci_dump_qhs(uhci_soft_qh_t *sqh) usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - if (sqh->hlink != NULL && !(le32toh(sqh->qh.qh_hlink) & UHCI_PTR_T)) + if (sqh->hlink != NULL && !(le32toh(sqh->qh->qh_hlink) & UHCI_PTR_T)) uhci_dump_qhs(sqh->hlink); else DPRINTF("No QH", 0, 0, 0, 0); usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREREAD); - if (sqh->elink != NULL && !(le32toh(sqh->qh.qh_elink) & UHCI_PTR_T)) + if (sqh->elink != NULL && !(le32toh(sqh->qh->qh_elink) & UHCI_PTR_T)) uhci_dump_tds(sqh->elink); else DPRINTF("No QH", 0, 0, 0, 0); @@ -930,12 +930,12 @@ uhci_dump_tds(uhci_soft_td_t *std) * already been moved there (seatbelt). */ usb_syncmem(&td->dma, td->offs + offsetof(uhci_td_t, td_link), - sizeof(td->td.td_link), + sizeof(td->td->td_link), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - stop = (le32toh(td->td.td_link) & UHCI_PTR_T || - le32toh(td->td.td_link) == 0); + stop = (le32toh(td->td->td_link) & UHCI_PTR_T || + le32toh(td->td->td_link) == 0); usb_syncmem(&td->dma, td->offs + offsetof(uhci_td_t, td_link), - sizeof(td->td.td_link), BUS_DMASYNC_PREREAD); + sizeof(td->td->td_link), BUS_DMASYNC_PREREAD); if (stop) break; } @@ -1101,11 +1101,11 @@ uhci_add_loop(uhci_softc_t *sc) if (++sc->sc_loops == 1) { DPRINTFN(5, "add loop", 0, 0, 0, 0); /* Note, we don't loop back the soft pointer. */ - sc->sc_last_qh->qh.qh_hlink = + sc->sc_last_qh->qh->qh_hlink = htole32(sc->sc_hctl_start->physaddr | UHCI_PTR_QH); usb_syncmem(&sc->sc_last_qh->dma, sc->sc_last_qh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(sc->sc_last_qh->qh.qh_hlink), + sizeof(sc->sc_last_qh->qh->qh_hlink), BUS_DMASYNC_PREWRITE); } } @@ -1121,10 +1121,10 @@ uhci_rem_loop(uhci_softc_t *sc) #endif if (--sc->sc_loops == 0) { DPRINTFN(5, "remove loop", 0, 0, 0, 0); - sc->sc_last_qh->qh.qh_hlink = htole32(UHCI_PTR_T); + sc->sc_last_qh->qh->qh_hlink = htole32(UHCI_PTR_T); usb_syncmem(&sc->sc_last_qh->dma, sc->sc_last_qh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(sc->sc_last_qh->qh.qh_hlink), + sizeof(sc->sc_last_qh->qh->qh_hlink), BUS_DMASYNC_PREWRITE); } } @@ -1142,17 +1142,17 @@ uhci_add_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) DPRINTFN(10, "sqh %#jx", (uintptr_t)sqh, 0, 0, 0); eqh = sc->sc_hctl_end; usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(eqh->qh.qh_hlink), + sizeof(eqh->qh->qh_hlink), BUS_DMASYNC_POSTWRITE); sqh->hlink = eqh->hlink; - sqh->qh.qh_hlink = eqh->qh.qh_hlink; + sqh->qh->qh_hlink = eqh->qh->qh_hlink; usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREWRITE); eqh->hlink = sqh; - eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH); + eqh->qh->qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH); sc->sc_hctl_end = sqh; usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); + sizeof(eqh->qh->qh_hlink), BUS_DMASYNC_PREWRITE); #ifdef UHCI_CTL_LOOP uhci_add_loop(sc); #endif @@ -1186,27 +1186,27 @@ uhci_remove_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) * sqh->hlink. */ usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), - sizeof(sqh->qh.qh_elink), + sizeof(sqh->qh->qh_elink), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - elink = le32toh(sqh->qh.qh_elink); + elink = le32toh(sqh->qh->qh_elink); usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), - sizeof(sqh->qh.qh_elink), BUS_DMASYNC_PREREAD); + sizeof(sqh->qh->qh_elink), BUS_DMASYNC_PREREAD); if (!(elink & UHCI_PTR_T)) { - sqh->qh.qh_elink = htole32(UHCI_PTR_T); + sqh->qh->qh_elink = htole32(UHCI_PTR_T); usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), - sizeof(sqh->qh.qh_elink), + sizeof(sqh->qh->qh_elink), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); delay(UHCI_QH_REMOVE_DELAY); } pqh = uhci_find_prev_qh(sc->sc_hctl_start, sqh); usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); + sizeof(sqh->qh->qh_hlink), BUS_DMASYNC_POSTWRITE); pqh->hlink = sqh->hlink; - pqh->qh.qh_hlink = sqh->qh.qh_hlink; + pqh->qh->qh_hlink = sqh->qh->qh_hlink; usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(pqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); + sizeof(pqh->qh->qh_hlink), BUS_DMASYNC_PREWRITE); delay(UHCI_QH_REMOVE_DELAY); if (sc->sc_hctl_end == sqh) sc->sc_hctl_end = pqh; @@ -1225,15 +1225,15 @@ uhci_add_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) eqh = sc->sc_lctl_end; usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); + sizeof(eqh->qh->qh_hlink), BUS_DMASYNC_POSTWRITE); sqh->hlink = eqh->hlink; - sqh->qh.qh_hlink = eqh->qh.qh_hlink; + sqh->qh->qh_hlink = eqh->qh->qh_hlink; usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREWRITE); eqh->hlink = sqh; - eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH); + eqh->qh->qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH); usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); + sizeof(eqh->qh->qh_hlink), BUS_DMASYNC_PREWRITE); sc->sc_lctl_end = sqh; } @@ -1251,26 +1251,26 @@ uhci_remove_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) /* See comment in uhci_remove_hs_ctrl() */ usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), - sizeof(sqh->qh.qh_elink), + sizeof(sqh->qh->qh_elink), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - elink = le32toh(sqh->qh.qh_elink); + elink = le32toh(sqh->qh->qh_elink); usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), - sizeof(sqh->qh.qh_elink), BUS_DMASYNC_PREREAD); + sizeof(sqh->qh->qh_elink), BUS_DMASYNC_PREREAD); if (!(elink & UHCI_PTR_T)) { - sqh->qh.qh_elink = htole32(UHCI_PTR_T); + sqh->qh->qh_elink = htole32(UHCI_PTR_T); usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), - sizeof(sqh->qh.qh_elink), + sizeof(sqh->qh->qh_elink), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); delay(UHCI_QH_REMOVE_DELAY); } pqh = uhci_find_prev_qh(sc->sc_lctl_start, sqh); usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); + sizeof(sqh->qh->qh_hlink), BUS_DMASYNC_POSTWRITE); pqh->hlink = sqh->hlink; - pqh->qh.qh_hlink = sqh->qh.qh_hlink; + pqh->qh->qh_hlink = sqh->qh->qh_hlink; usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(pqh->qh.qh_hlink), + sizeof(pqh->qh->qh_hlink), BUS_DMASYNC_PREWRITE); delay(UHCI_QH_REMOVE_DELAY); if (sc->sc_lctl_end == sqh) @@ -1290,15 +1290,15 @@ uhci_add_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh) eqh = sc->sc_bulk_end; usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); + sizeof(eqh->qh->qh_hlink), BUS_DMASYNC_POSTWRITE); sqh->hlink = eqh->hlink; - sqh->qh.qh_hlink = eqh->qh.qh_hlink; + sqh->qh->qh_hlink = eqh->qh->qh_hlink; usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREWRITE); eqh->hlink = sqh; - eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH); + eqh->qh->qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH); usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); + sizeof(eqh->qh->qh_hlink), BUS_DMASYNC_PREWRITE); sc->sc_bulk_end = sqh; uhci_add_loop(sc); } @@ -1317,23 +1317,23 @@ uhci_remove_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh) uhci_rem_loop(sc); /* See comment in uhci_remove_hs_ctrl() */ usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), - sizeof(sqh->qh.qh_elink), + sizeof(sqh->qh->qh_elink), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) { - sqh->qh.qh_elink = htole32(UHCI_PTR_T); + if (!(sqh->qh->qh_elink & htole32(UHCI_PTR_T))) { + sqh->qh->qh_elink = htole32(UHCI_PTR_T); usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), - sizeof(sqh->qh.qh_elink), + sizeof(sqh->qh->qh_elink), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); delay(UHCI_QH_REMOVE_DELAY); } pqh = uhci_find_prev_qh(sc->sc_bulk_start, sqh); usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); + sizeof(sqh->qh->qh_hlink), BUS_DMASYNC_POSTWRITE); pqh->hlink = sqh->hlink; - pqh->qh.qh_hlink = sqh->qh.qh_hlink; + pqh->qh->qh_hlink = sqh->qh->qh_hlink; usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(pqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); + sizeof(pqh->qh->qh_hlink), BUS_DMASYNC_PREWRITE); delay(UHCI_QH_REMOVE_DELAY); if (sc->sc_bulk_end == sqh) sc->sc_bulk_end = pqh; @@ -1525,12 +1525,12 @@ uhci_check_intr(uhci_softc_t *sc, struct uhci_xfer *ux, ux_completeq_t *cqp) usb_syncmem(&lstd->dma, lstd->offs + offsetof(uhci_td_t, td_status), - sizeof(lstd->td.td_status), + sizeof(lstd->td->td_status), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - status = le32toh(lstd->td.td_status); + status = le32toh(lstd->td->td_status); usb_syncmem(&lstd->dma, lstd->offs + offsetof(uhci_td_t, td_status), - sizeof(lstd->td.td_status), + sizeof(lstd->td->td_status), BUS_DMASYNC_PREREAD); /* If the last TD is not marked active we can complete */ @@ -1550,12 +1550,12 @@ uhci_check_intr(uhci_softc_t *sc, struct uhci_xfer *ux, ux_completeq_t *cqp) for (std = fstd; std != lstd; std = std->link.std) { usb_syncmem(&std->dma, std->offs + offsetof(uhci_td_t, td_status), - sizeof(std->td.td_status), + sizeof(std->td->td_status), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - status = le32toh(std->td.td_status); + status = le32toh(std->td->td_status); usb_syncmem(&std->dma, std->offs + offsetof(uhci_td_t, td_status), - sizeof(std->td.td_status), BUS_DMASYNC_PREREAD); + sizeof(std->td->td_status), BUS_DMASYNC_PREREAD); /* If there's an active TD the xfer isn't done. */ if (status & UHCI_TD_ACTIVE) { @@ -1583,7 +1583,7 @@ uhci_check_intr(uhci_softc_t *sc, struct uhci_xfer *ux, ux_completeq_t *cqp) "phase needs completion", (uintptr_t)ux, (uintptr_t)ux->ux_stdstart, 0, 0); - sqh->qh.qh_elink = + sqh->qh->qh_elink = htole32(stat->physaddr | UHCI_PTR_TD); usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREWRITE); @@ -1593,12 +1593,12 @@ uhci_check_intr(uhci_softc_t *sc, struct uhci_xfer *ux, ux_completeq_t *cqp) /* We want short packets, and it is short: it's done */ usb_syncmem(&std->dma, std->offs + offsetof(uhci_td_t, td_token), - sizeof(std->td.td_token), + sizeof(std->td->td_token), BUS_DMASYNC_POSTWRITE); if ((status & UHCI_TD_SPD) && UHCI_TD_GET_ACTLEN(status) < - UHCI_TD_GET_MAXLEN(le32toh(std->td.td_token))) { + UHCI_TD_GET_MAXLEN(le32toh(std->td->td_token))) { goto done; } } @@ -1665,9 +1665,9 @@ uhci_idone(struct uhci_xfer *ux, ux_completeq_t *cqp) n = 0; usb_syncmem(&std->dma, std->offs + offsetof(uhci_td_t, td_status), - sizeof(std->td.td_status), + sizeof(std->td->td_status), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - status = le32toh(std->td.td_status); + status = le32toh(std->td->td_status); len = UHCI_TD_GET_ACTLEN(status); xfer->ux_frlengths[i] = len; actlen += len; @@ -1693,12 +1693,12 @@ uhci_idone(struct uhci_xfer *ux, ux_completeq_t *cqp) for (std = ux->ux_stdstart; std != NULL; std = std->link.std) { usb_syncmem(&std->dma, std->offs, sizeof(std->td), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - nstatus = le32toh(std->td.td_status); + nstatus = le32toh(std->td->td_status); if (nstatus & UHCI_TD_ACTIVE) break; status = nstatus; - if (UHCI_TD_GET_PID(le32toh(std->td.td_token)) != + if (UHCI_TD_GET_PID(le32toh(std->td->td_token)) != UHCI_TD_PID_SETUP) actlen += UHCI_TD_GET_ACTLEN(status); else { @@ -1713,7 +1713,7 @@ uhci_idone(struct uhci_xfer *ux, ux_completeq_t *cqp) } /* If there are left over TDs we need to update the toggle. */ if (std != NULL) - upipe->nexttoggle = UHCI_TD_GET_DT(le32toh(std->td.td_token)); + upipe->nexttoggle = UHCI_TD_GET_DT(le32toh(std->td->td_token)); status &= UHCI_TD_ERROR; DPRINTFN(10, "actlen=%jd, status=%#jx", actlen, status, 0, 0); @@ -1844,19 +1844,25 @@ uhci_alloc_std(uhci_softc_t *sc) DPRINTFN(2, "allocating chunk", 0, 0, 0, 0); mutex_exit(&sc->sc_lock); - int err = usb_allocmem(&sc->sc_bus, UHCI_STD_SIZE * UHCI_STD_CHUNK, + int err = usb_allocmem(&sc->sc_bus, UHCI_TD_SIZE * UHCI_TD_CHUNK, UHCI_TD_ALIGN, USBMALLOC_COHERENT, &dma); if (err) return NULL; + uhci_soft_td_t *stds = + kmem_alloc(sizeof(*std) * UHCI_TD_CHUNK, KM_SLEEP); + mutex_enter(&sc->sc_lock); - for (i = 0; i < UHCI_STD_CHUNK; i++) { - offs = i * UHCI_STD_SIZE; - std = KERNADDR(&dma, offs); + for (i = 0; i < UHCI_TD_CHUNK; i++) { + std = &stds[i]; + offs = i * UHCI_TD_SIZE; + + std->td = KERNADDR(&dma, offs); std->physaddr = DMAADDR(&dma, offs); std->dma = dma; std->offs = offs; std->link.std = sc->sc_freetds; + sc->sc_freetds = std; } } @@ -1864,7 +1870,7 @@ uhci_alloc_std(uhci_softc_t *sc) sc->sc_freetds = std->link.std; mutex_exit(&sc->sc_lock); - memset(&std->td, 0, sizeof(uhci_td_t)); + memset(std->td, 0, sizeof(*std->td)); return std; } @@ -1877,11 +1883,11 @@ uhci_free_std_locked(uhci_softc_t *sc, uhci_soft_td_t *std) KASSERT(mutex_owned(&sc->sc_lock)); #ifdef DIAGNOSTIC - if (le32toh(std->td.td_token) == TD_IS_FREE) { + if (le32toh(std->td->td_token) == TD_IS_FREE) { printf("%s: freeing free TD %p\n", __func__, std); return; } - std->td.td_token = htole32(TD_IS_FREE); + std->td->td_token = htole32(TD_IS_FREE); #endif std->link.std = sc->sc_freetds; @@ -1910,19 +1916,25 @@ uhci_alloc_sqh(uhci_softc_t *sc) DPRINTFN(2, "allocating chunk", 0, 0, 0, 0); mutex_exit(&sc->sc_lock); - int err = usb_allocmem(&sc->sc_bus, UHCI_SQH_SIZE * UHCI_SQH_CHUNK, + int err = usb_allocmem(&sc->sc_bus, UHCI_QH_SIZE * UHCI_QH_CHUNK, UHCI_QH_ALIGN, USBMALLOC_COHERENT, &dma); if (err) return NULL; + uhci_soft_qh_t *sqhs = + kmem_alloc(sizeof(*sqh) * UHCI_QH_CHUNK, KM_SLEEP); + mutex_enter(&sc->sc_lock); - for (i = 0; i < UHCI_SQH_CHUNK; i++) { - offs = i * UHCI_SQH_SIZE; - sqh = KERNADDR(&dma, offs); + for (i = 0; i < UHCI_QH_CHUNK; i++) { + sqh = &sqhs[i]; + offs = i * UHCI_QH_SIZE; + + sqh->qh = KERNADDR(&dma, offs); sqh->physaddr = DMAADDR(&dma, offs); sqh->dma = dma; sqh->offs = offs; sqh->hlink = sc->sc_freeqhs; + sc->sc_freeqhs = sqh; } } @@ -1930,7 +1942,7 @@ uhci_alloc_sqh(uhci_softc_t *sc) sc->sc_freeqhs = sqh->hlink; mutex_exit(&sc->sc_lock); - memset(&sqh->qh, 0, sizeof(uhci_qh_t)); + memset(sqh->qh, 0, sizeof(*sqh->qh)); return sqh; } @@ -1960,18 +1972,18 @@ uhci_free_std_chain(uhci_softc_t *sc, uhci_soft_td_t *std, for (p = std; p != stdend; p = p->link.std) { usb_syncmem(&p->dma, p->offs + offsetof(uhci_td_t, td_link), - sizeof(p->td.td_link), + sizeof(p->td->td_link), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - td_link = le32toh(p->td.td_link); + td_link = le32toh(p->td->td_link); usb_syncmem(&p->dma, p->offs + offsetof(uhci_td_t, td_link), - sizeof(p->td.td_link), + sizeof(p->td->td_link), BUS_DMASYNC_PREREAD); if ((td_link & UHCI_PTR_T) == 0) { - p->td.td_link = htole32(UHCI_PTR_T); + p->td->td_link = htole32(UHCI_PTR_T); usb_syncmem(&p->dma, p->offs + offsetof(uhci_td_t, td_link), - sizeof(p->td.td_link), + sizeof(p->td->td_link), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } } @@ -2062,11 +2074,11 @@ uhci_free_stds(uhci_softc_t *sc, struct uhci_xfer *ux) for (size_t i = 0; i < ux->ux_nstd; i++) { uhci_soft_td_t *std = ux->ux_stds[i]; #ifdef DIAGNOSTIC - if (le32toh(std->td.td_token) == TD_IS_FREE) { + if (le32toh(std->td->td_token) == TD_IS_FREE) { printf("%s: freeing free TD %p\n", __func__, std); return; } - std->td.td_token = htole32(TD_IS_FREE); + std->td->td_token = htole32(TD_IS_FREE); #endif ux->ux_stds[i]->link.std = sc->sc_freetds; sc->sc_freetds = std; @@ -2124,7 +2136,7 @@ uhci_reset_std_chain(uhci_softc_t *sc, struct usbd_xfer *xfer, if (prev) { prev->link.std = std; - prev->td.td_link = htole32( + prev->td->td_link = htole32( std->physaddr | UHCI_PTR_VF | UHCI_PTR_TD ); usb_syncmem(&prev->dma, prev->offs, sizeof(prev->td), @@ -2134,16 +2146,16 @@ uhci_reset_std_chain(uhci_softc_t *sc, struct usbd_xfer *xfer, usb_syncmem(&std->dma, std->offs, sizeof(std->td), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - std->td.td_link = htole32(UHCI_PTR_T | UHCI_PTR_VF | UHCI_PTR_TD); - std->td.td_status = htole32(status); - std->td.td_token = htole32( + std->td->td_link = htole32(UHCI_PTR_T | UHCI_PTR_VF | UHCI_PTR_TD); + std->td->td_status = htole32(status); + std->td->td_token = htole32( UHCI_TD_SET_ENDPT(UE_GET_ADDR(endpt)) | UHCI_TD_SET_DEVADDR(addr) | UHCI_TD_SET_PID(isread ? UHCI_TD_PID_IN : UHCI_TD_PID_OUT) | UHCI_TD_SET_DT(tog) | UHCI_TD_SET_MAXLEN(l) ); - std->td.td_buffer = htole32(DMAADDR(dma, offs)); + std->td->td_buffer = htole32(DMAADDR(dma, offs)); std->link.std = NULL; @@ -2165,23 +2177,23 @@ uhci_reset_std_chain(uhci_softc_t *sc, struct usbd_xfer *xfer, uxfer->ux_nstd); std = uxfer->ux_stds[i++]; - std->td.td_link = htole32(UHCI_PTR_T | UHCI_PTR_VF | UHCI_PTR_TD); - std->td.td_status = htole32(status); - std->td.td_token = htole32( + std->td->td_link = htole32(UHCI_PTR_T | UHCI_PTR_VF | UHCI_PTR_TD); + std->td->td_status = htole32(status); + std->td->td_token = htole32( UHCI_TD_SET_ENDPT(UE_GET_ADDR(endpt)) | UHCI_TD_SET_DEVADDR(addr) | UHCI_TD_SET_PID(UHCI_TD_PID_OUT) | UHCI_TD_SET_DT(tog) | UHCI_TD_SET_MAXLEN(0) ); - std->td.td_buffer = 0; + std->td->td_buffer = 0; usb_syncmem(&std->dma, std->offs, sizeof(std->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); std->link.std = NULL; if (prev) { prev->link.std = std; - prev->td.td_link = htole32( + prev->td->td_link = htole32( std->physaddr | UHCI_PTR_VF | UHCI_PTR_TD ); usb_syncmem(&prev->dma, prev->offs, sizeof(prev->td), @@ -2312,10 +2324,10 @@ uhci_device_bulk_start(struct usbd_xfer *xfer) data = ux->ux_stdstart; ux->ux_stdend = dataend; - dataend->td.td_status |= htole32(UHCI_TD_IOC); + dataend->td->td_status |= htole32(UHCI_TD_IOC); usb_syncmem(&dataend->dma, dataend->offs + offsetof(uhci_td_t, td_status), - sizeof(dataend->td.td_status), + sizeof(dataend->td->td_status), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); #ifdef UHCI_DEBUG @@ -2333,7 +2345,7 @@ uhci_device_bulk_start(struct usbd_xfer *xfer) #endif sqh->elink = data; - sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD); + sqh->qh->qh_elink = htole32(data->physaddr | UHCI_PTR_TD); /* uhci_add_bulk() will do usb_syncmem(sqh) */ uhci_add_bulk(sc, sqh); @@ -2399,12 +2411,12 @@ uhci_abortx(struct usbd_xfer *xfer) for (std = ux->ux_stdstart; std != NULL; std = std->link.std) { usb_syncmem(&std->dma, std->offs + offsetof(uhci_td_t, td_status), - sizeof(std->td.td_status), + sizeof(std->td->td_status), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC)); + std->td->td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC)); usb_syncmem(&std->dma, std->offs + offsetof(uhci_td_t, td_status), - sizeof(std->td.td_status), + sizeof(std->td->td_status), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } @@ -2562,10 +2574,10 @@ uhci_device_ctrl_start(struct usbd_xfer *xfer) uhci_reset_std_chain(sc, xfer, len, isread, &upipe->nexttoggle, &dataend); dataend->link.std = stat; - dataend->td.td_link = htole32(stat->physaddr | UHCI_PTR_TD); + dataend->td->td_link = htole32(stat->physaddr | UHCI_PTR_TD); usb_syncmem(&dataend->dma, dataend->offs + offsetof(uhci_td_t, td_link), - sizeof(dataend->td.td_link), + sizeof(dataend->td->td_link), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } else { next = stat; @@ -2577,21 +2589,21 @@ uhci_device_ctrl_start(struct usbd_xfer *xfer) (dev->ud_speed == USB_SPEED_LOW ? UHCI_TD_LS : 0) ); setup->link.std = next; - setup->td.td_link = htole32(next->physaddr | UHCI_PTR_TD); - setup->td.td_status = htole32(status); - setup->td.td_token = htole32(UHCI_TD_SETUP(sizeof(*req), endpt, addr)); - setup->td.td_buffer = htole32(DMAADDR(&upipe->ctrl.reqdma, 0)); + setup->td->td_link = htole32(next->physaddr | UHCI_PTR_TD); + setup->td->td_status = htole32(status); + setup->td->td_token = htole32(UHCI_TD_SETUP(sizeof(*req), endpt, addr)); + setup->td->td_buffer = htole32(DMAADDR(&upipe->ctrl.reqdma, 0)); usb_syncmem(&setup->dma, setup->offs, sizeof(setup->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); stat->link.std = NULL; - stat->td.td_link = htole32(UHCI_PTR_T); - stat->td.td_status = htole32(status | UHCI_TD_IOC); - stat->td.td_token = + stat->td->td_link = htole32(UHCI_PTR_T); + stat->td->td_status = htole32(status | UHCI_TD_IOC); + stat->td->td_token = htole32(isread ? UHCI_TD_OUT(0, endpt, addr, 1) : UHCI_TD_IN (0, endpt, addr, 1)); - stat->td.td_buffer = htole32(0); + stat->td->td_buffer = htole32(0); usb_syncmem(&stat->dma, stat->offs, sizeof(stat->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); @@ -2613,7 +2625,7 @@ uhci_device_ctrl_start(struct usbd_xfer *xfer) #endif sqh->elink = setup; - sqh->qh.qh_elink = htole32(setup->physaddr | UHCI_PTR_TD); + sqh->qh->qh_elink = htole32(setup->physaddr | UHCI_PTR_TD); /* uhci_add_?s_ctrl() will do usb_syncmem(sqh) */ if (dev->ud_speed == USB_SPEED_LOW) @@ -2633,7 +2645,7 @@ uhci_device_ctrl_start(struct usbd_xfer *xfer) for (std = sc->sc_vframes[0].htd, link = 0; (link & UHCI_PTR_QH) == 0; std = std->link.std) { - link = le32toh(std->td.td_link); + link = le32toh(std->td->td_link); uhci_dump_td(std); } sxqh = (uhci_soft_qh_t *)std; @@ -2757,10 +2769,10 @@ uhci_device_intr_start(struct usbd_xfer *xfer) uhci_reset_std_chain(sc, xfer, xfer->ux_length, isread, &upipe->nexttoggle, &dataend); - dataend->td.td_status |= htole32(UHCI_TD_IOC); + dataend->td->td_status |= htole32(UHCI_TD_IOC); usb_syncmem(&dataend->dma, dataend->offs + offsetof(uhci_td_t, td_status), - sizeof(dataend->td.td_status), + sizeof(dataend->td->td_status), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); ux->ux_stdend = dataend; @@ -2777,10 +2789,10 @@ uhci_device_intr_start(struct usbd_xfer *xfer) for (i = 0; i < upipe->intr.npoll; i++) { sqh = upipe->intr.qhs[i]; sqh->elink = data; - sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD); + sqh->qh->qh_elink = htole32(data->physaddr | UHCI_PTR_TD); usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), - sizeof(sqh->qh.qh_elink), + sizeof(sqh->qh->qh_elink), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } uhci_add_intr_list(sc, ux); @@ -2961,14 +2973,14 @@ uhci_device_isoc_transfer(struct usbd_xfer *xfer) KASSERTMSG(len <= __SHIFTOUT_MASK(UHCI_TD_MAXLEN_MASK), "len %d", len); - std->td.td_buffer = htole32(buf); + std->td->td_buffer = htole32(buf); usb_syncmem(&xfer->ux_dmabuf, offs, len, rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); if (i == nframes - 1) status |= UHCI_TD_IOC; - std->td.td_status = htole32(status); - std->td.td_token &= htole32(~UHCI_TD_MAXLEN_MASK); - std->td.td_token |= htole32(UHCI_TD_SET_MAXLEN(len)); + std->td->td_status = htole32(status); + std->td->td_token &= htole32(~UHCI_TD_MAXLEN_MASK); + std->td->td_token |= htole32(UHCI_TD_SET_MAXLEN(len)); usb_syncmem(&std->dma, std->offs, sizeof(std->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); #ifdef UHCI_DEBUG @@ -3032,18 +3044,18 @@ uhci_device_isoc_abort(struct usbd_xfer *xfer) std = stds[n]; usb_syncmem(&std->dma, std->offs + offsetof(uhci_td_t, td_status), - sizeof(std->td.td_status), + sizeof(std->td->td_status), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC)); + std->td->td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC)); usb_syncmem(&std->dma, std->offs + offsetof(uhci_td_t, td_status), - sizeof(std->td.td_status), + sizeof(std->td->td_status), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); usb_syncmem(&std->dma, std->offs + offsetof(uhci_td_t, td_token), - sizeof(std->td.td_token), + sizeof(std->td->td_token), BUS_DMASYNC_POSTWRITE); - len = UHCI_TD_GET_MAXLEN(le32toh(std->td.td_token)); + len = UHCI_TD_GET_MAXLEN(le32toh(std->td->td_token)); if (len > maxlen) maxlen = len; if (++n >= UHCI_VFRAMELIST_COUNT) @@ -3088,12 +3100,12 @@ uhci_device_isoc_close(struct usbd_pipe *pipe) std = isoc->stds[i]; usb_syncmem(&std->dma, std->offs + offsetof(uhci_td_t, td_status), - sizeof(std->td.td_status), + sizeof(std->td->td_status), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - std->td.td_status &= htole32(~UHCI_TD_ACTIVE); + std->td->td_status &= htole32(~UHCI_TD_ACTIVE); usb_syncmem(&std->dma, std->offs + offsetof(uhci_td_t, td_status), - sizeof(std->td.td_status), + sizeof(std->td->td_status), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } /* wait for completion */ @@ -3114,12 +3126,12 @@ uhci_device_isoc_close(struct usbd_pipe *pipe) vstd->link = std->link; usb_syncmem(&std->dma, std->offs + offsetof(uhci_td_t, td_link), - sizeof(std->td.td_link), + sizeof(std->td->td_link), BUS_DMASYNC_POSTWRITE); - vstd->td.td_link = std->td.td_link; + vstd->td->td_link = std->td->td_link; usb_syncmem(&vstd->dma, vstd->offs + offsetof(uhci_td_t, td_link), - sizeof(vstd->td.td_link), + sizeof(vstd->td->td_link), BUS_DMASYNC_PREWRITE); uhci_free_std_locked(sc, std); } @@ -3155,8 +3167,8 @@ uhci_setup_isoc(struct usbd_pipe *pipe) std = uhci_alloc_std(sc); if (std == 0) goto bad; - std->td.td_status = htole32(UHCI_TD_IOS); /* iso, inactive */ - std->td.td_token = htole32(token); + std->td->td_status = htole32(UHCI_TD_IOS); /* iso, inactive */ + std->td->td_token = htole32(token); usb_syncmem(&std->dma, std->offs, sizeof(std->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); isoc->stds[i] = std; @@ -3170,19 +3182,19 @@ uhci_setup_isoc(struct usbd_pipe *pipe) vstd = sc->sc_vframes[i].htd; usb_syncmem(&vstd->dma, vstd->offs + offsetof(uhci_td_t, td_link), - sizeof(vstd->td.td_link), + sizeof(vstd->td->td_link), BUS_DMASYNC_POSTWRITE); std->link = vstd->link; - std->td.td_link = vstd->td.td_link; + std->td->td_link = vstd->td->td_link; usb_syncmem(&std->dma, std->offs + offsetof(uhci_td_t, td_link), - sizeof(std->td.td_link), + sizeof(std->td->td_link), BUS_DMASYNC_PREWRITE); vstd->link.std = std; - vstd->td.td_link = htole32(std->physaddr | UHCI_PTR_TD); + vstd->td->td_link = htole32(std->physaddr | UHCI_PTR_TD); usb_syncmem(&vstd->dma, vstd->offs + offsetof(uhci_td_t, td_link), - sizeof(vstd->td.td_link), + sizeof(vstd->td->td_link), BUS_DMASYNC_PREWRITE); } mutex_exit(&sc->sc_lock); @@ -3229,12 +3241,12 @@ uhci_device_isoc_done(struct usbd_xfer *xfer) /* Turn off the interrupt since it is active even if the TD is not. */ usb_syncmem(&ux->ux_stdend->dma, ux->ux_stdend->offs + offsetof(uhci_td_t, td_status), - sizeof(ux->ux_stdend->td.td_status), + sizeof(ux->ux_stdend->td->td_status), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - ux->ux_stdend->td.td_status &= htole32(~UHCI_TD_IOC); + ux->ux_stdend->td->td_status &= htole32(~UHCI_TD_IOC); usb_syncmem(&ux->ux_stdend->dma, ux->ux_stdend->offs + offsetof(uhci_td_t, td_status), - sizeof(ux->ux_stdend->td.td_status), + sizeof(ux->ux_stdend->td->td_status), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); offs = 0; @@ -3262,10 +3274,10 @@ uhci_device_intr_done(struct usbd_xfer *xfer) for (i = 0; i < npoll; i++) { sqh = upipe->intr.qhs[i]; sqh->elink = NULL; - sqh->qh.qh_elink = htole32(UHCI_PTR_T); + sqh->qh->qh_elink = htole32(UHCI_PTR_T); usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), - sizeof(sqh->qh.qh_elink), + sizeof(sqh->qh->qh_elink), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } const int endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; @@ -3342,15 +3354,15 @@ uhci_add_intr(uhci_softc_t *sc, uhci_soft_qh_t *sqh) eqh = vf->eqh; usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); + sizeof(eqh->qh->qh_hlink), BUS_DMASYNC_POSTWRITE); sqh->hlink = eqh->hlink; - sqh->qh.qh_hlink = eqh->qh.qh_hlink; + sqh->qh->qh_hlink = eqh->qh->qh_hlink; usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); + sizeof(sqh->qh->qh_hlink), BUS_DMASYNC_PREWRITE); eqh->hlink = sqh; - eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH); + eqh->qh->qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH); usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); + sizeof(eqh->qh->qh_hlink), BUS_DMASYNC_PREWRITE); vf->eqh = sqh; vf->bandwidth++; } @@ -3368,25 +3380,25 @@ uhci_remove_intr(uhci_softc_t *sc, uhci_soft_qh_t *sqh) /* See comment in uhci_remove_ctrl() */ usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), - sizeof(sqh->qh.qh_elink), + sizeof(sqh->qh->qh_elink), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) { - sqh->qh.qh_elink = htole32(UHCI_PTR_T); + if (!(sqh->qh->qh_elink & htole32(UHCI_PTR_T))) { + sqh->qh->qh_elink = htole32(UHCI_PTR_T); usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), - sizeof(sqh->qh.qh_elink), + sizeof(sqh->qh->qh_elink), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); delay(UHCI_QH_REMOVE_DELAY); } pqh = uhci_find_prev_qh(vf->hqh, sqh); usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(sqh->qh.qh_hlink), + sizeof(sqh->qh->qh_hlink), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); pqh->hlink = sqh->hlink; - pqh->qh.qh_hlink = sqh->qh.qh_hlink; + pqh->qh->qh_hlink = sqh->qh->qh_hlink; usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink), - sizeof(pqh->qh.qh_hlink), + sizeof(pqh->qh->qh_hlink), BUS_DMASYNC_PREWRITE); delay(UHCI_QH_REMOVE_DELAY); if (vf->eqh == sqh) @@ -3434,10 +3446,10 @@ uhci_device_setintr(uhci_softc_t *sc, struct uhci_pipe *upipe, int ival) for (i = 0; i < npoll; i++) { upipe->intr.qhs[i] = sqh = uhci_alloc_sqh(sc); sqh->elink = NULL; - sqh->qh.qh_elink = htole32(UHCI_PTR_T); + sqh->qh->qh_elink = htole32(UHCI_PTR_T); usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), - sizeof(sqh->qh.qh_elink), + sizeof(sqh->qh->qh_elink), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); sqh->pos = MOD(i * ival + bestoffs); } diff --git a/sys/dev/usb/uhcireg.h b/sys/dev/usb/uhcireg.h index 59b0953dfe38..3b3bd94bc0ae 100644 --- a/sys/dev/usb/uhcireg.h +++ b/sys/dev/usb/uhcireg.h @@ -116,9 +116,6 @@ #define UHCI_FRAMELIST_COUNT 1024 #define UHCI_FRAMELIST_ALIGN 4096 -#define UHCI_TD_ALIGN 16 -#define UHCI_QH_ALIGN 16 - typedef uint32_t uhci_physaddr_t; #define UHCI_PTR_T __BIT(0) #define UHCI_PTR_TD 0x00000000 @@ -188,6 +185,10 @@ typedef struct { (__SHIFTOUT((s), UHCI_TD_MAXLEN_MASK) + 1) volatile uint32_t td_buffer; } uhci_td_t; +#define UHCI_TD_ALIGN 16 +#define UHCI_TD_ALLOC_ALIGN MAX(UHCI_TD_ALIGN, CACHE_LINE_SIZE) +#define UHCI_TD_SIZE (roundup(sizeof(uhci_td_t), UHCI_TD_ALLOC_ALIGN)) +#define UHCI_TD_CHUNK (PAGE_SIZE / UHCI_TD_SIZE) #define UHCI_TD_ERROR \ (UHCI_TD_BITSTUFF|UHCI_TD_CRCTO|UHCI_TD_BABBLE|UHCI_TD_DBUFFER|UHCI_TD_STALLED) @@ -206,5 +207,9 @@ typedef struct { volatile uhci_physaddr_t qh_hlink; volatile uhci_physaddr_t qh_elink; } uhci_qh_t; +#define UHCI_QH_ALIGN 16 +#define UHCI_QH_ALLOC_ALIGN MAX(UHCI_QH_ALIGN, CACHE_LINE_SIZE) +#define UHCI_QH_SIZE (roundup(sizeof(uhci_qh_t), UHCI_TD_ALLOC_ALIGN)) +#define UHCI_QH_CHUNK (PAGE_SIZE / UHCI_QH_SIZE) #endif /* _DEV_USB_UHCIREG_H_ */ diff --git a/sys/dev/usb/uhcivar.h b/sys/dev/usb/uhcivar.h index 0277ab90ea74..ba00b71d8d3b 100644 --- a/sys/dev/usb/uhcivar.h +++ b/sys/dev/usb/uhcivar.h @@ -100,26 +100,18 @@ struct uhci_xfer { * Extra information that we need for a TD. */ struct uhci_soft_td { - uhci_td_t td; /* The real TD, must be first */ + uhci_td_t *td; /* The real TD */ uhci_soft_td_qh_t link; /* soft version of the td_link field */ uhci_physaddr_t physaddr; /* TD's physical address. */ usb_dma_t dma; /* TD's DMA infos */ int offs; /* TD's offset in usb_dma_t */ }; -/* - * Make the size such that it is a multiple of UHCI_TD_ALIGN. This way - * we can pack a number of soft TD together and have the real TD well - * aligned. - * NOTE: Minimum size is 32 bytes. - */ -#define UHCI_STD_SIZE (roundup(sizeof(struct uhci_soft_td), UHCI_TD_ALIGN)) -#define UHCI_STD_CHUNK 128 /*(PAGE_SIZE / UHCI_TD_SIZE)*/ /* * Extra information that we need for a QH. */ struct uhci_soft_qh { - uhci_qh_t qh; /* The real QH, must be first */ + uhci_qh_t *qh; /* The real QH */ uhci_soft_qh_t *hlink; /* soft version of qh_hlink */ uhci_soft_td_t *elink; /* soft version of qh_elink */ uhci_physaddr_t physaddr; /* QH's physical address. */ @@ -127,9 +119,6 @@ struct uhci_soft_qh { usb_dma_t dma; /* QH's DMA infos */ int offs; /* QH's offset in usb_dma_t */ }; -/* See comment about UHCI_STD_SIZE. */ -#define UHCI_SQH_SIZE (roundup(sizeof(struct uhci_soft_qh), UHCI_QH_ALIGN)) -#define UHCI_SQH_CHUNK 128 /*(PAGE_SIZE / UHCI_QH_SIZE)*/ /* * Information about an entry in the virtual frame list.