ia64/linux-2.6.18-xen.hg

changeset 593:bb937c2f7382

Hook Linux's PCI probe and remove callbacks

Hijack the pci_bus_type probe and remove callbacks. This option only
requires modification to the Xen specific part of Linux.

Signed-off-by: Joshua LeVasseur <joshua.levasseur@netronome.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jul 04 17:55:07 2008 +0100 (2008-07-04)
parents a2e385815f36
children da710ff0899a
files drivers/xen/core/Makefile drivers/xen/core/pci.c
line diff
     1.1 --- a/drivers/xen/core/Makefile	Fri Jul 04 17:53:20 2008 +0100
     1.2 +++ b/drivers/xen/core/Makefile	Fri Jul 04 17:55:07 2008 +0100
     1.3 @@ -4,6 +4,7 @@
     1.4  
     1.5  obj-y := evtchn.o gnttab.o features.o reboot.o machine_reboot.o firmware.o
     1.6  
     1.7 +obj-$(CONFIG_PCI)		+= pci.o
     1.8  obj-$(CONFIG_PROC_FS)		+= xen_proc.o
     1.9  obj-$(CONFIG_SYS_HYPERVISOR)	+= hypervisor_sysfs.o
    1.10  obj-$(CONFIG_HOTPLUG_CPU)	+= cpu_hotplug.o
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/drivers/xen/core/pci.c	Fri Jul 04 17:55:07 2008 +0100
     2.3 @@ -0,0 +1,61 @@
     2.4 +/*
     2.5 + * vim:shiftwidth=8:noexpandtab
     2.6 + */
     2.7 +
     2.8 +#include <linux/kernel.h>
     2.9 +#include <linux/init.h>
    2.10 +#include <linux/pci.h>
    2.11 +#include <xen/interface/physdev.h>
    2.12 +
    2.13 +static int (*pci_bus_probe)(struct device *dev);
    2.14 +static int (*pci_bus_remove)(struct device *dev);
    2.15 +
    2.16 +static int pci_bus_probe_wrapper(struct device *dev)
    2.17 +{
    2.18 +	int r;
    2.19 +	struct pci_dev *pci_dev = to_pci_dev(dev);
    2.20 +	struct physdev_manage_pci manage_pci;
    2.21 +	manage_pci.bus = pci_dev->bus->number;
    2.22 +	manage_pci.devfn = pci_dev->devfn;
    2.23 +
    2.24 +	r = HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_add, &manage_pci);
    2.25 +	if (r)
    2.26 +		return r;
    2.27 +
    2.28 +	r = pci_bus_probe(dev);
    2.29 +	if (r)
    2.30 +		HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_remove, &manage_pci);
    2.31 +
    2.32 +	return r;
    2.33 +}
    2.34 +
    2.35 +static int pci_bus_remove_wrapper(struct device *dev)
    2.36 +{
    2.37 +	int r;
    2.38 +	struct pci_dev *pci_dev = to_pci_dev(dev);
    2.39 +	struct physdev_manage_pci manage_pci;
    2.40 +	manage_pci.bus = pci_dev->bus->number;
    2.41 +	manage_pci.devfn = pci_dev->devfn;
    2.42 +
    2.43 +	r = pci_bus_remove(dev);
    2.44 +	/* dev and pci_dev are no longer valid!! */
    2.45 +
    2.46 +	HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_remove, &manage_pci);
    2.47 +	return r;
    2.48 +}
    2.49 +
    2.50 +static int __init hook_pci_bus(void)
    2.51 +{
    2.52 +	if (!is_running_on_xen() || !is_initial_xendomain())
    2.53 +		return 0;
    2.54 +
    2.55 +	pci_bus_probe = pci_bus_type.probe;
    2.56 +	pci_bus_type.probe = pci_bus_probe_wrapper;
    2.57 +
    2.58 +	pci_bus_remove = pci_bus_type.remove;
    2.59 +	pci_bus_type.remove = pci_bus_remove_wrapper;
    2.60 +
    2.61 +	return 0;
    2.62 +}
    2.63 +
    2.64 +core_initcall(hook_pci_bus);