[PATCH] ia64: use i386 dmi_scan.c
authorMatt Domsch <Matt_Domsch@dell.com>
Sun, 26 Mar 2006 09:37:03 +0000 (01:37 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Sun, 26 Mar 2006 16:56:54 +0000 (08:56 -0800)
Enable DMI table parsing on ia64.

Andi Kleen has a patch in his x86_64 tree which enables the use of i386
dmi_scan.c on x86_64.  dmi_scan.c functions are being used by the
drivers/char/ipmi/ipmi_si_intf.c driver for autodetecting the ports or
memory spaces where the IPMI controllers may be found.

This patch adds equivalent changes for ia64 as to what is in the x86_64
tree.  In addition, I reworked the DMI detection, such that on EFI-capable
systems, it uses the efi.smbios pointer to find the table, rather than
brute-force searching from 0xF0000.  On non-EFI systems, it continues the
brute-force search.

My test system, an Intel S870BN4 'Tiger4', aka Dell PowerEdge 7250, with
latest BIOS, does not list the IPMI controller in the ACPI namespace, nor
does it have an ACPI SPMI table.  Also note, currently shipping Dell x8xx
EM64T servers don't have these either, so DMI is the only method for
obtaining the address of the IPMI controller.

Signed-off-by: Matt Domsch <Matt_Domsch@dell.com>
Acked-by: "Luck, Tony" <tony.luck@intel.com>
Cc: Andi Kleen <ak@muc.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/i386/kernel/dmi_scan.c
arch/ia64/Kconfig
arch/ia64/kernel/Makefile
arch/ia64/kernel/setup.c
include/asm-ia64/dmi.h [new file with mode: 0644]
include/asm-ia64/io.h

index ebc8dc116c430425dd0051734d5db552f8bde4df..bfecbd46f22a171d558431b2396db458162c20b8 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/dmi.h>
+#include <linux/efi.h>
 #include <linux/bootmem.h>
 #include <linux/slab.h>
 #include <asm/dmi.h>
@@ -185,47 +186,72 @@ static void __init dmi_decode(struct dmi_header *dm)
        }
 }
 
-void __init dmi_scan_machine(void)
+static int __init dmi_present(char __iomem *p)
 {
        u8 buf[15];
-       char __iomem *p, *q;
+       memcpy_fromio(buf, p, 15);
+       if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) {
+               u16 num = (buf[13] << 8) | buf[12];
+               u16 len = (buf[7] << 8) | buf[6];
+               u32 base = (buf[11] << 24) | (buf[10] << 16) |
+                       (buf[9] << 8) | buf[8];
 
-       /*
-        * no iounmap() for that ioremap(); it would be a no-op, but it's
-        * so early in setup that sucker gets confused into doing what
-        * it shouldn't if we actually call it.
-        */
-       p = ioremap(0xF0000, 0x10000);
-       if (p == NULL)
-               goto out;
-
-       for (q = p; q < p + 0x10000; q += 16) {
-               memcpy_fromio(buf, q, 15);
-               if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) {
-                       u16 num = (buf[13] << 8) | buf[12];
-                       u16 len = (buf[7] << 8) | buf[6];
-                       u32 base = (buf[11] << 24) | (buf[10] << 16) |
-                                  (buf[9] << 8) | buf[8];
-
-                       /*
-                        * DMI version 0.0 means that the real version is taken from
-                        * the SMBIOS version, which we don't know at this point.
-                        */
-                       if (buf[14] != 0)
-                               printk(KERN_INFO "DMI %d.%d present.\n",
-                                       buf[14] >> 4, buf[14] & 0xF);
-                       else
-                               printk(KERN_INFO "DMI present.\n");
+               /*
+                * DMI version 0.0 means that the real version is taken from
+                * the SMBIOS version, which we don't know at this point.
+                */
+               if (buf[14] != 0)
+                       printk(KERN_INFO "DMI %d.%d present.\n",
+                              buf[14] >> 4, buf[14] & 0xF);
+               else
+                       printk(KERN_INFO "DMI present.\n");
+               if (dmi_table(base,len, num, dmi_decode) == 0)
+                       return 0;
+       }
+       return 1;
+}
 
