All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges
@ 2012-06-21  9:36 Jiang Liu
  2012-06-21  9:36 ` [PATCH v9 01/11] x86/PCI: split out pci_mmcfg_check_reserved() for code reuse Jiang Liu
                   ` (11 more replies)
  0 siblings, 12 replies; 18+ messages in thread
From: Jiang Liu @ 2012-06-21  9:36 UTC (permalink / raw)
  To: Bjorn Helgaas, Yinghai Lu, Taku Izumi, Kenji Kaneshige, Don Dutile
  Cc: Jiang Liu, Yijing Wang, Keping Chen, linux-pci

This patchset enhance pci_root driver to update MMCFG information when
hot-plugging PCI root bridges. It applies to 
git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci/next

-v2: split into smaller patches and skip updating MMCFG information when
     MMCFG is disabled
-v3: add mmconf_added to simply free path, also make pci_mmconfig_insert()
     to process extra exist case --- By Yinghai
-v4: tune arch_acpi_pci_root_add() to handle a corner case raised by Kenji
-v5: address review comments from Bjorn and Taku, also better handle corner
     cases in arch_acpi_pci_root_add()
-v6: get rid of arch_acpi_pci_root_xxx() by using existing hooks
     add MCFG information for host bridges on demand
     more corner cases clear up
     correctly handle condition compilation
     fix section mismatch issues
     fix a issue reported by Taku about a BIOS bug
-v7: unify log messages
     remove redundant host bridge resource related log messages
     fix a issue reported by Taku which breaks pnp resource allocation
-v8: 1) add acpi_pci_cache_mcfg() in patch "provide MCFG address for PCI host
     bridges" for better readability and fix a condition compilation issue
     2) change patch "add MMCFG information on demand" to RFC and fix
     compilation issues reported by Fengguang
     3) Add new patch "refine __pci_mmcfg_init() for better code readability"
      and "mark acpi_sfi_table_parse() as __init", there should no
      functionality changes.
-v9: changes from v7 (redo v8)
     Redo v8 to remove MCFG caching logic according to Yinghai's suggestion.
     1) remove patch "add MMCFG information on demand" and MCFG caching logic
     2) Add new patch "refine __pci_mmcfg_init() for better code readability"
      and "mark acpi_sfi_table_parse() as __init", there should no
      functionality changes.

Jiang Liu (11):
  x86/PCI: split out pci_mmcfg_check_reserved() for code reuse
  x86/PCI: split out pci_mmconfig_alloc() for code reuse
  x86/PCI: use RCU list to protect mmconfig list
  x86/PCI: introduce pci_mmcfg_arch_map()/pci_mmcfg_arch_unmap()
  x86/PCI: add pci_mmconfig_insert()/delete() for PCI root bridge
    hotplug
  PCI/ACPI: provide MCFG address for PCI host bridges
  x86/PCI: update MMCFG information when hot-plugging PCI host bridges
  x86/PCI: simplify pci_mmcfg_late_insert_resources()
  x86/PCI: get rid of redundant log messages
  x86, PCI: refine __pci_mmcfg_init() for better code readability
  ACPI: mark acpi_sfi_table_parse() as __init

 arch/x86/include/asm/pci_x86.h |    7 +
 arch/x86/pci/acpi.c            |   78 ++++++++-
 arch/x86/pci/mmconfig-shared.c |  361 +++++++++++++++++++++++++++-------------
 arch/x86/pci/mmconfig_32.c     |   30 +++-
 arch/x86/pci/mmconfig_64.c     |   37 ++++-
 drivers/acpi/pci_root.c        |    2 +
 drivers/pci/pci-acpi.c         |   14 ++
 include/acpi/acnames.h         |    1 +
 include/acpi/acpi_bus.h        |    1 +
 include/linux/pci-acpi.h       |    1 +
 include/linux/sfi_acpi.h       |    4 +-
 11 files changed, 403 insertions(+), 133 deletions(-)



