From 51170c3bdd3b311f424fab72ee713db7fa6162c3 Mon Sep 17 00:00:00 2001 From: mjacob Date: Wed, 31 May 2006 00:38:53 +0000 Subject: Since it's to all intents and purposes identical code to amd64 && i386, match the recent changes to bus_dmamem_alloc here. --- sys/ia64/ia64/busdma_machdep.c | 48 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) (limited to 'sys/ia64') diff --git a/sys/ia64/ia64/busdma_machdep.c b/sys/ia64/ia64/busdma_machdep.c index 911e9e7..4a59f81 100644 --- a/sys/ia64/ia64/busdma_machdep.c +++ b/sys/ia64/ia64/busdma_machdep.c @@ -410,7 +410,7 @@ int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, bus_dmamap_t *mapp) { - int mflags; + int mflags, malloc_used, swasnull = 0; if (flags & BUS_DMA_NOWAIT) mflags = M_NOWAIT; @@ -423,15 +423,27 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, *mapp = NULL; if (dmat->segments == NULL) { - dmat->segments = (bus_dma_segment_t *)malloc( - sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF, - M_NOWAIT); + dmat->segments = (bus_dma_segment_t *) malloc( + sizeof (bus_dma_segment_t) * dmat->nsegments, + M_DEVBUF, M_NOWAIT); if (dmat->segments == NULL) return (ENOMEM); + swasnull = 1; } - if ((dmat->maxsize <= PAGE_SIZE) && dmat->lowaddr >= ptoa(Maxmem)) { + /* + * XXX: + * (dmat->alignment < dmat->maxsize) is just a quick hack; the exact + * alignment guarantees of malloc need to be nailed down, and the + * code below should be rewritten to take that into account. + * + * In the meantime, we'll return an error if malloc gets it wrong. + */ + if ((dmat->maxsize <= PAGE_SIZE) && + (dmat->alignment < dmat->maxsize) && + dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem)) { *vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags); + malloc_used = 1; } else { /* * XXX Use Contigmalloc until it is merged into this facility @@ -442,9 +454,28 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, *vaddr = contigmalloc(dmat->maxsize, M_DEVBUF, mflags, 0ul, dmat->lowaddr, dmat->alignment? dmat->alignment : 1ul, dmat->boundary); + malloc_used = 0; } - if (*vaddr == NULL) + if (*vaddr == NULL) { + if (swasnull) { + free(dmat->segments, M_DEVBUF); + dmat->segments = NULL; + } return (ENOMEM); + } + if ((uintptr_t)*vaddr & (dmat->alignment - 1)) { + printf("bus_dmamem_alloc failed to align memory properly."); + if (malloc_used) { + free(*vaddr, M_DEVBUF); + } else { + contigfree(*vaddr, dmat->maxsize, M_DEVBUF); + } + if (swasnull) { + free(dmat->segments, M_DEVBUF); + dmat->segments = NULL; + } + return (EINVAL); + } return (0); } @@ -455,8 +486,13 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, void bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) { + malloc_used = 0; /* * dmamem does not need to be bounced, so the map should be + if (swasnull) { + free(dmat->segments, M_DEVBUF); + dmat->segments = NULL; + } * NULL */ if (map != NULL) -- cgit v1.1