diff options
-rw-r--r-- | sys/sparc64/include/bus.h | 188 | ||||
-rw-r--r-- | sys/sparc64/include/bus_private.h | 22 | ||||
-rw-r--r-- | sys/sparc64/include/iommuvar.h | 14 | ||||
-rw-r--r-- | sys/sparc64/pci/psycho.c | 11 | ||||
-rw-r--r-- | sys/sparc64/sbus/sbus.c | 11 | ||||
-rw-r--r-- | sys/sparc64/sparc64/bus_machdep.c | 219 | ||||
-rw-r--r-- | sys/sparc64/sparc64/iommu.c | 90 |
7 files changed, 190 insertions, 365 deletions
diff --git a/sys/sparc64/include/bus.h b/sys/sparc64/include/bus.h index d2b36a0..e3ca847 100644 --- a/sys/sparc64/include/bus.h +++ b/sys/sparc64/include/bus.h @@ -132,15 +132,6 @@ struct bus_space_tag { }; /* - * Helpers - */ -int sparc64_bus_mem_map(bus_space_tag_t, bus_space_handle_t, bus_size_t, - int, vm_offset_t, void **); -int sparc64_bus_mem_unmap(void *, bus_size_t); -bus_space_handle_t sparc64_fake_bustag(int, bus_addr_t, - struct bus_space_tag *); - -/* * Bus space function prototypes. */ static void bus_space_barrier(bus_space_tag_t, bus_space_handle_t, bus_size_t, @@ -939,10 +930,29 @@ typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); typedef void bus_dmamap_callback2_t(void *, bus_dma_segment_t *, int, bus_size_t, int); /* - * bus_dma_tag_t + * Method table for a bus_dma_tag. + */ +struct bus_dma_methods { + int (*dm_dmamap_create)(bus_dma_tag_t, int, bus_dmamap_t *); + int (*dm_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t); + int (*dm_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *, + bus_size_t, bus_dmamap_callback_t *, void *, int); + int (*dm_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t, + struct mbuf *, bus_dmamap_callback2_t *, void *, int); + int (*dm_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t, struct uio *, + bus_dmamap_callback2_t *, void *, int); + void (*dm_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t); + void (*dm_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t, + bus_dmasync_op_t); + int (*dm_dmamem_alloc)(bus_dma_tag_t, void **, int, bus_dmamap_t *); + void (*dm_dmamem_free)(bus_dma_tag_t, void *, bus_dmamap_t); +}; + +/* + * bus_dma_tag_t * - * A machine-dependent opaque type describing the implementation of - * DMA for a given bus. + * A machine-dependent opaque type describing the implementation of + * DMA for a given bus. */ struct bus_dma_tag { void *dt_cookie; /* cookie used in the guts */ @@ -960,162 +970,32 @@ struct bus_dma_tag { int dt_ref_count; int dt_map_count; - /* - * DMA mapping methods. - */ - int (*dt_dmamap_create)(bus_dma_tag_t, bus_dma_tag_t, int, - bus_dmamap_t *); - int (*dt_dmamap_destroy)(bus_dma_tag_t, bus_dma_tag_t, - bus_dmamap_t); - int (*dt_dmamap_load)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t, - void *, bus_size_t, bus_dmamap_callback_t *, void *, int); - int (*dt_dmamap_load_mbuf)(bus_dma_tag_t, bus_dma_tag_t, - bus_dmamap_t, struct mbuf *, bus_dmamap_callback2_t *, void *, int); - int (*dt_dmamap_load_uio)(bus_dma_tag_t, bus_dma_tag_t, - bus_dmamap_t, struct uio *, bus_dmamap_callback2_t *, void *, int); - void (*dt_dmamap_unload)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t); - void (*dt_dmamap_sync)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t, - bus_dmasync_op_t); - - /* - * DMA memory utility functions. - */ - int (*dt_dmamem_alloc)(bus_dma_tag_t, bus_dma_tag_t, void **, int, - bus_dmamap_t *); - void (*dt_dmamem_free)(bus_dma_tag_t, bus_dma_tag_t, void *, - bus_dmamap_t); + struct bus_dma_methods *dt_mt; }; -/* - * XXX: This is a kluge. It would be better to handle dma tags in a hierarchical - * way, and have a BUS_GET_DMA_TAG(); however, since this is not currently the - * case, save a root tag in the relevant bus attach function and use that. - * Keep the hierarchical structure, it might become needed in the future. - */ -extern bus_dma_tag_t sparc64_root_dma_tag; - int bus_dma_tag_create(bus_dma_tag_t, bus_size_t, bus_size_t, bus_addr_t, bus_addr_t, bus_dma_filter_t *, void *, bus_size_t, int, bus_size_t, int, bus_dma_tag_t *); int bus_dma_tag_destroy(bus_dma_tag_t); -int sparc64_dmamem_alloc_map(bus_dma_tag_t dmat, bus_dmamap_t *mapp); -void sparc64_dmamem_free_map(bus_dma_tag_t dmat, bus_dmamap_t map); - -static __inline int -sparc64_dmamap_create(bus_dma_tag_t pt, bus_dma_tag_t dt, int f, - bus_dmamap_t *p) -{ - bus_dma_tag_t lt; - - for (lt = pt; lt->dt_dmamap_create == NULL; lt = lt->dt_parent) - ; - return ((*lt->dt_dmamap_create)(lt, dt, f, p)); -} #define bus_dmamap_create(t, f, p) \ - sparc64_dmamap_create((t), (t), (f), (p)) - -static __inline int -sparc64_dmamap_destroy(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t p) -{ - bus_dma_tag_t lt; - - for (lt = pt; lt->dt_dmamap_destroy == NULL; lt = lt->dt_parent) - ; - return ((*lt->dt_dmamap_destroy)(lt, dt, p)); -} + ((t)->dt_mt->dm_dmamap_create((t), (f), (p))) #define bus_dmamap_destroy(t, p) \ - sparc64_dmamap_destroy((t), (t), (p)) - -static __inline int -sparc64_dmamap_load(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t m, - void *p, bus_size_t s, bus_dmamap_callback_t *cb, void *cba, int f) -{ - bus_dma_tag_t lt; - - for (lt = pt; lt->dt_dmamap_load == NULL; lt = lt->dt_parent) - ; - return ((*lt->dt_dmamap_load)(lt, dt, m, p, s, cb, cba, f)); -} + ((t)->dt_mt->dm_dmamap_destroy((t), (p))) #define bus_dmamap_load(t, m, p, s, cb, cba, f) \ - sparc64_dmamap_load((t), (t), (m), (p), (s), (cb), (cba), (f)) - -static __inline int -sparc64_dmamap_load_mbuf(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t m, - struct mbuf *mb, bus_dmamap_callback2_t *cb, void *cba, int f) -{ - bus_dma_tag_t lt; - - for (lt = pt; lt->dt_dmamap_load_mbuf == NULL; lt = lt->dt_parent) - ; - return ((*lt->dt_dmamap_load_mbuf)(lt, dt, m, mb, cb, cba, f)); -} -#define bus_dmamap_load_mbuf(t, m, mb, cb, cba, f) \ - sparc64_dmamap_load_mbuf((t), (t), (m), (mb), (cb), (cba), (f)) - -static __inline int -sparc64_dmamap_load_uio(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t m, - struct uio *ui, bus_dmamap_callback2_t *cb, void *cba, int f) -{ - bus_dma_tag_t lt; - - for (lt = pt; lt->dt_dmamap_load_uio == NULL; lt = lt->dt_parent) - ; - return ((*lt->dt_dmamap_load_uio)(lt, dt, m, ui, cb, cba, f)); -} -#define bus_dmamap_load_uio(t, m, ui, cb, cba, f) \ - sparc64_dmamap_load_uio((t), (t), (m), (ui), (cb), (cba), (f)) - -static __inline void -sparc64_dmamap_unload(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t p) -{ - bus_dma_tag_t lt; - - for (lt = pt; lt->dt_dmamap_unload == NULL; lt = lt->dt_parent) - ; - (*lt->dt_dmamap_unload)(lt, dt, p); -} + ((t)->dt_mt->dm_dmamap_load((t), (m), (p), (s), (cb), (cba), (f))) +#define bus_dmamap_load_mbuf(t, m, mb, cb, cba, f) \ + ((t)->dt_mt->dm_dmamap_load_mbuf((t), (m), (mb), (cb), (cba), (f))) +#define bus_dmamap_load_uio(t, m, ui, cb, cba, f) \ + ((t)->dt_mt->dm_dmamap_load_uio((t), (m), (ui), (cb), (cba), (f))) #define bus_dmamap_unload(t, p) \ - sparc64_dmamap_unload((t), (t), (p)) - -static __inline void -sparc64_dmamap_sync(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t m, - bus_dmasync_op_t op) -{ - bus_dma_tag_t lt; - - for (lt = pt; lt->dt_dmamap_sync == NULL; lt = lt->dt_parent) - ; - (*lt->dt_dmamap_sync)(lt, dt, m, op); -} + ((t)->dt_mt->dm_dmamap_unload((t), (p))) #define bus_dmamap_sync(t, m, op) \ - sparc64_dmamap_sync((t), (t), (m), (op)) - -static __inline int -sparc64_dmamem_alloc(bus_dma_tag_t pt, bus_dma_tag_t dt, void **v, int f, - bus_dmamap_t *m) -{ - bus_dma_tag_t lt; - - for (lt = pt; lt->dt_dmamem_alloc == NULL; lt = lt->dt_parent) - ; - return ((*lt->dt_dmamem_alloc)(lt, dt, v, f, m)); -} + ((t)->dt_mt->dm_dmamap_sync((t), (m), (op))) #define bus_dmamem_alloc(t, v, f, m) \ - sparc64_dmamem_alloc((t), (t), (v), (f), (m)) - -static __inline void -sparc64_dmamem_free(bus_dma_tag_t pt, bus_dma_tag_t dt, void *v, - bus_dmamap_t m) -{ - bus_dma_tag_t lt; - - for (lt = pt; lt->dt_dmamem_free == NULL; lt = lt->dt_parent) - ; - (*lt->dt_dmamem_free)(lt, dt, v, m); -} + ((t)->dt_mt->dm_dmamem_alloc((t), (v), (f), (m))) #define bus_dmamem_free(t, v, m) \ - sparc64_dmamem_free((t), (t), (v), (m)) + ((t)->dt_mt->dm_dmamem_free((t), (v), (m))) #endif /* !_MACHINE_BUS_H_ */ diff --git a/sys/sparc64/include/bus_private.h b/sys/sparc64/include/bus_private.h index 6c3a86e..71c8b76 100644 --- a/sys/sparc64/include/bus_private.h +++ b/sys/sparc64/include/bus_private.h @@ -34,6 +34,14 @@ #include <sys/queue.h> /* + * Helpers + */ +int sparc64_bus_mem_map(bus_space_tag_t, bus_space_handle_t, bus_size_t, + int, vm_offset_t, void **); +int sparc64_bus_mem_unmap(void *, bus_size_t); +bus_space_handle_t sparc64_fake_bustag(int, bus_addr_t, struct bus_space_tag *); + +/* * This is more or less arbitrary, except for the stack space consumed by * the segments array. Choose more than ((BUS_SPACE_MAXSIZE / PAGE_SIZE) + 1), * since in practice we could be map pages more than once. @@ -53,10 +61,14 @@ struct bus_dmamap { int dm_loaded; }; -static __inline void -sparc64_dmamap_init(struct bus_dmamap *m) -{ - SLIST_INIT(&m->dm_reslist); -} +int sparc64_dma_alloc_map(bus_dma_tag_t dmat, bus_dmamap_t *mapp); +void sparc64_dma_free_map(bus_dma_tag_t dmat, bus_dmamap_t map); + +/* + * XXX: This is a kluge. It would be better to handle dma tags in a hierarchical + * way, and have a BUS_GET_DMA_TAG(); however, since this is not currently the + * case, save a root tag in the relevant bus attach function and use that. + */ +extern bus_dma_tag_t sparc64_root_dma_tag; #endif /* !_MACHINE_BUS_PRIVATE_H_ */ diff --git a/sys/sparc64/include/iommuvar.h b/sys/sparc64/include/iommuvar.h index 493dee8..6640573 100644 --- a/sys/sparc64/include/iommuvar.h +++ b/sys/sparc64/include/iommuvar.h @@ -81,18 +81,6 @@ void iommu_enter(struct iommu_state *, vm_offset_t, vm_paddr_t, int); void iommu_remove(struct iommu_state *, vm_offset_t, size_t); void iommu_decode_fault(struct iommu_state *, vm_offset_t); -int iommu_dvmamap_create(bus_dma_tag_t, bus_dma_tag_t, int, bus_dmamap_t *); -int iommu_dvmamap_destroy(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t); -int iommu_dvmamap_load(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t, void *, - bus_size_t, bus_dmamap_callback_t *, void *, int); -int iommu_dvmamap_load_mbuf(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t, - struct mbuf *, bus_dmamap_callback2_t *, void *, int); -int iommu_dvmamap_load_uio(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t, - struct uio *, bus_dmamap_callback2_t *, void *, int); -void iommu_dvmamap_unload(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t); -void iommu_dvmamap_sync(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t, int); -int iommu_dvmamem_alloc(bus_dma_tag_t, bus_dma_tag_t, void **, int, - bus_dmamap_t *); -void iommu_dvmamem_free(bus_dma_tag_t, bus_dma_tag_t, void *, bus_dmamap_t); +extern struct bus_dma_methods iommu_dma_methods; #endif /* !_MACHINE_IOMMUVAR_H_ */ diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c index 041eca0..798cfad 100644 --- a/sys/sparc64/pci/psycho.c +++ b/sys/sparc64/pci/psycho.c @@ -49,6 +49,7 @@ #include <ofw/ofw_pci.h> #include <machine/bus.h> +#include <machine/bus_private.h> #include <machine/iommureg.h> #include <machine/bus_common.h> #include <machine/frame.h> @@ -546,15 +547,7 @@ psycho_attach(device_t dev) panic("psycho_attach: bus_dma_tag_create failed"); /* Customize the tag. */ sc->sc_dmat->dt_cookie = sc->sc_is; - sc->sc_dmat->dt_dmamap_create = iommu_dvmamap_create; - sc->sc_dmat->dt_dmamap_destroy = iommu_dvmamap_destroy; - sc->sc_dmat->dt_dmamap_load = iommu_dvmamap_load; - sc->sc_dmat->dt_dmamap_load_mbuf = iommu_dvmamap_load_mbuf; - sc->sc_dmat->dt_dmamap_load_uio = iommu_dvmamap_load_uio; - sc->sc_dmat->dt_dmamap_unload = iommu_dvmamap_unload; - sc->sc_dmat->dt_dmamap_sync = iommu_dvmamap_sync; - sc->sc_dmat->dt_dmamem_alloc = iommu_dvmamem_alloc; - sc->sc_dmat->dt_dmamem_free = iommu_dvmamem_free; + sc->sc_dmat->dt_mt = &iommu_dma_methods; /* XXX: register as root dma tag (kludge). */ sparc64_root_dma_tag = sc->sc_dmat; diff --git a/sys/sparc64/sbus/sbus.c b/sys/sparc64/sbus/sbus.c index a941e2f..22a0aeb 100644 --- a/sys/sparc64/sbus/sbus.c +++ b/sys/sparc64/sbus/sbus.c @@ -117,6 +117,7 @@ #include <ofw/openfirm.h> #include <machine/bus.h> +#include <machine/bus_private.h> #include <machine/iommureg.h> #include <machine/bus_common.h> #include <machine/frame.h> @@ -396,15 +397,7 @@ sbus_probe(device_t dev) panic("bus_dma_tag_create failed"); /* Customize the tag. */ sc->sc_cdmatag->dt_cookie = &sc->sc_is; - sc->sc_cdmatag->dt_dmamap_create = iommu_dvmamap_create; - sc->sc_cdmatag->dt_dmamap_destroy = iommu_dvmamap_destroy; - sc->sc_cdmatag->dt_dmamap_load = iommu_dvmamap_load; - sc->sc_cdmatag->dt_dmamap_load_mbuf = iommu_dvmamap_load_mbuf; - sc->sc_cdmatag->dt_dmamap_load_uio = iommu_dvmamap_load_uio; - sc->sc_cdmatag->dt_dmamap_unload = iommu_dvmamap_unload; - sc->sc_cdmatag->dt_dmamap_sync = iommu_dvmamap_sync; - sc->sc_cdmatag->dt_dmamem_alloc = iommu_dvmamem_alloc; - sc->sc_cdmatag->dt_dmamem_free = iommu_dvmamem_free; + sc->sc_cdmatag->dt_mt = &iommu_dma_methods; /* XXX: register as root dma tag (kludge). */ sparc64_root_dma_tag = sc->sc_cdmatag; diff --git a/sys/sparc64/sparc64/bus_machdep.c b/sys/sparc64/sparc64/bus_machdep.c index d8e46ed..90d6ffd 100644 --- a/sys/sparc64/sparc64/bus_machdep.c +++ b/sys/sparc64/sparc64/bus_machdep.c @@ -155,28 +155,6 @@ int bus_stream_asi[] = { }; /* - * busdma support code. - * Note: there is no support for bounce buffers yet. - */ - -static int nexus_dmamap_create(bus_dma_tag_t, bus_dma_tag_t, int, - bus_dmamap_t *); -static int nexus_dmamap_destroy(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t); -static int nexus_dmamap_load(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t, - void *, bus_size_t, bus_dmamap_callback_t *, void *, int); -static int nexus_dmamap_load_mbuf(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t, - struct mbuf *, bus_dmamap_callback2_t *, void *, int); -static int nexus_dmamap_load_uio(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t, - struct uio *, bus_dmamap_callback2_t *, void *, int); -static void nexus_dmamap_unload(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t); -static void nexus_dmamap_sync(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t, - bus_dmasync_op_t); -static int nexus_dmamem_alloc(bus_dma_tag_t, bus_dma_tag_t, void **, int, - bus_dmamap_t *); -static void nexus_dmamem_free(bus_dma_tag_t, bus_dma_tag_t, void *, - bus_dmamap_t); - -/* * Since there is now way for a device to obtain a dma tag from its parent * we use this kluge to handle different the different supported bus systems. * The sparc64_root_dma_tag is used as parent for tags that have none, so that @@ -193,7 +171,7 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, bus_dma_filter_t *filter, void *filterarg, bus_size_t maxsize, int nsegments, bus_size_t maxsegsz, int flags, bus_dma_tag_t *dmat) { - + bus_dma_tag_t impptag; bus_dma_tag_t newtag; /* Return a NULL tag on failure */ @@ -203,7 +181,15 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, if (newtag == NULL) return (ENOMEM); - newtag->dt_parent = parent != NULL ? parent : sparc64_root_dma_tag; + impptag = parent != NULL ? parent : sparc64_root_dma_tag; + /* + * The method table pointer and the cookie need to be taken over from + * the parent or the root tag. + */ + newtag->dt_cookie = impptag->dt_cookie; + newtag->dt_mt = impptag->dt_mt; + + newtag->dt_parent = parent; newtag->dt_alignment = alignment; newtag->dt_boundary = boundary; newtag->dt_lowaddr = trunc_page((vm_offset_t)lowaddr) + (PAGE_SIZE - 1); @@ -218,16 +204,6 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, newtag->dt_ref_count = 1; /* Count ourselves */ newtag->dt_map_count = 0; - newtag->dt_dmamap_create = NULL; - newtag->dt_dmamap_destroy = NULL; - newtag->dt_dmamap_load = NULL; - newtag->dt_dmamap_load_mbuf = NULL; - newtag->dt_dmamap_load_uio = NULL; - newtag->dt_dmamap_unload = NULL; - newtag->dt_dmamap_sync = NULL; - newtag->dt_dmamem_alloc = NULL; - newtag->dt_dmamem_free = NULL; - /* Take into account any restrictions imposed by our parent tag */ if (parent != NULL) { newtag->dt_lowaddr = ulmin(parent->dt_lowaddr, @@ -240,8 +216,8 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, */ newtag->dt_boundary = ulmin(parent->dt_boundary, newtag->dt_boundary); + atomic_add_int(&parent->dt_ref_count, 1); } - atomic_add_int(&newtag->dt_parent->dt_ref_count, 1); *dmat = newtag; return (0); @@ -273,34 +249,40 @@ bus_dma_tag_destroy(bus_dma_tag_t dmat) return (0); } -/* - * Common function for DMA map creation. May be called by bus-specific - * DMA map creation functions. - */ -static int -nexus_dmamap_create(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, int flags, - bus_dmamap_t *mapp) +/* Allocate/free a tag, and do the necessary management work. */ +int +sparc64_dma_alloc_map(bus_dma_tag_t dmat, bus_dmamap_t *mapp) { *mapp = malloc(sizeof(**mapp), M_DEVBUF, M_NOWAIT | M_ZERO); - if (*mapp != NULL) { - ddmat->dt_map_count++; - sparc64_dmamap_init(*mapp); - return (0); - } else + if (*mapp == NULL) return (ENOMEM); + + SLIST_INIT(&(*mapp)->dm_reslist); + dmat->dt_map_count++; + return (0); } -/* - * Common function for DMA map destruction. May be called by bus-specific - * DMA map destruction functions. - */ -static int -nexus_dmamap_destroy(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, bus_dmamap_t map) +void +sparc64_dma_free_map(bus_dma_tag_t dmat, bus_dmamap_t map) { free(map, M_DEVBUF); - ddmat->dt_map_count--; + dmat->dt_map_count--; +} + +static int +nexus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) +{ + + return (sparc64_dma_alloc_map(dmat, mapp)); +} + +static int +nexus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map) +{ + + sparc64_dma_free_map(dmat, map); return (0); } @@ -311,7 +293,7 @@ nexus_dmamap_destroy(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, bus_dmamap_t map) * first indicates if this is the first invocation of this function. */ static int -_nexus_dmamap_load_buffer(bus_dma_tag_t ddmat, bus_dma_segment_t segs[], +_nexus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dma_segment_t segs[], void *buf, bus_size_t buflen, struct thread *td, int flags, bus_addr_t *lastaddrp, int *segp, int first) { @@ -327,7 +309,7 @@ _nexus_dmamap_load_buffer(bus_dma_tag_t ddmat, bus_dma_segment_t segs[], pmap = NULL; lastaddr = *lastaddrp; - bmask = ~(ddmat->dt_boundary - 1); + bmask = ~(dmat->dt_boundary - 1); for (seg = *segp; buflen > 0 ; ) { /* @@ -348,8 +330,8 @@ _nexus_dmamap_load_buffer(bus_dma_tag_t ddmat, bus_dma_segment_t segs[], /* * Make sure we don't cross any boundaries. */ - if (ddmat->dt_boundary > 0) { - baddr = (curaddr + ddmat->dt_boundary) & bmask; + if (dmat->dt_boundary > 0) { + baddr = (curaddr + dmat->dt_boundary) & bmask; if (sgsize > (baddr - curaddr)) sgsize = (baddr - curaddr); } @@ -364,12 +346,12 @@ _nexus_dmamap_load_buffer(bus_dma_tag_t ddmat, bus_dma_segment_t segs[], first = 0; } else { if (curaddr == lastaddr && - (segs[seg].ds_len + sgsize) <= ddmat->dt_maxsegsz && - (ddmat->dt_boundary == 0 || + (segs[seg].ds_len + sgsize) <= dmat->dt_maxsegsz && + (dmat->dt_boundary == 0 || (segs[seg].ds_addr & bmask) == (curaddr & bmask))) segs[seg].ds_len += sgsize; else { - if (++seg >= ddmat->dt_nsegments) + if (++seg >= dmat->dt_nsegments) break; segs[seg].ds_addr = curaddr; segs[seg].ds_len = sgsize; @@ -401,19 +383,19 @@ _nexus_dmamap_load_buffer(bus_dma_tag_t ddmat, bus_dma_segment_t segs[], * bypass DVMA. */ static int -nexus_dmamap_load(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, bus_dmamap_t map, - void *buf, bus_size_t buflen, bus_dmamap_callback_t *callback, - void *callback_arg, int flags) +nexus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, + bus_size_t buflen, bus_dmamap_callback_t *callback, void *callback_arg, + int flags) { #ifdef __GNUC__ - bus_dma_segment_t dm_segments[ddmat->dt_nsegments]; + bus_dma_segment_t dm_segments[dmat->dt_nsegments]; #else bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; #endif bus_addr_t lastaddr; int error, nsegs; - error = _nexus_dmamap_load_buffer(ddmat, dm_segments, buf, buflen, + error = _nexus_dmamap_load_buffer(dmat, dm_segments, buf, buflen, NULL, flags, &lastaddr, &nsegs, 1); if (error == 0) { @@ -429,12 +411,11 @@ nexus_dmamap_load(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, bus_dmamap_t map, * Like nexus_dmamap_load(), but for mbufs. */ static int -nexus_dmamap_load_mbuf(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, - bus_dmamap_t map, struct mbuf *m0, bus_dmamap_callback2_t *callback, - void *callback_arg, int flags) +nexus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0, + bus_dmamap_callback2_t *callback, void *callback_arg, int flags) { #ifdef __GNUC__ - bus_dma_segment_t dm_segments[ddmat->dt_nsegments]; + bus_dma_segment_t dm_segments[dmat->dt_nsegments]; #else bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; #endif @@ -444,14 +425,14 @@ nexus_dmamap_load_mbuf(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, nsegs = 0; error = 0; - if (m0->m_pkthdr.len <= ddmat->dt_maxsize) { + if (m0->m_pkthdr.len <= dmat->dt_maxsize) { int first = 1; bus_addr_t lastaddr = 0; struct mbuf *m; for (m = m0; m != NULL && error == 0; m = m->m_next) { if (m->m_len > 0) { - error = _nexus_dmamap_load_buffer(ddmat, + error = _nexus_dmamap_load_buffer(dmat, dm_segments, m->m_data, m->m_len, NULL, flags, &lastaddr, &nsegs, first); first = 0; @@ -476,13 +457,12 @@ nexus_dmamap_load_mbuf(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, * Like nexus_dmamap_load(), but for uios. */ static int -nexus_dmamap_load_uio(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, - bus_dmamap_t map, struct uio *uio, bus_dmamap_callback2_t *callback, - void *callback_arg, int flags) +nexus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, struct uio *uio, + bus_dmamap_callback2_t *callback, void *callback_arg, int flags) { bus_addr_t lastaddr; #ifdef __GNUC__ - bus_dma_segment_t dm_segments[ddmat->dt_nsegments]; + bus_dma_segment_t dm_segments[dmat->dt_nsegments]; #else bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; #endif @@ -513,7 +493,7 @@ nexus_dmamap_load_uio(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, caddr_t addr = (caddr_t) iov[i].iov_base; if (minlen > 0) { - error = _nexus_dmamap_load_buffer(ddmat, dm_segments, + error = _nexus_dmamap_load_buffer(dmat, dm_segments, addr, minlen, td, flags, &lastaddr, &nsegs, first); first = 0; @@ -537,7 +517,7 @@ nexus_dmamap_load_uio(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, * bus-specific DMA map unload functions. */ static void -nexus_dmamap_unload(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, bus_dmamap_t map) +nexus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map) { map->dm_loaded = 0; @@ -548,8 +528,7 @@ nexus_dmamap_unload(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, bus_dmamap_t map) * by bus-specific DMA map synchronization functions. */ static void -nexus_dmamap_sync(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, bus_dmamap_t map, - bus_dmasync_op_t op) +nexus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) { /* @@ -577,45 +556,16 @@ nexus_dmamap_sync(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, bus_dmamap_t map, } /* - * Helper functions for buses that use their private dmamem_alloc/dmamem_free - * versions. - * These differ from the dmamap_alloc() functions in that they create a tag - * that is specifically for use with dmamem_alloc'ed memory. - * These are primitive now, but I expect that some fields of the map will need - * to be filled soon. - */ -int -sparc64_dmamem_alloc_map(bus_dma_tag_t dmat, bus_dmamap_t *mapp) -{ - - *mapp = malloc(sizeof(**mapp), M_DEVBUF, M_NOWAIT | M_ZERO); - if (*mapp == NULL) - return (ENOMEM); - - dmat->dt_map_count++; - sparc64_dmamap_init(*mapp); - return (0); -} - -void -sparc64_dmamem_free_map(bus_dma_tag_t dmat, bus_dmamap_t map) -{ - - free(map, M_DEVBUF); - dmat->dt_map_count--; -} - -/* * Common function for DMA-safe memory allocation. May be called * by bus-specific DMA memory allocation functions. */ static int -nexus_dmamem_alloc(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, void **vaddr, - int flags, bus_dmamap_t *mapp) +nexus_dmamem_alloc(bus_dma_tag_t dmat, void **vaddr, int flags, + bus_dmamap_t *mapp) { - if ((ddmat->dt_maxsize <= PAGE_SIZE)) { - *vaddr = malloc(ddmat->dt_maxsize, M_DEVBUF, + if ((dmat->dt_maxsize <= PAGE_SIZE)) { + *vaddr = malloc(dmat->dt_maxsize, M_DEVBUF, (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK); } else { /* @@ -624,17 +574,15 @@ nexus_dmamem_alloc(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, void **vaddr, * allocations yet though. */ mtx_lock(&Giant); - *vaddr = contigmalloc(ddmat->dt_maxsize, M_DEVBUF, + *vaddr = contigmalloc(dmat->dt_maxsize, M_DEVBUF, (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK, - 0ul, ddmat->dt_lowaddr, - ddmat->dt_alignment ? ddmat->dt_alignment : 1UL, - ddmat->dt_boundary); + 0ul, dmat->dt_lowaddr, + dmat->dt_alignment ? dmat->dt_alignment : 1UL, + dmat->dt_boundary); mtx_unlock(&Giant); } - if (*vaddr == NULL) { - free(*mapp, M_DEVBUF); + if (*vaddr == NULL) return (ENOMEM); - } return (0); } @@ -643,20 +591,30 @@ nexus_dmamem_alloc(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, void **vaddr, * bus-specific DMA memory free functions. */ static void -nexus_dmamem_free(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, void *vaddr, - bus_dmamap_t map) +nexus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) { - sparc64_dmamem_free_map(ddmat, map); - if ((ddmat->dt_maxsize <= PAGE_SIZE)) + if ((dmat->dt_maxsize <= PAGE_SIZE)) free(vaddr, M_DEVBUF); else { mtx_lock(&Giant); - contigfree(vaddr, ddmat->dt_maxsize, M_DEVBUF); + contigfree(vaddr, dmat->dt_maxsize, M_DEVBUF); mtx_unlock(&Giant); } } +struct bus_dma_methods nexus_dma_methods = { + nexus_dmamap_create, + nexus_dmamap_destroy, + nexus_dmamap_load, + nexus_dmamap_load_mbuf, + nexus_dmamap_load_uio, + nexus_dmamap_unload, + nexus_dmamap_sync, + nexus_dmamem_alloc, + nexus_dmamem_free, +}; + struct bus_dma_tag nexus_dmatag = { NULL, NULL, @@ -672,16 +630,7 @@ struct bus_dma_tag nexus_dmatag = { 0, 0, 0, - nexus_dmamap_create, - nexus_dmamap_destroy, - nexus_dmamap_load, - nexus_dmamap_load_mbuf, - nexus_dmamap_load_uio, - nexus_dmamap_unload, - nexus_dmamap_sync, - - nexus_dmamem_alloc, - nexus_dmamem_free, + &nexus_dma_methods, }; /* diff --git a/sys/sparc64/sparc64/iommu.c b/sys/sparc64/sparc64/iommu.c index c18206d..66fc86a 100644 --- a/sys/sparc64/sparc64/iommu.c +++ b/sys/sparc64/sparc64/iommu.c @@ -667,23 +667,23 @@ iommu_dvma_vallocseg(bus_dma_tag_t dt, struct iommu_state *is, bus_dmamap_t map, return (0); } -int -iommu_dvmamem_alloc(bus_dma_tag_t pt, bus_dma_tag_t dt, void **vaddr, - int flags, bus_dmamap_t *mapp) +static int +iommu_dvmamem_alloc(bus_dma_tag_t dt, void **vaddr, int flags, + bus_dmamap_t *mapp) { - struct iommu_state *is = pt->dt_cookie; + struct iommu_state *is = dt->dt_cookie; int error; /* * XXX: This will break for 32 bit transfers on machines with more than * 16G (1 << 34 bytes) of memory. */ - if ((error = sparc64_dmamem_alloc_map(dt, mapp)) != 0) + if ((error = sparc64_dma_alloc_map(dt, mapp)) != 0) return (error); if ((*vaddr = malloc(dt->dt_maxsize, M_IOMMU, (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL) { error = ENOMEM; - sparc64_dmamem_free_map(dt, *mapp); + sparc64_dma_free_map(dt, *mapp); return (error); } iommu_map_insq(*mapp); @@ -695,26 +695,24 @@ iommu_dvmamem_alloc(bus_dma_tag_t pt, bus_dma_tag_t dt, void **vaddr, return (0); } -void -iommu_dvmamem_free(bus_dma_tag_t pt, bus_dma_tag_t dt, void *vaddr, - bus_dmamap_t map) +static void +iommu_dvmamem_free(bus_dma_tag_t dt, void *vaddr, bus_dmamap_t map) { - struct iommu_state *is = pt->dt_cookie; + struct iommu_state *is = dt->dt_cookie; iommu_dvma_vfree(is, map); - sparc64_dmamem_free_map(dt, map); + sparc64_dma_free_map(dt, map); free(vaddr, M_IOMMU); } -int -iommu_dvmamap_create(bus_dma_tag_t pt, bus_dma_tag_t dt, int flags, - bus_dmamap_t *mapp) +static int +iommu_dvmamap_create(bus_dma_tag_t dt, int flags, bus_dmamap_t *mapp) { - struct iommu_state *is = pt->dt_cookie; + struct iommu_state *is = dt->dt_cookie; bus_size_t totsz, presz, currsz; int error, i, maxpre; - if ((error = sparc64_dmamap_create(pt->dt_parent, dt, flags, mapp)) != 0) + if ((error = sparc64_dma_alloc_map(dt, mapp)) != 0) return (error); KASSERT(SLIST_EMPTY(&(*mapp)->dm_reslist), ("iommu_dvmamap_create: hierarchy botched")); @@ -751,13 +749,14 @@ iommu_dvmamap_create(bus_dma_tag_t pt, bus_dma_tag_t dt, int flags, return (0); } -int -iommu_dvmamap_destroy(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t map) +static int +iommu_dvmamap_destroy(bus_dma_tag_t dt, bus_dmamap_t map) { - struct iommu_state *is = pt->dt_cookie; + struct iommu_state *is = dt->dt_cookie; iommu_dvma_vfree(is, map); - return (sparc64_dmamap_destroy(pt->dt_parent, dt, map)); + sparc64_dma_free_map(dt, map); + return (0); } /* @@ -842,12 +841,12 @@ iommu_dvmamap_load_buffer(bus_dma_tag_t dt, struct iommu_state *is, return (0); } -int -iommu_dvmamap_load(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t map, - void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb, void *cba, +static int +iommu_dvmamap_load(bus_dma_tag_t dt, bus_dmamap_t map, void *buf, + bus_size_t buflen, bus_dmamap_callback_t *cb, void *cba, int flags) { - struct iommu_state *is = pt->dt_cookie; + struct iommu_state *is = dt->dt_cookie; #ifdef __GNUC__ bus_dma_segment_t sgs[dt->dt_nsegments]; #else @@ -878,11 +877,11 @@ iommu_dvmamap_load(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t map, return (error); } -int -iommu_dvmamap_load_mbuf(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t map, - struct mbuf *m0, bus_dmamap_callback2_t *cb, void *cba, int flags) +static int +iommu_dvmamap_load_mbuf(bus_dma_tag_t dt, bus_dmamap_t map, struct mbuf *m0, + bus_dmamap_callback2_t *cb, void *cba, int flags) { - struct iommu_state *is = pt->dt_cookie; + struct iommu_state *is = dt->dt_cookie; #ifdef __GNUC__ bus_dma_segment_t sgs[dt->dt_nsegments]; #else @@ -923,11 +922,11 @@ iommu_dvmamap_load_mbuf(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t map, return (error); } -int -iommu_dvmamap_load_uio(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t map, - struct uio *uio, bus_dmamap_callback2_t *cb, void *cba, int flags) +static int +iommu_dvmamap_load_uio(bus_dma_tag_t dt, bus_dmamap_t map, struct uio *uio, + bus_dmamap_callback2_t *cb, void *cba, int flags) { - struct iommu_state *is = pt->dt_cookie; + struct iommu_state *is = dt->dt_cookie; #ifdef __GNUC__ bus_dma_segment_t sgs[dt->dt_nsegments]; #else @@ -982,23 +981,22 @@ iommu_dvmamap_load_uio(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t map, return (error); } -void -iommu_dvmamap_unload(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t map) +static void +iommu_dvmamap_unload(bus_dma_tag_t dt, bus_dmamap_t map) { - struct iommu_state *is = pt->dt_cookie; + struct iommu_state *is = dt->dt_cookie; if (map->dm_loaded == 0) return; iommu_dvmamap_vunload(is, map); iommu_map_insq(map); - sparc64_dmamap_unload(pt->dt_parent, dt, map); + map->dm_loaded = 0; } -void -iommu_dvmamap_sync(bus_dma_tag_t pt, bus_dma_tag_t dt, bus_dmamap_t map, - bus_dmasync_op_t op) +static void +iommu_dvmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op) { - struct iommu_state *is = pt->dt_cookie; + struct iommu_state *is = dt->dt_cookie; struct bus_dmamap_res *r; vm_offset_t va; vm_size_t len; @@ -1055,3 +1053,15 @@ iommu_diag(struct iommu_state *is, vm_offset_t va) } #endif /* IOMMU_DIAG */ + +struct bus_dma_methods iommu_dma_methods = { + iommu_dvmamap_create, + iommu_dvmamap_destroy, + iommu_dvmamap_load, + iommu_dvmamap_load_mbuf, + iommu_dvmamap_load_uio, + iommu_dvmamap_unload, + iommu_dvmamap_sync, + iommu_dvmamem_alloc, + iommu_dvmamem_free, +}; |