I have a couple of machines with an EHCI controller that refuses to work
with memory above 2G, causing all kinds of trouble. This diff enables
setting a bus_dma boundary and allows me to make off-site backups again.

Due to the bus_dma pool being shared across all HCs, it was necessary to
pull the allocator apart and allow for restrictions on a host controller
basis.

Since I was already changing all the usb_*mem functions, I've
renamed them so that they are in the same module space as the bus_mem.c
file they reside in. If someone feels strongly about the old function
names, it could be reversed - but it does not decrease the number of
lines changed.

So far tested on amd64, i386 and sparc64 with affected and
unaffected ehci controllers. I could also test ohci, but not uhci due to
me being cheap and not buying/finding Intel hw.

Enough talk, here is the glorious diff

Index: dev//pci/ehci_pci.c
===================================================================
RCS file: /home/vcs/cvs/openbsd/src/sys/dev/pci/ehci_pci.c,v
retrieving revision 1.23
diff -u -p -r1.23 ehci_pci.c
--- dev//pci/ehci_pci.c 26 Apr 2011 00:37:34 -0000      1.23
+++ dev//pci/ehci_pci.c 13 Mar 2012 22:34:34 -0000
@@ -109,6 +109,7 @@ ehci_pci_attach(struct device *parent, s
        const char *vendor;
        char *devname = sc->sc.sc_bus.bdev.dv_xname;
        usbd_status r;
+       bus_size_t boundary = 0; /* No limit */
        int s;
 
        /* Map I/O registers */
@@ -162,6 +163,19 @@ ehci_pci_attach(struct device *parent, s
                            EHCI_VT6202_WORKAROUND_REG, value | 0x20000000);
                }
                break;
+       case PCI_VENDOR_NVIDIA:
+               switch (PCI_PRODUCT(pa->pa_id)) {
+                       /*
+                        * According to Nvidia, these chips can't do DMA
+                        * transfers above 2G (limited to QH, ITD, SITD)
+                        */
+               case PCI_PRODUCT_NVIDIA_MCP04_EHCI:
+               case PCI_PRODUCT_NVIDIA_NFORCE3_EHCI:
+               case PCI_PRODUCT_NVIDIA_NFORCE3_250_EHCI:
+               case PCI_PRODUCT_NVIDIA_NFORCE4_EHCI:
+                       boundary = 1UL<<31;
+                       break;
+               }
        }
 
        /* Map and establish the interrupt. */
@@ -209,6 +223,7 @@ ehci_pci_attach(struct device *parent, s
                sc->sc.sc_flags |= EHCIF_DROPPED_INTR_WORKAROUND;
 
        ehci_pci_takecontroller(sc, 0);
+       usb_mem_init(&sc->sc.sc_bus.umem, boundary);
        r = ehci_init(&sc->sc);
        if (r != USBD_NORMAL_COMPLETION) {
                printf("%s: init failed, error=%d\n", devname, r);
Index: dev//usb/ehci.c
===================================================================
RCS file: /home/vcs/cvs/openbsd/src/sys/dev/usb/ehci.c,v
retrieving revision 1.118
diff -u -p -r1.118 ehci.c
--- dev//usb/ehci.c     10 Jul 2011 17:34:53 -0000      1.118
+++ dev//usb/ehci.c     13 Mar 2012 22:34:35 -0000
@@ -208,10 +208,11 @@ usbd_status       ehci_device_request(usbd_xfe
 usbd_status    ehci_device_setintr(ehci_softc_t *, ehci_soft_qh_t *,
                            int ival);
 
-void           ehci_add_qh(ehci_soft_qh_t *, ehci_soft_qh_t *);
+void           ehci_add_qh(ehci_softc_t *, ehci_soft_qh_t *, ehci_soft_qh_t *);
 void           ehci_rem_qh(ehci_softc_t *, ehci_soft_qh_t *,
                            ehci_soft_qh_t *);
-void           ehci_set_qh_qtd(ehci_soft_qh_t *, ehci_soft_qtd_t *);
+void           ehci_set_qh_qtd(ehci_softc_t *, ehci_soft_qh_t *,
+                       ehci_soft_qtd_t *);
 void           ehci_sync_hc(ehci_softc_t *);
 
 void           ehci_close_pipe(usbd_pipe_handle, ehci_soft_qh_t *);
@@ -225,7 +226,7 @@ void                ehci_dump_link(ehci_link_t, int);
 void           ehci_dump_sqtds(ehci_soft_qtd_t *);
 void           ehci_dump_sqtd(ehci_soft_qtd_t *);
 void           ehci_dump_qtd(ehci_qtd_t *);
-void           ehci_dump_sqh(ehci_soft_qh_t *);
+void           ehci_dump_sqh(ehci_softc_t *, ehci_soft_qh_t *);
 #if notyet
 void           ehci_dump_sitd(struct ehci_soft_itd *itd);
 void           ehci_dump_itd(struct ehci_soft_itd *);
@@ -334,6 +335,7 @@ ehci_init(ehci_softc_t *sc)
        u_int i, j;
        usbd_status err;
        ehci_soft_qh_t *sqh;
+       struct usb_mem *um = sc->sc_bus.umem;
 
 #ifdef EHCI_DEBUG
        u_int32_t vers;
@@ -346,6 +348,11 @@ ehci_init(ehci_softc_t *sc)
            vers >> 8, vers & 0xff));
 #endif
 
+       if (sc->sc_bus.umem == NULL) {
+               usb_mem_init(&sc->sc_bus.umem, 0);
+               um = sc->sc_bus.umem;
+       }
+
        sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
 
        sparams = EREAD4(sc, EHCI_HCSPARAMS);
@@ -394,7 +401,7 @@ ehci_init(ehci_softc_t *sc)
        case 3:
                return (USBD_IOERROR);
        }
