Author: marius
Date: Sat Mar 26 16:49:12 2011
New Revision: 220038
URL: http://svn.freebsd.org/changeset/base/220038

Log:
  - Merge the *_SET macros from fire(4) which generally print out the
    register changes when compiled with SCHIZO_DEBUG and take advantage
    of them.
  - Add support for the XMITS Fireplane/Safari to PCI-X bridges. I tought
    I'd need this for a Sun Fire 3800, which then turned out to not being
    equipped with such a bridge though. The support for these should be
    complete but given that it hasn't actually been tested probing is
    disabled for now.
    This required a way to alter the XMITS configuration in case a PCI-X
    device is found further down the device tree so the sparc64 specific
    ofw_pci kobj was revived with a ofw_pci_setup_device method, which is
    called by the ofw_pcibus code for every device added.
  - A closer inspection of the OpenSolaris code indicates that consistent
    DMA flushing/syncing as well as the block store workaround should be
    applied with every BUS_DMASYNC_POSTREAD instead of in a wrapper around
    interrupt handlers for devices behind PCI-PCI bridges only as suggested
    by the documentation (code for the latter actually exists in OpenSolaris
    but is disabled by default), which also makes more sense.
  - Add a workaround for Casinni/Skyhawk combinations. Chances are that
    this solves the crashes seen when using the the on-board Casinni NICs
    of Sun Fire V480 equipped with centerplanes other than 501-6780 or
    501-6790. This also takes advantage of the ofw_pci_setup_device method.
  - Mark some unused parameters as such.

Modified:
  head/sys/conf/files.sparc64
  head/sys/conf/files.sun4v
  head/sys/sparc64/pci/ofw_pci.h
  head/sys/sparc64/pci/ofw_pci_if.m
  head/sys/sparc64/pci/ofw_pcibus.c
  head/sys/sparc64/pci/schizo.c
  head/sys/sparc64/pci/schizoreg.h
  head/sys/sparc64/pci/schizovar.h

Modified: head/sys/conf/files.sparc64
==============================================================================
--- head/sys/conf/files.sparc64 Sat Mar 26 13:58:44 2011        (r220037)
+++ head/sys/conf/files.sparc64 Sat Mar 26 16:49:12 2011        (r220038)
@@ -79,6 +79,7 @@ sparc64/pci/fire.c            optional        pci
 sparc64/pci/ofw_pcib.c         optional        pci
 sparc64/pci/ofw_pcib_subr.c    optional        pci
 sparc64/pci/ofw_pcibus.c       optional        pci
+sparc64/pci/ofw_pci_if.m       optional        pci
 sparc64/pci/psycho.c           optional        pci
 sparc64/pci/sbbc.c             optional        sbbc uart
 sparc64/pci/schizo.c           optional        pci

Modified: head/sys/conf/files.sun4v
==============================================================================
--- head/sys/conf/files.sun4v   Sat Mar 26 13:58:44 2011        (r220037)
+++ head/sys/conf/files.sun4v   Sat Mar 26 16:49:12 2011        (r220038)
@@ -56,6 +56,7 @@ sun4v/sun4v/trap_trace.S      optional        trap_t
 sparc64/pci/ofw_pcib.c         optional        pci
 sparc64/pci/ofw_pcib_subr.c    optional        pci
 sparc64/pci/ofw_pcibus.c       optional        pci
+sparc64/pci/ofw_pci_if.m       optional        pci
 
 # XXX hvcons should be optional
 sun4v/sun4v/hvcons.c           standard

Modified: head/sys/sparc64/pci/ofw_pci.h
==============================================================================
--- head/sys/sparc64/pci/ofw_pci.h      Sat Mar 26 13:58:44 2011        
(r220037)
+++ head/sys/sparc64/pci/ofw_pci.h      Sat Mar 26 16:49:12 2011        
(r220038)
@@ -64,6 +64,8 @@
 
 #include <dev/ofw/ofw_bus_subr.h>
 
+#include "ofw_pci_if.h"
+
 typedef uint32_t ofw_pci_intr_t;
 
 /* PCI range child spaces. XXX: are these MI? */

Modified: head/sys/sparc64/pci/ofw_pci_if.m
==============================================================================
--- head/sys/sparc64/pci/ofw_pci_if.m   Sat Mar 26 13:58:44 2011        
(r220037)
+++ head/sys/sparc64/pci/ofw_pci_if.m   Sat Mar 26 16:49:12 2011        
(r220038)
@@ -1,5 +1,6 @@
 #-
 # Copyright (c) 2001, 2003 by Thomas Moestl <t...@freebsd.org>
+# Copyright (c) 2011 Marius Strobl <mar...@freebsd.org>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -26,28 +27,22 @@
 
 #include <sys/bus.h>
 
-#include <dev/ofw/openfirm.h>
-
-#include <sparc64/pci/ofw_pci.h>
-
 INTERFACE ofw_pci;
 
 CODE {
-       static ofw_pci_intr_pending_t ofw_pci_default_intr_pending;
+       static ofw_pci_setup_device_t ofw_pci_default_setup_device;
 
-       static int
-       ofw_pci_default_intr_pending(device_t dev, ofw_pci_intr_t intr)
+       static void
+       ofw_pci_default_setup_device(device_t dev, device_t child)
        {
 
                if (device_get_parent(dev) != NULL)
-                       return (OFW_PCI_INTR_PENDING(device_get_parent(dev),
-                           intr));
-               return (0);
+                       OFW_PCI_SETUP_DEVICE(device_get_parent(dev), child);
        }
 };
 
-# Return whether an interrupt request is pending for the INO intr.
-METHOD int intr_pending {
+# Setup a device further upward in the tree.
+METHOD void setup_device {
        device_t dev;
-       ofw_pci_intr_t intr;
-} DEFAULT ofw_pci_default_intr_pending;
+       device_t child;
+} DEFAULT ofw_pci_default_setup_device;

Modified: head/sys/sparc64/pci/ofw_pcibus.c
==============================================================================
--- head/sys/sparc64/pci/ofw_pcibus.c   Sat Mar 26 13:58:44 2011        
(r220037)
+++ head/sys/sparc64/pci/ofw_pcibus.c   Sat Mar 26 16:49:12 2011        
(r220038)
@@ -277,6 +277,7 @@ ofw_pcibus_attach(device_t dev)
                        continue;
                }
                pci_add_child(dev, (struct pci_devinfo *)dinfo);
+               OFW_PCI_SETUP_DEVICE(pcib, dinfo->opd_dinfo.cfg.dev);
        }
 
        return (bus_generic_attach(dev));

