Merge branch 'pci/misc' into next
* pci/misc: PCI: Fix return value from pci_user_{read,write}_config_*() PCI: Turn pcibios_penalize_isa_irq() into a weak function PCI: Test for std config alias when testing extended config space
This commit is contained in:
@@ -148,7 +148,7 @@ static noinline void pci_wait_cfg(struct pci_dev *dev)
|
||||
int pci_user_read_config_##size \
|
||||
(struct pci_dev *dev, int pos, type *val) \
|
||||
{ \
|
||||
int ret = 0; \
|
||||
int ret = PCIBIOS_SUCCESSFUL; \
|
||||
u32 data = -1; \
|
||||
if (PCI_##size##_BAD) \
|
||||
return -EINVAL; \
|
||||
@@ -159,9 +159,7 @@ int pci_user_read_config_##size \
|
||||
pos, sizeof(type), &data); \
|
||||
raw_spin_unlock_irq(&pci_lock); \
|
||||
*val = (type)data; \
|
||||
if (ret > 0) \
|
||||
ret = -EINVAL; \
|
||||
return ret; \
|
||||
return pcibios_err_to_errno(ret); \
|
||||
} \
|
||||
EXPORT_SYMBOL_GPL(pci_user_read_config_##size);
|
||||
|
||||
@@ -170,7 +168,7 @@ EXPORT_SYMBOL_GPL(pci_user_read_config_##size);
|
||||
int pci_user_write_config_##size \
|
||||
(struct pci_dev *dev, int pos, type val) \
|
||||
{ \
|
||||
int ret = -EIO; \
|
||||
int ret = PCIBIOS_SUCCESSFUL; \
|
||||
if (PCI_##size##_BAD) \
|
||||
return -EINVAL; \
|
||||
raw_spin_lock_irq(&pci_lock); \
|
||||
@@ -179,9 +177,7 @@ int pci_user_write_config_##size \
|
||||
ret = dev->bus->ops->write(dev->bus, dev->devfn, \
|
||||
pos, sizeof(type), val); \
|
||||
raw_spin_unlock_irq(&pci_lock); \
|
||||
if (ret > 0) \
|
||||
ret = -EINVAL; \
|
||||
return ret; \
|
||||
return pcibios_err_to_errno(ret); \
|
||||
} \
|
||||
EXPORT_SYMBOL_GPL(pci_user_write_config_##size);
|
||||
|
||||
|
@@ -1468,6 +1468,17 @@ void __weak pcibios_release_device(struct pci_dev *dev) {}
|
||||
*/
|
||||
void __weak pcibios_disable_device (struct pci_dev *dev) {}
|
||||
|
||||
/**
|
||||
* pcibios_penalize_isa_irq - penalize an ISA IRQ
|
||||
* @irq: ISA IRQ to penalize
|
||||
* @active: IRQ active or not
|
||||
*
|
||||
* Permits the platform to provide architecture-specific functionality when
|
||||
* penalizing ISA IRQs. This is the default implementation. Architecture
|
||||
* implementations can override this.
|
||||
*/
|
||||
void __weak pcibios_penalize_isa_irq(int irq, int active) {}
|
||||
|
||||
static void do_pci_disable_device(struct pci_dev *dev)
|
||||
{
|
||||
u16 pci_command;
|
||||
|
@@ -993,6 +993,43 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* pci_ext_cfg_is_aliased - is ext config space just an alias of std config?
|
||||
* @dev: PCI device
|
||||
*
|
||||
* PCI Express to PCI/PCI-X Bridge Specification, rev 1.0, 4.1.4 says that
|
||||
* when forwarding a type1 configuration request the bridge must check that
|
||||
* the extended register address field is zero. The bridge is not permitted
|
||||
* to forward the transactions and must handle it as an Unsupported Request.
|
||||
* Some bridges do not follow this rule and simply drop the extended register
|
||||
* bits, resulting in the standard config space being aliased, every 256
|
||||
* bytes across the entire configuration space. Test for this condition by
|
||||
* comparing the first dword of each potential alias to the vendor/device ID.
|
||||
* Known offenders:
|
||||
* ASM1083/1085 PCIe-to-PCI Reversible Bridge (1b21:1080, rev 01 & 03)
|
||||
* AMD/ATI SBx00 PCI to PCI Bridge (1002:4384, rev 40)
|
||||
*/
|
||||
static bool pci_ext_cfg_is_aliased(struct pci_dev *dev)
|
||||
{
|
||||
#ifdef CONFIG_PCI_QUIRKS
|
||||
int pos;
|
||||
u32 header, tmp;
|
||||
|
||||
pci_read_config_dword(dev, PCI_VENDOR_ID, &header);
|
||||
|
||||
for (pos = PCI_CFG_SPACE_SIZE;
|
||||
pos < PCI_CFG_SPACE_EXP_SIZE; pos += PCI_CFG_SPACE_SIZE) {
|
||||
if (pci_read_config_dword(dev, pos, &tmp) != PCIBIOS_SUCCESSFUL
|
||||
|| header != tmp)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_cfg_space_size - get the configuration space size of the PCI device.
|
||||
* @dev: PCI device
|
||||
@@ -1011,7 +1048,7 @@ static int pci_cfg_space_size_ext(struct pci_dev *dev)
|
||||
|
||||
if (pci_read_config_dword(dev, pos, &status) != PCIBIOS_SUCCESSFUL)
|
||||
goto fail;
|
||||
if (status == 0xffffffff)
|
||||
if (status == 0xffffffff || pci_ext_cfg_is_aliased(dev))
|
||||
goto fail;
|
||||
|
||||
return PCI_CFG_SPACE_EXP_SIZE;
|
||||
|
Reference in New Issue
Block a user