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 {