Module Name: src
Committed By: skrll
Date: Mon Sep 23 10:07:27 UTC 2024
Modified Files:
src/sys/dev/usb: ehci.c ehcireg.h ehcivar.h
Log Message:
Allocate a whole cacheline for all the descriptor types used by ehci so
that
i) they can be alloc'ed without USBMALLOC_COHERENT which can mean they're
now mapped cacheable, and
ii) the "soft" versions are cacheable, and mapped as small as possible.
A quick test of
dd if=/dev/rsd0 of=/dev/null bs=1m count=1024
improved by approximagely 10% on a Banana PI.
To generate a diff of this commit:
cvs rdiff -u -r1.325 -r1.326 src/sys/dev/usb/ehci.c
cvs rdiff -u -r1.40 -r1.41 src/sys/dev/usb/ehcireg.h
cvs rdiff -u -r1.52 -r1.53 src/sys/dev/usb/ehcivar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/usb/ehci.c
diff -u src/sys/dev/usb/ehci.c:1.325 src/sys/dev/usb/ehci.c:1.326
--- src/sys/dev/usb/ehci.c:1.325 Fri Apr 5 18:57:10 2024
+++ src/sys/dev/usb/ehci.c Mon Sep 23 10:07:26 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: ehci.c,v 1.325 2024/04/05 18:57:10 riastradh Exp $ */
+/* $NetBSD: ehci.c,v 1.326 2024/09/23 10:07:26 skrll Exp $ */
/*
* Copyright (c) 2004-2012,2016,2020 The NetBSD Foundation, Inc.
@@ -54,7 +54,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.325 2024/04/05 18:57:10 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.326 2024/09/23 10:07:26 skrll Exp $");
#include "ohci.h"
#include "uhci.h"
@@ -600,22 +600,23 @@ 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),
+ usb_syncmem(&sqh->dma, sqh->offs, sizeof(*sqh->qh),
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
}
/* Point the frame list at the last level (128ms). */
@@ -638,18 +639,18 @@ ehci_init(ehci_softc_t *sc)
goto fail3;
}
/* 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),
+ usb_syncmem(&sqh->dma, sqh->offs, sizeof(*sqh->qh),
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
#ifdef EHCI_DEBUG
DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0);
@@ -957,12 +958,12 @@ ehci_check_qh_intr(ehci_softc_t *sc, str
*/
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);
@@ -970,12 +971,12 @@ ehci_check_qh_intr(ehci_softc_t *sc, str
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;
@@ -1035,11 +1036,11 @@ ehci_check_itd_intr(ehci_softc_t *sc, st
*/
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;
}
@@ -1048,7 +1049,7 @@ ehci_check_itd_intr(ehci_softc_t *sc, st
}
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);
@@ -1080,13 +1081,13 @@ ehci_check_sitd_intr(ehci_softc_t *sc, s
*/
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;
@@ -1154,7 +1155,7 @@ ehci_idone(struct ehci_xfer *ex, ex_comp
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) {
@@ -1168,7 +1169,7 @@ ehci_idone(struct ehci_xfer *ex, ex_comp
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*/
@@ -1178,7 +1179,7 @@ ehci_idone(struct ehci_xfer *ex, ex_comp
}
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;
@@ -1198,7 +1199,7 @@ ehci_idone(struct ehci_xfer *ex, ex_comp
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);
/*
@@ -1211,10 +1212,10 @@ ehci_idone(struct ehci_xfer *ex, ex_comp
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|
@@ -1257,10 +1258,10 @@ ehci_idone(struct ehci_xfer *ex, ex_comp
#endif
for (sqtd = fsqtd; sqtd != lsqtd->nextqtd; sqtd = sqtd->nextqtd) {
- usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(sqtd->qtd),
+ usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(*sqtd->qtd),
BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
- nstatus = le32toh(sqtd->qtd.qtd_status);
- usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(sqtd->qtd),
+ nstatus = le32toh(sqtd->qtd->qtd_status);
+ usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(*sqtd->qtd),
BUS_DMASYNC_PREREAD);
if (nstatus & EHCI_QTD_ACTIVE)
break;
@@ -1318,7 +1319,7 @@ ehci_idone(struct ehci_xfer *ex, ex_comp
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
@@ -1585,7 +1586,7 @@ ehci_allocx(struct usbd_bus *bus, unsign
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);
@@ -1638,7 +1639,7 @@ ehci_device_clear_toggle(struct usbd_pip
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);
@@ -1728,12 +1729,12 @@ ehci_dump_sqtds(ehci_soft_qtd_t *sqtd)
ehci_dump_sqtd(sqtd);
usb_syncmem(&sqtd->dma,
sqtd->offs + offsetof(ehci_qtd_t, qtd_next),
- sizeof(sqtd->qtd),
+ sizeof(sqtd->qtd->qtd_next),
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);
+ sizeof(sqtd->qtd->qtd_next), BUS_DMASYNC_PREREAD);
}
if (!stop)
DPRINTF("dump aborted, too many TDs", 0, 0, 0, 0);
@@ -1745,14 +1746,14 @@ ehci_dump_sqtd(ehci_soft_qtd_t *sqtd)
EHCIHIST_FUNC(); EHCIHIST_CALLED();
usb_syncmem(&sqtd->dma, sqtd->offs,
- sizeof(sqtd->qtd), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
+ sizeof(*sqtd->qtd), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
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);
+ sizeof(*sqtd->qtd), BUS_DMASYNC_PREREAD);
}
Static void
@@ -1814,13 +1815,13 @@ 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();
usb_syncmem(&sqh->dma, sqh->offs,
- sizeof(sqh->qh), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
+ sizeof(*sqh->qh), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
DPRINTFN(10, "QH(%#jx) at %#jx:", (uintptr_t)sqh, sqh->physaddr, 0, 0);
link = le32toh(qh->qh_link);
@@ -1851,7 +1852,7 @@ ehci_dump_sqh(ehci_soft_qh_t *sqh)
DPRINTFN(10, "Overlay qTD:", 0, 0, 0, 0);
ehci_dump_qh_qtd(&qh->qh_qtd);
- usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
+ usb_syncmem(&sqh->dma, sqh->offs, sizeof(*sqh->qh),
BUS_DMASYNC_PREREAD);
}
@@ -1866,12 +1867,12 @@ ehci_dump_itds(ehci_soft_itd_t *itd)
ehci_dump_itd(itd);
usb_syncmem(&itd->dma,
itd->offs + offsetof(ehci_itd_t, itd_next),
- sizeof(itd->itd),
+ sizeof(itd->itd->itd_next),
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);
+ sizeof(itd->itd->itd_next), BUS_DMASYNC_PREREAD);
}
if (!stop)
DPRINTF("dump aborted, too many TDs", 0, 0, 0, 0);
@@ -1886,10 +1887,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",
@@ -1899,11 +1900,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",
@@ -2044,7 +2045,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) |
@@ -2054,27 +2055,27 @@ 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) |
(xfertype == UE_INTERRUPT ?
EHCI_QH_SET_SMASK(__BIT(1)) /* Start Split Y1 */
: 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(__BITS(3,5)) /* CS Y[345] */
: 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),
+ usb_syncmem(&sqh->dma, sqh->offs, sizeof(*sqh->qh),
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
epipe->sqh = sqh;
} else {
@@ -2172,19 +2173,19 @@ ehci_add_qh(ehci_softc_t *sc, ehci_soft_
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);
@@ -2209,11 +2210,11 @@ ehci_rem_qh(ehci_softc_t *sc, ehci_soft_
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);
}
@@ -2225,31 +2226,31 @@ ehci_set_qh_qtd(ehci_soft_qh_t *sqh, ehc
uint32_t status;
/* Save toggle bit and ping status. */
- usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
+ 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),
+ 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);
}
@@ -2325,7 +2326,7 @@ ehci_remove_itd_chain(ehci_softc_t *sc,
/* 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),
@@ -2335,10 +2336,10 @@ ehci_remove_itd_chain(ehci_softc_t *sc,
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)
@@ -2373,7 +2374,7 @@ ehci_remove_sitd_chain(ehci_softc_t *sc,
/* 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),
@@ -2383,10 +2384,10 @@ ehci_remove_sitd_chain(ehci_softc_t *sc,
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)
@@ -2908,24 +2909,32 @@ ehci_alloc_sqh(ehci_softc_t *sc)
DPRINTF("allocating chunk", 0, 0, 0, 0);
mutex_exit(&sc->sc_lock);
+ /*
+ * We can avoid USBMALLOC_COHERENT as the QHs are each on a
+ * cacheline.
+ */
usb_dma_t dma;
int err = usb_allocmem(sc->sc_dmatag,
- EHCI_SQH_SIZE * EHCI_SQH_CHUNK,
- EHCI_PAGE_SIZE, USBMALLOC_COHERENT, &dma);
+ EHCI_QH_SIZE * EHCI_QH_CHUNK,
+ EHCI_PAGE_SIZE, 0, &dma);
if (err) {
DPRINTF("alloc returned %jd", err, 0, 0, 0);
return NULL;
}
+ ehci_soft_qh_t *sqhs =
+ kmem_zalloc(sizeof(*sqh) * EHCI_QH_CHUNK, KM_SLEEP);
+
mutex_enter(&sc->sc_lock);
- for (size_t i = 0; i < EHCI_SQH_CHUNK; i++) {
- const int offs = i * EHCI_SQH_SIZE;
+ for (size_t i = 0; i < EHCI_QH_CHUNK; i++) {
+ const int offs = i * EHCI_QH_SIZE;
const bus_addr_t baddr = DMAADDR(&dma, offs);
KASSERT(BUS_ADDR_HI32(baddr) == 0);
- sqh = KERNADDR(&dma, offs);
+ sqh = &sqhs[i];
+ sqh->qh = KERNADDR(&dma, offs);
sqh->physaddr = BUS_ADDR_LO32(baddr);
sqh->dma = dma;
sqh->offs = offs;
@@ -2938,7 +2947,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;
}
@@ -2965,23 +2974,31 @@ ehci_alloc_sqtd(ehci_softc_t *sc)
mutex_exit(&sc->sc_lock);
usb_dma_t dma;
+ /*
+ * We can avoid USBMALLOC_COHERENT as the QTDs are each on a
+ * cacheline.
+ */
int err = usb_allocmem(sc->sc_dmatag,
- EHCI_SQTD_SIZE * EHCI_SQTD_CHUNK,
- EHCI_PAGE_SIZE, USBMALLOC_COHERENT, &dma);
+ EHCI_QTD_SIZE * EHCI_QTD_CHUNK,
+ EHCI_PAGE_SIZE, 0, &dma);
if (err) {
DPRINTF("alloc returned %jd", err, 0, 0, 0);
return NULL;
}
+ ehci_soft_qtd_t *sqtds =
+ kmem_zalloc(sizeof(*sqtd) * EHCI_QTD_CHUNK, KM_SLEEP);
+
mutex_enter(&sc->sc_lock);
- for (size_t i = 0; i < EHCI_SQTD_CHUNK; i++) {
- const int offs = i * EHCI_SQTD_SIZE;
+ for (size_t i = 0; i < EHCI_QTD_CHUNK; i++) {
+ const int offs = i * EHCI_QTD_SIZE;
const bus_addr_t baddr = DMAADDR(&dma, offs);
KASSERT(BUS_ADDR_HI32(baddr) == 0);
- sqtd = KERNADDR(&dma, offs);
+ sqtd = &sqtds[i];
+ sqtd->qtd = KERNADDR(&dma, offs);
sqtd->physaddr = BUS_ADDR_LO32(baddr);
sqtd->dma = dma;
sqtd->offs = offs;
@@ -2995,7 +3012,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;
@@ -3081,9 +3098,9 @@ ehci_append_sqtd(ehci_soft_qtd_t *sqtd,
{
if (prev) {
prev->nextqtd = sqtd;
- prev->qtd.qtd_next = htole32(sqtd->physaddr);
- prev->qtd.qtd_altnext = prev->qtd.qtd_next;
- usb_syncmem(&prev->dma, prev->offs, sizeof(prev->qtd),
+ 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_PREWRITE | BUS_DMASYNC_PREREAD);
}
}
@@ -3140,8 +3157,8 @@ ehci_reset_sqtd_chain(ehci_softc_t *sc,
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));
@@ -3153,17 +3170,17 @@ ehci_reset_sqtd_chain(ehci_softc_t *sc,
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),
+ usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(*sqtd->qtd),
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
sqtd->len = curlen;
@@ -3192,14 +3209,14 @@ ehci_reset_sqtd_chain(ehci_softc_t *sc,
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));
- usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(sqtd->qtd),
+ usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(*sqtd->qtd),
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
ehci_append_sqtd(sqtd, prev);
@@ -3225,15 +3242,22 @@ ehci_alloc_itd(ehci_softc_t *sc)
mutex_exit(&sc->sc_lock);
usb_dma_t dma;
+ /*
+ * We can avoid USBMALLOC_COHERENT as the ITDs are each on a
+ * cacheline.
+ */
int err = usb_allocmem(sc->sc_dmatag,
EHCI_ITD_SIZE * EHCI_ITD_CHUNK,
- EHCI_PAGE_SIZE, USBMALLOC_COHERENT, &dma);
+ EHCI_PAGE_SIZE, 0, &dma);
if (err) {
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 (size_t i = 0; i < EHCI_ITD_CHUNK; i++) {
const int offs = i * EHCI_ITD_SIZE;
@@ -3241,7 +3265,8 @@ ehci_alloc_itd(ehci_softc_t *sc)
KASSERT(BUS_ADDR_HI32(baddr) == 0);
- itd = KERNADDR(&dma, offs);
+ itd = &itds[i];
+ itd->itd = KERNADDR(&dma, offs);
itd->physaddr = BUS_ADDR_LO32(baddr);
itd->dma = dma;
itd->offs = offs;
@@ -3254,7 +3279,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;
@@ -3278,6 +3303,11 @@ ehci_alloc_sitd(ehci_softc_t *sc)
mutex_exit(&sc->sc_lock);
usb_dma_t dma;
+
+ /*
+ * We can avoid USBMALLOC_COHERENT as the SITDs are each on a
+ * cacheline.
+ */
int err = usb_allocmem(sc->sc_dmatag,
EHCI_SITD_SIZE * EHCI_SITD_CHUNK,
EHCI_PAGE_SIZE, USBMALLOC_COHERENT, &dma);
@@ -3286,6 +3316,8 @@ ehci_alloc_sitd(ehci_softc_t *sc)
DPRINTF("alloc returned %jd", err, 0, 0, 0);
return NULL;
}
+ struct ehci_soft_sitd *sitds =
+ kmem_alloc(sizeof(*sitd) * EHCI_SITD_CHUNK, KM_SLEEP);
mutex_enter(&sc->sc_lock);
for (size_t i = 0; i < EHCI_SITD_CHUNK; i++) {
@@ -3294,7 +3326,8 @@ ehci_alloc_sitd(ehci_softc_t *sc)
KASSERT(BUS_ADDR_HI32(baddr) == 0);
- sitd = KERNADDR(&dma, offs);
+ sitd = &sitds[i];
+ sitd->itd = KERNADDR(&dma, offs);
sitd->physaddr = BUS_ADDR_LO32(baddr);
sitd->dma = dma;
sitd->offs = offs;
@@ -3308,7 +3341,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;
@@ -3379,13 +3412,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) {
@@ -3398,12 +3431,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;
@@ -3425,9 +3458,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;
@@ -3438,21 +3471,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);
}
@@ -3523,18 +3556,18 @@ ehci_abort_isoc_xfer(struct usbd_xfer *x
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 {
@@ -3542,16 +3575,16 @@ ehci_abort_isoc_xfer(struct usbd_xfer *x
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);
}
}
@@ -3607,28 +3640,28 @@ ehci_device_ctrl_init(struct usbd_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;
@@ -3696,14 +3729,14 @@ ehci_device_ctrl_start(struct usbd_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;
@@ -3719,13 +3752,13 @@ ehci_device_ctrl_start(struct usbd_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) |
@@ -3733,18 +3766,18 @@ ehci_device_ctrl_start(struct usbd_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) |
@@ -3752,7 +3785,7 @@ ehci_device_ctrl_start(struct usbd_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
@@ -3769,10 +3802,10 @@ ehci_device_ctrl_start(struct usbd_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),
+ usb_syncmem(&end->dma, end->offs, sizeof(*end->qtd),
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
usb_syncmem(&xfer->ux_dmabuf, 0, len,
@@ -3780,15 +3813,15 @@ ehci_device_ctrl_start(struct usbd_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),
+ usb_syncmem(&setup->dma, setup->offs, sizeof(*setup->qtd),
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
- usb_syncmem(&status->dma, status->offs, sizeof(status->qtd),
+ 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);
@@ -3968,8 +4001,8 @@ ehci_device_bulk_start(struct usbd_xfer
ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end);
exfer->ex_sqtdend = end;
- end->qtd.qtd_status |= htole32(EHCI_QTD_IOC);
- usb_syncmem(&end->dma, end->offs, sizeof(end->qtd),
+ end->qtd->qtd_status |= htole32(EHCI_QTD_IOC);
+ usb_syncmem(&end->dma, end->offs, sizeof(*end->qtd),
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
#ifdef EHCI_DEBUG
@@ -4166,8 +4199,8 @@ ehci_device_intr_start(struct usbd_xfer
ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end);
- end->qtd.qtd_status |= htole32(EHCI_QTD_IOC);
- usb_syncmem(&end->dma, end->offs, sizeof(end->qtd),
+ 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;
@@ -4314,17 +4347,17 @@ ehci_device_fs_isoc_init(struct usbd_xfe
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;
@@ -4414,20 +4447,20 @@ ehci_device_fs_isoc_transfer(struct usbd
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 */
const bus_addr_t sba = DMAADDR(dma_buf, offs);
- sitd->sitd.sitd_buffer[0] = htole32(BUS_ADDR_LO32(sba));
- sitd->sitd.sitd_buffer_hi[0] = htole32(BUS_ADDR_HI32(sba));
+ sitd->sitd->sitd_buffer[0] = htole32(BUS_ADDR_LO32(sba));
+ sitd->sitd->sitd_buffer_hi[0] = htole32(BUS_ADDR_HI32(sba));
offs += xfer->ux_frlengths[i];
const bus_addr_t eba = DMAADDR(dma_buf, offs - 1);
- sitd->sitd.sitd_buffer[1] =
+ sitd->sitd->sitd_buffer[1] =
htole32(EHCI_SITD_SET_BPTR(BUS_ADDR_LO32(eba)));
- sitd->sitd.sitd_buffer_hi[1] = htole32(BUS_ADDR_HI32(eba));
+ sitd->sitd->sitd_buffer_hi[1] = htole32(BUS_ADDR_HI32(eba));
u_int huba __diagused = dev->ud_myhsport->up_parent->ud_addr;
@@ -4441,13 +4474,13 @@ ehci_device_fs_isoc_transfer(struct usbd
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;
@@ -4465,7 +4498,7 @@ ehci_device_fs_isoc_transfer(struct usbd
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;
@@ -4485,7 +4518,7 @@ ehci_device_fs_isoc_transfer(struct usbd
sb = 0xfc;
}
- sitd->sitd.sitd_sched = htole32(
+ sitd->sitd->sitd_sched = htole32(
EHCI_SITD_SET_SMASK(sa) |
EHCI_SITD_SET_CMASK(sb)
);
@@ -4495,10 +4528,10 @@ ehci_device_fs_isoc_transfer(struct usbd
} /* 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)
@@ -4536,13 +4569,13 @@ ehci_device_fs_isoc_transfer(struct usbd
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),
@@ -4661,7 +4694,7 @@ ehci_device_isoc_init(struct usbd_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;
@@ -4673,19 +4706,19 @@ ehci_device_isoc_init(struct usbd_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 */
@@ -4794,11 +4827,11 @@ ehci_device_isoc_transfer(struct usbd_xf
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;
}
@@ -4819,7 +4852,7 @@ ehci_device_isoc_transfer(struct usbd_xf
* 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))));
@@ -4828,7 +4861,7 @@ ehci_device_isoc_transfer(struct usbd_xf
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;
}
}
@@ -4851,25 +4884,25 @@ ehci_device_isoc_transfer(struct usbd_xf
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),
@@ -4917,17 +4950,17 @@ ehci_device_isoc_transfer(struct usbd_xf
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);
Index: src/sys/dev/usb/ehcireg.h
diff -u src/sys/dev/usb/ehcireg.h:1.40 src/sys/dev/usb/ehcireg.h:1.41
--- src/sys/dev/usb/ehcireg.h:1.40 Fri Mar 8 07:05:02 2024
+++ src/sys/dev/usb/ehcireg.h Mon Sep 23 10:07:26 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: ehcireg.h,v 1.40 2024/03/08 07:05:02 mrg Exp $ */
+/* $NetBSD: ehcireg.h,v 1.41 2024/09/23 10:07:26 skrll Exp $ */
/*
* Copyright (c) 2001, 2004 The NetBSD Foundation, Inc.
@@ -248,7 +248,10 @@ typedef struct ehci_itd_t {
#define EHCI_ITD_GET_MULTI(x) __SHIFTOUT((x), EHCI_ITD_MULTI_MASK)
#define EHCI_ITD_SET_MULTI(x) __SHIFTIN((x), EHCI_ITD_MULTI_MASK)
volatile ehci_isoc_bufr_ptr_t itd_bufr_hi[EHCI_ITD_NBUFFERS];
-} __aligned(EHCI_ITD_ALIGN) ehci_itd_t;
+} ehci_itd_t;
+#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 */
#define EHCI_SITD_ALIGN 32
@@ -295,7 +298,7 @@ typedef struct ehci_sitd_t {
volatile ehci_link_t sitd_back;
volatile uint32_t sitd_buffer_hi[EHCI_SITD_BUFFERS];
-} __aligned(EHCI_SITD_ALIGN) ehci_sitd_t;
+} ehci_sitd_t;
/* Queue Element Transfer Descriptor */
#define EHCI_QTD_NBUFFERS 5
@@ -339,7 +342,10 @@ typedef struct ehci_qtd_t {
#define EHCI_QTD_SET_TOGGLE(x) __SHIFTIN((x), EHCI_QTD_TOGGLE_MASK)
volatile ehci_physaddr_t qtd_buffer[EHCI_QTD_NBUFFERS];
volatile ehci_physaddr_t qtd_buffer_hi[EHCI_QTD_NBUFFERS];
-} __aligned(EHCI_QTD_ALIGN) ehci_qtd_t;
+} ehci_qtd_t;
+#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 */
#define EHCI_QH_ALIGN 32
@@ -389,26 +395,18 @@ typedef struct ehci_qh_t {
#define EHCI_QH_GET_MULT(x) __SHIFTOUT((x), EHCI_QH_MULTI_MASK)
#define EHCI_QH_SET_MULT(x) __SHIFTIN((x), EHCI_QH_MULTI_MASK)
volatile ehci_link_t qh_curqtd;
- /*
- * The QH descriptor contains a TD overlay, but it is not
- * 32-byte aligned, so declare the fields instead of embedding
- * a ehci_qtd_t directly.
- */
- struct ehci_qh_qtd_t {
- volatile ehci_link_t qtd_next;
- volatile ehci_link_t qtd_altnext;
- volatile uint32_t qtd_status;
- volatile ehci_physaddr_t qtd_buffer[EHCI_QTD_NBUFFERS];
- volatile ehci_physaddr_t qtd_buffer_hi[EHCI_QTD_NBUFFERS];
- } qh_qtd;
-} __aligned(EHCI_QH_ALIGN) ehci_qh_t;
+ ehci_qtd_t qh_qtd;
+} ehci_qh_t;
+#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 */
#define EHCI_FSTN_ALIGN 32
typedef struct ehci_fstn_t {
volatile ehci_link_t fstn_link;
volatile ehci_link_t fstn_back;
-} __aligned(EHCI_FSTN_ALIGN) ehci_fstn_t;
+} ehci_fstn_t;
/* Debug Port */
#define PCI_CAP_DEBUGPORT_OFFSET __BITS(28,16)
Index: src/sys/dev/usb/ehcivar.h
diff -u src/sys/dev/usb/ehcivar.h:1.52 src/sys/dev/usb/ehcivar.h:1.53
--- src/sys/dev/usb/ehcivar.h:1.52 Sat Jan 20 00:51:29 2024
+++ src/sys/dev/usb/ehcivar.h Mon Sep 23 10:07:26 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: ehcivar.h,v 1.52 2024/01/20 00:51:29 jmcneill Exp $ */
+/* $NetBSD: ehcivar.h,v 1.53 2024/09/23 10:07:26 skrll Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
#include <sys/pool.h>
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