From 411d8955bf1d366622c66beb2507a22250af9ca0 Mon Sep 17 00:00:00 2001
From: Roger Pau Monne <roger.pau@citrix.com>
Date: Mon, 3 Mar 2014 19:39:06 +0100
Subject: [PATCH 20/31] pci: make pci_add_child a PCI newbus method

This is needed so when running under Xen the calls to pci_add_child
can be intercepted and a custom Xen method can be used to register
those devices with Xen. This should not include any functional
change, since the Xen implementation will be added in a following
patch.

Approved by: xxx
Sponsored by: Citrix Systems R&D

dev/pci/pci.c:
dev/pci/pci_if.m:
dev/pci/pci_private.h:
dev/pci/pcivar.h:
 - Make pci_add_child a newbus method.

mips/nlm/xlp_pci.c:
powerpc/ofw/ofw_pcibus.c:
sparc64/pci/ofw_pcibus.c:
 - Fix previous callers of pci_add_child to use the new method.
---
 sys/dev/pci/pci.c            |   21 ++++++++++++++-------
 sys/dev/pci/pci_if.m         |    5 +++++
 sys/dev/pci/pci_private.h    |    2 +-
 sys/dev/pci/pcivar.h         |    6 ++++++
 sys/mips/nlm/xlp_pci.c       |    4 +++-
 sys/powerpc/ofw/ofw_pcibus.c |    8 ++++++--
 sys/sparc64/pci/ofw_pcibus.c |   11 ++++++++---
 7 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 57eea97..24c0c2e 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -180,6 +180,7 @@ static device_method_t pci_methods[] = {
 	DEVMETHOD(pci_release_msi,	pci_release_msi_method),
 	DEVMETHOD(pci_msi_count,	pci_msi_count_method),
 	DEVMETHOD(pci_msix_count,	pci_msix_count_method),
+	DEVMETHOD(pci_add_child,	pci_add_child_method),
 
 	DEVMETHOD_END
 };
@@ -3476,7 +3477,9 @@ pci_add_children(device_t dev, int domain, int busno, size_t dinfo_size)
 			dinfo = pci_read_device(pcib, domain, busno, s, f,
 			    dinfo_size);
 			if (dinfo != NULL) {
-				pci_add_child(dev, dinfo);
+				dinfo->cfg.dev = device_add_child(dev, NULL, -1);
+				device_set_ivars(dinfo->cfg.dev, dinfo);
+				pci_add_child(dinfo->cfg.dev);
 			}
 		}
 	}
@@ -3484,15 +3487,19 @@ pci_add_children(device_t dev, int domain, int busno, size_t dinfo_size)
 }
 
 void
-pci_add_child(device_t bus, struct pci_devinfo *dinfo)
+pci_add_child_method(device_t dev, device_t child)
 {
-	dinfo->cfg.dev = device_add_child(bus, NULL, -1);
-	device_set_ivars(dinfo->cfg.dev, dinfo);
+	struct pci_devinfo *dinfo;
+
+	dinfo = device_get_ivars(child);
+	KASSERT((dinfo != NULL),
+	    ("pci_add_child_method called with NULL pci_devinfo"));
+
 	resource_list_init(&dinfo->resources);
-	pci_cfg_save(dinfo->cfg.dev, dinfo, 0);
-	pci_cfg_restore(dinfo->cfg.dev, dinfo);
+	pci_cfg_save(child, dinfo, 0);
+	pci_cfg_restore(child, dinfo);
 	pci_print_verbose(dinfo);
-	pci_add_resources(bus, dinfo->cfg.dev, 0, 0);
+	pci_add_resources(dev, child, 0, 0);
 }
 
 static int
diff --git a/sys/dev/pci/pci_if.m b/sys/dev/pci/pci_if.m
index 451ac58..abfbd97 100644
--- a/sys/dev/pci/pci_if.m
+++ b/sys/dev/pci/pci_if.m
@@ -179,3 +179,8 @@ METHOD int msix_count {
 	device_t	dev;
 	device_t	child;
 } DEFAULT null_msi_count;
+
+METHOD void add_child {
+	device_t	dev;
+	device_t	child;
+};
diff --git a/sys/dev/pci/pci_private.h b/sys/dev/pci/pci_private.h
index 6a2b2cc..c8e9d1d 100644
--- a/sys/dev/pci/pci_private.h
+++ b/sys/dev/pci/pci_private.h
@@ -50,7 +50,6 @@ extern int 	pci_do_power_suspend;
 
 void		pci_add_children(device_t dev, int domain, int busno,
 		    size_t dinfo_size);
-void		pci_add_child(device_t bus, struct pci_devinfo *dinfo);
 void		pci_add_resources(device_t bus, device_t dev, int force,
 		    uint32_t prefetchmask);
 int		pci_attach_common(device_t dev);
