summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/conf/files.sparc641
-rw-r--r--sys/conf/files.sun4v1
-rw-r--r--sys/sparc64/pci/ofw_pci.c76
-rw-r--r--sys/sparc64/pci/ofw_pci.h2
-rw-r--r--sys/sparc64/pci/ofw_pci_if.m30
-rw-r--r--sys/sparc64/pci/ofw_pcib_subr.c27
-rw-r--r--sys/sparc64/pci/psycho.c17
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)
{
OpenPOWER on IntegriCloud