From 9d571f70778884c98026689ff71368ffa7c1cb9d Mon Sep 17 00:00:00 2001 From: marius Date: Tue, 29 Mar 2011 19:48:03 +0000 Subject: Allocate memory for a DMA method table only in case we need to override the iommu(4) provided one, i.e. in case of Hummingbird and Sabre bridges, otherwise just use the iommu(4) one. This also fixes a bug introduced in r220039 which caused an empty DMA method table to be used for the second of a pair of Psycho bridges. --- sys/sparc64/pci/psycho.c | 25 +++++++++++++++++-------- sys/sparc64/pci/psychovar.h | 2 +- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c index 0a3e5d5..2b81f27 100644 --- a/sys/sparc64/pci/psycho.c +++ b/sys/sparc64/pci/psycho.c @@ -529,21 +529,29 @@ psycho_attach(device_t dev) * * For the moment, 32KB should be more than enough. */ - memcpy(&sc->sc_dma_methods, &iommu_dma_methods, - sizeof(sc->sc_dma_methods)); - sc->sc_is = malloc(sizeof(struct iommu_state), M_DEVBUF, - M_NOWAIT | M_ZERO); + sc->sc_is = malloc(sizeof(*sc->sc_is), M_DEVBUF, M_NOWAIT | + M_ZERO); if (sc->sc_is == NULL) - panic("%s: malloc iommu_state failed", __func__); + panic("%s: could not malloc IOMMU state", __func__); sc->sc_is->is_flags = IOMMU_PRESERVE_PROM; if (sc->sc_mode == PSYCHO_MODE_SABRE) { - sc->sc_dma_methods.dm_dmamap_sync = + sc->sc_dma_methods = + malloc(sizeof(*sc->sc_dma_methods), M_DEVBUF, + M_NOWAIT); + if (sc->sc_dma_methods == NULL) + panic("%s: could not malloc DMA methods", + __func__); + memcpy(sc->sc_dma_methods, &iommu_dma_methods, + sizeof(*sc->sc_dma_methods)); + sc->sc_dma_methods->dm_dmamap_sync = sabre_dmamap_sync; sc->sc_is->is_pmaxaddr = IOMMU_MAXADDR(SABRE_IOMMU_BITS); - } else + } else { + sc->sc_dma_methods = &iommu_dma_methods; sc->sc_is->is_pmaxaddr = IOMMU_MAXADDR(PSYCHO_IOMMU_BITS); + } sc->sc_is->is_sb[0] = sc->sc_is->is_sb[1] = 0; if (OF_getproplen(node, "no-streaming-cache") < 0) sc->sc_is->is_sb[0] = sc->sc_pcictl + PCR_STRBUF; @@ -551,6 +559,7 @@ psycho_attach(device_t dev) psycho_iommu_init(sc, 3, dvmabase); } else { /* Just copy IOMMU state, config tag and address. */ + sc->sc_dma_methods = &iommu_dma_methods; sc->sc_is = osc->sc_is; if (OF_getproplen(node, "no-streaming-cache") < 0) sc->sc_is->is_sb[1] = sc->sc_pcictl + PCR_STRBUF; @@ -567,7 +576,7 @@ psycho_attach(device_t dev) panic("%s: bus_dma_tag_create failed", __func__); /* Customize the tag. */ sc->sc_pci_dmat->dt_cookie = sc->sc_is; - sc->sc_pci_dmat->dt_mt = &sc->sc_dma_methods; + sc->sc_pci_dmat->dt_mt = sc->sc_dma_methods; i = OF_getprop(node, "bus-range", (void *)prop_array, sizeof(prop_array)); diff --git a/sys/sparc64/pci/psychovar.h b/sys/sparc64/pci/psychovar.h index df7b8a0..117b738 100644 --- a/sys/sparc64/pci/psychovar.h +++ b/sys/sparc64/pci/psychovar.h @@ -36,7 +36,7 @@ * per pair of psychos. */ struct psycho_softc { - struct bus_dma_methods sc_dma_methods; + struct bus_dma_methods *sc_dma_methods; device_t sc_dev; -- cgit v1.1