Index: sys/arm64/arm64/busdma_bounce.c =================================================================== --- sys/arm64/arm64/busdma_bounce.c +++ sys/arm64/arm64/busdma_bounce.c @@ -74,7 +74,6 @@ struct bus_dma_tag_common common; int map_count; int bounce_flags; - bus_dma_segment_t *segments; struct bounce_zone *bounce_zone; }; @@ -129,6 +128,7 @@ int pagesneeded; int pagesreserved; bus_dma_tag_t dmat; + bus_dma_segment_t *segments; struct memdesc mem; bus_dmamap_callback_t *callback; void *callback_arg; @@ -184,7 +184,6 @@ newtag->common.impl = &bus_dma_bounce_impl; newtag->map_count = 0; - newtag->segments = NULL; if ((flags & BUS_DMA_COHERENT) != 0) newtag->bounce_flags |= BF_COHERENT; @@ -255,8 +254,6 @@ parent = (bus_dma_tag_t)dmat->common.parent; atomic_subtract_int(&dmat->common.ref_count, 1); if (dmat->common.ref_count == 0) { - if (dmat->segments != NULL) - free(dmat->segments, M_DEVBUF); free(dmat, M_DEVBUF); /* * Last reference count, so @@ -312,17 +309,6 @@ error = 0; - if (dmat->segments == NULL) { - dmat->segments = (bus_dma_segment_t *)malloc( - sizeof(bus_dma_segment_t) * dmat->common.nsegments, - M_DEVBUF, M_NOWAIT); - if (dmat->segments == NULL) { - CTR3(KTR_BUSDMA, "%s: tag %p error %d", - __func__, dmat, ENOMEM); - return (ENOMEM); - } - } - *mapp = alloc_dmamap(dmat, M_NOWAIT); if (*mapp == NULL) { CTR3(KTR_BUSDMA, "%s: tag %p error %d", @@ -330,6 +316,16 @@ return (ENOMEM); } + (*mapp)->segments = (bus_dma_segment_t *)malloc( + sizeof(bus_dma_segment_t) * dmat->common.nsegments, + M_DEVBUF, M_NOWAIT); + if ((*mapp)->segments == NULL) { + free(*mapp, M_DEVBUF); + CTR3(KTR_BUSDMA, "%s: map %p error %d", + __func__, *map, ENOMEM); + return (ENOMEM); + } + /* * Bouncing might be required if the driver asks for an active * exclusion region, a data alignment that is stricter than 1, and/or @@ -404,6 +400,7 @@ ("%s: Bounce zone when cannot bounce", __func__)); dmat->bounce_zone->map_count--; } + free(map->segments, M_DEVBUF); free(map, M_DEVBUF); dmat->map_count--; CTR2(KTR_BUSDMA, "%s: tag %p error 0", __func__, dmat); @@ -435,16 +432,6 @@ else mflags = M_WAITOK; - if (dmat->segments == NULL) { - dmat->segments = (bus_dma_segment_t *)malloc( - sizeof(bus_dma_segment_t) * dmat->common.nsegments, - M_DEVBUF, mflags); - if (dmat->segments == NULL) { - CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", - __func__, dmat, dmat->common.flags, ENOMEM); - return (ENOMEM); - } - } if (flags & BUS_DMA_ZERO) mflags |= M_ZERO; if (flags & BUS_DMA_NOCACHE) @@ -471,6 +458,16 @@ } (*mapp)->flags = DMAMAP_FROM_DMAMEM; + (*mapp)->segments = (bus_dma_segment_t *)malloc( + sizeof(bus_dma_segment_t) * dmat->common.nsegments, + M_DEVBUF, M_NOWAIT); + if ((*mapp)->segments == NULL) { + free(*mapp, M_DEVBUF); + CTR3(KTR_BUSDMA, "%s: map %p error %d", + __func__, *map, ENOMEM); + return (ENOMEM); + } + /* * Allocate the buffer from the malloc(9) allocator if... * - It's small enough to fit into a single power of two sized bucket. @@ -718,7 +715,7 @@ int error; if (segs == NULL) - segs = dmat->segments; + segs = map->segments; if ((dmat->bounce_flags & BF_COULD_BOUNCE) != 0) { _bus_dmamap_count_phys(dmat, map, buf, buflen, flags); @@ -789,7 +786,7 @@ int error; if (segs == NULL) - segs = dmat->segments; + segs = map->segments; if ((dmat->bounce_flags & BF_COULD_BOUNCE) != 0) { _bus_dmamap_count_pages(dmat, map, pmap, buf, buflen, flags); @@ -894,7 +891,7 @@ { if (segs == NULL) - segs = dmat->segments; + segs = map->segments; return (segs); }