Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 17 Jun 2014 16:07:57 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r267581 - in head/sys/dev/sound: pci pci/hda pcm
Message-ID:  <201406171607.s5HG7vJd058451@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Tue Jun 17 16:07:57 2014
New Revision: 267581
URL: http://svnweb.freebsd.org/changeset/base/267581

Log:
  Fix various bugs with freeing static DMA allocations in sound drivers:
  - Don't compare the DMA map to NULL to determine if bus_dmamap_unload()
    should be called when releasing a static allocation.  Instead, compare
    the bus address against 0.
  - Don't assume that the DMA map for static allocations is NULL.  Instead,
    save the value set by bus_dmamem_alloc() so it can later be passed to
    bus_dmamem_free().  Also, add missing calls to bus_dmamap_unload() in
    these cases before freeing the buffer.
  - Use the bus address from the bus_dma callback instead of calling
    vtophys() on the address allocated by bus_dmamem_alloc().
  
  Reviewed by:	kan

Modified:
  head/sys/dev/sound/pci/atiixp.c
  head/sys/dev/sound/pci/emu10k1.c
  head/sys/dev/sound/pci/emu10kx.c
  head/sys/dev/sound/pci/envy24.c
  head/sys/dev/sound/pci/envy24ht.c
  head/sys/dev/sound/pci/hda/hdac.c
  head/sys/dev/sound/pci/hdspe.c
  head/sys/dev/sound/pci/maestro.c
  head/sys/dev/sound/pci/via8233.c
  head/sys/dev/sound/pci/via82c686.c
  head/sys/dev/sound/pcm/buffer.c

Modified: head/sys/dev/sound/pci/atiixp.c
==============================================================================
--- head/sys/dev/sound/pci/atiixp.c	Tue Jun 17 14:47:49 2014	(r267580)
+++ head/sys/dev/sound/pci/atiixp.c	Tue Jun 17 16:07:57 2014	(r267581)
@@ -1146,13 +1146,14 @@ atiixp_release_resource(struct atiixp_in
 		bus_dma_tag_destroy(sc->parent_dmat);
 		sc->parent_dmat = NULL;
 	}
-	if (sc->sgd_dmamap)
+	if (sc->sgd_addr) {
 		bus_dmamap_unload(sc->sgd_dmat, sc->sgd_dmamap);
+		sc->sgd_addr = 0;
+	}
 	if (sc->sgd_table) {
 		bus_dmamem_free(sc->sgd_dmat, sc->sgd_table, sc->sgd_dmamap);
 		sc->sgd_table = NULL;
 	}
-	sc->sgd_dmamap = NULL;
 	if (sc->sgd_dmat) {
 		bus_dma_tag_destroy(sc->sgd_dmat);
 		sc->sgd_dmat = NULL;

Modified: head/sys/dev/sound/pci/emu10k1.c
==============================================================================
--- head/sys/dev/sound/pci/emu10k1.c	Tue Jun 17 14:47:49 2014	(r267580)
+++ head/sys/dev/sound/pci/emu10k1.c	Tue Jun 17 16:07:57 2014	(r267581)
@@ -160,6 +160,7 @@ struct emu_memblk {
 	void *buf;
 	bus_addr_t buf_addr;
 	u_int32_t pte_start, pte_size;
+	bus_dmamap_t buf_map;
 };
 
 struct emu_mem {
@@ -168,6 +169,8 @@ struct emu_mem {
 	void *silent_page;
 	bus_addr_t silent_page_addr;
 	bus_addr_t ptb_pages_addr;
+	bus_dmamap_t ptb_map;
+	bus_dmamap_t silent_map;
 	SLIST_HEAD(, emu_memblk) blocks;
 };
 
@@ -239,7 +242,7 @@ struct sc_info {
 /* stuff */
 static int emu_init(struct sc_info *);
 static void emu_intr(void *);
-static void *emu_malloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr);
+static void *emu_malloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr, bus_dmamap_t *map);
 static void *emu_memalloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr);
 static int emu_memfree(struct sc_info *sc, void *buf);
 static int emu_memstart(struct sc_info *sc, void *buf);
@@ -1315,24 +1318,27 @@ emu_setmap(void *arg, bus_dma_segment_t 
 }
 
 static void *
-emu_malloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr)
+emu_malloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr,
+    bus_dmamap_t *map)
 {
 	void *buf;
-	bus_dmamap_t map;
 
 	*addr = 0;
-	if (bus_dmamem_alloc(sc->parent_dmat, &buf, BUS_DMA_NOWAIT, &map))
+	if (bus_dmamem_alloc(sc->parent_dmat, &buf, BUS_DMA_NOWAIT, map))
 		return NULL;
-	if (bus_dmamap_load(sc->parent_dmat, map, buf, sz, emu_setmap, addr, 0)
-	    || !*addr)
+	if (bus_dmamap_load(sc->parent_dmat, *map, buf, sz, emu_setmap, addr, 0)
+	    || !*addr) {
+		bus_dmamem_free(sc->parent_dmat, buf, *map);
 		return NULL;
+	}
 	return buf;
 }
 
 static void
-emu_free(struct sc_info *sc, void *buf)
+emu_free(struct sc_info *sc, void *buf, bus_dmamap_t map)
 {
-	bus_dmamem_free(sc->parent_dmat, buf, NULL);
+	bus_dmamap_unload(sc->parent_dmat, map);
+	bus_dmamem_free(sc->parent_dmat, buf, map);
 }
 
 static void *
@@ -1362,7 +1368,7 @@ emu_memalloc(struct sc_info *sc, u_int32
 	blk = malloc(sizeof(*blk), M_DEVBUF, M_NOWAIT);
 	if (blk == NULL)
 		return NULL;
-	buf = emu_malloc(sc, sz, &blk->buf_addr);
+	buf = emu_malloc(sc, sz, &blk->buf_addr, &blk->buf_map);
 	*addr = blk->buf_addr;
 	if (buf == NULL) {
 		free(blk, M_DEVBUF);
@@ -1405,7 +1411,7 @@ emu_memfree(struct sc_info *sc, void *bu
 	if (blk == NULL)
 		return EINVAL;
 	SLIST_REMOVE(&mem->blocks, blk, emu_memblk, link);
-	emu_free(sc, buf);
+	emu_free(sc, buf, blk->buf_map);
 	tmp = (u_int32_t)(sc->mem.silent_page_addr) << 1;
 	for (idx = blk->pte_start; idx < blk->pte_start + blk->pte_size; idx++) {
 		mem->bmap[idx >> 3] &= ~(1 << (idx & 7));
@@ -1882,14 +1888,14 @@ emu_init(struct sc_info *sc)
 
 	SLIST_INIT(&sc->mem.blocks);
 	sc->mem.ptb_pages = emu_malloc(sc, EMUMAXPAGES * sizeof(u_int32_t),
-	    &sc->mem.ptb_pages_addr);
+	    &sc->mem.ptb_pages_addr, &sc->mem.ptb_map);
 	if (sc->mem.ptb_pages == NULL)
 		return -1;
 
 	sc->mem.silent_page = emu_malloc(sc, EMUPAGESIZE,
-	    &sc->mem.silent_page_addr);
+	    &sc->mem.silent_page_addr, &sc->mem.silent_map);
 	if (sc->mem.silent_page == NULL) {
-		emu_free(sc, sc->mem.ptb_pages);
+		emu_free(sc, sc->mem.ptb_pages, sc->mem.ptb_map);
 		return -1;
 	}
 	/* Clear page with silence & setup all pointers to this page */
@@ -2025,8 +2031,8 @@ emu_uninit(struct sc_info *sc)
 	/* init envelope engine */
 	if (!SLIST_EMPTY(&sc->mem.blocks))
 		device_printf(sc->dev, "warning: memblock list not empty\n");
-	emu_free(sc, sc->mem.ptb_pages);
-	emu_free(sc, sc->mem.silent_page);
+	emu_free(sc, sc->mem.ptb_pages, sc->mem.ptb_map);
+	emu_free(sc, sc->mem.silent_page, sc->mem.silent_map);
 
 	if(sc->mpu)
 	    mpu401_uninit(sc->mpu);

Modified: head/sys/dev/sound/pci/emu10kx.c
==============================================================================
--- head/sys/dev/sound/pci/emu10kx.c	Tue Jun 17 14:47:49 2014	(r267580)
+++ head/sys/dev/sound/pci/emu10kx.c	Tue Jun 17 16:07:57 2014	(r267581)
@@ -273,14 +273,17 @@ struct emu_memblk {
 	char		owner[16];
 	bus_addr_t	buf_addr;
 	uint32_t	pte_start, pte_size;
+	bus_dmamap_t	buf_map;
 };
 
 struct emu_mem {
 	uint8_t		bmap[EMU_MAXPAGES / 8];
 	uint32_t	*ptb_pages;
 	void		*silent_page;
-	bus_addr_t	silent_page_addr;
 	bus_addr_t	ptb_pages_addr;
+	bus_addr_t	silent_page_addr;
+	bus_dmamap_t	ptb_map;
+	bus_dmamap_t	silent_map;
 	bus_dma_tag_t	dmat;
 	struct emu_sc_info *card;
 	SLIST_HEAD(, emu_memblk) blocks;
@@ -377,8 +380,8 @@ struct emu_sc_info {
 };
 
 static void	emu_setmap(void *arg, bus_dma_segment_t * segs, int nseg, int error);
-static void*	emu_malloc(struct emu_mem *mem, uint32_t sz, bus_addr_t * addr);
-static void	emu_free(struct emu_mem *mem, void *dmabuf);
+static void*	emu_malloc(struct emu_mem *mem, uint32_t sz, bus_addr_t * addr, bus_dmamap_t *map);
+static void	emu_free(struct emu_mem *mem, void *dmabuf, bus_dmamap_t map);
 static void*	emu_memalloc(struct emu_mem *mem, uint32_t sz, bus_addr_t * addr, const char * owner);
 static int	emu_memfree(struct emu_mem *mem, void *membuf);
 static int	emu_memstart(struct emu_mem *mem, void *membuf);
@@ -1057,30 +1060,32 @@ emu_setmap(void *arg, bus_dma_segment_t 
 }
 
 static void *
-emu_malloc(struct emu_mem *mem, uint32_t sz, bus_addr_t * addr)
+emu_malloc(struct emu_mem *mem, uint32_t sz, bus_addr_t * addr,
+    bus_dmamap_t *map)
 {
 	void *dmabuf;
-	bus_dmamap_t map;
 	int error;
 
 	*addr = 0;
-	if ((error = bus_dmamem_alloc(mem->dmat, &dmabuf, BUS_DMA_NOWAIT, &map))) {
+	if ((error = bus_dmamem_alloc(mem->dmat, &dmabuf, BUS_DMA_NOWAIT, map))) {
 		if (mem->card->dbg_level > 2)
 			device_printf(mem->card->dev, "emu_malloc: failed to alloc DMA map: %d\n", error);
 		return (NULL);
 		}
-	if ((error = bus_dmamap_load(mem->dmat, map, dmabuf, sz, emu_setmap, addr, 0)) || !*addr) {
+	if ((error = bus_dmamap_load(mem->dmat, *map, dmabuf, sz, emu_setmap, addr, 0)) || !*addr) {
 		if (mem->card->dbg_level > 2)
 			device_printf(mem->card->dev, "emu_malloc: failed to load DMA memory: %d\n", error);
+		bus_dmamem_free(mem->dmat, dmabuf, *map);
 		return (NULL);
 		}
 	return (dmabuf);
 }
 
 static void
-emu_free(struct emu_mem *mem, void *dmabuf)
+emu_free(struct emu_mem *mem, void *dmabuf, bus_dmamap_t map)
 {
-	bus_dmamem_free(mem->dmat, dmabuf, NULL);
+	bus_dmamap_unload(mem->dmat, map);
+	bus_dmamem_free(mem->dmat, dmabuf, map);
 }
 
 static void *
@@ -1121,7 +1126,7 @@ emu_memalloc(struct emu_mem *mem, uint32
 		return (NULL);
 		}
 	bzero(blk, sizeof(*blk));
-	membuf = emu_malloc(mem, sz, &blk->buf_addr);
+	membuf = emu_malloc(mem, sz, &blk->buf_addr, &blk->buf_map);
 	*addr = blk->buf_addr;
 	if (membuf == NULL) {
 		if (mem->card->dbg_level > 2)
@@ -1159,7 +1164,7 @@ emu_memfree(struct emu_mem *mem, void *m
 	if (blk == NULL)
 		return (EINVAL);
 	SLIST_REMOVE(&mem->blocks, blk, emu_memblk, link);
-	emu_free(mem, membuf);
+	emu_free(mem, membuf, blk->buf_map);
 	tmp = (uint32_t) (mem->silent_page_addr) << 1;
 	for (idx = blk->pte_start; idx < blk->pte_start + blk->pte_size; idx++) {
 		mem->bmap[idx >> 3] &= ~(1 << (idx & 7));
@@ -2724,13 +2729,13 @@ emu_init(struct emu_sc_info *sc)
 
 	sc->mem.card = sc;
 	SLIST_INIT(&sc->mem.blocks);
-	sc->mem.ptb_pages = emu_malloc(&sc->mem, EMU_MAXPAGES * sizeof(uint32_t), &sc->mem.ptb_pages_addr);
+	sc->mem.ptb_pages = emu_malloc(&sc->mem, EMU_MAXPAGES * sizeof(uint32_t), &sc->mem.ptb_pages_addr, &sc->mem.ptb_map);
 	if (sc->mem.ptb_pages == NULL)
 		return (ENOMEM);
 
-	sc->mem.silent_page = emu_malloc(&sc->mem, EMUPAGESIZE, &sc->mem.silent_page_addr);
+	sc->mem.silent_page = emu_malloc(&sc->mem, EMUPAGESIZE, &sc->mem.silent_page_addr, &sc->mem.silent_map);
 	if (sc->mem.silent_page == NULL) {
-		emu_free(&sc->mem, sc->mem.ptb_pages);
+		emu_free(&sc->mem, sc->mem.ptb_pages, sc->mem.ptb_map);
 		return (ENOMEM);
 	}
 	/* Clear page with silence & setup all pointers to this page */
@@ -2946,8 +2951,8 @@ emu_uninit(struct emu_sc_info *sc)
 		if (blk != NULL)
 		device_printf(sc->dev, "lost %d for %s\n", blk->pte_size, blk->owner);
 
-	emu_free(&sc->mem, sc->mem.ptb_pages);
-	emu_free(&sc->mem, sc->mem.silent_page);
+	emu_free(&sc->mem, sc->mem.ptb_pages, sc->mem.ptb_map);
+	emu_free(&sc->mem, sc->mem.silent_page, sc->mem.silent_map);
 
 	return (0);
 }

Modified: head/sys/dev/sound/pci/envy24.c
==============================================================================
--- head/sys/dev/sound/pci/envy24.c	Tue Jun 17 14:47:49 2014	(r267580)
+++ head/sys/dev/sound/pci/envy24.c	Tue Jun 17 16:07:57 2014	(r267581)
@@ -163,6 +163,7 @@ struct sc_info {
 	u_int32_t	psize, rsize; /* DMA buffer size(byte) */
 	u_int16_t	blk[2]; /* transfer check blocksize(dword) */
 	bus_dmamap_t	pmap, rmap;
+	bus_addr_t	paddr, raddr;
 
 	/* current status */
 	u_int32_t	speed;
@@ -2166,15 +2167,16 @@ envy24_pci_probe(device_t dev)
 static void
 envy24_dmapsetmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 {
-	/* struct sc_info *sc = (struct sc_info *)arg; */
+	struct sc_info *sc = (struct sc_info *)arg;
 
+	sc->paddr = segs->ds_addr;
 #if(0)
 	device_printf(sc->dev, "envy24_dmapsetmap()\n");
 	if (bootverbose) {
 		printf("envy24(play): setmap %lx, %lx; ",
 		    (unsigned long)segs->ds_addr,
 		    (unsigned long)segs->ds_len);
-		printf("%p -> %lx\n", sc->pmap, (unsigned long)vtophys(sc->pmap));
+		printf("%p -> %lx\n", sc->pmap, sc->paddr);
 	}
 #endif
 }
@@ -2182,15 +2184,16 @@ envy24_dmapsetmap(void *arg, bus_dma_seg
 static void
 envy24_dmarsetmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 {
-	/* struct sc_info *sc = (struct sc_info *)arg; */
+	struct sc_info *sc = (struct sc_info *)arg;
 
+	sc->raddr = segs->ds_addr;
 #if(0)
 	device_printf(sc->dev, "envy24_dmarsetmap()\n");
 	if (bootverbose) {
 		printf("envy24(record): setmap %lx, %lx; ",
 		    (unsigned long)segs->ds_addr,
 		    (unsigned long)segs->ds_len);
-		printf("%p -> %lx\n", sc->rmap, (unsigned long)vtophys(sc->pmap));
+		printf("%p -> %lx\n", sc->rmap, sc->raddr);
 	}
 #endif
 }
@@ -2200,19 +2203,17 @@ envy24_dmafree(struct sc_info *sc)
 {
 #if(0)
 	device_printf(sc->dev, "envy24_dmafree():");
-	if (sc->rmap) printf(" sc->rmap(0x%08x)", (u_int32_t)sc->rmap);
-	else printf(" sc->rmap(null)");
-	if (sc->pmap) printf(" sc->pmap(0x%08x)", (u_int32_t)sc->pmap);
-	else printf(" sc->pmap(null)");
+	printf(" sc->raddr(0x%08x)", (u_int32_t)sc->raddr);
+	printf(" sc->paddr(0x%08x)", (u_int32_t)sc->paddr);
 	if (sc->rbuf) printf(" sc->rbuf(0x%08x)", (u_int32_t)sc->rbuf);
 	else printf(" sc->rbuf(null)");
 	if (sc->pbuf) printf(" sc->pbuf(0x%08x)\n", (u_int32_t)sc->pbuf);
 	else printf(" sc->pbuf(null)\n");
 #endif
 #if(0)
-	if (sc->rmap)
+	if (sc->raddr)
 		bus_dmamap_unload(sc->dmat, sc->rmap);
-	if (sc->pmap)
+	if (sc->paddr)
 		bus_dmamap_unload(sc->dmat, sc->pmap);
 	if (sc->rbuf)
 		bus_dmamem_free(sc->dmat, sc->rbuf, sc->rmap);
@@ -2225,7 +2226,7 @@ envy24_dmafree(struct sc_info *sc)
 	bus_dmamem_free(sc->dmat, sc->pbuf, sc->pmap);
 #endif
 
-	sc->rmap = sc->pmap = NULL;
+	sc->raddr = sc->paddr = 0;
 	sc->pbuf = NULL;
 	sc->rbuf = NULL;
 
@@ -2235,7 +2236,6 @@ envy24_dmafree(struct sc_info *sc)
 static int
 envy24_dmainit(struct sc_info *sc)
 {
-	u_int32_t addr;
 
 #if(0)
 	device_printf(sc->dev, "envy24_dmainit()\n");
@@ -2245,7 +2245,7 @@ envy24_dmainit(struct sc_info *sc)
 	sc->rsize = ENVY24_REC_BUFUNIT * ENVY24_SAMPLE_NUM;
 	sc->pbuf = NULL;
 	sc->rbuf = NULL;
-	sc->pmap = sc->rmap = NULL;
+	sc->paddr = sc->raddr = 0;
 	sc->blk[0] = sc->blk[1] = 0;
 
 	/* allocate DMA buffer */
@@ -2273,11 +2273,10 @@ envy24_dmainit(struct sc_info *sc)
 	bzero(sc->rbuf, sc->rsize);
 
 	/* set values to register */
-	addr = vtophys(sc->pbuf);
 #if(0)
-	device_printf(sc->dev, "pbuf(0x%08x)\n", addr);
+	device_printf(sc->dev, "paddr(0x%08x)\n", sc->paddr);
 #endif
-	envy24_wrmt(sc, ENVY24_MT_PADDR, addr, 4);
+	envy24_wrmt(sc, ENVY24_MT_PADDR, sc->paddr, 4);
 #if(0)
 	device_printf(sc->dev, "PADDR-->(0x%08x)\n", envy24_rdmt(sc, ENVY24_MT_PADDR, 4));
 	device_printf(sc->dev, "psize(%ld)\n", sc->psize / 4 - 1);
@@ -2286,8 +2285,7 @@ envy24_dmainit(struct sc_info *sc)
 #if(0)
 	device_printf(sc->dev, "PCNT-->(%ld)\n", envy24_rdmt(sc, ENVY24_MT_PCNT, 2));
 #endif
-	addr = vtophys(sc->rbuf);
-	envy24_wrmt(sc, ENVY24_MT_RADDR, addr, 4);
+	envy24_wrmt(sc, ENVY24_MT_RADDR, sc->raddr, 4);
 	envy24_wrmt(sc, ENVY24_MT_RCNT, sc->rsize / 4 - 1, 2);
 
 	return 0;

Modified: head/sys/dev/sound/pci/envy24ht.c
==============================================================================
--- head/sys/dev/sound/pci/envy24ht.c	Tue Jun 17 14:47:49 2014	(r267580)
+++ head/sys/dev/sound/pci/envy24ht.c	Tue Jun 17 16:07:57 2014	(r267581)
@@ -162,6 +162,7 @@ struct sc_info {
 	u_int32_t	psize, rsize; /* DMA buffer size(byte) */
 	u_int16_t	blk[2]; /* transfer check blocksize(dword) */
 	bus_dmamap_t	pmap, rmap;
+	bus_addr_t	paddr, raddr;
 
 	/* current status */
 	u_int32_t	speed;
@@ -2082,6 +2083,7 @@ envy24ht_dmapsetmap(void *arg, bus_dma_s
 {
 	struct sc_info *sc = arg;
 
+	sc->paddr = segs->ds_addr;
 #if(0)
 	device_printf(sc->dev, "envy24ht_dmapsetmap()\n");
 	if (bootverbose) {
@@ -2099,6 +2101,7 @@ envy24ht_dmarsetmap(void *arg, bus_dma_s
 {
 	struct sc_info *sc = arg;
 
+	sc->raddr = segs->ds_addr;
 #if(0)
 	device_printf(sc->dev, "envy24ht_dmarsetmap()\n");
 	if (bootverbose) {
@@ -2116,19 +2119,17 @@ envy24ht_dmafree(struct sc_info *sc)
 {
 #if(0)
 	device_printf(sc->dev, "envy24ht_dmafree():");
-	if (sc->rmap) printf(" sc->rmap(0x%08x)", (u_int32_t)sc->rmap);
-	else printf(" sc->rmap(null)");
-	if (sc->pmap) printf(" sc->pmap(0x%08x)", (u_int32_t)sc->pmap);
-	else printf(" sc->pmap(null)");
+	printf(" sc->raddr(0x%08x)", (u_int32_t)sc->raddr);
+	printf(" sc->paddr(0x%08x)", (u_int32_t)sc->paddr);
 	if (sc->rbuf) printf(" sc->rbuf(0x%08x)", (u_int32_t)sc->rbuf);
 	else printf(" sc->rbuf(null)");
 	if (sc->pbuf) printf(" sc->pbuf(0x%08x)\n", (u_int32_t)sc->pbuf);
 	else printf(" sc->pbuf(null)\n");
 #endif
 #if(0)
-	if (sc->rmap)
+	if (sc->raddr)
 		bus_dmamap_unload(sc->dmat, sc->rmap);
-	if (sc->pmap)
+	if (sc->paddr)
 		bus_dmamap_unload(sc->dmat, sc->pmap);
 	if (sc->rbuf)
 		bus_dmamem_free(sc->dmat, sc->rbuf, sc->rmap);
@@ -2141,7 +2142,7 @@ envy24ht_dmafree(struct sc_info *sc)
 	bus_dmamem_free(sc->dmat, sc->pbuf, sc->pmap);
 #endif
 
-	sc->rmap = sc->pmap = NULL;
+	sc->raddr = sc->paddr = 0;
 	sc->pbuf = NULL;
 	sc->rbuf = NULL;
 
@@ -2160,7 +2161,7 @@ envy24ht_dmainit(struct sc_info *sc)
 	sc->rsize = ENVY24HT_REC_BUFUNIT * ENVY24HT_SAMPLE_NUM;
 	sc->pbuf = NULL;
 	sc->rbuf = NULL;
-	sc->pmap = sc->rmap = NULL;
+	sc->paddr = sc->raddr = 0;
 	sc->blk[0] = sc->blk[1] = 0;
 
 	/* allocate DMA buffer */

Modified: head/sys/dev/sound/pci/hda/hdac.c
==============================================================================
--- head/sys/dev/sound/pci/hda/hdac.c	Tue Jun 17 14:47:49 2014	(r267580)
+++ head/sys/dev/sound/pci/hda/hdac.c	Tue Jun 17 16:07:57 2014	(r267581)
@@ -611,19 +611,19 @@ hdac_dma_alloc_fail:
 static void
 hdac_dma_free(struct hdac_softc *sc, struct hdac_dma *dma)
 {
-	if (dma->dma_map != NULL) {
+	if (dma->dma_paddr != 0) {
 #if 0
 		/* Flush caches */
 		bus_dmamap_sync(dma->dma_tag, dma->dma_map,
 		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 #endif
 		bus_dmamap_unload(dma->dma_tag, dma->dma_map);
+		dma->dma_paddr = 0;
 	}
 	if (dma->dma_vaddr != NULL) {
 		bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
 		dma->dma_vaddr = NULL;
 	}
-	dma->dma_map = NULL;
 	if (dma->dma_tag != NULL) {
 		bus_dma_tag_destroy(dma->dma_tag);
 		dma->dma_tag = NULL;

Modified: head/sys/dev/sound/pci/hdspe.c
==============================================================================
--- head/sys/dev/sound/pci/hdspe.c	Tue Jun 17 14:47:49 2014	(r267580)
+++ head/sys/dev/sound/pci/hdspe.c	Tue Jun 17 16:07:57 2014	(r267581)
@@ -344,7 +344,6 @@ hdspe_dmafree(struct sc_info *sc)
 	bus_dmamap_unload(sc->dmat, sc->pmap);
 	bus_dmamem_free(sc->dmat, sc->rbuf, sc->rmap);
 	bus_dmamem_free(sc->dmat, sc->pbuf, sc->pmap);
-	sc->rmap = sc->pmap = NULL;
 	sc->rbuf = sc->pbuf = NULL;
 }
 

Modified: head/sys/dev/sound/pci/maestro.c
==============================================================================
--- head/sys/dev/sound/pci/maestro.c	Tue Jun 17 14:47:49 2014	(r267580)
+++ head/sys/dev/sound/pci/maestro.c	Tue Jun 17 16:07:57 2014	(r267581)
@@ -110,6 +110,7 @@ struct agg_chinfo {
 	struct snd_dbuf		*buffer;
 
 	/* OS independent */
+	bus_dmamap_t		map;
 	bus_addr_t		phys;	/* channel buffer physical address */
 	bus_addr_t		base;	/* channel buffer segment base */
 	u_int32_t		blklen;	/* DMA block length in WORDs */
@@ -130,6 +131,7 @@ struct agg_rchinfo {
 	struct snd_dbuf		*buffer;
 
 	/* OS independent */
+	bus_dmamap_t		map;
 	bus_addr_t		phys;	/* channel buffer physical address */
 	bus_addr_t		base;	/* channel buffer segment base */
 	u_int32_t		blklen;	/* DMA block length in WORDs */
@@ -166,6 +168,7 @@ struct agg_info {
 	struct ac97_info	*codec;
 
 	/* OS independent */
+	bus_dmamap_t		stat_map;
 	u_int8_t		*stat;	/* status buffer pointer */
 	bus_addr_t		phys;	/* status buffer physical address */
 	unsigned int		bufsz;	/* channel buffer size in bytes */
@@ -262,8 +265,9 @@ static int	agg_suspend(device_t);
 static int	agg_resume(device_t);
 static int	agg_shutdown(device_t);
 
-static void	*dma_malloc(bus_dma_tag_t, u_int32_t, bus_addr_t*);
-static void	dma_free(bus_dma_tag_t, void *);
+static void	*dma_malloc(bus_dma_tag_t, u_int32_t, bus_addr_t*,
+		    bus_dmamap_t *);
+static void	dma_free(bus_dma_tag_t, void *, bus_dmamap_t);
 
 
 /* -----------------------------
@@ -1297,7 +1301,7 @@ aggpch_init(kobj_t obj, void *devinfo, s
 	ch->buffer = b;
 	ch->num = ess->playchns;
 
-	p = dma_malloc(ess->buf_dmat, ess->bufsz, &physaddr);
+	p = dma_malloc(ess->buf_dmat, ess->bufsz, &physaddr, &ch->map);
 	if (p == NULL)
 		return NULL;
 	ch->phys = physaddr;
@@ -1360,7 +1364,7 @@ aggpch_free(kobj_t obj, void *data)
 	struct agg_info *ess = ch->parent;
 
 	/* free up buffer - called after channel stopped */
-	dma_free(ess->buf_dmat, sndbuf_getbuf(ch->buffer));
+	dma_free(ess->buf_dmat, sndbuf_getbuf(ch->buffer), ch->map);
 
 	/* return 0 if ok */
 	return 0;
@@ -1722,25 +1726,26 @@ setmap(void *arg, bus_dma_segment_t *seg
 }
 
 static void *
-dma_malloc(bus_dma_tag_t dmat, u_int32_t sz, bus_addr_t *phys)
+dma_malloc(bus_dma_tag_t dmat, u_int32_t sz, bus_addr_t *phys,
+    bus_dmamap_t *map)
 {
 	void *buf;
-	bus_dmamap_t map;
 
-	if (bus_dmamem_alloc(dmat, &buf, BUS_DMA_NOWAIT, &map))
+	if (bus_dmamem_alloc(dmat, &buf, BUS_DMA_NOWAIT, map))
 		return NULL;
-	if (bus_dmamap_load(dmat, map, buf, sz, setmap, phys, 0)
-	    || !*phys || map) {
-		bus_dmamem_free(dmat, buf, map);
+	if (bus_dmamap_load(dmat, *map, buf, sz, setmap, phys, 0) != 0 ||
+	    *phys == 0) {
+		bus_dmamem_free(dmat, buf, *map);
 		return NULL;
 	}
 	return buf;
 }
 
 static void
-dma_free(bus_dma_tag_t dmat, void *buf)
+dma_free(bus_dma_tag_t dmat, void *buf, bus_dmamap_t map)
 {
-	bus_dmamem_free(dmat, buf, NULL);
+	bus_dmamap_unload(dmat, map);
+	bus_dmamem_free(dmat, buf, map);
 }
 
 static int
@@ -1836,7 +1841,8 @@ agg_attach(device_t dev)
 	}
 
 	/* Allocate the room for brain-damaging status buffer. */
-	ess->stat = dma_malloc(ess->stat_dmat, 3*ess->bufsz, &ess->phys);
+	ess->stat = dma_malloc(ess->stat_dmat, 3*ess->bufsz, &ess->phys,
+	    &ess->stat_map);
 	if (ess->stat == NULL) {
 		device_printf(dev, "cannot allocate status buffer\n");
 		ret = ENOMEM;
@@ -1939,7 +1945,7 @@ agg_attach(device_t dev)
 		bus_release_resource(dev, SYS_RES_IOPORT, regid, reg);
 	if (ess != NULL) {
 		if (ess->stat != NULL)
-			dma_free(ess->stat_dmat, ess->stat);
+			dma_free(ess->stat_dmat, ess->stat, ess->stat_map);
 		if (ess->stat_dmat != NULL)
 			bus_dma_tag_destroy(ess->stat_dmat);
 		if (ess->buf_dmat != NULL)
@@ -1983,7 +1989,7 @@ agg_detach(device_t dev)
 	bus_teardown_intr(dev, ess->irq, ess->ih);
 	bus_release_resource(dev, SYS_RES_IRQ, ess->irqid, ess->irq);
 	bus_release_resource(dev, SYS_RES_IOPORT, ess->regid, ess->reg);
-	dma_free(ess->stat_dmat, ess->stat);
+	dma_free(ess->stat_dmat, ess->stat, ess->stat_map);
 	bus_dma_tag_destroy(ess->stat_dmat);
 	bus_dma_tag_destroy(ess->buf_dmat);
 	mtx_destroy(&ess->lock);

Modified: head/sys/dev/sound/pci/via8233.c
==============================================================================
--- head/sys/dev/sound/pci/via8233.c	Tue Jun 17 14:47:49 2014	(r267580)
+++ head/sys/dev/sound/pci/via8233.c	Tue Jun 17 16:07:57 2014	(r267581)
@@ -1381,7 +1381,7 @@ bad:
 		bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq);
 	if (via->parent_dmat)
 		bus_dma_tag_destroy(via->parent_dmat);
-	if (via->sgd_dmamap)
+	if (via->sgd_addr)
 		bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap);
 	if (via->sgd_table)
 		bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap);

Modified: head/sys/dev/sound/pci/via82c686.c
==============================================================================
--- head/sys/dev/sound/pci/via82c686.c	Tue Jun 17 14:47:49 2014	(r267580)
+++ head/sys/dev/sound/pci/via82c686.c	Tue Jun 17 16:07:57 2014	(r267581)
@@ -606,7 +606,7 @@ bad:
 	if (via->ih) bus_teardown_intr(dev, via->irq, via->ih);
 	if (via->irq) bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq);
 	if (via->parent_dmat) bus_dma_tag_destroy(via->parent_dmat);
-	if (via->sgd_dmamap) bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap);
+	if (via->sgd_addr) bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap);
 	if (via->sgd_table) bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap);
 	if (via->sgd_dmat) bus_dma_tag_destroy(via->sgd_dmat);
 	if (via->lock) snd_mtxfree(via->lock);

Modified: head/sys/dev/sound/pcm/buffer.c
==============================================================================
--- head/sys/dev/sound/pcm/buffer.c	Tue Jun 17 14:47:49 2014	(r267580)
+++ head/sys/dev/sound/pcm/buffer.c	Tue Jun 17 16:07:57 2014	(r267581)
@@ -139,10 +139,9 @@ sndbuf_free(struct snd_dbuf *b)
 
 	if (b->buf) {
 		if (b->flags & SNDBUF_F_MANAGED) {
-			if (b->dmamap)
+			if (b->buf_addr)
 				bus_dmamap_unload(b->dmatag, b->dmamap);
-			if (b->dmatag)
-				bus_dmamem_free(b->dmatag, b->buf, b->dmamap);
+			bus_dmamem_free(b->dmatag, b->buf, b->dmamap);
 		} else
 			free(b->buf, M_DEVBUF);
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201406171607.s5HG7vJd058451>