^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v9 01/11] x86/PCI: split out pci_mmcfg_check_reserved() for code reuse
  2012-06-21  9:36 [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Jiang Liu
@ 2012-06-21  9:36 ` Jiang Liu
  2012-06-21  9:36 ` [PATCH v9 02/11] x86/PCI: split out pci_mmconfig_alloc() " Jiang Liu
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Jiang Liu @ 2012-06-21  9:36 UTC (permalink / raw)
  To: Bjorn Helgaas, Yinghai Lu, Taku Izumi, Kenji Kaneshige, Don Dutile
  Cc: Jiang Liu, Yijing Wang, Keping Chen, linux-pci, Jiang Liu

Split out pci_mmcfg_check_reserved() for code reuse, which will be used
when supporting PCI host bridge hotplug.

Signed-off-by: Jiang Liu <liuj97@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/x86/pci/mmconfig-shared.c |   51 +++++++++++++++++++--------------------
 1 files changed, 25 insertions(+), 26 deletions(-)

diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 301e325..f799949 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -474,39 +474,38 @@ static int __init is_mmconf_reserved(check_reserved_t is_reserved,
 	return valid;
 }
 
+static int __devinit pci_mmcfg_check_reserved(struct pci_mmcfg_region *cfg,
+					      int early)
+{
+	if (!early && !acpi_disabled) {
+		if (is_mmconf_reserved(is_acpi_reserved, cfg, 0))
+			return 1;
+		else
+			printk(KERN_ERR FW_BUG PREFIX
+			       "MMCONFIG at %pR not reserved in "
+			       "ACPI motherboard resources\n",
+			       &cfg->res);
+	}
+
+	/* Don't try to do this check unless configuration
+	   type 1 is available. how about type 2 ?*/
+	if (raw_pci_ops)
+		return is_mmconf_reserved(e820_all_mapped, cfg, 1);
+
+	return 0;
+}
+
 static void __init pci_mmcfg_reject_broken(int early)
 {
 	struct pci_mmcfg_region *cfg;
 
 	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
-		int valid = 0;
-
-		if (!early && !acpi_disabled) {
-			valid = is_mmconf_reserved(is_acpi_reserved, cfg, 0);
-
-			if (valid)
-				continue;
-			else
-				printk(KERN_ERR FW_BUG PREFIX
-				       "MMCONFIG at %pR not reserved in "
-				       "ACPI motherboard resources\n",
-				       &cfg->res);
+		if (pci_mmcfg_check_reserved(cfg, early) == 0) {
+			printk(KERN_INFO PREFIX "not using MMCONFIG\n");
+			free_all_mmcfg();
+			return;
 		}
-
-		/* Don't try to do this check unless configuration
-		   type 1 is available. how about type 2 ?*/
-		if (raw_pci_ops)
-			valid = is_mmconf_reserved(e820_all_mapped, cfg, 1);
-
-		if (!valid)
-			goto reject;
 	}
-
-	return;
-
-reject:
-	printk(KERN_INFO PREFIX "not using MMCONFIG\n");
-	free_all_mmcfg();
 }
 
 static int __initdata known_bridge;
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v9 02/11] x86/PCI: split out pci_mmconfig_alloc() for code reuse
  2012-06-21  9:36 [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Jiang Liu
  2012-06-21  9:36 ` [PATCH v9 01/11] x86/PCI: split out pci_mmcfg_check_reserved() for code reuse Jiang Liu
@ 2012-06-21  9:36 ` Jiang Liu
  2012-06-21  9:36 ` [PATCH v9 03/11] x86/PCI: use RCU list to protect mmconfig list Jiang Liu
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Jiang Liu @ 2012-06-21  9:36 UTC (permalink / raw)
  To: Bjorn Helgaas, Yinghai Lu, Taku Izumi, Kenji Kaneshige, Don Dutile
  Cc: Jiang Liu, Yijing Wang, Keping Chen, linux-pci, Jiang Liu

Split out pci_mmconfig_alloc() for code reuse, which will be used
when supporting PCI root bridge hotplug.

Signed-off-by: Jiang Liu <liuj97@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/x86/pci/mmconfig-shared.c |   19 +++++++++++++++----
 1 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index f799949..5e2cd2a 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -61,8 +61,9 @@ static __init void list_add_sorted(struct pci_mmcfg_region *new)
 	list_add_tail(&new->list, &pci_mmcfg_list);
 }
 
-static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
-							int end, u64 addr)
+static __devinit struct pci_mmcfg_region *pci_mmconfig_alloc(int segment,
+							     int start,
+							     int end, u64 addr)
 {
 	struct pci_mmcfg_region *new;
 	struct resource *res;
@@ -79,8 +80,6 @@ static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
 	new->start_bus = start;
 	new->end_bus = end;
 
-	list_add_sorted(new);
-
 	res = &new->res;
 	res->start = addr + PCI_MMCFG_BUS_OFFSET(start);
 	res->end = addr + PCI_MMCFG_BUS_OFFSET(end + 1) - 1;
@@ -96,6 +95,18 @@ static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
 	return new;
 }
 
+static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
+							int end, u64 addr)
+{
+	struct pci_mmcfg_region *new;
+
+	new = pci_mmconfig_alloc(segment, start, end, addr);
+	if (new)
+		list_add_sorted(new);
+
+	return new;
+}
+
 struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus)
 {
 	struct pci_mmcfg_region *cfg;
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v9 03/11] x86/PCI: use RCU list to protect mmconfig list
  2012-06-21  9:36 [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Jiang Liu
  2012-06-21  9:36 ` [PATCH v9 01/11] x86/PCI: split out pci_mmcfg_check_reserved() for code reuse Jiang Liu
  2012-06-21  9:36 ` [PATCH v9 02/11] x86/PCI: split out pci_mmconfig_alloc() " Jiang Liu
@ 2012-06-21  9:36 ` Jiang Liu
  2012-06-21  9:36 ` [PATCH v9 04/11] x86/PCI: introduce pci_mmcfg_arch_map()/pci_mmcfg_arch_unmap() Jiang Liu
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Jiang Liu @ 2012-06-21  9:36 UTC (permalink / raw)
  To: Bjorn Helgaas, Yinghai Lu, Taku Izumi, Kenji Kaneshige, Don Dutile
  Cc: Jiang Liu, Yijing Wang, Keping Chen, linux-pci, Jiang Liu

Use RCU list to protect mmconfig list from dynamic change
when supporting PCI host bridge hotplug.

Signed-off-by: Jiang Liu <liuj97@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/x86/pci/mmconfig-shared.c |   18 ++++++++++++------
 arch/x86/pci/mmconfig_32.c     |   13 +++++++++++--
 arch/x86/pci/mmconfig_64.c     |   13 +++++++++++--
 3 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 5e2cd2a..0ac97d5 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -17,6 +17,8 @@
 #include <linux/bitmap.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/rculist.h>
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
 #include <asm/acpi.h>
@@ -25,6 +27,7 @@
 
 /* Indicate if the mmcfg resources have been placed into the resource table. */
 static int __initdata pci_mmcfg_resources_inserted;
+static DEFINE_MUTEX(pci_mmcfg_lock);
 
 LIST_HEAD(pci_mmcfg_list);
 
@@ -45,20 +48,20 @@ static __init void free_all_mmcfg(void)
 		pci_mmconfig_remove(cfg);
 }
 
-static __init void list_add_sorted(struct pci_mmcfg_region *new)
+static __devinit void list_add_sorted(struct pci_mmcfg_region *new)
 {
 	struct pci_mmcfg_region *cfg;
 
 	/* keep list sorted by segment and starting bus number */
-	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list) {
 		if (cfg->segment > new->segment ||
 		    (cfg->segment == new->segment &&
 		     cfg->start_bus >= new->start_bus)) {
-			list_add_tail(&new->list, &cfg->list);
+			list_add_tail_rcu(&new->list, &cfg->list);
 			return;
 		}
 	}
-	list_add_tail(&new->list, &pci_mmcfg_list);
+	list_add_tail_rcu(&new->list, &pci_mmcfg_list);
 }
 
 static __devinit struct pci_mmcfg_region *pci_mmconfig_alloc(int segment,
@@ -101,8 +104,11 @@ static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
 	struct pci_mmcfg_region *new;
 
 	new = pci_mmconfig_alloc(segment, start, end, addr);
-	if (new)
+	if (new) {
+		mutex_lock(&pci_mmcfg_lock);
 		list_add_sorted(new);
+		mutex_unlock(&pci_mmcfg_lock);
+	}
 
 	return new;
 }
@@ -111,7 +117,7 @@ struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus)
 {
 	struct pci_mmcfg_region *cfg;
 
-	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
 		if (cfg->segment == segment &&
 		    cfg->start_bus <= bus && bus <= cfg->end_bus)
 			return cfg;
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
index 5372e86..5dad04a 100644
--- a/arch/x86/pci/mmconfig_32.c
+++ b/arch/x86/pci/mmconfig_32.c
@@ -11,6 +11,7 @@
 
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/rcupdate.h>
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
 #include <acpi/acpi.h>
@@ -60,9 +61,12 @@ err:		*value = -1;
 		return -EINVAL;
 	}
 
+	rcu_read_lock();
 	base = get_base_addr(seg, bus, devfn);
-	if (!base)
+	if (!base) {
+		rcu_read_unlock();
 		goto err;
+	}
 
 	raw_spin_lock_irqsave(&pci_config_lock, flags);
 
@@ -80,6 +84,7 @@ err:		*value = -1;
 		break;
 	}
 	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
+	rcu_read_unlock();
 
 	return 0;
 }
@@ -93,9 +98,12 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 	if ((bus > 255) || (devfn > 255) || (reg > 4095))
 		return -EINVAL;
 
+	rcu_read_lock();
 	base = get_base_addr(seg, bus, devfn);
-	if (!base)
+	if (!base) {
+		rcu_read_unlock();
 		return -EINVAL;
+	}
 
 	raw_spin_lock_irqsave(&pci_config_lock, flags);
 
@@ -113,6 +121,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 		break;
 	}
 	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
+	rcu_read_unlock();
 
 	return 0;
 }
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
index 915a493..acc48c5 100644
--- a/arch/x86/pci/mmconfig_64.c
+++ b/arch/x86/pci/mmconfig_64.c
@@ -9,6 +9,7 @@
 #include <linux/init.h>
 #include <linux/acpi.h>
 #include <linux/bitmap.h>
+#include <linux/rcupdate.h>
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
 
@@ -34,9 +35,12 @@ err:		*value = -1;
 		return -EINVAL;
 	}
 
+	rcu_read_lock();
 	addr = pci_dev_base(seg, bus, devfn);
-	if (!addr)
+	if (!addr) {
+		rcu_read_unlock();
 		goto err;
+	}
 
 	switch (len) {
 	case 1:
@@ -49,6 +53,7 @@ err:		*value = -1;
 		*value = mmio_config_readl(addr + reg);
 		break;
 	}
+	rcu_read_unlock();
 
 	return 0;
 }
@@ -62,9 +67,12 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
 		return -EINVAL;
 
+	rcu_read_lock();
 	addr = pci_dev_base(seg, bus, devfn);
-	if (!addr)
+	if (!addr) {
+		rcu_read_unlock();
 		return -EINVAL;
+	}
 
 	switch (len) {
 	case 1:
@@ -77,6 +85,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 		mmio_config_writel(addr + reg, value);
 		break;
 	}
+	rcu_read_unlock();
 
 	return 0;
 }
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v9 04/11] x86/PCI: introduce pci_mmcfg_arch_map()/pci_mmcfg_arch_unmap()
  2012-06-21  9:36 [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Jiang Liu
                   ` (2 preceding siblings ...)
  2012-06-21  9:36 ` [PATCH v9 03/11] x86/PCI: use RCU list to protect mmconfig list Jiang Liu
@ 2012-06-21  9:36 ` Jiang Liu
  2012-06-21 21:25   ` Yinghai Lu
  2012-06-21  9:36 ` [PATCH v9 05/11] x86/PCI: add pci_mmconfig_insert()/delete() for PCI root bridge hotplug Jiang Liu
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 18+ messages in thread
From: Jiang Liu @ 2012-06-21  9:36 UTC (permalink / raw)
  To: Bjorn Helgaas, Yinghai Lu, Taku Izumi, Kenji Kaneshige, Don Dutile
  Cc: Jiang Liu, Yijing Wang, Keping Chen, linux-pci, Jiang Liu

Introduce pci_mmcfg_arch_map()/pci_mmcfg_arch_unmap(), which will be used
when supporting PCI root bridge hotplug.

Signed-off-by: Jiang Liu <liuj97@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/x86/include/asm/pci_x86.h |    2 ++
 arch/x86/pci/mmconfig_32.c     |   15 +++++++++++++++
 arch/x86/pci/mmconfig_64.c     |   22 +++++++++++++++++++++-
 3 files changed, 38 insertions(+), 1 deletions(-)

diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index b3a5317..df898ce 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -135,6 +135,8 @@ struct pci_mmcfg_region {
 
 extern int __init pci_mmcfg_arch_init(void);
 extern void __init pci_mmcfg_arch_free(void);
+extern int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
+extern void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg);
 extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
 
 extern struct list_head pci_mmcfg_list;
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
index 5dad04a..a22785d 100644
--- a/arch/x86/pci/mmconfig_32.c
+++ b/arch/x86/pci/mmconfig_32.c
@@ -141,3 +141,18 @@ int __init pci_mmcfg_arch_init(void)
 void __init pci_mmcfg_arch_free(void)
 {
 }
+
+int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
+{
+	return 0;
+}
+
+void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg)
+{
+	unsigned long flags;
+
+	/* Invalidate the cached mmcfg map entry. */
+	raw_spin_lock_irqsave(&pci_config_lock, flags);
+	mmcfg_last_accessed_device = 0;
+	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
+}
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
index acc48c5..4e05779 100644
--- a/arch/x86/pci/mmconfig_64.c
+++ b/arch/x86/pci/mmconfig_64.c
@@ -95,7 +95,7 @@ static const struct pci_raw_ops pci_mmcfg = {
 	.write =	pci_mmcfg_write,
 };
 
-static void __iomem * __init mcfg_ioremap(struct pci_mmcfg_region *cfg)
+static void __iomem * __devinit mcfg_ioremap(struct pci_mmcfg_region *cfg)
 {
 	void __iomem *addr;
 	u64 start, size;
@@ -138,3 +138,23 @@ void __init pci_mmcfg_arch_free(void)
 		}
 	}
 }
