lkml.org 
[lkml]   [2002]   [Oct]   [8]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Subject[PATCH 2.4] i386/dmi_scan updates v.2
FromJean Delvare <>
DateTue, 8 Oct 2002 13:48:27 CEST
Hi everyone,

The changes I made to i386/dmi_scan for the 2.2 tree being OK by Alan,
I ported the patch to 2.4. I will port it to 2.5 really soon also.

This patch applies to the Linux 2.4 tree and has been built against
2.4.20-pre9.

Features:
 - Ensure that dmi_string always return a null-terminated string.
 - Fix an off-by-one error causing the last entry of the DMI table
   not to be decoded.
 - Ensure we don't run off the table in dmi_table. Call dmi_decode only
   if the whole entry (formated area and strings) fits in the table.
 - 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 to be
   0x100000, not 0xFFFF0 as it should.
 - Do not display the DMI version if it would be 0.0.
 - Remove now senseless tests in dump (debug) code.
Other changes are simple cleanups and should be straightforward to
understand.

Some numbers:
  source code: +23 bytes
  binary w/o debug: -96 bytes
  binary w/ debug: -176 bytes

Please apply.
All comments are of course welcome.

--- linux-2.4.20-pre9/arch/i386/kernel/dmi_scan.c.orig	Sat Oct  5 14:54:55 2002
+++ linux-2.4.20-pre9/arch/i386/kernel/dmi_scan.c	Tue Oct  8 10:59:26 2002
@@ -31,7 +31,7 @@
 	if(!s)
 		return "";
 	s--;
-	while(s>0)
+	while(s>0 && *bp)
 	{
 		bp+=strlen(bp);
 		bp++;
@@ -50,7 +50,7 @@
 	u8 *buf;
 	struct dmi_header *dm;
 	u8 *data;
-	int i=1;
+	int i=0;
 		
 	buf = bt_ioremap(base, len);
 	if(buf==NULL)
@@ -59,28 +59,23 @@
 	data = buf;
 
 	/*
- 	 *	Stop when we see al the items the table claimed to have
+ 	 *	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) < len)
+	while(i<num && data-buf+sizeof(struct dmi_header)<=len)
 	{
 		dm=(struct dmi_header *)data;
-	
 		/*
-		 *	Avoid misparsing crud if the length of the last
-	 	 *	record is crap 
+		 *  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
 		 */
-		if((data-buf+dm->length) >= len)
-			break;
-		decode(dm);		
 		data+=dm->length;
-		/*
-		 *	Don't go off the end of the data if there is
-	 	 *	stuff looking like string fill past the end
-	 	 */
-		while((data-buf) < len && (*data || data[1]))
+		while(data-buf<len-1 && (data[0] || data[1]))
 			data++;
+		if(data-buf<len-1)
+			decode(dm);
 		data+=2;
 		i++;
 	}
@@ -89,11 +84,20 @@
 }
 
 
+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 *))
 {
-	unsigned char buf[20];
-	long fp=0xE0000L;
-	fp -= 16;
+	u8 buf[15];
+	u32 fp=0xF0000;
 
 #ifdef CONFIG_SIMNOW
 	/*
@@ -105,24 +109,30 @@
  	
 	while( fp < 0xFFFFF)
 	{
-		fp+=16;
-		isa_memcpy_fromio(buf, fp, 20);
-		if(memcmp(buf, "_DMI_", 5)==0)
+		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_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)
+				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",
-				buf[13]<<8|buf[12],
-				buf[7]<<8|buf[6]));
+				num, len));
 			dmi_printk((KERN_INFO "DMI table at 0x%08X.\n",
-				buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8]));
+				base));
 			if(dmi_table(base,len, num, decode)==0)
 				return 0;
 		}
+		fp+=16;
 	}
 	return -1;
 }
@@ -810,59 +820,43 @@
 static void __init dmi_decode(struct dmi_header *dm)
 {
 	u8 *data = (u8 *)dm;
-	char *p;
 	
 	switch(dm->type)
 	{
 		case  0:
-			p=dmi_string(dm,data[4]);
-			if(*p)
-			{
-				dmi_printk(("BIOS Vendor: %s\n", p));
-				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);
-			}
+			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:
-			p=dmi_string(dm,data[4]);
-			if(*p)
-			{
-				dmi_printk(("System Vendor: %s.\n",p));
-				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])));
-			}
+			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:
-			p=dmi_string(dm,data[4]);
-			if(*p)
-			{
-				dmi_printk(("Board Vendor: %s.\n",p));
-				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;
-		case 3:
-			p=dmi_string(dm,data[8]);
-			if(*p && *p!=' ')
-				dmi_printk(("Asset Tag: %s.\n", p));
+			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;
 	}
 }

___________________________________
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/

\
 
 \ /
  Last update: 2005-03-22 13:29    [W:0.192 / U:0.010 seconds]
©2003-2008 Jasper Spaans