@@ -125,6 +124,7 @@ int		pci_assign_interrupt_method(device_t dev, device_t child);
 int		pci_resume(device_t dev);
 int		pci_suspend(device_t dev);
 bus_dma_tag_t pci_get_dma_tag(device_t bus, device_t dev);
+void		pci_add_child_method(device_t dev, device_t child);
 
 /** Restore the config register state.  The state must be previously
  * saved with pci_cfg_save.  However, the pci bus driver takes care of
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
index 2933ebb..29b31e9 100644
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -500,6 +500,12 @@ pci_msix_count(device_t dev)
     return (PCI_MSIX_COUNT(device_get_parent(dev), dev));
 }
 
+static __inline void
+pci_add_child(device_t dev)
+{
+    return (PCI_ADD_CHILD(device_get_parent(dev), dev));
+}
+
 device_t pci_find_bsf(uint8_t, uint8_t, uint8_t);
 device_t pci_find_dbsf(uint32_t, uint8_t, uint8_t, uint8_t);
 device_t pci_find_device(uint16_t, uint16_t);
diff --git a/sys/mips/nlm/xlp_pci.c b/sys/mips/nlm/xlp_pci.c
index 71f1d19..ee51a22 100644
--- a/sys/mips/nlm/xlp_pci.c
+++ b/sys/mips/nlm/xlp_pci.c
@@ -273,7 +273,9 @@ xlp_add_soc_child(device_t pcib, device_t dev, int b, int s, int f)
 	if ((flags & MEM_RES_EMUL) != 0)
 		xlp_dinfo->mem_res_start = XLP_DEFAULT_IO_BASE + devoffset +
 		    XLP_IO_PCI_HDRSZ;
-	pci_add_child(dev, dinfo);
+	dinfo->cfg.dev = device_add_child(dev, NULL, -1);
+	device_set_ivars(dinfo->cfg.dev, dinfo);
+	pci_add_child(dinfo->cfg.dev);
 }
 
 static int
diff --git a/sys/powerpc/ofw/ofw_pcibus.c b/sys/powerpc/ofw/ofw_pcibus.c
index ee14ccf..7fa9c6a 100644
--- a/sys/powerpc/ofw/ofw_pcibus.c
+++ b/sys/powerpc/ofw/ofw_pcibus.c
@@ -192,7 +192,9 @@ ofw_pcibus_enum_devtree(device_t dev, u_int domain, u_int busno)
 			continue;
 		}
 		dinfo->opd_dma_tag = NULL;
-		pci_add_child(dev, (struct pci_devinfo *)dinfo);
+		dinfo->cfg.dev = device_add_child(dev, NULL, -1);
+		device_set_ivars(dinfo->cfg.dev, dinfo);
+		pci_add_child(dinfo->cfg.dev);
 
 		/*
 		 * Some devices don't have an intpin set, but do have
@@ -283,7 +285,9 @@ ofw_pcibus_enum_bus(device_t dev, u_int domain, u_int busno)
 				    PCIR_INTLINE, PCI_INVALID_IRQ, 1);
 			}
 
-			pci_add_child(dev, (struct pci_devinfo *)dinfo);
+			dinfo->cfg.dev = device_add_child(dev, NULL, -1);
+			device_set_ivars(dinfo->cfg.dev, dinfo);
+			pci_add_child(dinfo->cfg.dev);
 		}
 	}
 }
diff --git a/sys/sparc64/pci/ofw_pcibus.c b/sys/sparc64/pci/ofw_pcibus.c
index 92b9f76..07a7ee6 100644
--- a/sys/sparc64/pci/ofw_pcibus.c
+++ b/sys/sparc64/pci/ofw_pcibus.c
@@ -252,8 +252,11 @@ ofw_pcibus_attach(device_t dev)
 	    domain, busno, 0, 0, sizeof(*dinfo))) != NULL) {
 		if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, node) != 0)
 			pci_freecfg((struct pci_devinfo *)dinfo);
-		else
-			pci_add_child(dev, (struct pci_devinfo *)dinfo);
+		else {
+			dinfo->cfg.dev = device_add_child(dev, NULL, -1);
+			device_set_ivars(dinfo->cfg.dev, dinfo);
+			pci_add_child(dinfo->cfg.dev);
+		}
 	}
 
 	if (OF_getprop(ofw_bus_get_node(pcib), "clock-frequency", &clock,
@@ -277,7 +280,9 @@ ofw_pcibus_attach(device_t dev)
 			pci_freecfg((struct pci_devinfo *)dinfo);
 			continue;
 		}
-		pci_add_child(dev, (struct pci_devinfo *)dinfo);
+		dinfo->cfg.dev = device_add_child(dev, NULL, -1);
+		device_set_ivars(dinfo->cfg.dev, dinfo);
+		pci_add_child(dinfo->cfg.dev);
 		OFW_PCI_SETUP_DEVICE(pcib, dinfo->opd_dinfo.cfg.dev);
 	}
 
-- 
1.7.7.5 (Apple Git-26)

