Commit 3ed3bce8 authored by Matt Domsch's avatar Matt Domsch Committed by Linus Torvalds

[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: default avatarMatt Domsch <Matt_Domsch@dell.com>
Acked-by: default avatar"Luck, Tony" <tony.luck@intel.com>
Cc: Andi Kleen <ak@muc.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 10dbe196
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/efi.h>
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/dmi.h> #include <asm/dmi.h>
...@@ -185,22 +186,10 @@ static void __init dmi_decode(struct dmi_header *dm) ...@@ -185,22 +186,10 @@ 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]; u8 buf[15];
char __iomem *p, *q; memcpy_fromio(buf, p, 15);
/*
* 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)) { if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) {
u16 num = (buf[13] << 8) | buf[12]; u16 num = (buf[13] << 8) | buf[12];
u16 len = (buf[7] << 8) | buf[6]; u16 len = (buf[7] << 8) | buf[6];
...@@ -216,16 +205,53 @@ void __init dmi_scan_machine(void) ...@@ -216,16 +205,53 @@ void __init dmi_scan_machine(void)
buf[14] >> 4, buf[14] & 0xF); buf[14] >> 4, buf[14] & 0xF);
else else
printk(KERN_INFO "DMI present.\n"); printk(KERN_INFO "DMI present.\n");
if (dmi_table(base,len, num, dmi_decode) == 0) if (dmi_table(base,len, num, dmi_decode) == 0)
return; return 0;
} }
return 1;
}
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;
out: printk(KERN_INFO "DMI not present or invalid.\n"); 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");
} }
/** /**
* dmi_check_system - check system DMI data * dmi_check_system - check system DMI data
* @list: array of dmi_system_id structures to match against * @list: array of dmi_system_id structures to match against
......
...@@ -42,6 +42,10 @@ config TIME_INTERPOLATION ...@@ -42,6 +42,10 @@ config TIME_INTERPOLATION
bool bool
default y default y
config DMI
bool
default y
config EFI config EFI
bool bool
default y default y
......
...@@ -7,7 +7,7 @@ extra-y := head.o init_task.o vmlinux.lds ...@@ -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 \ 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 \ 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 \ 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_BRL_EMU) += brl_emu.o
obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o
...@@ -30,6 +30,7 @@ obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o ...@@ -30,6 +30,7 @@ obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o
obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o
obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o
mca_recovery-y += mca_drv.o mca_drv_asm.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. # The gate DSO image is built using a special linker script.
targets += gate.so gate-syms.o targets += gate.so gate-syms.o
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/threads.h> #include <linux/threads.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/dmi.h>
#include <linux/serial.h> #include <linux/serial.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/efi.h> #include <linux/efi.h>
...@@ -887,3 +888,10 @@ check_bugs (void) ...@@ -887,3 +888,10 @@ check_bugs (void)
ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles, ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles,
(unsigned long) __end___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);
#ifndef _ASM_DMI_H
#define _ASM_DMI_H 1
#include <asm/io.h>
#endif
...@@ -435,6 +435,11 @@ iounmap (volatile void __iomem *addr) ...@@ -435,6 +435,11 @@ iounmap (volatile void __iomem *addr)
#define ioremap_nocache(o,s) ioremap(o,s) #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__ # ifdef __KERNEL__
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment