From owner-svn-src-all@FreeBSD.ORG Sun Mar 22 22:19:54 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E65CD1065672; Sun, 22 Mar 2009 22:19:54 +0000 (UTC) (envelope-from marius@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D1F528FC16; Sun, 22 Mar 2009 22:19:54 +0000 (UTC) (envelope-from marius@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n2MMJsRT085867; Sun, 22 Mar 2009 22:19:54 GMT (envelope-from marius@svn.freebsd.org) Received: (from marius@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n2MMJsPB085861; Sun, 22 Mar 2009 22:19:54 GMT (envelope-from marius@svn.freebsd.org) Message-Id: <200903222219.n2MMJsPB085861@svn.freebsd.org> From: Marius Strobl Date: Sun, 22 Mar 2009 22:19:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r190297 - in stable/7/sys: . conf contrib/pf dev/ath/ath_hal dev/cxgb sparc64/pci sparc64/sparc64 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 22 Mar 2009 22:19:55 -0000 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 #include #include +#include #include #include @@ -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;