Module Name: src Committed By: jakllsch Date: Mon Jul 26 15:41:33 UTC 2010
Modified Files: src/sys/dev/ic: siisata.c siisatavar.h Log Message: Store information for bus_dmamem_unmap() and bus_dmamem_free() somewhere outside the bus_dmamap_t. The bus_dmamap_t has already been destroyed by this time. Fixes DMA memory leak at siisata_detach() time. To generate a diff of this commit: cvs rdiff -u -r1.11 -r1.12 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.5 -r1.6 src/sys/dev/ic/siisatavar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.11 src/sys/dev/ic/siisata.c:1.12 --- src/sys/dev/ic/siisata.c:1.11 Sun Apr 25 15:39:41 2010 +++ src/sys/dev/ic/siisata.c Mon Jul 26 15:41:33 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.11 2010/04/25 15:39:41 rmind Exp $ */ +/* $NetBSD: siisata.c,v 1.12 2010/07/26 15:41:33 jakllsch Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.11 2010/04/25 15:39:41 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.12 2010/07/26 15:41:33 jakllsch Exp $"); #include <sys/types.h> #include <sys/malloc.h> @@ -238,10 +238,8 @@ siisata_attach_port(struct siisata_softc *sc, int port) { int j; - bus_dma_segment_t seg; int dmasize; int error; - int rseg; void *prbp; struct siisata_channel *schp; struct ata_channel *chp; @@ -266,7 +264,7 @@ __func__, dmasize), DEBUG_FUNCS); error = bus_dmamem_alloc(sc->sc_dmat, dmasize, PAGE_SIZE, 0, - &seg, 1, &rseg, BUS_DMA_NOWAIT); + &schp->sch_prb_seg, 1, &schp->sch_prb_nseg, BUS_DMA_NOWAIT); if (error) { aprint_error_dev(sc->sc_atac.atac_dev, "unable to allocate PRB table memory, " @@ -274,13 +272,15 @@ return; } - error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, dmasize, - &prbp, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); + error = bus_dmamem_map(sc->sc_dmat, + &schp->sch_prb_seg, schp->sch_prb_nseg, + dmasize, &prbp, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); if (error) { aprint_error_dev(sc->sc_atac.atac_dev, "unable to map PRB table memory, " "error=%d\n", error); - bus_dmamem_free(sc->sc_dmat, &seg, rseg); + bus_dmamem_free(sc->sc_dmat, + &schp->sch_prb_seg, schp->sch_prb_nseg); return; } @@ -291,7 +291,8 @@ "unable to create PRB table map, " "error=%d\n", error); bus_dmamem_unmap(sc->sc_dmat, prbp, dmasize); - bus_dmamem_free(sc->sc_dmat, &seg, rseg); + bus_dmamem_free(sc->sc_dmat, + &schp->sch_prb_seg, schp->sch_prb_nseg); return; } @@ -303,7 +304,8 @@ "error=%d\n", error); bus_dmamap_destroy(sc->sc_dmat, schp->sch_prbd); bus_dmamem_unmap(sc->sc_dmat, prbp, dmasize); - bus_dmamem_free(sc->sc_dmat, &seg, rseg); + bus_dmamem_free(sc->sc_dmat, + &schp->sch_prb_seg, schp->sch_prb_nseg); return; } @@ -362,7 +364,6 @@ struct scsipi_adapter *adapt = &atac->atac_atapi_adapter._generic; struct siisata_channel *schp; struct ata_channel *chp; - bus_dmamap_t dmam; int i, j, error; for (i = 0; i < sc->sc_atac.atac_nchannels; i++) { @@ -377,12 +378,12 @@ for (j = 0; j < SIISATA_MAX_SLOTS; j++) bus_dmamap_destroy(sc->sc_dmat, schp->sch_datad[j]); - dmam = schp->sch_prbd; - bus_dmamap_unload(sc->sc_dmat, dmam); - bus_dmamap_destroy(sc->sc_dmat, dmam); + bus_dmamap_unload(sc->sc_dmat, schp->sch_prbd); + bus_dmamap_destroy(sc->sc_dmat, schp->sch_prbd); bus_dmamem_unmap(sc->sc_dmat, schp->sch_prb[0], - dmam->dm_mapsize); - bus_dmamem_free(sc->sc_dmat, dmam->dm_segs, dmam->dm_nsegs); + SIISATA_CMD_SIZE * SIISATA_MAX_SLOTS); + bus_dmamem_free(sc->sc_dmat, + &schp->sch_prb_seg, schp->sch_prb_nseg); free(chp->ch_queue, M_DEVBUF); chp->atabus = NULL; Index: src/sys/dev/ic/siisatavar.h diff -u src/sys/dev/ic/siisatavar.h:1.5 src/sys/dev/ic/siisatavar.h:1.6 --- src/sys/dev/ic/siisatavar.h:1.5 Mon Oct 19 18:41:13 2009 +++ src/sys/dev/ic/siisatavar.h Mon Jul 26 15:41:33 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: siisatavar.h,v 1.5 2009/10/19 18:41:13 bouyer Exp $ */ +/* $NetBSD: siisatavar.h,v 1.6 2010/07/26 15:41:33 jakllsch Exp $ */ /* from ahcisatavar.h */ @@ -91,8 +91,10 @@ bus_space_handle_t sch_sstatus; bus_space_handle_t sch_serror; - /* command activation PRBs */ + bus_dma_segment_t sch_prb_seg; + int sch_prb_nseg; bus_dmamap_t sch_prbd; + /* command activation PRBs */ struct siisata_prb *sch_prb[SIISATA_MAX_SLOTS]; bus_addr_t sch_bus_prb[SIISATA_MAX_SLOTS];