WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

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

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [rfc 14/18] ioemu: use devfn instead of slots as the unit for passthrough
From: Simon Horman <horms@xxxxxxxxxxxx>
Date: Tue, 17 Feb 2009 20:08:02 +1100
Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Delivery-date: Tue, 17 Feb 2009 01:32:56 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20090217090748.580007796@xxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: quilt/0.46-1
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

<Prev in Thread] Current Thread [Next in Thread>