From f1c66c4678ad223bda0dcd261e4048f009234f85 Mon Sep 17 00:00:00 2001 From: Yijing Wang Date: Tue, 24 Sep 2013 12:08:06 -0600 Subject: PCI: Export pcie_set_mps() and pcie_get_mps() Export pcie_get_mps() and pcie_set_mps() functions so drivers can use them to simplify code. Signed-off-by: Yijing Wang Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/pci/pci.c') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e8ccf6c0f08..8c812464f25 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3972,6 +3972,7 @@ int pcie_get_mps(struct pci_dev *dev) return 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5); } +EXPORT_SYMBOL(pcie_get_mps); /** * pcie_set_mps - set PCI Express maximum payload size @@ -3996,6 +3997,7 @@ int pcie_set_mps(struct pci_dev *dev, int mps) return pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_PAYLOAD, v); } +EXPORT_SYMBOL(pcie_set_mps); /** * pcie_get_minimum_link - determine minimum link settings of a PCI device -- cgit v1.2.3-70-g09d2 From a006482b67a96c16dfefc558e36863c51e1829bf Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Mon, 23 Sep 2013 15:25:26 -0600 Subject: PCI: Drop "setting latency timer" messages This message isn't useful any more, so drop it. Reference: https://bugzilla.kernel.org/show_bug.cgi?id=60636 Reported-by: Oleksil Shevchuk Reference: http://lkml.kernel.org/r/CALCETrWkr53ZjqdN3t7rTTfr=+ZKZXJoYsuBcwPf0kN_33GfAw@mail.gmail.com Reported-by: Andy Lutomirski 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 e8ccf6c0f08..ad7fc72a40a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2854,7 +2854,7 @@ void __weak pcibios_set_master(struct pci_dev *dev) lat = pcibios_max_latency; else return; - dev_printk(KERN_DEBUG, &dev->dev, "setting latency timer to %d\n", lat); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); } -- cgit v1.2.3-70-g09d2 From 0394cb192db4397753046775a8caa736397737b5 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 16 Oct 2013 12:32:53 -0600 Subject: PCI: Report pci_pme_active() kmalloc failure Previously, if kmalloc() failed, we claimed "PME# enabled" in dmesg, even though we didn't add the device to the pci_pme_list. This prints a more correct warning. Signed-off-by: Bjorn Helgaas Acked-by: Rafael J. Wysocki --- drivers/pci/pci.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/pci/pci.c') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index ad7fc72a40a..36cc8d5ae8b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1638,8 +1638,10 @@ void pci_pme_active(struct pci_dev *dev, bool enable) if (enable) { pme_dev = kmalloc(sizeof(struct pci_pme_device), GFP_KERNEL); - if (!pme_dev) - goto out; + if (!pme_dev) { + dev_warn(&dev->dev, "can't enable PME#\n"); + return; + } pme_dev->dev = dev; mutex_lock(&pci_pme_list_mutex); list_add(&pme_dev->list, &pci_pme_list); @@ -1660,7 +1662,6 @@ void pci_pme_active(struct pci_dev *dev, bool enable) } } -out: dev_dbg(&dev->dev, "PME# %s\n", enable ? "enabled" : "disabled"); } -- cgit v1.2.3-70-g09d2 From cf3e1feba7f906f233790f1806592730a88f584d Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 5 Nov 2013 13:34:38 -0700 Subject: PCI: Workaround missing pci_set_master in pci drivers Ben Herrenschmidt found that commit 928bea964827 ("PCI: Delay enabling bridges until they're needed") breaks PCI in some powerpc environments. The reason is that the PCIe port driver will call pci_enable_device() on the bridge, so the device is enabled, but skips pci_set_master because pcie_port_auto and no acpi on powerpc. Because of that, pci_enable_bridge() later on (called as a result of the child device driver doing pci_enable_device) will see the bridge as already enabled and will not call pci_set_master() on it. Fixed by add checking in pci_enable_bridge, and call pci_set_master if driver skip that. That will make the code more robot and wade off problem for missing pci_set_master in drivers. Reported-by: Benjamin Herrenschmidt Signed-off-by: Yinghai Lu Signed-off-by: Linus Torvalds --- drivers/pci/pci.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/pci/pci.c') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 36cc8d5ae8b..7a92d81c28e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1155,8 +1155,14 @@ static void pci_enable_bridge(struct pci_dev *dev) pci_enable_bridge(dev->bus->self); - if (pci_is_enabled(dev)) + if (pci_is_enabled(dev)) { + if (!dev->is_busmaster) { + dev_warn(&dev->dev, "driver skip pci_set_master, fix it!\n"); + pci_set_master(dev); + } return; + } + retval = pci_enable_device(dev); if (retval) dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n", -- cgit v1.2.3-70-g09d2 From fbeeb822f6f45cadf154d7b7cff1c13537cd799d Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 5 Nov 2013 13:34:51 -0700 Subject: PCI: Drop warning about drivers that don't use pci_set_master() f41f064cf4 ("PCI: Workaround missing pci_set_master in pci drivers") made pci_enable_bridge() turn on bus mastering if the driver hadn't done so already. It also added a warning in this case. But there's no reason to warn about it unless it's actually a problem to enable bus mastering here. This patch drops the warning because I'm not aware of any such problem. Signed-off-by: Bjorn Helgaas CC: Paul Bolle --- drivers/pci/pci.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/pci/pci.c') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 7a92d81c28e..ac40f90cfd5 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1156,10 +1156,8 @@ static void pci_enable_bridge(struct pci_dev *dev) pci_enable_bridge(dev->bus->self); if (pci_is_enabled(dev)) { - if (!dev->is_busmaster) { - dev_warn(&dev->dev, "driver skip pci_set_master, fix it!\n"); + if (!dev->is_busmaster) pci_set_master(dev); - } return; } -- cgit v1.2.3-70-g09d2 From 79272138bd5c35edb9be5ae7b473a2741751a706 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 6 Nov 2013 10:00:51 -0700 Subject: PCI: Enable upstream bridges even for VFs on virtual buses Previously we enabled the upstream PCI-to-PCI bridge only when "dev->bus->self != NULL". In the case of a VF on a virtual bus, where "bus->self == NULL", we didn't enable the upstream bridge. This fixes that by enabling the upstream bridge of the PF corresponding to the VF. Signed-off-by: Bjorn Helgaas Acked-by: Yinghai Lu --- drivers/pci/pci.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/pci/pci.c') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index ac40f90cfd5..d3ed931c077 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1148,12 +1148,12 @@ int pci_reenable_device(struct pci_dev *dev) static void pci_enable_bridge(struct pci_dev *dev) { + struct pci_dev *bridge; int retval; - if (!dev) - return; - - pci_enable_bridge(dev->bus->self); + bridge = pci_upstream_bridge(dev); + if (bridge) + pci_enable_bridge(bridge); if (pci_is_enabled(dev)) { if (!dev->is_busmaster) @@ -1170,6 +1170,7 @@ static void pci_enable_bridge(struct pci_dev *dev) static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) { + struct pci_dev *bridge; int err; int i, bars = 0; @@ -1188,7 +1189,9 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) if (atomic_inc_return(&dev->enable_cnt) > 1) return 0; /* already enabled */ - pci_enable_bridge(dev->bus->self); + bridge = pci_upstream_bridge(dev); + if (bridge) + pci_enable_bridge(bridge); /* only skip sriov related */ for (i = 0; i <= PCI_ROM_RESOURCE; i++) -- cgit v1.2.3-70-g09d2