svn commit: r186290 - head/sys/sparc64/pci
Marius Strobl
marius at FreeBSD.org
Thu Dec 18 18:29:16 UTC 2008
Author: marius
Date: Thu Dec 18 18:29:15 2008
New Revision: 186290
URL: http://svn.freebsd.org/changeset/base/186290
Log:
- Failing to register as interrupt controller during attach shouldn't
be fatal so just inform about this instead of panicing.
- Ensure we use the right softc in case the interrupt of a child is
is routed to the companion PBM instead. This hasn't been seen in the
wild so far but given that it's the case for the Schizo interrupts,
handling this situation also for child interrupts as a precaution
seemed a good idea.
- Deal with broken firmware versions which miss child entries in the
ino-bitmap as seen on V880 by belatedly registering as interrupt
controller in schizo_setup_intr(). [1]
- Add missing '\n' when printing the warning regarding Schizo Errata
I-13.
Reported and tested by: Beat Gaetzi [1]
Modified:
head/sys/sparc64/pci/schizo.c
Modified: head/sys/sparc64/pci/schizo.c
==============================================================================
--- head/sys/sparc64/pci/schizo.c Thu Dec 18 18:28:03 2008 (r186289)
+++ head/sys/sparc64/pci/schizo.c Thu Dec 18 18:29:15 2008 (r186290)
@@ -394,9 +394,10 @@ schizo_attach(device_t dev)
/*
* Hunt through all the interrupt mapping regs and register
- * the interrupt controller for our interrupt vectors. This
- * is complicated by the fact that a pair of Schizo PBMs
- * share one IGN.
+ * the interrupt controller for our interrupt vectors. We do
+ * this early in order to be able to catch stray interrupts.
+ * This is complicated by the fact that a pair of Schizo PBMs
+ * shares one IGN.
*/
n = OF_getprop(node, "ino-bitmap", (void *)prop_array,
sizeof(prop_array));
@@ -411,8 +412,8 @@ schizo_attach(device_t dev)
continue;
i = schizo_intr_register(sc, n);
if (i != 0)
- panic("%s: could not register interrupt controller "
- "for INO %d (%d)", __func__, n, i);
+ device_printf(dev, "could not register interrupt "
+ "controller for INO %d (%d)\n", n, i);
}
/*
@@ -1127,16 +1128,40 @@ schizo_setup_intr(device_t dev, device_t
sc = device_get_softc(dev);
/*
- * Make sure the vector is fully specified and we registered
- * our interrupt controller for it.
+ * Make sure the vector is fully specified.
*/
vec = rman_get_start(ires);
- if (INTIGN(vec) != sc->sc_ign ||
- intr_vectors[vec].iv_ic != &schizo_ic) {
+ if (INTIGN(vec) != sc->sc_ign) {
device_printf(dev, "invalid interrupt vector 0x%lx\n", vec);
return (EINVAL);
}
+ if (intr_vectors[vec].iv_ic == &schizo_ic) {
+ /*
+ * Ensure we use the right softc in case the interrupt
+ * is routed to our companion PBM for some odd reason.
+ */
+ sc = ((struct schizo_icarg *)intr_vectors[vec].iv_icarg)->
+ sica_sc;
+ } else if (intr_vectors[vec].iv_ic == NULL) {
+ /*
+ * Work around broken firmware which misses entries in
+ * the ino-bitmap.
+ */
+ error = schizo_intr_register(sc, INTINO(vec));
+ if (error != 0) {
+ device_printf(dev, "could not register interrupt "
+ "controller for vector 0x%lx (%d)\n", vec, error);
+ return (error);
+ }
+ device_printf(dev, "belatedly registered as interrupt "
+ "controller for vector 0x%lx\n", vec);
+ } else {
+ device_printf(dev,
+ "invalid interrupt controller for vector 0x%lx\n", vec);
+ return (EINVAL);
+ }
+
/*
* Install a a wrapper for CDMA flushing/syncing for devices
* behind PCI-PCI bridges if possible.
@@ -1205,7 +1230,7 @@ schizo_setup_intr(device_t dev, device_t
return (error);
} else if (found != 0)
device_printf(dev, "WARNING: using devices behind PCI-PCI "
- "bridges may cause data corruption");
+ "bridges may cause data corruption\n");
return (bus_generic_setup_intr(dev, child, ires, flags, filt, intr,
arg, cookiep));
}
More information about the svn-src-all
mailing list