svn commit: r190297 - in stable/7/sys: . conf contrib/pf
dev/ath/ath_hal dev/cxgb sparc64/pci sparc64/sparc64
Marius Strobl
marius at FreeBSD.org
Sun Mar 22 15:19:55 PDT 2009
Author: marius
Date: Sun Mar 22 22:19:54 2009
New Revision: 190297
URL: http://svn.freebsd.org/changeset/base/190297
Log:
MFC: r183423, r184428, r185133, r186290, r190108
Add a driver for `Schizo' Fireplane/Safari to PCI 2.1 and `Tomatillo'
JBus to PCI 2.2 bridges including subsequent fixes and improvements
as of r190108.
Added:
stable/7/sys/sparc64/pci/schizo.c
- copied, changed from r183423, head/sys/sparc64/pci/schizo.c
stable/7/sys/sparc64/pci/schizoreg.h
- copied, changed from r183423, head/sys/sparc64/pci/schizoreg.h
stable/7/sys/sparc64/pci/schizovar.h
- copied, changed from r183423, head/sys/sparc64/pci/schizovar.h
Modified:
stable/7/sys/ (props changed)
stable/7/sys/conf/files.sparc64
stable/7/sys/conf/options.sparc64
stable/7/sys/contrib/pf/ (props changed)
stable/7/sys/dev/ath/ath_hal/ (props changed)
stable/7/sys/dev/cxgb/ (props changed)
stable/7/sys/sparc64/sparc64/nexus.c
Modified: stable/7/sys/conf/files.sparc64
==============================================================================
--- stable/7/sys/conf/files.sparc64 Sun Mar 22 22:14:46 2009 (r190296)
+++ stable/7/sys/conf/files.sparc64 Sun Mar 22 22:19:54 2009 (r190297)
@@ -74,6 +74,7 @@ sparc64/pci/ofw_pcib.c optional pci
sparc64/pci/ofw_pcib_subr.c optional pci
sparc64/pci/ofw_pcibus.c optional pci
sparc64/pci/psycho.c optional pci
+sparc64/pci/schizo.c optional pci
sparc64/sbus/dma_sbus.c optional sbus
sparc64/sbus/sbus.c optional sbus
sparc64/sbus/lsi64854.c optional sbus
Modified: stable/7/sys/conf/options.sparc64
==============================================================================
--- stable/7/sys/conf/options.sparc64 Sun Mar 22 22:14:46 2009 (r190296)
+++ stable/7/sys/conf/options.sparc64 Sun Mar 22 22:19:54 2009 (r190297)
@@ -24,5 +24,7 @@ PSM_RESETAFTERSUSPEND opt_psm.h
DEBUGGER_ON_POWERFAIL opt_psycho.h
PSYCHO_DEBUG opt_psycho.h
+SCHIZO_DEBUG opt_schizo.h
+
SUNKBD_DFLT_KEYMAP opt_sunkbd.h
SUNKBD_EMULATE_ATKBD opt_sunkbd.h
Copied and modified: stable/7/sys/sparc64/pci/schizo.c (from r183423, head/sys/sparc64/pci/schizo.c)
==============================================================================
--- head/sys/sparc64/pci/schizo.c Sun Sep 28 00:07:05 2008 (r183423, copy source)
+++ stable/7/sys/sparc64/pci/schizo.c Sun Mar 22 22:19:54 2009 (r190297)
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/pcpu.h>
#include <sys/rman.h>
+#include <sys/time.h>
#include <sys/timetc.h>
#include <dev/ofw/ofw_bus.h>
@@ -79,11 +80,13 @@ __FBSDID("$FreeBSD$");
static const struct schizo_desc *schizo_get_desc(device_t);
static void schizo_set_intr(struct schizo_softc *, u_int, u_int,
driver_filter_t);
-static driver_filter_t schizo_dmasync;
+static driver_filter_t schizo_dma_sync_stub;
+static driver_filter_t ichip_dma_sync_stub;
static void schizo_intr_enable(void *);
static void schizo_intr_disable(void *);
static void schizo_intr_assign(void *);
static void schizo_intr_clear(void *);
+static int schizo_intr_register(struct schizo_softc *sc, u_int ino);
static int schizo_get_intrmap(struct schizo_softc *, u_int,
bus_addr_t *, bus_addr_t *);
static bus_space_tag_t schizo_alloc_bus_tag(struct schizo_softc *, int);
@@ -94,6 +97,7 @@ static driver_filter_t schizo_pci_bus;
static driver_filter_t schizo_ue;
static driver_filter_t schizo_ce;
static driver_filter_t schizo_host_bus;
+static driver_filter_t schizo_cdma;
/* IOMMU support */
static void schizo_iommu_init(struct schizo_softc *, int, uint32_t);
@@ -145,7 +149,7 @@ static device_method_t schizo_methods[]
/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_node, schizo_get_node),
- { 0, 0 }
+ KOBJMETHOD_END
};
static devclass_t schizo_devclass;
@@ -170,14 +174,16 @@ struct schizo_icarg {
bus_addr_t sica_clr;
};
-struct schizo_dmasync {
+struct schizo_dma_sync {
struct schizo_softc *sds_sc;
driver_filter_t *sds_handler;
void *sds_arg;
void *sds_cookie;
- bus_size_t sds_syncreg;
uint64_t sds_syncval;
- u_int sds_bswar;
+ device_t sds_ppb; /* farest PCI-PCI bridge */
+ uint8_t sds_bus; /* bus of farest PCI device */
+ uint8_t sds_slot; /* slot of farest PCI device */
+ uint8_t sds_func; /* func. of farest PCI device */
};
#define SCHIZO_PERF_CNT_QLTY 100
@@ -212,7 +218,7 @@ struct schizo_desc {
const char *sd_name;
};
-static const struct schizo_desc schizo_compats[] = {
+static const struct schizo_desc const schizo_compats[] = {
{ "pci108e,8001", SCHIZO_MODE_SCZ, "Schizo" },
{ "pci108e,a801", SCHIZO_MODE_TOM, "Tomatillo" },
{ NULL, 0, NULL }
@@ -252,10 +258,8 @@ schizo_attach(device_t dev)
{
struct ofw_pci_ranges *range;
const struct schizo_desc *desc;
- struct schizo_icarg *sica;
struct schizo_softc *asc, *sc, *osc;
struct timecounter *tc;
- bus_addr_t intrclr, intrmap;
uint64_t ino_bitmap, reg;
phandle_t node;
uint32_t prop, prop_array[2];
@@ -269,6 +273,7 @@ schizo_attach(device_t dev)
sc->sc_dev = dev;
sc->sc_node = node;
sc->sc_mode = mode;
+ sc->sc_flags = 0;
/*
* The Schizo has three register banks:
@@ -322,6 +327,8 @@ schizo_attach(device_t dev)
panic("%s: could not malloc mutex", __func__);
mtx_init(sc->sc_mtx, "pcib_mtx", NULL, MTX_SPIN);
} else {
+ if (sc->sc_mode != SCHIZO_MODE_SCZ)
+ panic("%s: no partner expected", __func__);
if (mtx_initialized(osc->sc_mtx) == 0)
panic("%s: mutex not initialized", __func__);
sc->sc_mtx = osc->sc_mtx;
@@ -388,9 +395,10 @@ schizo_attach(device_t dev)
/*
* Hunt through all the interrupt mapping regs and register
- * the interrupt controller for our interrupt vectors. This
- * is complicated by the fact that a pair of Schizo PBMs
- * share one IGN.
+ * the interrupt controller for our interrupt vectors. We do
+ * this early in order to be able to catch stray interrupts.
+ * This is complicated by the fact that a pair of Schizo PBMs
+ * shares one IGN.
*/
n = OF_getprop(node, "ino-bitmap", (void *)prop_array,
sizeof(prop_array));
@@ -403,24 +411,10 @@ schizo_attach(device_t dev)
if (n == STX_FB0_INO || n == STX_FB1_INO)
/* Leave for upa(4). */
continue;
- if (schizo_get_intrmap(sc, n, &intrmap, &intrclr) == 0)
- continue;
- sica = malloc(sizeof(*sica), M_DEVBUF, M_NOWAIT);
- if (sica == NULL)
- panic("%s: could not allocate interrupt controller "
- "argument", __func__);
- sica->sica_sc = sc;
- sica->sica_map = intrmap;
- sica->sica_clr = intrclr;
-#ifdef SCHIZO_DEBUG
- device_printf(dev, "intr map (INO %d) %#lx: %#lx, clr: %#lx\n",
- n, (u_long)intrmap, (u_long)SCHIZO_PCI_READ_8(sc, intrmap),
- (u_long)intrclr);
-#endif
- if (intr_controller_register(INTMAP_VEC(sc->sc_ign, n),
- &schizo_ic, sica) != 0)
- panic("%s: could not register interrupt controller "
- "for INO %d", __func__, n);
+ i = schizo_intr_register(sc, n);
+ if (i != 0)
+ device_printf(dev, "could not register interrupt "
+ "controller for INO %d (%d)\n", n, i);
}
/*
@@ -456,11 +450,16 @@ schizo_attach(device_t dev)
tc_init(tc);
}
- /* Set up the IOMMU. Both Schizo and Tomatillo have one per PBM. */
+ /*
+ * Set up the IOMMU. Schizo, Tomatillo and XMITS all have
+ * one per PBM. Schizo and XMITS additionally have a streaming
+ * buffer, in Schizo version < 5 (i.e. revision < 2.3) it's
+ * affected by several errata and basically unusable though.
+ */
sc->sc_is.is_pmaxaddr = IOMMU_MAXADDR(STX_IOMMU_BITS);
- sc->sc_is.is_sb[0] = 0;
- sc->sc_is.is_sb[1] = 0;
- if (OF_getproplen(node, "no-streaming-cache") < 0)
+ sc->sc_is.is_sb[0] = sc->sc_is.is_sb[1] = 0;
+ if (OF_getproplen(node, "no-streaming-cache") < 0 &&
+ !(sc->sc_mode == SCHIZO_MODE_SCZ && sc->sc_ver < 5))
sc->sc_is.is_sb[0] = STX_PCI_STRBUF;
#define TSBCASE(x) \
@@ -489,6 +488,7 @@ schizo_attach(device_t dev)
}
schizo_iommu_init(sc, tsbsize, prop_array[0]);
}
+
#undef TSBCASE
/* Initialize memory and I/O rmans. */
@@ -627,6 +627,39 @@ schizo_attach(device_t dev)
schizo_set_intr(sc, 3, STX_BUS_INO, schizo_host_bus);
/*
+ * According to the Schizo Errata I-13, consistent DMA flushing/
+ * syncing is FUBAR in version < 5 (i.e. revision < 2.3) bridges,
+ * so we can't use it and need to live with the consequences.
+ * With Schizo version >= 5, CDMA flushing/syncing is usable
+ * but requires the the workaround described in Schizo Errata
+ * I-23. With Tomatillo and XMITS, CDMA flushing/syncing works
+ * as expected, Tomatillo version <= 4 (i.e. revision <= 2.3)
+ * bridges additionally require a block store after a write to
+ * TOMXMS_PCI_DMA_SYNC_PEND though.
+ */
+ if ((sc->sc_mode == SCHIZO_MODE_SCZ && sc->sc_ver >= 5) ||
+ sc->sc_mode == SCHIZO_MODE_TOM || sc->sc_mode == SCHIZO_MODE_XMS) {
+ sc->sc_flags |= SCHIZO_FLAGS_CDMA;
+ if (sc->sc_mode == SCHIZO_MODE_SCZ) {
+ n = STX_CDMA_A_INO + sc->sc_half;
+ if (bus_set_resource(dev, SYS_RES_IRQ, 5,
+ INTMAP_VEC(sc->sc_ign, n), 1) != 0)
+ panic("%s: failed to add CDMA interrupt",
+ __func__);
+ i = schizo_intr_register(sc, n);
+ if (i != 0)
+ panic("%s: could not register interrupt "
+ "controller for CDMA (%d)", __func__, i);
+ (void)schizo_get_intrmap(sc, n, NULL,
+ &sc->sc_cdma_clr);
+ sc->sc_cdma_state = SCHIZO_CDMA_STATE_DONE;
+ schizo_set_intr(sc, 5, n, schizo_cdma);
+ }
+ if (sc->sc_mode == SCHIZO_MODE_TOM && sc->sc_ver <= 4)
+ sc->sc_flags |= SCHIZO_FLAGS_BSWAR;
+ }
+
+ /*
* Set the latency timer register as this isn't always done by the
* firmware.
*/
@@ -653,12 +686,40 @@ schizo_set_intr(struct schizo_softc *sc,
INTIGN(vec = rman_get_start(sc->sc_irq_res[index])) != sc->sc_ign ||
INTINO(vec) != ino ||
intr_vectors[vec].iv_ic != &schizo_ic ||
- bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index], INTR_TYPE_MISC,
- handler, NULL, sc, &sc->sc_ihand[index]) != 0)
+ bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index],
+ INTR_TYPE_MISC | INTR_FAST, handler, NULL, sc,
+ &sc->sc_ihand[index]) != 0)
panic("%s: failed to set up interrupt %d", __func__, index);
}
static int
+schizo_intr_register(struct schizo_softc *sc, u_int ino)
+{
+ struct schizo_icarg *sica;
+ bus_addr_t intrclr, intrmap;
+ int error;
+
+ if (schizo_get_intrmap(sc, ino, &intrmap, &intrclr) == 0)
+ return (ENXIO);
+ sica = malloc(sizeof(*sica), M_DEVBUF, M_NOWAIT);
+ if (sica == NULL)
+ return (ENOMEM);
+ sica->sica_sc = sc;
+ sica->sica_map = intrmap;
+ sica->sica_clr = intrclr;
+#ifdef SCHIZO_DEBUG
+ device_printf(sc->sc_dev, "intr map (INO %d) %#lx: %#lx, clr: %#lx\n",
+ ino, (u_long)intrmap, (u_long)SCHIZO_PCI_READ_8(sc, intrmap),
+ (u_long)intrclr);
+#endif
+ error = (intr_controller_register(INTMAP_VEC(sc->sc_ign, ino),
+ &schizo_ic, sica));
+ if (error != 0)
+ free(sica, M_DEVBUF);
+ return (error);
+}
+
+static int
schizo_get_intrmap(struct schizo_softc *sc, u_int ino, bus_addr_t *intrmapptr,
bus_addr_t *intrclrptr)
{
@@ -801,6 +862,15 @@ schizo_host_bus(void *arg)
return (FILTER_HANDLED);
}
+static int
+schizo_cdma(void *arg)
+{
+ struct schizo_softc *sc = arg;
+
+ atomic_store_rel_32(&sc->sc_cdma_state, SCHIZO_CDMA_STATE_DONE);
+ return (FILTER_HANDLED);
+}
+
static void
schizo_iommu_init(struct schizo_softc *sc, int tsbsize, uint32_t dvmabase)
{
@@ -947,33 +1017,65 @@ schizo_read_ivar(device_t dev, device_t
return (ENOENT);
}
+static int
+schizo_dma_sync_stub(void *arg)
+{
+ struct timeval cur, end;
+ struct schizo_dma_sync *sds = arg;
+ struct schizo_softc *sc = sds->sds_sc;
+ uint32_t state;
+
+ (void)PCIB_READ_CONFIG(sds->sds_ppb, sds->sds_bus, sds->sds_slot,
+ sds->sds_func, PCIR_VENDOR, 2);
+ for (; atomic_cmpset_acq_32(&sc->sc_cdma_state, SCHIZO_CDMA_STATE_DONE,
+ SCHIZO_CDMA_STATE_PENDING) == 0;)
+ ;
+ SCHIZO_PCI_WRITE_8(sc, sc->sc_cdma_clr, 1);
+ microuptime(&cur);
+ end.tv_sec = 1;
+ end.tv_usec = 0;
+ timevaladd(&end, &cur);
+ for (; (state = atomic_load_32(&sc->sc_cdma_state)) !=
+ SCHIZO_CDMA_STATE_DONE && timevalcmp(&cur, &end, <=);)
+ microuptime(&cur);
+ if (state != SCHIZO_CDMA_STATE_DONE)
+ panic("%s: DMA does not sync", __func__);
+ return (sds->sds_handler(sds->sds_arg));
+}
+
#define VIS_BLOCKSIZE 64
static int
-schizo_dmasync(void *arg)
+ichip_dma_sync_stub(void *arg)
{
static u_char buf[VIS_BLOCKSIZE] __aligned(VIS_BLOCKSIZE);
- struct schizo_dmasync *sds = arg;
+ struct timeval cur, end;
+ struct schizo_dma_sync *sds = arg;
struct schizo_softc *sc = sds->sds_sc;
- uint64_t reg;
- int timeout;
+ register_t reg, s;
- SCHIZO_PCI_WRITE_8(sc, sds->sds_syncreg, sds->sds_syncval);
- timeout = 1000000;
- for (; (SCHIZO_PCI_READ_8(sc, sds->sds_syncreg) &
- sds->sds_syncval) != 0;)
- if (--timeout < 0)
- panic("%s: DMA does not sync", __func__);
+ (void)PCIB_READ_CONFIG(sds->sds_ppb, sds->sds_bus, sds->sds_slot,
+ sds->sds_func, PCIR_VENDOR, 2);
+ SCHIZO_PCI_WRITE_8(sc, TOMXMS_PCI_DMA_SYNC_PEND, sds->sds_syncval);
+ microuptime(&cur);
+ end.tv_sec = 1;
+ end.tv_usec = 0;
+ timevaladd(&end, &cur);
+ for (; ((reg = SCHIZO_PCI_READ_8(sc, TOMXMS_PCI_DMA_SYNC_PEND)) &
+ sds->sds_syncval) != 0 && timevalcmp(&cur, &end, <=);)
+ microuptime(&cur);
+ if ((reg & sds->sds_syncval) != 0)
+ panic("%s: DMA does not sync", __func__);
- if (sds->sds_bswar != 0) {
- critical_enter();
+ if ((sc->sc_flags & SCHIZO_FLAGS_BSWAR) != 0) {
+ s = intr_disable();
reg = rd(fprs);
wr(fprs, reg | FPRS_FEF, 0);
- __asm__ __volatile__("stda %%f0, [%0] %1"
+ __asm __volatile("stda %%f0, [%0] %1"
: : "r" (buf), "n" (ASI_BLK_COMMIT_S));
- wr(fprs, reg, 0);
membar(Sync);
- critical_exit();
+ wr(fprs, reg, 0);
+ intr_restore(s);
}
return (sds->sds_handler(sds->sds_arg));
}
@@ -1021,56 +1123,109 @@ schizo_setup_intr(device_t dev, device_t
int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
void **cookiep)
{
- struct schizo_dmasync *sds;
+ devclass_t pci_devclass;
+ device_t cdev, pdev, pcidev;
+ struct schizo_dma_sync *sds;
struct schizo_softc *sc;
u_long vec;
- int error;
+ int error, found;
sc = device_get_softc(dev);
/*
- * Make sure the vector is fully specified and we registered
- * our interrupt controller for it.
+ * Make sure the vector is fully specified.
*/
vec = rman_get_start(ires);
- if (INTIGN(vec) != sc->sc_ign ||
- intr_vectors[vec].iv_ic != &schizo_ic) {
+ if (INTIGN(vec) != sc->sc_ign) {
device_printf(dev, "invalid interrupt vector 0x%lx\n", vec);
return (EINVAL);
}
+ if (intr_vectors[vec].iv_ic == &schizo_ic) {
+ /*
+ * Ensure we use the right softc in case the interrupt
+ * is routed to our companion PBM for some odd reason.
+ */
+ sc = ((struct schizo_icarg *)intr_vectors[vec].iv_icarg)->
+ sica_sc;
+ } else if (intr_vectors[vec].iv_ic == NULL) {
+ /*
+ * Work around broken firmware which misses entries in
+ * the ino-bitmap.
+ */
+ error = schizo_intr_register(sc, INTINO(vec));
+ if (error != 0) {
+ device_printf(dev, "could not register interrupt "
+ "controller for vector 0x%lx (%d)\n", vec, error);
+ return (error);
+ }
+ if (bootverbose)
+ device_printf(dev, "belatedly registered as "
+ "interrupt controller for vector 0x%lx\n", vec);
+ } else {
+ device_printf(dev,
+ "invalid interrupt controller for vector 0x%lx\n", vec);
+ return (EINVAL);
+ }
+
/*
- * Schizo revision >= 2.3 (i.e. version >= 5) and Tomatillo bridges
- * need to be manually told to sync DMA writes.
- * Tomatillo revision <= 2.3 (i.e. version <= 4) bridges additionally
- * need a block store as a workaround for a hardware bug.
- * XXX setup of the wrapper and the contents of schizo_dmasync()
- * should be moved to schizo(4)-specific bus_dma_tag_create() and
- * bus_dmamap_sync() methods, respectively, once DMA tag creation
- * is newbus'ified, so the wrapper isn't only applied for interrupt
- * handlers but also for polling(4) callbacks.
+ * Install a a wrapper for CDMA flushing/syncing for devices
+ * behind PCI-PCI bridges if possible.
*/
- if ((sc->sc_mode == SCHIZO_MODE_SCZ && sc->sc_ver >= 5) ||
- sc->sc_mode == SCHIZO_MODE_TOM) {
+ pcidev = NULL;
+ found = 0;
+ pci_devclass = devclass_find("pci");
+ for (cdev = child; cdev != dev; cdev = pdev) {
+ pdev = device_get_parent(cdev);
+ if (pcidev == NULL) {
+ if (device_get_devclass(pdev) != pci_devclass)
+ continue;
+ pcidev = cdev;
+ continue;
+ }
+ if (pci_get_class(cdev) == PCIC_BRIDGE &&
+ pci_get_subclass(cdev) == PCIS_BRIDGE_PCI)
+ found = 1;
+ }
+ if ((sc->sc_flags & SCHIZO_FLAGS_CDMA) != 0) {
sds = malloc(sizeof(*sds), M_DEVBUF, M_NOWAIT | M_ZERO);
if (sds == NULL)
return (ENOMEM);
- sds->sds_sc = sc;
- sds->sds_arg = arg;
- sds->sds_syncreg = sc->sc_mode == SCHIZO_MODE_SCZ ?
- SCZ_PCI_DMA_SYNC : TOMXMS_PCI_DMA_SYNC_PEND;
- sds->sds_syncval = 1ULL << INTINO(vec);
- if (sc->sc_mode == SCHIZO_MODE_TOM && sc->sc_ver <= 4)
- sds->sds_bswar = 1;
- if (intr == NULL) {
- sds->sds_handler = filt;
- error = bus_generic_setup_intr(dev, child, ires,
- flags, schizo_dmasync, intr, sds, cookiep);
- } else {
- sds->sds_handler = (driver_filter_t *)intr;
+ if (found != 0 && pcidev != NULL) {
+ sds->sds_sc = sc;
+ sds->sds_arg = arg;
+ sds->sds_ppb =
+ device_get_parent(device_get_parent(pcidev));
+ sds->sds_bus = pci_get_bus(pcidev);
+ sds->sds_slot = pci_get_slot(pcidev);
+ sds->sds_func = pci_get_function(pcidev);
+ sds->sds_syncval = 1ULL << INTINO(vec);
+ if (bootverbose)
+ device_printf(dev, "installed DMA sync "
+ "wrapper for device %d.%d on bus %d\n",
+ sds->sds_slot, sds->sds_func,
+ sds->sds_bus);
+
+#define DMA_SYNC_STUB \
+ (sc->sc_mode == SCHIZO_MODE_SCZ ? schizo_dma_sync_stub : \
+ ichip_dma_sync_stub)
+
+ if (intr == NULL) {
+ sds->sds_handler = filt;
+ error = bus_generic_setup_intr(dev, child,
+ ires, flags, DMA_SYNC_STUB, intr, sds,
+ cookiep);
+ } else {
+ sds->sds_handler = (driver_filter_t *)intr;
+ error = bus_generic_setup_intr(dev, child,
+ ires, flags, filt, (driver_intr_t *)
+ DMA_SYNC_STUB, sds, cookiep);
+ }
+
+#undef DMA_SYNC_STUB
+
+ } else
error = bus_generic_setup_intr(dev, child, ires,
- flags, filt, (driver_intr_t *)schizo_dmasync,
- sds, cookiep);
- }
+ flags, filt, intr, arg, cookiep);
if (error != 0) {
free(sds, M_DEVBUF);
return (error);
@@ -1078,7 +1233,9 @@ schizo_setup_intr(device_t dev, device_t
sds->sds_cookie = *cookiep;
*cookiep = sds;
return (error);
- }
+ } else if (found != 0)
+ device_printf(dev, "WARNING: using devices behind PCI-PCI "
+ "bridges may cause data corruption\n");
return (bus_generic_setup_intr(dev, child, ires, flags, filt, intr,
arg, cookiep));
}
@@ -1087,12 +1244,12 @@ static int
schizo_teardown_intr(device_t dev, device_t child, struct resource *vec,
void *cookie)
{
- struct schizo_dmasync *sds;
+ struct schizo_dma_sync *sds;
struct schizo_softc *sc;
int error;
sc = device_get_softc(dev);
- if (sc->sc_mode == SCHIZO_MODE_TOM) {
+ if ((sc->sc_flags & SCHIZO_FLAGS_CDMA) != 0) {
sds = cookie;
error = bus_generic_teardown_intr(dev, child, vec,
sds->sds_cookie);
@@ -1176,8 +1333,8 @@ schizo_activate_resource(device_t bus, d
type, rid, r));
if (type == SYS_RES_MEMORY) {
/*
- * Need to memory-map the device space, as some drivers depend
- * on the virtual address being set and useable.
+ * Need to memory-map the device space, as some drivers
+ * depend on the virtual address being set and usable.
*/
error = sparc64_bus_mem_map(rman_get_bustag(r),
rman_get_bushandle(r), rman_get_size(r), 0, 0, &p);
Copied and modified: stable/7/sys/sparc64/pci/schizoreg.h (from r183423, head/sys/sparc64/pci/schizoreg.h)
==============================================================================
--- head/sys/sparc64/pci/schizoreg.h Sun Sep 28 00:07:05 2008 (r183423, copy source)
+++ stable/7/sys/sparc64/pci/schizoreg.h Sun Mar 22 22:19:54 2009 (r190297)
@@ -31,7 +31,7 @@
#ifndef _SPARC64_PCI_SCHIZOREG_H_
#define _SPARC64_PCI_SCHIZOREG_H_
-#define STX_NINTR 4
+#define STX_NINTR 5 /* 4 via OFW + 1 CDMA */
#define STX_NRANGE 4
#define SCZ_NREG 3
#define TOM_NREG 4
@@ -276,6 +276,8 @@
#define STX_PCIERR_A_INO 0x32 /* PCI bus A error */
#define STX_PCIERR_B_INO 0x33 /* PCI bus B error */
#define STX_BUS_INO 0x34 /* Safari/JBus error */
+#define STX_CDMA_A_INO 0x35 /* PCI bus A CDMA */
+#define STX_CDMA_B_INO 0x36 /* PCI bus B CDMA */
#define STX_MAX_INO 0x37
/* Device space defines */
Copied and modified: stable/7/sys/sparc64/pci/schizovar.h (from r183423, head/sys/sparc64/pci/schizovar.h)
==============================================================================
--- head/sys/sparc64/pci/schizovar.h Sun Sep 28 00:07:05 2008 (r183423, copy source)
+++ stable/7/sys/sparc64/pci/schizovar.h Sun Mar 22 22:19:54 2009 (r190297)
@@ -39,9 +39,18 @@ struct schizo_softc {
phandle_t sc_node;
u_int sc_mode;
-#define SCHIZO_MODE_SCZ 1
-#define SCHIZO_MODE_TOM 2
-#define SCHIZO_MODE_XMS 3
+#define SCHIZO_MODE_SCZ 0
+#define SCHIZO_MODE_TOM 1
+#define SCHIZO_MODE_XMS 2
+
+ u_int sc_flags;
+#define SCHIZO_FLAGS_BSWAR (1 << 0)
+#define SCHIZO_FLAGS_CDMA (1 << 1)
+
+ bus_addr_t sc_cdma_clr;
+ uint32_t sc_cdma_state;
+#define SCHIZO_CDMA_STATE_DONE (1 << 0)
+#define SCHIZO_CDMA_STATE_PENDING (1 << 1)
u_int sc_half;
uint32_t sc_ign;
Modified: stable/7/sys/sparc64/sparc64/nexus.c
==============================================================================
--- stable/7/sys/sparc64/sparc64/nexus.c Sun Mar 22 22:14:46 2009 (r190296)
+++ stable/7/sys/sparc64/sparc64/nexus.c Sun Mar 22 22:19:54 2009 (r190297)
@@ -96,7 +96,7 @@ static ofw_bus_get_devinfo_t nexus_get_d
#ifdef SMP
static int nexus_bind_intr(device_t, device_t, struct resource *, int);
#endif
-static int nexus_inlist(const char *, const char **);
+static int nexus_inlist(const char *, const char *const *);
static struct nexus_devinfo * nexus_setup_dinfo(device_t, phandle_t);
static void nexus_destroy_dinfo(struct nexus_devinfo *);
static int nexus_print_res(struct nexus_devinfo *);
@@ -122,6 +122,7 @@ static device_method_t nexus_methods[] =
DEVMETHOD(bus_release_resource, nexus_release_resource),
DEVMETHOD(bus_setup_intr, nexus_setup_intr),
DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
+ DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
DEVMETHOD(bus_get_resource_list, nexus_get_resource_list),
#ifdef SMP
@@ -145,7 +146,7 @@ static devclass_t nexus_devclass;
DEFINE_CLASS_0(nexus, nexus_driver, nexus_methods, sizeof(struct nexus_softc));
DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
-static const char *nexus_excl_name[] = {
+static const char *const nexus_excl_name[] = {
"aliases",
"associations",
"chosen",
@@ -159,7 +160,7 @@ static const char *nexus_excl_name[] = {
NULL
};
-static const char *nexus_excl_type[] = {
+static const char *const nexus_excl_type[] = {
"cpu",
NULL
};
@@ -168,7 +169,7 @@ extern struct bus_space_tag nexus_bustag
extern struct bus_dma_tag nexus_dmatag;
static int
-nexus_inlist(const char *name, const char **list)
+nexus_inlist(const char *name, const char *const *list)
{
int i;
More information about the svn-src-stable-7
mailing list