Module Name: src Committed By: jmcneill Date: Sun Sep 22 14:05:47 UTC 2024
Modified Files: src/sys/dev/usb: ohci.c ohcireg.h ohcivar.h Log Message: ohci: Allocate a whole cacheline for all descriptors Allocate a whole cacheline for all descriptor types such 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. Patch/idea mainly from Nick (skrll@) with a few fixes from me. To generate a diff of this commit: cvs rdiff -u -r1.328 -r1.329 src/sys/dev/usb/ohci.c cvs rdiff -u -r1.28 -r1.29 src/sys/dev/usb/ohcireg.h cvs rdiff -u -r1.62 -r1.63 src/sys/dev/usb/ohcivar.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/ohci.c diff -u src/sys/dev/usb/ohci.c:1.328 src/sys/dev/usb/ohci.c:1.329 --- src/sys/dev/usb/ohci.c:1.328 Sun Apr 28 08:55:03 2024 +++ src/sys/dev/usb/ohci.c Sun Sep 22 14:05:47 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: ohci.c,v 1.328 2024/04/28 08:55:03 skrll Exp $ */ +/* $NetBSD: ohci.c,v 1.329 2024/09/22 14:05:47 jmcneill Exp $ */ /* * Copyright (c) 1998, 2004, 2005, 2012, 2016, 2020 The NetBSD Foundation, Inc. @@ -42,7 +42,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.328 2024/04/28 08:55:03 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.329 2024/09/22 14:05:47 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -409,19 +409,29 @@ 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.ub_dmatag, OHCI_SED_SIZE * OHCI_SED_CHUNK, - OHCI_ED_ALIGN, 0 /*!USBMALLOC_COHERENT*/, &dma); + int err = usb_allocmem(sc->sc_bus.ub_dmatag, + OHCI_ED_SIZE * OHCI_ED_CHUNK, + OHCI_ED_ALIGN, 0, &dma); if (err) return NULL; + ohci_soft_ed_t *seds = + kmem_alloc(sizeof(*sed) * OHCI_ED_CHUNK, KM_SLEEP); + /* + * We can avoid USBMALLOC_COHERENT as the EDs are each on a + * cacheline. + */ 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++) { + offs = i * OHCI_ED_SIZE; + + sed = &seds[i]; + sed->ed = KERNADDR(&dma, offs); sed->physaddr = DMAADDR(&dma, offs); sed->dma = dma; sed->offs = offs; sed->next = sc->sc_freeeds; + sc->sc_freeeds = sed; } } @@ -429,7 +439,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 +477,29 @@ 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.ub_dmatag, OHCI_STD_SIZE * OHCI_STD_CHUNK, - OHCI_TD_ALIGN, USBMALLOC_COHERENT, &dma); + ohci_soft_td_t *stds = + kmem_alloc(sizeof(*std) * OHCI_TD_CHUNK, KM_SLEEP); + /* + * We can avoid USBMALLOC_COHERENT as the TDs are each on a + * cacheline. + */ + int err = usb_allocmem(sc->sc_bus.ub_dmatag, + OHCI_TD_SIZE * OHCI_TD_CHUNK, + OHCI_TD_ALIGN, 0, &dma); if (err) return NULL; 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++) { + offs = i * OHCI_TD_SIZE; + + std = &stds[i]; + 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 +508,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 +671,10 @@ ohci_reset_std_chain(ohci_softc_t *sc, s 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; @@ -667,20 +687,20 @@ ohci_reset_std_chain(ohci_softc_t *sc, s if (len != 0) { KASSERT(next != NULL); DPRINTFN(10, "extend chain", 0, 0, 0, 0); - usb_syncmem(&cur->dma, cur->offs, sizeof(cur->td), + usb_syncmem(&cur->dma, cur->offs, sizeof(*cur->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); cur = next; } } - cur->td.td_flags |= + cur->td->td_flags |= HTOO32(xfer->ux_flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0); if (!rd && (flags & USBD_FORCE_SHORT_XFER) && alen % mps == 0) { /* We're adding a ZLP so sync the previous TD */ - usb_syncmem(&cur->dma, cur->offs, sizeof(cur->td), + usb_syncmem(&cur->dma, cur->offs, sizeof(*cur->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); /* Force a 0 length transfer at the end. */ @@ -688,10 +708,10 @@ ohci_reset_std_chain(ohci_softc_t *sc, s 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 +739,26 @@ 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.ub_dmatag, OHCI_SITD_SIZE * OHCI_SITD_CHUNK, - OHCI_ITD_ALIGN, USBMALLOC_COHERENT, &dma); + int err = usb_allocmem(sc->sc_bus.ub_dmatag, + OHCI_ITD_SIZE * OHCI_ITD_CHUNK, + OHCI_ITD_ALIGN, 0, &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++) { + offs = i * OHCI_ITD_SIZE; + + sitd = &sitds[i]; + 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 +767,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,9 +871,9 @@ 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); usb_syncmem(&sc->sc_ctrl_head->dma, sc->sc_ctrl_head->offs, - sizeof(sc->sc_ctrl_head->ed), + sizeof(*sc->sc_ctrl_head->ed), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); /* Allocate dummy ED that starts the bulk list. */ @@ -854,9 +882,9 @@ 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), + sizeof(*sc->sc_bulk_head->ed), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); /* Allocate dummy ED that starts the isochronous list. */ @@ -865,9 +893,9 @@ 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), + sizeof(*sc->sc_isoc_head->ed), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); /* Allocate all the dummy EDs that make up the interrupt tree. */ @@ -881,14 +909,14 @@ 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); - usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), + sed->ed->ed_nexted = HTOO32(psed->physaddr); + usb_syncmem(&sed->dma, sed->offs, sizeof(*sed->ed), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } /* @@ -1453,20 +1481,20 @@ ohci_softintr(void *v) for (sdone = NULL, sidone = NULL; done != 0; ) { std = ohci_hash_find_td(sc, done); if (std != NULL) { - usb_syncmem(&std->dma, std->offs, sizeof(std->td), + 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; } sitd = ohci_hash_find_itd(sc, done); if (sitd != NULL) { - usb_syncmem(&sitd->dma, sitd->offs, sizeof(sitd->itd), + 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; @@ -1519,14 +1547,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) { @@ -1553,11 +1581,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); @@ -1613,21 +1641,21 @@ ohci_softintr(void *v) sitd = next) { next = sitd->nextitd; - usb_syncmem(&sitd->dma, sitd->offs, sizeof(sitd->itd), + usb_syncmem(&sitd->dma, sitd->offs, sizeof(*sitd->itd), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 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) @@ -1813,17 +1841,17 @@ ohci_add_ed(ohci_softc_t *sc, ohci_soft_ 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); } @@ -1843,12 +1871,12 @@ ohci_rem_ed(ohci_softc_t *sc, ohci_soft_ 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); } @@ -1959,10 +1987,10 @@ ohci_dump_td(ohci_softc_t *sc, ohci_soft { OHCIHIST_FUNC(); OHCIHIST_CALLED(); - usb_syncmem(&std->dma, std->offs, sizeof(std->td), + 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), @@ -1972,9 +2000,9 @@ ohci_dump_td(ohci_softc_t *sc, ohci_soft 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 @@ -1982,31 +2010,31 @@ ohci_dump_itd(ohci_softc_t *sc, ohci_sof { OHCIHIST_FUNC(); OHCIHIST_CALLED(); - usb_syncmem(&sitd->dma, sitd->offs, sizeof(sitd->itd), + 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 @@ -2021,10 +2049,10 @@ ohci_dump_ed(ohci_softc_t *sc, ohci_soft { OHCIHIST_FUNC(); OHCIHIST_CALLED(); - usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), + 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), @@ -2036,12 +2064,12 @@ ohci_dump_ed(ohci_softc_t *sc, ohci_soft __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 @@ -2116,16 +2144,16 @@ 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); - usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), + sed->ed->ed_tailp = HTOO32(tdphys); + usb_syncmem(&sed->dma, sed->offs, sizeof(*sed->ed), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); switch (xfertype) { @@ -2188,15 +2216,16 @@ ohci_close_pipe(struct usbd_pipe *pipe, 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)) { + // XXXNH usb_sync + 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); @@ -2205,8 +2234,8 @@ ohci_close_pipe(struct usbd_pipe *pipe, 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 @@ -2214,7 +2243,7 @@ ohci_close_pipe(struct usbd_pipe *pipe, /* 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); } @@ -2266,15 +2295,15 @@ ohci_abortx(struct usbd_xfer *xfer) * waiting for the next start of frame (OHCI_SF) */ DPRINTFN(1, "stop ed=%#jx", (uintptr_t)sed, 0, 0, 0); - usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), + usb_syncmem(&sed->dma, sed->offs, sizeof(*sed->ed), 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, @@ -2337,16 +2366,16 @@ 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; usb_syncmem(&p->dma, p->offs + offsetof(ohci_td_t, td_flags), - sizeof(p->td.td_flags), + sizeof(p->td->td_flags), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - 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; @@ -2380,13 +2409,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); @@ -2396,11 +2425,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); dying: DPRINTFN(14, "end", 0, 0, 0, 0); @@ -2808,13 +2837,13 @@ ohci_device_ctrl_start(struct usbd_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 */ @@ -2828,21 +2857,21 @@ ohci_device_ctrl_start(struct usbd_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), + usb_syncmem(&end->dma, end->offs, sizeof(*end->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); usb_syncmem(&xfer->ux_dmabuf, 0, len, 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); } @@ -2855,15 +2884,15 @@ ohci_device_ctrl_start(struct usbd_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; @@ -2871,32 +2900,32 @@ ohci_device_ctrl_start(struct usbd_xfer ohci_hash_add_td(sc, setup); xfer->ux_hcpriv = setup; - usb_syncmem(&setup->dma, setup->offs, sizeof(setup->td), + 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; stat->xfer = xfer; ohci_hash_add_td(sc, stat); - usb_syncmem(&stat->dma, stat->offs, sizeof(stat->td), + 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; - usb_syncmem(&tail->dma, tail->offs, sizeof(tail->td), + usb_syncmem(&tail->dma, tail->offs, sizeof(*tail->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); #ifdef OHCI_DEBUG @@ -2909,10 +2938,10 @@ ohci_device_ctrl_start(struct usbd_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); xfer->ux_status = USBD_IN_PROGRESS; @@ -2963,13 +2992,13 @@ ohci_device_clear_toggle(struct usbd_pip ohci_soft_ed_t *sed = opipe->sed; usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_headp), - sizeof(sed->ed.ed_headp), + sizeof(sed->ed->ed_headp), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - opipe->sed->ed.ed_headp &= HTOO32(~OHCI_TOGGLECARRY); + opipe->sed->ed->ed_headp &= HTOO32(~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); } @@ -3080,13 +3109,13 @@ ohci_device_bulk_start(struct usbd_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; DPRINTFN(10, "xfer=%#jx new tail=%#jx held at %#ux", (uintptr_t)ox, (uintptr_t)tail, (uintptr_t)tail->held, 0); - usb_syncmem(&tail->dma, tail->offs, sizeof(tail->td), + usb_syncmem(&tail->dma, tail->offs, sizeof(*tail->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); xfer->ux_hcpriv = data; @@ -3095,20 +3124,20 @@ ohci_device_bulk_start(struct usbd_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), + usb_syncmem(&last->dma, last->offs, sizeof(*last->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 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); @@ -3123,11 +3152,11 @@ ohci_device_bulk_start(struct usbd_xfer for (tdp = data; tdp != tail; tdp = tdp->nexttd) { KASSERT(tdp->xfer == xfer); } - usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), + 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); - usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), + 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); xfer->ux_status = USBD_IN_PROGRESS; @@ -3272,13 +3301,13 @@ ohci_device_intr_start(struct usbd_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; DPRINTFN(10, "xfer=%#jx new tail=%#jx held at %#jx", (uintptr_t)ox, (uintptr_t)tail, (uintptr_t)tail->held, 0); - usb_syncmem(&tail->dma, tail->offs, sizeof(tail->td), + usb_syncmem(&tail->dma, tail->offs, sizeof(*tail->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); xfer->ux_hcpriv = data; @@ -3287,13 +3316,13 @@ ohci_device_intr_start(struct usbd_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), + usb_syncmem(&last->dma, last->offs, sizeof(*last->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); #ifdef OHCI_DEBUG @@ -3306,11 +3335,11 @@ ohci_device_intr_start(struct usbd_xfer #endif /* Insert ED in schedule */ - usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), + 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); - usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), + 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); xfer->ux_status = USBD_IN_PROGRESS; @@ -3347,22 +3376,22 @@ ohci_device_intr_close(struct usbd_pipe DPRINTFN(1, "pipe=%#jx nslots=%jd pos=%jd", (uintptr_t)pipe, nslots, 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); + sizeof(*sed->ed), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); + 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++) @@ -3422,20 +3451,20 @@ ohci_device_setintr(ohci_softc_t *sc, st hsed = sc->sc_eds[best]; sed->next = hsed->next; 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); - 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_nexted), - sizeof(sed->ed.ed_nexted), + sizeof(sed->ed->ed_nexted), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); hsed->next = sed; usb_syncmem(&hsed->dma, hsed->offs + offsetof(ohci_ed_t, ed_nexted), - sizeof(hsed->ed.ed_nexted), + sizeof(hsed->ed->ed_nexted), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - 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_nexted), - sizeof(hsed->ed.ed_nexted), + sizeof(hsed->ed->ed_nexted), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); mutex_exit(&sc->sc_lock); @@ -3624,15 +3653,15 @@ ohci_device_isoc_enter(struct usbd_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; @@ -3640,7 +3669,7 @@ ohci_device_isoc_enter(struct usbd_xfer sitd->isdone = false; #endif ohci_hash_add_itd(sc, sitd); - usb_syncmem(&sitd->dma, sitd->offs, sizeof(sitd->itd), + usb_syncmem(&sitd->dma, sitd->offs, sizeof(*sitd->itd), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); sitd = nsitd; @@ -3648,7 +3677,7 @@ ohci_device_isoc_enter(struct usbd_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; } @@ -3656,23 +3685,23 @@ ohci_device_isoc_enter(struct usbd_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; - usb_syncmem(&tail->dma, tail->offs, sizeof(tail->itd), + usb_syncmem(&tail->dma, tail->offs, sizeof(*tail->itd), 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; @@ -3680,7 +3709,7 @@ ohci_device_isoc_enter(struct usbd_xfer sitd->isdone = false; #endif ohci_hash_add_itd(sc, sitd); - usb_syncmem(&sitd->dma, sitd->offs, sizeof(sitd->itd), + usb_syncmem(&sitd->dma, sitd->offs, sizeof(*sitd->itd), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); isoc->next = isoc->next + ncur; @@ -3703,11 +3732,11 @@ ohci_device_isoc_enter(struct usbd_xfer } #endif - usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), + 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); - usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), + 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); } @@ -3735,11 +3764,11 @@ ohci_device_isoc_abort(struct usbd_xfer xfer->ux_status = USBD_CANCELLED; sed = opipe->sed; - usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), + 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; @@ -3759,9 +3788,9 @@ ohci_device_isoc_abort(struct usbd_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 */ - usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), + 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); done: Index: src/sys/dev/usb/ohcireg.h diff -u src/sys/dev/usb/ohcireg.h:1.28 src/sys/dev/usb/ohcireg.h:1.29 --- src/sys/dev/usb/ohcireg.h:1.28 Wed Jun 3 15:38:02 2020 +++ src/sys/dev/usb/ohcireg.h Sun Sep 22 14:05:47 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: ohcireg.h,v 1.28 2020/06/03 15:38:02 skrll Exp $ */ +/* $NetBSD: ohcireg.h,v 1.29 2024/09/22 14:05:47 jmcneill Exp $ */ /* $FreeBSD: src/sys/dev/usb/ohcireg.h,v 1.8 1999/11/17 22:33:40 n_hibma Exp $ */ /* @@ -142,7 +142,7 @@ typedef uint32_t ohci_physaddr_t; #define OHCI_NO_INTRS 32 struct ohci_hcca { volatile ohci_physaddr_t hcca_interrupt_table[OHCI_NO_INTRS]; - volatile uint32_t hcca_frame_number; + volatile uint32_t hcca_frame_number; volatile ohci_physaddr_t hcca_done_head; #define OHCI_DONE_INTRS 1 }; @@ -186,6 +186,10 @@ typedef struct { } ohci_ed_t; /* #define OHCI_ED_SIZE 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 Index: src/sys/dev/usb/ohcivar.h diff -u src/sys/dev/usb/ohcivar.h:1.62 src/sys/dev/usb/ohcivar.h:1.63 --- src/sys/dev/usb/ohcivar.h:1.62 Wed Dec 9 07:10:01 2020 +++ src/sys/dev/usb/ohcivar.h Sun Sep 22 14:05:47 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: ohcivar.h,v 1.62 2020/12/09 07:10:01 skrll Exp $ */ +/* $NetBSD: ohcivar.h,v 1.63 2024/09/22 14:05:47 jmcneill Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -36,18 +36,16 @@ #include <sys/pool.h> 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)