svn commit: r256816 - in head/sys: dev/ofw powerpc/ofw

Nathan Whitehorn nwhitehorn at FreeBSD.org
Mon Oct 21 00:04:27 UTC 2013


Author: nwhitehorn
Date: Mon Oct 21 00:04:26 2013
New Revision: 256816
URL: http://svnweb.freebsd.org/changeset/base/256816

Log:
  Allow the OFW interrupt mapping code to work with PCI devices not enumerated
  by Open Firmware, as in the case of FDT.

Modified:
  head/sys/dev/ofw/ofw_bus_subr.c
  head/sys/powerpc/ofw/ofw_pci.c
  head/sys/powerpc/ofw/ofw_pcib_pci.c
  head/sys/powerpc/ofw/ofw_pcibus.c

Modified: head/sys/dev/ofw/ofw_bus_subr.c
==============================================================================
--- head/sys/dev/ofw/ofw_bus_subr.c	Sun Oct 20 23:40:16 2013	(r256815)
+++ head/sys/dev/ofw/ofw_bus_subr.c	Mon Oct 21 00:04:26 2013	(r256816)
@@ -208,7 +208,6 @@ ofw_bus_has_prop(device_t dev, const cha
 	return (OF_hasprop(node, propname));
 }
 
-#ifndef FDT
 void
 ofw_bus_setup_iinfo(phandle_t node, struct ofw_bus_iinfo *ii, int intrsz)
 {
@@ -246,9 +245,11 @@ ofw_bus_lookup_imap(phandle_t node, stru
 	KASSERT(regsz >= ii->opi_addrc,
 	    ("ofw_bus_lookup_imap: register size too small: %d < %d",
 		regsz, ii->opi_addrc));
-	rv = OF_getprop(node, "reg", reg, regsz);
-	if (rv < regsz)
-		panic("ofw_bus_lookup_imap: could not get reg property");
+	if (node != -1) {
+		rv = OF_getprop(node, "reg", reg, regsz);
+		if (rv < regsz)
+			panic("ofw_bus_lookup_imap: cannot get reg property");
+	}
 	return (ofw_bus_search_intrmap(pintr, pintrsz, reg, ii->opi_addrc,
 	    ii->opi_imap, ii->opi_imapsz, ii->opi_imapmsk, maskbuf, mintr,
 	    mintrsz, iparent));
@@ -328,4 +329,4 @@ ofw_bus_search_intrmap(void *intr, int i
 	}
 	return (0);
 }
-#endif /* !FDT */
+

Modified: head/sys/powerpc/ofw/ofw_pci.c
==============================================================================
--- head/sys/powerpc/ofw/ofw_pci.c	Sun Oct 20 23:40:16 2013	(r256815)
+++ head/sys/powerpc/ofw/ofw_pci.c	Mon Oct 21 00:04:26 2013	(r256816)
@@ -246,6 +246,13 @@ ofw_pci_route_interrupt(device_t bus, de
 
 	sc = device_get_softc(bus);
 	pintr = pin;
+
+	/* Fabricate imap information in case this isn't an OFW device */
+	bzero(&reg, sizeof(reg));
+	reg.phys_hi = (pci_get_bus(dev) << OFW_PCI_PHYS_HI_BUSSHIFT) |
+	    (pci_get_slot(dev) << OFW_PCI_PHYS_HI_DEVICESHIFT) |
+	    (pci_get_function(dev) << OFW_PCI_PHYS_HI_FUNCTIONSHIFT);
+
 	if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, &reg,
 	    sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
 	    &iparent, maskbuf))

Modified: head/sys/powerpc/ofw/ofw_pcib_pci.c
==============================================================================
--- head/sys/powerpc/ofw/ofw_pcib_pci.c	Sun Oct 20 23:40:16 2013	(r256815)
+++ head/sys/powerpc/ofw/ofw_pcib_pci.c	Mon Oct 21 00:04:26 2013	(r256816)
@@ -29,6 +29,7 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/systm.h>
 #include <sys/module.h>
 #include <sys/bus.h>
 #include <sys/malloc.h>
@@ -141,6 +142,13 @@ ofw_pcib_pci_route_interrupt(device_t br
 	ii = &sc->ops_iinfo;
 	if (ii->opi_imapsz > 0) {
 		pintr = intpin;
+
+		/* Fabricate imap information if this isn't an OFW device */
+		bzero(&reg, sizeof(reg));
+		reg.phys_hi = (pci_get_bus(dev) << OFW_PCI_PHYS_HI_BUSSHIFT) |
+		    (pci_get_slot(dev) << OFW_PCI_PHYS_HI_DEVICESHIFT) |
+		    (pci_get_function(dev) << OFW_PCI_PHYS_HI_FUNCTIONSHIFT);
+
 		if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), ii, &reg,
 		    sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
 		    &iparent, maskbuf)) {

Modified: head/sys/powerpc/ofw/ofw_pcibus.c
==============================================================================
--- head/sys/powerpc/ofw/ofw_pcibus.c	Sun Oct 20 23:40:16 2013	(r256815)
+++ head/sys/powerpc/ofw/ofw_pcibus.c	Mon Oct 21 00:04:26 2013	(r256816)
@@ -322,20 +322,9 @@ ofw_pcibus_assign_interrupt(device_t dev
 	if (node == -1) {
 		/* Non-firmware enumerated child, use standard routing */
 	
-		/*
-		 * XXX: Right now we don't have anything sensible to do here,
-		 * since the ofw_imap stuff relies on nodes having a reg
-		 * property. There exist ways around this, so the ePAPR
-		 * spec will need to be studied.
-		 */
-
-		return (PCI_INVALID_IRQ);
-
-#ifdef NOTYET
 		intr = pci_get_intpin(child);
 		return (PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child, 
 		    intr));
-#endif
 	}
 	
 	/*


More information about the svn-src-head mailing list