public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2.4] add SMBIOS information to /proc/smbios -- UPDATED
@ 2004-04-30  2:21 Michael Brown
  2004-04-30  3:34 ` viro
  2004-05-03 23:40 ` Marcelo Tosatti
  0 siblings, 2 replies; 11+ messages in thread
From: Michael Brown @ 2004-04-30  2:21 UTC (permalink / raw)
  To: linux-kernel, marcelo.tosatti, michael_e_brown; +Cc: viro

Marcelo, Al,
	Below is an updated patch to add SMBIOS information to /proc/smbios.
Updates have been made per Al's previous comments. Please apply.

For reference, here are previous postings:
Previous 2.4 thread:
http://marc.theaimsgroup.com/?t=108321757100001&r=1&w=1

Previous 2.6 thread:
http://marc.theaimsgroup.com/?t=108311959700002&r=1&w=1

Thank you,
Michael Brown


# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/04/29 21:11:19-05:00 michael_e_brown@meb-laptop.michaels-house.net 
#   Updates per Al Viro: 
#   	-- remove MOD_{INC,DEC}_USE_COUNT
#   	-- use normal read call instead of proc read call
# 
# drivers/char/smbios.c
#   2004/04/29 21:11:17-05:00 michael_e_brown@meb-laptop.michaels-house.net +35 -47
#   Updates per comments from Al Viro.
# 
# ChangeSet
#   2004/04/29 00:16:35-05:00 michael_e_brown@meb-laptop.michaels-house.net 
#   rename smbios to proper smbios.c
# 
# drivers/char/Makefile
#   2004/04/29 00:09:15-05:00 michael_e_brown@meb-laptop.michaels-house.net +1 -1
#   rename smbios driver to 'smbios'.
# 
# drivers/char/smbios.c
#   2004/04/29 00:08:51-05:00 michael_e_brown@meb-laptop.michaels-house.net +0 -0
#   Rename: drivers/char/procsmbios.c -> drivers/char/smbios.c
# 
# ChangeSet
#   2004/04/28 23:51:19-05:00 michael_e_brown@meb-laptop.michaels-house.net 
#   Add SMBIOS driver that exports system SMBIOS information as files in /proc/smbios.
# 
# drivers/char/smbios.h
#   2004/04/28 23:50:15-05:00 michael_e_brown@meb-laptop.michaels-house.net +53 -0
# 
# drivers/char/procsmbios.c
#   2004/04/28 23:50:15-05:00 michael_e_brown@meb-laptop.michaels-house.net +251 -0
# 
# drivers/char/smbios.h
#   2004/04/28 23:50:15-05:00 michael_e_brown@meb-laptop.michaels-house.net +0 -0
#   BitKeeper file /home/michael_e_brown/kernel/bk/subtrees/smbios-24-driver/drivers/char/smbios.h
# 
# drivers/char/procsmbios.c
#   2004/04/28 23:50:15-05:00 michael_e_brown@meb-laptop.michaels-house.net +0 -0
#   BitKeeper file /home/michael_e_brown/kernel/bk/subtrees/smbios-24-driver/drivers/char/procsmbios.c
# 
# drivers/char/Makefile
#   2004/04/28 23:50:15-05:00 michael_e_brown@meb-laptop.michaels-house.net +1 -0
#   Add SMBIOS driver to build system
# 
# drivers/char/Config.in
#   2004/04/28 23:50:15-05:00 michael_e_brown@meb-laptop.michaels-house.net +1 -0
#   Add config option to turn on SMBIOS proc driver
# 
# Documentation/Configure.help
#   2004/04/28 23:50:15-05:00 michael_e_brown@meb-laptop.michaels-house.net +14 -0
#   Add help text for SMBIOS driver
# 
diff -Nru a/Documentation/Configure.help b/Documentation/Configure.help
--- a/Documentation/Configure.help	Thu Apr 29 21:13:45 2004
+++ b/Documentation/Configure.help	Thu Apr 29 21:13:45 2004
@@ -19914,6 +19914,20 @@
 
   If unsure, say N.
 
+SMBIOS table information in /proc
+CONFIG_SMBIOS
+  This driver creates two files in /proc, /proc/smbios/table_entry_point
+  and /proc/smbios/table. These two files contain the contents of the 
+  BIOS-generated SMBIOS tables. Generally, PC-like architectures made
+  after 1997 have this, it is safe to enable on any system.
+  
+  To compile this driver as a module ( = code which can be inserted in
+  and removed from the running kernel whenever you want), say M here
+  and read <file:Documentation/modules.txt>. The module will be called
+  smbios.o.
+  
+  If unsure, say N.
+
 Sony Vaio Programmable I/O Control Device support
 CONFIG_SONYPI
   This driver enables access to the Sony Programmable I/O Control
diff -Nru a/drivers/char/Config.in b/drivers/char/Config.in
--- a/drivers/char/Config.in	Thu Apr 29 21:13:45 2004
+++ b/drivers/char/Config.in	Thu Apr 29 21:13:45 2004
@@ -333,6 +333,7 @@
 if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_X86" = "y" -a "$CONFIG_X86_64" != "y" ]; then
    dep_tristate 'Sony Vaio Programmable I/O Control Device support (EXPERIMENTAL)' CONFIG_SONYPI $CONFIG_PCI
 fi
+tristate 'SMBIOS table information in /proc' CONFIG_SMBIOS
 
 mainmenu_option next_comment
 comment 'Ftape, the floppy tape device driver'
diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile
--- a/drivers/char/Makefile	Thu Apr 29 21:13:45 2004
+++ b/drivers/char/Makefile	Thu Apr 29 21:13:45 2004
@@ -265,6 +265,7 @@
 obj-$(CONFIG_HW_RANDOM) += hw_random.o
 obj-$(CONFIG_AMD_PM768) += amd76x_pm.o
 obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o
+obj-$(CONFIG_SMBIOS) += smbios.o
 
 obj-$(CONFIG_ITE_GPIO) += ite_gpio.o
 obj-$(CONFIG_AU1X00_GPIO) += au1000_gpio.o
