Rafael J. Wysocki | 28 May 04:12 2015
Picon

[PATCH] Revert "PCI/PM: Remove pci_pm_complete()"

From: Rafael J. Wysocki <rafael.j.wysocki <at> intel.com>

Revert commit 84822b158fd3 "PCI/PM: Remove pci_pm_complete()" that
removed the execution of the device driver's ->complete callback
from the PCI bus type.

That was a mistake, because those callbacks are not executed at all
now even if present.

Fixes: 84822b158fd3 "PCI/PM: Remove pci_pm_complete()"
Cc: 3.13+ <stable <at> vger.kernel.org> # 3.13+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki <at> intel.com>

diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 3cb2210de553..75c6aaec5c9b 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
 <at>  <at>  -669,10 +669,18  <at>  <at>  static int pci_pm_prepare(struct device *dev)
 	return pci_dev_keep_suspended(to_pci_dev(dev));
 }

+static void pci_pm_complete(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+
+	if (drv && drv->pm && drv->pm->complete)
+		drv->pm->complete(dev);
+}

 #else /* !CONFIG_PM_SLEEP */
(Continue reading)

Tang, Jason (ES | 27 May 22:59 2015
Picon

[PATCH v0 10/13] PCI: Invalidate resources conflicting with bridge memories

If the static enumeration profile reserves memory behind a bridge, and
that memory was already assigned to a device's BAR by the BIOS, then
invalidate those BAR resources. The core PCI subsystem will then
reassign those BARs to a different, not-conflicting location.

Signed-off-by: Jason Tang <jason.tang2 <at> ngc.com>
---
 drivers/pci/pci_static_enum.c |   42 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/drivers/pci/pci_static_enum.c b/drivers/pci/pci_static_enum.c
index 8d479a9..f000c7f 100644
--- a/drivers/pci/pci_static_enum.c
+++ b/drivers/pci/pci_static_enum.c
 <at>  <at>  -259,6 +259,41  <at>  <at>  int pci_static_enum_get_busnr(struct pci_bus *bus, struct pci_dev *dev,
 }

 /**
+ * pci_static_enum_invalidate() - callback invoked while invalidating
+ * bridge resources
+ *  <at> dev: device to examine
+ *  <at> data: overridden bridge memory
+ *
+ * For each of  <at> dev's BARs, if it conflicts with the memory being
+ * reserved for a bridge then invalidate it.
+ *
+ * Return: 0
+ */
+static int pci_static_enum_invalidate(struct pci_dev *dev, void *data)
+{
(Continue reading)

Tang, Jason (ES | 27 May 22:59 2015
Picon

[PATCH v0 13/13] PCI: Don't adjust settings for statically enumerated

Once a PCI device's memory settings have been fixed through a static
enumeration profile, do not allow other parts of the PCI subsystem
to reset those settings.  Specifically,
pci_reassigndev_resource_alignment() will remove the memory behind a
bridge if there are no devices downstream.  With static enumeration,
devices may appear downstream later on, after the initial scan. Thus,
do not remove resources explicitly set by the static enumeration
profile.

Signed-off-by: Jason Tang <jason.tang2 <at> ngc.com>
---
 drivers/pci/pci.h             |   12 ++++++++++++
 drivers/pci/pci_static_enum.c |    4 ++++
 drivers/pci/probe.c           |    3 ++-
 include/linux/pci.h           |    4 ++++
 4 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index db710ac..6233998 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
 <at>  <at>  -336,6 +336,14  <at>  <at>  static inline unsigned char pci_bus_subordinate(struct pci_bus *bus)
 {
 	return bus->subordinate;
 }
+/**
+ * pci_static_enum_set() - return %true if  <at> dev's bridge and BAR
+ * settings have been set by a static enumeration profile
+ */
+static inline bool pci_static_enum_set(struct pci_dev *dev)
(Continue reading)

Tang, Jason (ES | 27 May 22:59 2015
Picon

[PATCH v0 12/13] PCI: Keep searching upstream for enclosing bus

When reassigning a device's BARs, look for an enumeration profile in all
upstream buses, not just the immediate upstream bus.

Signed-off-by: Jason Tang <jason.tang2 <at> ngc.com>
---
 drivers/pci/pci_static_enum.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/pci_static_enum.c b/drivers/pci/pci_static_enum.c
index 50f4db4..14626cd 100644
--- a/drivers/pci/pci_static_enum.c
+++ b/drivers/pci/pci_static_enum.c
 <at>  <at>  -542,11 +542,14  <at>  <at>  void pci_static_enum_device(struct pci_dev *dev)
 	 */
 	parent = pci_upstream_bridge(dev);

-	if (parent) {
+	while (parent) {
 		setting = pci_static_enum_find_setting(pci_domain_nr(dev->bus),
 						       parent->bus->number,
 						       parent->devfn);
-		if (setting)
+		if (setting) {
 			pci_static_enum_set_mmio_bars(dev, setting);
+			break;
+		}
+		parent = pci_upstream_bridge(parent);
 	}
 }
--

-- 
(Continue reading)

Tang, Jason (ES | 27 May 22:59 2015
Picon

[PATCH v0 11/13] PCI: Reassign device's MMIO BARs

If the upstream bridge has a static enumeration profile, then reassign
all of the device's MMIO BARs to fit within the upstream bridge's
memory space. Use a first-fit algorithm to minimize memory holes.

Signed-off-by: Jason Tang <jason.tang2 <at> ngc.com>
---
 drivers/pci/pci_static_enum.c |  175 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 175 insertions(+)

diff --git a/drivers/pci/pci_static_enum.c b/drivers/pci/pci_static_enum.c
index f000c7f..50f4db4 100644
--- a/drivers/pci/pci_static_enum.c
+++ b/drivers/pci/pci_static_enum.c
 <at>  <at>  -21,6 +21,12  <at>  <at> 

 static DEFINE_SPINLOCK(static_enum_lock);

+struct pci_static_enum_memspace {
+	struct list_head list;
+	resource_size_t start;
+	resource_size_t size;
+};
+
 struct pci_static_enum_setting {
 	struct list_head list;
 	int seg;
 <at>  <at>  -29,6 +35,7  <at>  <at>  struct pci_static_enum_setting {
 	unsigned char secondary_bus;
 	unsigned char subordinate_bus;
 	resource_size_t bridgemem_start, bridgemem_end;
(Continue reading)

Tang, Jason (ES | 27 May 22:59 2015
Picon

[PATCH v0 05/13] PCI: Specify static enumeration on kcmdline

The user can specify a static enumeration profile via kernel command
line. A future commit will parse those options.

Signed-off-by: Jason Tang <jason.tang2 <at> ngc.com>
---
 drivers/pci/Makefile          |    2 ++
 drivers/pci/pci.c             |    2 ++
 drivers/pci/pci.h             |    2 ++
 drivers/pci/pci_static_enum.c |   54 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 60 insertions(+)
 create mode 100644 drivers/pci/pci_static_enum.c

diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 73e4af4..3cacdfc 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
 <at>  <at>  -59,5 +59,7  <at>  <at>  obj-$(CONFIG_OF) += of.o

 ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG

+obj-$(CONFIG_PCI_STATIC_ENUMERATION) += pci_static_enum.o
+
 # PCI host controller drivers
 obj-y += host/
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 81f06e8..5d8c0e0 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
 <at>  <at>  -4607,6 +4607,8  <at>  <at>  static int __init pci_setup(char *str)
 				pcie_bus_config = PCIE_BUS_PEER2PEER;
(Continue reading)

Tang, Jason (ES | 27 May 22:59 2015
Picon

[PATCH v0 08/13] PCI: Statically specify bus memory regions

In the static enumeration profile, the user may override the memory
space associated with a bus. This is needed so that when a PCI endpoint
is later discovered, it can fit within its upstream bus's memory space
without requiring that the bus's memory be resized (and hence other
device potentially moved).

Signed-off-by: Jason Tang <jason.tang2 <at> ngc.com>
---
 Documentation/kernel-parameters.txt |    2 ++
 drivers/pci/pci.h                   |    2 ++
 drivers/pci/pci_static_enum.c       |   47 +++++++++++++++++++++++++++++++++++
 drivers/pci/probe.c                 |    3 +++
 4 files changed, 54 insertions(+)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index af2ce92..5413155 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
 <at>  <at>  -2773,6 +2773,8  <at>  <at>  bytes respectively. Such letter suffixes can also be entirely omitted.
 				and <option> is any combination of:
 				B<secondary>-<subordinate> -
 				  force secondary and subordinate bus numbers
+				M<address>-<address> -
+				  set MMIO memory range
 				All values are in hexadecimal.

 	pcie_aspm=	[PCIE] Forcibly enable or disable PCIe Active State Power
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 665c798..db710ac 100644
--- a/drivers/pci/pci.h
(Continue reading)

Tang, Jason (ES | 27 May 22:59 2015
Picon

[PATCH v0 09/13] PCI: Adjust upstream bridge memories to match static enumeration

After overriding the memory behind a bridge, update all upstream bridges
so that their memory bases and limits encompass the overridden values.

Signed-off-by: Jason Tang <jason.tang2 <at> ngc.com>
---
 drivers/pci/pci_static_enum.c |   37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/drivers/pci/pci_static_enum.c b/drivers/pci/pci_static_enum.c
index 9c9ea4a..8d479a9 100644
--- a/drivers/pci/pci_static_enum.c
+++ b/drivers/pci/pci_static_enum.c
 <at>  <at>  -269,6 +269,10  <at>  <at>  static void pci_static_enum_set_bridge_memory(struct pci_dev *dev, struct pci_st
 					      *setting)
 {
 	u16 mem_base_lo, mem_limit_lo;
+	struct pci_dev *parent;
+	struct resource *res;
+	u16 parent_base_lo, parent_limit_lo;
+	unsigned long base, limit;

 	dev_info(&dev->dev, "Overriding memory base and limit to %pa-%pa\n",
 		 &setting->bridgemem_start, &setting->bridgemem_end);
 <at>  <at>  -276,6 +280,39  <at>  <at>  static void pci_static_enum_set_bridge_memory(struct pci_dev *dev, struct pci_st
 	mem_limit_lo = (setting->bridgemem_end >> 16) & ~0xf;
 	pci_write_config_word(dev, PCI_MEMORY_BASE, mem_base_lo);
 	pci_write_config_word(dev, PCI_MEMORY_LIMIT, mem_limit_lo);
+
+	/* update all upstream bridges' memory to encompass this
+	   bridge memory */
(Continue reading)

Tang, Jason (ES | 27 May 22:59 2015
Picon

[PATCH v0 07/13] PCI: Calculate child's bus number based upon enumeration

While scanning a bridge, pci_scan_bridge() checks if a child pci_bus
already exists by looking up its bus number. It uses the value
'max+1' as the expected child bus number. If the child does not exist,
pci_scan_bridge() will create a new pci_bus for the child.

While rescanning the same bridge, pci_scan_bridge() assumes an existing
child's bus number is 'max+1'. This is not always true, given a static
enumeration profile. The profile may intentionally skip bus numbers.
Thus, the child's number is not necessarily 'max+1'.

This commit changes the scanning behavior slightly. If the device being
scanned has an enumeration profile, then pci_scan_bridge() will use
that number when searching for it. Otherwise it falls back to the
default 'max+1' bus number.

Signed-off-by: Jason Tang <jason.tang2 <at> ngc.com>
---
 drivers/pci/pci.h             |    7 +++++++
 drivers/pci/pci_static_enum.c |   24 ++++++++++++++++++++++++
 drivers/pci/probe.c           |    6 ++++--
 3 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 7a051f5..665c798 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
 <at>  <at>  -325,6 +325,8  <at>  <at>  static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
 void pci_static_enum_set_opt(const char *str);
 int pci_static_enum_exists(void);
 void pci_static_enum_bus_nums(struct pci_bus *bus);
(Continue reading)

Tang, Jason (ES | 27 May 22:59 2015
Picon

[PATCH v0 06/13] PCI: Set secondary and subordinate bus numbers

By using the static enumeration kcmdline, a user can override secondary
and subordinate bus numbers assigned to child bridges. This includes
adding padding to subordinate bus numbers, to accommodate dynamic PCI
device discovery.

Signed-off-by: Jason Tang <jason.tang2 <at> ngc.com>
---
 Documentation/kernel-parameters.txt |    9 ++
 drivers/pci/pci.h                   |    4 +
 drivers/pci/pci_static_enum.c       |  173 +++++++++++++++++++++++++++++++++++
 drivers/pci/probe.c                 |    8 +-
 4 files changed, 193 insertions(+), 1 deletion(-)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 4d68ec8..af2ce92 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
 <at>  <at>  -2765,6 +2765,15  <at>  <at>  bytes respectively. Such letter suffixes can also be entirely omitted.
 		pcie_scan_all	Scan all possible PCIe devices.  Otherwise we
 				only look for one device below a PCIe downstream
 				port.
+		enum=		Enable static enumeration, overriding any
+				BIOS/firmware settings.  If "off" then disable
+				all static enumeration. Otherwise format is:
+				<device> <at> <option>[<option2>...]
+				Where <device> is <domain>:<bus>:<slot>.<func>
+				and <option> is any combination of:
+				B<secondary>-<subordinate> -
+				  force secondary and subordinate bus numbers
+				All values are in hexadecimal.
(Continue reading)

Tang, Jason (ES | 27 May 22:58 2015
Picon

[PATCH v0 04/13] PCI: Track subordinate values in struct pci_bus

This commit adds the subordinate field to struct pci_bus. Normally,
the subordinate is automatically calculated while scanning children of
the bus and counting the number of downstream buses.

With static enumeration, a bus's subordinate may need to be greater than
the count, such as when a PCI device is powered on after initial
enumeration.  Without the subordinate field, if the newly powered device
is itself a bridge, then it will not have a valid secondary number
without reshuffling all existing devices.

By storing the bus's intended subordinate number, the scanning algorithm
can skip over reserved numbers while enumerating devices. The value 0
means to use the existing enumerating algorithm. An upcoming commit will
set that subordinate field to a non-zero value.

Signed-off-by: Jason Tang <jason.tang2 <at> ngc.com>
---
 drivers/pci/pci.h   |   16 ++++++++++++++++
 drivers/pci/probe.c |   16 ++++++++++++++++
 include/linux/pci.h |    3 +++
 3 files changed, 35 insertions(+)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 4091f82..075bd9d 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
 <at>  <at>  -321,4 +321,20  <at>  <at>  static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
 }
 #endif

(Continue reading)


Gmane