Commit 3ed3bce846abc7ef460104b461cac793e41afe5e

Authored by Matt Domsch
Committed by Linus Torvalds
1 parent 10dbe196a8

[PATCH] ia64: use i386 dmi_scan.c

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>

Showing 6 changed files with 83 additions and 33 deletions Side-by-side Diff

arch/i386/kernel/dmi_scan.c
... ... @@ -3,6 +3,7 @@
3 3 #include <linux/init.h>
4 4 #include <linux/module.h>
5 5 #include <linux/dmi.h>
  6 +#include <linux/efi.h>
6 7 #include <linux/bootmem.h>
7 8 #include <linux/slab.h>
8 9 #include <asm/dmi.h>
9 10  
10 11  
11 12  
12 13  
13 14  
14 15  
15 16  
16 17  
... ... @@ -185,46 +186,71 @@
185 186 }
186 187 }
187 188  
188   -void __init dmi_scan_machine(void)
  189 +static int __init dmi_present(char __iomem *p)
189 190 {
190 191 u8 buf[15];
  192 + memcpy_fromio(buf, p, 15);
  193 + if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) {
  194 + u16 num = (buf[13] << 8) | buf[12];
  195 + u16 len = (buf[7] << 8) | buf[6];
  196 + u32 base = (buf[11] << 24) | (buf[10] << 16) |
  197 + (buf[9] << 8) | buf[8];
  198 +
  199 + /*
  200 + * DMI version 0.0 means that the real version is taken from
  201 + * the SMBIOS version, which we don't know at this point.
  202 + */
  203 + if (buf[14] != 0)
  204 + printk(KERN_INFO "DMI %d.%d present.\n",
  205 + buf[14] >> 4, buf[14] & 0xF);
  206 + else
  207 + printk(KERN_INFO "DMI present.\n");
  208 + if (dmi_table(base,len, num, dmi_decode) == 0)
  209 + return 0;
  210 + }
  211 + return 1;
  212 +}
  213 +
  214 +void __init dmi_scan_machine(void)
  215 +{
191 216 char __iomem *p, *q;
  217 + int rc;
192 218  
193   - /*
194   - * no iounmap() for that ioremap(); it would be a no-op, but it's
195   - * so early in setup that sucker gets confused into doing what
196   - * it shouldn't if we actually call it.
197   - */
198   - p = ioremap(0xF0000, 0x10000);
199   - if (p == NULL)
200   - goto out;
  219 + if (efi_enabled) {
  220 + if (!efi.smbios)
  221 + goto out;
201 222  
202   - for (q = p; q < p + 0x10000; q += 16) {
203   - memcpy_fromio(buf, q, 15);
204   - if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) {
205   - u16 num = (buf[13] << 8) | buf[12];
206   - u16 len = (buf[7] << 8) | buf[6];
207   - u32 base = (buf[11] << 24) | (buf[10] << 16) |
208   - (buf[9] << 8) | buf[8];
  223 + /* This is called as a core_initcall() because it isn't
  224 + * needed during early boot. This also means we can
  225 + * iounmap the space when we're done with it.
  226 + */
  227 + p = dmi_ioremap((unsigned long)efi.smbios, 0x10000);
  228 + if (p == NULL)
  229 + goto out;
209 230  
210   - /*
211   - * DMI version 0.0 means that the real version is taken from
212   - * the SMBIOS version, which we don't know at this point.
213   - */
214   - if (buf[14] != 0)
215   - printk(KERN_INFO "DMI %d.%d present.\n",
216   - buf[14] >> 4, buf[14] & 0xF);
217   - else
218   - printk(KERN_INFO "DMI present.\n");
  231 + rc = dmi_present(p + 0x10); /* offset of _DMI_ string */
  232 + iounmap(p);
  233 + if (!rc)
  234 + return;
  235 + }
  236 + else {
  237 + /*
  238 + * no iounmap() for that ioremap(); it would be a no-op, but
  239 + * it's so early in setup that sucker gets confused into doing
  240 + * what it shouldn't if we actually call it.
  241 + */
  242 + p = dmi_ioremap(0xF0000, 0x10000);
  243 + if (p == NULL)
  244 + goto out;
219 245  
220   - if (dmi_table(base,len, num, dmi_decode) == 0)
  246 + for (q = p; q < p + 0x10000; q += 16) {
  247 + rc = dmi_present(q);
  248 + if (!rc)
221 249 return;
222 250 }
223 251 }
224   -
225   -out: printk(KERN_INFO "DMI not present or invalid.\n");
  252 + out: printk(KERN_INFO "DMI not present or invalid.\n");
226 253 }
227   -
228 254  
229 255 /**
230 256 * dmi_check_system - check system DMI data
... ... @@ -42,6 +42,10 @@
42 42 bool
43 43 default y
44 44  
  45 +config DMI
  46 + bool
  47 + default y
  48 +
45 49 config EFI
46 50 bool
47 51 default y
arch/ia64/kernel/Makefile
... ... @@ -7,7 +7,7 @@
7 7 obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \
8 8 irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \
9 9 salinfo.o semaphore.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \
10   - unwind.o mca.o mca_asm.o topology.o
  10 + unwind.o mca.o mca_asm.o topology.o dmi_scan.o
11 11  
12 12 obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o
13 13 obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o
... ... @@ -30,6 +30,7 @@
30 30 obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o
31 31 obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o
32 32 mca_recovery-y += mca_drv.o mca_drv_asm.o
  33 +dmi_scan-y += ../../i386/kernel/dmi_scan.o
33 34  
34 35 # The gate DSO image is built using a special linker script.
35 36 targets += gate.so gate-syms.o
arch/ia64/kernel/setup.c
... ... @@ -37,6 +37,7 @@
37 37 #include <linux/string.h>
38 38 #include <linux/threads.h>
39 39 #include <linux/tty.h>
  40 +#include <linux/dmi.h>
40 41 #include <linux/serial.h>
41 42 #include <linux/serial_core.h>
42 43 #include <linux/efi.h>
... ... @@ -887,4 +888,11 @@
887 888 ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles,
888 889 (unsigned long) __end___mckinley_e9_bundles);
889 890 }
  891 +
  892 +static int __init run_dmi_scan(void)
  893 +{
  894 + dmi_scan_machine();
  895 + return 0;
  896 +}
  897 +core_initcall(run_dmi_scan);
include/asm-ia64/dmi.h
  1 +#ifndef _ASM_DMI_H
  2 +#define _ASM_DMI_H 1
  3 +
  4 +#include <asm/io.h>
  5 +
  6 +#endif
include/asm-ia64/io.h
... ... @@ -435,6 +435,11 @@
435 435  
436 436 #define ioremap_nocache(o,s) ioremap(o,s)
437 437  
  438 +/* Use normal IO mappings for DMI */
  439 +#define dmi_ioremap ioremap
  440 +#define dmi_iounmap(x,l) iounmap(x)
  441 +#define dmi_alloc(l) kmalloc(l, GFP_ATOMIC)
  442 +
438 443 # ifdef __KERNEL__
439 444  
440 445 /*