+
+int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
+{
+	cfg->virt = mcfg_ioremap(cfg);
+	if (!cfg->virt) {
+		printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n",
+		       &cfg->res);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg)
+{
+	if (cfg && cfg->virt) {
+		iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus));
+		cfg->virt = NULL;
+	}
+}
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v9 05/11] x86/PCI: add pci_mmconfig_insert()/delete() for PCI root bridge hotplug
  2012-06-21  9:36 [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Jiang Liu
                   ` (3 preceding siblings ...)
  2012-06-21  9:36 ` [PATCH v9 04/11] x86/PCI: introduce pci_mmcfg_arch_map()/pci_mmcfg_arch_unmap() Jiang Liu
@ 2012-06-21  9:36 ` Jiang Liu
  2012-06-21 21:44   ` Yinghai Lu
  2012-06-21  9:36 ` [PATCH v9 06/11] PCI/ACPI: provide MCFG address for PCI host bridges Jiang Liu
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 18+ messages in thread
From: Jiang Liu @ 2012-06-21  9:36 UTC (permalink / raw)
  To: Bjorn Helgaas, Yinghai Lu, Taku Izumi, Kenji Kaneshige, Don Dutile
  Cc: Jiang Liu, Yijing Wang, Keping Chen, linux-pci, Jiang Liu

Introduce pci_mmconfig_insert()/pci_mmconfig_delete(), which will be used
to update MMCFG information when supporting PCI root bridge hotplug.

[bhelgaas: KERN_INFO, not KERN_ERR, for missing ACPI PNP0C01/02 reservation]
Signed-off-by: Jiang Liu <liuj97@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/x86/include/asm/pci_x86.h |    4 +
 arch/x86/pci/mmconfig-shared.c |  213 ++++++++++++++++++++++++++++++++--------
 2 files changed, 177 insertions(+), 40 deletions(-)

diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index df898ce..af5018f 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -137,6 +137,10 @@ extern int __init pci_mmcfg_arch_init(void);
 extern void __init pci_mmcfg_arch_free(void);
 extern int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
 extern void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg);
+extern int __devinit pci_mmconfig_insert(struct device *dev,
+					 u16 seg, u8 start,
+					 u8 end, phys_addr_t addr);
+extern int pci_mmconfig_delete(u16 seg, u8 start, u8 end);
 extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
 
 extern struct list_head pci_mmcfg_list;
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 0ac97d5..19fc42b 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -27,6 +27,8 @@
 
 /* Indicate if the mmcfg resources have been placed into the resource table. */
 static int __initdata pci_mmcfg_resources_inserted;
+static bool pci_mmcfg_running_state;
+static bool pci_mmcfg_arch_init_failed;
 static DEFINE_MUTEX(pci_mmcfg_lock);
 
 LIST_HEAD(pci_mmcfg_list);
@@ -91,10 +93,6 @@ static __devinit struct pci_mmcfg_region *pci_mmconfig_alloc(int segment,
 		 "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end);
 	res->name = new->name;
 
-	printk(KERN_INFO PREFIX "MMCONFIG for domain %04x [bus %02x-%02x] at "
-	       "%pR (base %#lx)\n", segment, start, end, &new->res,
-	       (unsigned long) addr);
-
 	return new;
 }
 
@@ -108,6 +106,11 @@ static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
 		mutex_lock(&pci_mmcfg_lock);
 		list_add_sorted(new);
 		mutex_unlock(&pci_mmcfg_lock);
+
+		printk(KERN_INFO PREFIX
+		       "MMCONFIG for domain %04x [bus %02x-%02x] at %pR "
+		       "(base %#lx)\n",
+		       segment, start, end, &new->res, (unsigned long)addr);
 	}
 
 	return new;
@@ -375,14 +378,15 @@ static void __init pci_mmcfg_insert_resources(void)
 	struct pci_mmcfg_region *cfg;
 
 	list_for_each_entry(cfg, &pci_mmcfg_list, list)
-		insert_resource(&iomem_resource, &cfg->res);
+		if (!cfg->res.parent)
+			insert_resource(&iomem_resource, &cfg->res);
 
 	/* Mark that the resources have been inserted. */
 	pci_mmcfg_resources_inserted = 1;
 }
 
-static acpi_status __init check_mcfg_resource(struct acpi_resource *res,
-					      void *data)
+static acpi_status __devinit check_mcfg_resource(struct acpi_resource *res,
+						 void *data)
 {
 	struct resource *mcfg_res = data;
 	struct acpi_resource_address64 address;
@@ -418,8 +422,8 @@ static acpi_status __init check_mcfg_resource(struct acpi_resource *res,
 	return AE_OK;
 }
 
-static acpi_status __init find_mboard_resource(acpi_handle handle, u32 lvl,
-		void *context, void **rv)
+static acpi_status __devinit find_mboard_resource(acpi_handle handle, u32 lvl,
+						  void *context, void **rv)
 {
 	struct resource *mcfg_res = context;
 
@@ -432,7 +436,7 @@ static acpi_status __init find_mboard_resource(acpi_handle handle, u32 lvl,
 	return AE_OK;
 }
 
-static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used)
+static int __devinit is_acpi_reserved(u64 start, u64 end, unsigned not_used)
 {
 	struct resource mcfg_res;
 
@@ -451,13 +455,15 @@ static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used)
 
 typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type);
 
-static int __init is_mmconf_reserved(check_reserved_t is_reserved,
-				    struct pci_mmcfg_region *cfg, int with_e820)
+static int __ref is_mmconf_reserved(check_reserved_t is_reserved,
+				    struct pci_mmcfg_region *cfg,
+				    struct device *dev, int with_e820)
 {
 	u64 addr = cfg->res.start;
 	u64 size = resource_size(&cfg->res);
 	u64 old_size = size;
-	int valid = 0, num_buses;
+	int num_buses;
+	char *method = with_e820 ? "E820" : "ACPI motherboard resources";
 
 	while (!is_reserved(addr, addr + size, E820_RESERVED)) {
 		size >>= 1;
@@ -465,49 +471,75 @@ static int __init is_mmconf_reserved(check_reserved_t is_reserved,
 			break;
 	}
 
-	if (size >= (16UL<<20) || size == old_size) {
-		printk(KERN_INFO PREFIX "MMCONFIG at %pR reserved in %s\n",
-		       &cfg->res,
-		       with_e820 ? "E820" : "ACPI motherboard resources");
-		valid = 1;
-
-		if (old_size != size) {
-			/* update end_bus */
-			cfg->end_bus = cfg->start_bus + ((size>>20) - 1);
-			num_buses = cfg->end_bus - cfg->start_bus + 1;
-			cfg->res.end = cfg->res.start +
-			    PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
-			snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN,
-				 "PCI MMCONFIG %04x [bus %02x-%02x]",
-				 cfg->segment, cfg->start_bus, cfg->end_bus);
+	if (size < (16UL<<20) && size != old_size)
+		return 0;
+
+	if (dev)
+		dev_info(dev, "MMCONFIG at %pR reserved in %s\n",
+			 &cfg->res, method);
+	else
+		printk(KERN_INFO PREFIX
+		       "MMCONFIG at %pR reserved in %s\n",
+		       &cfg->res, method);
+
+	if (old_size != size) {
+		/* update end_bus */
+		cfg->end_bus = cfg->start_bus + ((size>>20) - 1);
+		num_buses = cfg->end_bus - cfg->start_bus + 1;
+		cfg->res.end = cfg->res.start +
+		    PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
+		snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN,
+			 "PCI MMCONFIG %04x [bus %02x-%02x]",
+			 cfg->segment, cfg->start_bus, cfg->end_bus);
+
+		if (dev)
+			dev_info(dev,
+				"MMCONFIG "
+				"at %pR (base %#lx) (size reduced!)\n",
+				&cfg->res, (unsigned long) cfg->address);
+		else
 			printk(KERN_INFO PREFIX
-			       "MMCONFIG for %04x [bus%02x-%02x] "
-			       "at %pR (base %#lx) (size reduced!)\n",
-			       cfg->segment, cfg->start_bus, cfg->end_bus,
-			       &cfg->res, (unsigned long) cfg->address);
-		}
+				"MMCONFIG for %04x [bus%02x-%02x] "
+				"at %pR (base %#lx) (size reduced!)\n",
+				cfg->segment, cfg->start_bus, cfg->end_bus,
+				&cfg->res, (unsigned long) cfg->address);
 	}
 
-	return valid;
+	return 1;
 }
 
-static int __devinit pci_mmcfg_check_reserved(struct pci_mmcfg_region *cfg,
-					      int early)
+static int __ref pci_mmcfg_check_reserved(struct device *dev,
+		  struct pci_mmcfg_region *cfg, int early)
 {
 	if (!early && !acpi_disabled) {
-		if (is_mmconf_reserved(is_acpi_reserved, cfg, 0))
+		if (is_mmconf_reserved(is_acpi_reserved, cfg, dev, 0))
 			return 1;
+
+		if (dev)
+			dev_info(dev, FW_INFO
+				 "MMCONFIG at %pR not reserved in "
+				 "ACPI motherboard resources\n",
+				 &cfg->res);
 		else
-			printk(KERN_ERR FW_BUG PREFIX
+			printk(KERN_INFO FW_INFO PREFIX
 			       "MMCONFIG at %pR not reserved in "
 			       "ACPI motherboard resources\n",
 			       &cfg->res);
 	}
 
+	/*
+	 * e820_all_mapped() is marked as __init.
+	 * All entries from ACPI MCFG table have been checked at boot time.
+	 * For MCFG information constructed from hotpluggable host bridge's
+	 * _CBA method, just assume it's reserved.
+	 */
+	if (pci_mmcfg_running_state)
+		return 1;
+
 	/* Don't try to do this check unless configuration
 	   type 1 is available. how about type 2 ?*/
 	if (raw_pci_ops)
-		return is_mmconf_reserved(e820_all_mapped, cfg, 1);
+		return is_mmconf_reserved(e820_all_mapped, cfg, dev, 1);
 
 	return 0;
 }
@@ -517,7 +549,7 @@ static void __init pci_mmcfg_reject_broken(int early)
 	struct pci_mmcfg_region *cfg;
 
 	list_for_each_entry(cfg, &pci_mmcfg_list, list) {
-		if (pci_mmcfg_check_reserved(cfg, early) == 0) {
+		if (pci_mmcfg_check_reserved(NULL, cfg, early) == 0) {
 			printk(KERN_INFO PREFIX "not using MMCONFIG\n");
 			free_all_mmcfg();
 			return;
@@ -641,6 +673,7 @@ static void __init __pci_mmcfg_init(int early)
 		 * the architecture mmcfg setup could not initialize.
 		 */
 		pci_mmcfg_resources_inserted = 1;
+		pci_mmcfg_arch_init_failed = true;
 	}
 }
 
@@ -656,6 +689,8 @@ void __init pci_mmcfg_late_init(void)
 
 static int __init pci_mmcfg_late_insert_resources(void)
 {
+	pci_mmcfg_running_state = true;
+
 	/*
 	 * If resources are already inserted or we are not using MMCONFIG,
 	 * don't insert the resources.
@@ -681,3 +716,101 @@ static int __init pci_mmcfg_late_insert_resources(void)
  * with other system resources.
  */
 late_initcall(pci_mmcfg_late_insert_resources);
+
+/* Add MMCFG information for host bridges */
+int __devinit pci_mmconfig_insert(struct device *dev,
+				  u16 seg, u8 start, u8 end,
+				  phys_addr_t addr)
+{
+	int rc;
+	struct resource *tmp = NULL;
+	struct pci_mmcfg_region *cfg;
+
+	if (!(pci_probe & PCI_PROBE_MMCONF) || pci_mmcfg_arch_init_failed)
+		return -ENODEV;
+
+	if (start > end)
+		return -EINVAL;
+
+	mutex_lock(&pci_mmcfg_lock);
+	cfg = pci_mmconfig_lookup(seg, start);
+	if (cfg) {
+		if (cfg->end_bus < end)
+			dev_info(dev, FW_INFO
+				 "MMCONFIG for "
+				 "domain %04x [bus %02x-%02x] "
+				 "only partially covers this bridge\n",
+				  cfg->segment, cfg->start_bus, cfg->end_bus);
+		mutex_unlock(&pci_mmcfg_lock);
+		return -EEXIST;
+	}
+
+	if (!addr) {
+		mutex_unlock(&pci_mmcfg_lock);
+		return -EINVAL;
+	}
+
+	rc = -EBUSY;
+	cfg = pci_mmconfig_alloc(seg, start, end, addr);
+	if (cfg == NULL) {
+		dev_warn(dev, "fail to add MMCONFIG (out of memory)\n");
+		rc = -ENOMEM;
+	} else if (!pci_mmcfg_check_reserved(dev, cfg, 0)) {
+		dev_warn(dev, FW_BUG "MMCONFIG %pR isn't reserved\n",
+			 &cfg->res);
+	} else {
+		/* Insert resource if it's not in boot stage */
+		if (pci_mmcfg_running_state)
+			tmp = insert_resource_conflict(&iomem_resource,
+						       &cfg->res);
+
+		if (tmp) {
+			dev_warn(dev,
+				 "MMCONFIG %pR conflicts with "
+				 "%s %pR\n",
+				 &cfg->res, tmp->name, tmp);
+		} else if (pci_mmcfg_arch_map(cfg)) {
+			dev_warn(dev, "fail to map MMCONFIG %pR.\n",
+				 &cfg->res);
+		} else {
+			list_add_sorted(cfg);
+			dev_info(dev, "MMCONFIG at %pR (base %#lx)\n",
+				 &cfg->res, (unsigned long)addr);
+			cfg = NULL;
+			rc = 0;
+		}
+	}
+
+	if (cfg) {
+		if (cfg->res.parent)
+			release_resource(&cfg->res);
+		kfree(cfg);
+	}
+
+	mutex_unlock(&pci_mmcfg_lock);
+
+	return rc;
+}
+
+/* Delete MMCFG information for host bridges */
+int pci_mmconfig_delete(u16 seg, u8 start, u8 end)
+{
+	struct pci_mmcfg_region *cfg;
+
+	mutex_lock(&pci_mmcfg_lock);
+	list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
+		if (cfg->segment == seg && cfg->start_bus == start &&
+		    cfg->end_bus == end) {
+			list_del_rcu(&cfg->list);
+			synchronize_rcu();
+			pci_mmcfg_arch_unmap(cfg);
+			if (cfg->res.parent)
+				release_resource(&cfg->res);
+			mutex_unlock(&pci_mmcfg_lock);
+			kfree(cfg);
+			return 0;
+		}
+	mutex_unlock(&pci_mmcfg_lock);
+
+	return -ENOENT;
+}
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v9 06/11] PCI/ACPI: provide MCFG address for PCI host bridges
  2012-06-21  9:36 [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Jiang Liu
                   ` (4 preceding siblings ...)
  2012-06-21  9:36 ` [PATCH v9 05/11] x86/PCI: add pci_mmconfig_insert()/delete() for PCI root bridge hotplug Jiang Liu
@ 2012-06-21  9:36 ` Jiang Liu
  2012-06-21  9:36 ` [PATCH v9 07/11] x86/PCI: update MMCFG information when hot-plugging " Jiang Liu
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Jiang Liu @ 2012-06-21  9:36 UTC (permalink / raw)
  To: Bjorn Helgaas, Yinghai Lu, Taku Izumi, Kenji Kaneshige, Don Dutile
  Cc: Jiang Liu, Yijing Wang, Keping Chen, linux-pci, Jiang Liu

This patch provide MCFG address for PCI host bridges, which will
be used to support host bridge hotplug.  It gets MCFG address
by evaluating _CBA method if available, or by scanning the ACPI
MCFG table.

Signed-off-by: Jiang Liu <liuj97@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/acpi/pci_root.c  |    2 ++
 drivers/pci/pci-acpi.c   |   14 ++++++++++++++
 include/acpi/acnames.h   |    1 +
 include/acpi/acpi_bus.h  |    1 +
 include/linux/pci-acpi.h |    1 +
 5 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 7aff631..ec54014 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -505,6 +505,8 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
 	strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
 	device->driver_data = root;
 
+	root->mcfg_addr = acpi_pci_root_get_mcfg_addr(device->handle);
+
 	/*
 	 * All supported architectures that use ACPI have support for
 	 * PCI domains, so we indicate this in _OSC support capabilities.
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 61e2fef..87f4c50 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -162,6 +162,20 @@ acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
 	return remove_pm_notifier(dev, pci_acpi_wake_dev);
 }
 
+phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle)
+{
+	acpi_status status = AE_NOT_EXIST;
+	unsigned long long mcfg_addr;
+
+	if (handle)
+		status = acpi_evaluate_integer(handle, METHOD_NAME__CBA,
+					       NULL, &mcfg_addr);
+	if (ACPI_FAILURE(status))
+		return 0;
+
+	return (phys_addr_t)mcfg_addr;
+}
+
 /*
  * _SxD returns the D-state with the highest power
  * (lowest D-state number) supported in the S-state "x".
diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h
index 38f5088..b177f97 100644
--- a/include/acpi/acnames.h
+++ b/include/acpi/acnames.h
@@ -62,6 +62,7 @@
 #define METHOD_NAME__AEI        "_AEI"
 #define METHOD_NAME__PRW        "_PRW"
 #define METHOD_NAME__SRS        "_SRS"
+#define METHOD_NAME__CBA        "_CBA"
 
 /* Method names - these methods must appear at the namespace root */
 
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 9e6e1c6..4579740 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -401,6 +401,7 @@ struct acpi_pci_root {
 
 	u32 osc_support_set;	/* _OSC state of support bits */
 	u32 osc_control_set;	/* _OSC state of control bits */
+	phys_addr_t mcfg_addr;
 };
 
 /* helper */
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index 4462350..248fba2 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -17,6 +17,7 @@ extern acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev);
 extern acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev,
 					     struct pci_dev *pci_dev);
 extern acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev);
+extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle);
 
 static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
 {
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v9 07/11] x86/PCI: update MMCFG information when hot-plugging PCI host bridges
  2012-06-21  9:36 [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Jiang Liu
                   ` (5 preceding siblings ...)
  2012-06-21  9:36 ` [PATCH v9 06/11] PCI/ACPI: provide MCFG address for PCI host bridges Jiang Liu
@ 2012-06-21  9:36 ` Jiang Liu
  2012-06-21 22:11   ` Yinghai Lu
  2012-06-21  9:37 ` [PATCH v9 08/11] x86/PCI: simplify pci_mmcfg_late_insert_resources() Jiang Liu
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 18+ messages in thread
From: Jiang Liu @ 2012-06-21  9:36 UTC (permalink / raw)
  To: Bjorn Helgaas, Yinghai Lu, Taku Izumi, Kenji Kaneshige, Don Dutile
  Cc: Jiang Liu, Yijing Wang, Keping Chen, linux-pci, Jiang Liu

This patch enhances x86 arch specific code to update MMCFG information
when PCI host bridge hotplug event happens.

Signed-off-by: Jiang Liu <liuj97@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/x86/include/asm/pci_x86.h |    1 +
 arch/x86/pci/acpi.c            |   71 ++++++++++++++++++++++++++++++++++++++++
 arch/x86/pci/mmconfig_32.c     |    2 +-
 arch/x86/pci/mmconfig_64.c     |    2 +-
 4 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index af5018f..b2652e9 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -100,6 +100,7 @@ struct pci_raw_ops {
 extern const struct pci_raw_ops *raw_pci_ops;
 extern const struct pci_raw_ops *raw_pci_ext_ops;
 
+extern const struct pci_raw_ops pci_mmcfg;
 extern const struct pci_raw_ops pci_direct_conf1;
 extern bool port_cf9_safe;
 
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 2bb885a..f701179 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -4,6 +4,7 @@
 #include <linux/irq.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
+#include <linux/pci-acpi.h>
 #include <asm/numa.h>
 #include <asm/pci_x86.h>
 
@@ -13,6 +14,12 @@ struct pci_root_info {
 	unsigned int res_num;
 	struct resource *res;
 	struct pci_sysdata sd;
+#ifdef	CONFIG_PCI_MMCONFIG
+	bool mcfg_added;
+	u16 segment;
+	u8 start_bus;
+	u8 end_bus;
+#endif
 };
 
 static bool pci_use_crs = true;
@@ -119,6 +126,61 @@ void __init pci_acpi_crs_quirks(void)
 	       pci_use_crs ? "nocrs" : "use_crs");
 }
 
