mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-14 15:54:15 +08:00
Merge branches 'pci/enumeration', 'pci/hotplug', 'pci/misc', 'pci/numa' and 'pci/virtualization' into next
* pci/enumeration: PCI: Remove fixed parameter in pci_iov_resource_bar() PCI: Add informational printk for invalid BARs PCI: Shrink decoding-disabled window while sizing BARs PCI: Restore detection of read-only BARs * pci/hotplug: PCI: Remove unused and broken to_hotplug_slot() * pci/misc: PCI: Make FLR and AF FLR reset warning messages different PCI: Simplify if-return sequences PCI: Delete unnecessary NULL pointer checks * pci/numa: PCI: Allow numa_node override via sysfs * pci/virtualization: xen/pcifront: Process failure for pcifront_(re)scan_root()
This commit is contained in:
commit
18e88beceb
@ -281,3 +281,16 @@ Description:
|
||||
opt-out of driver binding using a driver_override name such as
|
||||
"none". Only a single driver may be specified in the override,
|
||||
there is no support for parsing delimiters.
|
||||
|
||||
What: /sys/bus/pci/devices/.../numa_node
|
||||
Date: Oct 2014
|
||||
Contact: Prarit Bhargava <prarit@redhat.com>
|
||||
Description:
|
||||
This file contains the NUMA node to which the PCI device is
|
||||
attached, or -1 if the node is unknown. The initial value
|
||||
comes from an ACPI _PXM method or a similar firmware
|
||||
source. If that is missing or incorrect, this file can be
|
||||
written to override the node. In that case, please report
|
||||
a firmware bug to the system vendor. Writing to this file
|
||||
taints the kernel with TAINT_FIRMWARE_WORKAROUND, which
|
||||
reduces the supportability of your system.
|
||||
|
@ -376,10 +376,7 @@ int __init ibmphp_rsrc_init (void)
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
rc = once_over (); /* This is to align ranges (so no -1) */
|
||||
if (rc)
|
||||
return rc;
|
||||
return 0;
|
||||
return once_over (); /* This is to align ranges (so no -1) */
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
|
@ -479,20 +479,16 @@ void pci_iov_release(struct pci_dev *dev)
|
||||
* pci_iov_resource_bar - get position of the SR-IOV BAR
|
||||
* @dev: the PCI device
|
||||
* @resno: the resource number
|
||||
* @type: the BAR type to be filled in
|
||||
*
|
||||
* Returns position of the BAR encapsulated in the SR-IOV capability.
|
||||
*/
|
||||
int pci_iov_resource_bar(struct pci_dev *dev, int resno,
|
||||
enum pci_bar_type *type)
|
||||
int pci_iov_resource_bar(struct pci_dev *dev, int resno)
|
||||
{
|
||||
if (resno < PCI_IOV_RESOURCES || resno > PCI_IOV_RESOURCE_END)
|
||||
return 0;
|
||||
|
||||
BUG_ON(!dev->is_physfn);
|
||||
|
||||
*type = pci_bar_unknown;
|
||||
|
||||
return dev->sriov->pos + PCI_SRIOV_BAR +
|
||||
4 * (resno - PCI_IOV_RESOURCES);
|
||||
}
|
||||
@ -510,13 +506,12 @@ int pci_iov_resource_bar(struct pci_dev *dev, int resno,
|
||||
resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno)
|
||||
{
|
||||
struct resource tmp;
|
||||
enum pci_bar_type type;
|
||||
int reg = pci_iov_resource_bar(dev, resno, &type);
|
||||
int reg = pci_iov_resource_bar(dev, resno);
|
||||
|
||||
if (!reg)
|
||||
return 0;
|
||||
|
||||
__pci_read_base(dev, type, &tmp, reg);
|
||||
__pci_read_base(dev, pci_bar_unknown, &tmp, reg);
|
||||
return resource_alignment(&tmp);
|
||||
}
|
||||
|
||||
|
@ -322,8 +322,7 @@ static void pci_acpi_wake_dev(struct work_struct *work)
|
||||
pci_wakeup_event(pci_dev);
|
||||
pm_runtime_resume(&pci_dev->dev);
|
||||
|
||||
if (pci_dev->subordinate)
|
||||
pci_pme_wakeup_bus(pci_dev->subordinate);
|
||||
pci_pme_wakeup_bus(pci_dev->subordinate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -221,12 +221,37 @@ static ssize_t enabled_show(struct device *dev, struct device_attribute *attr,
|
||||
static DEVICE_ATTR_RW(enabled);
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
static ssize_t numa_node_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int node, ret;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
ret = kstrtoint(buf, 0, &node);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!node_online(node))
|
||||
return -EINVAL;
|
||||
|
||||
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
|
||||
dev_alert(&pdev->dev, FW_BUG "Overriding NUMA node to %d. Contact your vendor for updates.",
|
||||
node);
|
||||
|
||||
dev->numa_node = node;
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t numa_node_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", dev->numa_node);
|
||||
}
|
||||
static DEVICE_ATTR_RO(numa_node);
|
||||
static DEVICE_ATTR_RW(numa_node);
|
||||
#endif
|
||||
|
||||
static ssize_t dma_mask_bits_show(struct device *dev,
|
||||
|
@ -1012,11 +1012,7 @@ int pci_save_state(struct pci_dev *dev)
|
||||
if (i != 0)
|
||||
return i;
|
||||
|
||||
i = pci_save_vc_state(dev);
|
||||
if (i != 0)
|
||||
return i;
|
||||
|
||||
return 0;
|
||||
return pci_save_vc_state(dev);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_save_state);
|
||||
|
||||
@ -3144,12 +3140,10 @@ static int pcie_flr(struct pci_dev *dev, int probe)
|
||||
return 0;
|
||||
|
||||
if (!pci_wait_for_pending_transaction(dev))
|
||||
dev_err(&dev->dev, "transaction is not cleared; proceeding with reset anyway\n");
|
||||
dev_err(&dev->dev, "timed out waiting for pending transaction; performing function level reset anyway\n");
|
||||
|
||||
pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
|
||||
|
||||
msleep(100);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3174,16 +3168,12 @@ static int pci_af_flr(struct pci_dev *dev, int probe)
|
||||
* is used, so we use the conrol offset rather than status and shift
|
||||
* the test bit to match.
|
||||
*/
|
||||
if (pci_wait_for_pending(dev, pos + PCI_AF_CTRL,
|
||||
if (!pci_wait_for_pending(dev, pos + PCI_AF_CTRL,
|
||||
PCI_AF_STATUS_TP << 8))
|
||||
goto clear;
|
||||
dev_err(&dev->dev, "timed out waiting for pending transaction; performing AF function level reset anyway\n");
|
||||
|
||||
dev_err(&dev->dev, "transaction is not cleared; proceeding with reset anyway\n");
|
||||
|
||||
clear:
|
||||
pci_write_config_byte(dev, pos + PCI_AF_CTRL, PCI_AF_CTRL_FLR);
|
||||
msleep(100);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4180,7 +4170,8 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
|
||||
return dev->rom_base_reg;
|
||||
} else if (resno < PCI_BRIDGE_RESOURCES) {
|
||||
/* device specific resource */
|
||||
reg = pci_iov_resource_bar(dev, resno, type);
|
||||
*type = pci_bar_unknown;
|
||||
reg = pci_iov_resource_bar(dev, resno);
|
||||
if (reg)
|
||||
return reg;
|
||||
}
|
||||
|
@ -251,8 +251,7 @@ static inline void pci_restore_ats_state(struct pci_dev *dev)
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
int pci_iov_init(struct pci_dev *dev);
|
||||
void pci_iov_release(struct pci_dev *dev);
|
||||
int pci_iov_resource_bar(struct pci_dev *dev, int resno,
|
||||
enum pci_bar_type *type);
|
||||
int pci_iov_resource_bar(struct pci_dev *dev, int resno);
|
||||
resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno);
|
||||
void pci_restore_iov_state(struct pci_dev *dev);
|
||||
int pci_iov_bus_range(struct pci_bus *bus);
|
||||
@ -266,8 +265,7 @@ static inline void pci_iov_release(struct pci_dev *dev)
|
||||
|
||||
{
|
||||
}
|
||||
static inline int pci_iov_resource_bar(struct pci_dev *dev, int resno,
|
||||
enum pci_bar_type *type)
|
||||
static inline int pci_iov_resource_bar(struct pci_dev *dev, int resno)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -87,8 +87,7 @@ static void release_pcibus_dev(struct device *dev)
|
||||
{
|
||||
struct pci_bus *pci_bus = to_pci_bus(dev);
|
||||
|
||||
if (pci_bus->bridge)
|
||||
put_device(pci_bus->bridge);
|
||||
put_device(pci_bus->bridge);
|
||||
pci_bus_remove_resources(pci_bus);
|
||||
pci_release_bus_of_node(pci_bus);
|
||||
kfree(pci_bus);
|
||||
@ -175,7 +174,6 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
|
||||
u64 l64, sz64, mask64;
|
||||
u16 orig_cmd;
|
||||
struct pci_bus_region region, inverted_region;
|
||||
bool bar_too_big = false, bar_too_high = false, bar_invalid = false;
|
||||
|
||||
mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
|
||||
|
||||
@ -201,8 +199,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
|
||||
* memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit
|
||||
* 1 must be clear.
|
||||
*/
|
||||
if (!sz || sz == 0xffffffff)
|
||||
goto fail;
|
||||
if (sz == 0xffffffff)
|
||||
sz = 0;
|
||||
|
||||
/*
|
||||
* I don't know how l can have all bits set. Copied from old code.
|
||||
@ -215,23 +213,22 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
|
||||
res->flags = decode_bar(dev, l);
|
||||
res->flags |= IORESOURCE_SIZEALIGN;
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
l &= PCI_BASE_ADDRESS_IO_MASK;
|
||||
mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT;
|
||||
l64 = l & PCI_BASE_ADDRESS_IO_MASK;
|
||||
sz64 = sz & PCI_BASE_ADDRESS_IO_MASK;
|
||||
mask64 = PCI_BASE_ADDRESS_IO_MASK & (u32)IO_SPACE_LIMIT;
|
||||
} else {
|
||||
l &= PCI_BASE_ADDRESS_MEM_MASK;
|
||||
mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
|
||||
l64 = l & PCI_BASE_ADDRESS_MEM_MASK;
|
||||
sz64 = sz & PCI_BASE_ADDRESS_MEM_MASK;
|
||||
mask64 = (u32)PCI_BASE_ADDRESS_MEM_MASK;
|
||||
}
|
||||
} else {
|
||||
res->flags |= (l & IORESOURCE_ROM_ENABLE);
|
||||
l &= PCI_ROM_ADDRESS_MASK;
|
||||
mask = (u32)PCI_ROM_ADDRESS_MASK;
|
||||
l64 = l & PCI_ROM_ADDRESS_MASK;
|
||||
sz64 = sz & PCI_ROM_ADDRESS_MASK;
|
||||
mask64 = (u32)PCI_ROM_ADDRESS_MASK;
|
||||
}
|
||||
|
||||
if (res->flags & IORESOURCE_MEM_64) {
|
||||
l64 = l;
|
||||
sz64 = sz;
|
||||
mask64 = mask | (u64)~0 << 32;
|
||||
|
||||
pci_read_config_dword(dev, pos + 4, &l);
|
||||
pci_write_config_dword(dev, pos + 4, ~0);
|
||||
pci_read_config_dword(dev, pos + 4, &sz);
|
||||
@ -239,18 +236,30 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
|
||||
|
||||
l64 |= ((u64)l << 32);
|
||||
sz64 |= ((u64)sz << 32);
|
||||
mask64 |= ((u64)~0 << 32);
|
||||
}
|
||||
|
||||
sz64 = pci_size(l64, sz64, mask64);
|
||||
if (!dev->mmio_always_on && (orig_cmd & PCI_COMMAND_DECODE_ENABLE))
|
||||
pci_write_config_word(dev, PCI_COMMAND, orig_cmd);
|
||||
|
||||
if (!sz64)
|
||||
goto fail;
|
||||
if (!sz64)
|
||||
goto fail;
|
||||
|
||||
sz64 = pci_size(l64, sz64, mask64);
|
||||
if (!sz64) {
|
||||
dev_info(&dev->dev, FW_BUG "reg 0x%x: invalid BAR (can't size)\n",
|
||||
pos);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (res->flags & IORESOURCE_MEM_64) {
|
||||
if ((sizeof(dma_addr_t) < 8 || sizeof(resource_size_t) < 8) &&
|
||||
sz64 > 0x100000000ULL) {
|
||||
res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
|
||||
res->start = 0;
|
||||
res->end = 0;
|
||||
bar_too_big = true;
|
||||
dev_err(&dev->dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n",
|
||||
pos, (unsigned long long)sz64);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -259,22 +268,15 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
|
||||
res->flags |= IORESOURCE_UNSET;
|
||||
res->start = 0;
|
||||
res->end = sz64;
|
||||
bar_too_high = true;
|
||||
dev_info(&dev->dev, "reg 0x%x: can't handle BAR above 4GB (bus address %#010llx)\n",
|
||||
pos, (unsigned long long)l64);
|
||||
goto out;
|
||||
} else {
|
||||
region.start = l64;
|
||||
region.end = l64 + sz64;
|
||||
}
|
||||
} else {
|
||||
sz = pci_size(l, sz, mask);
|
||||
|
||||
if (!sz)
|
||||
goto fail;
|
||||
|
||||
region.start = l;
|
||||
region.end = l + sz;
|
||||
}
|
||||
|
||||
region.start = l64;
|
||||
region.end = l64 + sz64;
|
||||
|
||||
pcibios_bus_to_resource(dev->bus, res, ®ion);
|
||||
pcibios_resource_to_bus(dev->bus, &inverted_region, res);
|
||||
|
||||
@ -293,7 +295,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
|
||||
res->flags |= IORESOURCE_UNSET;
|
||||
res->start = 0;
|
||||
res->end = region.end - region.start;
|
||||
bar_invalid = true;
|
||||
dev_info(&dev->dev, "reg 0x%x: initial BAR value %#010llx invalid\n",
|
||||
pos, (unsigned long long)region.start);
|
||||
}
|
||||
|
||||
goto out;
|
||||
@ -302,19 +305,6 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
|
||||
fail:
|
||||
res->flags = 0;
|
||||
out:
|
||||
if (!dev->mmio_always_on &&
|
||||
(orig_cmd & PCI_COMMAND_DECODE_ENABLE))
|
||||
pci_write_config_word(dev, PCI_COMMAND, orig_cmd);
|
||||
|
||||
if (bar_too_big)
|
||||
dev_err(&dev->dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n",
|
||||
pos, (unsigned long long) sz64);
|
||||
if (bar_too_high)
|
||||
dev_info(&dev->dev, "reg 0x%x: can't handle BAR above 4G (bus address %#010llx)\n",
|
||||
pos, (unsigned long long) l64);
|
||||
if (bar_invalid)
|
||||
dev_info(&dev->dev, "reg 0x%x: initial BAR value %#010llx invalid\n",
|
||||
pos, (unsigned long long) region.start);
|
||||
if (res->flags)
|
||||
dev_printk(KERN_DEBUG, &dev->dev, "reg 0x%x: %pR\n", pos, res);
|
||||
|
||||
|
@ -271,8 +271,7 @@ static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id,
|
||||
match_pci_dev_by_id);
|
||||
if (dev)
|
||||
pdev = to_pci_dev(dev);
|
||||
if (from)
|
||||
pci_dev_put(from);
|
||||
pci_dev_put(from);
|
||||
return pdev;
|
||||
}
|
||||
|
||||
|
@ -596,8 +596,7 @@ static pci_ers_result_t pcifront_common_process(int cmd,
|
||||
pcidev = pci_get_bus_and_slot(bus, devfn);
|
||||
if (!pcidev || !pcidev->driver) {
|
||||
dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n");
|
||||
if (pcidev)
|
||||
pci_dev_put(pcidev);
|
||||
pci_dev_put(pcidev);
|
||||
return result;
|
||||
}
|
||||
pdrv = pcidev->driver;
|
||||
@ -866,6 +865,11 @@ static int pcifront_try_connect(struct pcifront_device *pdev)
|
||||
xenbus_dev_error(pdev->xdev, err,
|
||||
"No PCI Roots found, trying 0000:00");
|
||||
err = pcifront_scan_root(pdev, 0, 0);
|
||||
if (err) {
|
||||
xenbus_dev_fatal(pdev->xdev, err,
|
||||
"Error scanning PCI root 0000:00");
|
||||
goto out;
|
||||
}
|
||||
num_roots = 0;
|
||||
} else if (err != 1) {
|
||||
if (err == 0)
|
||||
@ -947,6 +951,11 @@ static int pcifront_attach_devices(struct pcifront_device *pdev)
|
||||
xenbus_dev_error(pdev->xdev, err,
|
||||
"No PCI Roots found, trying 0000:00");
|
||||
err = pcifront_rescan_root(pdev, 0, 0);
|
||||
if (err) {
|
||||
xenbus_dev_fatal(pdev->xdev, err,
|
||||
"Error scanning PCI root 0000:00");
|
||||
goto out;
|
||||
}
|
||||
num_roots = 0;
|
||||
} else if (err != 1) {
|
||||
if (err == 0)
|
||||
|
@ -109,7 +109,6 @@ struct hotplug_slot {
|
||||
struct list_head slot_list;
|
||||
struct pci_slot *pci_slot;
|
||||
};
|
||||
#define to_hotplug_slot(n) container_of(n, struct hotplug_slot, kobj)
|
||||
|
||||
static inline const char *hotplug_slot_name(const struct hotplug_slot *slot)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user