Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Jan 2009 19:48:56 GMT
From:      Marius Strobl <marius@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 156822 for review
Message-ID:  <200901281948.n0SJmudD096982@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=156822

Change 156822 by marius@flak on 2009/01/28 19:48:33

	Fix vendor merge botches.

Affected files ...

.. //depot/projects/usiii/dev/sbni/if_sbni.c#3 add
.. //depot/projects/usiii/dev/sbni/if_sbni_isa.c#3 add
.. //depot/projects/usiii/dev/sbni/if_sbni_pci.c#3 add
.. //depot/projects/usiii/dev/sbni/if_sbnireg.h#3 add
.. //depot/projects/usiii/dev/sbni/if_sbnivar.h#3 add
.. //depot/projects/usiii/dev/usb/u3g.c#2 edit
.. //depot/projects/usiii/modules/sbni/Makefile#3 add
.. //depot/projects/usiii/sparc64/include/dcr.h#2 edit
.. //depot/projects/usiii/sparc64/pci/schizo.c#13 edit
.. //depot/projects/usiii/sparc64/pci/schizoreg.h#6 edit
.. //depot/projects/usiii/sparc64/pci/schizovar.h#5 edit
.. //depot/projects/usiii/sparc64/sparc64/jbusppm.c#2 edit
.. //depot/projects/usiii/sparc64/sparc64/schppm.c#2 edit
.. //depot/projects/usiii/ufs/ffs/ffs_alloc.c#5 edit
.. //depot/projects/usiii/ufs/ffs/ffs_balloc.c#5 edit
.. //depot/projects/usiii/ufs/ffs/ffs_extern.h#4 edit
.. //depot/projects/usiii/ufs/ffs/ffs_inode.c#6 edit
.. //depot/projects/usiii/ufs/ffs/ffs_vnops.c#8 edit

Differences ...

==== //depot/projects/usiii/dev/usb/u3g.c#2 (text+ko) ====

@@ -16,7 +16,7 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $FreeBSD: src/sys/dev/usb/u3g.c,v 1.21 2008/11/26 17:16:54 n_hibma Exp $
+ * $FreeBSD: src/sys/dev/usb/u3g.c,v 1.22 2009/01/27 19:37:30 n_hibma Exp $
  */
 
 /*
@@ -108,6 +108,9 @@
 	{7200000, 384000},
 };
 
+#define U3GIBUFSIZE	1024
+#define U3GOBUFSIZE	1024
+
 /*
  * Various supported device vendors/products.
  */
@@ -296,10 +299,9 @@
 				ucom->sc_iface = uaa->ifaces[i];
 				ucom->sc_bulkin_no = bulkin_no;
 				ucom->sc_bulkout_no = bulkout_no;
-				// Allocate a buffer enough for 10ms worth of data
-				ucom->sc_ibufsize = u3g_speeds[sc->sc_speed].ispeed/10/USB_FRAMES_PER_SECOND*10;
-				ucom->sc_ibufsizepad = ucom->sc_ibufsize;
-				ucom->sc_obufsize = u3g_speeds[sc->sc_speed].ospeed/10/USB_FRAMES_PER_SECOND*10;
+				ucom->sc_ibufsize = U3GIBUFSIZE;
+				ucom->sc_ibufsizepad = U3GIBUFSIZE;
+				ucom->sc_obufsize = U3GOBUFSIZE;
 				ucom->sc_opkthdrlen = 0;
 
 				ucom->sc_callback = &u3g_callback;
@@ -362,7 +364,6 @@
 	 * anyway.
 	 * Note: We abuse the fact that ucom sets the speed through
 	 * ispeed/ospeed, not through ispeedwat/ospeedwat.
