Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
d2d64066
Commit
d2d64066
authored
Apr 27, 2004
by
Michael E. Brown
Committed by
Greg Kroah-Hartman
Apr 27, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] add SMBIOS tables to sysfs -- UPDATED
parent
533a071f
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
328 additions
and
0 deletions
+328
-0
drivers/firmware/Kconfig
drivers/firmware/Kconfig
+8
-0
drivers/firmware/Makefile
drivers/firmware/Makefile
+1
-0
drivers/firmware/smbios.c
drivers/firmware/smbios.c
+266
-0
drivers/firmware/smbios.h
drivers/firmware/smbios.h
+53
-0
No files found.
drivers/firmware/Kconfig
View file @
d2d64066
...
...
@@ -34,4 +34,12 @@ config EFI_VARS
Subsequent efibootmgr releases may be found at:
http://linux.dell.com/efibootmgr
config SMBIOS
tristate "BIOS SMBIOS table access driver."
help
Say Y or M here if you want to enable access to the SMBIOS table
via driverfs. It exposes /sys/firmware/smbios/ subdirectory tree
containing a binary dump of the SMBIOS table header as well as the SMBIOS
table.
endmenu
drivers/firmware/Makefile
View file @
d2d64066
...
...
@@ -3,3 +3,4 @@
#
obj-$(CONFIG_EDD)
+=
edd.o
obj-$(CONFIG_EFI_VARS)
+=
efivars.o
obj-$(CONFIG_SMBIOS)
+=
smbios.o
drivers/firmware/smbios.c
0 → 100644
View file @
d2d64066
/*
* linux/drivers/firmware/smbios.c
* Copyright (C) 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 as:
* /sys/firmware/smbios/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/device.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include "smbios.h"
MODULE_AUTHOR
(
"Michael Brown <Michael_E_Brown@Dell.com>"
);
MODULE_DESCRIPTION
(
"sysfs interface to SMBIOS information"
);
MODULE_LICENSE
(
"GPL"
);
#define SMBIOS_VERSION "1.0 2004-04-19"
struct
smbios_device
{
struct
smbios_table_entry_point
table_eps
;
unsigned
int
smbios_table_real_length
;
struct
kobject
kobj
;
};
/* there shall be only one */
static
struct
smbios_device
the_smbios_device
;
#define to_smbios_device(obj) container_of(obj,struct smbios_device,kobj)
/* don't currently have any "normal" attributes, so we don't need a way to
* show them. */
static
struct
sysfs_ops
smbios_attr_ops
=
{
};
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
;
}
static
ssize_t
smbios_read_table_entry_point
(
struct
kobject
*
kobj
,
char
*
buffer
,
loff_t
pos
,
size_t
size
)
{
struct
smbios_device
*
sdev
=
to_smbios_device
(
kobj
);
const
char
*
p
=
(
const
char
*
)
&
(
sdev
->
table_eps
);
unsigned
int
count
=
size
>
sizeof
(
sdev
->
table_eps
)
?
sizeof
(
sdev
->
table_eps
)
:
size
;
memcpy
(
buffer
,
p
,
count
);
return
count
;
}
static
ssize_t
smbios_read_table
(
struct
kobject
*
kobj
,
char
*
buffer
,
loff_t
pos
,
size_t
size
)
{
struct
smbios_device
*
sdev
=
to_smbios_device
(
kobj
);
u8
*
buf
;
unsigned
int
count
=
sdev
->
smbios_table_real_length
-
pos
;
int
i
=
0
;
count
=
count
<
size
?
count
:
size
;
if
(
pos
>
sdev
->
smbios_table_real_length
)
return
0
;
buf
=
ioremap
(
sdev
->
table_eps
.
table_address
,
sdev
->
smbios_table_real_length
);
if
(
buf
==
NULL
)
return
-
ENXIO
;
/* memcpy( buffer, buf+pos, count ); */
for
(
i
=
0
;
i
<
count
;
++
i
)
{
buffer
[
i
]
=
readb
(
buf
+
pos
+
i
);
}
iounmap
(
buf
);
return
count
;
}
static
struct
bin_attribute
tep_attr
=
{
.
attr
=
{.
name
=
"table_entry_point"
,
.
owner
=
THIS_MODULE
,
.
mode
=
0444
},
.
size
=
sizeof
(
struct
smbios_table_entry_point
),
.
read
=
smbios_read_table_entry_point
,
/* not writeable */
};
static
struct
bin_attribute
table_attr
=
{
.
attr
=
{
.
name
=
"table"
,
.
owner
=
THIS_MODULE
,
.
mode
=
0444
},
/* size set later, we don't know it here. */
.
read
=
smbios_read_table
,
/* not writeable */
};
/* no default attributes yet. */
static
struct
attribute
*
def_attrs
[]
=
{
NULL
,
};
static
struct
kobj_type
ktype_smbios
=
{
.
sysfs_ops
=
&
smbios_attr_ops
,
.
default_attrs
=
def_attrs
,
/* statically allocated, no release method necessary */
};
static
decl_subsys
(
smbios
,
&
ktype_smbios
,
NULL
);
static
inline
void
smbios_device_unregister
(
struct
smbios_device
*
sdev
)
{
sysfs_remove_bin_file
(
&
sdev
->
kobj
,
&
tep_attr
);
sysfs_remove_bin_file
(
&
sdev
->
kobj
,
&
table_attr
);
kobject_unregister
(
&
sdev
->
kobj
);
}
static
int
smbios_device_register
(
struct
smbios_device
*
sdev
)
{
int
error
;
if
(
!
sdev
)
return
1
;
kobject_set_name
(
&
sdev
->
kobj
,
"smbios"
);
kobj_set_kset_s
(
sdev
,
smbios_subsys
);
error
=
kobject_register
(
&
sdev
->
kobj
);
if
(
!
error
){
sysfs_create_bin_file
(
&
sdev
->
kobj
,
&
tep_attr
);
sysfs_create_bin_file
(
&
sdev
->
kobj
,
&
table_attr
);
}
return
error
;
}
static
int
__init
smbios_init
(
void
)
{
int
rc
=
0
;
printk
(
KERN_INFO
"SMBIOS facility v%s
\n
"
,
SMBIOS_VERSION
);
rc
=
find_table_entry_point
(
&
the_smbios_device
);
if
(
rc
)
return
rc
;
table_attr
.
size
=
find_table_max_address
(
&
the_smbios_device
);
rc
=
firmware_register
(
&
smbios_subsys
);
if
(
rc
)
return
rc
;
rc
=
smbios_device_register
(
&
the_smbios_device
);
if
(
rc
)
firmware_unregister
(
&
smbios_subsys
);
return
rc
;
}
static
void
__exit
smbios_exit
(
void
)
{
smbios_device_unregister
(
&
the_smbios_device
);
firmware_unregister
(
&
smbios_subsys
);
}
late_initcall
(
smbios_init
);
module_exit
(
smbios_exit
);
drivers/firmware/smbios.h
0 → 100644
View file @
d2d64066
/*
* 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 */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment