ia64/xen-unstable

changeset 18048:caba894b265f

vt-d: Remove the FLR logic in Xen.

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>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Jul 14 10:10:14 2008 +0100 (2008-07-14)
parents 2463e2ef602f
children e61978c24d84
files xen/drivers/passthrough/amd/pci_amd_iommu.c xen/drivers/passthrough/pci.c xen/drivers/passthrough/vtd/iommu.c xen/include/xen/pci.h
line diff
     1.1 --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c	Mon Jul 14 10:09:25 2008 +0100
     1.2 +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c	Mon Jul 14 10:10:14 2008 +0100
     1.3 @@ -507,7 +507,6 @@ static int reassign_device( struct domai
     1.4      if ( !pdev )
     1.5  	return -ENODEV;
     1.6  
     1.7 -    pdev_flr(pdev);
     1.8      bdf = (bus << 8) | devfn;
     1.9      /* supported device? */
    1.10      iommu = (bdf < ivrs_bdf_entries) ?
     2.1 --- a/xen/drivers/passthrough/pci.c	Mon Jul 14 10:09:25 2008 +0100
     2.2 +++ b/xen/drivers/passthrough/pci.c	Mon Jul 14 10:10:14 2008 +0100
     2.3 @@ -161,71 +161,6 @@ void pci_release_devices(struct domain *
     2.4      }
     2.5  }
     2.6  
     2.7 -#define PCI_D3hot	        (3)
     2.8 -#define PCI_CONFIG_DWORD_SIZE   (64)
     2.9 -#define PCI_EXP_DEVCAP_FLR      (1 << 28)
    2.10 -#define PCI_EXP_DEVCTL_FLR      (1 << 15)
    2.11 -
    2.12 -void pdev_flr(struct pci_dev *pdev)
    2.13 -{
    2.14 -    u8 pos;
    2.15 -    u32 dev_cap, dev_status, pm_ctl;
    2.16 -    int flr = 0;
    2.17 -    u8 dev = PCI_SLOT(pdev->devfn);
    2.18 -    u8 func = PCI_FUNC(pdev->devfn);
    2.19 -
    2.20 -    pos = pci_find_cap_offset(pdev->bus, dev, func, PCI_CAP_ID_EXP);
    2.21 -    if ( pos != 0 )
    2.22 -    {
    2.23 -        dev_cap = pci_conf_read32(pdev->bus, dev, func, pos + PCI_EXP_DEVCAP);
    2.24 -        if ( dev_cap & PCI_EXP_DEVCAP_FLR )
    2.25 -        {
    2.26 -            pci_conf_write32(pdev->bus, dev, func,
    2.27 -                             pos + PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_FLR);
    2.28 -            do {
    2.29 -                dev_status = pci_conf_read32(pdev->bus, dev, func,
    2.30 -                                             pos + PCI_EXP_DEVSTA);
    2.31 -            } while ( dev_status & PCI_EXP_DEVSTA_TRPND );
    2.32 -
    2.33 -            flr = 1;
    2.34 -        }
    2.35 -    }
    2.36 -
    2.37 -    /* If this device doesn't support function level reset,
    2.38 -     * program device from D0 t0 D3hot, and then return to D0
    2.39 -     * to implement function level reset
    2.40 -     */
    2.41 -    if ( flr == 0 )
    2.42 -    {
    2.43 -        pos = pci_find_cap_offset(pdev->bus, dev, func, PCI_CAP_ID_PM);
    2.44 -        if ( pos != 0 )
    2.45 -        {
    2.46 -            int i;
    2.47 -            u32 config[PCI_CONFIG_DWORD_SIZE];
    2.48 -            for ( i = 0; i < PCI_CONFIG_DWORD_SIZE; i++ )
    2.49 -                config[i] = pci_conf_read32(pdev->bus, dev, func, i*4);
    2.50 -
    2.51 -            /* Enter D3hot without soft reset */
    2.52 -            pm_ctl = pci_conf_read32(pdev->bus, dev, func, pos + PCI_PM_CTRL);
    2.53 -            pm_ctl |= PCI_PM_CTRL_NO_SOFT_RESET;
    2.54 -            pm_ctl &= ~PCI_PM_CTRL_STATE_MASK;
    2.55 -            pm_ctl |= PCI_D3hot;
    2.56 -            pci_conf_write32(pdev->bus, dev, func, pos + PCI_PM_CTRL, pm_ctl);
    2.57 -            mdelay(10);
    2.58 -
    2.59 -            /* From D3hot to D0 */
    2.60 -            pci_conf_write32(pdev->bus, dev, func, pos + PCI_PM_CTRL, 0);
    2.61 -            mdelay(10);
    2.62 -
    2.63 -            /* Write saved configurations to device */
    2.64 -            for ( i = 0; i < PCI_CONFIG_DWORD_SIZE; i++ )
    2.65 -                pci_conf_write32(pdev->bus, dev, func, i*4, config[i]);
    2.66 -
    2.67 -            flr = 1;
    2.68 -        }
    2.69 -    }
    2.70 -}
    2.71 -
    2.72  static void dump_pci_devices(unsigned char ch)
    2.73  {
    2.74      struct pci_dev *pdev;
     3.1 --- a/xen/drivers/passthrough/vtd/iommu.c	Mon Jul 14 10:09:25 2008 +0100
     3.2 +++ b/xen/drivers/passthrough/vtd/iommu.c	Mon Jul 14 10:10:14 2008 +0100
     3.3 @@ -1382,7 +1382,6 @@ static int reassign_device_ownership(
     3.4      if ( !(pdev = pci_lock_domain_pdev(source, bus, devfn)) )
     3.5          return -ENODEV;
     3.6  
     3.7 -    pdev_flr(pdev);
     3.8      drhd = acpi_find_matched_drhd_unit(bus, devfn);
     3.9      pdev_iommu = drhd->iommu;
    3.10      domain_context_unmap(bus, devfn);
     4.1 --- a/xen/include/xen/pci.h	Mon Jul 14 10:09:25 2008 +0100
     4.2 +++ b/xen/include/xen/pci.h	Mon Jul 14 10:10:14 2008 +0100
     4.3 @@ -56,7 +56,6 @@ void free_pdev(struct pci_dev *pdev);
     4.4  struct pci_dev *pci_lock_pdev(int bus, int devfn);
     4.5  struct pci_dev *pci_lock_domain_pdev(struct domain *d, int bus, int devfn);
     4.6  
     4.7 -void pdev_flr(struct pci_dev *pdev);
     4.8  void pci_release_devices(struct domain *d);
     4.9  int pci_add_device(u8 bus, u8 devfn);
    4.10  int pci_remove_device(u8 bus, u8 devfn);