-	 * XXX Are the speeds correct?
 	 */
 	if (portno == 0) {
 		struct u3g_softc *sc = addr;

==== //depot/projects/usiii/sparc64/include/dcr.h#2 (text+ko) ====

@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: src/sys/sparc64/include/dcr.h,v 1.1 2008/09/04 19:58:52 marius Exp $
  */
 
 #ifndef	_MACHINE_DCR_H_

==== //depot/projects/usiii/sparc64/pci/schizo.c#13 (text+ko) ====

@@ -1,7 +1,7 @@
 /*-
  * Copyright (c) 1999, 2000 Matthew R. Green
  * Copyright (c) 2001 - 2003 by Thomas Moestl <tmm@FreeBSD.org>
- * Copyright (c) 2005, 2008 by Marius Strobl <marius@FreeBSD.org>
+ * Copyright (c) 2005, 2007, 2008 by Marius Strobl <marius@FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: src/sys/sparc64/pci/schizo.c,v 1.5 2008/12/18 18:29:15 marius Exp $");
 
 /*
  * Driver for `Schizo' Fireplane/Safari to PCI 2.1 and `Tomatillo' JBus to
@@ -52,6 +52,7 @@
 #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>
@@ -64,7 +65,6 @@
 #include <machine/fsr.h>
 #include <machine/iommureg.h>
 #include <machine/iommuvar.h>
-#include <machine/ofw_bus.h>
 #include <machine/resource.h>
 
 #include <dev/pci/pcireg.h>
@@ -79,11 +79,13 @@
 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 +96,7 @@
 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);
@@ -170,14 +173,16 @@
 	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 +217,7 @@
 	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 +257,8 @@
 {
 	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 +272,7 @@
 	sc->sc_dev = dev;
 	sc->sc_node = node;
 	sc->sc_mode = mode;
+	sc->sc_flags = 0;
 
 	/*
 	 * The Schizo has three register banks:
@@ -302,7 +306,7 @@
 	}
 
 	/*
-	 * Match other Schizo's that are already configured against
+	 * Match other Schizos that are already configured against
 	 * the controller base physical address.  This will be the
 	 * same for a pair of devices that share register space.
 	 */
@@ -322,6 +326,8 @@
 			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 +394,10 @@
 
 	/*
 	 * 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 +410,10 @@
 		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);
 	}
 
 	/*
@@ -460,8 +453,10 @@
 	sc->sc_is.is_pmaxaddr = IOMMU_MAXADDR(STX_IOMMU_BITS);
 	sc->sc_is.is_sb[0] = 0;
 	sc->sc_is.is_sb[1] = 0;
+#ifdef notyet
 	if (OF_getproplen(node, "no-streaming-cache") < 0)
 		sc->sc_is.is_sb[0] = STX_PCI_STRBUF;
+#endif
 
 #define	TSBCASE(x)							\
 	case (IOTSB_BASESZ << (x)) << (IO_PAGE_SHIFT - IOTTE_SHIFT):	\
@@ -489,6 +484,7 @@
 		}
 		schizo_iommu_init(sc, tsbsize, prop_array[0]);
 	}
+
 #undef TSBCASE
 
 	/* Initialize memory and I/O rmans. */
@@ -627,6 +623,39 @@
 		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 +682,40 @@
 	    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 +858,15 @@
 	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 +1013,65 @@
 	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));
+		membar(Sync);
 		wr(fprs, reg, 0);
-		membar(Sync);
-		critical_exit();
+		intr_restore(s);
 	}
 	return (sds->sds_handler(sds->sds_arg));
 }
@@ -1021,56 +1119,108 @@
     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);
+		}
+		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;
+		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, schizo_dmasync, intr, sds, cookiep);
-		} else {
-			sds->sds_handler = (driver_filter_t *)intr;
-			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 +1228,9 @@
 		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 +1239,12 @@
 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 +1328,8 @@
 		    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);

==== //depot/projects/usiii/sparc64/pci/schizoreg.h#6 (text+ko) ====

@@ -25,13 +25,13 @@
  * POSSIBILITY OF SUCH DAMAGE.
  *
  *	from: OpenBSD: schizoreg.h,v 1.8 2005/05/19 18:28:59 mickey Exp
- * $FreeBSD$
+ * $FreeBSD: src/sys/sparc64/pci/schizoreg.h,v 1.2 2008/11/20 18:44:09 marius Exp $
  */
 
 #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 */

==== //depot/projects/usiii/sparc64/pci/schizovar.h#5 (text+ko) ====

@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: src/sys/sparc64/pci/schizovar.h,v 1.2 2008/11/20 18:44:09 marius Exp $
  */
 
 #ifndef _SPARC64_PCI_SCHIZOVAR_H_
@@ -39,9 +39,18 @@
 	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;

==== //depot/projects/usiii/sparc64/sparc64/jbusppm.c#2 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: src/sys/sparc64/sparc64/jbusppm.c,v 1.1 2008/09/10 20:22:27 marius Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>

==== //depot/projects/usiii/sparc64/sparc64/schppm.c#2 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: src/sys/sparc64/sparc64/schppm.c,v 1.1 2008/09/10 20:22:27 marius Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>

==== //depot/projects/usiii/ufs/ffs/ffs_alloc.c#5 (text+ko) ====

@@ -60,7 +60,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/ufs/ffs/ffs_alloc.c,v 1.150 2008/08/28 09:19:50 kib Exp $");
+__FBSDID("$FreeBSD: src/sys/ufs/ffs/ffs_alloc.c,v 1.151 2009/01/27 21:48:47 rwatson Exp $");
 
 #include "opt_quota.h"
 
@@ -130,10 +130,10 @@
  *      available block is located.
  */
 int
-ffs_alloc(ip, lbn, bpref, size, cred, bnp)
+ffs_alloc(ip, lbn, bpref, size, flags, cred, bnp)
 	struct inode *ip;
 	ufs2_daddr_t lbn, bpref;
-	int size;
+	int size, flags;
 	struct ucred *cred;
 	ufs2_daddr_t *bnp;
 {
@@ -191,7 +191,10 @@
 			UFS_UNLOCK(ump);
 		}
 		DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + delta);
-		ip->i_flag |= IN_CHANGE | IN_UPDATE;
+		if (flags & IO_EXT)
+			ip->i_flag |= IN_CHANGE;
+		else
+			ip->i_flag |= IN_CHANGE | IN_UPDATE;
 		*bnp = bno;
 		return (0);
 	}
@@ -227,12 +230,12 @@
  * invoked to get an appropriate block.
  */
 int
-ffs_realloccg(ip, lbprev, bprev, bpref, osize, nsize, cred, bpp)
+ffs_realloccg(ip, lbprev, bprev, bpref, osize, nsize, flags, cred, bpp)
 	struct inode *ip;
 	ufs2_daddr_t lbprev;
 	ufs2_daddr_t bprev;
 	ufs2_daddr_t bpref;
-	int osize, nsize;
+	int osize, nsize, flags;
 	struct ucred *cred;
 	struct buf **bpp;
 {
@@ -317,7 +320,10 @@
 			UFS_UNLOCK(ump);
 		}
 		DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + delta);
-		ip->i_flag |= IN_CHANGE | IN_UPDATE;
+		if (flags & IO_EXT)
+			ip->i_flag |= IN_CHANGE;
+		else
+			ip->i_flag |= IN_CHANGE | IN_UPDATE;
 		allocbuf(bp, nsize);
 		bp->b_flags |= B_DONE;
 		if ((bp->b_flags & (B_MALLOC | B_VMIO)) != B_VMIO)
@@ -392,7 +398,10 @@
 			UFS_UNLOCK(ump);
 		}
 		DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + delta);
-		ip->i_flag |= IN_CHANGE | IN_UPDATE;
+		if (flags & IO_EXT)
+			ip->i_flag |= IN_CHANGE;
+		else
+			ip->i_flag |= IN_CHANGE | IN_UPDATE;
 		allocbuf(bp, nsize);
 		bp->b_flags |= B_DONE;
 		if ((bp->b_flags & (B_MALLOC | B_VMIO)) != B_VMIO)

==== //depot/projects/usiii/ufs/ffs/ffs_balloc.c#5 (text+ko) ====

@@ -60,7 +60,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/ufs/ffs/ffs_balloc.c,v 1.54 2008/07/23 14:32:44 kib Exp $");
+__FBSDID("$FreeBSD: src/sys/ufs/ffs/ffs_balloc.c,v 1.55 2009/01/27 21:48:47 rwatson Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -133,7 +133,8 @@
 			UFS_LOCK(ump);
 			error = ffs_realloccg(ip, nb, dp->di_db[nb],
 			   ffs_blkpref_ufs1(ip, lastlbn, (int)nb,
-			   &dp->di_db[0]), osize, (int)fs->fs_bsize, cred, &bp);
+			   &dp->di_db[0]), osize, (int)fs->fs_bsize, flags,
+			   cred, &bp);
 			if (error)
 				return (error);
 			if (DOINGSOFTDEP(vp))
@@ -184,7 +185,8 @@
 				UFS_LOCK(ump);
 				error = ffs_realloccg(ip, lbn, dp->di_db[lbn],
 				    ffs_blkpref_ufs1(ip, lbn, (int)lbn,
-				    &dp->di_db[0]), osize, nsize, cred, &bp);
+				    &dp->di_db[0]), osize, nsize, flags,
+				    cred, &bp);
 				if (error)
 					return (error);
 				if (DOINGSOFTDEP(vp))
@@ -200,7 +202,7 @@
 			UFS_LOCK(ump);
 			error = ffs_alloc(ip, lbn,
 			    ffs_blkpref_ufs1(ip, lbn, (int)lbn, &dp->di_db[0]),
-			    nsize, cred, &newb);
+			    nsize, flags, cred, &newb);
 			if (error)
 				return (error);
 			bp = getblk(vp, lbn, nsize, 0, 0, 0);
@@ -241,7 +243,7 @@
 		UFS_LOCK(ump);
 		pref = ffs_blkpref_ufs1(ip, lbn, 0, (ufs1_daddr_t *)0);
 	        if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
-		    cred, &newb)) != 0) {
+		    flags, cred, &newb)) != 0) {
 			curthread->td_pflags &= saved_inbdflush;
 			return (error);
 		}
@@ -291,8 +293,8 @@
 		UFS_LOCK(ump);
 		if (pref == 0)
 			pref = ffs_blkpref_ufs1(ip, lbn, 0, (ufs1_daddr_t *)0);
-		if ((error =
-		    ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, &newb)) != 0) {
+		if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
+		    flags, cred, &newb)) != 0) {
 			brelse(bp);
 			goto fail;
 		}
@@ -346,7 +348,7 @@
 		UFS_LOCK(ump);
 		pref = ffs_blkpref_ufs1(ip, lbn, indirs[i].in_off, &bap[0]);
 		error = ffs_alloc(ip,
-		    lbn, pref, (int)fs->fs_bsize, cred, &newb);
+		    lbn, pref, (int)fs->fs_bsize, flags, cred, &newb);
 		if (error) {
 			brelse(bp);
 			goto fail;
@@ -534,7 +536,7 @@
 				    dp->di_extb[nb],
 				    ffs_blkpref_ufs2(ip, lastlbn, (int)nb,
 				    &dp->di_extb[0]), osize,
-				    (int)fs->fs_bsize, cred, &bp);
+				    (int)fs->fs_bsize, flags, cred, &bp);
 				if (error)
 					return (error);
 				if (DOINGSOFTDEP(vp))
@@ -545,7 +547,7 @@
 				dp->di_extsize = smalllblktosize(fs, nb + 1);
 				dp->di_extb[nb] = dbtofsb(fs, bp->b_blkno);
 				bp->b_xflags |= BX_ALTDATA;
-				ip->i_flag |= IN_CHANGE | IN_UPDATE;
+				ip->i_flag |= IN_CHANGE;
 				if (flags & IO_SYNC)
 					bwrite(bp);
 				else
@@ -588,7 +590,8 @@
 				error = ffs_realloccg(ip, -1 - lbn,
 				    dp->di_extb[lbn],
 				    ffs_blkpref_ufs2(ip, lbn, (int)lbn,
-				    &dp->di_extb[0]), osize, nsize, cred, &bp);
+				    &dp->di_extb[0]), osize, nsize, flags,
+				    cred, &bp);
 				if (error)
 					return (error);
 				bp->b_xflags |= BX_ALTDATA;
@@ -605,7 +608,7 @@
 			UFS_LOCK(ump);
 			error = ffs_alloc(ip, lbn,
 			   ffs_blkpref_ufs2(ip, lbn, (int)lbn, &dp->di_extb[0]),
-			   nsize, cred, &newb);
+			   nsize, flags, cred, &newb);
 			if (error)
 				return (error);
 			bp = getblk(vp, -1 - lbn, nsize, 0, 0, 0);
@@ -618,7 +621,7 @@
 				    nsize, 0, bp);
 		}
 		dp->di_extb[lbn] = dbtofsb(fs, bp->b_blkno);
-		ip->i_flag |= IN_CHANGE | IN_UPDATE;
+		ip->i_flag |= IN_CHANGE;
 		*bpp = bp;
 		return (0);
 	}
@@ -636,7 +639,7 @@
 			error = ffs_realloccg(ip, nb, dp->di_db[nb],
 				ffs_blkpref_ufs2(ip, lastlbn, (int)nb,
 				    &dp->di_db[0]), osize, (int)fs->fs_bsize,
-				    cred, &bp);
+				    flags, cred, &bp);
 			if (error)
 				return (error);
 			if (DOINGSOFTDEP(vp))
