From f7ffe19a6fab14df70bd0acca9a4836aa80b15f5 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 4 Jan 2013 12:13:15 -0700 Subject: PCI: Use "unsigned long" for __pci_enable_device_flags to match ioport.h __pci_enable_device_flags() takes values like IORESOURCE_IO and IORESOURCE_MEM, which are values for struct resource.flags, which is "unsigned long", not "resource_size_t". Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/pci/pci.c') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 5cb5820fae40..d574fbdbf4b0 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1157,7 +1157,7 @@ int pci_reenable_device(struct pci_dev *dev) } static int __pci_enable_device_flags(struct pci_dev *dev, - resource_size_t flags) + unsigned long flags) { int err; int i, bars = 0; -- cgit v1.2.3 From b4b4fbba46a7a638878e58f303317e7904edfa13 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 4 Jan 2013 12:12:55 -0700 Subject: PCI: Drop "__" prefix on __pci_enable_device_flags() Drop the useless "__" prefix on __pci_enable_device_flags(). Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/pci/pci.c') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d574fbdbf4b0..a2f30394c091 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1156,8 +1156,7 @@ int pci_reenable_device(struct pci_dev *dev) return 0; } -static int __pci_enable_device_flags(struct pci_dev *dev, - unsigned long flags) +static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) { int err; int i, bars = 0; @@ -1201,7 +1200,7 @@ static int __pci_enable_device_flags(struct pci_dev *dev, */ int pci_enable_device_io(struct pci_dev *dev) { - return __pci_enable_device_flags(dev, IORESOURCE_IO); + return pci_enable_device_flags(dev, IORESOURCE_IO); } /** @@ -1214,7 +1213,7 @@ int pci_enable_device_io(struct pci_dev *dev) */ int pci_enable_device_mem(struct pci_dev *dev) { - return __pci_enable_device_flags(dev, IORESOURCE_MEM); + return pci_enable_device_flags(dev, IORESOURCE_MEM); } /** @@ -1230,7 +1229,7 @@ int pci_enable_device_mem(struct pci_dev *dev) */ int pci_enable_device(struct pci_dev *dev) { - return __pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO); + return pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO); } /* -- cgit v1.2.3 From b0cc6020e1cc62f1253215f189611b34be4a83c7 Mon Sep 17 00:00:00 2001 From: Yijing Wang Date: Tue, 15 Jan 2013 11:12:16 +0800 Subject: PCI: Enable ARI if dev and upstream bridge support it; disable otherwise Currently, we enable ARI in a device's upstream bridge if the bridge and the device support it. But we never disable ARI, even if the device is removed and replaced with a device that doesn't support ARI. This means that if we hot-remove an ARI device and replace it with a non-ARI multi-function device, we find only function 0 of the new device because the upstream bridge still has ARI enabled, and next_ari_fn() only returns function 0 for the new non-ARI device. This patch disables ARI in the upstream bridge if the device doesn't support ARI. See the PCIe spec, r3.0, sec 6.13. [bhelgaas: changelog, function comment] Signed-off-by: Yijing Wang Signed-off-by: Jiang Liu Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers/pci/pci.c') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 5cb5820fae40..8b47f70b7d8f 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2069,6 +2069,9 @@ void pci_free_cap_save_buffers(struct pci_dev *dev) /** * pci_enable_ari - enable ARI forwarding if hardware support it * @dev: the PCI device + * + * If @dev and its upstream bridge both support ARI, enable ARI in the + * bridge. Otherwise, disable ARI in the bridge. */ void pci_enable_ari(struct pci_dev *dev) { @@ -2078,9 +2081,6 @@ void pci_enable_ari(struct pci_dev *dev) if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn) return; - if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) - return; - bridge = dev->bus->self; if (!bridge) return; @@ -2089,8 +2089,15 @@ void pci_enable_ari(struct pci_dev *dev) if (!(cap & PCI_EXP_DEVCAP2_ARI)) return; - pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_ARI); - bridge->ari_enabled = 1; + if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) { + pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2, + PCI_EXP_DEVCTL2_ARI); + bridge->ari_enabled = 1; + } else { + pcie_capability_clear_word(bridge, PCI_EXP_DEVCTL2, + PCI_EXP_DEVCTL2_ARI); + bridge->ari_enabled = 0; + } } /** -- cgit v1.2.3 From 10c463a7a3b96285133c37e230781a1274abbd31 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 18 Mar 2012 22:46:26 -0700 Subject: PCI: Kill pci_is_reassigndev() pci_reassigndev_resource_alignment() is the only user of pci_is_reassigndev(). If we just use pci_specified_resource_alignment() directly, we only need to call it once instead of twice, and we can get rid of pci_is_reassigndev() altogether. No functional change. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'drivers/pci/pci.c') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index a2f30394c091..11c36654c95d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3765,18 +3765,6 @@ resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) return align; } -/** - * pci_is_reassigndev - check if specified PCI is target device to reassign - * @dev: the PCI device to check - * - * RETURNS: non-zero for PCI device is a target device to reassign, - * or zero is not. - */ -int pci_is_reassigndev(struct pci_dev *dev) -{ - return (pci_specified_resource_alignment(dev) != 0); -} - /* * This function disables memory decoding and releases memory resources * of the device specified by kernel's boot parameter 'pci=resource_alignment='. @@ -3791,7 +3779,9 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) resource_size_t align, size; u16 command; - if (!pci_is_reassigndev(dev)) + /* check if specified PCI is target device to reassign */ + align = pci_specified_resource_alignment(dev); + if (!align) return; if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL && @@ -3807,7 +3797,6 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) command &= ~PCI_COMMAND_MEMORY; pci_write_config_word(dev, PCI_COMMAND, command); - align = pci_specified_resource_alignment(dev); for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) { r = &dev->resource[i]; if (!(r->flags & IORESOURCE_MEM)) -- cgit v1.2.3 From 31ab247623c541d56b39a0b792cdfe4e94dd2a45 Mon Sep 17 00:00:00 2001 From: Yijing Wang Date: Tue, 15 Jan 2013 11:12:17 +0800 Subject: PCI: Rename pci_enable_ari() to pci_configure_ari() pci_enable_ari() now supports enabling or disabling ARI forwarding. So rename pci_enable_ari() to pci_configure_ari() for easy understanding. No functional change. [bhelgaas: changelog] Signed-off-by: Yijing Wang Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 4 ++-- drivers/pci/pci.h | 2 +- drivers/pci/probe.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/pci/pci.c') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 8b47f70b7d8f..66eefefbe0c5 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2067,13 +2067,13 @@ void pci_free_cap_save_buffers(struct pci_dev *dev) } /** - * pci_enable_ari - enable ARI forwarding if hardware support it + * pci_configure_ari - enable or disable ARI forwarding * @dev: the PCI device * * If @dev and its upstream bridge both support ARI, enable ARI in the * bridge. Otherwise, disable ARI in the bridge. */ -void pci_enable_ari(struct pci_dev *dev) +void pci_configure_ari(struct pci_dev *dev) { u32 cap; struct pci_dev *bridge; diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index e8518292826f..19043cbe097c 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -209,7 +209,7 @@ extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, extern int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type); extern int pci_bus_add_child(struct pci_bus *bus); -extern void pci_enable_ari(struct pci_dev *dev); +extern void pci_configure_ari(struct pci_dev *dev); /** * pci_ari_enabled - query ARI forwarding status * @bus: the PCI bus diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6186f03d84f3..7b9e691b95b1 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1286,7 +1286,7 @@ static void pci_init_capabilities(struct pci_dev *dev) pci_vpd_pci22_init(dev); /* Alternative Routing-ID Forwarding */ - pci_enable_ari(dev); + pci_configure_ari(dev); /* Single Root I/O Virtualization */ pci_iov_init(dev); -- cgit v1.2.3 From fd6dceab017e6be6c158dc56ec6dacf817f21a5b Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Mon, 4 Feb 2013 15:56:01 +0400 Subject: PCI: Catch attempts to disable already-disabled devices Warn when disabling a device that has already been disabled. [bhelgaas: message wording] Signed-off-by: Konstantin Khlebnikov Signed-off-by: Bjorn Helgaas Acked-by: Rafael J. Wysocki --- drivers/pci/pci.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/pci/pci.c') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 5cb5820fae40..29a09b705f04 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1401,6 +1401,9 @@ pci_disable_device(struct pci_dev *dev) if (dr) dr->enabled = 0; + dev_WARN_ONCE(&dev->dev, atomic_read(&dev->enable_cnt) <= 0, + "disabling already-disabled device"); + if (atomic_sub_return(1, &dev->enable_cnt) != 0) return; -- cgit v1.2.3 From cc7ba39bab126339d6d525ada07dea5633d71521 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Mon, 11 Feb 2013 16:47:01 -0700 Subject: PCI: Use atomic_inc_return() rather than atomic_add_return() No functional change; just use atomic_inc_return() rather than the general-purpose atomic_add_return(). Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/pci/pci.c') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 29a09b705f04..c746b04afd6a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1174,7 +1174,7 @@ static int __pci_enable_device_flags(struct pci_dev *dev, dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); } - if (atomic_add_return(1, &dev->enable_cnt) > 1) + if (atomic_inc_return(&dev->enable_cnt) > 1) return 0; /* already enabled */ /* only skip sriov related */ @@ -1404,7 +1404,7 @@ pci_disable_device(struct pci_dev *dev) dev_WARN_ONCE(&dev->dev, atomic_read(&dev->enable_cnt) <= 0, "disabling already-disabled device"); - if (atomic_sub_return(1, &dev->enable_cnt) != 0) + if (atomic_dec_return(&dev->enable_cnt) != 0) return; do_pci_disable_device(dev); -- cgit v1.2.3