-       err = usb_allocmem(&sc->sc_bus, sc->sc_flsize * sizeof(ehci_link_t),
+       err = usb_mem_alloc(um, &sc->sc_bus, sc->sc_flsize * 
sizeof(ehci_link_t),
            EHCI_FLALIGN_ALIGN, &sc->sc_fldma);
        if (err)
                return (err);
@@ -450,7 +457,7 @@ ehci_init(ehci_softc_t *sc)
                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_mem_sync(um, &sqh->dma, sqh->offs, sizeof(sqh->qh),
                    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
        }
        /* Point the frame list at the last level (128ms). */
@@ -459,7 +466,7 @@ ehci_init(ehci_softc_t *sc)
                        sc->sc_flist[j] = htole32(EHCI_LINK_QH | sc->sc_islots[
                            EHCI_IQHIDX(EHCI_IPOLLRATES - 1, ehci_reverse_bits(
                            i, EHCI_IPOLLRATES - 1))].sqh->physaddr);
-       usb_syncmem(&sc->sc_fldma, 0, sc->sc_flsize * sizeof(ehci_link_t),
+       usb_mem_sync(um, &sc->sc_fldma, 0, sc->sc_flsize * sizeof(ehci_link_t),
            BUS_DMASYNC_PREWRITE);
 
        /* Allocate dummy QH that starts the async list. */
@@ -481,11 +488,11 @@ ehci_init(ehci_softc_t *sc)
        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_mem_sync(um, &sqh->dma, sqh->offs, sizeof(sqh->qh),
            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 #ifdef EHCI_DEBUG
        if (ehcidebug)
-               ehci_dump_sqh(sqh);
+               ehci_dump_sqh(sc, sqh);
 #endif
 
        /* Point to async list */
@@ -529,7 +536,7 @@ ehci_init(ehci_softc_t *sc)
        ehci_free_sqh(sc, sc->sc_async_head);
 #endif
  bad1:
-       usb_freemem(&sc->sc_bus, &sc->sc_fldma);
+       usb_mem_free(um, &sc->sc_bus, &sc->sc_fldma);
        return (err);
 }
 
@@ -708,6 +715,7 @@ void
 ehci_check_qh_intr(ehci_softc_t *sc, struct ehci_xfer *ex)
 {
        ehci_soft_qtd_t *sqtd, *lsqtd;
+       struct usb_mem *um = sc->sc_bus.umem;
        __uint32_t status;
 
        if (ex->sqtdstart == NULL) {
@@ -727,19 +735,19 @@ ehci_check_qh_intr(ehci_softc_t *sc, str
         * is a an error somewhere in the middle, or whether there was a
         * short packet (SPD and not ACTIVE).
         */
-       usb_syncmem(&lsqtd->dma,
+       usb_mem_sync(um, &lsqtd->dma,
            lsqtd->offs + offsetof(ehci_qtd_t, qtd_status),
            sizeof(lsqtd->qtd.qtd_status),
            BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
        if (letoh32(lsqtd->qtd.qtd_status) & EHCI_QTD_ACTIVE) {
                DPRINTFN(12, ("ehci_check_intr: active ex=%p\n", ex));
                for (sqtd = ex->sqtdstart; sqtd != lsqtd; sqtd=sqtd->nextqtd) {
-                       usb_syncmem(&sqtd->dma,
+                       usb_mem_sync(um, &sqtd->dma,
                            sqtd->offs + offsetof(ehci_qtd_t, qtd_status),
                            sizeof(sqtd->qtd.qtd_status),
                            BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
                        status = letoh32(sqtd->qtd.qtd_status);
-                       usb_syncmem(&sqtd->dma,
+                       usb_mem_sync(um, &sqtd->dma,
                            sqtd->offs + offsetof(ehci_qtd_t, qtd_status),
                            sizeof(sqtd->qtd.qtd_status), BUS_DMASYNC_PREREAD);
                        /* If there's an active QTD the xfer isn't done. */
@@ -754,7 +762,7 @@ ehci_check_qh_intr(ehci_softc_t *sc, str
                }
                DPRINTFN(12, ("ehci_check_intr: ex=%p std=%p still active\n",
                              ex, ex->sqtdstart));
-               usb_syncmem(&lsqtd->dma,
+               usb_mem_sync(um, &lsqtd->dma,
                    lsqtd->offs + offsetof(ehci_qtd_t, qtd_status),
                    sizeof(lsqtd->qtd.qtd_status), BUS_DMASYNC_PREREAD);
                return;
@@ -769,6 +777,7 @@ ehci_check_qh_intr(ehci_softc_t *sc, str
 void
 ehci_check_itd_intr(ehci_softc_t *sc, struct ehci_xfer *ex) {
        ehci_soft_itd_t *itd;
+       struct usb_mem *um = sc->sc_bus.umem;
        int i;
 
        if (&ex->xfer != SIMPLEQ_FIRST(&ex->xfer.pipe->queue))
@@ -791,7 +800,7 @@ ehci_check_itd_intr(ehci_softc_t *sc, st
         * check no active transfers in last itd, meaning we're finished
         */
 
-       usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_ctl),
+       usb_mem_sync(um, &itd->dma, itd->offs + offsetof(ehci_itd_t, itd_ctl),
            sizeof(itd->itd.itd_ctl), BUS_DMASYNC_POSTWRITE |
            BUS_DMASYNC_POSTREAD);
 
@@ -817,8 +826,10 @@ void
 ehci_idone(struct ehci_xfer *ex)
 {
        usbd_xfer_handle xfer = &ex->xfer;
+       struct usb_mem *um = xfer->device->bus->umem;
 #ifdef EHCI_DEBUG
        struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
+       ehci_softc_t *sc = (ehci_softc_t *)xfer->device->bus;
 #endif
        ehci_soft_qtd_t *sqtd, *lsqtd;
        u_int32_t status = 0, nstatus = 0;
@@ -884,7 +895,7 @@ ehci_idone(struct ehci_xfer *ex)
                }
 
                for (itd = ex->itdstart; itd != NULL; itd = itd->xfer_next) {
-                       usb_syncmem(&itd->dma,
+                       usb_mem_sync(um, &itd->dma,
                            itd->offs + offsetof(ehci_itd_t, itd_ctl),
                            sizeof(itd->itd.itd_ctl), BUS_DMASYNC_POSTWRITE |
                            BUS_DMASYNC_POSTREAD);
@@ -924,7 +935,7 @@ ehci_idone(struct ehci_xfer *ex)
        actlen = 0;
        for (sqtd = ex->sqtdstart; sqtd != lsqtd->nextqtd;
            sqtd = sqtd->nextqtd) {
-               usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(sqtd->qtd),
+               usb_mem_sync(um, &sqtd->dma, sqtd->offs, sizeof(sqtd->qtd),
                    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
                nstatus = letoh32(sqtd->qtd.qtd_status);
                if (nstatus & EHCI_QTD_ACTIVE)
@@ -958,7 +969,7 @@ ehci_idone(struct ehci_xfer *ex)
                          xfer->pipe->endpoint->edesc->bEndpointAddress,
                          sbuf));
                if (ehcidebug > 2) {
-                       ehci_dump_sqh(epipe->sqh);
+                       ehci_dump_sqh(sc, epipe->sqh);
                        ehci_dump_sqtds(ex->sqtdstart);
                }
 #endif
@@ -1188,10 +1199,10 @@ ehci_allocm(struct usbd_bus *bus, usb_dm
        struct ehci_softc *sc = (struct ehci_softc *)bus;
        usbd_status err;
 
-       err = usb_allocmem(&sc->sc_bus, size, 0, dma);
+       err = usb_mem_alloc(sc->sc_bus.umem, &sc->sc_bus, size, 0, dma);
 #ifdef EHCI_DEBUG
        if (err)
-               printf("ehci_allocm: usb_allocmem()=%d\n", err);
+               printf("ehci_allocm: usb_mem_alloc()=%d\n", err);
 #endif
        return (err);
 }
@@ -1201,7 +1212,7 @@ ehci_freem(struct usbd_bus *bus, usb_dma
 {
        struct ehci_softc *sc = (struct ehci_softc *)bus;
 
-       usb_freemem(&sc->sc_bus, dma);
+       usb_mem_free(sc->sc_bus.umem, &sc->sc_bus, dma);
 }
 
 usbd_xfer_handle
@@ -1339,18 +1350,19 @@ ehci_dump_link(ehci_link_t link, int typ
 void
 ehci_dump_sqtds(ehci_soft_qtd_t *sqtd)
 {
+       struct usb_mem *um = sqtd->xfer->device->bus->umem;
        int i;
        u_int32_t stop;
 
        stop = 0;
        for (i = 0; sqtd && i < 20 && !stop; sqtd = sqtd->nextqtd, i++) {
                ehci_dump_sqtd(sqtd);
-               usb_syncmem(&sqtd->dma,
+               usb_mem_sync(um, &sqtd->dma,
                    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);
-               usb_syncmem(&sqtd->dma,
+               usb_mem_sync(um, &sqtd->dma,
                    sqtd->offs + offsetof(ehci_qtd_t, qtd_next),
                    sizeof(sqtd->qtd), BUS_DMASYNC_PREREAD);
        }
@@ -1361,11 +1373,13 @@ ehci_dump_sqtds(ehci_soft_qtd_t *sqtd)
 void
 ehci_dump_sqtd(ehci_soft_qtd_t *sqtd)
 {
-       usb_syncmem(&sqtd->dma, sqtd->offs, 
+       struct usb_mem *um = sqtd->xfer->device->bus->umem;
+
+       usb_mem_sync(um, &sqtd->dma, sqtd->offs,
            sizeof(sqtd->qtd), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
        printf("QTD(%p) at 0x%08x:\n", sqtd, sqtd->physaddr);
        ehci_dump_qtd(&sqtd->qtd);
-       usb_syncmem(&sqtd->dma, sqtd->offs, 
+       usb_mem_sync(um, &sqtd->dma, sqtd->offs,
            sizeof(sqtd->qtd), BUS_DMASYNC_PREREAD);
 }
 
@@ -1392,12 +1406,13 @@ ehci_dump_qtd(ehci_qtd_t *qtd)
 }
 
 void
-ehci_dump_sqh(ehci_soft_qh_t *sqh)
+ehci_dump_sqh(ehci_softc_t *sc, ehci_soft_qh_t *sqh)
 {
        ehci_qh_t *qh = &sqh->qh;
+       struct usb_mem *um = sc->sc_bus.umem;
        u_int32_t endp, endphub;
 
-       usb_syncmem(&sqh->dma, sqh->offs,
+       usb_mem_sync(um, &sqh->dma, sqh->offs,
            sizeof(sqh->qh), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
        printf("QH(%p) at 0x%08x:\n", sqh, sqh->physaddr);
        printf("  link="); ehci_dump_link(qh->qh_link, 1); printf("\n");
@@ -1419,7 +1434,7 @@ ehci_dump_sqh(ehci_soft_qh_t *sqh)
        printf("  curqtd="); ehci_dump_link(qh->qh_curqtd, 0); printf("\n");
        printf("Overlay qTD:\n");
        ehci_dump_qtd(&qh->qh_qtd);
-       usb_syncmem(&sqh->dma, sqh->offs,
+       usb_mem_sync(um, &sqh->dma, sqh->offs,
            sizeof(sqh->qh), BUS_DMASYNC_PREREAD);
 }
 
@@ -1479,6 +1494,7 @@ ehci_open(usbd_pipe_handle pipe)
        usbd_device_handle dev = pipe->device;
        ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
        usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
+       struct usb_mem *um = sc->sc_bus.umem;
        u_int8_t addr = dev->address;
        u_int8_t xfertype = ed->bmAttributes & UE_XFERTYPE;
        struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
@@ -1573,7 +1589,7 @@ ehci_open(usbd_pipe_handle pipe)
                sqh->qh.qh_qtd.qtd_status =
                    htole32(EHCI_QTD_SET_TOGGLE(pipe->endpoint->savedtoggle));
 
-               usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
+               usb_mem_sync(um, &sqh->dma, sqh->offs, sizeof(sqh->qh),
                    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
                epipe->sqh = sqh;
        } else {
@@ -1582,23 +1598,23 @@ ehci_open(usbd_pipe_handle pipe)
 
        switch (xfertype) {
        case UE_CONTROL:
-               err = usb_allocmem(&sc->sc_bus, sizeof(usb_device_request_t),
-                   0, &epipe->u.ctl.reqdma);
+               err = usb_mem_alloc(um, &sc->sc_bus,
+                   sizeof(usb_device_request_t), 0, &epipe->u.ctl.reqdma);
 #ifdef EHCI_DEBUG
                if (err)
-                       printf("ehci_open: usb_allocmem()=%d\n", err);
+                       printf("ehci_open: usb_mem_alloc()=%d\n", err);
 #endif
                if (err)
                        goto bad;
                pipe->methods = &ehci_device_ctrl_methods;
                s = splusb();
-               ehci_add_qh(sqh, sc->sc_async_head);
+               ehci_add_qh(sc, sqh, sc->sc_async_head);
                splx(s);
                break;
        case UE_BULK:
                pipe->methods = &ehci_device_bulk_methods;
                s = splusb();
-               ehci_add_qh(sqh, sc->sc_async_head);
+               ehci_add_qh(sc, sqh, sc->sc_async_head);
                splx(s);
                break;
        case UE_INTERRUPT:
@@ -1643,28 +1659,30 @@ bad:
  * If in the intr schedule it may not.
  */
 void
-ehci_add_qh(ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
+ehci_add_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
 {
+       struct usb_mem *um = sc->sc_bus.umem;
+
        SPLUSBCHECK;
 
-       usb_syncmem(&head->dma, head->offs + offsetof(ehci_qh_t, qh_link),
+       usb_mem_sync(um, &head->dma, head->offs + offsetof(ehci_qh_t, qh_link),
            sizeof(head->qh.qh_link), BUS_DMASYNC_POSTWRITE);
        sqh->next = head->next;
        sqh->prev = head;
        sqh->qh.qh_link = head->qh.qh_link;
-       usb_syncmem(&sqh->dma, sqh->offs + offsetof(ehci_qh_t, qh_link),
+       usb_mem_sync(um, &sqh->dma, sqh->offs + offsetof(ehci_qh_t, qh_link),
            sizeof(sqh->qh.qh_link), BUS_DMASYNC_PREWRITE);
        head->next = sqh;
        if (sqh->next)
                sqh->next->prev = sqh;
        head->qh.qh_link = htole32(sqh->physaddr | EHCI_LINK_QH);
-       usb_syncmem(&head->dma, head->offs + offsetof(ehci_qh_t, qh_link),
+       usb_mem_sync(um, &head->dma, head->offs + offsetof(ehci_qh_t, qh_link),
            sizeof(head->qh.qh_link), BUS_DMASYNC_PREWRITE);
 
 #ifdef EHCI_DEBUG
        if (ehcidebug > 5) {
                printf("ehci_add_qh:\n");
-               ehci_dump_sqh(sqh);
+               ehci_dump_sqh(sc, sqh);
        }
 #endif
 }
@@ -1676,15 +1694,17 @@ ehci_add_qh(ehci_soft_qh_t *sqh, ehci_so
 void
 ehci_rem_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
 {
+       struct usb_mem *um = sc->sc_bus.umem;
+
        SPLUSBCHECK;
        /* XXX */
-       usb_syncmem(&sqh->dma, sqh->offs + offsetof(ehci_qh_t, qh_link),
+       usb_mem_sync(um, &sqh->dma, sqh->offs + offsetof(ehci_qh_t, qh_link),
            sizeof(sqh->qh.qh_link), BUS_DMASYNC_POSTWRITE);
        sqh->prev->qh.qh_link = sqh->qh.qh_link;
        sqh->prev->next = sqh->next;
        if (sqh->next)
                sqh->next->prev = sqh->prev;
-       usb_syncmem(&sqh->prev->dma,
+       usb_mem_sync(um, &sqh->prev->dma,
            sqh->prev->offs + offsetof(ehci_qh_t, qh_link),
            sizeof(sqh->prev->qh.qh_link), BUS_DMASYNC_PREWRITE);
 
@@ -1692,13 +1712,14 @@ ehci_rem_qh(ehci_softc_t *sc, ehci_soft_
 }
 
 void
-ehci_set_qh_qtd(ehci_soft_qh_t *sqh, ehci_soft_qtd_t *sqtd)
+ehci_set_qh_qtd(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qtd_t *sqtd)
 {
+       struct usb_mem *um = sc->sc_bus.umem;
        int i;
        u_int32_t status;
 
        /* Save toggle bit and ping status. */
-       usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
+       usb_mem_sync(um, &sqh->dma, sqh->offs, sizeof(sqh->qh),
            BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
        status = sqh->qh.qh_qtd.qtd_status &
            htole32(EHCI_QTD_TOGGLE_MASK |
@@ -1706,7 +1727,7 @@ ehci_set_qh_qtd(ehci_soft_qh_t *sqh, ehc
        /* Set HALTED to make hw leave it alone. */
        sqh->qh.qh_qtd.qtd_status =
            htole32(EHCI_QTD_SET_STATUS(EHCI_QTD_HALTED));
-       usb_syncmem(&sqh->dma,
+       usb_mem_sync(um, &sqh->dma,
            sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status),
            sizeof(sqh->qh.qh_qtd.qtd_status),
            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
@@ -1716,11 +1737,11 @@ ehci_set_qh_qtd(ehci_soft_qh_t *sqh, ehc
        for (i = 0; i < EHCI_QTD_NBUFFERS; i++)
                sqh->qh.qh_qtd.qtd_buffer[i] = 0;
        sqh->sqtd = sqtd;
-       usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
+       usb_mem_sync(um, &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;
-       usb_syncmem(&sqh->dma,
+       usb_mem_sync(um, &sqh->dma,
            sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status),
            sizeof(sqh->qh.qh_qtd.qtd_status),
            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
@@ -1772,6 +1793,7 @@ void
 ehci_rem_free_itd_chain(ehci_softc_t *sc, struct ehci_xfer *exfer)
 {
        struct ehci_soft_itd *itd, *prev;
+       struct usb_mem *um = sc->sc_bus.umem;
 
        prev = NULL;
 
@@ -1784,7 +1806,7 @@ ehci_rem_free_itd_chain(ehci_softc_t *sc
                if (prev == NULL) { /* We're at the table head */
                        sc->sc_softitds[itd->slot] = itd->u.frame_list.next;
                        sc->sc_flist[itd->slot] = itd->itd.itd_next;
-                       usb_syncmem(&sc->sc_fldma,
+                       usb_mem_sync(um, &sc->sc_fldma,
                            sizeof(ehci_link_t) * itd->slot,
                            sizeof(ehci_link_t),
                            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
@@ -1795,7 +1817,7 @@ ehci_rem_free_itd_chain(ehci_softc_t *sc
                } else {
                        /* XXX this part is untested... */
                        prev->itd.itd_next = itd->itd.itd_next;
-                       usb_syncmem(&itd->dma,
+                       usb_mem_sync(um, &itd->dma,
                            itd->offs + offsetof(ehci_itd_t, itd_next),
                            sizeof(itd->itd.itd_next), BUS_DMASYNC_PREWRITE);
 
@@ -2410,11 +2432,11 @@ ehci_alloc_sqh(ehci_softc_t *sc)
 
        if (sc->sc_freeqhs == NULL) {
                DPRINTFN(2, ("ehci_alloc_sqh: allocating chunk\n"));
-               err = usb_allocmem(&sc->sc_bus, EHCI_SQH_SIZE * EHCI_SQH_CHUNK,
-                   EHCI_PAGE_SIZE, &dma);
+               err = usb_mem_alloc(sc->sc_bus.umem, &sc->sc_bus,
+                   EHCI_SQH_SIZE * EHCI_SQH_CHUNK, EHCI_PAGE_SIZE, &dma);
 #ifdef EHCI_DEBUG
                if (err)
-                       printf("ehci_alloc_sqh: usb_allocmem()=%d\n", err);
+                       printf("ehci_alloc_sqh: usb_mem_alloc()=%d\n", err);
 #endif
                if (err)
                        return (NULL);
@@ -2454,11 +2476,11 @@ ehci_alloc_sqtd(ehci_softc_t *sc)
 
        if (sc->sc_freeqtds == NULL) {
                DPRINTFN(2, ("ehci_alloc_sqtd: allocating chunk\n"));
-               err = usb_allocmem(&sc->sc_bus, EHCI_SQTD_SIZE*EHCI_SQTD_CHUNK,
-                   EHCI_PAGE_SIZE, &dma);
+               err = usb_mem_alloc(sc->sc_bus.umem, &sc->sc_bus,
+                   EHCI_SQTD_SIZE*EHCI_SQTD_CHUNK, EHCI_PAGE_SIZE, &dma);
 #ifdef EHCI_DEBUG
                if (err)
-                       printf("ehci_alloc_sqtd: usb_allocmem()=%d\n", err);
+                       printf("ehci_alloc_sqtd: usb_mem_alloc()=%d\n", err);
 #endif
                if (err)
                        return (NULL);
@@ -2502,6 +2524,7 @@ ehci_alloc_sqtd_chain(struct ehci_pipe *
     int rd, usbd_xfer_handle xfer, ehci_soft_qtd_t **sp, ehci_soft_qtd_t **ep)
 {
        ehci_soft_qtd_t *next, *cur;
+       struct usb_mem *um = sc->sc_bus.umem;
        ehci_physaddr_t dataphys, dataphyspage, dataphyslastpage, nextphys;
        u_int32_t qtdstatus;
        u_int len, curlen;
@@ -2534,7 +2557,7 @@ ehci_alloc_sqtd_chain(struct ehci_pipe *
        if (cur == NULL)
                goto nomem;
 
-       usb_syncmem(dma, 0, alen,
+       usb_mem_sync(um, dma, 0, alen,
            rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
        for (;;) {
                dataphyspage = EHCI_PAGE(dataphys);
@@ -2623,14 +2646,14 @@ ehci_alloc_sqtd_chain(struct ehci_pipe *
                                break;
                        forceshort = 0;
                }
-               usb_syncmem(&cur->dma, cur->offs, sizeof(cur->qtd),
+               usb_mem_sync(um, &cur->dma, cur->offs, sizeof(cur->qtd),
                    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
                DPRINTFN(10,("ehci_alloc_sqtd_chain: extend chain\n"));
                dataphys += curlen;
                cur = next;
        }
        cur->qtd.qtd_status |= htole32(EHCI_QTD_IOC);
-       usb_syncmem(&cur->dma, cur->offs, sizeof(cur->qtd),
+       usb_mem_sync(um, &cur->dma, cur->offs, sizeof(cur->qtd),
            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
        *ep = cur;
 
@@ -2665,6 +2688,7 @@ ehci_soft_itd_t *
 ehci_alloc_itd(ehci_softc_t *sc)
 {
        struct ehci_soft_itd *itd, *freeitd;
+       struct usb_mem *um = sc->sc_bus.umem;
        usbd_status err;
        int i, s, offs, frindex, previndex;
        usb_dma_t dma;
@@ -2690,8 +2714,8 @@ ehci_alloc_itd(ehci_softc_t *sc)
 
        if (freeitd == NULL) {
                DPRINTFN(2, ("ehci_alloc_itd allocating chunk\n"));
-               err = usb_allocmem(&sc->sc_bus, EHCI_ITD_SIZE * EHCI_ITD_CHUNK,
-                   EHCI_PAGE_SIZE, &dma);
+               err = usb_mem_alloc(um, &sc->sc_bus,
+                   EHCI_ITD_SIZE * EHCI_ITD_CHUNK, EHCI_PAGE_SIZE, &dma);
 
                if (err) {
                        DPRINTF(("ehci_alloc_itd, alloc returned %d\n", err));
@@ -2712,7 +2736,7 @@ ehci_alloc_itd(ehci_softc_t *sc)
        itd = freeitd;
        LIST_REMOVE(itd, u.free_list);
        memset(&itd->itd, 0, sizeof(ehci_itd_t));
-       usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_next),
+       usb_mem_sync(um, &itd->dma, itd->offs + offsetof(ehci_itd_t, itd_next),
            sizeof(itd->itd.itd_next), BUS_DMASYNC_PREWRITE |
            BUS_DMASYNC_PREREAD);
 
@@ -2775,6 +2799,7 @@ ehci_abort_xfer(usbd_xfer_handle xfer, u
        ehci_softc_t *sc = (ehci_softc_t *)epipe->pipe.device->bus;
        ehci_soft_qh_t *sqh = epipe->sqh;
        ehci_soft_qtd_t *sqtd, *snext, **psqtd;
+       struct usb_mem *um = sc->sc_bus.umem;
        ehci_physaddr_t cur, us, next;
        int s;
        int hit;
@@ -2841,12 +2866,12 @@ ehci_abort_xfer(usbd_xfer_handle xfer, u
         * behaves correctly when we deactivate them afterwards.
         */
        for (sqtd = exfer->sqtdstart; ; sqtd = sqtd->nextqtd) {
-               usb_syncmem(&sqtd->dma,
+               usb_mem_sync(um, &sqtd->dma,
                    sqtd->offs + offsetof(ehci_qtd_t, qtd_status),
                    sizeof(sqtd->qtd.qtd_status),
                    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
                sqtd->qtd.qtd_status = htole32(EHCI_QTD_HALTED);
-               usb_syncmem(&sqtd->dma,
+               usb_mem_sync(um, &sqtd->dma,
                    sqtd->offs + offsetof(ehci_qtd_t, qtd_status),
                    sizeof(sqtd->qtd.qtd_status),
                    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
@@ -2881,7 +2906,7 @@ ehci_abort_xfer(usbd_xfer_handle xfer, u
         * the aborting xfer.  (If there is something past us).
         * Hardware and software.
         */
-       usb_syncmem(&sqh->dma,
+       usb_mem_sync(um, &sqh->dma,
            sqh->offs + offsetof(ehci_qh_t, qh_curqtd),
            sizeof(sqh->qh.qh_curqtd),
            BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
@@ -2939,7 +2964,7 @@ ehci_abort_xfer(usbd_xfer_handle xfer, u
                 */
                if (hit) {
                        if (snext) {
-                               ehci_set_qh_qtd(sqh, snext);
+                               ehci_set_qh_qtd(sc, sqh, snext);
                        } else {
 
                                sqh->qh.qh_curqtd = 0; /* unlink qTDs */
@@ -2950,7 +2975,7 @@ ehci_abort_xfer(usbd_xfer_handle xfer, u
                        }
                }
        }
-       ehci_add_qh(sqh, psqh);
+       ehci_add_qh(sc, sqh, psqh);
 
        /*
         * Step 6: Execute callback.
@@ -3196,6 +3221,7 @@ ehci_device_request(usbd_xfer_handle xfe
        usb_device_request_t *req = &xfer->request;
        usbd_device_handle dev = epipe->pipe.device;
        ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
+       struct usb_mem *um = sc->sc_bus.umem;
        int addr = dev->address;
        ehci_soft_qtd_t *setup, *stat, *next;
        ehci_soft_qh_t *sqh;
@@ -3250,14 +3276,14 @@ ehci_device_request(usbd_xfer_handle xfe
                end->nextqtd = stat;
                end->qtd.qtd_next =
                    end->qtd.qtd_altnext = htole32(stat->physaddr);
-               usb_syncmem(&end->dma, end->offs, sizeof(end->qtd),
+               usb_mem_sync(um, &end->dma, end->offs, sizeof(end->qtd),
                    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
        } else {
                next = stat;
        }
 
        memcpy(KERNADDR(&epipe->u.ctl.reqdma, 0), req, sizeof(*req));
-       usb_syncmem(&epipe->u.ctl.reqdma, 0, sizeof *req, BUS_DMASYNC_PREWRITE);
+       usb_mem_sync(um, &epipe->u.ctl.reqdma, 0, sizeof *req, 
BUS_DMASYNC_PREWRITE);
 
        /* Clear toggle */
        setup->qtd.qtd_status = htole32(
@@ -3272,7 +3298,7 @@ ehci_device_request(usbd_xfer_handle xfe
        setup->qtd.qtd_next = setup->qtd.qtd_altnext = htole32(next->physaddr);
        setup->xfer = xfer;
        setup->len = sizeof(*req);
-       usb_syncmem(&setup->dma, setup->offs, sizeof(setup->qtd),
+       usb_mem_sync(um, &setup->dma, setup->offs, sizeof(setup->qtd),
            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 
        stat->qtd.qtd_status = htole32(
@@ -3287,13 +3313,13 @@ ehci_device_request(usbd_xfer_handle xfe
        stat->qtd.qtd_next = stat->qtd.qtd_altnext = EHCI_NULL;
        stat->xfer = xfer;
        stat->len = 0;
-       usb_syncmem(&stat->dma, stat->offs, sizeof(stat->qtd),
+       usb_mem_sync(um, &stat->dma, stat->offs, sizeof(stat->qtd),
            BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 
 #ifdef EHCI_DEBUG
        if (ehcidebug > 5) {
                DPRINTF(("ehci_device_request:\n"));
-               ehci_dump_sqh(sqh);
+               ehci_dump_sqh(sc, sqh);
                ehci_dump_sqtds(setup);
        }
 #endif
@@ -3309,7 +3335,7 @@ ehci_device_request(usbd_xfer_handle xfe
 
        /* Insert qTD in QH list. */
        s = splusb();
-       ehci_set_qh_qtd(sqh, setup);
+       ehci_set_qh_qtd(sc, sqh, setup);
        if (xfer->timeout && !sc->sc_bus.use_polling) {
                timeout_del(&xfer->timeout_handle);
                timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
@@ -3325,8 +3351,8 @@ ehci_device_request(usbd_xfer_handle xfe
                    EOREAD4(sc, EHCI_USBSTS)));
                delay(10000);
                ehci_dump_regs(sc);
-               ehci_dump_sqh(sc->sc_async_head);
-               ehci_dump_sqh(sqh);
+               ehci_dump_sqh(sc, sc->sc_async_head);
+               ehci_dump_sqh(sc, sqh);
                ehci_dump_sqtds(setup);
        }
 #endif
@@ -3405,7 +3431,7 @@ ehci_device_bulk_start(usbd_xfer_handle 
 #ifdef EHCI_DEBUG
        if (ehcidebug > 5) {
                DPRINTF(("ehci_device_bulk_start: data(1)\n"));
-               ehci_dump_sqh(sqh);
+               ehci_dump_sqh(sc, sqh);
                ehci_dump_sqtds(data);
        }
 #endif
@@ -3421,7 +3447,7 @@ ehci_device_bulk_start(usbd_xfer_handle 
 #endif
 
        s = splusb();
-       ehci_set_qh_qtd(sqh, data);
+       ehci_set_qh_qtd(sc, sqh, data);
        if (xfer->timeout && !sc->sc_bus.use_polling) {
                timeout_del(&xfer->timeout_handle);
                timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
@@ -3439,10 +3465,10 @@ ehci_device_bulk_start(usbd_xfer_handle 
                ehci_dump_regs(sc);
 #if 0
                printf("async_head:\n");
-               ehci_dump_sqh(sc->sc_async_head);
+               ehci_dump_sqh(sc, sc->sc_async_head);
 #endif
                printf("sqh:\n");
-               ehci_dump_sqh(sqh);
+               ehci_dump_sqh(sc, sqh);
                ehci_dump_sqtds(data);
        }
 #endif
@@ -3488,7 +3514,7 @@ ehci_device_bulk_done(usbd_xfer_handle x
        if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) {
                ehci_del_intr_list(sc, ex);     /* remove from active list */
                ehci_free_sqtd_chain(sc, ex->sqtdstart, NULL);
-               usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+               usb_mem_sync(sc->sc_bus.umem, &xfer->dmabuf, 0, xfer->length,
                    rd ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
        }
 
@@ -3519,7 +3545,7 @@ ehci_device_setintr(ehci_softc_t *sc, eh
 
        sqh->islot = islot;
        isp = &sc->sc_islots[islot];
-       ehci_add_qh(sqh, isp->sqh);
+       ehci_add_qh(sc, sqh, isp->sqh);
 
        return (USBD_NORMAL_COMPLETION);
 }
@@ -3585,7 +3611,7 @@ ehci_device_intr_start(usbd_xfer_handle 
 #ifdef EHCI_DEBUG
        if (ehcidebug > 5) {
                DPRINTF(("ehci_device_intr_start: data(1)\n"));
-               ehci_dump_sqh(sqh);
+               ehci_dump_sqh(sc, sqh);
                ehci_dump_sqtds(data);
        }
 #endif
@@ -3600,7 +3626,7 @@ ehci_device_intr_start(usbd_xfer_handle 
 #endif
 
        s = splusb();
-       ehci_set_qh_qtd(sqh, data);
+       ehci_set_qh_qtd(sc, sqh, data);
        if (xfer->timeout && !sc->sc_bus.use_polling) {
                timeout_del(&xfer->timeout_handle);
                timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
@@ -3617,7 +3643,7 @@ ehci_device_intr_start(usbd_xfer_handle 
                DPRINTF(("ehci_device_intr_start: data(3)\n"));
                ehci_dump_regs(sc);
                printf("sqh:\n");
-               ehci_dump_sqh(sqh);
+               ehci_dump_sqh(sc, sqh);
                ehci_dump_sqtds(data);
        }
 #endif
@@ -3665,6 +3691,7 @@ ehci_device_intr_done(usbd_xfer_handle x
        struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
        ehci_soft_qtd_t *data, *dataend;
        ehci_soft_qh_t *sqh;
+       struct usb_mem *um = sc->sc_bus.umem;
        usbd_status err;
        u_int len;
        int isread, endpt, s;
@@ -3679,7 +3706,7 @@ ehci_device_intr_done(usbd_xfer_handle x
                xfer->length = len;
                endpt = epipe->pipe.endpoint->edesc->bEndpointAddress;
                isread = UE_GET_DIR(endpt) == UE_DIR_IN;
-               usb_syncmem(&xfer->dmabuf, 0, len,
+               usb_mem_sync(um, &xfer->dmabuf, 0, len,
                    isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
                sqh = epipe->sqh;
 
@@ -3703,7 +3730,7 @@ ehci_device_intr_done(usbd_xfer_handle x
 #endif
 
                s = splusb();
-               ehci_set_qh_qtd(sqh, data);
+               ehci_set_qh_qtd(sc, sqh, data);
                if (xfer->timeout && !sc->sc_bus.use_polling) {
                        timeout_del(&xfer->timeout_handle);
                        timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
@@ -3717,7 +3744,7 @@ ehci_device_intr_done(usbd_xfer_handle x
                ehci_free_sqtd_chain(sc, ex->sqtdstart, NULL);
                endpt = epipe->pipe.endpoint->edesc->bEndpointAddress;
                isread = UE_GET_DIR(endpt) == UE_DIR_IN;
-               usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+               usb_mem_sync(um, &xfer->dmabuf, 0, xfer->length,
                    isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
        }
 #undef exfer
Index: dev//usb/ohci.c
===================================================================
RCS file: /home/vcs/cvs/openbsd/src/sys/dev/usb/ohci.c,v
retrieving revision 1.105
diff -u -p -r1.105 ohci.c
--- dev//usb/ohci.c     18 Sep 2011 18:29:20 -0000      1.105
+++ dev//usb/ohci.c     13 Mar 2012 22:34:35 -0000
@@ -427,8 +427,8 @@ ohci_alloc_sed(ohci_softc_t *sc)
 
        if (sc->sc_freeeds == NULL) {
                DPRINTFN(2, ("ohci_alloc_sed: allocating chunk\n"));
-               err = usb_allocmem(&sc->sc_bus, OHCI_SED_SIZE * OHCI_SED_CHUNK,
-                         OHCI_ED_ALIGN, &dma);
+               err = usb_mem_alloc(sc->sc_bus.umem, &sc->sc_bus,
+                   OHCI_SED_SIZE * OHCI_SED_CHUNK, OHCI_ED_ALIGN, &dma);
                if (err)
                        return (0);
                for(i = 0; i < OHCI_SED_CHUNK; i++) {
@@ -464,8 +464,8 @@ ohci_alloc_std(ohci_softc_t *sc)
 
        if (sc->sc_freetds == NULL) {
                DPRINTFN(2, ("ohci_alloc_std: allocating chunk\n"));
-               err = usb_allocmem(&sc->sc_bus, OHCI_STD_SIZE * OHCI_STD_CHUNK,
-                         OHCI_TD_ALIGN, &dma);
+               err = usb_mem_alloc(sc->sc_bus.umem, &sc->sc_bus,
+                   OHCI_STD_SIZE * OHCI_STD_CHUNK, OHCI_TD_ALIGN, &dma);
                if (err)
                        return (NULL);
                s = splusb();
@@ -621,8 +621,8 @@ ohci_alloc_sitd(ohci_softc_t *sc)
 
        if (sc->sc_freeitds == NULL) {
                DPRINTFN(2, ("ohci_alloc_sitd: allocating chunk\n"));
-               err = usb_allocmem(&sc->sc_bus, OHCI_SITD_SIZE * 
OHCI_SITD_CHUNK,
-                         OHCI_ITD_ALIGN, &dma);
+               err = usb_mem_alloc(sc->sc_bus.umem, &sc->sc_bus,
+                   OHCI_SITD_SIZE * OHCI_SITD_CHUNK, OHCI_ITD_ALIGN, &dma);
                if (err)
                        return (NULL);
                s = splusb();
@@ -742,9 +742,10 @@ ohci_init(ohci_softc_t *sc)
 
        SIMPLEQ_INIT(&sc->sc_free_xfers);
 
+       usb_mem_init(&sc->sc_bus.umem, 0);
        /* XXX determine alignment by R/W */
        /* Allocate the HCCA area. */
-       err = usb_allocmem(&sc->sc_bus, OHCI_HCCA_SIZE,
+       err = usb_mem_alloc(sc->sc_bus.umem, &sc->sc_bus, OHCI_HCCA_SIZE,
                         OHCI_HCCA_ALIGN, &sc->sc_hccadma);
        if (err)
                return (err);
@@ -946,7 +947,7 @@ ohci_init(ohci_softc_t *sc)
  bad2:
        ohci_free_sed(sc, sc->sc_ctrl_head);
  bad1:
-       usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
+       usb_mem_free(sc->sc_bus.umem, &sc->sc_bus, &sc->sc_hccadma);
        return (err);
 }
 
@@ -955,7 +956,7 @@ ohci_allocm(struct usbd_bus *bus, usb_dm
 {
        struct ohci_softc *sc = (struct ohci_softc *)bus;
 
-       return (usb_allocmem(&sc->sc_bus, size, 0, dma));
+       return (usb_mem_alloc(sc->sc_bus.umem, &sc->sc_bus, size, 0, dma));
 }
 
 void
@@ -963,7 +964,7 @@ ohci_freem(struct usbd_bus *bus, usb_dma
 {
        struct ohci_softc *sc = (struct ohci_softc *)bus;
 
-       usb_freemem(&sc->sc_bus, dma);
+       usb_mem_free(sc->sc_bus.umem, &sc->sc_bus, dma);
 }
 
 usbd_xfer_handle
@@ -2069,7 +2070,7 @@ ohci_open(usbd_pipe_handle pipe)
                switch (xfertype) {
                case UE_CONTROL:
                        pipe->methods = &ohci_device_ctrl_methods;
-                       err = usb_allocmem(&sc->sc_bus,
+                       err = usb_mem_alloc(sc->sc_bus.umem, &sc->sc_bus,
                                  sizeof(usb_device_request_t),
                                  0, &opipe->u.ctl.reqdma);
                        if (err)
Index: dev//usb/uhci.c
===================================================================
RCS file: /home/vcs/cvs/openbsd/src/sys/dev/usb/uhci.c,v
retrieving revision 1.90
diff -u -p -r1.90 uhci.c
--- dev//usb/uhci.c     3 Jul 2011 15:47:17 -0000       1.90
+++ dev//usb/uhci.c     13 Mar 2012 22:34:35 -0000
@@ -404,7 +404,8 @@ uhci_init(uhci_softc_t *sc)
        UWRITE1(sc, UHCI_SOF, sc->sc_saved_sof);
 
        /* Allocate and initialize real frame array. */
-       err = usb_allocmem(&sc->sc_bus,
+       usb_mem_init(&sc->sc_bus.umem, 0);
+       err = usb_mem_alloc(sc->sc_bus.umem, &sc->sc_bus,
                  UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t),
                  UHCI_FRAMELIST_ALIGN, &sc->sc_dma);
        if (err)
@@ -655,13 +656,15 @@ uhci_allocm(struct usbd_bus *bus, usb_dm
                free(stds, M_TEMP);
        }
 
-       return (usb_allocmem(&sc->sc_bus, size, 0, dma));
+       return (usb_mem_alloc(sc->sc_bus.umem, &sc->sc_bus, size, 0, dma));
 }
 
 void
 uhci_freem(struct usbd_bus *bus, usb_dma_t *dma)
 {
-       usb_freemem(&((struct uhci_softc *)bus)->sc_bus, dma);
+       struct uhci_softc * sc = (struct uhci_softc *)bus;
+
+       usb_mem_free(sc->sc_bus.umem, &sc->sc_bus, dma);
 }
 
 usbd_xfer_handle
@@ -1588,8 +1591,8 @@ uhci_alloc_std(uhci_softc_t *sc)
 
        if (sc->sc_freetds == NULL) {
                DPRINTFN(2,("uhci_alloc_std: allocating chunk\n"));
-               err = usb_allocmem(&sc->sc_bus, UHCI_STD_SIZE * UHCI_STD_CHUNK,
-                         UHCI_TD_ALIGN, &dma);
+               err = usb_mem_alloc(sc->sc_bus.umem, &sc->sc_bus,
+                   UHCI_STD_SIZE * UHCI_STD_CHUNK, UHCI_TD_ALIGN, &dma);
                if (err)
                        return (0);
                for(i = 0; i < UHCI_STD_CHUNK; i++) {
@@ -1631,8 +1634,8 @@ uhci_alloc_sqh(uhci_softc_t *sc)
 
        if (sc->sc_freeqhs == NULL) {
                DPRINTFN(2, ("uhci_alloc_sqh: allocating chunk\n"));
-               err = usb_allocmem(&sc->sc_bus, UHCI_SQH_SIZE * UHCI_SQH_CHUNK,
-                         UHCI_QH_ALIGN, &dma);
+               err = usb_mem_alloc(sc->sc_bus.umem, &sc->sc_bus,
+                   UHCI_SQH_SIZE * UHCI_SQH_CHUNK, UHCI_QH_ALIGN, &dma);
                if (err)
                        return (0);
                for(i = 0; i < UHCI_SQH_CHUNK; i++) {
@@ -2857,7 +2860,7 @@ uhci_open(usbd_pipe_handle pipe)
                                uhci_free_std(sc, upipe->u.ctl.setup);
                                goto bad;
                        }
-                       err = usb_allocmem(&sc->sc_bus,
+                       err = usb_mem_alloc(sc->sc_bus.umem, &sc->sc_bus,
                                  sizeof(usb_device_request_t),
                                  0, &upipe->u.ctl.reqdma);
                        if (err) {
Index: dev//usb/usb_mem.c
===================================================================
RCS file: /home/vcs/cvs/openbsd/src/sys/dev/usb/usb_mem.c,v
retrieving revision 1.23
diff -u -p -r1.23 usb_mem.c
--- dev//usb/usb_mem.c  5 Apr 2011 19:54:35 -0000       1.23
+++ dev//usb/usb_mem.c  13 Mar 2012 22:34:35 -0000
@@ -76,44 +76,65 @@ struct usb_frag_dma {
        LIST_ENTRY(usb_frag_dma) next;
 };
 
-usbd_status    usb_block_allocmem(bus_dma_tag_t, size_t, size_t,
-                                          usb_dma_block_t **);
-void           usb_block_freemem(usb_dma_block_t *);
-
-LIST_HEAD(, usb_dma_block) usb_blk_freelist =
-       LIST_HEAD_INITIALIZER(usb_blk_freelist);
-int usb_blk_nfree = 0;
+struct usb_mem {
 /* XXX should have different free list for different tags (for speed) */
-LIST_HEAD(, usb_frag_dma) usb_frag_freelist =
-       LIST_HEAD_INITIALIZER(usb_frag_freelist);
+       LIST_HEAD(, usb_dma_block) um_blk_freelist;
+       LIST_HEAD(, usb_frag_dma) um_frag_freelist;
+       bus_size_t um_boundary;
+       int um_blk_nfree;
+};
+
+/* Internal */
+usbd_status usb_mem_block_alloc(struct usb_mem *, bus_dma_tag_t, size_t,
+    size_t, usb_dma_block_t **);
+void usb_mem_block_free(struct usb_mem *, usb_dma_block_t *);
+
+void
+usb_mem_init(struct usb_mem **um, bus_size_t boundary)
+{
+       *um = malloc(sizeof(struct usb_mem), M_USB, M_WAITOK|M_ZERO);
+
+       LIST_INIT(&(*um)->um_blk_freelist);
+       LIST_INIT(&(*um)->um_frag_freelist);
+       (*um)->um_boundary = boundary;
+       (*um)->um_blk_nfree = 0;
+}
+
+#if 0
+/* usb_block_real_freemem() needs to be implemented first */
+void
+usb_mem_destroy(struct usb_mem *um)
+{
+}
+#endif
 
 usbd_status
-usb_block_allocmem(bus_dma_tag_t tag, size_t size, size_t align,
-                  usb_dma_block_t **dmap)
+usb_mem_block_alloc(struct usb_mem *um, bus_dma_tag_t tag, size_t size,
+    size_t align, usb_dma_block_t **dmap)
 {
        int error;
         usb_dma_block_t *p;
        int s;
 
-       DPRINTFN(5, ("usb_block_allocmem: size=%lu align=%lu\n",
-                    (u_long)size, (u_long)align));
+       DPRINTFN(5, ("%s: size=%lu align=%lu\n", __func__,
+                   (u_long)size, (u_long)align));
 
 #ifdef DIAGNOSTIC
        if (!curproc) {
-               printf("usb_block_allocmem: in interrupt context, size=%lu\n",
+               printf("%s: in interrupt context, size=%lu\n",
                    (unsigned long) size);
        }
 #endif
 
        s = splusb();
        /* First check the free list. */
-       for (p = LIST_FIRST(&usb_blk_freelist); p; p = LIST_NEXT(p, next)) {
+       for (p = LIST_FIRST(&um->um_blk_freelist); p; p = LIST_NEXT(p, next)) {
                if (p->tag == tag && p->size >= size && p->align >= align) {
                        LIST_REMOVE(p, next);
-                       usb_blk_nfree--;
+                       um->um_blk_nfree--;
                        splx(s);
                        *dmap = p;
-                       DPRINTFN(6,("usb_block_allocmem: free list size=%lu\n",
+                       DPRINTFN(6,("%s: free list size=%lu\n", __func__,
                                    (u_long)p->size));
                        return (USBD_NORMAL_COMPLETION);
                }
@@ -122,12 +143,12 @@ usb_block_allocmem(bus_dma_tag_t tag, si
 
 #ifdef DIAGNOSTIC
        if (!curproc) {
-               printf("usb_block_allocmem: in interrupt context, failed\n");
+               printf("%s: in interrupt context, failed\n", __func__);
                return (USBD_NOMEM);
        }
 #endif
 
-       DPRINTFN(6, ("usb_block_allocmem: no free\n"));
+       DPRINTFN(6, ("%s: no free\n", __func__));
        p = malloc(sizeof *p, M_USB, M_NOWAIT);
        if (p == NULL)
                return (USBD_NOMEM);
@@ -135,7 +156,7 @@ usb_block_allocmem(bus_dma_tag_t tag, si
        p->tag = tag;
        p->size = size;
        p->align = align;
-       error = bus_dmamem_alloc(tag, p->size, align, 0,
+       error = bus_dmamem_alloc(tag, p->size, align, um->um_boundary,
                                 p->segs, nitems(p->segs),
                                 &p->nsegs, BUS_DMA_NOWAIT);
        if (error)
@@ -147,7 +168,7 @@ usb_block_allocmem(bus_dma_tag_t tag, si
                goto free1;
 
        error = bus_dmamap_create(tag, p->size, 1, p->size,
-                                 0, BUS_DMA_NOWAIT, &p->map);
+                                 um->um_boundary, BUS_DMA_NOWAIT, &p->map);
        if (error)
                goto unmap;
 
@@ -156,6 +177,8 @@ usb_block_allocmem(bus_dma_tag_t tag, si
        if (error)
                goto destroy;
 
+       DPRINTFN(6, ("%s: kaddr=%p phys=%p\n", __func__, p->kaddr,
+                   p->segs[0].ds_addr));
        *dmap = p;
        return (USBD_NORMAL_COMPLETION);
 
@@ -194,19 +217,20 @@ usb_block_real_freemem(usb_dma_block_t *
  * XXX when should we really free?
  */
 void
-usb_block_freemem(usb_dma_block_t *p)
+usb_mem_block_free(struct usb_mem *um, usb_dma_block_t *p)
 {
        int s;
 
-       DPRINTFN(6, ("usb_block_freemem: size=%lu\n", (u_long)p->size));
+       DPRINTFN(6, ("%s: size=%lu\n", __func__, (u_long)p->size));
        s = splusb();
-       LIST_INSERT_HEAD(&usb_blk_freelist, p, next);
-       usb_blk_nfree++;
+       LIST_INSERT_HEAD(&um->um_blk_freelist, p, next);
+       um->um_blk_nfree++;
        splx(s);
 }
 
 usbd_status
-usb_allocmem(usbd_bus_handle bus, size_t size, size_t align, usb_dma_t *p)
+usb_mem_alloc(struct usb_mem *um, usbd_bus_handle bus, size_t size,
+    size_t align, usb_dma_t *p)
 {
        bus_dma_tag_t tag = bus->dmatag;
        usbd_status err;
@@ -217,9 +241,9 @@ usb_allocmem(usbd_bus_handle bus, size_t
 
        /* If the request is large then just use a full block. */
        if (size > USB_MEM_SMALL || align > USB_MEM_SMALL) {
-               DPRINTFN(1, ("usb_allocmem: large alloc %d\n", (int)size));
+               DPRINTFN(1, ("%s: large alloc %d\n", __func__, (int)size));
                size = (size + USB_MEM_BLOCK - 1) & ~(USB_MEM_BLOCK - 1);
-               err = usb_block_allocmem(tag, size, align, &p->block);
+               err = usb_mem_block_alloc(um, tag, size, align, &p->block);
                if (!err) {
                        p->block->fullblock = 1;
                        p->offs = 0;
@@ -229,12 +253,13 @@ usb_allocmem(usbd_bus_handle bus, size_t
 
        s = splusb();
        /* Check for free fragments. */
-       for (f = LIST_FIRST(&usb_frag_freelist); f; f = LIST_NEXT(f, next))
+       for (f = LIST_FIRST(&um->um_frag_freelist); f; f = LIST_NEXT(f, next))
                if (f->block->tag == tag)
                        break;
        if (f == NULL) {
-               DPRINTFN(1, ("usb_allocmem: adding fragments\n"));
-               err = usb_block_allocmem(tag, USB_MEM_BLOCK, USB_MEM_SMALL,&b);
+               DPRINTFN(1, ("%s: adding fragments\n", __func__));
+               err = usb_mem_block_alloc(um, tag, USB_MEM_BLOCK,
+                   USB_MEM_SMALL, &b);
                if (err) {
                        splx(s);
                        return (err);
@@ -244,40 +269,41 @@ usb_allocmem(usbd_bus_handle bus, size_t
                        f = (struct usb_frag_dma *)(b->kaddr + i);
                        f->block = b;
                        f->offs = i;
-                       LIST_INSERT_HEAD(&usb_frag_freelist, f, next);
+                       LIST_INSERT_HEAD(&um->um_frag_freelist, f, next);
                }
-               f = LIST_FIRST(&usb_frag_freelist);
+               f = LIST_FIRST(&um->um_frag_freelist);
        }
        p->block = f->block;
        p->offs = f->offs;
        LIST_REMOVE(f, next);
        splx(s);
-       DPRINTFN(5, ("usb_allocmem: use frag=%p size=%d\n", f, (int)size));
+       DPRINTFN(5, ("%s: use frag=%p size=%d\n", __func__, f, (int)size));
        return (USBD_NORMAL_COMPLETION);
 }
 
 void
-usb_freemem(usbd_bus_handle bus, usb_dma_t *p)
+usb_mem_free(struct usb_mem *um, usbd_bus_handle bus, usb_dma_t *p)
 {
        struct usb_frag_dma *f;
        int s;
 
        if (p->block->fullblock) {
-               DPRINTFN(1, ("usb_freemem: large free\n"));
-               usb_block_freemem(p->block);
+               DPRINTFN(1, ("%s: large free\n", __func__));
+               usb_mem_block_free(um, p->block);
                return;
        }
        f = KERNADDR(p, 0);
        f->block = p->block;
        f->offs = p->offs;
        s = splusb();
-       LIST_INSERT_HEAD(&usb_frag_freelist, f, next);
+       LIST_INSERT_HEAD(&um->um_frag_freelist, f, next);
        splx(s);
-       DPRINTFN(5, ("usb_freemem: frag=%p\n", f));
+       DPRINTFN(5, ("%s: frag=%p\n", __func__, f));
 }
 
 void
-usb_syncmem(usb_dma_t *p, bus_addr_t offset, bus_size_t len, int ops)
+usb_mem_sync(struct usb_mem *um, usb_dma_t *p, bus_addr_t offset,
+    bus_size_t len, int ops)
 {
        bus_dmamap_sync(p->block->tag, p->block->map, p->offs + offset,
            len, ops);
Index: dev//usb/usb_mem.h
===================================================================
RCS file: /home/vcs/cvs/openbsd/src/sys/dev/usb/usb_mem.h,v
retrieving revision 1.13
diff -u -p -r1.13 usb_mem.h
--- dev//usb/usb_mem.h  29 Sep 2010 20:06:38 -0000      1.13
+++ dev//usb/usb_mem.h  13 Mar 2012 22:34:35 -0000
@@ -48,6 +48,9 @@ typedef struct usb_dma_block {
 #define KERNADDR(dma, o) \
        ((void *)((char *)((dma)->block->kaddr + (dma)->offs) + (o)))
 
-usbd_status    usb_allocmem(usbd_bus_handle,size_t,size_t, usb_dma_t *);
-void           usb_freemem(usbd_bus_handle, usb_dma_t *);
-void           usb_syncmem(usb_dma_t *, bus_addr_t, bus_size_t, int);
+void           usb_mem_init(struct usb_mem **, bus_size_t);
+usbd_status    usb_mem_alloc(struct usb_mem *, usbd_bus_handle, size_t,
+                       size_t, usb_dma_t *);
+void           usb_mem_free(struct usb_mem *, usbd_bus_handle, usb_dma_t *);
+void           usb_mem_sync(struct usb_mem *, usb_dma_t *, bus_addr_t,
+                       bus_size_t, int);
Index: dev//usb/usbdivar.h
===================================================================
RCS file: /home/vcs/cvs/openbsd/src/sys/dev/usb/usbdivar.h,v
retrieving revision 1.43
diff -u -p -r1.43 usbdivar.h
--- dev//usb/usbdivar.h 8 Jan 2012 13:12:38 -0000       1.43
+++ dev//usb/usbdivar.h 13 Mar 2012 22:34:35 -0000
@@ -120,6 +120,7 @@ struct usbd_bus {
 #define USBREV_STR { "unknown", "pre 1.0", "1.0", "1.1", "2.0" }
        void                   *soft; /* soft interrupt cookie */
        bus_dma_tag_t           dmatag; /* DMA tag */
+       struct usb_mem          *umem;          /* DMA memory pool */
 };
 
 struct usbd_device {

Reply via email to