[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [qemu-xen-unstable] passthrough: use devfn instead of slots as the unit for pass-through
commit 7551a514dd944a5155747071135bac11deb61c43 Author: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> Date: Thu Jun 25 18:30:25 2009 +0100 passthrough: use devfn instead of slots as the unit for pass-through This is part of support for multi-function PCI devices in guests Instead of reading a slot number from xend, read a devfn. This and subsequent other changes will allow xend to ask for more than one function to be inserted into a single slot - by specifying which function of the slot should be used. This is a minimal patch for this change. A subsequent patch that has a lot of noise to rename slot to devfn follows. This patch breaks compatibility with xend and corresponding patches to xend are required. Cc: Dexuan Cui <dexuan.cui@xxxxxxxxx> Cc: Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx> Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx> [3/8; cross-compatibility issues with xen-unstable.hg] --- hw/pass-through.c | 40 ++++++++++++++-------------- hw/pci.h | 7 +++- hw/piix4acpi.c | 75 ++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 79 insertions(+), 43 deletions(-) diff --git a/hw/pass-through.c b/hw/pass-through.c index 07ca751..d19fb82 100644 --- a/hw/pass-through.c +++ b/hw/pass-through.c @@ -103,7 +103,7 @@ struct php_dev { }; struct dpci_infos { - struct php_dev php_devs[NR_PCI_DEV]; + struct php_dev php_devs[NR_PCI_DEVFN]; PCIBus *e_bus; struct pci_access *pci_access; @@ -859,7 +859,7 @@ static int parse_bdf(char **str, int *seg, int *bus, int *dev, int *func, } else { - *vslot = AUTO_PHP_SLOT; + *vslot = AUTO_PHP_DEVFN; *opt = token; } @@ -903,30 +903,30 @@ static int pci_slot_match(int bus, int dev, int func, int slot) } /* Insert a new pass-through device into a specific pci slot. - * input dom:bus:dev.func@slot, chose free one if slot == AUTO_PHP_SLOT + * input dom:bus:dev.func@slot, chose free one if slot == AUTO_PHP_DEVFN * return -2: requested slot not available * -1: no free slots * >=0: the new hotplug slot */ -static int __insert_to_pci_slot(int bus, int dev, int func, int slot, +static int __insert_to_pci_slot(int bus, int dev, int func, int devfn, char *opt) { PCIBus *e_bus = dpci_infos.e_bus; + int slot; - /* preferred virt pci slot */ - if ( slot != AUTO_PHP_SLOT) + /* preferred virt pci devfn */ + if ( devfn != AUTO_PHP_DEVFN ) { - if ( !test_pci_slot(slot) && - !pci_devfn_in_use(e_bus, PCI_DEVFN(slot, 0)) ) + if ( !test_pci_slot(devfn) && !pci_devfn_in_use(e_bus, devfn) ) goto found; return -2; } - /* slot == 0, pick up a free one */ + /* pick a free slot */ for ( slot = 0; slot < NR_PCI_DEV; slot++ ) { - if ( !test_pci_slot(slot) && - !pci_devfn_in_use(e_bus, PCI_DEVFN(slot, 0)) ) + devfn = PCI_DEVFN(slot, 0); + if ( !test_pci_slot(devfn) && !pci_devfn_in_use(e_bus, devfn) ) goto found; } @@ -934,12 +934,12 @@ static int __insert_to_pci_slot(int bus, int dev, int func, int slot, return -1; found: - dpci_infos.php_devs[slot].valid = 1; - dpci_infos.php_devs[slot].r_bus = bus; - dpci_infos.php_devs[slot].r_dev = dev; - dpci_infos.php_devs[slot].r_func = func; - dpci_infos.php_devs[slot].opt = opt; - return slot; + dpci_infos.php_devs[devfn].valid = 1; + dpci_infos.php_devs[devfn].r_bus = bus; + dpci_infos.php_devs[devfn].r_dev = dev; + dpci_infos.php_devs[devfn].r_func = func; + dpci_infos.php_devs[devfn].opt = opt; + return devfn; } /* Insert a new pass-through device into a specific pci slot. @@ -966,7 +966,7 @@ int insert_to_pci_slot(char *bdf_slt) */ int test_pci_slot(int slot) { - if ( slot < 0 || slot >= NR_PCI_DEV ) + if ( slot < 0 || slot >= NR_PCI_DEVFN ) return -1; if ( dpci_infos.php_devs[slot].valid ) @@ -987,7 +987,7 @@ int bdf_to_slot(char *bdf_str) } /* locate the virtual pci slot for this VTd device */ - for ( i = 0; i < NR_PCI_DEV; i++ ) + for ( i = 0; i < NR_PCI_DEVFN; i++ ) { if ( pci_slot_match(bus, dev, func, i) ) return i; @@ -4037,7 +4037,7 @@ static struct pt_dev * register_real_device(PCIBus *e_bus, /* Register device */ assigned_device = (struct pt_dev *) pci_register_device(e_bus, e_dev_name, - sizeof(struct pt_dev), PCI_DEVFN(e_slot, 0), + sizeof(struct pt_dev), e_slot, pt_pci_read_config, pt_pci_write_config); if ( assigned_device == NULL ) { diff --git a/hw/pci.h b/hw/pci.h index d45b80c..b5947f3 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -255,8 +255,11 @@ void pci_info(void); PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did, pci_map_irq_fn map_irq, const char *name); -#define NR_PCI_DEV 32 -#define AUTO_PHP_SLOT NR_PCI_DEV +#define NR_PCI_FUNC 8 +#define NR_PCI_DEV 32 +#define NR_PCI_DEVFN (NR_PCI_FUNC * NR_PCI_DEV) +#define AUTO_PHP_SLOT NR_PCI_DEV +#define AUTO_PHP_DEVFN NR_PCI_DEVFN int insert_to_pci_slot(char*); int test_pci_slot(int); diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c index d5c5c35..836abd5 100644 --- a/hw/piix4acpi.c +++ b/hw/piix4acpi.c @@ -33,6 +33,8 @@ #include <xen/hvm/ioreq.h> #include <xen/hvm/params.h> +#include <pci/header.h> + /* PM1a_CNT bits, as defined in the ACPI specification. */ #define SCI_EN (1 << 0) #define GBL_RLS (1 << 2) @@ -276,7 +278,7 @@ static void acpi_php_writeb(void *opaque, uint32_t addr, uint32_t val) hotplug_slots->plug_slot = 0; /* power off the slot */ - power_off_php_slot(slot); + power_off_php_slot(PCI_DEVFN(slot, 0)); /* signal the CP ACPI hot remove done. */ xenstore_record_dm_state("pci-removed"); @@ -459,17 +461,32 @@ static void acpi_sci_intr(GPEState *s) } } -void acpi_php_del(int slot) +void acpi_php_del(int devfn) { GPEState *s = &gpe_state; + int slot, func; + + slot = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); - if ( test_pci_slot(slot) < 0 ) { - fprintf(logfile, "hot remove: pci slot %d " - "is not used by a hotplug device.\n", slot); + if ( test_pci_slot(devfn) < 0 ) { + fprintf(logfile, "hot remove: pci slot 0x%02x, function 0x%x " + "is not used by a hotplug device.\n", slot, func); return; } + /* ACPI PHP can only work on slots + * So only remove zero-functions - + * which will remove all other fucntions of the same device in the + * guest. + */ + if ( func ) { + fprintf(logfile, "hot remove: Attempt to remove non-zero function " + "slot=0x%02x func=0x%0x.\n", slot, func); + return; + } + /* update the php controller status */ php_slots.plug_evt = PHP_EVT_REMOVE; php_slots.plug_slot = slot; @@ -478,18 +495,19 @@ void acpi_php_del(int slot) acpi_sci_intr(s); } -void acpi_php_add(int slot) +void acpi_php_add(int devfn) { GPEState *s = &gpe_state; char ret_str[30]; + int slot, func; - if ( slot < 0 ) { - fprintf(logfile, "hot add pci slot %d exceed.\n", slot); + if ( devfn < 0 ) { + fprintf(logfile, "hot add pci devfn %d exceed.\n", devfn); - if ( slot == -1 ) - sprintf(ret_str, "no free hotplug slots"); - else if ( slot == -2 ) - sprintf(ret_str, "wrong bdf or vslot"); + if ( devfn == -1 ) + sprintf(ret_str, "no free hotplug devfn"); + else if ( devfn == -2 ) + sprintf(ret_str, "wrong bdf or vdevfn"); if ( strlen(ret_str) > 0 ) xenstore_record_dm("parameter", ret_str); @@ -497,25 +515,40 @@ void acpi_php_add(int slot) return; } - /* update the php controller status */ - php_slots.plug_evt = PHP_EVT_ADD; - php_slots.plug_slot = slot; + /* ACPI PHP can only work on slots + * For function 0 we do a full hot-add. + * For other functions we just register the device with the hypervisor. + * Assuming that function 0 is added after non-zero functions, + * its ACPI PHP event will cause all previously registered functions + * to be added to the guest. + */ - /* update the slot status as present */ - php_slots.status[slot] = 0xf; + slot = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); - /* power on the slot */ - power_on_php_slot(slot); + if ( !func ) + { + /* update the php controller status */ + php_slots.plug_evt = PHP_EVT_ADD; + php_slots.plug_slot = slot; + + /* update the slot status as present */ + php_slots.status[slot] = 0xf; + } + + /* power on the function */ + power_on_php_slot(devfn); /* tell Control panel which slot for the new pass-throgh dev */ - sprintf(ret_str, "0x%02x", slot); + sprintf(ret_str, "0x%02x", devfn); xenstore_record_dm("parameter", ret_str); /* signal the CP ACPI hot insert done */ xenstore_record_dm_state("pci-inserted"); /* generate a SCI interrupt */ - acpi_sci_intr(s); + if ( !func ) + acpi_sci_intr(s); } #endif /* CONFIG_PASSTHROUGH */ -- generated by git-patchbot for /home/xen/git/qemu-xen-unstable.git _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |