summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2006-05-31 00:37:56 +0000
committermjacob <mjacob@FreeBSD.org>2006-05-31 00:37:56 +0000
commit1b7bd7c5ee06751d6c926105d9b922784b66ff55 (patch)
treeea73f3c2455d4e4b361529c8c6151530ebd0360d /sys/amd64
parent154c6ddb9a713fb77a6b9283d3cf8f6f8be6a8a3 (diff)
downloadFreeBSD-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/amd64')
-rw-r--r--sys/amd64/amd64/busdma_machdep.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/sys/amd64/amd64/busdma_machdep.c b/sys/amd64/amd64/busdma_machdep.c
index 20dae8a..e04ff39 100644
--- a/sys/amd64/amd64/busdma_machdep.c
+++ b/sys/amd64/amd64/busdma_machdep.c
@@ -469,7 +469,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;
@@ -490,6 +490,7 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
__func__, dmat, dmat->flags, ENOMEM);
return (ENOMEM);
}
+ swasnull = 1;
}
/*
@@ -498,12 +499,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
@@ -514,13 +516,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);
OpenPOWER on IntegriCloud