diff options
author | gibbs <gibbs@FreeBSD.org> | 1998-10-07 03:38:14 +0000 |
---|---|---|
committer | gibbs <gibbs@FreeBSD.org> | 1998-10-07 03:38:14 +0000 |
commit | 04f5e2e068d6ab729527b802a57364c9f7dea8e6 (patch) | |
tree | 7ab9eb429946788cdf577407a791bc137e9125f2 /sys/amd64 | |
parent | 0c2fc2fa254e73e4e2179a04f7dfd561b52709b6 (diff) | |
download | FreeBSD-src-04f5e2e068d6ab729527b802a57364c9f7dea8e6.zip FreeBSD-src-04f5e2e068d6ab729527b802a57364c9f7dea8e6.tar.gz |
Fix a parent tag reference count bug during tag teardown.
Enable optimization for nobounce_dmamap clients by setting the map
held by the client to NULL. This allows the macros in bus.h to check
against a constant to avoid function calls.
Don't attempt to 'free()' contigmalloced pages in bus_dmamem_free().
We currently leak these pages, which is not ideal, but is better than
a panic. The leak will be fixed when contigmalloc is merged into the
bus dma framework after 3.0R.
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/busdma_machdep.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/sys/amd64/amd64/busdma_machdep.c b/sys/amd64/amd64/busdma_machdep.c index f1d6d86..d900e9b 100644 --- a/sys/amd64/amd64/busdma_machdep.c +++ b/sys/amd64/amd64/busdma_machdep.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 Justin T. Gibbs. + * Copyright (c) 1997, 1998 Justin T. Gibbs. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: busdma_machdep.c,v 1.8 1998/09/15 10:03:42 gibbs Exp $ + * $Id: busdma_machdep.c,v 1.9 1998/09/29 09:06:00 bde Exp $ */ #include <sys/param.h> @@ -219,8 +219,14 @@ bus_dma_tag_destroy(bus_dma_tag_t dmat) dmat->ref_count--; if (dmat->ref_count == 0) { free(dmat, M_DEVBUF); - } - dmat = parent; + /* + * Last reference count, so + * release our reference + * count on our parent. + */ + dmat = parent; + } else + dmat = NULL; } } return (0); @@ -280,7 +286,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) } } } else { - *mapp = &nobounce_dmamap; + *mapp = NULL; } if (error == 0) dmat->map_count++; @@ -314,7 +320,7 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, bus_dmamap_t *mapp) { /* If we succeed, no mapping/bouncing will be required */ - *mapp = &nobounce_dmamap; + *mapp = NULL; if ((dmat->maxsize <= PAGE_SIZE) && dmat->lowaddr >= ptoa(Maxmem)) { *vaddr = malloc(dmat->maxsize, M_DEVBUF, @@ -348,7 +354,9 @@ bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) */ if (map != &nobounce_dmamap) panic("bus_dmamem_free: Invalid map freed\n"); - free(vaddr, M_DEVBUF); + /* XXX There is no "contigfree" and "free" doesn't work */ + if ((dmat->maxsize <= PAGE_SIZE) && dmat->lowaddr >= ptoa(Maxmem)) + free(vaddr, M_DEVBUF); } #define BUS_DMAMAP_NSEGS ((BUS_SPACE_MAXSIZE / PAGE_SIZE) + 1) @@ -372,6 +380,9 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, int seg; int error; + if (map == NULL) + map = &nobounce_dmamap; + error = 0; /* * If we are being called during a callback, pagesneeded will |