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