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

From: John Baldwin <jhb_at_freebsd.org>
Date: Sat, 08 Feb 2014 16:57:11 -0500
On Tuesday, December 24, 2013 12:21:00 PM Roger Pau Monne wrote:
> 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.

It's really hackish to make this PCI specific.  OTOH, I can't think of a
good place to have a more generic new-bus callback.  You could make the
eventhandler pass the 'device_t' instead of the dinfo.  The dinfo isn't
really a public structure, and since the device_t's ivars are already set
you can use things like 'pci_get_domain()' and 'pci_get_bus()' of the
passed in device in your callback function.

> ---
>  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
> _at__at_ -3293,6 +3293,7 _at__at_ 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
> _at__at_ -269,5 +269,10 _at__at_ 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
> _at__at_ -39,6 +39,9 _at__at_ __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>
> _at__at_ -63,6 +66,8 _at__at_ __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 */
> _at__at_ -384,6 +389,22 _at__at_ 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
> _at__at_ -34,6 +34,7 _at__at_ __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>
> 
> _at__at_ -42,6 +43,7 _at__at_ __FBSDID("$FreeBSD$");
>  #include <machine/nexusvar.h>
> 
>  #include <xen/xen-os.h>
> +#include <xen/pv.h>
> 
>  static const char *xen_devices[] =
>  {
> _at__at_ -87,6 +89,10 _at__at_ 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
> _at__at_ -24,5 +24,6 _at__at_
>  #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__ */

-- 
John Baldwin
Received on Thu Feb 13 2014 - 19:24:54 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:46 UTC