+static int __devinit setup_mcfg_map(struct pci_root_info *info,
+				    u16 seg, u8 start, u8 end,
+				    phys_addr_t addr)
+{
+#ifdef	CONFIG_PCI_MMCONFIG
+	int result;
+	struct device *dev = &info->bridge->dev;
+
+	info->start_bus = start;
+	info->end_bus = end;
+	info->mcfg_added = false;
+
+	/* return success if MMCFG is not in use */
+	if (raw_pci_ext_ops && raw_pci_ext_ops != &pci_mmcfg)
+		return 0;
+
+	if (!(pci_probe & PCI_PROBE_MMCONF)) {
+		/* still could use raw_pci_ops for devices on segment 0 */
+		if (seg)
+			dev_warn(dev,
+				 "MMCONFIG is disabled, can't access extended "
+				 "configuration space under this bridge.\n");
+		return 0;
+	}
+
+	result = pci_mmconfig_insert(dev, seg, start, end, addr);
+	if (result == 0) {
+		/* enable MMCFG if it hasn't been enabled yet */
+		if (raw_pci_ext_ops == NULL)
+			raw_pci_ext_ops = &pci_mmcfg;
+		info->mcfg_added = true;
+	} else if (result != -EEXIST && addr) {
+		/*
+		 * Failure in adding MMCFG information is not fatal,
+		 * just can't access [extended] configuration space of
+		 * devices under this host bridge.
+		 */
+		dev_warn(dev, "fail to add MMCONFIG information.\n");
+	}
+#endif
+
+	return 0;
+}
+
+static void teardown_mcfg_map(struct pci_root_info *info)
+{
+#ifdef	CONFIG_PCI_MMCONFIG
+	if (info->mcfg_added) {
+		pci_mmconfig_delete(info->segment, info->start_bus,
+				    info->end_bus);
+		info->mcfg_added = false;
+	}
+#endif
+}
+
 static acpi_status
 resource_to_addr(struct acpi_resource *resource,
 			struct acpi_resource_address64 *addr)
@@ -331,8 +393,11 @@ static void __release_pci_root_info(struct pci_root_info *info)
 
 	free_pci_root_info_res(info);
 
+	teardown_mcfg_map(info);
+
 	kfree(info);
 }
+
 static void release_pci_root_info(struct pci_host_bridge *bridge)
 {
 	struct pci_root_info *info = bridge->release_data;
@@ -438,6 +503,12 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
 			x86_pci_root_bus_resources(busnum, &resources);
 		}
 
+		if (root->mcfg_addr)
+			setup_mcfg_map(info, root->segment,
+				       (u8) root->secondary.start,
+				       (u8) root->secondary.end,
+				       root->mcfg_addr);
+
 		bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd,
 					  &resources);
 		if (bus) {
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
index a22785d..db63ac2 100644
--- a/arch/x86/pci/mmconfig_32.c
+++ b/arch/x86/pci/mmconfig_32.c
@@ -126,7 +126,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 	return 0;
 }
 
-static const struct pci_raw_ops pci_mmcfg = {
+const struct pci_raw_ops pci_mmcfg = {
 	.read =		pci_mmcfg_read,
 	.write =	pci_mmcfg_write,
 };
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
index 4e05779..34c08dd 100644
--- a/arch/x86/pci/mmconfig_64.c
+++ b/arch/x86/pci/mmconfig_64.c
@@ -90,7 +90,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 	return 0;
 }
 
-static const struct pci_raw_ops pci_mmcfg = {
+const struct pci_raw_ops pci_mmcfg = {
 	.read =		pci_mmcfg_read,
 	.write =	pci_mmcfg_write,
 };
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v9 08/11] x86/PCI: simplify pci_mmcfg_late_insert_resources()
  2012-06-21  9:36 [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Jiang Liu
                   ` (6 preceding siblings ...)
  2012-06-21  9:36 ` [PATCH v9 07/11] x86/PCI: update MMCFG information when hot-plugging " Jiang Liu
@ 2012-06-21  9:37 ` Jiang Liu
  2012-06-21  9:37 ` [PATCH v9 09/11] x86/PCI: get rid of redundant log messages Jiang Liu
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Jiang Liu @ 2012-06-21  9:37 UTC (permalink / raw)
  To: Bjorn Helgaas, Yinghai Lu, Taku Izumi, Kenji Kaneshige, Don Dutile
  Cc: Jiang Liu, Yijing Wang, Keping Chen, linux-pci, Jiang Liu

Reduce redundant code to simplify pci_mmcfg_late_insert_resources().

Signed-off-by: Jiang Liu <liuj97@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/x86/pci/mmconfig-shared.c |   34 ++++++++--------------------------
 1 files changed, 8 insertions(+), 26 deletions(-)

diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 19fc42b..332fabd 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -26,7 +26,6 @@
 #define PREFIX "PCI: "
 
 /* Indicate if the mmcfg resources have been placed into the resource table. */
-static int __initdata pci_mmcfg_resources_inserted;
 static bool pci_mmcfg_running_state;
 static bool pci_mmcfg_arch_init_failed;
 static DEFINE_MUTEX(pci_mmcfg_lock);
@@ -373,18 +372,6 @@ static int __init pci_mmcfg_check_hostbridge(void)
 	return !list_empty(&pci_mmcfg_list);
 }
 
-static void __init pci_mmcfg_insert_resources(void)
-{
-	struct pci_mmcfg_region *cfg;
-
-	list_for_each_entry(cfg, &pci_mmcfg_list, list)
-		if (!cfg->res.parent)
-			insert_resource(&iomem_resource, &cfg->res);
-
-	/* Mark that the resources have been inserted. */
-	pci_mmcfg_resources_inserted = 1;
-}
-
 static acpi_status __devinit check_mcfg_resource(struct acpi_resource *res,
 						 void *data)
 {
@@ -668,11 +655,7 @@ static void __init __pci_mmcfg_init(int early)
 	if (pci_mmcfg_arch_init())
 		pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
 	else {
-		/*
-		 * Signal not to attempt to insert mmcfg resources because
-		 * the architecture mmcfg setup could not initialize.
-		 */
-		pci_mmcfg_resources_inserted = 1;
+		free_all_mmcfg();
 		pci_mmcfg_arch_init_failed = true;
 	}
 }
@@ -689,15 +672,12 @@ void __init pci_mmcfg_late_init(void)
 
 static int __init pci_mmcfg_late_insert_resources(void)
 {
+	struct pci_mmcfg_region *cfg;
+
 	pci_mmcfg_running_state = true;
 
-	/*
-	 * If resources are already inserted or we are not using MMCONFIG,
-	 * don't insert the resources.
-	 */
-	if ((pci_mmcfg_resources_inserted == 1) ||
-	    (pci_probe & PCI_PROBE_MMCONF) == 0 ||
-	    list_empty(&pci_mmcfg_list))
+	/* If we are not using MMCONFIG, don't insert the resources. */
+	if ((pci_probe & PCI_PROBE_MMCONF) == 0)
 		return 1;
 
 	/*
@@ -705,7 +685,9 @@ static int __init pci_mmcfg_late_insert_resources(void)
 	 * marked so it won't cause request errors when __request_region is
 	 * called.
 	 */
-	pci_mmcfg_insert_resources();
+	list_for_each_entry(cfg, &pci_mmcfg_list, list)
+		if (!cfg->res.parent)
+			insert_resource(&iomem_resource, &cfg->res);
 
 	return 0;
 }
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v9 09/11] x86/PCI: get rid of redundant log messages
  2012-06-21  9:36 [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Jiang Liu
                   ` (7 preceding siblings ...)
  2012-06-21  9:37 ` [PATCH v9 08/11] x86/PCI: simplify pci_mmcfg_late_insert_resources() Jiang Liu
@ 2012-06-21  9:37 ` Jiang Liu
  2012-06-21  9:37 ` [PATCH v9 10/11] x86, PCI: refine __pci_mmcfg_init() for better code readability Jiang Liu
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Jiang Liu @ 2012-06-21  9:37 UTC (permalink / raw)
  To: Bjorn Helgaas, Yinghai Lu, Taku Izumi, Kenji Kaneshige, Don Dutile
  Cc: Jiang Liu, Yijing Wang, Keping Chen, linux-pci, Jiang Liu

For each resource of a PCI host bridge, the arch code and PCI
code log following messages:
"pci_root PNP0A08:00: host bridge window [io 0x0000-0x03af]",
"pci_bus 0000:00: root bus resource [io  0x0000-0x03af]"

Signed-off-by: Jiang Liu <liuj97@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/x86/pci/acpi.c |    7 -------
 1 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index f701179..5f778ae 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -295,13 +295,6 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
 	}
 
 	info->res_num++;
