PERFORCE change 152961 for review

Nathan Whitehorn nwhitehorn at FreeBSD.org
Thu Nov 13 20:48:15 PST 2008


http://perforce.freebsd.org/chv.cgi?CH=152961

Change 152961 by nwhitehorn at nwhitehorn_trantor on 2008/11/14 04:47:43

	Make the unified OFW PCI stuff really work well. IRQs show up in dmesg,
	and interrupt assignment works on Uninorth systems with many PCI
	devices, which it did not before. Once sparc64 can use this code too
	(which requires only mechanical changes, since it came from sparc64),
	it will be in good shape to merge.

Affected files ...

.. //depot/projects/ppc-g5/sys/powerpc/ofw/ofw_pcibus.c#3 edit
.. //depot/projects/ppc-g5/sys/powerpc/powermac/cpcht.c#9 edit
.. //depot/projects/ppc-g5/sys/powerpc/powermac/cpchtvar.h#3 edit
.. //depot/projects/ppc-g5/sys/powerpc/powermac/grackle.c#6 edit
.. //depot/projects/ppc-g5/sys/powerpc/powermac/gracklevar.h#3 edit
.. //depot/projects/ppc-g5/sys/powerpc/powermac/uninorth.c#7 edit
.. //depot/projects/ppc-g5/sys/powerpc/powermac/uninorthvar.h#6 edit

Differences ...

==== //depot/projects/ppc-g5/sys/powerpc/ofw/ofw_pcibus.c#3 (text+ko) ====

@@ -56,8 +56,8 @@
 typedef uint32_t ofw_pci_intr_t;
 
 /* Helper functions */
-static void ofw_pcibus_setup_device(device_t bridge, uint32_t clock,
-    u_int busno, u_int slot, u_int func);
+static void ofw_pcibus_setup_device(device_t bridge, phandle_t dev, 
+    uint32_t clock, u_int busno, u_int slot, u_int func);
 
 /* Methods */
 static device_probe_t ofw_pcibus_probe;
@@ -114,16 +114,20 @@
  * Perform miscellaneous setups the firmware usually does not do for us.
  */
 static void
-ofw_pcibus_setup_device(device_t bridge, uint32_t clock, u_int busno,
-    u_int slot, u_int func)
+ofw_pcibus_setup_device(device_t bridge, phandle_t dev,  uint32_t clock, 
+    u_int busno, u_int slot, u_int func)
 {
+	int intline = PCI_INVALID_IRQ;
+
 	/*
 	 * The preset in the intline register is usually wrong.  Reset
 	 * it to 255, so that the PCI code will reroute the interrupt if
 	 * needed.
 	 */
+	if (OF_getproplen(dev, "interrupts") > 0)
+		intline = 0;
 	PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_INTLINE,
-	    PCI_INVALID_IRQ, 1);
+	    intline, 1);
 }
 
 static int
@@ -155,7 +159,7 @@
 		/* Some OFW device trees contain dupes. */
 		if (pci_find_dbsf(domain, busno, slot, func) != NULL)
 			continue;
-		ofw_pcibus_setup_device(pcib, clock, busno, slot, func);
+		ofw_pcibus_setup_device(pcib, child, clock, busno, slot, func);
 		dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib,
 		    domain, busno, slot, func, sizeof(*dinfo));
 		if (dinfo == NULL)

==== //depot/projects/ppc-g5/sys/powerpc/powermac/cpcht.c#9 (text+ko) ====

@@ -318,7 +318,7 @@
 cpcpci_attach(device_t dev)
 {
 	struct		cpcpci_softc *sc;
-	phandle_t	node;
+	phandle_t	node, iparent;
 	u_int32_t	reg[2], busrange[2], config_base;
 	struct		cpcpci_range *rp, *io, *mem[2];
 	struct		cpcpci_range fakeio;
@@ -415,6 +415,12 @@
 
 	ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(cell_t));
 
+	/* We need the number of interrupt cells to read the imap */
+	sc->sc_icells = 2;
+	if (OF_getprop(node, "interrupt-parent", &iparent,sizeof(iparent)) > 0)
+		OF_getprop(iparent,"#interrupt-cells",&sc->sc_icells, 
+		    sizeof(sc->sc_icells));
+
 	device_add_child(dev, "pci", device_get_unit(dev));
 
 	return (bus_generic_attach(dev));
@@ -606,14 +612,15 @@
 {
 	struct cpcpci_softc *sc;
 	struct ofw_pci_register reg;
-	uint32_t pintr, mintr;
+	uint32_t pintr, mintr[2];
 	uint8_t maskbuf[sizeof(reg) + sizeof(pintr)];
 
 	sc = device_get_softc(bus);
 	pintr = pin;
 	if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, &reg,
-	    sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr), maskbuf))
-		return (mintr);
+	    sizeof(reg), &pintr, sizeof(pintr), &mintr, 
+	    sizeof(mintr[0])*sc->sc_icells, maskbuf))
+		return (mintr[0]);
 
 	/* Maybe it's a real interrupt, not an intpin */
 	if (pin > 4)

