Re: Cardbus bridge fixup for SPARCle

Julian Coleman <[email protected]>
Newsgroups gmane.os.netbsd.ports.sparc64
Message-ID <[email protected]>
Hi,

> What's the best way to handle this?  I assume that the bus-range property
> needs fixing up.  It is currently:
> 
>   bus-range               00000000 000000ff ........ ........   ........
> 
> Is the way to fix this to go through the OFW tree and set all the bus ranges
> correctly for all the PCI busses, which will allow the code in
> pccbb_attach_hook() to correctly set the secondary bus number?

The attached patch fixes up the bus-range correctly for psycho0.  It starts
with a bus-range of 0 -> 0, checks for any PCI-PCI bridges and expands the
bus-range if any are found.  On the SPARCle, there are no PCI-PCI bridges,
so we end up with a final range of 0 -> 0.  With this patch, cardbus0 at
cbb0 attaches OK (*).  Note, that the patch only alters the bus-range of
the root bridge and any bridges below that, but does not alter the businfo
register on any bridges.

Thanks,

J

(*) The slot doesn't power up any inserted cards, but I think that that is
caused by us not having a power-management driver for the Tadpole PMU.
-- 
   NetBSD: simple; works; documented    /        Sailing at Newbiggin
        http://www.netbsd.org/        /   http://www.newbigginsailingclub.org/
psycho.c.diffs (text/plain, 2.2 KB)
Index: psycho.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/dev/psycho.c,v
retrieving revision 1.112
diff -u -r1.112 psycho.c
--- psycho.c	27 Jan 2012 18:53:03 -0000	1.112
+++ psycho.c	12 Oct 2012 17:05:34 -0000
@@ -108,6 +108,7 @@
 static struct extent *psycho_alloc_extent(struct psycho_pbm *, int, int,
 	const char *);
 static void psycho_get_bus_range(int, int *);
+static void psycho_fixup_bus_range(int, int *);
 static void psycho_get_ranges(int, struct psycho_ranges **, int *);
 static void psycho_set_intr(struct psycho_softc *, int, void *, uint64_t *,
 	uint64_t *);
@@ -468,6 +469,10 @@
 	pba.pba_bus = psycho_br[0];
 	pba.pba_bridgetag = NULL;
 
+	/* Fix up invalid 0x00-0xff bus-range, as found on SPARCle */
+	if (psycho_br[0] == 0 && psycho_br[1] == 0xff)
+		psycho_fixup_bus_range(sc->sc_node, psycho_br);
+
 	aprint_normal("bus range %u to %u", psycho_br[0], psycho_br[1]);
 	aprint_normal("; PCI bus %d", psycho_br[0]);
 
@@ -859,6 +864,44 @@
 }
 
 static void
+psycho_fixup_bus_range(int node0, int *brp0)
+{
+	int node;
+	int len, busrange[2], *brp;
+
+	DPRINTF(PDB_PROM,
+	    ("psycho debug: fixing up `bus-range' for node %08x: %u - %u\n",
+	    node0, brp0[0], brp0[1]));
+
+	/*
+	 * Check all nodes under this one and increase the bus range to
+	 * match.  Recurse through PCI-PCI bridges.  Cardbus bridges are
+	 * fixed up in pccbb_attach_hook().  Assumes that "bus-range" for
+	 * PCI-PCI bridges apart from this one is correct.
+	 */
+	brp0[1] = brp0[0];
+	node = prom_firstchild(node0);
+	for (node = ((node)); node; node = prom_nextsibling(node)) {
+		len = 2;
+		brp = busrange;
+		if (prom_getprop(node, "bus-range", sizeof(*brp),
+		    &len, &brp) != 0)
+			break;
+		if (len != 2)
+			break;
+		psycho_fixup_bus_range(node, busrange);
+		if (brp0[0] > busrange[0] && busrange[0] >= 0)
+			brp0[0] = busrange[0];
+		if (brp0[1] < busrange[1] && busrange[1] < 256)
+			brp0[1] = busrange[1];
+	}
+
+	DPRINTF(PDB_PROM,
+	    ("psycho debug: fixed up `bus-range' for node %08x: %u - %u\n",
+	    node0, brp[0], brp[1]));
+}
+
+static void
 psycho_get_ranges(int node, struct psycho_ranges **rp, int *np)
 {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.