[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [rfc 14/18] ioemu: use devfn instead of slots as the unit for passthrough



This allows multi-function cards to be appear in guets as
multi-function cards, with the restriction that function 0 must
be passed through. Otherwise each function is allocated its own
slot, as before.

e.g.

1. Function 0 and two other functions of a multi-function card are
passed through, and the function numbers are maintained in the guest.

Physical                     Guest
0:1b.0    - pass through ->  0:6.0
0:1b.1    - pass through ->  0:6.1
0:1b.2    - pass through ->  0:6.2

2. Two functions other than zero of a multi-function card are
passed through. Each function is represent as function 0 of a slot
in the guest.

Physical                     Guest
0:1b.1    - pass through ->  0:6.0
0:1b.2    - pass through ->  0:7.0

Subsequent patches will allow the virtual device and function
to be specified which amongst other things allows the exisiting
default behaviour to be configured.

This patch seems to break hotplug.
I am unsure of why, but am working towards a fix.

Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx>

--- 
* Thu, 12 Feb 2009 21:10:27 +1100
  Add missing PCI_TO_PHP_DEVFN conversion of non-zero devfn passed to
  insert_to_php_devfn(). This is a regression introduced by this patch.

Fri, 13 Feb 2009 15:22:10 +1100
* Rebased
  from "Restore xenfb.h and atkbd_ translation tables for * xenfbfront"
  to "fix memory/fd leak in pt_msix_init()"

Index: ioemu-remote/hw/piix4acpi.c
===================================================================
--- ioemu-remote.orig/hw/piix4acpi.c    2009-02-17 17:29:14.000000000 +0900
+++ ioemu-remote/hw/piix4acpi.c 2009-02-17 17:36:01.000000000 +0900
@@ -74,12 +74,12 @@ typedef struct GPEState {
 
 static GPEState gpe_state;
 
-typedef struct PHPSlots {
-    uint8_t status[PHP_SLOT_LEN]; /* Apaptor stats */
-    uint8_t plug_evt;      /* slot|event slot:0-no event;1-1st. 
event:0-remove;1-add */
-} PHPSlots;
+typedef struct PHPDevFn {
+    uint8_t status[PHP_DEVFN_LEN];    /* Apaptor stats */
+    uint16_t plug_evt;     /* devfn|event devfn:0-no event;1-1st. 
event:0-remove;1-add */
+} PHPDevFn;
 
-static PHPSlots php_slots;
+static PHPDevFn php_devfn_stat;
 int s3_shutdown_flag;
 static qemu_irq sci_irq;
 
@@ -218,25 +218,25 @@ static void acpi_dbg_writel(void *opaque
 /*
  * simple PCI hotplug controller IO 
  * ACPI_PHP_IO_ADDR + :
- * 0 - the hotplug description: slot(|event(remove/add); 
- * 1 - 1st php slot ctr/sts reg
- * 2 - 2nd php slot ctr/sts reg
+ * 0 - the hotplug description: devfn(|event(remove/add);
+ * 1 - 1st php devfn ctr/sts reg
+ * 2 - 2nd php devfn ctr/sts reg
  * ......
  */
 static uint32_t acpi_php_readb(void *opaque, uint32_t addr)
 {
-    PHPSlots *hotplug_slots = opaque;
+    PHPDevFn *hotplug_devfn = opaque;
     int num;
     uint32_t val; 
 
     switch (addr)
     {
     case ACPI_PHP_IO_ADDR:
-        val = hotplug_slots->plug_evt;
+        val = hotplug_devfn->plug_evt;
         break;
     default:
         num = addr - ACPI_PHP_IO_ADDR - 1;
-        val = hotplug_slots->status[num];
+        val = hotplug_devfn->status[num];
     }
 
     fprintf(logfile, "ACPI PCI hotplug: read addr=0x%x, val=0x%x.\n",
@@ -247,8 +247,8 @@ static uint32_t acpi_php_readb(void *opa
 
 static void acpi_php_writeb(void *opaque, uint32_t addr, uint32_t val)
 {
-    PHPSlots *hotplug_slots = opaque;
-    int php_slot;
+    PHPDevFn *hotplug_devfn = opaque;
+    int php_devfn;
 
     fprintf(logfile, "ACPI PCI hotplug: write addr=0x%x, val=0x%x.\n",
             addr, val);
@@ -258,16 +258,16 @@ static void acpi_php_writeb(void *opaque
     case ACPI_PHP_IO_ADDR:
         break;
     default:
-        php_slot = addr - ACPI_PHP_IO_ADDR - 1;
+        php_devfn = addr - ACPI_PHP_IO_ADDR - 1;
         if ( val == 0x1 ) { /* Eject command */
-            /* make _STA of the slot 0 */
-            hotplug_slots->status[php_slot] = 0;
+            /* make _STA of devfn 0 */
+            hotplug_devfn->status[php_devfn] = 0;
 
             /* clear the hotplug event */
-            hotplug_slots->plug_evt = 0;
+            hotplug_devfn->plug_evt = 0;
 
-            /* power off the slot */
-            power_off_php_slot(php_slot);
+            /* power off the devfn */
+            power_off_php_devfn(php_devfn);
 
             /* signal the CP ACPI hot remove done. */
             xenstore_record_dm_state("pci-removed");
@@ -275,48 +275,48 @@ static void acpi_php_writeb(void *opaque
     }
 }
 
-static void pcislots_save(QEMUFile* f, void* opaque)
+static void php_devfn_save(QEMUFile* f, void* opaque)
 {
-    PHPSlots *hotplug_slots = opaque;
+    PHPDevFn *hotplug_devfn = opaque;
     int i;
-    for ( i = 0; i < PHP_SLOT_LEN; i++ ) {
-        qemu_put_8s( f, &hotplug_slots->status[i]);
+    for ( i = 0; i < PHP_DEVFN_LEN; i++ ) {
+        qemu_put_8s( f, &hotplug_devfn->status[i]);
     }
-    qemu_put_8s(f, &hotplug_slots->plug_evt);
+    qemu_put_8s(f, &hotplug_devfn->plug_evt);
 }
 
-static int pcislots_load(QEMUFile* f, void* opaque, int version_id)
+static int php_devfn_load(QEMUFile* f, void* opaque, int version_id)
 {
-    PHPSlots *hotplug_slots = opaque;
+    PHPDevFn *hotplug_devfn = opaque;
     int i;
     if (version_id != 1)
         return -EINVAL;
-    for ( i = 0; i < PHP_SLOT_LEN; i++ ) {
-        qemu_get_8s( f, &hotplug_slots->status[i]);
+    for ( i = 0; i < PHP_DEVFN_LEN; i++ ) {
+        qemu_get_8s( f, &hotplug_devfn->status[i]);
     }
-    qemu_get_8s(f, &hotplug_slots->plug_evt);
+    qemu_get_8s(f, &hotplug_devfn->plug_evt);
     return 0;
 }
 
-static void php_slots_init(void)
+static void php_devfn_init(void)
 {
     int i;
-    memset(&php_slots, 0, sizeof(PHPSlots));
 
-    /* update the pci slot status */
-    for ( i = 0; i < PHP_SLOT_LEN; i++ ) {
-        if ( test_pci_slot( PHP_TO_PCI_SLOT(i) ) == 1 )
-            php_slots.status[i] = 0xf;
-    }
+    memset(&php_devfn_stat, 0, sizeof(PHPDevFn));
 
+    /* update the pci devfn status */
+    for ( i = 0; i < PHP_DEVFN_LEN; i++ ) {
+        if ( test_php_devfn(PHP_TO_PCI_DEVFN(i)) == 1 )
+            php_devfn_stat.status[i] = 0xf;
+    }
 
     /* ACPI PCI hotplug controller */
     register_ioport_read(ACPI_PHP_IO_ADDR, PHP_SLOT_LEN + 1, 1,
-                         acpi_php_readb, &php_slots);
+                         acpi_php_readb, &php_devfn_stat);
     register_ioport_write(ACPI_PHP_IO_ADDR, PHP_SLOT_LEN + 1, 1,
-                          acpi_php_writeb, &php_slots);
-    register_savevm("pcislots", 0, 1, pcislots_save, pcislots_load,
-                    &php_slots);
+                          acpi_php_writeb, &php_devfn_stat);
+    register_savevm("pcidevfn", 0, 1, php_devfn_save, php_devfn_load,
+                    &php_devfn_stat);
 }
 
 /* GPEx_STS occupy 1st half of the block, while GPEx_EN 2nd half */
@@ -449,37 +449,36 @@ static void acpi_sci_intr(GPEState *s)
     }
 }
 
-void acpi_php_del(int pci_slot)
+void acpi_php_del(int devfn)
 {
     GPEState *s = &gpe_state;
-    int php_slot = PCI_TO_PHP_SLOT(pci_slot);
-
-    if ( pci_slot < PHP_SLOT_START || pci_slot >= PHP_SLOT_END ) {
-        fprintf(logfile, "not find the pci slot %d when hot remove.\n", 
pci_slot);
+    int php_devfn = PCI_TO_PHP_DEVFN(devfn);
 
+    if ( !PCI_DEVFN_IS_PHP(devfn) ) {
+        fprintf(logfile, "not a php devfn: %d\n", devfn);
         return;
     }
 
     /* update the php controller status */
-    php_slots.plug_evt = (((php_slot+1) << 4) | PHP_EVT_REMOVE);
+    php_devfn_stat.plug_evt = (((php_devfn+1) << 4) | PHP_EVT_REMOVE);
 
     /* generate a SCI interrupt */
     acpi_sci_intr(s);
 }
 
-void acpi_php_add(int pci_slot)
+void acpi_php_add(int devfn)
 {
     GPEState *s = &gpe_state;
-    int php_slot = PCI_TO_PHP_SLOT(pci_slot);
+    int php_devfn = PCI_TO_PHP_DEVFN(devfn);
     char ret_str[30];
 
-    if ( pci_slot < PHP_SLOT_START || pci_slot >= PHP_SLOT_END ) {
-        fprintf(logfile, "hot add pci slot %d exceed.\n", pci_slot);
+    if ( !PCI_DEVFN_IS_PHP(devfn) ) {
+        fprintf(logfile, "not a php devfn: %d\n", devfn);
 
-        if ( pci_slot == 0 )
-            sprintf(ret_str, "no free hotplug slots");
-        else if ( pci_slot == -1 )
-            sprintf(ret_str, "wrong bdf or vslot");
+        if ( devfn == 0 )
+            sprintf(ret_str, "no free hotplug devfn");
+        else if ( devfn == -1 )
+            sprintf(ret_str, "wrong bdf or vdevfn");
 
         if ( strlen(ret_str) > 0 )
             xenstore_record_dm("parameter", ret_str);
@@ -488,16 +487,16 @@ void acpi_php_add(int pci_slot)
     }
 
     /* update the php controller status */
-    php_slots.plug_evt = (((php_slot+1) << 4) | PHP_EVT_ADD);
+    php_devfn_stat.plug_evt = (((php_devfn+1) << 4) | PHP_EVT_ADD);
 
-    /* update the slot status as present */
-    php_slots.status[php_slot]= 0xf;
+    /* update the devfn status as present */
+    php_devfn_stat.status[php_devfn]= 0xf;
 
-    /* power on the slot */
-    power_on_php_slot(php_slot);
+    /* power on the devfn */
+    power_on_php_devfn(php_devfn);
 
-    /* tell Control panel which slot for the new pass-throgh dev */
-    sprintf(ret_str, "0x%x", pci_slot);
+    /* tell Control panel which devfn for the new pass-throgh dev */
+    sprintf(ret_str, "0x%x", devfn);
     xenstore_record_dm("parameter", ret_str);
 
     /* signal the CP ACPI hot insert done */
@@ -555,7 +554,7 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int 
 
 #ifdef CONFIG_PASSTHROUGH
     gpe_acpi_init();
-    php_slots_init();
+    php_devfn_init();
     register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, d);
 #endif
 
Index: ioemu-remote/hw/pci.c
===================================================================
--- ioemu-remote.orig/hw/pci.c  2009-02-17 17:28:20.000000000 +0900
+++ ioemu-remote/hw/pci.c       2009-02-17 17:36:01.000000000 +0900
@@ -139,8 +139,7 @@ PCIDevice *pci_register_device(PCIBus *b
 
     if (devfn == PCI_DEVFN_AUTO) {
         for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
-            if ( !bus->devices[devfn] &&
-                 !( devfn >= PHP_DEVFN_START && devfn < PHP_DEVFN_END ) )
+            if ( !bus->devices[devfn] && !PCI_DEVFN_IS_PHP(devfn) )
                 goto found;
         }
         return NULL;
Index: ioemu-remote/hw/pass-through.c
===================================================================
--- ioemu-remote.orig/hw/pass-through.c 2009-02-17 17:29:05.000000000 +0900
+++ ioemu-remote/hw/pass-through.c      2009-02-17 17:36:01.000000000 +0900
@@ -38,7 +38,7 @@ struct php_dev {
 };
 static struct dpci_infos {
 
-    struct php_dev php_devs[PHP_SLOT_LEN];
+    struct php_dev php_devs[PHP_DEVFN_LEN];
 
     PCIBus *e_bus;
     struct pci_access *pci_access;
@@ -76,6 +76,8 @@ static uint32_t pt_msgdata_reg_init(stru
     struct pt_reg_info_tbl *reg, uint32_t real_offset);
 static uint32_t pt_msixctrl_reg_init(struct pt_dev *ptdev,
     struct pt_reg_info_tbl *reg, uint32_t real_offset);
+static uint32_t pt_header_type_reg_init(struct pt_dev *ptdev,
+    struct pt_reg_info_tbl *reg, uint32_t real_offset);
 static uint8_t pt_reg_grp_size_init(struct pt_dev *ptdev,
     struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset);
 static uint8_t pt_msi_size_init(struct pt_dev *ptdev,
@@ -243,7 +245,7 @@ static struct pt_reg_info_tbl pt_emu_reg
         .init_val   = 0x00,
         .ro_mask    = 0xFF,
         .emu_mask   = 0x80,
-        .init       = pt_common_reg_init,
+        .init       = pt_header_type_reg_init,
         .u.b.read   = pt_byte_reg_read,
         .u.b.write  = pt_byte_reg_write,
     },
@@ -794,58 +796,66 @@ static void msi_set_enable(struct pt_dev
     pci_write_word(ptdev->pci_dev, address, val);
 }
 
-/* Insert a new pass-through device into a specific pci slot.
+/* Insert a new pass-through device into function 0 of a specific pci slot.
  * input  dom:bus:dev.func@slot, chose free one if slot == 0
  * return -1: required slot not available
  *         0: no free hotplug slots, but normal slot should okay
- *        >0: the new hotplug slot
+ *        >0: the new hotplug devfn
  */
-static int __insert_to_pci_slot(int bus, int dev, int func, int slot,
+static int insert_to_php_devfn(int bus, int dev, int func, int devfn,
                                 char *opt)
 {
-    int i, php_slot;
+    int php_slot, php_func, php_devfn, php_devfn_match;
 
     /* preferred virt pci slot */
-    if ( slot >= PHP_SLOT_START && slot < PHP_SLOT_END )
+    if ( devfn >= PHP_DEVFN_START && devfn < PHP_DEVFN_END )
     {
-        php_slot = PCI_TO_PHP_SLOT(slot);
-        if ( !dpci_infos.php_devs[php_slot].valid )
-        {
+        php_devfn = PCI_TO_PHP_DEVFN(devfn);
+        if ( !dpci_infos.php_devs[php_devfn].valid )
             goto found;
-        }
-        else
-            return -1;
     }
-
-    if ( slot != 0 )
+    if ( devfn != 0 )
         return -1;
 
-    /* slot == 0, pick up a free one */
-    for ( i = 0; i < PHP_SLOT_LEN; i++ )
+    /* Co-locate functions for the same device in the same slot */
+    for ( php_slot = 0; php_slot < PHP_SLOT_LEN; php_slot++ )
     {
-        if ( !dpci_infos.php_devs[i].valid )
+        php_devfn = PCI_DEVFN(php_slot, func);
+        for ( php_func = 0; php_func < 8; php_func++ )
         {
-            php_slot = i;
-            goto found;
+            php_devfn_match = PCI_DEVFN(php_slot, php_func);
+            if ( dpci_infos.php_devs[php_devfn_match].valid &&
+                 dpci_infos.php_devs[php_devfn_match].r_bus == bus &&
+                 dpci_infos.php_devs[php_devfn_match].r_dev == dev &&
+                 !dpci_infos.php_devs[php_devfn].valid )
+                goto found;
         }
     }
 
+    /* Pick a free slot */
+    for ( php_slot = 0; php_slot < PHP_SLOT_LEN; php_slot++ )
+    {
+        php_devfn = PCI_DEVFN(php_slot, 0);
+        if ( !dpci_infos.php_devs[php_devfn].valid )
+            goto found;
+    }
+
     /* not found */
     return 0;
 
 found:
-    dpci_infos.php_devs[php_slot].valid  = 1;
-    dpci_infos.php_devs[php_slot].r_bus  = bus;
-    dpci_infos.php_devs[php_slot].r_dev  = dev;
-    dpci_infos.php_devs[php_slot].r_func = func;
-    dpci_infos.php_devs[php_slot].opt = opt;
-    return PHP_TO_PCI_SLOT(php_slot);
+    dpci_infos.php_devs[php_devfn].valid  = 1;
+    dpci_infos.php_devs[php_devfn].r_bus  = bus;
+    dpci_infos.php_devs[php_devfn].r_dev  = dev;
+    dpci_infos.php_devs[php_devfn].r_func = func;
+    dpci_infos.php_devs[php_devfn].opt = opt;
+    return PHP_TO_PCI_DEVFN(php_devfn);
 }
 
-/* Insert a new pass-through device into a specific pci slot.
+/* Insert a new pass-through device into function 0 of a specific pci slot.
  * input  dom:bus:dev.func@slot
  */
-int insert_to_pci_slot(char *bdf_slt)
+int insert_bdf_to_php_devfn(char *bdf_slt)
 {
     int seg, bus, dev, func, slot;
     char *bdf_str, *slt_str, *opt;
@@ -860,31 +870,31 @@ int insert_to_pci_slot(char *bdf_slt)
         return -1;
     }
 
-    return __insert_to_pci_slot(bus, dev, func, slot, opt);
+    return insert_to_php_devfn(bus, dev, func, PCI_DEVFN(slot, 0), opt);
 
 }
 
-/* Test if a pci slot has a device
+/* Test if a pci devfn has a device
  * 1:  present
  * 0:  not present
  * -1: invalide pci slot input
  */
-int test_pci_slot(int slot)
+int test_php_devfn(int devfn)
 {
-    int php_slot;
+    int php_devfn;
 
-    if ( slot < PHP_SLOT_START || slot >= PHP_SLOT_END )
+    if ( ! PCI_DEVFN_IS_PHP(devfn) )
         return -1;
 
-    php_slot = PCI_TO_PHP_SLOT(slot);
-    if ( dpci_infos.php_devs[php_slot].valid )
+    php_devfn = PCI_TO_PHP_DEVFN(devfn);
+    if ( dpci_infos.php_devs[php_devfn].valid )
         return 1;
     else
         return 0;
 }
 
 /* find the pci slot for pass-through dev with specified BDF */
-int bdf_to_slot(char *bdf_str)
+int bdf_to_php_devfn(char *bdf_str)
 {
     int seg, bus, dev, func, i;
     char *opt;
@@ -893,16 +903,17 @@ int bdf_to_slot(char *bdf_str)
     {
         return -1;
     }
+    PT_LOG("%s: bdf: %04x:%02x.%x\n", __func__, bus, dev, func);
 
     /* locate the virtual pci slot for this VTd device */
-    for ( i = 0; i < PHP_SLOT_LEN; i++ )
+    for ( i = 0; i < PHP_DEVFN_LEN; i++ )
     {
         if ( dpci_infos.php_devs[i].valid &&
            dpci_infos.php_devs[i].r_bus == bus &&
            dpci_infos.php_devs[i].r_dev  == dev &&
            dpci_infos.php_devs[i].r_func == func )
         {
-            return PHP_TO_PCI_SLOT(i);
+            return PHP_TO_PCI_DEVFN(i);
         }
     }
 
@@ -2313,6 +2324,19 @@ static uint8_t pt_pcie_size_init(struct 
     return pcie_size;
 }
 
+/* read PCI_HEADER_TYPE */
+static uint32_t pt_header_type_reg_init(struct pt_dev *ptdev,
+    struct pt_reg_info_tbl *reg, uint32_t real_offset)
+{
+    uint32_t r_val;
+
+    r_val = pci_read_byte(ptdev->pci_dev, PCI_HEADER_TYPE);
+
+    /* If the real device is multi-function,
+     * the passed-through device can be too */
+    return reg->init_val | (r_val & 0x80);
+}
+
 /* read byte size emulate register */
 static int pt_byte_reg_read(struct pt_dev *ptdev,
         struct pt_reg_tbl *cfg_entry,
@@ -3078,7 +3102,7 @@ static struct pt_dev * register_real_dev
     struct pci_dev *pci_dev;
     uint8_t e_device, e_intx;
     struct pci_config_cf8 machine_bdf;
-    int free_pci_slot = -1;
+    int free_devfn = -1;
     char *key, *val;
     int msi_translate;
 
@@ -3103,9 +3127,9 @@ static struct pt_dev * register_real_dev
 
     if ( e_devfn == PCI_DEVFN_AUTO ) {
         /*indicate a static assignment(not hotplug), so find a free PCI hot 
plug slot */
-        free_pci_slot = __insert_to_pci_slot(r_bus, r_dev, r_func, 0, NULL);
-        if ( free_pci_slot > 0 )
-            e_devfn = free_pci_slot  << 3;
+        free_devfn = insert_to_php_devfn(r_bus, r_dev, r_func, 0, NULL);
+        if ( free_devfn > 0 )
+            e_devfn = free_devfn;
         else
             PT_LOG("Error: no free virtual PCI hot plug slot, thus no live 
migration.\n");
     }
@@ -3148,8 +3172,9 @@ static struct pt_dev * register_real_dev
         return NULL;
     }
 
-    if ( free_pci_slot > 0 )
-        dpci_infos.php_devs[PCI_TO_PHP_SLOT(free_pci_slot)].pt_dev = 
assigned_device;
+    if ( free_devfn > 0 )
+        dpci_infos.php_devs[PCI_TO_PHP_DEVFN(free_devfn)].pt_dev =
+                assigned_device;
 
     assigned_device->pci_dev = pci_dev;
     assigned_device->msi_trans_cap = msi_translate;
@@ -3254,7 +3279,7 @@ out:
     return assigned_device;
 }
 
-static int unregister_real_device(int php_slot)
+static int unregister_real_device(int php_devfn)
 {
     struct php_dev *php_dev;
     struct pci_dev *pci_dev;
@@ -3264,10 +3289,10 @@ static int unregister_real_device(int ph
     uint32_t bdf = 0;
     int rc = -1;
 
-    if ( php_slot < 0 || php_slot >= PHP_SLOT_LEN )
+    if ( !PHP_DEVFN_IS_VALID(php_devfn) )
        return -1;
 
-    php_dev = &dpci_infos.php_devs[php_slot];
+    php_dev = &dpci_infos.php_devs[php_devfn];
     assigned_device = php_dev->pt_dev;
 
     if ( !assigned_device || !php_dev->valid )
@@ -3279,7 +3304,7 @@ static int unregister_real_device(int ph
     pci_hide_device((PCIDevice*)assigned_device);
 
     /* Unbind interrupt */
-    e_device = (assigned_device->dev.devfn >> 3) & 0x1f;
+    e_device = assigned_device->dev.devfn;
     /* fix virtual interrupt pin to INTA# */
     e_intx = 0;
     machine_irq = assigned_device->machine_irq;
@@ -3325,15 +3350,15 @@ static int unregister_real_device(int ph
     return 0;
 }
 
-int power_on_php_slot(int php_slot)
+int power_on_php_devfn(int php_devfn)
 {
-    struct php_dev *php_dev = &dpci_infos.php_devs[php_slot];
-    int pci_slot = php_slot + PHP_SLOT_START;
+    struct php_dev *php_dev = &dpci_infos.php_devs[php_devfn];
+    int pci_devfn = PHP_TO_PCI_DEVFN(php_devfn);
     struct pt_dev *pt_dev;
     pt_dev = 
         register_real_device(dpci_infos.e_bus,
             "DIRECT PCI",
-            PCI_DEVFN(pci_slot, 0),
+            pci_devfn,
             php_dev->r_bus,
             php_dev->r_dev,
             php_dev->r_func,
@@ -3349,14 +3374,14 @@ int power_on_php_slot(int php_slot)
 
 }
 
-int power_off_php_slot(int php_slot)
+int power_off_php_devfn(int php_devfn)
 {
-    return unregister_real_device(php_slot);
+    return unregister_real_device(php_devfn);
 }
 
 int pt_init(PCIBus *e_bus, const char *direct_pci)
 {
-    int seg, b, d, f, php_slot = 0, status = -1;
+    int seg, b, d, f, status = -1;
     struct pt_dev *pt_dev;
     struct pci_access *pci_access;
     char *vslots;
@@ -3403,17 +3428,8 @@ int pt_init(PCIBus *e_bus, const char *d
             goto err;
         }
 
-        /* Record the virtual slot info */
-        if ( php_slot < PHP_SLOT_LEN &&
-              dpci_infos.php_devs[php_slot].pt_dev == pt_dev )
-        {
-            sprintf(slot_str, "0x%x;", PHP_TO_PCI_SLOT(php_slot));
-        }
-        else
-            sprintf(slot_str, "0x%x;", 0);
-
+        sprintf(slot_str, "0x%x;", pt_dev->dev.devfn);
         strcat(vslots, slot_str);
-        php_slot++;
     }
 
     /* Write virtual slots info to xenstore for Control panel use */
Index: ioemu-remote/hw/pci.h
===================================================================
--- ioemu-remote.orig/hw/pci.h  2009-02-17 17:28:20.000000000 +0900
+++ ioemu-remote/hw/pci.h       2009-02-17 17:36:01.000000000 +0900
@@ -107,16 +107,19 @@ PCIBus *pci_bridge_init(PCIBus *bus, int
 #define PHP_SLOT_START  (6)
 #define PHP_SLOT_END    (8)
 #define PHP_SLOT_LEN    (PHP_SLOT_END - PHP_SLOT_START)
-#define PHP_TO_PCI_SLOT(x) (x + PHP_SLOT_START)
-#define PCI_TO_PHP_SLOT(x) (x - PHP_SLOT_START)
-#define PHP_DEVFN_START (PHP_SLOT_START << 3)
-#define PHP_DEVFN_END   (PHP_SLOT_END << 3)
-
-int insert_to_pci_slot(char*);
-int test_pci_slot(int);
-int bdf_to_slot(char*);
-int power_on_php_slot(int);
-int power_off_php_slot(int);
+#define PHP_DEVFN_START       (PHP_SLOT_START << 3)
+#define PHP_DEVFN_END         (PHP_SLOT_END << 3)
+#define PHP_DEVFN_LEN         (PHP_DEVFN_END - PHP_DEVFN_START)
+#define PCI_TO_PHP_DEVFN(x)   ((x) - PHP_DEVFN_START)
+#define PHP_TO_PCI_DEVFN(x)   ((x) + PHP_DEVFN_START)
+#define PCI_DEVFN_IS_PHP(x)   ((x) >= PHP_DEVFN_START && (x) < PHP_DEVFN_END)
+#define PHP_DEVFN_IS_VALID(x) (PCI_DEVFN_IS_PHP(PHP_TO_PCI_DEVFN(x)))
+
+int insert_bdf_to_php_devfn(char *bfd_slt);
+int test_php_devfn(int devfn);
+int bdf_to_php_devfn(char *bfd_str);
+int power_on_php_devfn(int php_devfn);
+int power_off_php_devfn(int php_devfn);
 
 /* pci_emulation.c */
 #include "hw/pci_emulation.h"
Index: ioemu-remote/hw/pc.h
===================================================================
--- ioemu-remote.orig/hw/pc.h   2009-02-17 17:28:18.000000000 +0900
+++ ioemu-remote/hw/pc.h        2009-02-17 17:36:01.000000000 +0900
@@ -96,8 +96,8 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int 
 void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
 void acpi_bios_init(void);
 
-void acpi_php_add(int);
-void acpi_php_del(int);
+void acpi_php_add(int devfn);
+void acpi_php_del(int devfn);
 
 /* pcspk.c */
 void pcspk_init(PITState *);
Index: ioemu-remote/vl.c
===================================================================
--- ioemu-remote.orig/vl.c      2009-02-17 17:28:06.000000000 +0900
+++ ioemu-remote/vl.c   2009-02-17 17:36:01.000000000 +0900
@@ -3900,19 +3900,19 @@ void qemu_chr_close(CharDriverState *chr
 #ifdef CONFIG_PASSTHROUGH
 void do_pci_del(char *devname)
 {
-    int pci_slot;
-    pci_slot = bdf_to_slot(devname);
+    int devfn;
+    devfn = bdf_to_php_devfn(devname);
 
-    acpi_php_del(pci_slot);
+    acpi_php_del(devfn);
 }
 
 void do_pci_add(char *devname)
 {
-    int pci_slot;
+    int devfn;
 
-    pci_slot = insert_to_pci_slot(devname);
+    devfn = insert_bdf_to_php_devfn(devname);
 
-    acpi_php_add(pci_slot);
+    acpi_php_add(devfn);
 }
 #endif
 

-- 

-- 
Simon Horman
  VA Linux Systems Japan K.K., Sydney, Australia Satellite Office
  H: www.vergenet.net/~horms/             W: www.valinux.co.jp/en


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.