-	if (addr.translation_offset)
-		dev_info(&info->bridge->dev, "host bridge window %pR "
-			 "(PCI address [%#llx-%#llx])\n",
-			 res, res->start - addr.translation_offset,
-			 res->end - addr.translation_offset);
-	else
-		dev_info(&info->bridge->dev, "host bridge window %pR\n", res);
 
 	return AE_OK;
 }
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v9 10/11] x86, PCI: refine __pci_mmcfg_init() for better code readability
  2012-06-21  9:36 [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Jiang Liu
                   ` (8 preceding siblings ...)
  2012-06-21  9:37 ` [PATCH v9 09/11] x86/PCI: get rid of redundant log messages Jiang Liu
@ 2012-06-21  9:37 ` Jiang Liu
  2012-06-21  9:37 ` [PATCH v9 11/11] ACPI: mark acpi_sfi_table_parse() as __init Jiang Liu
  2012-06-21 20:06 ` [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Bjorn Helgaas
  11 siblings, 0 replies; 18+ messages in thread
From: Jiang Liu @ 2012-06-21  9:37 UTC (permalink / raw)
  To: Bjorn Helgaas, Yinghai Lu, Taku Izumi, Kenji Kaneshige, Don Dutile
  Cc: Jiang Liu, Yijing Wang, Keping Chen, linux-pci, Jiang Liu

Refine __pci_mmcfg_init() for better code readability.

Signed-off-by: Jiang Liu <liuj97@gmail.com>
---
 arch/x86/pci/mmconfig-shared.c |   46 ++++++++++++++++++---------------------
 1 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 332fabd..ffe72b9 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -544,8 +544,6 @@ static void __init pci_mmcfg_reject_broken(int early)
 	}
 }
 
-static int __initdata known_bridge;
-
 static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
 					struct acpi_mcfg_allocation *cfg)
 {
@@ -617,28 +615,7 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header)
 
 static void __init __pci_mmcfg_init(int early)
 {
-	/* MMCONFIG disabled */
-	if ((pci_probe & PCI_PROBE_MMCONF) == 0)
-		return;
-
-	/* MMCONFIG already enabled */
-	if (!early && !(pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF))
-		return;
-
-	/* for late to exit */
-	if (known_bridge)
-		return;
-
-	if (early) {
-		if (pci_mmcfg_check_hostbridge())
-			known_bridge = 1;
-	}
-
-	if (!known_bridge)
-		acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
-
 	pci_mmcfg_reject_broken(early);
-
 	if (list_empty(&pci_mmcfg_list))
 		return;
 
@@ -660,14 +637,33 @@ static void __init __pci_mmcfg_init(int early)
 	}
 }
 
+static int __initdata known_bridge;
+
 void __init pci_mmcfg_early_init(void)
 {
-	__pci_mmcfg_init(1);
+	if (pci_probe & PCI_PROBE_MMCONF) {
+		if (pci_mmcfg_check_hostbridge())
+			known_bridge = 1;
+		else
+			acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
+		__pci_mmcfg_init(1);
+	}
 }
 
 void __init pci_mmcfg_late_init(void)
 {
-	__pci_mmcfg_init(0);
+	/* MMCONFIG disabled */
+	if ((pci_probe & PCI_PROBE_MMCONF) == 0)
+		return;
+
+	if (known_bridge)
+		return;
+
+	/* MMCONFIG hasn't been enabled yet, try again */
+	if (pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF) {
+		acpi_sfi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
+		__pci_mmcfg_init(0);
+	}
 }
 
 static int __init pci_mmcfg_late_insert_resources(void)
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v9 11/11] ACPI: mark acpi_sfi_table_parse() as __init
  2012-06-21  9:36 [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Jiang Liu
                   ` (9 preceding siblings ...)
  2012-06-21  9:37 ` [PATCH v9 10/11] x86, PCI: refine __pci_mmcfg_init() for better code readability Jiang Liu
@ 2012-06-21  9:37 ` Jiang Liu
  2012-06-21 20:06 ` [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Bjorn Helgaas
  11 siblings, 0 replies; 18+ messages in thread
From: Jiang Liu @ 2012-06-21  9:37 UTC (permalink / raw)
  To: Bjorn Helgaas, Yinghai Lu, Taku Izumi, Kenji Kaneshige, Don Dutile
  Cc: Jiang Liu, Yijing Wang, Keping Chen, linux-pci, Jiang Liu

Mark function acpi_sfi_table_parse() as __init to avoid warning messages:
WARNING: vmlinux.o(.text+0x4cd2d2): Section mismatch in reference from the
function acpi_sfi_table_parse.clone.0() to the function

Function acpi_sfi_table_parse() calls acpi_table_parse() and pci_parse_mcfg(),
which are both marked as __init. And currently acpi_sfi_table_parse() is used
by MMCONFIG to scan MCFG table at boot time only, so it's safe to mark
acpi_sfi_table_parse() as __init.

.init.text:pci_parse_mcfg()

Signed-off-by: Jiang Liu <liuj97@gmail.com>
---
 include/linux/sfi_acpi.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/sfi_acpi.h b/include/linux/sfi_acpi.h
index c4a5a8c..631af63 100644
--- a/include/linux/sfi_acpi.h
+++ b/include/linux/sfi_acpi.h
@@ -66,7 +66,7 @@ extern int sfi_acpi_table_parse(char *signature, char *oem_id,
 				char *oem_table_id,
 				int (*handler)(struct acpi_table_header *));
 
-static inline int acpi_sfi_table_parse(char *signature,
+static inline int __init acpi_sfi_table_parse(char *signature,
 				int (*handler)(struct acpi_table_header *))
 {
 	if (!acpi_table_parse(signature, handler))
@@ -83,7 +83,7 @@ static inline int sfi_acpi_table_parse(char *signature, char *oem_id,
 	return -1;
 }
 
-static inline int acpi_sfi_table_parse(char *signature,
+static inline int __init acpi_sfi_table_parse(char *signature,
 				int (*handler)(struct acpi_table_header *))
 {
 	return acpi_table_parse(signature, handler);
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges
  2012-06-21  9:36 [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Jiang Liu
                   ` (10 preceding siblings ...)
  2012-06-21  9:37 ` [PATCH v9 11/11] ACPI: mark acpi_sfi_table_parse() as __init Jiang Liu
@ 2012-06-21 20:06 ` Bjorn Helgaas
  2012-06-21 21:20   ` Yinghai Lu
  2012-06-21 22:22   ` Yinghai Lu
  11 siblings, 2 replies; 18+ messages in thread
From: Bjorn Helgaas @ 2012-06-21 20:06 UTC (permalink / raw)
  To: Jiang Liu
  Cc: Yinghai Lu, Taku Izumi, Kenji Kaneshige, Don Dutile, Yijing Wang,
	Keping Chen, linux-pci

On Thu, Jun 21, 2012 at 3:36 AM, Jiang Liu <jiang.liu@huawei.com> wrote:
> This patchset enhance pci_root driver to update MMCFG information when
> hot-plugging PCI root bridges. It applies to
> git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci/next

Yinghai, I'm hoping you will review these.  I'd like to get them into
-next soon and you're the main person paying attention to them :)  If
you can't, let me know and I'll give it a go myself.

Bjorn

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges
  2012-06-21 20:06 ` [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Bjorn Helgaas
@ 2012-06-21 21:20   ` Yinghai Lu
  2012-06-21 22:22   ` Yinghai Lu
  1 sibling, 0 replies; 18+ messages in thread
From: Yinghai Lu @ 2012-06-21 21:20 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Jiang Liu, Taku Izumi, Kenji Kaneshige, Don Dutile, Yijing Wang,
	Keping Chen, linux-pci

On Thu, Jun 21, 2012 at 1:06 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> On Thu, Jun 21, 2012 at 3:36 AM, Jiang Liu <jiang.liu@huawei.com> wrote:
>> This patchset enhance pci_root driver to update MMCFG information when
>> hot-plugging PCI root bridges. It applies to
>> git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci/next
>
> Yinghai, I'm hoping you will review these.  I'd like to get them into
> -next soon and you're the main person paying attention to them :)  If
> you can't, let me know and I'll give it a go myself.

ok, I will check them today.

Yinghai

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v9 04/11] x86/PCI: introduce pci_mmcfg_arch_map()/pci_mmcfg_arch_unmap()
  2012-06-21  9:36 ` [PATCH v9 04/11] x86/PCI: introduce pci_mmcfg_arch_map()/pci_mmcfg_arch_unmap() Jiang Liu
@ 2012-06-21 21:25   ` Yinghai Lu
  0 siblings, 0 replies; 18+ messages in thread
From: Yinghai Lu @ 2012-06-21 21:25 UTC (permalink / raw)
  To: Jiang Liu
  Cc: Bjorn Helgaas, Taku Izumi, Kenji Kaneshige, Don Dutile,
	Yijing Wang, Keping Chen, linux-pci, Jiang Liu

On Thu, Jun 21, 2012 at 2:36 AM, Jiang Liu <jiang.liu@huawei.com> wrote:
> Introduce pci_mmcfg_arch_map()/pci_mmcfg_arch_unmap(), which will be used
> when supporting PCI root bridge hotplug.
>
> Signed-off-by: Jiang Liu <liuj97@gmail.com>
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
> ---
>  arch/x86/include/asm/pci_x86.h |    2 ++
>  arch/x86/pci/mmconfig_32.c     |   15 +++++++++++++++
>  arch/x86/pci/mmconfig_64.c     |   22 +++++++++++++++++++++-
>  3 files changed, 38 insertions(+), 1 deletions(-)
>
> diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
> index b3a5317..df898ce 100644
> --- a/arch/x86/include/asm/pci_x86.h
> +++ b/arch/x86/include/asm/pci_x86.h
> @@ -135,6 +135,8 @@ struct pci_mmcfg_region {
>
>  extern int __init pci_mmcfg_arch_init(void);
>  extern void __init pci_mmcfg_arch_free(void);
> +extern int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
> +extern void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg);
>  extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
>
>  extern struct list_head pci_mmcfg_list;
> diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
> index 5dad04a..a22785d 100644
> --- a/arch/x86/pci/mmconfig_32.c
> +++ b/arch/x86/pci/mmconfig_32.c
> @@ -141,3 +141,18 @@ int __init pci_mmcfg_arch_init(void)
>  void __init pci_mmcfg_arch_free(void)
>  {
>  }
> +
> +int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
> +{
> +       return 0;
> +}
> +
> +void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg)
> +{
> +       unsigned long flags;
> +
> +       /* Invalidate the cached mmcfg map entry. */
> +       raw_spin_lock_irqsave(&pci_config_lock, flags);
> +       mmcfg_last_accessed_device = 0;
> +       raw_spin_unlock_irqrestore(&pci_config_lock, flags);
> +}
> diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
> index acc48c5..4e05779 100644
> --- a/arch/x86/pci/mmconfig_64.c
> +++ b/arch/x86/pci/mmconfig_64.c
> @@ -95,7 +95,7 @@ static const struct pci_raw_ops pci_mmcfg = {
>        .write =        pci_mmcfg_write,
>  };
>
> -static void __iomem * __init mcfg_ioremap(struct pci_mmcfg_region *cfg)
> +static void __iomem * __devinit mcfg_ioremap(struct pci_mmcfg_region *cfg)
>  {
>        void __iomem *addr;
>        u64 start, size;
> @@ -138,3 +138,23 @@ void __init pci_mmcfg_arch_free(void)
>                }
>        }
>  }
> +
> +int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
> +{
> +       cfg->virt = mcfg_ioremap(cfg);
> +       if (!cfg->virt) {
> +               printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n",
> +                      &cfg->res);
> +               return -ENOMEM;
> +       }
> +
> +       return 0;
> +}
> +
> +void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg)
> +{
> +       if (cfg && cfg->virt) {
> +               iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus));
> +               cfg->virt = NULL;
> +       }
> +}

Can you merge pci_mmcfg_arch_map/unmap with pci_mmcfg_arch_init/free?

at least init/free could call map/unmap.

Thanks

Yinghai

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v9 05/11] x86/PCI: add pci_mmconfig_insert()/delete() for PCI root bridge hotplug
  2012-06-21  9:36 ` [PATCH v9 05/11] x86/PCI: add pci_mmconfig_insert()/delete() for PCI root bridge hotplug Jiang Liu
@ 2012-06-21 21:44   ` Yinghai Lu
  0 siblings, 0 replies; 18+ messages in thread
From: Yinghai Lu @ 2012-06-21 21:44 UTC (permalink / raw)
  To: Jiang Liu
  Cc: Bjorn Helgaas, Taku Izumi, Kenji Kaneshige, Don Dutile,
	Yijing Wang, Keping Chen, linux-pci, Jiang Liu

On Thu, Jun 21, 2012 at 2:36 AM, Jiang Liu <jiang.liu@huawei.com> wrote:
> Introduce pci_mmconfig_insert()/pci_mmconfig_delete(), which will be used
> to update MMCFG information when supporting PCI root bridge hotplug.
>
> [bhelgaas: KERN_INFO, not KERN_ERR, for missing ACPI PNP0C01/02 reservation]
> Signed-off-by: Jiang Liu <liuj97@gmail.com>
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
> ---
>  arch/x86/include/asm/pci_x86.h |    4 +
>  arch/x86/pci/mmconfig-shared.c |  213 ++++++++++++++++++++++++++++++++--------
>  2 files changed, 177 insertions(+), 40 deletions(-)

this one is way to big, you may chop it to two or three.

>
> diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
> index df898ce..af5018f 100644
> --- a/arch/x86/include/asm/pci_x86.h
> +++ b/arch/x86/include/asm/pci_x86.h
> @@ -137,6 +137,10 @@ extern int __init pci_mmcfg_arch_init(void);
>  extern void __init pci_mmcfg_arch_free(void);
>  extern int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
>  extern void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg);
> +extern int __devinit pci_mmconfig_insert(struct device *dev,
> +                                        u16 seg, u8 start,
> +                                        u8 end, phys_addr_t addr);
> +extern int pci_mmconfig_delete(u16 seg, u8 start, u8 end);
>  extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
>
>  extern struct list_head pci_mmcfg_list;
> diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
> index 0ac97d5..19fc42b 100644
> --- a/arch/x86/pci/mmconfig-shared.c
> +++ b/arch/x86/pci/mmconfig-shared.c
> @@ -27,6 +27,8 @@
>
>  /* Indicate if the mmcfg resources have been placed into the resource table. */
>  static int __initdata pci_mmcfg_resources_inserted;
> +static bool pci_mmcfg_running_state;
> +static bool pci_mmcfg_arch_init_failed;
>  static DEFINE_MUTEX(pci_mmcfg_lock);
>
>  LIST_HEAD(pci_mmcfg_list);
> @@ -91,10 +93,6 @@ static __devinit struct pci_mmcfg_region *pci_mmconfig_alloc(int segment,
>                 "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end);
>        res->name = new->name;
>
> -       printk(KERN_INFO PREFIX "MMCONFIG for domain %04x [bus %02x-%02x] at "
> -              "%pR (base %#lx)\n", segment, start, end, &new->res,
> -              (unsigned long) addr);
> -
>        return new;
>  }
>
> @@ -108,6 +106,11 @@ static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
>                mutex_lock(&pci_mmcfg_lock);
>                list_add_sorted(new);
>                mutex_unlock(&pci_mmcfg_lock);
> +
> +               printk(KERN_INFO PREFIX
> +                      "MMCONFIG for domain %04x [bus %02x-%02x] at %pR "
> +                      "(base %#lx)\n",
> +                      segment, start, end, &new->res, (unsigned long)addr);
>        }
>
>        return new;
> @@ -375,14 +378,15 @@ static void __init pci_mmcfg_insert_resources(void)
>        struct pci_mmcfg_region *cfg;
>
>        list_for_each_entry(cfg, &pci_mmcfg_list, list)
> -               insert_resource(&iomem_resource, &cfg->res);
> +               if (!cfg->res.parent)
> +                       insert_resource(&iomem_resource, &cfg->res);
>
>        /* Mark that the resources have been inserted. */
>        pci_mmcfg_resources_inserted = 1;
>  }
>
> -static acpi_status __init check_mcfg_resource(struct acpi_resource *res,
> -                                             void *data)
> +static acpi_status __devinit check_mcfg_resource(struct acpi_resource *res,
> +                                                void *data)
>  {
>        struct resource *mcfg_res = data;
>        struct acpi_resource_address64 address;
> @@ -418,8 +422,8 @@ static acpi_status __init check_mcfg_resource(struct acpi_resource *res,
>        return AE_OK;
>  }
>
> -static acpi_status __init find_mboard_resource(acpi_handle handle, u32 lvl,
> -               void *context, void **rv)
> +static acpi_status __devinit find_mboard_resource(acpi_handle handle, u32 lvl,
> +                                                 void *context, void **rv)
>  {
>        struct resource *mcfg_res = context;
>
> @@ -432,7 +436,7 @@ static acpi_status __init find_mboard_resource(acpi_handle handle, u32 lvl,
>        return AE_OK;
>  }
>
> -static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used)
> +static int __devinit is_acpi_reserved(u64 start, u64 end, unsigned not_used)
>  {
>        struct resource mcfg_res;
>
> @@ -451,13 +455,15 @@ static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used)
>
>  typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type);
>
> -static int __init is_mmconf_reserved(check_reserved_t is_reserved,
> -                                   struct pci_mmcfg_region *cfg, int with_e820)
> +static int __ref is_mmconf_reserved(check_reserved_t is_reserved,
> +                                   struct pci_mmcfg_region *cfg,
> +                                   struct device *dev, int with_e820)
>  {
>        u64 addr = cfg->res.start;
>        u64 size = resource_size(&cfg->res);
>        u64 old_size = size;
> -       int valid = 0, num_buses;
> +       int num_buses;
> +       char *method = with_e820 ? "E820" : "ACPI motherboard resources";
>
>        while (!is_reserved(addr, addr + size, E820_RESERVED)) {
>                size >>= 1;
> @@ -465,49 +471,75 @@ static int __init is_mmconf_reserved(check_reserved_t is_reserved,
>                        break;
>        }
>
> -       if (size >= (16UL<<20) || size == old_size) {
> -               printk(KERN_INFO PREFIX "MMCONFIG at %pR reserved in %s\n",
> -                      &cfg->res,
> -                      with_e820 ? "E820" : "ACPI motherboard resources");
> -               valid = 1;
> -
> -               if (old_size != size) {
> -                       /* update end_bus */
> -                       cfg->end_bus = cfg->start_bus + ((size>>20) - 1);
> -                       num_buses = cfg->end_bus - cfg->start_bus + 1;
> -                       cfg->res.end = cfg->res.start +
> -                           PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
> -                       snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN,
> -                                "PCI MMCONFIG %04x [bus %02x-%02x]",
> -                                cfg->segment, cfg->start_bus, cfg->end_bus);
> +       if (size < (16UL<<20) && size != old_size)
> +               return 0;
> +
> +       if (dev)
> +               dev_info(dev, "MMCONFIG at %pR reserved in %s\n",
> +                        &cfg->res, method);
> +       else
> +               printk(KERN_INFO PREFIX
> +                      "MMCONFIG at %pR reserved in %s\n",
> +                      &cfg->res, method);
> +
> +       if (old_size != size) {
> +               /* update end_bus */
> +               cfg->end_bus = cfg->start_bus + ((size>>20) - 1);
> +               num_buses = cfg->end_bus - cfg->start_bus + 1;
> +               cfg->res.end = cfg->res.start +
> +                   PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
> +               snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN,
> +                        "PCI MMCONFIG %04x [bus %02x-%02x]",
> +                        cfg->segment, cfg->start_bus, cfg->end_bus);
> +
> +               if (dev)
> +                       dev_info(dev,
> +                               "MMCONFIG "
> +                               "at %pR (base %#lx) (size reduced!)\n",
> +                               &cfg->res, (unsigned long) cfg->address);
> +               else
>                        printk(KERN_INFO PREFIX
> -                              "MMCONFIG for %04x [bus%02x-%02x] "
> -                              "at %pR (base %#lx) (size reduced!)\n",
> -                              cfg->segment, cfg->start_bus, cfg->end_bus,
> -                              &cfg->res, (unsigned long) cfg->address);
> -               }
> +                               "MMCONFIG for %04x [bus%02x-%02x] "
> +                               "at %pR (base %#lx) (size reduced!)\n",
> +                               cfg->segment, cfg->start_bus, cfg->end_bus,
> +                               &cfg->res, (unsigned long) cfg->address);
>        }
>
> -       return valid;
> +       return 1;
>  }
>
> -static int __devinit pci_mmcfg_check_reserved(struct pci_mmcfg_region *cfg,
> -                                             int early)
> +static int __ref pci_mmcfg_check_reserved(struct device *dev,
> +                 struct pci_mmcfg_region *cfg, int early)
>  {
>        if (!early && !acpi_disabled) {
> -               if (is_mmconf_reserved(is_acpi_reserved, cfg, 0))
> +               if (is_mmconf_reserved(is_acpi_reserved, cfg, dev, 0))
>                        return 1;
> +
> +               if (dev)
> +                       dev_info(dev, FW_INFO
> +                                "MMCONFIG at %pR not reserved in "
> +                                "ACPI motherboard resources\n",
> +                                &cfg->res);
>                else
> -                       printk(KERN_ERR FW_BUG PREFIX
> +                       printk(KERN_INFO FW_INFO PREFIX
>                               "MMCONFIG at %pR not reserved in "
>                               "ACPI motherboard resources\n",
>                               &cfg->res);
>        }
>
> +       /*
> +        * e820_all_mapped() is marked as __init.
> +        * All entries from ACPI MCFG table have been checked at boot time.
> +        * For MCFG information constructed from hotpluggable host bridge's
> +        * _CBA method, just assume it's reserved.
> +        */
> +       if (pci_mmcfg_running_state)
> +               return 1;
> +
>        /* Don't try to do this check unless configuration
>           type 1 is available. how about type 2 ?*/
>        if (raw_pci_ops)
> -               return is_mmconf_reserved(e820_all_mapped, cfg, 1);
> +               return is_mmconf_reserved(e820_all_mapped, cfg, dev, 1);
>
>        return 0;
>  }
> @@ -517,7 +549,7 @@ static void __init pci_mmcfg_reject_broken(int early)
>        struct pci_mmcfg_region *cfg;
>
>        list_for_each_entry(cfg, &pci_mmcfg_list, list) {
> -               if (pci_mmcfg_check_reserved(cfg, early) == 0) {
> +               if (pci_mmcfg_check_reserved(NULL, cfg, early) == 0) {
>                        printk(KERN_INFO PREFIX "not using MMCONFIG\n");
>                        free_all_mmcfg();
>                        return;
> @@ -641,6 +673,7 @@ static void __init __pci_mmcfg_init(int early)
>                 * the architecture mmcfg setup could not initialize.
>                 */
>                pci_mmcfg_resources_inserted = 1;
> +               pci_mmcfg_arch_init_failed = true;
>        }
>  }
>
> @@ -656,6 +689,8 @@ void __init pci_mmcfg_late_init(void)
>
>  static int __init pci_mmcfg_late_insert_resources(void)
>  {
> +       pci_mmcfg_running_state = true;
> +
>        /*
>         * If resources are already inserted or we are not using MMCONFIG,
>         * don't insert the resources.
> @@ -681,3 +716,101 @@ static int __init pci_mmcfg_late_insert_resources(void)
>  * with other system resources.
>  */
>  late_initcall(pci_mmcfg_late_insert_resources);
> +
> +/* Add MMCFG information for host bridges */
> +int __devinit pci_mmconfig_insert(struct device *dev,
> +                                 u16 seg, u8 start, u8 end,
> +                                 phys_addr_t addr)
> +{
> +       int rc;
> +       struct resource *tmp = NULL;
> +       struct pci_mmcfg_region *cfg;
> +
> +       if (!(pci_probe & PCI_PROBE_MMCONF) || pci_mmcfg_arch_init_failed)
> +               return -ENODEV;
> +
> +       if (start > end)
> +               return -EINVAL;
> +
> +       mutex_lock(&pci_mmcfg_lock);
> +       cfg = pci_mmconfig_lookup(seg, start);
> +       if (cfg) {
> +               if (cfg->end_bus < end)
> +                       dev_info(dev, FW_INFO
> +                                "MMCONFIG for "
> +                                "domain %04x [bus %02x-%02x] "
> +                                "only partially covers this bridge\n",
> +                                 cfg->segment, cfg->start_bus, cfg->end_bus);
> +               mutex_unlock(&pci_mmcfg_lock);
> +               return -EEXIST;
> +       }
> +
> +       if (!addr) {
> +               mutex_unlock(&pci_mmcfg_lock);
> +               return -EINVAL;
> +       }
> +
> +       rc = -EBUSY;
> +       cfg = pci_mmconfig_alloc(seg, start, end, addr);
> +       if (cfg == NULL) {
> +               dev_warn(dev, "fail to add MMCONFIG (out of memory)\n");
> +               rc = -ENOMEM;
> +       } else if (!pci_mmcfg_check_reserved(dev, cfg, 0)) {
> +               dev_warn(dev, FW_BUG "MMCONFIG %pR isn't reserved\n",
> +                        &cfg->res);
> +       } else {
> +               /* Insert resource if it's not in boot stage */
> +               if (pci_mmcfg_running_state)
> +                       tmp = insert_resource_conflict(&iomem_resource,
> +                                                      &cfg->res);
> +
> +               if (tmp) {
> +                       dev_warn(dev,
> +                                "MMCONFIG %pR conflicts with "
> +                                "%s %pR\n",
> +                                &cfg->res, tmp->name, tmp);
> +               } else if (pci_mmcfg_arch_map(cfg)) {
> +                       dev_warn(dev, "fail to map MMCONFIG %pR.\n",
> +                                &cfg->res);
> +               } else {
> +                       list_add_sorted(cfg);
> +                       dev_info(dev, "MMCONFIG at %pR (base %#lx)\n",
> +                                &cfg->res, (unsigned long)addr);
> +                       cfg = NULL;
> +                       rc = 0;
> +               }
> +       }
> +
> +       if (cfg) {
> +               if (cfg->res.parent)
> +                       release_resource(&cfg->res);
> +               kfree(cfg);
> +       }
> +
> +       mutex_unlock(&pci_mmcfg_lock);
> +
> +       return rc;
> +}
> +
> +/* Delete MMCFG information for host bridges */
> +int pci_mmconfig_delete(u16 seg, u8 start, u8 end)
> +{
> +       struct pci_mmcfg_region *cfg;
> +
> +       mutex_lock(&pci_mmcfg_lock);
> +       list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
> +               if (cfg->segment == seg && cfg->start_bus == start &&
> +                   cfg->end_bus == end) {
> +                       list_del_rcu(&cfg->list);
> +                       synchronize_rcu();
> +                       pci_mmcfg_arch_unmap(cfg);
> +                       if (cfg->res.parent)
> +                               release_resource(&cfg->res);
> +                       mutex_unlock(&pci_mmcfg_lock);
> +                       kfree(cfg);
> +                       return 0;
> +               }
> +       mutex_unlock(&pci_mmcfg_lock);
> +
> +       return -ENOENT;
> +}
> --
> 1.7.1
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v9 07/11] x86/PCI: update MMCFG information when hot-plugging PCI host bridges
  2012-06-21  9:36 ` [PATCH v9 07/11] x86/PCI: update MMCFG information when hot-plugging " Jiang Liu
@ 2012-06-21 22:11   ` Yinghai Lu
  0 siblings, 0 replies; 18+ messages in thread
From: Yinghai Lu @ 2012-06-21 22:11 UTC (permalink / raw)
  To: Jiang Liu
  Cc: Bjorn Helgaas, Taku Izumi, Kenji Kaneshige, Don Dutile,
	Yijing Wang, Keping Chen, linux-pci, Jiang Liu

On Thu, Jun 21, 2012 at 2:36 AM, Jiang Liu <jiang.liu@huawei.com> wrote:
> This patch enhances x86 arch specific code to update MMCFG information
> when PCI host bridge hotplug event happens.
>
> Signed-off-by: Jiang Liu <liuj97@gmail.com>
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
> ---
>  arch/x86/include/asm/pci_x86.h |    1 +
>  arch/x86/pci/acpi.c            |   71 ++++++++++++++++++++++++++++++++++++++++
>  arch/x86/pci/mmconfig_32.c     |    2 +-
>  arch/x86/pci/mmconfig_64.c     |    2 +-
>  4 files changed, 74 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
> index af5018f..b2652e9 100644
> --- a/arch/x86/include/asm/pci_x86.h
> +++ b/arch/x86/include/asm/pci_x86.h
> @@ -100,6 +100,7 @@ struct pci_raw_ops {
>  extern const struct pci_raw_ops *raw_pci_ops;
>  extern const struct pci_raw_ops *raw_pci_ext_ops;
>
> +extern const struct pci_raw_ops pci_mmcfg;
>  extern const struct pci_raw_ops pci_direct_conf1;
>  extern bool port_cf9_safe;
>
> diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
> index 2bb885a..f701179 100644
> --- a/arch/x86/pci/acpi.c
> +++ b/arch/x86/pci/acpi.c
> @@ -4,6 +4,7 @@
>  #include <linux/irq.h>
>  #include <linux/dmi.h>
>  #include <linux/slab.h>
> +#include <linux/pci-acpi.h>
>  #include <asm/numa.h>
>  #include <asm/pci_x86.h>
>
> @@ -13,6 +14,12 @@ struct pci_root_info {
>        unsigned int res_num;
>        struct resource *res;
>        struct pci_sysdata sd;
> +#ifdef CONFIG_PCI_MMCONFIG
> +       bool mcfg_added;
> +       u16 segment;
> +       u8 start_bus;
> +       u8 end_bus;
> +#endif
>  };
>
>  static bool pci_use_crs = true;
> @@ -119,6 +126,61 @@ void __init pci_acpi_crs_quirks(void)
>               pci_use_crs ? "nocrs" : "use_crs");
>  }
>
> +static int __devinit setup_mcfg_map(struct pci_root_info *info,
> +                                   u16 seg, u8 start, u8 end,
> +                                   phys_addr_t addr)
> +{
> +#ifdef CONFIG_PCI_MMCONFIG
> +       int result;
> +       struct device *dev = &info->bridge->dev;
> +
> +       info->start_bus = start;
> +       info->end_bus = end;
> +       info->mcfg_added = false;
> +
> +       /* return success if MMCFG is not in use */
> +       if (raw_pci_ext_ops && raw_pci_ext_ops != &pci_mmcfg)
> +               return 0;
> +
> +       if (!(pci_probe & PCI_PROBE_MMCONF)) {
> +               /* still could use raw_pci_ops for devices on segment 0 */
> +               if (seg)
> +                       dev_warn(dev,
> +                                "MMCONFIG is disabled, can't access extended "
> +                                "configuration space under this bridge.\n");
> +               return 0;
> +       }
that mean, user disable mmconf checking.
if it is with pci segment other than 0, that bridge can not be used
without MMCFG.

so should be:
> +               if (seg)
> +                        return -EXXX;
> +               dev_warn(dev,
> +                            "MMCONFIG is disabled, can't access extended "
> +                           "configuration space under this bridge.\n");
> +               return 0;

> +
> +       result = pci_mmconfig_insert(dev, seg, start, end, addr);
> +       if (result == 0) {
> +               /* enable MMCFG if it hasn't been enabled yet */
> +               if (raw_pci_ext_ops == NULL)
> +                       raw_pci_ext_ops = &pci_mmcfg;
> +               info->mcfg_added = true;
> +       } else if (result != -EEXIST && addr) {
> +               /*
> +                * Failure in adding MMCFG information is not fatal,
> +                * just can't access [extended] configuration space of
> +                * devices under this host bridge.
> +                */
> +               dev_warn(dev, "fail to add MMCONFIG information.\n");

need to check if seg is other 0.

> +       }
> +#endif
> +
> +       return 0;
> +}
> +
> +static void teardown_mcfg_map(struct pci_root_info *info)
> +{
> +#ifdef CONFIG_PCI_MMCONFIG
> +       if (info->mcfg_added) {
> +               pci_mmconfig_delete(info->segment, info->start_bus,
> +                                   info->end_bus);
> +               info->mcfg_added = false;
> +       }
> +#endif
> +}
> +
>  static acpi_status
>  resource_to_addr(struct acpi_resource *resource,
>                        struct acpi_resource_address64 *addr)
> @@ -331,8 +393,11 @@ static void __release_pci_root_info(struct pci_root_info *info)
>
>        free_pci_root_info_res(info);
>
> +       teardown_mcfg_map(info);
> +
>        kfree(info);
>  }
> +
>  static void release_pci_root_info(struct pci_host_bridge *bridge)
>  {
>        struct pci_root_info *info = bridge->release_data;
> @@ -438,6 +503,12 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
>                        x86_pci_root_bus_resources(busnum, &resources);
>                }
>
> +               if (root->mcfg_addr)
> +                       setup_mcfg_map(info, root->segment,
> +                                      (u8) root->secondary.start,
> +                                      (u8) root->secondary.end,
> +                                      root->mcfg_addr);
> +

should check setup_mcfg_map return there. should skip the host bridge
if can not add MCFG for non 0 pci segment.

>                bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd,
>                                          &resources);
>                if (bus) {
> diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
> index a22785d..db63ac2 100644
> --- a/arch/x86/pci/mmconfig_32.c
> +++ b/arch/x86/pci/mmconfig_32.c
> @@ -126,7 +126,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
>        return 0;
>  }
>
> -static const struct pci_raw_ops pci_mmcfg = {
> +const struct pci_raw_ops pci_mmcfg = {
>        .read =         pci_mmcfg_read,
>        .write =        pci_mmcfg_write,
>  };
> diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
> index 4e05779..34c08dd 100644
> --- a/arch/x86/pci/mmconfig_64.c
> +++ b/arch/x86/pci/mmconfig_64.c
> @@ -90,7 +90,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
>        return 0;
>  }
>
> -static const struct pci_raw_ops pci_mmcfg = {
> +const struct pci_raw_ops pci_mmcfg = {
>        .read =         pci_mmcfg_read,
>        .write =        pci_mmcfg_write,
>  };
> --
> 1.7.1
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges
  2012-06-21 20:06 ` [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Bjorn Helgaas
  2012-06-21 21:20   ` Yinghai Lu
@ 2012-06-21 22:22   ` Yinghai Lu
  1 sibling, 0 replies; 18+ messages in thread
From: Yinghai Lu @ 2012-06-21 22:22 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Jiang Liu, Taku Izumi, Kenji Kaneshige, Don Dutile, Yijing Wang,
	Keping Chen, linux-pci

On Thu, Jun 21, 2012 at 1:06 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> On Thu, Jun 21, 2012 at 3:36 AM, Jiang Liu <jiang.liu@huawei.com> wrote:
>> This patchset enhance pci_root driver to update MMCFG information when
>> hot-plugging PCI root bridges. It applies to
>> git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci/next
>
> Yinghai, I'm hoping you will review these.  I'd like to get them into
> -next soon and you're the main person paying attention to them :)  If
> you can't, let me know and I'll give it a go myself.

Hi, Bjorn,

Only

[PATCH v9 07/11] x86/PCI: update MMCFG information when hot-plugging
PCI host bridges

still have problem with non-0 segment handling on failing path.

So assume us time tonight, and china time friday daytime, Jiang could fix it.

otherwise I will fix it tomorrow morning, then you could merge tomorrow noon.

Thanks

Yinghai

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2012-06-21 22:22 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-21  9:36 [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Jiang Liu
2012-06-21  9:36 ` [PATCH v9 01/11] x86/PCI: split out pci_mmcfg_check_reserved() for code reuse Jiang Liu
2012-06-21  9:36 ` [PATCH v9 02/11] x86/PCI: split out pci_mmconfig_alloc() " Jiang Liu
2012-06-21  9:36 ` [PATCH v9 03/11] x86/PCI: use RCU list to protect mmconfig list Jiang Liu
2012-06-21  9:36 ` [PATCH v9 04/11] x86/PCI: introduce pci_mmcfg_arch_map()/pci_mmcfg_arch_unmap() Jiang Liu
2012-06-21 21:25   ` Yinghai Lu
2012-06-21  9:36 ` [PATCH v9 05/11] x86/PCI: add pci_mmconfig_insert()/delete() for PCI root bridge hotplug Jiang Liu
2012-06-21 21:44   ` Yinghai Lu
2012-06-21  9:36 ` [PATCH v9 06/11] PCI/ACPI: provide MCFG address for PCI host bridges Jiang Liu
2012-06-21  9:36 ` [PATCH v9 07/11] x86/PCI: update MMCFG information when hot-plugging " Jiang Liu
2012-06-21 22:11   ` Yinghai Lu
2012-06-21  9:37 ` [PATCH v9 08/11] x86/PCI: simplify pci_mmcfg_late_insert_resources() Jiang Liu
2012-06-21  9:37 ` [PATCH v9 09/11] x86/PCI: get rid of redundant log messages Jiang Liu
2012-06-21  9:37 ` [PATCH v9 10/11] x86, PCI: refine __pci_mmcfg_init() for better code readability Jiang Liu
2012-06-21  9:37 ` [PATCH v9 11/11] ACPI: mark acpi_sfi_table_parse() as __init Jiang Liu
2012-06-21 20:06 ` [PATCH v9 00/11] PCI, x86: update MMCFG information when hot-plugging PCI host bridges Bjorn Helgaas
2012-06-21 21:20   ` Yinghai Lu
2012-06-21 22:22   ` Yinghai Lu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.