diff options
| author | Adrian Chadd <adrian@FreeBSD.org> | 2026-02-18 06:50:12 +0000 |
|---|---|---|
| committer | Adrian Chadd <adrian@FreeBSD.org> | 2026-05-01 21:14:44 +0000 |
| commit | 00ec88d2aa8d8267b1e80991d5e632bb9f012b07 (patch) | |
| tree | c9dba5dcecaf8eb4ae503dade971f6cd0018eed8 /sys/powerpc | |
| parent | df3bd7201efc88b0518c9fe7997f3dbf656eccd5 (diff) | |
Diffstat (limited to 'sys/powerpc')
| -rw-r--r-- | sys/powerpc/include/bus_dma_impl.h | 6 | ||||
| -rw-r--r-- | sys/powerpc/powerpc/busdma_bounce.c | 41 | ||||
| -rw-r--r-- | sys/powerpc/powerpc/busdma_machdep.c | 65 |
3 files changed, 74 insertions, 38 deletions
diff --git a/sys/powerpc/include/bus_dma_impl.h b/sys/powerpc/include/bus_dma_impl.h index 80d775f2cf9e..cb495236646d 100644 --- a/sys/powerpc/include/bus_dma_impl.h +++ b/sys/powerpc/include/bus_dma_impl.h @@ -80,4 +80,10 @@ struct bus_dma_impl { extern struct bus_dma_impl bus_dma_bounce_impl; +extern int common_bus_dma_tag_create(struct bus_dma_tag_common *parent, + bus_size_t alignment, bus_addr_t boundary, bus_addr_t lowaddr, + bus_addr_t highaddr, bus_size_t maxsize, int nsegments, + bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc, + void *lockfuncarg, size_t sz, void **dmat); + #endif diff --git a/sys/powerpc/powerpc/busdma_bounce.c b/sys/powerpc/powerpc/busdma_bounce.c index 790903712da7..36c4d38cc7f6 100644 --- a/sys/powerpc/powerpc/busdma_bounce.c +++ b/sys/powerpc/powerpc/busdma_bounce.c @@ -159,9 +159,6 @@ bounce_bus_dma_zone_setup(bus_dma_tag_t newtag) /* * Allocate a device specific dma_tag. - * - * TODO: this does ALL of the work, rather than it being split into - * common and bounce specific. That'll need fixing. */ static int bounce_bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, @@ -184,46 +181,20 @@ bounce_bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, /* Return a NULL tag on failure */ *dmat = NULL; - newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_DEVBUF, - M_ZERO | M_NOWAIT); - if (newtag == NULL) { - CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d", - __func__, newtag, 0, error); - return (ENOMEM); - } + error = common_bus_dma_tag_create(parent != NULL ? &parent->common : + NULL, alignment, boundary, lowaddr, highaddr, maxsize, nsegments, + maxsegsz, flags, lockfunc, lockfuncarg, + sizeof (struct bus_dma_tag), (void **)&newtag); + if (error != 0) + return (error); - newtag->common.alignment = alignment; - newtag->common.boundary = boundary; - newtag->common.lowaddr = trunc_page((vm_paddr_t)lowaddr) + (PAGE_SIZE - 1); - newtag->common.highaddr = trunc_page((vm_paddr_t)highaddr) + (PAGE_SIZE - 1); - newtag->common.maxsize = maxsize; - newtag->common.nsegments = nsegments; - newtag->common.maxsegsz = maxsegsz; - newtag->common.flags = flags; newtag->map_count = 0; newtag->common.impl = &bus_dma_bounce_impl; - if (lockfunc != NULL) { - newtag->common.lockfunc = lockfunc; - newtag->common.lockfuncarg = lockfuncarg; - } else { - newtag->common.lockfunc = _busdma_dflt_lock; - newtag->common.lockfuncarg = NULL; - } /* Take into account any restrictions imposed by our parent tag */ if (parent != NULL) { - newtag->common.lowaddr = MIN(parent->common.lowaddr, newtag->common.lowaddr); - newtag->common.highaddr = MAX(parent->common.highaddr, newtag->common.highaddr); - if (newtag->common.boundary == 0) - newtag->common.boundary = parent->common.boundary; - else if (parent->common.boundary != 0) - newtag->common.boundary = MIN(parent->common.boundary, - newtag->common.boundary); - newtag->iommu = parent->iommu; newtag->iommu_cookie = parent->iommu_cookie; - newtag->common.domain = vm_phys_domain_match(newtag->common.domain, 0ul, - newtag->common.lowaddr); } if (newtag->common.lowaddr < ptoa((vm_paddr_t)Maxmem) && newtag->iommu == NULL) diff --git a/sys/powerpc/powerpc/busdma_machdep.c b/sys/powerpc/powerpc/busdma_machdep.c index aba11e64145c..575b3fcbe2bf 100644 --- a/sys/powerpc/powerpc/busdma_machdep.c +++ b/sys/powerpc/powerpc/busdma_machdep.c @@ -53,10 +53,69 @@ #include <machine/atomic.h> #include <machine/bus.h> -#include <machine/cpufunc.h> -#include <machine/md_var.h> +#include <machine/bus_dma_impl.h> -#include "iommu_if.h" +int +common_bus_dma_tag_create(struct bus_dma_tag_common *parent, + bus_size_t alignment, bus_addr_t boundary, bus_addr_t lowaddr, + bus_addr_t highaddr, bus_size_t maxsize, int nsegments, + bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc, + void *lockfuncarg, size_t sz, void **dmat) +{ + void *newtag; + struct bus_dma_tag_common *common; + + KASSERT(sz >= sizeof(struct bus_dma_tag_common), ("sz")); + /* Return a NULL tag on failure */ + *dmat = NULL; + /* Basic sanity checking */ + if (boundary != 0 && boundary < maxsegsz) + maxsegsz = boundary; + if (maxsegsz == 0) + return (EINVAL); + + newtag = malloc(sz, M_DEVBUF, M_ZERO | M_NOWAIT); + if (newtag == NULL) { + CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d", + __func__, newtag, 0, ENOMEM); + return (ENOMEM); + } + + common = newtag; + common->impl = &bus_dma_bounce_impl; + common->alignment = alignment; + common->boundary = boundary; + common->lowaddr = trunc_page((vm_paddr_t)lowaddr) + (PAGE_SIZE - 1); + common->highaddr = trunc_page((vm_paddr_t)highaddr) + (PAGE_SIZE - 1); + common->maxsize = maxsize; + common->nsegments = nsegments; + common->maxsegsz = maxsegsz; + common->flags = flags; + if (lockfunc != NULL) { + common->lockfunc = lockfunc; + common->lockfuncarg = lockfuncarg; + } else { + common->lockfunc = _busdma_dflt_lock; + common->lockfuncarg = NULL; + } + + /* Take into account any restrictions imposed by our parent tag */ + if (parent != NULL) { + common->impl = parent->impl; + common->lowaddr = MIN(parent->lowaddr, common->lowaddr); + common->highaddr = MAX(parent->highaddr, common->highaddr); + if (common->boundary == 0) + common->boundary = parent->boundary; + else if (parent->boundary != 0) { + common->boundary = MIN(parent->boundary, + common->boundary); + } + common->domain = vm_phys_domain_match(common->domain, 0ul, + common->lowaddr); + } + *dmat = common; + return (0); +} /* * Allocate a device specific dma_tag. |