Modified: head/sys/sparc64/pci/schizo.c
==============================================================================
--- head/sys/sparc64/pci/schizo.c       Sat Mar 26 13:58:44 2011        
(r220037)
+++ head/sys/sparc64/pci/schizo.c       Sat Mar 26 16:49:12 2011        
(r220038)
@@ -1,7 +1,7 @@
 /*-
  * Copyright (c) 1999, 2000 Matthew R. Green
  * Copyright (c) 2001 - 2003 by Thomas Moestl <t...@freebsd.org>
- * Copyright (c) 2005, 2007, 2008 by Marius Strobl <mar...@freebsd.org>
+ * Copyright (c) 2005 - 2011 by Marius Strobl <mar...@freebsd.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,8 +35,8 @@
 __FBSDID("$FreeBSD$");
 
 /*
- * Driver for `Schizo' Fireplane/Safari to PCI 2.1 and `Tomatillo' JBus to
- * PCI 2.2 bridges
+ * Driver for `Schizo' Fireplane/Safari to PCI 2.1, `Tomatillo' JBus to
+ * PCI 2.2 and `XMITS' Fireplane/Safari to PCI-X bridges
  */
 
 #include "opt_ofw_pci.h"
@@ -80,8 +80,10 @@ __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_dma_sync_stub;
-static driver_filter_t ichip_dma_sync_stub;
+static void schizo_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map,
+    bus_dmasync_op_t op);
+static void ichip_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map,
+    bus_dmasync_op_t op);
 static void schizo_intr_enable(void *);
 static void schizo_intr_disable(void *);
 static void schizo_intr_assign(void *);
@@ -109,18 +111,17 @@ static device_probe_t schizo_probe;
 static device_attach_t schizo_attach;
 static bus_read_ivar_t schizo_read_ivar;
 static bus_setup_intr_t schizo_setup_intr;
-static bus_teardown_intr_t schizo_teardown_intr;
 static bus_alloc_resource_t schizo_alloc_resource;
 static bus_activate_resource_t schizo_activate_resource;
 static bus_deactivate_resource_t schizo_deactivate_resource;
 static bus_release_resource_t schizo_release_resource;
-static bus_describe_intr_t schizo_describe_intr;
 static bus_get_dma_tag_t schizo_get_dma_tag;
 static pcib_maxslots_t schizo_maxslots;
 static pcib_read_config_t schizo_read_config;
 static pcib_write_config_t schizo_write_config;
 static pcib_route_interrupt_t schizo_route_interrupt;
 static ofw_bus_get_node_t schizo_get_node;
+static ofw_pci_setup_device_t schizo_setup_device;
 
 static device_method_t schizo_methods[] = {
        /* Device interface */
@@ -134,12 +135,11 @@ static device_method_t schizo_methods[] 
        DEVMETHOD(bus_print_child,      bus_generic_print_child),
        DEVMETHOD(bus_read_ivar,        schizo_read_ivar),
        DEVMETHOD(bus_setup_intr,       schizo_setup_intr),
-       DEVMETHOD(bus_teardown_intr,    schizo_teardown_intr),
+       DEVMETHOD(bus_teardown_intr,    bus_generic_teardown_intr),
        DEVMETHOD(bus_alloc_resource,   schizo_alloc_resource),
        DEVMETHOD(bus_activate_resource,        schizo_activate_resource),
        DEVMETHOD(bus_deactivate_resource,      schizo_deactivate_resource),
        DEVMETHOD(bus_release_resource, schizo_release_resource),
-       DEVMETHOD(bus_describe_intr,    schizo_describe_intr),
        DEVMETHOD(bus_get_dma_tag,      schizo_get_dma_tag),
 
        /* pcib interface */
@@ -151,6 +151,9 @@ static device_method_t schizo_methods[] 
        /* ofw_bus interface */
        DEVMETHOD(ofw_bus_get_node,     schizo_get_node),
 
+       /* ofw_pci interface */          
+       DEVMETHOD(ofw_pci_setup_device, schizo_setup_device),
+
        KOBJMETHOD_END
 };
 
@@ -177,25 +180,27 @@ struct schizo_icarg {
        bus_addr_t              sica_clr;
 };
 
-struct schizo_dma_sync {
-       struct schizo_softc     *sds_sc;
-       driver_filter_t         *sds_handler;
-       void                    *sds_arg;
-       void                    *sds_cookie;
-       uint64_t                sds_syncval;
-       device_t                sds_ppb;        /* farest PCI-PCI bridge */
-       uint8_t                 sds_bus;        /* bus of farest PCI dev. */
-       uint8_t                 sds_slot;       /* slot of farest PCI dev. */
-       uint8_t                 sds_func;       /* func. of farest PCI dev. */
-};
-
 #define        SCHIZO_PERF_CNT_QLTY    100
 
+#define        SCHIZO_SPC_BARRIER(spc, sc, offs, len, flags)                   
\
+       bus_barrier((sc)->sc_mem_res[(spc)], (offs), (len), (flags))
 #define        SCHIZO_SPC_READ_8(spc, sc, offs)                                
\
        bus_read_8((sc)->sc_mem_res[(spc)], (offs))
 #define        SCHIZO_SPC_WRITE_8(spc, sc, offs, v)                            
\
        bus_write_8((sc)->sc_mem_res[(spc)], (offs), (v))
 
+#ifndef SCHIZO_DEBUG
+#define        SCHIZO_SPC_SET(spc, sc, offs, reg, v)                           
\
+       SCHIZO_SPC_WRITE_8((spc), (sc), (offs), (v))
+#else
+#define        SCHIZO_SPC_SET(spc, sc, offs, reg, v) do {                      
\
+       device_printf((sc)->sc_dev, reg " 0x%016llx -> 0x%016llx\n",    \
+           (unsigned long long)SCHIZO_SPC_READ_8((spc), (sc), (offs)), \
+           (unsigned long long)(v));                                   \
+       SCHIZO_SPC_WRITE_8((spc), (sc), (offs), (v));                   \
+       } while (0)
+#endif
+
 #define        SCHIZO_PCI_READ_8(sc, offs)                                     
\
        SCHIZO_SPC_READ_8(STX_PCI, (sc), (offs))
 #define        SCHIZO_PCI_WRITE_8(sc, offs, v)                                 
