diff options
author | mjacob <mjacob@FreeBSD.org> | 2006-05-31 00:37:56 +0000 |
---|---|---|
committer | mjacob <mjacob@FreeBSD.org> | 2006-05-31 00:37:56 +0000 |
commit | 1b7bd7c5ee06751d6c926105d9b922784b66ff55 (patch) | |
tree | ea73f3c2455d4e4b361529c8c6151530ebd0360d /sys/i386 | |
parent | 154c6ddb9a713fb77a6b9283d3cf8f6f8be6a8a3 (diff) | |
download | FreeBSD-src-1b7bd7c5ee06751d6c926105d9b922784b66ff55.zip FreeBSD-src-1b7bd7c5ee06751d6c926105d9b922784b66ff55.tar.gz |
Turn the panic on not being able to meet alignment constraints
in bus_dmamem_alloc into the more reasonable EINVAL return.
Also, reclaim memory allocated but then not used if we had
an error return.
Diffstat (limited to 'sys/i386')
-rw-r--r-- | sys/i386/i386/busdma_machdep.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/sys/i386/i386/busdma_machdep.c b/sys/i386/i386/busdma_machdep.c index 1b2bf39..1ca9531 100644 --- a/sys/i386/i386/busdma_machdep.c +++ b/sys/i386/i386/busdma_machdep.c @@ -472,7 +472,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; @@ -493,6 +493,7 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, __func__, dmat, dmat->flags, ENOMEM); return (ENOMEM); } + swasnull = 1; } /* @@ -501,12 +502,13 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, * 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 panic if malloc gets it wrong. + * 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 @@ -517,13 +519,29 @@ 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 (swasnull) { + free(dmat->segments, M_DEVBUF); + dmat->segments = NULL; + } CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", __func__, dmat, dmat->flags, ENOMEM); return (ENOMEM); - } else if ((uintptr_t)*vaddr & (dmat->alignment - 1)) { - panic("bus_dmamem_alloc failed to align memory properly."); + } + 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); } CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", __func__, dmat, dmat->flags, ENOMEM); |