diff -Nru a/drivers/char/smbios.c b/drivers/char/smbios.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/smbios.c	Thu Apr 29 21:13:45 2004
@@ -0,0 +1,239 @@
+/*
+ * linux/drivers/firmware/smbios.c
+ *  Copyright (C) 2002, 2003, 2004 Dell Inc.
+ *  by Michael Brown <Michael_E_Brown@dell.com>
+ *  vim:noet:ts=8:sw=8:filetype=c:textwidth=80:
+ *
+ * BIOS SMBIOS Table access
+ * conformant to DMTF SMBIOS definition
+ *   at http://www.dmtf.org/standards/smbios
+ *
+ * This code takes information provided by SMBIOS tables
+ * and presents it in procfs as:
+ *    /proc/smbios
+ *		|--> /table_entry_point
+ *		|--> /table
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License v2.0 as published by
+ * the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include "smbios.h"
+
+#define SMBIOS_VERSION "1.0"
+#define SMBIOS_DATE    "2004-04-29"
+
+MODULE_AUTHOR("Michael Brown <Michael_E_Brown@Dell.com>");
+MODULE_DESCRIPTION("procfs interface to SMBIOS information");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
+
+struct smbios_device {
+	struct smbios_table_entry_point table_eps;
+	unsigned int smbios_table_real_length;
+};
+
+/* there shall be only one */
+static struct smbios_device the_smbios_device;
+
+static struct proc_dir_entry *smbios_dir, *table_eps_file, *table_file;
+
+static __init int
+checksum_eps(struct smbios_table_entry_point *table_eps)
+{
+	u8 *p = (u8 *)table_eps;
+	u8 checksum = 0;
+	int i=0;
+	for (i=0; i < table_eps->eps_length && i < sizeof(*table_eps); ++i) {
+		checksum += p[i];
+	}
+	return(checksum == 0);
+}
+
+static __init int
+find_table_entry_point(struct smbios_device *sdev)
+{
+	struct smbios_table_entry_point *table_eps = &(sdev->table_eps);
+	u32 fp = 0xF0000;
+	while (fp < 0xFFFFF) {
+		isa_memcpy_fromio(table_eps, fp, sizeof(*table_eps));
+		if (memcmp(table_eps->anchor, "_SM_", 4)==0 &&
+					checksum_eps(table_eps)) {
+			return 0;
+		}
+		fp += 16;
+	}
+
+	printk(KERN_INFO "SMBIOS table entry point not found in "
+			"0xF0000 - 0xFFFFF\n");
+	return -ENODEV;
+}
+
+static __init int
+find_table_max_address(struct smbios_device *sdev)
+{
+	/* break out on one of three conditions:
+	 *   -- hit table_eps.table_length
+	 *   -- hit number of items that table claims we have
+	 *   -- hit structure type 127
+	 */
+
+	u8 *buf = ioremap(sdev->table_eps.table_address,
+			sdev->table_eps.table_length);
+	u8 *ptr = buf;
+	int count = 0, keep_going = 1;
+	int max_count = sdev->table_eps.table_num_structs;
+	int max_length = sdev->table_eps.table_length;
+	while(keep_going && ((ptr - buf) <= max_length) && count < max_count){
+		if (ptr[0] == 0x7F)   /* ptr[0] is type */
+			keep_going = 0;
+
+		ptr += ptr[1]; /* ptr[1] is length, skip structure */
+		/* skip strings at end of structure */
+		while((ptr-buf) < max_length && (ptr[0] || ptr[1]))
+			++ptr;
+
+		/* string area ends in double-null. skip it. */
+		ptr += 2;
+		++count;
+	}
+	sdev->smbios_table_real_length = (ptr - buf);
+	iounmap(buf);
+
+	if (count != max_count)
+		printk(KERN_INFO "Warning: SMBIOS table structure count"
+				" does not match count specified in the"
+				" table entry point.\n"
+				" Table entry point count: %d\n"
+				" Actual count: %d\n",
+				max_count, count);
+
+	if (keep_going != 0)
+		printk(KERN_INFO "Warning: SMBIOS table does not end with a"
+				" structure type 127. This may indicate a"
+				" truncated table.");
+
+	if (sdev->smbios_table_real_length != max_length)
+		printk(KERN_INFO "Warning: BIOS specified SMBIOS table length"
+				" does not match calculated length.\n"
+				" BIOS specified: %d\n"
+				" calculated length: %d\n",
+				max_length, sdev->smbios_table_real_length);
+
+	return sdev->smbios_table_real_length;
+}
+
+/* simple procfs style. Print the whole thing and let core
+ * handle splitting it out for userspace and setting eof.
+ */
+static ssize_t
+smbios_read_table_entry_point(char *page, char **start,
+				off_t off, int count,
+				int *eof, void *data)
+{
+	unsigned int max_off = sizeof(the_smbios_device.table_eps);
+	memcpy(page, &the_smbios_device.table_eps, max_off);
+	return max_off;
+}
+
+static ssize_t smbios_read_table(struct file *file, char *buf,
+                size_t count, loff_t *ppos)
+{
+	unsigned long origppos = *ppos;
+	unsigned long max_off = the_smbios_device.smbios_table_real_length;
+	u8 *ptr;
+
+	if(*ppos >= max_off)
+		return 0;
+
+	if(count > (max_off - *ppos))
+		count = max_off - *ppos;
+
+	ptr = ioremap(the_smbios_device.table_eps.table_address, max_off);
+	if (ptr == NULL)
+		return -ENXIO;
+
+	while (*ppos < max_off) {
+		put_user(readb(ptr + *ppos), buf);
+		++(*ppos); ++buf;
+	}
+	iounmap(ptr);
+	return *ppos - origppos;
+}
+
+static struct file_operations proc_smbios_table_operations = {
+	.read   = smbios_read_table,
+};
+
+static int __init
+smbios_init(void)
+{
+	int rc=0;
+
+	printk(KERN_INFO "SMBIOS facility v%s %s\n",
+			SMBIOS_VERSION, SMBIOS_DATE);
+
+	rc = find_table_entry_point(&the_smbios_device);
+	if (rc)
+		return rc;
+
+	find_table_max_address(&the_smbios_device);
+
+	rc = -ENOMEM;
+	smbios_dir = proc_mkdir("smbios", NULL);
+	if (smbios_dir == NULL)
+		goto out;
+
+	smbios_dir->owner = THIS_MODULE;
+
+	table_eps_file = create_proc_read_entry("table_entry_point",
+						0444, smbios_dir,
+						smbios_read_table_entry_point,
+						NULL);
+	if (table_eps_file == NULL)
+		goto no_table_eps_file;
+
+	table_eps_file->owner = THIS_MODULE;
+
+	table_file = create_proc_entry("table", 0444, smbios_dir);
+	if (table_file == NULL)
+		goto no_table_file;
+
+	table_file->proc_fops = &proc_smbios_table_operations;
+	table_file->owner = THIS_MODULE;
+
+	rc = 0;
+	goto out;
+no_table_file:
+	remove_proc_entry("table_entry_point", smbios_dir);
+
+no_table_eps_file:
+	remove_proc_entry("smbios", NULL);
+
+out:
+	return rc;
+}
+
+static void __exit
+smbios_exit(void)
+{
+	remove_proc_entry("table_entry_point", smbios_dir);
+	remove_proc_entry("table", smbios_dir);
+	remove_proc_entry("smbios", NULL);
+}
+
+module_init(smbios_init);
+module_exit(smbios_exit);
diff -Nru a/drivers/char/smbios.h b/drivers/char/smbios.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/smbios.h	Thu Apr 29 21:13:45 2004
@@ -0,0 +1,53 @@
+/*
+ * linux/drivers/firmware/smbios.c
+ *  Copyright (C) 2002, 2003, 2004 Dell Inc.
+ *  by Michael Brown <Michael_E_Brown@dell.com>
+ *  vim:noet:ts=8:sw=8:filetype=c:textwidth=80:
+ *
+ * BIOS SMBIOS Table access 
+ * conformant to DMTF SMBIOS definition
+ *   at http://www.dmtf.org/standards/smbios
+ *
+ * This code takes information provided by SMBIOS tables
+ * and presents it in sysfs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License v2.0 as published by
+ * the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_SMBIOS_H
+#define _LINUX_SMBIOS_H
+
+#include <linux/types.h>
+
+struct smbios_table_entry_point {
+	u8 anchor[4];
+	u8 checksum;
+	u8 eps_length;
+	u8 major_ver;
+	u8 minor_ver;
+	u16 max_struct_size;
+	u8 revision;
+	u8 formatted_area[5];
+	u8 dmi_anchor[5];
+	u8 intermediate_checksum;
+	u16 table_length;
+	u32 table_address;
+	u16 table_num_structs;
+	u8 smbios_bcd_revision;
+} __attribute__ ((packed));
+
+struct smbios_structure_header {
+	u8 type;
+	u8 length;
+	u16 handle;
+} __attribute__ ((packed));
+
+#endif				/* _LINUX_SMBIOS_H */



