Module Name:    src
Committed By:   jdc
Date:           Tue Sep 24 18:23:07 UTC 2013

Modified Files:
        src/sys/arch/sparc64/dev: psycho.c

Log Message:
Work around invalid root PCI bus bus-range (0x00-0xff) by checking the
bus-range of any child buses, and altering the root bus bus-range to
suit.  Required for cardbus bridge attach on SPARCle.


To generate a diff of this commit:
cvs rdiff -u -r1.115 -r1.116 src/sys/arch/sparc64/dev/psycho.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/sparc64/dev/psycho.c
diff -u src/sys/arch/sparc64/dev/psycho.c:1.115 src/sys/arch/sparc64/dev/psycho.c:1.116
--- src/sys/arch/sparc64/dev/psycho.c:1.115	Thu Aug 22 09:57:30 2013
+++ src/sys/arch/sparc64/dev/psycho.c	Tue Sep 24 18:23:07 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: psycho.c,v 1.115 2013/08/22 09:57:30 nakayama Exp $	*/
+/*	$NetBSD: psycho.c,v 1.116 2013/09/24 18:23:07 jdc Exp $	*/
 
 /*
  * Copyright (c) 1999, 2000 Matthew R. Green
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: psycho.c,v 1.115 2013/08/22 09:57:30 nakayama Exp $");
+__KERNEL_RCSID(0, "$NetBSD: psycho.c,v 1.116 2013/09/24 18:23:07 jdc Exp $");
 
 #include "opt_ddb.h"
 
@@ -109,6 +109,7 @@ static pci_chipset_tag_t psycho_alloc_ch
 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 *);
@@ -475,6 +476,10 @@ found:
 	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]);
 
@@ -866,6 +871,44 @@ psycho_get_bus_range(int node, int *brp)
 }
 
 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)
 {
 

Reply via email to