[PATCH RFC 11/13] pci: introduce a new event on PCI device detection

Roger Pau Monne roger.pau at citrix.com
Tue Dec 24 11:25:27 UTC 2013


Add a new event that will fire each time a PCI device is added to the
system, and allows us to register the device with Xen.
---
 sys/dev/pci/pci.c       |    1 +
 sys/sys/eventhandler.h  |    5 +++++
 sys/x86/xen/pv.c        |   21 +++++++++++++++++++++
 sys/x86/xen/xen_nexus.c |    6 ++++++
 sys/xen/pv.h            |    1 +
 5 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 4d8837f..2ee5093 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -3293,6 +3293,7 @@ pci_add_child(device_t bus, struct pci_devinfo *dinfo)
 	resource_list_init(&dinfo->resources);
 	pci_cfg_save(dinfo->cfg.dev, dinfo, 0);
 	pci_cfg_restore(dinfo->cfg.dev, dinfo);
+	EVENTHANDLER_INVOKE(pci_add, dinfo);
 	pci_print_verbose(dinfo);
 	pci_add_resources(bus, dinfo->cfg.dev, 0, 0);
 }
diff --git a/sys/sys/eventhandler.h b/sys/sys/eventhandler.h
index 111c21b..3201848 100644
--- a/sys/sys/eventhandler.h
+++ b/sys/sys/eventhandler.h
@@ -269,5 +269,10 @@ typedef void (*unregister_framebuffer_fn)(void *, struct fb_info *);
 EVENTHANDLER_DECLARE(register_framebuffer, register_framebuffer_fn);
 EVENTHANDLER_DECLARE(unregister_framebuffer, unregister_framebuffer_fn);
 
+/* PCI events */
+struct pci_devinfo;
+typedef void (*pci_add_fn)(void *, struct pci_devinfo *);
+EVENTHANDLER_DECLARE(pci_add, pci_add_fn);
+
 #endif /* _SYS_EVENTHANDLER_H_ */
 
diff --git a/sys/x86/xen/pv.c b/sys/x86/xen/pv.c
index e5ad200..a44f8ca 100644
--- a/sys/x86/xen/pv.c
+++ b/sys/x86/xen/pv.c
@@ -39,6 +39,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/rwlock.h>
 #include <sys/mutex.h>
 #include <sys/smp.h>
+#include <sys/reboot.h>
+#include <sys/pciio.h>
+#include <sys/eventhandler.h>
 
 #include <vm/vm.h>
 #include <vm/vm_extern.h>
@@ -63,6 +66,8 @@ __FBSDID("$FreeBSD$");
 
 #include <xen/interface/vcpu.h>
 
+#include <dev/pci/pcivar.h>
+
 /* Native initial function */
 extern u_int64_t hammer_time(u_int64_t, u_int64_t);
 /* Xen initial function */
@@ -384,6 +389,22 @@ xen_pv_ioapic_register_intr(struct ioapic_intsrc *pin)
 	xen_register_pirq(pin->io_irq, pin->io_activehi, pin->io_edgetrigger);
 }
 
+void
+xen_pv_pci_device_add(void *arg, struct pci_devinfo *dinfo)
+{
+	struct physdev_pci_device_add add_pci;
+	int error;
+
+	bzero(&add_pci, sizeof(add_pci));
+	add_pci.seg = dinfo->cfg.domain;
+	add_pci.bus = dinfo->cfg.bus;
+	add_pci.devfn = (dinfo->cfg.slot << 3) | dinfo->cfg.func;
+	error = HYPERVISOR_physdev_op(PHYSDEVOP_pci_device_add, &add_pci);
+	if (error)
+		printf("unable to add device bus %u devfn %u error: %d\n",
+		       add_pci.bus, add_pci.devfn, error);
+}
+
 static void
 xen_pv_set_init_ops(void)
 {
diff --git a/sys/x86/xen/xen_nexus.c b/sys/x86/xen/xen_nexus.c
index 823b3bc..60c6c5d 100644
--- a/sys/x86/xen/xen_nexus.c
+++ b/sys/x86/xen/xen_nexus.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/sysctl.h>
 #include <sys/systm.h>
 #include <sys/smp.h>
+#include <sys/eventhandler.h>
 
 #include <contrib/dev/acpica/include/acpi.h>
 
@@ -42,6 +43,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/nexusvar.h>
 
 #include <xen/xen-os.h>
+#include <xen/pv.h>
 
 static const char *xen_devices[] =
 {
@@ -87,6 +89,10 @@ nexus_xen_attach(device_t dev)
 		/* Disable some ACPI devices that are not usable by Dom0 */
 		setenv("debug.acpi.disabled", "cpu hpet timer");
 
+		/* Register PCI add hook */
+		EVENTHANDLER_REGISTER(pci_add, xen_pv_pci_device_add, NULL,
+		                      EVENTHANDLER_PRI_FIRST);
+
 		acpi_dev = BUS_ADD_CHILD(dev, 10, "acpi", 0);
 		if (acpi_dev == NULL)
 			panic("Unable to add ACPI bus to Xen Dom0");
diff --git a/sys/xen/pv.h b/sys/xen/pv.h
index a9d6eb0..ac737a7 100644
--- a/sys/xen/pv.h
+++ b/sys/xen/pv.h
@@ -24,5 +24,6 @@
 #define	__XEN_PV_H__
 
 int	xen_pv_start_all_aps(void);
+void	xen_pv_pci_device_add(void *, struct pci_devinfo *);
 
 #endif	/* __XEN_PV_H__ */
-- 
1.7.7.5 (Apple Git-26)



More information about the freebsd-current mailing list