Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=036fff4cf732c4d69f99a2915924935705744b00
Commit:     036fff4cf732c4d69f99a2915924935705744b00
Parent:     8fa5913d54f3b1e09948e6a0db34da887e05ff1f
Author:     Gary Hade <[EMAIL PROTECTED]>
AuthorDate: Wed Oct 3 15:56:14 2007 -0700
Committer:  Greg Kroah-Hartman <[EMAIL PROTECTED]>
CommitDate: Fri Oct 12 15:03:18 2007 -0700

    PCI: skip ISA ioresource alignment on some systems
    
    Skip ISA ioresource alignment on some systems
    
    To conserve limited PCI i/o resource on some IBM multi-node systems, the
    BIOS allocates (via _CRS) and expects the kernel to use addresses in
    ranges currently excluded by pcibios_align_resource() [i386/pci/i386.c].
    This change allows the kernel to use the currently excluded address
    ranges on the IBM x3800, x3850, and x3950.
    
    Signed-off-by: Gary Hade <[EMAIL PROTECTED]>
    Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>
---
 arch/x86/pci/acpi.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 arch/x86/pci/i386.c |   13 +++++++++++++
 arch/x86/pci/pci.h  |    1 +
 drivers/pci/probe.c |    4 ++--
 4 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index bc8a44b..1dd6f3f 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -2,15 +2,57 @@
 #include <linux/acpi.h>
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/dmi.h>
 #include <asm/numa.h>
 #include "pci.h"
 
+static int __devinit can_skip_ioresource_align(struct dmi_system_id *d)
+{
+       pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
+       printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", 
d->ident);
+       return 0;
+}
+
+static struct dmi_system_id acpi_pciprobe_dmi_table[] = {
+/*
+ * Systems where PCI IO resource ISA alignment can be skipped
+ * when the ISA enable bit in the bridge control is not set
+ */
+       {
+               .callback = can_skip_ioresource_align,
+               .ident = "IBM System x3800",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
+               },
+       },
+       {
+               .callback = can_skip_ioresource_align,
+               .ident = "IBM System x3850",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "x3850"),
+               },
+       },
+       {
+               .callback = can_skip_ioresource_align,
+               .ident = "IBM System x3950",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "x3950"),
+               },
+       },
+       {}
+};
+
 struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int 
domain, int busnum)
 {
        struct pci_bus *bus;
        struct pci_sysdata *sd;
        int pxm;
 
+       dmi_check_system(acpi_pciprobe_dmi_table);
+
        /* Allocate per-root-bus (not per bus) arch-specific data.
         * TODO: leak; this memory is never freed.
         * It's arguable whether it's worth the trouble to care.
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index bcd2f94..055187b 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -33,6 +33,15 @@
 
 #include "pci.h"
 
+static int
+skip_isa_ioresource_align(struct pci_dev *dev) {
+
+       if ((pci_probe & PCI_CAN_SKIP_ISA_ALIGN) &&
+           (dev->bus->bridge_ctl & PCI_BRIDGE_CTL_NO_ISA))
+               return 1;
+       return 0;
+}
+
 /*
  * We need to avoid collisions with `mirrored' VGA ports
  * and other strange ISA hardware, so we always want the
@@ -50,9 +59,13 @@ void
 pcibios_align_resource(void *data, struct resource *res,
                        resource_size_t size, resource_size_t align)
 {
+       struct pci_dev *dev = data;
+
        if (res->flags & IORESOURCE_IO) {
                resource_size_t start = res->start;
 
+               if (skip_isa_ioresource_align(dev))
+                       return;
                if (start & 0x300) {
                        start = (start + 0x3ff) & ~0x3ff;
                        res->start = start;
diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h
index 8c66f27..057f335 100644
--- a/arch/x86/pci/pci.h
+++ b/arch/x86/pci/pci.h
@@ -26,6 +26,7 @@
 #define PCI_ASSIGN_ROMS                0x1000
 #define PCI_BIOS_IRQ_SCAN      0x2000
 #define PCI_ASSIGN_ALL_BUSSES  0x4000
+#define PCI_CAN_SKIP_ISA_ALIGN 0x8000
 
 extern unsigned int pci_probe;
 extern unsigned long pirq_table_addr;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 40e571d..59d6c30 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -544,7 +544,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * 
dev, int max, int pass
                        goto out;
                child->primary = buses & 0xFF;
                child->subordinate = (buses >> 16) & 0xFF;
-               child->bridge_ctl = bctl;
+               child->bridge_ctl = bctl ^ PCI_BRIDGE_CTL_NO_ISA;
 
                cmax = pci_scan_child_bus(child);
                if (cmax > max)
@@ -597,7 +597,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * 
dev, int max, int pass
                pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses);
 
                if (!is_cardbus) {
-                       child->bridge_ctl = bctl | PCI_BRIDGE_CTL_NO_ISA;
+                       child->bridge_ctl = bctl ^ PCI_BRIDGE_CTL_NO_ISA;
                        /*
                         * Adjust subordinate busnr in parent buses.
                         * We do this before scanning for children because
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to