Merge branches 'pci/aspm', 'pci/hotplug', 'pci/misc' and 'pci/msi' into next

* pci/aspm:
  PCI/ASPM: Make sysfs link_state_store() consistent with link_state_show()

* pci/hotplug:
  PCI: pciehp: Always protect pciehp_disable_slot() with hotplug mutex

* pci/misc:
  x86/PCI: Simplify pci_bios_{read,write}
  PCI: Simplify config space size computation
  PCI: Limit config space size for Netronome NFP6000 family
  PCI: Add Netronome vendor and device IDs
  PCI: Support PCIe devices with short cfg_size
  x86/PCI: Clarify AMD Fam10h config access restrictions comment
  PCI: Print warnings for all invalid expansion ROM headers
  PCI: Check for PCI_HEADER_TYPE_BRIDGE equality, not bitmask

* pci/msi:
  PCI/MSI: Remove empty pci_msi_init_pci_dev()
  PCI/MSI: Initialize MSI capability for all architectures
This commit is contained in:
Bjorn Helgaas 2015-12-10 19:40:14 -06:00
16 changed files with 104 additions and 145 deletions

View File

@ -400,7 +400,7 @@ static void *eeh_rmv_device(void *data, void *userdata)
* support EEH. So we just care about PCI devices for
* simplicity here.
*/
if (!dev || (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE))
if (!dev || (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE))
return NULL;
/*

View File

@ -187,9 +187,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
pci_device_add(dev, bus);
/* Setup MSI caps & disable MSI/MSI-X interrupts */
pci_msi_setup_pci_dev(dev);
return dev;
}
EXPORT_SYMBOL(of_create_pci_dev);

View File

@ -151,11 +151,11 @@ extern struct list_head pci_mmcfg_list;
#define PCI_MMCFG_BUS_OFFSET(bus) ((bus) << 20)
/*
* AMD Fam10h CPUs are buggy, and cannot access MMIO config space
* on their northbrige except through the * %eax register. As such, you MUST
* NOT use normal IOMEM accesses, you need to only use the magic mmio-config
* accessor functions.
* In fact just use pci_config_*, nothing else please.
* On AMD Fam10h CPUs, all PCI MMIO configuration space accesses must use
* %eax. No other source or target registers may be used. The following
* mmio_config_* accessors enforce this. See "BIOS and Kernel Developer's
* Guide (BKDG) For AMD Family 10h Processors", rev. 3.48, sec 2.11.1,
* "MMIO Configuration Coding Requirements".
*/
static inline unsigned char mmio_config_readb(void __iomem *pos)
{

View File

@ -180,6 +180,7 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
unsigned long result = 0;
unsigned long flags;
unsigned long bx = (bus << 8) | devfn;
u16 number = 0, mask = 0;
WARN_ON(seg);
if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
@ -189,53 +190,35 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
switch (len) {
case 1:
__asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
: "=c" (*value),
"=a" (result)
: "1" (PCIBIOS_READ_CONFIG_BYTE),
"b" (bx),
"D" ((long)reg),
"S" (&pci_indirect));
/*
* Zero-extend the result beyond 8 bits, do not trust the
* BIOS having done it:
*/
*value &= 0xff;
number = PCIBIOS_READ_CONFIG_BYTE;
mask = 0xff;
break;
case 2:
__asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
: "=c" (*value),
"=a" (result)
: "1" (PCIBIOS_READ_CONFIG_WORD),
"b" (bx),
"D" ((long)reg),
"S" (&pci_indirect));
/*
* Zero-extend the result beyond 16 bits, do not trust the
* BIOS having done it:
*/
*value &= 0xffff;
number = PCIBIOS_READ_CONFIG_WORD;
mask = 0xffff;
break;
case 4:
__asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
: "=c" (*value),
"=a" (result)
: "1" (PCIBIOS_READ_CONFIG_DWORD),
"b" (bx),
"D" ((long)reg),
"S" (&pci_indirect));
number = PCIBIOS_READ_CONFIG_DWORD;
break;
}
__asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
: "=c" (*value),
"=a" (result)
: "1" (number),
"b" (bx),
"D" ((long)reg),
"S" (&pci_indirect));
/*
* Zero-extend the result beyond 8 or 16 bits, do not trust the
* BIOS having done it:
*/
if (mask)
*value &= mask;
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
return (int)((result & 0xff00) >> 8);
@ -247,6 +230,7 @@ static int pci_bios_write(unsigned int seg, unsigned int bus,
unsigned long result = 0;
unsigned long flags;
unsigned long bx = (bus << 8) | devfn;
u16 number = 0;
WARN_ON(seg);
if ((bus > 255) || (devfn > 255) || (reg > 255))
@ -256,43 +240,27 @@ static int pci_bios_write(unsigned int seg, unsigned int bus,
switch (len) {
case 1:
__asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
: "=a" (result)
: "0" (PCIBIOS_WRITE_CONFIG_BYTE),
"c" (value),
"b" (bx),
"D" ((long)reg),
"S" (&pci_indirect));
number = PCIBIOS_WRITE_CONFIG_BYTE;
break;
case 2:
__asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
: "=a" (result)
: "0" (PCIBIOS_WRITE_CONFIG_WORD),
"c" (value),
"b" (bx),
"D" ((long)reg),
"S" (&pci_indirect));
number = PCIBIOS_WRITE_CONFIG_WORD;
break;
case 4:
__asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
: "=a" (result)
: "0" (PCIBIOS_WRITE_CONFIG_DWORD),
"c" (value),
"b" (bx),
"D" ((long)reg),
"S" (&pci_indirect));
number = PCIBIOS_WRITE_CONFIG_DWORD;
break;
}
__asm__("lcall *(%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
: "=a" (result)
: "0" (number),
"c" (value),
"b" (bx),
"D" ((long)reg),
"S" (&pci_indirect));
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
return (int)((result & 0xff00) >> 8);