^ permalink raw reply	[flat|nested] 11+ messages in thread
[parent not found: <1QvX0-A4-29@gated-at.bofh.it>]
* Re: [PATCH 2.4] add SMBIOS information to /proc/smbios -- UPDATED
@ 2004-05-01 21:00 Lev Makhlis
  2004-05-01 21:20 ` Andi Kleen
  0 siblings, 1 reply; 11+ messages in thread
From: Lev Makhlis @ 2004-05-01 21:00 UTC (permalink / raw)
  To: Andi Kleen, Michael Brown; +Cc: linux-kernel

> > -- This information is, in the very near future, _not_ going to be
> > static anymore. There will be systems that update the information in
> > dynamically during SMIs.
>
> That's fine - /dev/mem can handle that too. An user will have to
> poll for changes anyways, so having it it /proc does not have
> any advantages.

One problem is that /dev/mem access isn't atomic.  You need to read
a pointer, then follow the pointer to read data.  If the pointer changes
in the middle, you lose.  That said, I don't see any mechanism that
helps avoid that in kernel, either.


^ permalink raw reply	[flat|nested] 11+ messages in thread
* RE: [PATCH 2.4] add SMBIOS information to /proc/smbios -- UPDATED
@ 2004-05-03 23:49 Michael_E_Brown
  0 siblings, 0 replies; 11+ messages in thread
From: Michael_E_Brown @ 2004-05-03 23:49 UTC (permalink / raw)
  To: marcelo.tosatti, mebrown; +Cc: linux-kernel, viro

Yes, Greg KH has pushed it into current -mm, and intends to push it up
for 2.6.7.
--
Michael

> -----Original Message-----
> From: Marcelo Tosatti [mailto:marcelo.tosatti@cyclades.com] 
> Sent: Monday, May 03, 2004 6:40 PM
> To: Michael Brown
> Cc: linux-kernel@vger.kernel.org; Brown, Michael E; 
> viro@parcelfarce.linux.theplanet.co.uk
> Subject: Re: [PATCH 2.4] add SMBIOS information to 
> /proc/smbios -- UPDATED
> 
> 
> On Thu, Apr 29, 2004 at 09:21:52PM -0500, Michael Brown wrote:
> > Marcelo, Al,
> > 	Below is an updated patch to add SMBIOS information to 
> /proc/smbios.
> > Updates have been made per Al's previous comments. Please apply.
> > 
> > For reference, here are previous postings:
> > Previous 2.4 thread:
> > http://marc.theaimsgroup.com/?t=108321757100001&r=1&w=1
> > 
> > Previous 2.6 thread:
> > http://marc.theaimsgroup.com/?t=108311959700002&r=1&w=1
> 
> Hi Michael,
> 
> Has your patch been accepted into v2.6? 
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2004-05-03 23:49 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-04-30  2:21 [PATCH 2.4] add SMBIOS information to /proc/smbios -- UPDATED Michael Brown
2004-04-30  3:34 ` viro
2004-04-30  4:37   ` Michael Brown
2004-05-03 23:40 ` Marcelo Tosatti
     [not found] <1QvX0-A4-29@gated-at.bofh.it>
2004-04-30 19:22 ` Andi Kleen
2004-05-01  3:30   ` Michael Brown
2004-05-01  3:43     ` Michael Brown
2004-05-01 15:01     ` Andi Kleen
  -- strict thread matches above, loose matches on Subject: below --
2004-05-01 21:00 Lev Makhlis
2004-05-01 21:20 ` Andi Kleen
2004-05-03 23:49 Michael_E_Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox