diff options
author | marius <marius@FreeBSD.org> | 2011-03-29 19:48:03 +0000 |
---|---|---|
committer | marius <marius@FreeBSD.org> | 2011-03-29 19:48:03 +0000 |
commit | 9d571f70778884c98026689ff71368ffa7c1cb9d (patch) | |
tree | 0081bedf5e1d58f75c5a0c9ade553029765eafa4 /sys | |
parent | 8d3dbe6760ab9b60f6eb6d4e07a1571c0ec2b034 (diff) | |
download | FreeBSD-src-9d571f70778884c98026689ff71368ffa7c1cb9d.zip FreeBSD-src-9d571f70778884c98026689ff71368ffa7c1cb9d.tar.gz |
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.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/sparc64/pci/psycho.c | 25 | ||||
-rw-r--r-- | 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; |