Skip to content

Commit

Permalink
Merge branches 'pci/aspm', 'pci/hotplug', 'pci/misc' and 'pci/msi' in…
Browse files Browse the repository at this point in the history
…to 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
  • Loading branch information
Bjorn Helgaas committed Dec 11, 2015
5 parents 1ec2183 + 57d86a0 + 64609ea + 96ae646 + 128fc68 commit 800e07b
Show file tree
Hide file tree
Showing 16 changed files with 104 additions and 145 deletions.
2 changes: 1 addition & 1 deletion arch/powerpc/kernel/eeh_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/*
Expand Down
3 changes: 0 additions & 3 deletions arch/powerpc/kernel/pci_of_scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
10 changes: 5 additions & 5 deletions arch/x86/include/asm/pci_x86.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
108 changes: 38 additions & 70 deletions arch/x86/pci/pcbios.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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);
Expand All @@ -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))
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion drivers/pci/hotplug/ibmphp_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions drivers/pci/hotplug/pciehp_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 0 additions & 4 deletions drivers/pci/msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 9 additions & 9 deletions drivers/pci/pci-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -1424,10 +1424,10 @@ int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
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;
}
Expand Down Expand Up @@ -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);

Expand Down
2 changes: 0 additions & 2 deletions drivers/pci/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 5 additions & 5 deletions drivers/pci/pcie/aer/aerdrv_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 */
Expand Down
16 changes: 5 additions & 11 deletions drivers/pci/pcie/aspm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading

0 comments on commit 800e07b

Please sign in to comment.