From owner-svn-src-head@FreeBSD.ORG Tue Jun 17 16:07:59 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id CFFF36A4; Tue, 17 Jun 2014 16:07:59 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BBA762EFC; Tue, 17 Jun 2014 16:07:59 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s5HG7x1Z058467; Tue, 17 Jun 2014 16:07:59 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s5HG7vJd058451; Tue, 17 Jun 2014 16:07:57 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201406171607.s5HG7vJd058451@svn.freebsd.org> From: John Baldwin Date: Tue, 17 Jun 2014 16:07:57 +0000 (UTC) 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 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Jun 2014 16:07:59 -0000 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); }