summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2006-05-31 00:38:53 +0000
committermjacob <mjacob@FreeBSD.org>2006-05-31 00:38:53 +0000
commit51170c3bdd3b311f424fab72ee713db7fa6162c3 (patch)
tree8ad962f3e474738a378418b0f5087817d83407b8 /sys/ia64
parent1b7bd7c5ee06751d6c926105d9b922784b66ff55 (diff)
downloadFreeBSD-src-51170c3bdd3b311f424fab72ee713db7fa6162c3.zip
FreeBSD-src-51170c3bdd3b311f424fab72ee713db7fa6162c3.tar.gz
Since it's to all intents and purposes identical
code to amd64 && i386, match the recent changes to bus_dmamem_alloc here.
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/busdma_machdep.c48
1 files changed, 42 insertions, 6 deletions
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)
OpenPOWER on IntegriCloud