mirror of
https://github.com/lm-sensors/lm-sensors.git
synced 2026-10-17 10:59:31 +00:00
Delete dmi_scan.h, now useless. git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@2423 7894878c-1315-0410-8ee3-d5d059ff63e0
250 lines
5.2 KiB
C
250 lines
5.2 KiB
C
/*
|
|
Taken from arch/i386/kernel/dmi_scan.c.
|
|
Changes dmi_ident to be non-static so we can access.
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/config.h>
|
|
#include <linux/types.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/string.h>
|
|
#include <linux/init.h>
|
|
#include <linux/apm_bios.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/pm.h>
|
|
#include <asm/io.h>
|
|
#include <asm/keyboard.h>
|
|
#include <asm/system.h>
|
|
#include "version.h"
|
|
|
|
int is_unsafe_smbus;
|
|
EXPORT_SYMBOL(is_unsafe_smbus);
|
|
|
|
struct dmi_header
|
|
{
|
|
u8 type;
|
|
u8 length;
|
|
u16 handle;
|
|
};
|
|
|
|
enum
|
|
{
|
|
DMI_BIOS_VENDOR,
|
|
DMI_BIOS_VERSION,
|
|
DMI_BIOS_DATE,
|
|
DMI_SYS_VENDOR,
|
|
DMI_PRODUCT_NAME,
|
|
DMI_PRODUCT_VERSION,
|
|
DMI_BOARD_VENDOR,
|
|
DMI_BOARD_NAME,
|
|
DMI_BOARD_VERSION,
|
|
DMI_STRING_MAX
|
|
};
|
|
|
|
#define dmi_printk(x)
|
|
//#define dmi_printk(x) printk x
|
|
|
|
static char * __init dmi_string(struct dmi_header *dm, u8 s)
|
|
{
|
|
u8 *bp=(u8 *)dm;
|
|
bp+=dm->length;
|
|
if(!s)
|
|
return "";
|
|
s--;
|
|
while(s>0 && *bp)
|
|
{
|
|
bp+=strlen(bp);
|
|
bp++;
|
|
s--;
|
|
}
|
|
return bp;
|
|
}
|
|
|
|
/*
|
|
* We have to be cautious here. We have seen BIOSes with DMI pointers
|
|
* pointing to completely the wrong place for example
|
|
*/
|
|
|
|
static int __init dmi_table(u32 base, int len, int num, void (*decode)(struct dmi_header *))
|
|
{
|
|
u8 *buf;
|
|
struct dmi_header *dm;
|
|
u8 *data;
|
|
int i=0;
|
|
|
|
buf = ioremap(base, len);
|
|
if(buf==NULL)
|
|
return -1;
|
|
|
|
data = buf;
|
|
|
|
/*
|
|
* Stop when we see all the items the table claimed to have
|
|
* OR we run off the end of the table (also happens)
|
|
*/
|
|
|
|
while(i<num && data-buf+sizeof(struct dmi_header)<=len)
|
|
{
|
|
dm=(struct dmi_header *)data;
|
|
/*
|
|
* We want to know the total length (formated area and strings)
|
|
* before decoding to make sure we won't run off the table in
|
|
* dmi_decode or dmi_string
|
|
*/
|
|
data+=dm->length;
|
|
while(data-buf<len-1 && (data[0] || data[1]))
|
|
data++;
|
|
if(data-buf<len-1)
|
|
decode(dm);
|
|
data+=2;
|
|
i++;
|
|
}
|
|
iounmap(buf);
|
|
return 0;
|
|
}
|
|
|
|
|
|
inline static int __init dmi_checksum(u8 *buf)
|
|
{
|
|
u8 sum=0;
|
|
int a;
|
|
|
|
for(a=0; a<15; a++)
|
|
sum+=buf[a];
|
|
return (sum==0);
|
|
}
|
|
|
|
static int __init dmi_iterate(void (*decode)(struct dmi_header *))
|
|
{
|
|
u8 buf[15];
|
|
u32 fp=0xF0000;
|
|
|
|
#ifdef CONFIG_SIMNOW
|
|
/*
|
|
* Skip on x86/64 with simnow. Will eventually go away
|
|
* If you see this ifdef in 2.6pre mail me !
|
|
*/
|
|
return -1;
|
|
#endif
|
|
|
|
while( fp < 0xFFFFF)
|
|
{
|
|
isa_memcpy_fromio(buf, fp, 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)
|
|
dmi_printk((KERN_INFO "DMI %d.%d present.\n",
|
|
buf[14]>>4, buf[14]&0x0F));
|
|
else
|
|
dmi_printk((KERN_INFO "DMI present.\n"));
|
|
dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n",
|
|
num, len));
|
|
dmi_printk((KERN_INFO "DMI table at 0x%08X.\n",
|
|
base));
|
|
if(dmi_table(base,len, num, decode)==0)
|
|
return 0;
|
|
}
|
|
fp+=16;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
char *dmi_ident[DMI_STRING_MAX];
|
|
|
|
/*
|
|
* Save a DMI string
|
|
*/
|
|
|
|
static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
|
|
{
|
|
char *d = (char*)dm;
|
|
char *p = dmi_string(dm, d[string]);
|
|
if(p==NULL || *p == 0)
|
|
return;
|
|
if (dmi_ident[slot])
|
|
return;
|
|
dmi_ident[slot] = kmalloc(strlen(p)+1, GFP_KERNEL);
|
|
if(dmi_ident[slot])
|
|
strcpy(dmi_ident[slot], p);
|
|
else
|
|
printk(KERN_ERR "dmi_save_ident: out of memory.\n");
|
|
}
|
|
|
|
/*
|
|
* Process a DMI table entry. Right now all we care about are the BIOS
|
|
* and machine entries. For 2.5 we should pull the smbus controller info
|
|
* out of here.
|
|
*/
|
|
|
|
static void __init dmi_decode(struct dmi_header *dm)
|
|
{
|
|
switch(dm->type)
|
|
{
|
|
case 0:
|
|
dmi_printk(("BIOS Vendor: %s\n",
|
|
dmi_string(dm, data[4])));
|
|
dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
|
|
dmi_printk(("BIOS Version: %s\n",
|
|
dmi_string(dm, data[5])));
|
|
dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
|
|
dmi_printk(("BIOS Release: %s\n",
|
|
dmi_string(dm, data[8])));
|
|
dmi_save_ident(dm, DMI_BIOS_DATE, 8);
|
|
break;
|
|
case 1:
|
|
dmi_printk(("System Vendor: %s\n",
|
|
dmi_string(dm, data[4])));
|
|
dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
|
|
dmi_printk(("Product Name: %s\n",
|
|
dmi_string(dm, data[5])));
|
|
dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
|
|
dmi_printk(("Version: %s\n",
|
|
dmi_string(dm, data[6])));
|
|
dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
|
|
dmi_printk(("Serial Number: %s\n",
|
|
dmi_string(dm, data[7])));
|
|
break;
|
|
case 2:
|
|
dmi_printk(("Board Vendor: %s\n",
|
|
dmi_string(dm, data[4])));
|
|
dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
|
|
dmi_printk(("Board Name: %s\n",
|
|
dmi_string(dm, data[5])));
|
|
dmi_save_ident(dm, DMI_BOARD_NAME, 5);
|
|
dmi_printk(("Board Version: %s\n",
|
|
dmi_string(dm, data[6])));
|
|
dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
|
|
break;
|
|
}
|
|
}
|
|
|
|
int __init dmi_scan_mach(void)
|
|
{
|
|
int err;
|
|
printk("dmi_scan.o version %s (%s)\n", LM_VERSION, LM_DATE);
|
|
err = dmi_iterate(dmi_decode);
|
|
if(err)
|
|
printk("dmi_scan.o: SM BIOS not found\n");
|
|
else
|
|
printk("dmi_scan.o: SM BIOS found\n");
|
|
|
|
if(dmi_ident[DMI_SYS_VENDOR] != NULL
|
|
&& strncmp(dmi_ident[DMI_SYS_VENDOR], "IBM", 3) == 0)
|
|
is_unsafe_smbus = 1;
|
|
return 0;
|
|
}
|
|
|
|
MODULE_DESCRIPTION("SM BIOS DMI Scanner");
|
|
MODULE_LICENSE("GPL");
|
|
|
|
module_init(dmi_scan_mach);
|