patch-2.2.18 linux/arch/i386/kernel/dmi_scan.c
Next file: linux/arch/i386/kernel/i386_ksyms.c
Previous file: linux/arch/i386/kernel/cpuid.c
Back to the patch index
Back to the overall index
- Lines: 183
- Date:
Thu Dec 7 15:14:02 2000
- Orig file:
v2.2.17/arch/i386/kernel/dmi_scan.c
- Orig date:
Thu Jan 1 01:00:00 1970
diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.17/arch/i386/kernel/dmi_scan.c linux/arch/i386/kernel/dmi_scan.c
@@ -0,0 +1,182 @@
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <asm/io.h>
+
+struct dmi_header
+{
+ u8 type;
+ u8 length;
+ u16 handle;
+};
+
+static char * __init dmi_string(struct dmi_header *dm, u8 s)
+{
+ u8 *bp=(u8 *)dm;
+ bp+=dm->length;
+ s--;
+ while(s>0)
+ {
+ bp+=strlen(bp);
+ bp++;
+ s--;
+ }
+ return bp;
+}
+
+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=1;
+ int last = 0;
+
+ buf = ioremap(base, len);
+ if(buf==NULL)
+ return -1;
+
+ data = buf;
+ while(i<num && (data-buf) < len)
+ {
+ dm=(struct dmi_header *)data;
+ if(dm->type < last)
+ break;
+ last = dm->type;
+ decode(dm);
+ data+=dm->length;
+ while(*data || data[1])
+ data++;
+ data+=2;
+ i++;
+ }
+ iounmap(buf);
+ return 0;
+}
+
+
+int __init dmi_iterate(void (*decode)(struct dmi_header *))
+{
+ unsigned char buf[20];
+ long fp=0xE0000L;
+ fp -= 16;
+
+ while( fp < 0xFFFFF)
+ {
+ fp+=16;
+ memcpy_fromio(buf, fp, 20);
+ if(memcmp(buf, "_DMI_", 5)==0)
+ {
+ 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];
+#ifdef DUMP_DMI
+ printk(KERN_INFO "DMI %d.%d present.\n",
+ buf[14]>>4, buf[14]&0x0F);
+ printk(KERN_INFO "%d structures occupying %d bytes.\n",
+ buf[13]<<8|buf[12],
+ buf[7]<<8|buf[6]);
+ printk(KERN_INFO "DMI table at 0x%08X.\n",
+ buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8]);
+#endif
+ if(dmi_table(base,len, num, decode)==0)
+ return 0;
+ }
+ }
+ return -1;
+}
+
+
+/*
+ * Process a DMI table entry. Right now all we care about are the BIOS
+ * and machine entries. For 2.4 we should pull the smbus controller info
+ * out of here.
+ */
+
+static void __init dmi_decode(struct dmi_header *dm)
+{
+ u8 *data = (u8 *)dm;
+ char *p;
+
+ switch(dm->type)
+ {
+ case 0:
+#ifdef DUMP_DMI
+ p=dmi_string(dm,data[4]);
+ if(*p && *p!=' ')
+ {
+ printk("BIOS Vendor: %s\n", p);
+ printk("BIOS Version: %s\n",
+ dmi_string(dm, data[5]));
+ printk("BIOS Release: %s\n",
+ dmi_string(dm, data[8]));
+ }
+#endif
+ /*
+ * Check for clue free BIOS implementations who use
+ * the following QA technique
+ *
+ * [ Write BIOS Code ]<------
+ * | ^
+ * < Does it Compile >----N--
+ * |Y ^
+ * < Does it Boot Win98 >-N--
+ * |Y
+ * [Ship It]
+ */
+
+ if(strcmp(dmi_string(dm, data[4]), "Phoenix Technologies LTD")==0 &&
+ strcmp(dmi_string(dm, data[5]), "A04")==0 &&
+ strcmp(dmi_string(dm, data[8]), "08/24/2000")==0)
+ {
+#ifdef CONFIG_APM
+ extern void apm_battery_horked(void);
+ apm_battery_horked();
+ printk(KERN_WARNING "BIOS strings suggest APM bugs, disabling battery reporting.\n");
+#endif
+ }
+ break;
+#ifdef DUMP_DMI
+ case 1:
+ p=dmi_string(dm,data[4]);
+
+ if(*p && *p!=' ')
+ {
+ printk("System Vendor: %s.\n",p);
+ printk("Product Name: %s.\n",
+ dmi_string(dm, data[5]));
+ printk("Version %s.\n",
+ dmi_string(dm, data[6]));
+ printk("Serial Number %s.\n",
+ dmi_string(dm, data[7]));
+ }
+ break;
+ case 2:
+ p=dmi_string(dm,data[4]);
+
+ if(*p && *p!=' ')
+ {
+ printk("Board Vendor: %s.\n",p);
+ printk("Board Name: %s.\n",
+ dmi_string(dm, data[5]));
+ printk("Board Version: %s.\n",
+ dmi_string(dm, data[6]));
+ }
+ break;
+ case 3:
+ p=dmi_string(dm,data[8]);
+ if(*p && *p!=' ')
+ printk("Asset Tag: %s.\n", p);
+ break;
+#endif
+ }
+}
+
+int __init dmi_scan_machine(void)
+{
+ return dmi_iterate(dmi_decode);
+}
+
+__initcall(dmi_scan_machine);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)