ia64/linux-2.6.18-xen.hg

changeset 812:44fd32e157f2

Backport: PCI: fix ARI code to be compatible with mixed ARI/non-ARI
systems

commit 8113587c2d14d3be2414190845b2e2617c0aa33b
Author: Zhao, Yu <yu.zhao@intel.com>
Date: Thu Oct 23 13:15:39 2008 +0800

PCI: fix ARI code to be compatible with mixed ARI/non-ARI systems

The original ARI support code has a compatibility problem with
non-ARI
devices. If a device doesn't support ARI, turning on ARI
forwarding on
its upper level bridge will cause undefined behavior.

This fix turns on ARI forwarding only when the subordinate devices
support it.

Tested-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Yu Zhao <yu.zhao@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>

Signed-off-by: Yu Zhao <yu.zhao@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Mar 13 07:41:23 2009 +0000 (2009-03-13)
parents 36d8c23b7574
children 955d92afcbce
files drivers/pci/pci.c
line diff
     1.1 --- a/drivers/pci/pci.c	Fri Mar 13 07:40:54 2009 +0000
     1.2 +++ b/drivers/pci/pci.c	Fri Mar 13 07:41:23 2009 +0000
     1.3 @@ -638,27 +638,32 @@ void pci_enable_ari(struct pci_dev *dev)
     1.4  	int pos;
     1.5  	u32 cap;
     1.6  	u16 ctrl;
     1.7 +	struct pci_dev *bridge;
     1.8  
     1.9 -	if (!dev->is_pcie)
    1.10 +	if (dev->devfn)
    1.11  		return;
    1.12  
    1.13 -	if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
    1.14 -	    dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
    1.15 -		return;
    1.16 -
    1.17 -	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
    1.18 +	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI);
    1.19  	if (!pos)
    1.20  		return;
    1.21  
    1.22 -	pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap);
    1.23 +	bridge = dev->bus->self;
    1.24 +	if (!bridge)
    1.25 +		return;
    1.26 +
    1.27 +	pos = pci_find_capability(bridge, PCI_CAP_ID_EXP);
    1.28 +	if (!pos)
    1.29 +		return;
    1.30 +
    1.31 +	pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap);
    1.32  	if (!(cap & PCI_EXP_DEVCAP2_ARI))
    1.33  		return;
    1.34  
    1.35 -	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
    1.36 +	pci_read_config_word(bridge, pos + PCI_EXP_DEVCTL2, &ctrl);
    1.37  	ctrl |= PCI_EXP_DEVCTL2_ARI;
    1.38 -	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
    1.39 +	pci_write_config_word(bridge, pos + PCI_EXP_DEVCTL2, ctrl);
    1.40  
    1.41 -	dev->ari_enabled = 1;
    1.42 +	bridge->ari_enabled = 1;
    1.43  }
    1.44  
    1.45  int