[PATCH 3/4] MMCONFIG: fix unreachable_devices()

Previous thread: Understanding cpufreq? by James Pearson on Tuesday, January 9, 2007 - 1:53 pm. (2 messages)

Next thread: [PATCH 1/3] Handle 32 bit PerfMon Counter writes cleanly in x86_64 nmi_watchdog by Venkatesh Pallipadi on Tuesday, January 9, 2007 - 2:50 pm. (1 message)
To: Andrew Morton <akpm@...>
Cc: <linux-kernel@...>, Arjan van de Ven <arjan@...>, Andi Kleen <ak@...>
Date: Tuesday, January 9, 2007 - 2:59 pm

This just cleans up.

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

arch/i386/pci/mmconfig-shared.c | 50 +++++++++++++++++-----------------------
arch/i386/pci/mmconfig.c | 13 +++-------
arch/i386/pci/pci.h | 4 ++-
arch/x86_64/pci/mmconfig.c | 16 +++---------
4 files changed, 33 insertions(+), 50 deletions(-)

diff -puN arch/i386/pci/mmconfig-shared.c~pci-mmconfig-cleanup arch/i386/pci/mmconfig-shared.c
--- linux-2.6/arch/i386/pci/mmconfig-shared.c~pci-mmconfig-cleanup 2007-01-06 00:15:02.000000000 +0900
+++ linux-2.6-hirofumi/arch/i386/pci/mmconfig-shared.c 2007-01-06 00:43:36.000000000 +0900
@@ -22,10 +22,6 @@
#define MMCONFIG_APER_MIN (2 * 1024*1024)
#define MMCONFIG_APER_MAX (256 * 1024*1024)

-/* Verify the first 16 busses. We assume that systems with more busses
- get MCFG right. */
-#define PCI_MMCFG_MAX_CHECK_BUS 16
-
DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);

