Port-sparc64 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Cardbus bridge fixup for SPARCle



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/
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)
 {
 


Home | Main Index | Thread Index | Old Index