\
@@ -213,6 +218,11 @@ struct schizo_dma_sync {
 #define        SCHIZO_ICON_WRITE_8(sc, offs, v)                                
\
        SCHIZO_SPC_WRITE_8(STX_ICON, (sc), (offs), (v))
 
+#define        SCHIZO_PCI_SET(sc, offs, v)                                     
\
+       SCHIZO_SPC_SET(STX_PCI, (sc), (offs), # offs, (v))
+#define        SCHIZO_CTRL_SET(sc, offs, v)                                    
\
+       SCHIZO_SPC_SET(STX_CTRL, (sc), (offs), # offs, (v))
+
 struct schizo_desc {
        const char      *sd_string;
        int             sd_mode;
@@ -221,6 +231,9 @@ struct schizo_desc {
 
 static const struct schizo_desc const schizo_compats[] = {
        { "pci108e,8001",       SCHIZO_MODE_SCZ,        "Schizo" },
+#if 0
+       { "pci108e,8002",       SCHIZO_MODE_XMS,        "XMITS" },
+#endif
        { "pci108e,a801",       SCHIZO_MODE_TOM,        "Tomatillo" },
        { NULL,                 0,                      NULL }
 };
@@ -340,65 +353,70 @@ schizo_attach(device_t dev)
        if (OF_getprop(node, "version#", &sc->sc_ver, sizeof(sc->sc_ver)) ==
            -1)
                panic("%s: could not determine version", __func__);
+       if (mode == SCHIZO_MODE_XMS && OF_getprop(node, "module-revision#",
+           &sc->sc_mrev, sizeof(sc->sc_mrev)) == -1)
+               panic("%s: could not determine module-revision", __func__);
        if (OF_getprop(node, "clock-frequency", &prop, sizeof(prop)) == -1)
                prop = 33000000;
 
-       device_printf(dev, "%s, version %d, IGN %#x, bus %c, %dMHz\n",
-           desc->sd_name, sc->sc_ver, sc->sc_ign, 'A' + sc->sc_half,
-           prop / 1000 / 1000);
+       if (mode == SCHIZO_MODE_XMS && (SCHIZO_PCI_READ_8(sc, STX_PCI_CTRL) &
+           XMS_PCI_CTRL_X_MODE) != 0) {
+               if (sc->sc_mrev < 1)
+                       panic("PCI-X mode unsupported");
+               sc->sc_flags |= SCHIZO_FLAGS_XMODE;
+       }
+
+       device_printf(dev, "%s, version %d, ", desc->sd_name, sc->sc_ver);
+       if (mode == SCHIZO_MODE_XMS)
+               printf("module-revision %d, ", sc->sc_mrev);
+       printf("IGN %#x, bus %c, PCI%s mode, %dMHz\n", sc->sc_ign,
+           'A' + sc->sc_half, (sc->sc_flags & SCHIZO_FLAGS_XMODE) != 0 ?
+           "-X" : "", prop / 1000 / 1000);
 
        /* Set up the PCI interrupt retry timer. */
-#ifdef SCHIZO_DEBUG
-       device_printf(dev, "PCI IRT 0x%016llx\n", (unsigned long long)
-           SCHIZO_PCI_READ_8(sc, STX_PCI_INTR_RETRY_TIM));
-#endif
-       SCHIZO_PCI_WRITE_8(sc, STX_PCI_INTR_RETRY_TIM, 5);
+       SCHIZO_PCI_SET(sc, STX_PCI_INTR_RETRY_TIM, 5);
 
        /* Set up the PCI control register. */
        reg = SCHIZO_PCI_READ_8(sc, STX_PCI_CTRL);
+       reg &= ~(TOM_PCI_CTRL_DTO_IEN | STX_PCI_CTRL_ARB_PARK |
+           STX_PCI_CTRL_ARB_MASK);
        reg |= STX_PCI_CTRL_MMU_IEN | STX_PCI_CTRL_SBH_IEN |
-           STX_PCI_CTRL_ERR_IEN | STX_PCI_CTRL_ARB_MASK;
-       reg &= ~(TOM_PCI_CTRL_DTO_IEN | STX_PCI_CTRL_ARB_PARK);
+           STX_PCI_CTRL_ERR_IEN;
        if (OF_getproplen(node, "no-bus-parking") < 0)
                reg |= STX_PCI_CTRL_ARB_PARK;
+       if (mode == SCHIZO_MODE_XMS && sc->sc_mrev == 1)
+               reg |= XMS_PCI_CTRL_XMITS10_ARB_MASK;
+       else
+               reg |= STX_PCI_CTRL_ARB_MASK;
        if (mode == SCHIZO_MODE_TOM) {
                reg |= TOM_PCI_CTRL_PRM | TOM_PCI_CTRL_PRO | TOM_PCI_CTRL_PRL;
                if (sc->sc_ver <= 1)    /* revision <= 2.0 */
                        reg |= TOM_PCI_CTRL_DTO_IEN;
                else
                        reg |= STX_PCI_CTRL_PTO;
+       } else if (mode == SCHIZO_MODE_XMS) {
+               SCHIZO_PCI_SET(sc, XMS_PCI_PARITY_DETECT, 0x3fff);
+               SCHIZO_PCI_SET(sc, XMS_PCI_UPPER_RETRY_COUNTER, 0x3e8);
+               reg |= XMS_PCI_CTRL_X_ERRINT_EN;
        }
-#ifdef SCHIZO_DEBUG
-       device_printf(dev, "PCI CSR 0x%016llx -> 0x%016llx\n",
-           (unsigned long long)SCHIZO_PCI_READ_8(sc, STX_PCI_CTRL),
-           (unsigned long long)reg);
-#endif
-       SCHIZO_PCI_WRITE_8(sc, STX_PCI_CTRL, reg);
+       SCHIZO_PCI_SET(sc, STX_PCI_CTRL, reg);
 
        /* Set up the PCI diagnostic register. */
        reg = SCHIZO_PCI_READ_8(sc, STX_PCI_DIAG);
        reg &= ~(SCZ_PCI_DIAG_RTRYARB_DIS | STX_PCI_DIAG_RETRY_DIS |
            STX_PCI_DIAG_INTRSYNC_DIS);
-#ifdef SCHIZO_DEBUG
-       device_printf(dev, "PCI DR 0x%016llx -> 0x%016llx\n",
-           (unsigned long long)SCHIZO_PCI_READ_8(sc, STX_PCI_DIAG),
-           (unsigned long long)reg);
-#endif
-       SCHIZO_PCI_WRITE_8(sc, STX_PCI_DIAG, reg);
+       SCHIZO_PCI_SET(sc, STX_PCI_DIAG, reg);
 
        /*
         * Enable DMA write parity error interrupts of version >= 7 (i.e.
-        * revision >= 2.5) Schizo.
+        * revision >= 2.5) Schizo and XMITS (enabling it on XMITS < 3.0 has
+        * no effect though).
         */
-       if (mode == SCHIZO_MODE_SCZ && sc->sc_ver >= 7) {
+       if ((mode == SCHIZO_MODE_SCZ && sc->sc_ver >= 7) ||
+           mode == SCHIZO_MODE_XMS) {
                reg = SCHIZO_PCI_READ_8(sc, SX_PCI_CFG_ICD);
                reg |= SX_PCI_CFG_ICD_DMAW_PERR_IEN;
-#ifdef SCHIZO_DEBUG
-               device_printf(dev, "PCI CFG/ICD 0x%016llx -> 0x%016llx\n",
-               (unsigned long long)SCHIZO_PCI_READ_8(sc, SX_PCI_CFG_ICD),
-               (unsigned long long)reg);
-#endif
-               SCHIZO_PCI_WRITE_8(sc, SX_PCI_CFG_ICD, reg);
+               SCHIZO_PCI_SET(sc, SX_PCI_CFG_ICD, reg);
        }
 
        /*
@@ -406,7 +424,7 @@ schizo_attach(device_t dev)
         * Jalapeno bug).
         */
        if (mode == SCHIZO_MODE_TOM)
-               SCHIZO_PCI_WRITE_8(sc, TOM_PCI_IOC_CSR, TOM_PCI_IOC_PW |
+               SCHIZO_PCI_SET(sc, TOM_PCI_IOC_CSR, TOM_PCI_IOC_PW |
                    (1 << TOM_PCI_IOC_PREF_OFF_SHIFT) | TOM_PCI_IOC_CPRM |
                    TOM_PCI_IOC_CPRO | TOM_PCI_IOC_CPRL);
 
@@ -457,7 +475,7 @@ schizo_attach(device_t dev)
         * "pair" of Tomatillos, too.
         */
        if (sc->sc_half == 0) {
-               SCHIZO_CTRL_WRITE_8(sc, STX_CTRL_PERF,
+               SCHIZO_CTRL_SET(sc, STX_CTRL_PERF,
                    (STX_CTRL_PERF_DIS << STX_CTRL_PERF_CNT1_SHIFT) |
                    (STX_CTRL_PERF_BUSCYC << STX_CTRL_PERF_CNT0_SHIFT));
                tc = malloc(sizeof(*tc), M_DEVBUF, M_NOWAIT | M_ZERO);
@@ -486,12 +504,15 @@ schizo_attach(device_t dev)
         * buffer, in Schizo version < 5 (i.e. revision < 2.3) it's
         * affected by several errata and basically unusable though.
         */
-       sc->sc_is.is_flags = IOMMU_PRESERVE_PROM;
-       sc->sc_is.is_pmaxaddr = IOMMU_MAXADDR(STX_IOMMU_BITS);
-       sc->sc_is.is_sb[0] = sc->sc_is.is_sb[1] = 0;
+       memcpy(&sc->sc_dma_methods, &iommu_dma_methods,
+           sizeof(sc->sc_dma_methods));
+       sc->sc_is.sis_sc = sc;
+       sc->sc_is.sis_is.is_flags = IOMMU_PRESERVE_PROM;
+       sc->sc_is.sis_is.is_pmaxaddr = IOMMU_MAXADDR(STX_IOMMU_BITS);
+       sc->sc_is.sis_is.is_sb[0] = sc->sc_is.sis_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;
+               sc->sc_is.sis_is.is_sb[0] = STX_PCI_STRBUF;
 
 #define        TSBCASE(x)                                                      
\
        case (IOTSB_BASESZ << (x)) << (IO_PAGE_SHIFT - IOTTE_SHIFT):    \
@@ -564,12 +585,13 @@ schizo_attach(device_t dev)
        sc->sc_pci_iot = schizo_alloc_bus_tag(sc, PCI_IO_BUS_SPACE);
        sc->sc_pci_cfgt = schizo_alloc_bus_tag(sc, PCI_CONFIG_BUS_SPACE);
        if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0,
-           sc->sc_is.is_pmaxaddr, ~0, NULL, NULL, sc->sc_is.is_pmaxaddr,
-           0xff, 0xffffffff, 0, NULL, NULL, &sc->sc_pci_dmat) != 0)
+           sc->sc_is.sis_is.is_pmaxaddr, ~0, NULL, NULL,
+           sc->sc_is.sis_is.is_pmaxaddr, 0xff, 0xffffffff, 0, NULL, NULL,
+           &sc->sc_pci_dmat) != 0)
                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 = &iommu_dma_methods;
+       sc->sc_pci_dmat->dt_mt = &sc->sc_dma_methods;
 
        /*
         * Get the bus range from the firmware.
@@ -591,10 +613,8 @@ schizo_attach(device_t dev)
        PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, STX_CS_DEVICE, STX_CS_FUNC,
            PCIR_STATUS, PCIB_READ_CONFIG(dev, sc->sc_pci_secbus,
            STX_CS_DEVICE, STX_CS_FUNC, PCIR_STATUS, 2), 2);
-       SCHIZO_PCI_WRITE_8(sc, STX_PCI_CTRL,
-           SCHIZO_PCI_READ_8(sc, STX_PCI_CTRL));
-       SCHIZO_PCI_WRITE_8(sc, STX_PCI_AFSR,
-           SCHIZO_PCI_READ_8(sc, STX_PCI_AFSR));
+       SCHIZO_PCI_SET(sc, STX_PCI_CTRL, SCHIZO_PCI_READ_8(sc, STX_PCI_CTRL));
+       SCHIZO_PCI_SET(sc, STX_PCI_AFSR, SCHIZO_PCI_READ_8(sc, STX_PCI_AFSR));
 
        /*
         * Establish handlers for interesting interrupts...
@@ -671,9 +691,10 @@ schizo_attach(device_t dev)
        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) {
-                       sc->sc_cdma_state = SCHIZO_CDMA_STATE_DONE;
+                       sc->sc_dma_methods.dm_dmamap_sync =
+                           schizo_dmamap_sync;
+                       sc->sc_cdma_state = SCHIZO_CDMA_STATE_IDLE;
                        /*
                         * Some firmware versions include the CDMA interrupt
                         * at RID 4 but most don't.  With the latter we add
@@ -700,6 +721,14 @@ schizo_attach(device_t dev)
                                   &sc->sc_cdma_clr);
                                schizo_set_intr(sc, 5, i, schizo_cdma);
                        }
+               } else {
+                       if (sc->sc_mode == SCHIZO_MODE_XMS)
+                               mtx_init(&sc->sc_sync_mtx, "pcib_sync_mtx",
+                                   NULL, MTX_SPIN);
+                       sc->sc_sync_val = 1ULL << (STX_PCIERR_A_INO +
+                           sc->sc_half);
+                       sc->sc_dma_methods.dm_dmamap_sync =
+                           ichip_dmamap_sync;
                }
                if (sc->sc_mode == SCHIZO_MODE_TOM && sc->sc_ver <= 4)
                        sc->sc_flags |= SCHIZO_FLAGS_BSWAR;
@@ -820,7 +849,7 @@ static int
 schizo_pci_bus(void *arg)
 {
        struct schizo_softc *sc = arg;
-       uint64_t afar, afsr, csr, iommu;
+       uint64_t afar, afsr, csr, iommu, xstat;
        uint32_t status;
        u_int fatal;
 
@@ -832,6 +861,10 @@ schizo_pci_bus(void *arg)
        afsr = SCHIZO_PCI_READ_8(sc, STX_PCI_AFSR);
        csr = SCHIZO_PCI_READ_8(sc, STX_PCI_CTRL);
        iommu = SCHIZO_PCI_READ_8(sc, STX_PCI_IOMMU);
+       if ((sc->sc_flags & SCHIZO_FLAGS_XMODE) != 0)
+               xstat = SCHIZO_PCI_READ_8(sc, XMS_PCI_X_ERR_STAT);
+       else
+               xstat = 0;
        status = PCIB_READ_CONFIG(sc->sc_dev, sc->sc_pci_secbus,
            STX_CS_DEVICE, STX_CS_FUNC, PCIR_STATUS, 2);
 
@@ -858,14 +891,19 @@ schizo_pci_bus(void *arg)
            STX_PCI_AFSR_P_RTRY | STX_PCI_AFSR_P_PERR | STX_PCI_AFSR_P_TTO |
            STX_PCI_AFSR_P_UNUS)) != 0)
                fatal = 1;
+       if (xstat & (XMS_PCI_X_ERR_STAT_P_SC_DSCRD |
+           XMS_PCI_X_ERR_STAT_P_SC_TTO | XMS_PCI_X_ERR_STAT_P_SDSTAT |
+           XMS_PCI_X_ERR_STAT_P_SMMU | XMS_PCI_X_ERR_STAT_P_CDSTAT |
+           XMS_PCI_X_ERR_STAT_P_CMMU | XMS_PCI_X_ERR_STAT_PERR_RCV))
+               fatal = 1;
        if (fatal == 0)
                sc->sc_stats_pci_non_fatal++;
 
        device_printf(sc->sc_dev, "PCI bus %c error AFAR %#llx AFSR %#llx "
-           "PCI CSR %#llx IOMMU %#llx STATUS %#llx\n", 'A' + sc->sc_half,
-           (unsigned long long)afar, (unsigned long long)afsr,
-           (unsigned long long)csr, (unsigned long long)iommu,
-           (unsigned long long)status);
+           "PCI CSR %#llx IOMMU %#llx PCI-X %#llx STATUS %#x\n",
+           'A' + sc->sc_half, (unsigned long long)afar,
+           (unsigned long long)afsr, (unsigned long long)csr,
+           (unsigned long long)iommu, (unsigned long long)xstat, status);
 
        /* Clear the error bits that we caught. */
        PCIB_WRITE_CONFIG(sc->sc_dev, sc->sc_pci_secbus, STX_CS_DEVICE,
@@ -873,6 +911,8 @@ schizo_pci_bus(void *arg)
        SCHIZO_PCI_WRITE_8(sc, STX_PCI_CTRL, csr);
        SCHIZO_PCI_WRITE_8(sc, STX_PCI_AFSR, afsr);
        SCHIZO_PCI_WRITE_8(sc, STX_PCI_IOMMU, iommu);
+       if ((sc->sc_flags & SCHIZO_FLAGS_XMODE) != 0)
+               SCHIZO_PCI_WRITE_8(sc, XMS_PCI_X_ERR_STAT, xstat);
 
        mtx_unlock_spin(sc->sc_mtx);
 
@@ -945,7 +985,7 @@ schizo_cdma(void *arg)
 {
        struct schizo_softc *sc = arg;
 
-       atomic_store_rel_32(&sc->sc_cdma_state, SCHIZO_CDMA_STATE_DONE);
+       atomic_store_rel_32(&sc->sc_cdma_state, SCHIZO_CDMA_STATE_RECEIVED);
        return (FILTER_HANDLED);
 }
 
@@ -954,17 +994,18 @@ schizo_iommu_init(struct schizo_softc *s
 {
 
        /* Punch in our copies. */
-       sc->sc_is.is_bustag = rman_get_bustag(sc->sc_mem_res[STX_PCI]);
-       sc->sc_is.is_bushandle = rman_get_bushandle(sc->sc_mem_res[STX_PCI]);
-       sc->sc_is.is_iommu = STX_PCI_IOMMU;
-       sc->sc_is.is_dtag = STX_PCI_IOMMU_TLB_TAG_DIAG;
-       sc->sc_is.is_ddram = STX_PCI_IOMMU_TLB_DATA_DIAG;
-       sc->sc_is.is_dqueue = STX_PCI_IOMMU_QUEUE_DIAG;
-       sc->sc_is.is_dva = STX_PCI_IOMMU_SVADIAG;
-       sc->sc_is.is_dtcmp = STX_PCI_IOMMU_TLB_CMP_DIAG;
+       sc->sc_is.sis_is.is_bustag = rman_get_bustag(sc->sc_mem_res[STX_PCI]);
+       sc->sc_is.sis_is.is_bushandle =
+           rman_get_bushandle(sc->sc_mem_res[STX_PCI]);
+       sc->sc_is.sis_is.is_iommu = STX_PCI_IOMMU;
+       sc->sc_is.sis_is.is_dtag = STX_PCI_IOMMU_TLB_TAG_DIAG;
+       sc->sc_is.sis_is.is_ddram = STX_PCI_IOMMU_TLB_DATA_DIAG;
+       sc->sc_is.sis_is.is_dqueue = STX_PCI_IOMMU_QUEUE_DIAG;
+       sc->sc_is.sis_is.is_dva = STX_PCI_IOMMU_SVADIAG;
+       sc->sc_is.sis_is.is_dtcmp = STX_PCI_IOMMU_TLB_CMP_DIAG;
 
-       iommu_init(device_get_nameunit(sc->sc_dev), &sc->sc_is, tsbsize,
-           dvmabase, 0);
+       iommu_init(device_get_nameunit(sc->sc_dev),
+           (struct iommu_state *)&sc->sc_is, tsbsize, dvmabase, 0);
 }
 
 static int
@@ -1103,67 +1144,100 @@ schizo_read_ivar(device_t dev, device_t 
        return (ENOENT);
 }
 
-static int
-schizo_dma_sync_stub(void *arg)
+static void
+schizo_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op)
 {
        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, INTCLR_RECEIVED);
-       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, <=);)
+       struct schizo_iommu_state *sis = dt->dt_cookie;
+       struct schizo_softc *sc = sis->sis_sc;
+       int res;
+
+       if ((map->dm_flags & DMF_STREAMED) != 0) {
+               iommu_dma_methods.dm_dmamap_sync(dt, map, op);
+               return;
+       }
+
+       if ((map->dm_flags & DMF_LOADED) == 0)
+               return;
+
+       if ((op & BUS_DMASYNC_POSTREAD) != 0) {
+               /*
+                * Note that in order to allow this function to be called from
+                * filters we would need to use a spin mutex for serialization
+                * but given that these disable interrupts we have to emulate
+                * one.
+                */
+               for (; atomic_cmpset_acq_32(&sc->sc_cdma_state,
+                   SCHIZO_CDMA_STATE_IDLE, SCHIZO_CDMA_STATE_PENDING) == 0;)
+                       ;
+               SCHIZO_PCI_WRITE_8(sc, sc->sc_cdma_clr, INTCLR_RECEIVED);
                microuptime(&cur);
-       if (state != SCHIZO_CDMA_STATE_DONE)
-               panic("%s: DMA does not sync", __func__);
-       return (sds->sds_handler(sds->sds_arg));
+               end.tv_sec = 1;
+               end.tv_usec = 0;
+               timevaladd(&end, &cur);
+               for (; (res = atomic_cmpset_rel_32(&sc->sc_cdma_state,
+                   SCHIZO_CDMA_STATE_RECEIVED, SCHIZO_CDMA_STATE_IDLE)) ==
+                   0 && timevalcmp(&cur, &end, <=);)
+                       microuptime(&cur);
+               if (res == 0)
+                       panic("%s: DMA does not sync", __func__);
+       }
+
+       if ((op & BUS_DMASYNC_PREWRITE) != 0)
+               membar(Sync);
 }
 
 #define        VIS_BLOCKSIZE   64
 
-static int
-ichip_dma_sync_stub(void *arg)
+static void
+ichip_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op)
 {
        static u_char buf[VIS_BLOCKSIZE] __aligned(VIS_BLOCKSIZE);
        struct timeval cur, end;
-       struct schizo_dma_sync *sds = arg;
-       struct schizo_softc *sc = sds->sds_sc;
+       struct schizo_iommu_state *sis = dt->dt_cookie;
+       struct schizo_softc *sc = sis->sis_sc;
        register_t reg, s;
 
-       (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, <=);)
+       if ((map->dm_flags & DMF_STREAMED) != 0) {
+               iommu_dma_methods.dm_dmamap_sync(dt, map, op);
+               return;
+       }
+
+       if ((map->dm_flags & DMF_LOADED) == 0)
+               return;
+
+       if ((op & BUS_DMASYNC_POSTREAD) != 0) {
+               if (sc->sc_mode == SCHIZO_MODE_XMS)
+                       mtx_lock_spin(&sc->sc_sync_mtx);
+               SCHIZO_PCI_WRITE_8(sc, TOMXMS_PCI_DMA_SYNC_PEND,
+                   sc->sc_sync_val);
                microuptime(&cur);
-       if ((reg & sds->sds_syncval) != 0)
-               panic("%s: DMA does not sync", __func__);
+               end.tv_sec = 1;
+               end.tv_usec = 0;
+               timevaladd(&end, &cur);
+               for (; ((reg = SCHIZO_PCI_READ_8(sc,
+                   TOMXMS_PCI_DMA_SYNC_PEND)) & sc->sc_sync_val) != 0 &&
+                   timevalcmp(&cur, &end, <=);)
+                       microuptime(&cur);
+               if ((reg & sc->sc_sync_val) != 0)
+                       panic("%s: DMA does not sync", __func__);
+               if (sc->sc_mode == SCHIZO_MODE_XMS)
+                       mtx_unlock_spin(&sc->sc_sync_mtx);
+               else 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"
+                           : : "r" (buf), "n" (ASI_BLK_COMMIT_S));
+                       membar(Sync);
+                       wr(fprs, reg, 0);
+                       intr_restore(s);
+                       return;
+               }
+       }
 