@@ -688,7 +691,8 @@
 				UFS_LOCK(ump);
 				error = ffs_realloccg(ip, lbn, dp->di_db[lbn],
 				    ffs_blkpref_ufs2(ip, lbn, (int)lbn,
-				       &dp->di_db[0]), osize, nsize, cred, &bp);
+				       &dp->di_db[0]), osize, nsize, flags,
+				    cred, &bp);
 				if (error)
 					return (error);
 				if (DOINGSOFTDEP(vp))
@@ -704,7 +708,7 @@
 			UFS_LOCK(ump);
 			error = ffs_alloc(ip, lbn,
 			    ffs_blkpref_ufs2(ip, lbn, (int)lbn,
-				&dp->di_db[0]), nsize, cred, &newb);
+				&dp->di_db[0]), nsize, flags, cred, &newb);
 			if (error)
 				return (error);
 			bp = getblk(vp, lbn, nsize, 0, 0, 0);
@@ -745,7 +749,7 @@
 		UFS_LOCK(ump);
 		pref = ffs_blkpref_ufs2(ip, lbn, 0, (ufs2_daddr_t *)0);
 	        if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
-		    cred, &newb)) != 0) {
+		    flags, cred, &newb)) != 0) {
 			curthread->td_pflags &= saved_inbdflush;
 			return (error);
 		}
@@ -795,8 +799,8 @@
 		UFS_LOCK(ump);
 		if (pref == 0)
 			pref = ffs_blkpref_ufs2(ip, lbn, 0, (ufs2_daddr_t *)0);
-		if ((error =
-		    ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, &newb)) != 0) {
+		if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
+		    flags, cred, &newb)) != 0) {
 			brelse(bp);
 			goto fail;
 		}
@@ -850,7 +854,7 @@
 		UFS_LOCK(ump);
 		pref = ffs_blkpref_ufs2(ip, lbn, indirs[i].in_off, &bap[0]);
 		error = ffs_alloc(ip,
-		    lbn, pref, (int)fs->fs_bsize, cred, &newb);
+		    lbn, pref, (int)fs->fs_bsize, flags, cred, &newb);
 		if (error) {
 			brelse(bp);
 			goto fail;

==== //depot/projects/usiii/ufs/ffs/ffs_extern.h#4 (text+ko) ====

@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)ffs_extern.h	8.6 (Berkeley) 3/30/95
- * $FreeBSD: src/sys/ufs/ffs/ffs_extern.h,v 1.77 2008/09/16 11:51:06 kib Exp $
+ * $FreeBSD: src/sys/ufs/ffs/ffs_extern.h,v 1.78 2009/01/27 21:48:47 rwatson Exp $
  */
 
 #ifndef _UFS_FFS_EXTERN_H
@@ -48,8 +48,8 @@
 struct vop_fsync_args;
 struct vop_reallocblks_args;
 
-int	ffs_alloc(struct inode *,
-	    ufs2_daddr_t, ufs2_daddr_t, int, struct ucred *, ufs2_daddr_t *);
+int	ffs_alloc(struct inode *, ufs2_daddr_t, ufs2_daddr_t, int, int,
+	    struct ucred *, ufs2_daddr_t *);
 int	ffs_balloc_ufs1(struct vnode *a_vp, off_t a_startoffset, int a_size,
             struct ucred *a_cred, int a_flags, struct buf **a_bpp);
 int	ffs_balloc_ufs2(struct vnode *a_vp, off_t a_startoffset, int a_size,
@@ -72,7 +72,7 @@
 int	ffs_mountroot(void);
 int	ffs_reallocblks(struct vop_reallocblks_args *);
 int	ffs_realloccg(struct inode *, ufs2_daddr_t, ufs2_daddr_t,
-	    ufs2_daddr_t, int, int, struct ucred *, struct buf **);
+	    ufs2_daddr_t, int, int, int, struct ucred *, struct buf **);
 int	ffs_sbupdate(struct ufsmount *, int, int);
 void	ffs_setblock(struct fs *, u_char *, ufs1_daddr_t);
 int	ffs_snapblkfree(struct fs *, struct vnode *, ufs2_daddr_t, long, ino_t);

==== //depot/projects/usiii/ufs/ffs/ffs_inode.c#6 (text+ko) ====

@@ -30,7 +30,7 @@

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200901281948.n0SJmudD096982>