View File

@ -1119,7 +1119,7 @@ static struct res_needed *scan_behind_bridge (struct pci_func *func, u8 busno)
pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
debug ("hdr_type behind the bridge is %x\n", hdr_type);
if (hdr_type & PCI_HEADER_TYPE_BRIDGE) {
if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
err ("embedded bridges not supported for hot-plugging.\n");
amount->not_correct = 1;
return amount;

View File

@ -511,7 +511,9 @@ int pciehp_sysfs_disable_slot(struct slot *p_slot)
case STATIC_STATE:
p_slot->state = POWEROFF_STATE;
mutex_unlock(&p_slot->lock);
mutex_lock(&p_slot->hotplug_lock);
retval = pciehp_disable_slot(p_slot);
mutex_unlock(&p_slot->hotplug_lock);
mutex_lock(&p_slot->lock);
p_slot->state = STATIC_STATE;
break;

View File

@ -1024,10 +1024,6 @@ int pci_msi_enabled(void)
}
EXPORT_SYMBOL(pci_msi_enabled);
void pci_msi_init_pci_dev(struct pci_dev *dev)
{
}
/**
* pci_enable_msi_range - configure device's MSI capability structure
* @dev: device to configure

View File

@ -1369,10 +1369,10 @@ int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
if (!sysfs_initialized)
return -EACCES;
if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
else
if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
retval = sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
else
retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
if (retval)
goto err;
@ -1424,10 +1424,10 @@ err_rom_file:
err_resource_files:
pci_remove_resource_files(pdev);
err_config_file:
if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
else
if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
else
sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
err:
return retval;
}
@ -1461,10 +1461,10 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
pci_remove_capabilities_sysfs(pdev);
if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
else
if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
else
sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
pci_remove_resource_files(pdev);

View File

@ -144,10 +144,8 @@ extern unsigned int pci_pm_d3_delay;
#ifdef CONFIG_PCI_MSI
void pci_no_msi(void);
void pci_msi_init_pci_dev(struct pci_dev *dev);
#else
static inline void pci_no_msi(void) { }
static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { }
#endif
static inline void pci_msi_set_enable(struct pci_dev *dev, int enable)

View File

@ -246,7 +246,7 @@ static int report_error_detected(struct pci_dev *dev, void *data)
!dev->driver->err_handler ||
!dev->driver->err_handler->error_detected) {
if (result_data->state == pci_channel_io_frozen &&
!(dev->hdr_type & PCI_HEADER_TYPE_BRIDGE)) {
dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
/*
* In case of fatal recovery, if one of down-
* stream device has no driver. We might be
@ -269,7 +269,7 @@ static int report_error_detected(struct pci_dev *dev, void *data)
* without recovery.
*/
if (!(dev->hdr_type & PCI_HEADER_TYPE_BRIDGE))
if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE)
vote = PCI_ERS_RESULT_NO_AER_DRIVER;
else
vote = PCI_ERS_RESULT_NONE;
@ -369,7 +369,7 @@ static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
else
result_data.result = PCI_ERS_RESULT_RECOVERED;
if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) {
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
/*
* If the error is reported by a bridge, we think this error
* is related to the downstream link of the bridge, so we
@ -440,7 +440,7 @@ static pci_ers_result_t reset_link(struct pci_dev *dev)
pci_ers_result_t status;
struct pcie_port_service_driver *driver;
if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) {
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
/* Reset this port for all subordinates */
udev = dev;
} else {
@ -660,7 +660,7 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
&info->mask);
if (!(info->status & ~info->mask))
return 0;
} else if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE ||
} else if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
info->severity == AER_NONFATAL) {
/* Link is still healthy for IO reads */

View File

@ -834,21 +834,15 @@ static ssize_t link_state_store(struct device *dev,
{
struct pci_dev *pdev = to_pci_dev(dev);
struct pcie_link_state *link, *root = pdev->link_state->root;
u32 val, state = 0;
if (kstrtouint(buf, 10, &val))
return -EINVAL;
u32 state;
if (aspm_disabled)
return -EPERM;
if (n < 1 || val > 3)
return -EINVAL;
/* Convert requested state to ASPM state */
if (val & PCIE_LINK_STATE_L0S)
state |= ASPM_STATE_L0S;
if (val & PCIE_LINK_STATE_L1)
state |= ASPM_STATE_L1;
if (kstrtouint(buf, 10, &state))
return -EINVAL;
if ((state & ~ASPM_STATE_ALL) != 0)
return -EINVAL;
down_read(&pci_bus_sem);
mutex_lock(&aspm_lock);

View File

@ -1107,14 +1107,11 @@ static int pci_cfg_space_size_ext(struct pci_dev *dev)
int pos = PCI_CFG_SPACE_SIZE;
if (pci_read_config_dword(dev, pos, &status) != PCIBIOS_SUCCESSFUL)
goto fail;
return PCI_CFG_SPACE_SIZE;
if (status == 0xffffffff || pci_ext_cfg_is_aliased(dev))
goto fail;
return PCI_CFG_SPACE_SIZE;
return PCI_CFG_SPACE_EXP_SIZE;
fail:
return PCI_CFG_SPACE_SIZE;
}
int pci_cfg_space_size(struct pci_dev *dev)
@ -1127,25 +1124,23 @@ int pci_cfg_space_size(struct pci_dev *dev)
if (class == PCI_CLASS_BRIDGE_HOST)
return pci_cfg_space_size_ext(dev);
if (!pci_is_pcie(dev)) {
pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
if (!pos)
goto fail;
if (pci_is_pcie(dev))
return pci_cfg_space_size_ext(dev);
pci_read_config_dword(dev, pos + PCI_X_STATUS, &status);
if (!(status & (PCI_X_STATUS_266MHZ | PCI_X_STATUS_533MHZ)))
goto fail;
}
pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
if (!pos)
return PCI_CFG_SPACE_SIZE;
return pci_cfg_space_size_ext(dev);
pci_read_config_dword(dev, pos + PCI_X_STATUS, &status);
if (status & (PCI_X_STATUS_266MHZ | PCI_X_STATUS_533MHZ))
return pci_cfg_space_size_ext(dev);
fail:
return PCI_CFG_SPACE_SIZE;
}
#define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
void pci_msi_setup_pci_dev(struct pci_dev *dev)
static void pci_msi_setup_pci_dev(struct pci_dev *dev)
{
/*
* Disable the MSI hardware to avoid screaming interrupts
@ -1212,8 +1207,6 @@ int pci_setup_device(struct pci_dev *dev)
/* "Unknown power state" */
dev->current_state = PCI_UNKNOWN;
pci_msi_setup_pci_dev(dev);
/* Early fixups, before probing the BARs */
pci_fixup_device(pci_fixup_early, dev);
/* device class may be changed after fixup */
@ -1603,8 +1596,8 @@ static void pci_init_capabilities(struct pci_dev *dev)
/* Enhanced Allocation */
pci_ea_init(dev);
/* MSI/MSI-X list */
pci_msi_init_pci_dev(dev);
/* Setup MSI caps & disable MSI/MSI-X interrupts */
pci_msi_setup_pci_dev(dev);
/* Buffers for saving PCIe and PCI-X capabilities */
pci_allocate_cap_save_buffers(dev);

View File

@ -287,6 +287,17 @@ static void quirk_citrine(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, quirk_citrine);
/*
* This chip can cause bus lockups if config addresses above 0x600
* are read or written.
*/
static void quirk_nfp6000(struct pci_dev *dev)
{
dev->cfg_size = 0x600;
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_NFP6000, quirk_nfp6000);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETRONOME, PCI_DEVICE_ID_NETRONOME_NFP6000_VF, quirk_nfp6000);
/* On IBM Crocodile ipr SAS adapters, expand BAR to system page size */
static void quirk_extend_bar_to_page(struct pci_dev *dev)
{

View File

@ -77,22 +77,18 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
do {
void __iomem *pds;
/* Standard PCI ROMs start out with these bytes 55 AA */
if (readb(image) != 0x55) {
dev_err(&pdev->dev, "Invalid ROM contents\n");
if (readw(image) != 0xAA55) {
dev_err(&pdev->dev, "Invalid PCI ROM header signature: expecting 0xaa55, got %#06x\n",
readw(image));
break;
}
if (readb(image + 1) != 0xAA)
break;
/* get the PCI data structure and check its signature */
/* get the PCI data structure and check its "PCIR" signature */
pds = image + readw(image + 24);
if (readb(pds) != 'P')
break;
if (readb(pds + 1) != 'C')
break;
if (readb(pds + 2) != 'I')
break;
if (readb(pds + 3) != 'R')
if (readl(pds) != 0x52494350) {
dev_err(&pdev->dev, "Invalid PCI ROM data signature: expecting 0x52494350, got %#010x\n",
readl(pds));
break;
}
last_image = readb(pds + 21) & 0x80;
length = readw(pds + 16);
image += length * 512;

View File

@ -1248,8 +1248,6 @@ struct msix_entry {
u16 entry; /* driver uses to specify entry, OS writes */
};
void pci_msi_setup_pci_dev(struct pci_dev *dev);
#ifdef CONFIG_PCI_MSI
int pci_msi_vec_count(struct pci_dev *dev);
void pci_msi_shutdown(struct pci_dev *dev);

View File

@ -2495,6 +2495,12 @@
#define PCI_DEVICE_ID_KORENIX_JETCARDF2 0x1700
#define PCI_DEVICE_ID_KORENIX_JETCARDF3 0x17ff
#define PCI_VENDOR_ID_NETRONOME 0x19ee
#define PCI_DEVICE_ID_NETRONOME_NFP3200 0x3200
#define PCI_DEVICE_ID_NETRONOME_NFP3240 0x3240
#define PCI_DEVICE_ID_NETRONOME_NFP6000 0x6000
#define PCI_DEVICE_ID_NETRONOME_NFP6000_VF 0x6003
#define PCI_VENDOR_ID_QMI 0x1a32
#define PCI_VENDOR_ID_AZWAVE 0x1a3b