vt-d: Remove the FLR logic in Xen.
authorKeir Fraser <keir.fraser@citrix.com>
Mon, 14 Jul 2008 09:10:14 +0000 (10:10 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Mon, 14 Jul 2008 09:10:14 +0000 (10:10 +0100)
The current simple logic has some issues: 1) Dstate transition is not
guaranteed to properly clear the device state; 2) the current code for
PCIe FLR is actually buggy: PCI_EXP_DEVSTA_TRPND doesn't mean the
completion of FLR; according to the PCIe spec, after issuing FLR, we
should wait at least 100ms.

The improved FLR logic will be added into xend.

Signed-off-by: Dexuan Cui <dexuan.cui@intel.com>
xen/drivers/passthrough/amd/pci_amd_iommu.c
xen/drivers/passthrough/pci.c
xen/drivers/passthrough/vtd/iommu.c
xen/include/xen/pci.h

index 31f485086c0fc8256b414065129cbc1a5965d253..cd3ea8e5fc99cb4866d3b9d7cbe987a224423937 100644 (file)
@@ -507,7 +507,6 @@ static int reassign_device( struct domain *source, struct domain *target,
     if ( !pdev )
        return -ENODEV;
 
-    pdev_flr(pdev);
     bdf = (bus << 8) | devfn;
     /* supported device? */
     iommu = (bdf < ivrs_bdf_entries) ?
index 2faba151fbbad96a965e50aa21c2024dff153bea..6309495f477e279600ce0a795e0fdf81e6ef6fba 100644 (file)
@@ -161,71 +161,6 @@ void pci_release_devices(struct domain *d)
     }
 }
 
-#define PCI_D3hot              (3)
-#define PCI_CONFIG_DWORD_SIZE   (64)
-#define PCI_EXP_DEVCAP_FLR      (1 << 28)
-#define PCI_EXP_DEVCTL_FLR      (1 << 15)
-
-void pdev_flr(struct pci_dev *pdev)
-{
-    u8 pos;
-    u32 dev_cap, dev_status, pm_ctl;
-    int flr = 0;
-    u8 dev = PCI_SLOT(pdev->devfn);
-    u8 func = PCI_FUNC(pdev->devfn);
-
-    pos = pci_find_cap_offset(pdev->bus, dev, func, PCI_CAP_ID_EXP);
-    if ( pos != 0 )
-    {
-        dev_cap = pci_conf_read32(pdev->bus, dev, func, pos + PCI_EXP_DEVCAP);
-        if ( dev_cap & PCI_EXP_DEVCAP_FLR )
-        {
-            pci_conf_write32(pdev->bus, dev, func,
-                             pos + PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_FLR);
-            do {
-                dev_status = pci_conf_read32(pdev->bus, dev, func,
-                                             pos + PCI_EXP_DEVSTA);
-            } while ( dev_status & PCI_EXP_DEVSTA_TRPND );
-
-            flr = 1;
-        }
-    }
-
-    /* If this device doesn't support function level reset,
-     * program device from D0 t0 D3hot, and then return to D0
-     * to implement function level reset
-     */
-    if ( flr == 0 )
-    {
-        pos = pci_find_cap_offset(pdev->bus, dev, func, PCI_CAP_ID_PM);
-        if ( pos != 0 )
-        {
-            int i;
-            u32 config[PCI_CONFIG_DWORD_SIZE];
-            for ( i = 0; i < PCI_CONFIG_DWORD_SIZE; i++ )
-                config[i] = pci_conf_read32(pdev->bus, dev, func, i*4);
-
-            /* Enter D3hot without soft reset */
-            pm_ctl = pci_conf_read32(pdev->bus, dev, func, pos + PCI_PM_CTRL);
-            pm_ctl |= PCI_PM_CTRL_NO_SOFT_RESET;
-            pm_ctl &= ~PCI_PM_CTRL_STATE_MASK;
-            pm_ctl |= PCI_D3hot;
-            pci_conf_write32(pdev->bus, dev, func, pos + PCI_PM_CTRL, pm_ctl);
-            mdelay(10);
-
-            /* From D3hot to D0 */
-            pci_conf_write32(pdev->bus, dev, func, pos + PCI_PM_CTRL, 0);
-            mdelay(10);
-
-            /* Write saved configurations to device */
-            for ( i = 0; i < PCI_CONFIG_DWORD_SIZE; i++ )
-                pci_conf_write32(pdev->bus, dev, func, i*4, config[i]);
-
-            flr = 1;
-        }
-    }
-}
-
 static void dump_pci_devices(unsigned char ch)
 {
     struct pci_dev *pdev;
index 67126140a12626c839cd9776307e4ac84ff9ed9b..94b24f38456be491e9f94af7b1a22c9f29764a68 100644 (file)
@@ -1382,7 +1382,6 @@ static int reassign_device_ownership(
     if ( !(pdev = pci_lock_domain_pdev(source, bus, devfn)) )
         return -ENODEV;
 
-    pdev_flr(pdev);
     drhd = acpi_find_matched_drhd_unit(bus, devfn);
     pdev_iommu = drhd->iommu;
     domain_context_unmap(bus, devfn);
index 22bcae986cbb35fe2c1887a18a05f3ba8ea5f8de..bfc7354e8eec6be11257f0ae0d1abd97b6274ec9 100644 (file)
@@ -56,7 +56,6 @@ void free_pdev(struct pci_dev *pdev);
 struct pci_dev *pci_lock_pdev(int bus, int devfn);
 struct pci_dev *pci_lock_domain_pdev(struct domain *d, int bus, int devfn);
 
-void pdev_flr(struct pci_dev *pdev);
 void pci_release_devices(struct domain *d);
 int pci_add_device(u8 bus, u8 devfn);
 int pci_remove_device(u8 bus, u8 devfn);