diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2007-08-15 01:26:37 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2007-08-15 01:26:37 +0000 |
commit | 4d45c5178e9af23b72cb5bfb24642729b6fcbfb0 (patch) | |
tree | 38b755730618b23d70906766437b2e03491102b2 /sys/dev | |
parent | 8443623c5a6331ca6df46ea6d587e3373cc5cb8f (diff) |
pull my wrapper around single segment dma allocations in. its got to be at
least half a dozen drivers now that use this.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/if_nxe.c | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/sys/dev/pci/if_nxe.c b/sys/dev/pci/if_nxe.c index f1266fc2940..a7c0abd4a1c 100644 --- a/sys/dev/pci/if_nxe.c +++ b/sys/dev/pci/if_nxe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_nxe.c,v 1.20 2007/08/15 01:22:06 dlg Exp $ */ +/* $OpenBSD: if_nxe.c,v 1.21 2007/08/15 01:26:36 dlg Exp $ */ /* * Copyright (c) 2007 David Gwynne <dlg@openbsd.org> @@ -532,6 +532,17 @@ struct nxe_board { u_int brd_mode; }; +struct nxe_dmamem { + bus_dmamap_t ndm_map; + bus_dma_segment_t ndm_seg; + size_t ndm_size; + caddr_t ndm_kva; +}; +#define NXE_DMA_MAP(_ndm) ((_ndm)->ndm_map) +#define NXE_DMA_LEN(_ndm) ((_ndm)->ndm_size) +#define NXE_DMA_DVA(_ndm) ((_ndm)->ndm_map->dm_segs[0].ds_addr) +#define NXE_DMA_KVA(_ndm) ((void *)(_ndm)->ndm_kva) + /* * autoconf glue */ @@ -587,6 +598,12 @@ void nxe_pci_unmap(struct nxe_softc *); int nxe_board_info(struct nxe_softc *sc); int nxe_user_info(struct nxe_softc *sc); +/* wrapper around dmaable memory allocations */ +struct nxe_dmamem *nxe_dmamem_alloc(struct nxe_softc *, bus_size_t, + bus_size_t); +void nxe_dmamem_free(struct nxe_softc *, + struct nxe_dmamem *); + /* low level hardware access goo */ u_int32_t nxe_read(struct nxe_softc *, bus_size_t); void nxe_write(struct nxe_softc *, bus_size_t, u_int32_t); @@ -822,6 +839,57 @@ out: return (rv); } +struct nxe_dmamem * +nxe_dmamem_alloc(struct nxe_softc *sc, bus_size_t size, bus_size_t align) +{ + struct nxe_dmamem *ndm; + int nsegs; + + ndm = malloc(sizeof(struct nxe_dmamem), M_DEVBUF, M_WAITOK); + bzero(ndm, sizeof(struct nxe_dmamem)); + ndm->ndm_size = size; + + if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, + BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &ndm->ndm_map) != 0) + goto ndmfree; + + if (bus_dmamem_alloc(sc->sc_dmat, size, align, 0, &ndm->ndm_seg, 1, + &nsegs, BUS_DMA_WAITOK) != 0) + goto destroy; + + if (bus_dmamem_map(sc->sc_dmat, &ndm->ndm_seg, nsegs, size, + &ndm->ndm_kva, BUS_DMA_WAITOK) != 0) + goto free; + + if (bus_dmamap_load(sc->sc_dmat, ndm->ndm_map, ndm->ndm_kva, size, + NULL, BUS_DMA_WAITOK) != 0) + goto unmap; + + bzero(ndm->ndm_kva, size); + + return (ndm); + +unmap: + bus_dmamem_unmap(sc->sc_dmat, ndm->ndm_kva, size); +free: + bus_dmamem_free(sc->sc_dmat, &ndm->ndm_seg, 1); +destroy: + bus_dmamap_destroy(sc->sc_dmat, ndm->ndm_map); +ndmfree: + free(ndm, M_DEVBUF); + + return (NULL); +} + +void +nxe_dmamem_free(struct nxe_softc *sc, struct nxe_dmamem *ndm) +{ + bus_dmamem_unmap(sc->sc_dmat, ndm->ndm_kva, ndm->ndm_size); + bus_dmamem_free(sc->sc_dmat, &ndm->ndm_seg, 1); + bus_dmamap_destroy(sc->sc_dmat, ndm->ndm_map); + free(ndm, M_DEVBUF); +} + u_int32_t nxe_read(struct nxe_softc *sc, bus_size_t r) { |