==== //depot/projects/ppc-g5/sys/powerpc/powermac/cpchtvar.h#3 (text+ko) ====

@@ -53,6 +53,7 @@
 	bus_space_tag_t		sc_memt;
 	bus_dma_tag_t		sc_dmat;
 	struct ofw_bus_iinfo	sc_pci_iinfo;
+	int			sc_icells;
 };
 
 #endif  /* _POWERPC_POWERMAC_CPCHTVAR_H_ */

==== //depot/projects/ppc-g5/sys/powerpc/powermac/grackle.c#6 (text+ko) ====

@@ -165,7 +165,7 @@
 grackle_attach(device_t dev)
 {
 	struct		grackle_softc *sc;
-	phandle_t	node;
+	phandle_t	node, iparent;
 	u_int32_t	busrange[2];
 	struct		grackle_range *rp, *io, *mem[2];
 	int		nmem, i, error;
@@ -254,6 +254,12 @@
 
 	ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(cell_t));
 
+	/* We need the number of interrupt cells to read the imap */
+	sc->sc_icells = 2;
+	if (OF_getprop(node, "interrupt-parent", &iparent,sizeof(iparent)) > 0)
+		OF_getprop(iparent,"#interrupt-cells",&sc->sc_icells, 
+		    sizeof(sc->sc_icells));
+
 	device_add_child(dev, "pci", device_get_unit(dev));
 	return (bus_generic_attach(dev));
 }
@@ -340,14 +346,15 @@
 {
 	struct grackle_softc *sc;
 	struct ofw_pci_register reg;
-	uint32_t pintr, mintr;
+	uint32_t pintr, mintr[2];
 	uint8_t maskbuf[sizeof(reg) + sizeof(pintr)];
 
 	sc = device_get_softc(bus);
 	pintr = pin;
 	if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, &reg,
-	    sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr), maskbuf))
-		return (mintr);
+	    sizeof(reg), &pintr, sizeof(pintr), &mintr, 
+	    sizeof(mintr[0])*sc->sc_icells, maskbuf))
+		return (mintr[0]);
 
 	/* Maybe it's a real interrupt, not an intpin */
 	if (pin > 4)

==== //depot/projects/ppc-g5/sys/powerpc/powermac/gracklevar.h#3 (text+ko) ====

@@ -52,6 +52,7 @@
 	struct			rman sc_mem_rman;
 	bus_space_tag_t		sc_memt;
 	bus_dma_tag_t		sc_dmat;
+	int			sc_icells;
 
 	struct ofw_bus_iinfo	sc_pci_iinfo;
 };

==== //depot/projects/ppc-g5/sys/powerpc/powermac/uninorth.c#7 (text+ko) ====

@@ -164,8 +164,7 @@
 {
 	struct		uninorth_softc *sc;
 	const char	*compatible;
-	phandle_t	node;
-	phandle_t	child;
+	phandle_t	node, child, iparent;
 	u_int32_t	reg[2], busrange[2];
 	struct		uninorth_range *rp, *io, *mem[2];
 	int		nmem, i, error;
@@ -297,6 +296,12 @@
 
 	ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(cell_t));
 
+	/* We need the number of interrupt cells to read the imap */
+	sc->sc_icells = 2;
+	if (OF_getprop(node, "interrupt-parent", &iparent,sizeof(iparent)) > 0)
+		OF_getprop(iparent,"#interrupt-cells",&sc->sc_icells, 
+		    sizeof(sc->sc_icells));
+
 	device_add_child(dev, "pci", device_get_unit(dev));
 	return (bus_generic_attach(dev));
 }
@@ -365,14 +370,15 @@
 {
 	struct uninorth_softc *sc;
 	struct ofw_pci_register reg;
-	uint32_t pintr, mintr;
+	uint32_t pintr, mintr[2];
 	uint8_t maskbuf[sizeof(reg) + sizeof(pintr)];
 
 	sc = device_get_softc(bus);
 	pintr = pin;
 	if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, &reg,
-	    sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr), maskbuf))
-		return (mintr);
+	    sizeof(reg), &pintr, sizeof(pintr), mintr, 
+	    sizeof(mintr[0])*sc->sc_icells, maskbuf))
+		return (mintr[0]);
 
 	/* Maybe it's a real interrupt, not an intpin */
 	if (pin > 4)

==== //depot/projects/ppc-g5/sys/powerpc/powermac/uninorthvar.h#6 (text+ko) ====

@@ -64,6 +64,7 @@
 	struct ofw_bus_iinfo	sc_pci_iinfo;
 
 	int			sc_u3;
+	int			sc_icells;
 };
 
 struct unin_chip_softc {


More information about the p4-projects mailing list