-       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"
-                   : : "r" (buf), "n" (ASI_BLK_COMMIT_S));
+       if ((op & BUS_DMASYNC_PREWRITE) != 0)
                membar(Sync);
-               wr(fprs, reg, 0);
-               intr_restore(s);
-       }
-       return (sds->sds_handler(sds->sds_arg));
 }
 
 static void
@@ -1209,12 +1283,9 @@ schizo_setup_intr(device_t dev, device_t
     int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
     void **cookiep)
 {
-       devclass_t pci_devclass;
-       device_t cdev, pdev, pcidev;
-       struct schizo_dma_sync *sds;
        struct schizo_softc *sc;
        u_long vec;
-       int error, found;
+       int error;
 
        sc = device_get_softc(dev);
        /*
@@ -1252,112 +1323,10 @@ schizo_setup_intr(device_t dev, device_t
                    "invalid interrupt controller for vector 0x%lx\n", vec);
                return (EINVAL);
        }
-
-       /*
-        * Install a a wrapper for CDMA flushing/syncing for devices
-        * behind PCI-PCI bridges if possible.
-        */
-       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);
-               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, intr, arg, cookiep);
-               if (error != 0) {
-                       free(sds, M_DEVBUF);
-                       return (error);
-               }
-               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));
 }
 
-static int
-schizo_teardown_intr(device_t dev, device_t child, struct resource *vec,
-    void *cookie)
-{
-       struct schizo_dma_sync *sds;
-       struct schizo_softc *sc;
-       int error;
-
-       sc = device_get_softc(dev);
-       if ((sc->sc_flags & SCHIZO_FLAGS_CDMA) != 0) {
-               sds = cookie;
-               error = bus_generic_teardown_intr(dev, child, vec,
-                   sds->sds_cookie);
-               if (error == 0)
-                       free(sds, M_DEVBUF);
-               return (error);
-       }
-       return (bus_generic_teardown_intr(dev, child, vec, cookie));
-}
-
-static int
-schizo_describe_intr(device_t dev, device_t child, struct resource *vec,
-    void *cookie, const char *descr)
-{
-       struct schizo_softc *sc;
-
-       sc = device_get_softc(dev);
-       if ((sc->sc_flags & SCHIZO_FLAGS_CDMA) != 0)
-               cookie = ((struct schizo_dma_sync *)cookie)->sds_cookie;
-       return (bus_generic_describe_intr(dev, child, vec, cookie, descr));
-}
-
 static struct resource *
 schizo_alloc_resource(device_t bus, device_t child, int type, int *rid,
     u_long start, u_long end, u_long count, u_int flags)