/* K8 systems have some devices (typically in the builtin northbridge)
@@ -34,29 +30,30 @@ DECLARE_BITMAP(pci_mmcfg_fallback_slots,
and assigning suitable _SEGs, but this isn't implemented in some BIOS.
Instead try to discover all devices on bus 0 that are unreachable using MM
and fallback for them. */
-static __init void unreachable_devices(void)
+static void __init unreachable_devices(void)
{
- int i, k;
+ int i, bus;
/* Use the max bus number from ACPI here? */
- for (k = 0; k < PCI_MMCFG_MAX_CHECK_BUS; k++) {
+ for (bus = 0; bus < PCI_MMCFG_MAX_CHECK_BUS; bus++) {
for (i = 0; i < 32; i++) {
+ unsigned int devfn = PCI_DEVFN(i, 0);
u32 val1, val2;

- pci_conf1_read(0, k, PCI_DEVFN(i,0), 0, 4, &val1);
+ pci_conf1_read(0, bus, devfn, 0, 4, &val1);
if (val1 == 0xffffffff)
continue;

- raw_pci_ops->read(0, k, PCI_DEVFN(i, 0), 0, 4, &val2);
+ raw_pci_ops->read(0, bus, devfn, 0, 4, &val2);
if (val1 != val2) {
- set_bit(i + 32*k,...

To: OGAWA Hirofumi <hirofumi@...>
Cc: Andrew Morton <akpm@...>, <linux-kernel@...>, Arjan van de Ven <arjan@...>
Date: Tuesday, January 9, 2007 - 8:21 pm

The mmconfig code has completely changed in -mm/x86_64 soon. Can you resubmit against
that please?

-Andi
-

To: Andi Kleen <ak@...>
Cc: Andrew Morton <akpm@...>, <linux-kernel@...>, Arjan van de Ven <arjan@...>
Date: Tuesday, January 9, 2007 - 8:41 pm

No problem. I'll do for next -mm.
--
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
-

To: Andrew Morton <akpm@...>
Cc: <linux-kernel@...>, Arjan van de Ven <arjan@...>, Andi Kleen <ak@...>
Date: Tuesday, January 9, 2007 - 3:00 pm

This rejects a broken MCFG tables on Asus etc.
Arjan and Andi suggest this.

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

arch/i386/pci/mmconfig-shared.c | 24 +++++++++++++++++++++++-
arch/i386/pci/mmconfig.c | 9 ---------
arch/x86_64/pci/mmconfig.c | 9 ---------
3 files changed, 23 insertions(+), 19 deletions(-)

diff -puN arch/i386/pci/mmconfig-shared.c~pci-mmconfig-reject-mcfg_broken arch/i386/pci/mmconfig-shared.c
--- linux-2.6/arch/i386/pci/mmconfig-shared.c~pci-mmconfig-reject-mcfg_broken 2007-01-06 00:43:43.000000000 +0900
+++ linux-2.6-hirofumi/arch/i386/pci/mmconfig-shared.c 2007-01-06 00:43:43.000000000 +0900
@@ -184,6 +184,26 @@ static void __init pci_mmcfg_insert_reso
}
}

+static void __init pci_mmcfg_reject_broken(void)
+{
+ struct acpi_table_mcfg_config *cfg = &pci_mmcfg_config[0];
+
+ /*
+ * Handle more broken MCFG tables on Asus etc.
+ * They only contain a single entry for bus 0-0.
+ */
+ if (pci_mmcfg_config_num == 1 &&
+ cfg->pci_segment_group_number == 0 &&
+ (cfg->start_bus_number | cfg->end_bus_number) == 0) {
+ kfree(pci_mmcfg_config);
+ pci_mmcfg_config = NULL;
+ pci_mmcfg_config_num = 0;
+
+ printk(KERN_ERR "PCI: start and end of bus number is 0. "
+ "Rejected as broken MCFG.");
+ }
+}
+
void __init pci_mmcfg_init(int type)
{
int known_bridge = 0;
@@ -194,8 +214,10 @@ void __init pci_mmcfg_init(int type)
if (type == 1 && pci_mmcfg_check_hostbridge())
known_bridge = 1;

- if (!known_bridge)
+ if (!known_bridge) {
acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
+ pci_mmcfg_reject_broken();
+ }

if ((pci_mmcfg_config_num == 0) ||
(pci_mmcfg_config == NULL) ||
diff -puN arch/i386/pci/mmconfig.c~pci-mmconfig-reject-mcfg_broken arch/i386/pci/mmconfig.c
--- linux-2.6/arch/i386/pci/mmconfig.c~pci-mmconfig-reject-mcfg_broken 2007-01-06 00:43:43.000000000 +0900
+++ linux-2.6-hirofumi/arch/i386/pci/mmconfig.c 20...

To: Andrew Morton <akpm@...>
Cc: <linux-kernel@...>, Arjan van de Ven <arjan@...>, Andi Kleen <ak@...>
Date: Tuesday, January 9, 2007 - 3:00 pm

Currently, unreachable_devices() compares value of mmconfig and value
of conf1. But it doesn't check the device is reachable or not.

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

arch/i386/pci/mmconfig-shared.c | 12 +++++++-----
arch/i386/pci/mmconfig.c | 6 ++++++
arch/i386/pci/pci.h | 2 ++
arch/x86_64/pci/mmconfig.c | 6 ++++++
4 files changed, 21 insertions(+), 5 deletions(-)

diff -puN arch/i386/pci/mmconfig-shared.c~pci-mmconfig-fix-unreachable_devices arch/i386/pci/mmconfig-shared.c
--- linux-2.6/arch/i386/pci/mmconfig-shared.c~pci-mmconfig-fix-unreachable_devices 2007-01-06 00:47:39.000000000 +0900
+++ linux-2.6-hirofumi/arch/i386/pci/mmconfig-shared.c 2007-01-06 04:47:21.000000000 +0900
@@ -43,12 +43,14 @@ static void __init unreachable_devices(v
if (val1 == 0xffffffff)
continue;

- raw_pci_ops->read(0, bus, devfn, 0, 4, &val2);
- if (val1 != val2) {
- set_bit(i + 32 * bus, pci_mmcfg_fallback_slots);
- printk(KERN_NOTICE "PCI: No mmconfig possible"
- " on device %02x:%02x\n", bus, i);
+ if (pci_mmcfg_arch_reachable(0, bus, devfn)) {
+ raw_pci_ops->read(0, bus, devfn, 0, 4, &val2);
+ if (val1 == val2)
+ continue;
}
+ set_bit(i + 32 * bus, pci_mmcfg_fallback_slots);
+ printk(KERN_NOTICE "PCI: No mmconfig possible on device"
+ " %02x:%02x\n", bus, i);
}
}
}
diff -puN arch/i386/pci/mmconfig.c~pci-mmconfig-fix-unreachable_devices arch/i386/pci/mmconfig.c
--- linux-2.6/arch/i386/pci/mmconfig.c~pci-mmconfig-fix-unreachable_devices 2007-01-06 00:47:39.000000000 +0900
+++ linux-2.6-hirofumi/arch/i386/pci/mmconfig.c 2007-01-06 04:47:14.000000000 +0900
@@ -136,6 +136,12 @@ static struct pci_raw_ops pci_mmcfg = {
.write = pci_mmcfg_write,
};

+int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus,
+ unsigned int devfn)
+{
+ return get_base_addr(seg, bus, devfn) != 0;
+}
+
int __init pci_mmcfg_arch_ini...

To: Andrew Morton <akpm@...>
Cc: <linux-kernel@...>, Arjan van de Ven <arjan@...>, Andi Kleen <ak@...>
Date: Tuesday, January 9, 2007 - 3:01 pm

Current mmconfig has some problems of remapped range. The base
address always corresponds to bus number 0, but currently we are
assuming it corresponds to start bus number.

This patch fixes the above problems.

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

arch/x86_64/pci/mmconfig.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)

diff -puN arch/x86_64/pci/mmconfig.c~pci-mmconfig-ioremap-range-fix-mm arch/x86_64/pci/mmconfig.c
--- linux-2.6/arch/x86_64/pci/mmconfig.c~pci-mmconfig-ioremap-range-fix-mm 2007-01-06 01:04:47.000000000 +0900
+++ linux-2.6-hirofumi/arch/x86_64/pci/mmconfig.c 2007-01-06 01:05:35.000000000 +0900
@@ -118,6 +118,20 @@ int __init pci_mmcfg_arch_reachable(unsi
return pci_dev_base(seg, bus, devfn) != NULL;
}

+static void __iomem * __init mcfg_ioremap(struct acpi_table_mcfg_config *cfg)
+{
+ void __iomem *addr;
+ u32 size;
+
+ size = (cfg->end_bus_number + 1) << 20;
+ addr = ioremap_nocache(cfg->base_address, size);
+ if (addr) {
+ printk(KERN_INFO "PCI: Using MMCONFIG at %x - %x\n",
+ cfg->base_address, cfg->base_address + size - 1);
+ }
+ return addr;
+}
+
int __init pci_mmcfg_arch_init(void)
{
int i;
@@ -128,19 +142,14 @@ int __init pci_mmcfg_arch_init(void)
}

for (i = 0; i < pci_mmcfg_config_num; ++i) {
- u32 size = (pci_mmcfg_config[0].end_bus_number - pci_mmcfg_config[0].start_bus_number + 1) << 20;
pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
- pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address,
- size);
+ pci_mmcfg_virt[i].virt = mcfg_ioremap(&pci_mmcfg_config[i]);
if (!pci_mmcfg_virt[i].virt) {
printk(KERN_ERR "PCI: Cannot map mmconfig aperture for "
"segment %d\n",
pci_mmcfg_config[i].pci_segment_group_number);
return 0;
}
- printk(KERN_INFO "PCI: Using MMCONFIG at %x-%x\n",
- pci_mmcfg_config[i].base_address,
- pci_mmcfg_config[i].b...

Previous thread: Understanding cpufreq? by James Pearson on Tuesday, January 9, 2007 - 1:53 pm. (2 messages)

Next thread: [PATCH 1/3] Handle 32 bit PerfMon Counter writes cleanly in x86_64 nmi_watchdog by Venkatesh Pallipadi on Tuesday, January 9, 2007 - 2:50 pm. (1 message)