[PATCH 2.2] i386/dmi_scan updates

From: Jean Delvare (khali@linux-fr.org)
Date: Sat Oct 05 2002 - 14:36:24 EST


Hi everyone,

I have been working on Alan's userspace program "dmidecode" recently, and made some fixes to it. It happens that this userspace program shares some code with linux/arch/i386/dmi_scan.c, so I thought it would be a good idea to backport the changes that apply to the linux kernel tree. I have been writing patches for Linux 2.2, 2.4 and 2.5.

This specific patch applies to the Linux 2.2 tree and has been built against 2.2.22.

Main changes:
 - Stop skipping DMI entries when type is less than those of the
   previous entry. I could see no reason for doing this.
 - Verify the DMI entry point structure checksum.
 - Start looking for the DMI entry point from 0xF0000, not 0xE0000.
 - Fix an off-by-one error causing the last address scanned being
   0x100000, not 0xFFFF0 as it should.
 - Do not display the DMI version if it would be 0.0.
 - Remove senseless tests in dump (debug) code.

Other changes are simple cleanups and should be straightforward to understand.

All comments are of course welcome.

--- linux-2.2.22/arch/i386/kernel/dmi_scan.c.orig Sun Mar 25 18:37:29 2001
+++ linux-2.2.22/arch/i386/kernel/dmi_scan.c Wed Oct 2 14:43:22 2002
@@ -32,7 +32,6 @@
         struct dmi_header *dm;
         u8 *data;
         int i=1;
- int last = 0;
                 
         buf = ioremap(base, len);
         if(buf==NULL)
@@ -42,9 +41,6 @@
         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])
@@ -57,33 +53,48 @@
 }
 
 
+inline int __init dmi_checksum(u8 *buf)
+{
+ u8 sum=0;
+ int a;
+
+ for(a=0; a<15; a++)
+ sum+=buf[a];
+ return (sum==0);
+}
+
 int __init dmi_iterate(void (*decode)(struct dmi_header *))
 {
- unsigned char buf[20];
- long fp=0xE0000L;
- fp -= 16;
+ u8 buf[15];
+ u32 fp=0xF0000;
         
         while( fp < 0xFFFFF)
         {
- fp+=16;
- memcpy_fromio(buf, fp, 20);
- if(memcmp(buf, "_DMI_", 5)==0)
+ 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];
 #ifdef DUMP_DMI
- printk(KERN_INFO "DMI %d.%d present.\n",
- buf[14]>>4, buf[14]&0x0F);
+ /*
+ * 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 %u.%u present.\n",
+ buf[14]>>4, buf[14]&0x0F);
+ else
+ printk(KERN_INFO "DMI present.\n");
                         printk(KERN_INFO "%d structures occupying %d bytes.\n",
- buf[13]<<8|buf[12],
- buf[7]<<8|buf[6]);
+ num, len);
                         printk(KERN_INFO "DMI table at 0x%08X.\n",
- buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8]);
+ base);
 #endif
                         if(dmi_table(base,len, num, decode)==0)
                                 return 0;
                 }
+ fp+=16;
         }
         return -1;
 }
@@ -98,21 +109,17 @@
 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]));
- }
+ printk("BIOS Vendor: %s\n",
+ dmi_string(dm, data[4]));
+ 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
@@ -142,35 +149,22 @@
                         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]));
- }
+ printk("System Vendor: %s\n",
+ dmi_string(dm, data[4]));
+ 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",
+ printk("Board Vendor: %s\n",
+ dmi_string(dm, data[4]));
+ 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);
+ printk("Board Version: %s\n",
+ dmi_string(dm, data[6]));
                         break;
 #endif
         }

___________________________________
Webmail Nerim, http://www.nerim.net/

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Oct 07 2002 - 22:00:51 EST