@@ -1476,7 +1445,7 @@ schizo_release_resource(device_t bus, de
 }
 
 static bus_dma_tag_t
-schizo_get_dma_tag(device_t bus, device_t child)
+schizo_get_dma_tag(device_t bus, device_t child __unused)
 {
        struct schizo_softc *sc;
 
@@ -1485,7 +1454,7 @@ schizo_get_dma_tag(device_t bus, device_
 }
 
 static phandle_t
-schizo_get_node(device_t bus, device_t dev)
+schizo_get_node(device_t bus, device_t child __unused)
 {
        struct schizo_softc *sc;
 
@@ -1494,6 +1463,42 @@ schizo_get_node(device_t bus, device_t d
        return (sc->sc_node);
 }
 
+static void
+schizo_setup_device(device_t bus, device_t child)
+{
+       struct schizo_softc *sc;
+       uint64_t reg;
+       int capreg;
+
+       sc = device_get_softc(bus);
+       /*
+        * Disable bus parking in order to work around a bus hang caused by
+        * Casinni/Skyhawk combinations.
+        */ 
+       if (OF_getproplen(ofw_bus_get_node(child), "pci-req-removal") >= 0)
+               SCHIZO_PCI_SET(sc, STX_PCI_CTRL, SCHIZO_PCI_READ_8(sc,
+                   STX_PCI_CTRL) & ~STX_PCI_CTRL_ARB_PARK);
+
+       if (sc->sc_mode == SCHIZO_MODE_XMS) {
+               /* XMITS NCPQ WAR: set outstanding split transactions to 1. */
+               if ((sc->sc_flags & SCHIZO_FLAGS_XMODE) != 0 &&
+                   (pci_read_config(child, PCIR_HDRTYPE, 1) &
+                   PCIM_HDRTYPE) != PCIM_HDRTYPE_BRIDGE &&
+                   pci_find_cap(child, PCIY_PCIX, &capreg) == 0)
+                       pci_write_config(child, capreg + PCIXR_COMMAND,
+                           pci_read_config(child, capreg + PCIXR_COMMAND,
+                           2) & 0x7c, 2);
+               /* XMITS 3.x WAR: set BUGCNTL iff value is unexpected. */
+               if (sc->sc_mrev >= 4) {
+                       reg = ((sc->sc_flags & SCHIZO_FLAGS_XMODE) != 0 ?
+                           0xa0UL : 0xffUL) << XMS_PCI_X_DIAG_BUGCNTL_SHIFT;
+                       if ((SCHIZO_PCI_READ_8(sc, XMS_PCI_X_DIAG) &
+                           XMS_PCI_X_DIAG_BUGCNTL_MASK) != reg)
+                               SCHIZO_PCI_SET(sc, XMS_PCI_X_DIAG, reg);
+               }
+       }
+}
+
 static bus_space_tag_t
 schizo_alloc_bus_tag(struct schizo_softc *sc, int type)
 {

Modified: head/sys/sparc64/pci/schizoreg.h
==============================================================================
--- head/sys/sparc64/pci/schizoreg.h    Sat Mar 26 13:58:44 2011        
(r220037)
+++ head/sys/sparc64/pci/schizoreg.h    Sat Mar 26 16:49:12 2011        
(r220038)
@@ -55,9 +55,13 @@
 #define        STX_PCI_AFSR                    0x02010
 #define        STX_PCI_AFAR                    0x02018
 #define        STX_PCI_DIAG                    0x02020
+#define        XMS_PCI_PARITY_DETECT           0x02040
 #define        TOM_PCI_IOC_CSR                 0x02248
 #define        TOM_PCI_IOC_TAG                 0x02290
 #define        TOM_PCI_IOC_DATA                0x02290
+#define        XMS_PCI_X_ERR_STAT              0x02300
+#define        XMS_PCI_X_DIAG                  0x02308
+#define        XMS_PCI_UPPER_RETRY_COUNTER     0x02310
 #define        STX_PCI_STRBUF                  0x02800
 #define        STX_PCI_STRBUF_CTXFLUSH         0x02818
 #define        STX_PCI_IOMMU_SVADIAG           0x0a400
@@ -68,7 +72,7 @@
 #define        STX_PCI_IOBIO_DIAG              0x0a808
 #define        STX_PCI_STRBUF_CTXMATCH         0x10000
 
-/* PCI configuration/idle check diagnostic registers */
+/* PCI configuration/idle check diagnostic register */
 #define        SX_PCI_CFG_ICD_PCI_2_0_COMPAT   0x0000000000008000ULL
 #define        SX_PCI_CFG_ICD_DMAW_PERR_IEN    0x0000000000004000ULL
 #define        SX_PCI_CFG_ICD_IFC_NOT_IDLE     0x0000000000000010ULL
@@ -77,7 +81,7 @@
 #define        SX_PCI_CFG_ICD_PBM_NOT_IDLE     0x0000000000000002ULL
 #define        SX_PCI_CFG_ICD_STC_NOT_IDLE     0x0000000000000001ULL
 
-/* PCI IOMMU control registers */
+/* PCI IOMMU control register */
 #define        TOM_PCI_IOMMU_ERR_BAD_VA        0x0000000010000000ULL
 #define        TOM_PCI_IOMMU_ERR_ILLTSBTBW     0x0000000008000000ULL
 #define        TOM_PCI_IOMMU_ECC_ERR           0x0000000006000000ULL
@@ -94,6 +98,7 @@
 #define        TOM_PCI_CTRL_DTO_ERR            0x4000000000000000ULL
 #define        TOM_PCI_CTRL_DTO_IEN            0x2000000000000000ULL
 #define        SCZ_PCI_CTRL_ESLCK              0x0008000000000000ULL
+#define        XMS_PCI_CTRL_DMA_WR_PERR        0x0008000000000000ULL
 #define        SCZ_PCI_CTRL_ERRSLOT            0x0007000000000000ULL
 #define        STX_PCI_CTRL_TTO_ERR            0x0000004000000000ULL
 #define        STX_PCI_CTRL_RTRY_ERR           0x0000002000000000ULL
@@ -101,16 +106,19 @@
 #define        SCZ_PCI_CTRL_SBH_ERR            0x0000000800000000ULL
 #define        STX_PCI_CTRL_SERR               0x0000000400000000ULL
 #define        SCZ_PCI_CTRL_PCISPD             0x0000000200000000ULL
+#define        XMS_PCI_CTRL_X_MODE             0x0000000100000000ULL
 #define        TOM_PCI_CTRL_PRM                0x0000000040000000ULL
 #define        TOM_PCI_CTRL_PRO                0x0000000020000000ULL
 #define        TOM_PCI_CTRL_PRL                0x0000000010000000ULL
 #define        STX_PCI_CTRL_PTO                0x0000000003000000ULL
+#define        XMS_PCI_CTRL_X_ERRINT_EN        0x0000000000100000ULL
 #define        STX_PCI_CTRL_MMU_IEN            0x0000000000080000ULL
 #define        STX_PCI_CTRL_SBH_IEN            0x0000000000040000ULL
 #define        STX_PCI_CTRL_ERR_IEN            0x0000000000020000ULL
 #define        STX_PCI_CTRL_ARB_PARK           0x0000000000010000ULL
 #define        SCZ_PCI_CTRL_PCIRST             0x0000000000000100ULL
 #define        STX_PCI_CTRL_ARB_MASK           0x00000000000000ffULL
+#define        XMS_PCI_CTRL_XMITS10_ARB_MASK   0x000000000000000fULL
 
 /* PCI asynchronous fault status register */
 #define        STX_PCI_AFSR_P_MA               0x8000000000000000ULL
@@ -160,6 +168,32 @@
 #define        TOM_PCI_IOC_CPRO                0x0000000000000002ULL
 #define        TOM_PCI_IOC_CPRL                0x0000000000000001ULL
 
+/* XMITS PCI-X error status register */
+#define        XMS_PCI_X_ERR_STAT_P_SC_DSCRD   0x8000000000000000ULL
+#define        XMS_PCI_X_ERR_STAT_P_SC_TTO     0x4000000000000000ULL
+#define        XMS_PCI_X_ERR_STAT_P_SDSTAT     0x2000000000000000ULL
+#define        XMS_PCI_X_ERR_STAT_P_SMMU       0x1000000000000000ULL
+#define        XMS_PCI_X_ERR_STAT_P_CDSTAT     0x0800000000000000ULL
+#define        XMS_PCI_X_ERR_STAT_P_CMMU       0x0400000000000000ULL
+#define        XMS_PCI_X_ERR_STAT_S_SC_DSCRD   0x0080000000000000ULL
+#define        XMS_PCI_X_ERR_STAT_S_SC_TTO     0x0040000000000000ULL
+#define        XMS_PCI_X_ERR_STAT_S_SDSTAT     0x0020000000000000ULL
+#define        XMS_PCI_X_ERR_STAT_S_SMMU       0x0010000000000000ULL
+#define        XMS_PCI_X_ERR_STAT_S_CDSTAT     0x0008000000000000ULL
+#define        XMS_PCI_X_ERR_STAT_S_CMMU       0x0004000000000000ULL
+#define        XMS_PCI_X_ERR_STAT_PERR_RCV_IEN 0x0000000400000000ULL
+#define        XMS_PCI_X_ERR_STAT_PERR_RCV     0x0000000200000000ULL
+#define        XMS_PCI_X_ERR_STAT_SERR_ON_PERR 0x0000000100000000ULL
+
+/* XMITS PCI-X diagnostic register */
+#define        XMS_PCI_X_DIAG_DIS_FAIR         0x0000000000080000ULL
+#define        XMS_PCI_X_DIAG_CRCQ_VALID       0x0000000000040000ULL
+#define        XMS_PCI_X_DIAG_SRCQ_ONE         0x0000000000000200ULL
+#define        XMS_PCI_X_DIAG_CRCQ_FLUSH       0x0000000000000100ULL
+#define        XMS_PCI_X_DIAG_BUGCNTL_MASK     0x0000ffff00000000ULL
+#define        XMS_PCI_X_DIAG_BUGCNTL_SHIFT    32
+#define        XMS_PCI_X_DIAG_SRCQ_MASK        0x00000000000000ffULL
+
 /* Controller configuration and status registers */
 /* Note that these are shared on Schizo but per-PBM on Tomatillo. */
 #define        STX_CTRL_BUS_ERRLOG             0x00018

Modified: head/sys/sparc64/pci/schizovar.h
==============================================================================
--- head/sys/sparc64/pci/schizovar.h    Sat Mar 26 13:58:44 2011        
(r220037)
+++ head/sys/sparc64/pci/schizovar.h    Sat Mar 26 16:49:12 2011        
(r220038)
@@ -31,9 +31,21 @@
 #ifndef _SPARC64_PCI_SCHIZOVAR_H_
 #define        _SPARC64_PCI_SCHIZOVAR_H_
 
+struct schizo_softc;
+
+struct schizo_iommu_state {
+       struct iommu_state      sis_is;
+       struct schizo_softc     *sis_sc;
+};
+
 struct schizo_softc {
+       struct bus_dma_methods          sc_dma_methods;
+
        device_t                        sc_dev;
 
+       struct mtx                      sc_sync_mtx;
+       uint64_t                        sc_sync_val;
+
        struct mtx                      *sc_mtx;
 
        phandle_t                       sc_node;
@@ -45,22 +57,24 @@ struct schizo_softc {
 
        u_int                           sc_flags;
 #define        SCHIZO_FLAGS_BSWAR              (1 << 0)
-#define        SCHIZO_FLAGS_CDMA               (1 << 1)
+#define        SCHIZO_FLAGS_XMODE              (1 << 1)
 
        bus_addr_t                      sc_cdma_clr;
        uint32_t                        sc_cdma_state;
-#define        SCHIZO_CDMA_STATE_DONE          (1 << 0)
+#define        SCHIZO_CDMA_STATE_IDLE          (1 << 0)
 #define        SCHIZO_CDMA_STATE_PENDING       (1 << 1)
+#define        SCHIZO_CDMA_STATE_RECEIVED      (1 << 2)
 
        u_int                           sc_half;
        uint32_t                        sc_ign;
        uint32_t                        sc_ver;
+       uint32_t                        sc_mrev;
 
        struct resource                 *sc_mem_res[TOM_NREG];
        struct resource                 *sc_irq_res[STX_NINTR];
        void                            *sc_ihand[STX_NINTR];
 
-       struct iommu_state              sc_is;
+       struct schizo_iommu_state       sc_is;
 
        struct rman                     sc_pci_mem_rman;
        struct rman                     sc_pci_io_rman;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to