summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2011-03-29 19:48:03 +0000
committermarius <marius@FreeBSD.org>2011-03-29 19:48:03 +0000
commit9d571f70778884c98026689ff71368ffa7c1cb9d (patch)
tree0081bedf5e1d58f75c5a0c9ade553029765eafa4
parent8d3dbe6760ab9b60f6eb6d4e07a1571c0ec2b034 (diff)
downloadFreeBSD-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.
-rw-r--r--sys/sparc64/pci/psycho.c25
-rw-r--r--sys/sparc64/pci/psychovar.h2
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;
OpenPOWER on IntegriCloud