diff options
-rw-r--r-- | sys/conf/files.sparc64 | 1 | ||||
-rw-r--r-- | sys/conf/files.sun4v | 1 | ||||
-rw-r--r-- | sys/sparc64/pci/ofw_pci.c | 76 | ||||
-rw-r--r-- | sys/sparc64/pci/ofw_pci.h | 2 | ||||
-rw-r--r-- | sys/sparc64/pci/ofw_pci_if.m | 30 | ||||
-rw-r--r-- | sys/sparc64/pci/ofw_pcib_subr.c | 27 | ||||
-rw-r--r-- | sys/sparc64/pci/psycho.c | 17 |
7 files changed, 55 insertions, 99 deletions
diff --git a/sys/conf/files.sparc64 b/sys/conf/files.sparc64 index 3295531..b00e383 100644 --- a/sys/conf/files.sparc64 +++ b/sys/conf/files.sparc64 @@ -81,7 +81,6 @@ sparc64/isa/isa.c optional isa sparc64/isa/isa_dma.c optional isa sparc64/isa/ofw_isa.c optional ebus | isa sparc64/pci/apb.c optional pci -sparc64/pci/ofw_pci.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 diff --git a/sys/conf/files.sun4v b/sys/conf/files.sun4v index 571b3b8..e126035 100644 --- a/sys/conf/files.sun4v +++ b/sys/conf/files.sun4v @@ -47,7 +47,6 @@ sun4v/sun4v/exception.S standard no-obj sparc64/sparc64/gdb_machdep.c optional gdb sun4v/sun4v/hv_pci.c optional pci sun4v/sun4v/trap_trace.S optional trap_tracing -sparc64/pci/ofw_pci.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 diff --git a/sys/sparc64/pci/ofw_pci.c b/sys/sparc64/pci/ofw_pci.c deleted file mode 100644 index 998b498..0000000 --- a/sys/sparc64/pci/ofw_pci.c +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * Copyright (c) 1999, 2000 Matthew R. Green - * Copyright (c) 2001 - 2003 by Thomas Moestl <tmm@FreeBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: NetBSD: psycho.c,v 1.35 2001/09/10 16:17:06 eeh Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "opt_ofw_pci.h" - -#include <sys/param.h> -#include <sys/kernel.h> -#include <sys/systm.h> -#include <sys/bus.h> - -#include <dev/ofw/openfirm.h> - -#include <machine/bus.h> - -#include <sparc64/pci/ofw_pci.h> - -static uint8_t pci_bus_cnt; -static phandle_t *pci_bus_map; -static int pci_bus_map_sz; - -#define PCI_BUS_MAP_INC 10 - -uint8_t -ofw_pci_alloc_busno(phandle_t node) -{ - phandle_t *om; - int osz; - uint8_t n; - - n = pci_bus_cnt++; - /* Establish a mapping between bus numbers and device nodes. */ - if (n >= pci_bus_map_sz) { - osz = pci_bus_map_sz; - om = pci_bus_map; - pci_bus_map_sz = n + PCI_BUS_MAP_INC; - pci_bus_map = malloc(sizeof(*pci_bus_map) * pci_bus_map_sz, - M_DEVBUF, M_WAITOK | M_ZERO); - if (om != NULL) { - bcopy(om, pci_bus_map, sizeof(*om) * osz); - free(om, M_DEVBUF); - } - } - pci_bus_map[n] = node; - return (n); -} diff --git a/sys/sparc64/pci/ofw_pci.h b/sys/sparc64/pci/ofw_pci.h index 6d102b0..40d531e 100644 --- a/sys/sparc64/pci/ofw_pci.h +++ b/sys/sparc64/pci/ofw_pci.h @@ -64,6 +64,4 @@ struct ofw_pci_ranges { (((uint64_t)(r)->size_hi << 32) | (uint64_t)(r)->size_lo) #define OFW_PCI_RANGE_CS(r) (((r)->cspace >> 24) & 0x03) -uint8_t ofw_pci_alloc_busno(phandle_t); - #endif /* ! _SPARC64_PCI_OFW_PCI_H_ */ diff --git a/sys/sparc64/pci/ofw_pci_if.m b/sys/sparc64/pci/ofw_pci_if.m index 9e7412a..d93f978 100644 --- a/sys/sparc64/pci/ofw_pci_if.m +++ b/sys/sparc64/pci/ofw_pci_if.m @@ -34,20 +34,35 @@ INTERFACE ofw_pci; CODE { static ofw_pci_intr_pending_t ofw_pci_default_intr_pending; + static ofw_pci_alloc_busno_t ofw_pci_default_alloc_busno; static ofw_pci_adjust_busrange_t ofw_pci_default_adjust_busrange; static int ofw_pci_default_intr_pending(device_t dev, ofw_pci_intr_t intr) { - return (OFW_PCI_INTR_PENDING(device_get_parent(dev), intr)); + if (device_get_parent(dev) != NULL) + return (OFW_PCI_INTR_PENDING(device_get_parent(dev), + intr)); + return (0); + } + + static int + ofw_pci_default_alloc_busno(device_t dev) + { + + if (device_get_parent(dev) != NULL) + return (OFW_PCI_ALLOC_BUSNO(device_get_parent(dev))); + return (-1); } static void ofw_pci_default_adjust_busrange(device_t dev, u_int busno) { - return (OFW_PCI_ADJUST_BUSRANGE(device_get_parent(dev), busno)); + if (device_get_parent(dev) != NULL) + return (OFW_PCI_ADJUST_BUSRANGE(device_get_parent(dev), + busno)); } }; @@ -57,8 +72,15 @@ METHOD int intr_pending { ofw_pci_intr_t intr; } DEFAULT ofw_pci_default_intr_pending; -# Make sure that all PCI bridges up in the hierarchy contain this bus in their -# subordinate bus range. This is required because we reenumerate all PCI +# Allocate a bus number for reenumerating a PCI bus. A return value of -1 +# means that reenumeration is generally not supported, otherwise all PCI +# busses must be reenumerated using bus numbers obtained via this method. +METHOD int alloc_busno { + device_t dev; +} DEFAULT ofw_pci_default_alloc_busno; + +# Make sure that all PCI bridges up in the hierarchy contain this bus in +# their subordinate bus range. This is required when reenumerating the PCI # buses. METHOD void adjust_busrange { device_t dev; diff --git a/sys/sparc64/pci/ofw_pcib_subr.c b/sys/sparc64/pci/ofw_pcib_subr.c index 834ebe3..7cc867b 100644 --- a/sys/sparc64/pci/ofw_pcib_subr.c +++ b/sys/sparc64/pci/ofw_pcib_subr.c @@ -27,7 +27,6 @@ __FBSDID("$FreeBSD$"); #include "opt_ofw_pci.h" -#include "opt_global.h" #include <sys/param.h> #include <sys/systm.h> @@ -54,7 +53,7 @@ ofw_pcib_gen_setup(device_t bridge) { struct ofw_pcib_gen_softc *sc; #ifndef SUN4V - u_int secbus; + int secbus; #endif sc = device_get_softc(bridge); @@ -64,18 +63,20 @@ ofw_pcib_gen_setup(device_t bridge) ("ofw_pcib_gen_setup: no ofw pci parent bus!")); /* - * Setup the secondary bus number register, by allocating a new unique - * bus number for it; the firmware preset does not always seem to be - * correct. + * Setup the secondary bus number register, if supported, by + * allocating a new unique bus number for it; the firmware + * preset does not always seem to be correct in that case. */ #ifndef SUN4V - secbus = ofw_pci_alloc_busno(sc->ops_node); - pci_write_config(bridge, PCIR_PRIBUS_1, pci_get_bus(bridge), 1); - pci_write_config(bridge, PCIR_SECBUS_1, secbus, 1); - pci_write_config(bridge, PCIR_SUBBUS_1, secbus, 1); - sc->ops_pcib_sc.subbus = sc->ops_pcib_sc.secbus = secbus; - /* Notify parent bridges. */ - OFW_PCI_ADJUST_BUSRANGE(device_get_parent(bridge), secbus); + secbus = OFW_PCI_ALLOC_BUSNO(bridge); + if (secbus != -1) { + pci_write_config(bridge, PCIR_PRIBUS_1, pci_get_bus(bridge), 1); + pci_write_config(bridge, PCIR_SECBUS_1, secbus, 1); + pci_write_config(bridge, PCIR_SUBBUS_1, secbus, 1); + sc->ops_pcib_sc.subbus = sc->ops_pcib_sc.secbus = secbus; + /* Notify parent bridges. */ + OFW_PCI_ADJUST_BUSRANGE(device_get_parent(bridge), secbus); + } #endif ofw_bus_setup_iinfo(sc->ops_node, &sc->ops_iinfo, @@ -135,7 +136,7 @@ ofw_pcib_gen_adjust_busrange(device_t bridge, u_int subbus) if (subbus > sc->ops_pcib_sc.subbus) { #ifdef OFW_PCI_DEBUG device_printf(bridge, - "adjusting secondary bus number from %d to %d\n", + "adjusting subordinate bus number from %d to %d\n", sc->ops_pcib_sc.subbus, subbus); #endif pci_write_config(bridge, PCIR_SUBBUS_1, subbus, 1); diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c index 4dcccef..6ecc6c8 100644 --- a/sys/sparc64/pci/psycho.c +++ b/sys/sparc64/pci/psycho.c @@ -120,6 +120,7 @@ static pcib_write_config_t psycho_write_config; static pcib_route_interrupt_t psycho_route_interrupt; static ofw_pci_intr_pending_t psycho_intr_pending; static ofw_bus_get_node_t psycho_get_node; +static ofw_pci_alloc_busno_t psycho_alloc_busno; static ofw_pci_adjust_busrange_t psycho_adjust_busrange; static device_method_t psycho_methods[] = { @@ -152,6 +153,7 @@ static device_method_t psycho_methods[] = { /* ofw_pci interface */ DEVMETHOD(ofw_pci_intr_pending, psycho_intr_pending), + DEVMETHOD(ofw_pci_alloc_busno, psycho_alloc_busno), DEVMETHOD(ofw_pci_adjust_busrange, psycho_adjust_busrange), { 0, 0 } @@ -167,9 +169,11 @@ static devclass_t psycho_devclass; DRIVER_MODULE(psycho, nexus, psycho_driver, psycho_devclass, 0, 0); -SLIST_HEAD(, psycho_softc) psycho_softcs = +static SLIST_HEAD(, psycho_softc) psycho_softcs = SLIST_HEAD_INITIALIZER(psycho_softcs); +static uint8_t psycho_pci_bus_cnt; + struct psycho_clr { struct psycho_softc *pci_sc; bus_addr_t pci_clr; /* clear register */ @@ -629,7 +633,7 @@ psycho_attach(device_t dev) PCIB_WRITE_CONFIG(dev, psycho_br[0], PCS_DEVICE, PCS_FUNC, PCIR_LATTIMER, 64, 1); - sc->sc_pci_secbus = sc->sc_pci_subbus = ofw_pci_alloc_busno(node); + sc->sc_pci_secbus = sc->sc_pci_subbus = psycho_alloc_busno(dev); /* * Program the bus range registers. * NOTE: for the Psycho, the second write changes the bus number the @@ -1306,6 +1310,15 @@ psycho_get_node(device_t bus, device_t dev) return (sc->sc_node); } +static int +psycho_alloc_busno(device_t dev) +{ + + if (psycho_pci_bus_cnt == PCI_BUSMAX) + panic("%s: out of PCI bus numbers", __func__); + return (psycho_pci_bus_cnt++); +} + static void psycho_adjust_busrange(device_t dev, u_int subbus) { |