-                       if (dmi_table(base,len, num, dmi_decode) == 0)
+void __init dmi_scan_machine(void)
+{
+       char __iomem *p, *q;
+       int rc;
+
+       if (efi_enabled) {
+               if (!efi.smbios)
+                       goto out;
+
+               /* This is called as a core_initcall() because it isn't
+                * needed during early boot.  This also means we can
+                * iounmap the space when we're done with it.
+               */
+               p = dmi_ioremap((unsigned long)efi.smbios, 0x10000);
+               if (p == NULL)
+                       goto out;
+
+               rc = dmi_present(p + 0x10); /* offset of _DMI_ string */
+               iounmap(p);
+               if (!rc)
+                       return;
+       }
+       else {
+               /*
+                * no iounmap() for that ioremap(); it would be a no-op, but
+                * it's so early in setup that sucker gets confused into doing
+                * what it shouldn't if we actually call it.
+                */
+               p = dmi_ioremap(0xF0000, 0x10000);
+               if (p == NULL)
+                       goto out;
+
+               for (q = p; q < p + 0x10000; q += 16) {
+                       rc = dmi_present(q);
+                       if (!rc)
                                return;
                }
        }
-
-out:   printk(KERN_INFO "DMI not present or invalid.\n");
+ out:  printk(KERN_INFO "DMI not present or invalid.\n");
 }
 
-
 /**
  *     dmi_check_system - check system DMI data
  *     @list: array of dmi_system_id structures to match against
index 10b6b9e7716baae92d2d5fe2b852d965c86b2e07..d790a6d9026160987dbc72e52474aead08ce78f0 100644 (file)
@@ -42,6 +42,10 @@ config TIME_INTERPOLATION
        bool
        default y
 
+config DMI
+       bool
+       default y
+
 config EFI
        bool
        default y
index 09a0dbc17fb687bfc6e79ba6377e012246846180..59e871dae7423454edcadb968b9e0a54ca9111e1 100644 (file)
@@ -7,7 +7,7 @@ extra-y := head.o init_task.o vmlinux.lds
 obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o      \
         irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o          \
         salinfo.o semaphore.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \
-        unwind.o mca.o mca_asm.o topology.o
+        unwind.o mca.o mca_asm.o topology.o dmi_scan.o
 
 obj-$(CONFIG_IA64_BRL_EMU)     += brl_emu.o
 obj-$(CONFIG_IA64_GENERIC)     += acpi-ext.o
@@ -30,6 +30,7 @@ obj-$(CONFIG_IA64_MCA_RECOVERY)       += mca_recovery.o
 obj-$(CONFIG_KPROBES)          += kprobes.o jprobes.o
 obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR)  += uncached.o
 mca_recovery-y                 += mca_drv.o mca_drv_asm.o
+dmi_scan-y                     += ../../i386/kernel/dmi_scan.o
 
 # The gate DSO image is built using a special linker script.
 targets += gate.so gate-syms.o
index eb388e271b2b5a73746f4454347882c04aa0c8cc..a4421a66ea5beea6501755409eb14132cecf2b43 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/string.h>
 #include <linux/threads.h>
 #include <linux/tty.h>
+#include <linux/dmi.h>
 #include <linux/serial.h>
 #include <linux/serial_core.h>
 #include <linux/efi.h>
@@ -887,3 +888,10 @@ check_bugs (void)
        ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles,
                               (unsigned long) __end___mckinley_e9_bundles);
 }
+
+static int __init run_dmi_scan(void)
+{
+       dmi_scan_machine();
+       return 0;
+}
+core_initcall(run_dmi_scan);
diff --git a/include/asm-ia64/dmi.h b/include/asm-ia64/dmi.h
new file mode 100644 (file)
index 0000000..f3efaa2
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _ASM_DMI_H
+#define _ASM_DMI_H 1
+
+#include <asm/io.h>
+
+#endif
index b64fdb9854941cfcd816f003b99d3e66235dc34d..0d9bcc36f2a992c2628665a86486b539c3c3ef80 100644 (file)
@@ -435,6 +435,11 @@ iounmap (volatile void __iomem *addr)
 
 #define ioremap_nocache(o,s)   ioremap(o,s)
 
+/* Use normal IO mappings for DMI */
+#define dmi_ioremap ioremap
+#define dmi_iounmap(x,l) iounmap(x)
+#define dmi_alloc(l) kmalloc(l, GFP_ATOMIC)
+
 # ifdef __KERNEL__
 
 /*