mirror of
https://git.jff.email/cgit/dmidecode.git
synced 2026-08-07 20:05:49 +00:00
Imported Upstream version 3.0
This commit is contained in:
parent
723024faf0
commit
53bafb796b
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
biosdecode
|
||||
dmidecode
|
||||
ownership
|
||||
vpddecode
|
||||
*.o
|
||||
8
AUTHORS
8
AUTHORS
@ -1,9 +1,9 @@
|
||||
DEVELOPER AND MAINTAINER
|
||||
Anton Arapov <anton@redhat.com>
|
||||
Jean Delvare <jdelvare@suse.de>
|
||||
|
||||
ORIGINAL AUTHORS
|
||||
Alan Cox <alan@redhat.com>
|
||||
Jean Delvare <khali@linux-fr.org>
|
||||
Jean Delvare <jdelvare@suse.de>
|
||||
|
||||
CODE CONTRIBUTORS (IN CHRONOLOGICAL ORDER)
|
||||
Matt Domsch <Matt_Domsch@dell.com>
|
||||
@ -16,6 +16,9 @@ Roberto Nibali <ratz@tac.ch>
|
||||
John Cagle <jcagle@kernel.org>
|
||||
Jens Elkner <elkner@linofee.org>
|
||||
Jarod Wilson <jarod@redhat.com>
|
||||
Anton Arapov <anton@redhat.com>
|
||||
Roy Franz <roy.franz@linaro.org>
|
||||
Tyler Bell <tyler.bell@hp.com>
|
||||
|
||||
MANY THANKS TO (IN CHRONOLOGICAL ORDER)
|
||||
Werner Heuser
|
||||
@ -84,3 +87,4 @@ Thomas Mingarelli
|
||||
Andrey Matveyev
|
||||
Stefan Tauner
|
||||
Naga Chumbalkar
|
||||
Jens Rosenboom
|
||||
|
||||
39
LICENSE
39
LICENSE
@ -1,12 +1,12 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
@ -225,7 +225,7 @@ impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
@ -303,10 +303,9 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names:
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
||||
6
Makefile
6
Makefile
@ -4,7 +4,7 @@
|
||||
# VPD Decode
|
||||
#
|
||||
# Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
|
||||
# Copyright (C) 2002-2007 Jean Delvare <khali@linux-fr.org>
|
||||
# Copyright (C) 2002-2015 Jean Delvare <jdelvare@suse.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -15,6 +15,10 @@
|
||||
CC = gcc
|
||||
CFLAGS = -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual \
|
||||
-Wcast-align -Wwrite-strings -Wmissing-prototypes -Winline -Wundef
|
||||
|
||||
# Let lseek and mmap support 64-bit wide offsets
|
||||
CFLAGS += -D_FILE_OFFSET_BITS=64
|
||||
|
||||
#CFLAGS += -DBIGENDIAN
|
||||
#CFLAGS += -DALIGNMENT_WORKAROUND
|
||||
|
||||
|
||||
35
biosdecode.c
35
biosdecode.c
@ -2,7 +2,7 @@
|
||||
* BIOS Decode
|
||||
*
|
||||
* Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
|
||||
* Copyright (C) 2002-2008 Jean Delvare <khali@linux-fr.org>
|
||||
* Copyright (C) 2002-2015 Jean Delvare <jdelvare@suse.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -25,10 +25,10 @@
|
||||
* are deemed to be part of the source code.
|
||||
*
|
||||
* References:
|
||||
* - DMTF "System Management BIOS Reference Specification"
|
||||
* Version 2.3.4
|
||||
* - DMTF "System Management BIOS (SMBIOS) Reference Specification"
|
||||
* Version 3.0.0
|
||||
* http://www.dmtf.org/standards/smbios
|
||||
* - Intel "Preboot Execution Environment (PXE) Specification"
|
||||
* - Intel "Preboot Execution Environment (PXE) Specification"
|
||||
* Version 2.1
|
||||
* http://www.intel.com/labs/manage/wfm/wfmspecs.htm
|
||||
* - ACPI "Advanced Configuration and Power Interface Specification"
|
||||
@ -90,6 +90,26 @@ struct bios_entry {
|
||||
* SMBIOS
|
||||
*/
|
||||
|
||||
static size_t smbios3_length(const u8 *p)
|
||||
{
|
||||
return p[0x06];
|
||||
}
|
||||
|
||||
static int smbios3_decode(const u8 *p, size_t len)
|
||||
{
|
||||
if (len < 0x18 || !checksum(p, p[0x06]))
|
||||
return 0;
|
||||
|
||||
printf("SMBIOS %u.%u.%u present.\n",
|
||||
p[0x07], p[0x08], p[0x09]);
|
||||
printf("\tStructure Table Maximum Length: %u bytes\n",
|
||||
DWORD(p + 0x0C));
|
||||
printf("\tStructure Table 64-bit Address: 0x%08X%08X\n",
|
||||
QWORD(p + 0x10).h, QWORD(p + 0x10).l);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static size_t smbios_length(const u8 *p)
|
||||
{
|
||||
return p[0x05] == 0x1E ? 0x1F : p[0x05];
|
||||
@ -105,7 +125,7 @@ static int smbios_decode(const u8 *p, size_t len)
|
||||
printf("SMBIOS %u.%u present.\n",
|
||||
p[0x06], p[0x07]);
|
||||
printf("\tStructure Table Length: %u bytes\n",
|
||||
WORD(p+0x16));
|
||||
WORD(p + 0x16));
|
||||
printf("\tStructure Table Address: 0x%08X\n",
|
||||
DWORD(p + 0x18));
|
||||
printf("\tNumber Of Structures: %u\n",
|
||||
@ -516,7 +536,7 @@ static int fjkeyinf_decode(const u8 *p, size_t len)
|
||||
return 1;
|
||||
printf("\tDevice %d: type %u, chip %u", i + 1,
|
||||
*(p + 8 + i * 4), *(p + 8 + i * 4 + 2));
|
||||
if (*(p+8+i*4+1)) /* Access method */
|
||||
if (*(p + 8 + i * 4 + 1)) /* Access method */
|
||||
printf(", SMBus address 0x%x",
|
||||
*(p + 8 + i * 4 + 3) >> 1);
|
||||
printf("\n");
|
||||
@ -530,6 +550,7 @@ static int fjkeyinf_decode(const u8 *p, size_t len)
|
||||
*/
|
||||
|
||||
static struct bios_entry bios_entries[] = {
|
||||
{ "_SM3_", 0, 0xF0000, 0xFFFFF, smbios3_length, smbios3_decode },
|
||||
{ "_SM_", 0, 0xF0000, 0xFFFFF, smbios_length, smbios_decode },
|
||||
{ "_DMI_", 0, 0xF0000, 0xFFFFF, dmi_length, dmi_decode },
|
||||
{ "_SYSID_", 0, 0xE0000, 0xFFFFF, sysid_length, sysid_decode },
|
||||
@ -565,7 +586,7 @@ static int parse_command_line(int argc, char * const argv[])
|
||||
{ "dev-mem", required_argument, NULL, 'd' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ 0, 0, 0, 0 }
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
while ((option = getopt_long(argc, argv, optstring, longopts, NULL)) != -1)
|
||||
|
||||
423
dmidecode.c
423
dmidecode.c
@ -2,7 +2,7 @@
|
||||
* DMI Decode
|
||||
*
|
||||
* Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
|
||||
* Copyright (C) 2002-2010 Jean Delvare <khali@linux-fr.org>
|
||||
* Copyright (C) 2002-2015 Jean Delvare <jdelvare@suse.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -25,7 +25,7 @@
|
||||
* are deemed to be part of the source code.
|
||||
*
|
||||
* Unless specified otherwise, all references are aimed at the "System
|
||||
* Management BIOS Reference Specification, Version 2.8.0" document,
|
||||
* Management BIOS Reference Specification, Version 3.0.0" document,
|
||||
* available from http://www.dmtf.org/standards/smbios.
|
||||
*
|
||||
* Note to contributors:
|
||||
@ -69,12 +69,30 @@
|
||||
#define out_of_spec "<OUT OF SPEC>"
|
||||
static const char *bad_index = "<BAD INDEX>";
|
||||
|
||||
#define SUPPORTED_SMBIOS_VER 0x0207
|
||||
#define SUPPORTED_SMBIOS_VER 0x0300
|
||||
|
||||
#define FLAG_NO_FILE_OFFSET (1 << 0)
|
||||
#define FLAG_STOP_AT_EOT (1 << 1)
|
||||
|
||||
#define SYS_ENTRY_FILE "/sys/firmware/dmi/tables/smbios_entry_point"
|
||||
#define SYS_TABLE_FILE "/sys/firmware/dmi/tables/DMI"
|
||||
|
||||
/*
|
||||
* Type-independant Stuff
|
||||
*/
|
||||
|
||||
/* Returns 1 if the buffer contains only printable ASCII characters */
|
||||
int is_printable(const u8 *data, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if (data[i] < 32 || data[i] >= 127)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *dmi_string(const struct dmi_header *dm, u8 s)
|
||||
{
|
||||
char *bp = (char *)dm->data;
|
||||
@ -529,12 +547,15 @@ static const char *dmi_chassis_type(u8 code)
|
||||
"CompactPCI",
|
||||
"AdvancedTCA",
|
||||
"Blade",
|
||||
"Blade Enclosing" /* 0x1D */
|
||||
"Blade Enclosing",
|
||||
"Tablet",
|
||||
"Convertible",
|
||||
"Detachable" /* 0x20 */
|
||||
};
|
||||
|
||||
code &= 0x7F; /* bits 6:0 are chassis type, 7th bit is the lock bit */
|
||||
|
||||
if (code >= 0x01 && code <= 0x1D)
|
||||
if (code >= 0x01 && code <= 0x20)
|
||||
return type[code - 0x01];
|
||||
return out_of_spec;
|
||||
}
|
||||
@ -695,6 +716,7 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver)
|
||||
{ 0x29, "Core Duo Mobile" },
|
||||
{ 0x2A, "Core Solo Mobile" },
|
||||
{ 0x2B, "Atom" },
|
||||
{ 0x2C, "Core M" },
|
||||
|
||||
{ 0x30, "Alpha" },
|
||||
{ 0x31, "Alpha 21064" },
|
||||
@ -712,7 +734,6 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver)
|
||||
{ 0x3D, "Opteron 6200" },
|
||||
{ 0x3E, "Opteron 4200" },
|
||||
{ 0x3F, "FX" },
|
||||
|
||||
{ 0x40, "MIPS" },
|
||||
{ 0x41, "MIPS R4000" },
|
||||
{ 0x42, "MIPS R4200" },
|
||||
@ -729,7 +750,6 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver)
|
||||
{ 0x4D, "Opteron 6300" },
|
||||
{ 0x4E, "Opteron 3300" },
|
||||
{ 0x4F, "FirePro" },
|
||||
|
||||
{ 0x50, "SPARC" },
|
||||
{ 0x51, "SuperSPARC" },
|
||||
{ 0x52, "MicroSPARC II" },
|
||||
@ -746,6 +766,9 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver)
|
||||
{ 0x63, "68010" },
|
||||
{ 0x64, "68020" },
|
||||
{ 0x65, "68030" },
|
||||
{ 0x66, "Athlon X4" },
|
||||
{ 0x67, "Opteron X1000" },
|
||||
{ 0x68, "Opteron X2000" },
|
||||
|
||||
{ 0x70, "Hobbit" },
|
||||
|
||||
@ -821,7 +844,7 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver)
|
||||
{ 0xC9, "G4" },
|
||||
{ 0xCA, "G5" },
|
||||
{ 0xCB, "ESA/390 G6" },
|
||||
{ 0xCC, "z/Architectur" },
|
||||
{ 0xCC, "z/Architecture" },
|
||||
{ 0xCD, "Core i5" },
|
||||
{ 0xCE, "Core i3" },
|
||||
|
||||
@ -1014,11 +1037,11 @@ static void dmi_processor_id(u8 type, const u8 *p, const char *version, const ch
|
||||
sig = 1;
|
||||
else if ((type >= 0x18 && type <= 0x1D) /* AMD */
|
||||
|| type == 0x1F /* AMD */
|
||||
|| (type >= 0x38 && type <= 0x3E) /* AMD */
|
||||
|| (type >= 0x46 && type <= 0x49) /* AMD */
|
||||
|| (type >= 0x38 && type <= 0x3F) /* AMD */
|
||||
|| (type >= 0x46 && type <= 0x4F) /* AMD */
|
||||
|| (type >= 0x83 && type <= 0x8F) /* AMD */
|
||||
|| (type >= 0xB6 && type <= 0xB7) /* AMD */
|
||||
|| (type >= 0xE6 && type <= 0xEF)) /* AMD */
|
||||
|| (type >= 0xE4 && type <= 0xEF)) /* AMD */
|
||||
sig = 2;
|
||||
else if (type == 0x01 || type == 0x02)
|
||||
{
|
||||
@ -1173,10 +1196,14 @@ static const char *dmi_processor_upgrade(u8 code)
|
||||
"Socket FM1",
|
||||
"Socket FM2",
|
||||
"Socket LGA2011-3",
|
||||
"Socket LGA1356-3" /* 0x2C */
|
||||
"Socket LGA1356-3",
|
||||
"Socket LGA1150",
|
||||
"Socket BGA1168",
|
||||
"Socket BGA1234",
|
||||
"Socket BGA1364" /* 0x30 */
|
||||
};
|
||||
|
||||
if (code >= 0x01 && code <= 0x2A)
|
||||
if (code >= 0x01 && code <= 0x30)
|
||||
return upgrade[code - 0x01];
|
||||
return out_of_spec;
|
||||
}
|
||||
@ -1672,7 +1699,20 @@ static const char *dmi_slot_type(u8 code)
|
||||
"AGP 2x",
|
||||
"AGP 4x",
|
||||
"PCI-X",
|
||||
"AGP 8x" /* 0x13 */
|
||||
"AGP 8x",
|
||||
"M.2 Socket 1-DP",
|
||||
"M.2 Socket 1-SD",
|
||||
"M.2 Socket 2",
|
||||
"M.2 Socket 3",
|
||||
"MXM Type I",
|
||||
"MXM Type II",
|
||||
"MXM Type III",
|
||||
"MXM Type III-HE",
|
||||
"MXM Type IV",
|
||||
"MXM 3.0 Type A",
|
||||
"MXM 3.0 Type B",
|
||||
"PCI Express 2 SFF-8639",
|
||||
"PCI Express 3 SFF-8639" /* 0x20 */
|
||||
};
|
||||
static const char *type_0xA0[] = {
|
||||
"PC-98/C20", /* 0xA0 */
|
||||
@ -1699,8 +1739,12 @@ static const char *dmi_slot_type(u8 code)
|
||||
"PCI Express 3 x8",
|
||||
"PCI Express 3 x16" /* 0xB6 */
|
||||
};
|
||||
/*
|
||||
* Note to developers: when adding entries to these lists, check if
|
||||
* function dmi_slot_id below needs updating too.
|
||||
*/
|
||||
|
||||
if (code >= 0x01 && code <= 0x13)
|
||||
if (code >= 0x01 && code <= 0x20)
|
||||
return type[code - 0x01];
|
||||
if (code >= 0xA0 && code <= 0xB6)
|
||||
return type_0xA0[code - 0xA0];
|
||||
@ -1780,6 +1824,8 @@ static void dmi_slot_id(u8 code1, u8 code2, u8 type, const char *prefix)
|
||||
case 0x11: /* AGP */
|
||||
case 0x12: /* PCI-X */
|
||||
case 0x13: /* AGP */
|
||||
case 0x1F: /* PCI Express 2 */
|
||||
case 0x20: /* PCI Express 3 */
|
||||
case 0xA5: /* PCI Express */
|
||||
case 0xA6: /* PCI Express */
|
||||
case 0xA7: /* PCI Express */
|
||||
@ -1792,6 +1838,12 @@ static void dmi_slot_id(u8 code1, u8 code2, u8 type, const char *prefix)
|
||||
case 0xAE: /* PCI Express 2 */
|
||||
case 0xAF: /* PCI Express 2 */
|
||||
case 0xB0: /* PCI Express 2 */
|
||||
case 0xB1: /* PCI Express 3 */
|
||||
case 0xB2: /* PCI Express 3 */
|
||||
case 0xB3: /* PCI Express 3 */
|
||||
case 0xB4: /* PCI Express 3 */
|
||||
case 0xB5: /* PCI Express 3 */
|
||||
case 0xB6: /* PCI Express 3 */
|
||||
printf("%sID: %u\n", prefix, code1);
|
||||
break;
|
||||
case 0x07: /* PCMCIA */
|
||||
@ -2236,7 +2288,7 @@ static void dmi_memory_voltage_value(u16 code)
|
||||
if (code == 0)
|
||||
printf(" Unknown");
|
||||
else
|
||||
printf(" %.3f V", (float)(i16)code / 1000);
|
||||
printf(code % 100 ? " %g V" : " %.1f V", (float)code / 1000);
|
||||
}
|
||||
|
||||
static const char *dmi_memory_device_form_factor(u8 code)
|
||||
@ -2303,10 +2355,15 @@ static const char *dmi_memory_device_type(u8 code)
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"DDR3",
|
||||
"FBD2", /* 0x19 */
|
||||
"FBD2",
|
||||
"DDR4",
|
||||
"LPDDR",
|
||||
"LPDDR2",
|
||||
"LPDDR3",
|
||||
"LPDDR4" /* 0x1E */
|
||||
};
|
||||
|
||||
if (code >= 0x01 && code <= 0x19)
|
||||
if (code >= 0x01 && code <= 0x1E)
|
||||
return type[code - 0x01];
|
||||
return out_of_spec;
|
||||
}
|
||||
@ -2338,7 +2395,7 @@ static void dmi_memory_device_type_detail(u16 code)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= 14; i++)
|
||||
for (i = 1; i <= 15; i++)
|
||||
if (code & (1 << i))
|
||||
printf(" %s", detail[i - 1]);
|
||||
}
|
||||
@ -2883,6 +2940,25 @@ static void dmi_64bit_memory_error_address(u64 code)
|
||||
* 7.35 Management Device (Type 34)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Several boards have a bug where some type 34 structures have their
|
||||
* length incorrectly set to 0x10 instead of 0x0B. This causes the
|
||||
* first 5 characters of the device name to be trimmed. It's easy to
|
||||
* check and fix, so do it, but warn.
|
||||
*/
|
||||
static void dmi_fixup_type_34(struct dmi_header *h)
|
||||
{
|
||||
u8 *p = h->data;
|
||||
|
||||
/* Make sure the hidden data is ASCII only */
|
||||
if (h->length == 0x10
|
||||
&& is_printable(p + 0x0B, 0x10 - 0x0B))
|
||||
{
|
||||
printf("Invalid entry length (%u). Fixed up to %u.\n", 0x10, 0x0B);
|
||||
h->length = 0x0B;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *dmi_management_device_type(u8 code)
|
||||
{
|
||||
/* 7.35.1 */
|
||||
@ -3155,7 +3231,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
|
||||
const u8 *data = h->data;
|
||||
|
||||
/*
|
||||
* Note: DMI types 37, 39 and 40 are untested
|
||||
* Note: DMI types 37 and 42 are untested
|
||||
*/
|
||||
switch (h->type)
|
||||
{
|
||||
@ -3350,11 +3426,17 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
|
||||
dmi_string(h, data[0x22]));
|
||||
if (h->length < 0x28) break;
|
||||
if (data[0x23] != 0)
|
||||
printf("\tCore Count: %u\n", data[0x23]);
|
||||
printf("\tCore Count: %u\n",
|
||||
h->length >= 0x2C && data[0x23] == 0xFF ?
|
||||
WORD(data + 0x2A) : data[0x23]);
|
||||
if (data[0x24] != 0)
|
||||
printf("\tCore Enabled: %u\n", data[0x24]);
|
||||
printf("\tCore Enabled: %u\n",
|
||||
h->length >= 0x2E && data[0x24] == 0xFF ?
|
||||
WORD(data + 0x2C) : data[0x24]);
|
||||
if (data[0x25] != 0)
|
||||
printf("\tThread Count: %u\n", data[0x25]);
|
||||
printf("\tThread Count: %u\n",
|
||||
h->length >= 0x30 && data[0x25] == 0xFF ?
|
||||
WORD(data + 0x2E) : data[0x25]);
|
||||
printf("\tCharacteristics:");
|
||||
dmi_processor_characteristics(WORD(data + 0x26), "\t\t");
|
||||
break;
|
||||
@ -3657,13 +3739,13 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
|
||||
dmi_memory_device_speed(WORD(data + 0x20));
|
||||
printf("\n");
|
||||
if (h->length < 0x28) break;
|
||||
printf("\tMinimum voltage: ");
|
||||
printf("\tMinimum Voltage:");
|
||||
dmi_memory_voltage_value(WORD(data + 0x22));
|
||||
printf("\n");
|
||||
printf("\tMaximum voltage: ");
|
||||
printf("\tMaximum Voltage:");
|
||||
dmi_memory_voltage_value(WORD(data + 0x24));
|
||||
printf("\n");
|
||||
printf("\tConfigured voltage: ");
|
||||
printf("\tConfigured Voltage:");
|
||||
dmi_memory_voltage_value(WORD(data + 0x26));
|
||||
printf("\n");
|
||||
break;
|
||||
@ -4212,8 +4294,9 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
|
||||
|
||||
case 40: /* 7.41 Additional Information */
|
||||
if (h->length < 0x0B) break;
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
dmi_additional_info(h, "");
|
||||
if (opt.flags & FLAG_QUIET)
|
||||
return;
|
||||
dmi_additional_info(h, "");
|
||||
break;
|
||||
|
||||
case 41: /* 7.42 Onboard Device Extended Information */
|
||||
@ -4306,65 +4389,21 @@ static void dmi_table_string(const struct dmi_header *h, const u8 *data, u16 ver
|
||||
}
|
||||
}
|
||||
|
||||
static void dmi_table_dump(u32 base, u16 len, const char *devmem)
|
||||
static void dmi_table_dump(const u8 *buf, u32 len)
|
||||
{
|
||||
u8 *buf;
|
||||
|
||||
if ((buf = mem_chunk(base, len, devmem)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to read table, sorry.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
printf("# Writing %d bytes to %s.\n", len, opt.dumpfile);
|
||||
write_dump(32, len, buf, opt.dumpfile, 0);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem)
|
||||
static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags)
|
||||
{
|
||||
u8 *buf;
|
||||
u8 *data;
|
||||
int i = 0;
|
||||
|
||||
if (ver > SUPPORTED_SMBIOS_VER)
|
||||
{
|
||||
printf("# SMBIOS implementations newer than version %u.%u are not\n"
|
||||
"# fully supported by this version of dmidecode.\n",
|
||||
SUPPORTED_SMBIOS_VER >> 8, SUPPORTED_SMBIOS_VER & 0xFF);
|
||||
}
|
||||
|
||||
if (opt.flags & FLAG_DUMP_BIN)
|
||||
{
|
||||
dmi_table_dump(base, len, devmem);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
{
|
||||
if (opt.type == NULL)
|
||||
{
|
||||
printf("%u structures occupying %u bytes.\n",
|
||||
num, len);
|
||||
if (!(opt.flags & FLAG_FROM_DUMP))
|
||||
printf("Table at 0x%08X.\n", base);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if ((buf = mem_chunk(base, len, devmem)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Table is unreachable, sorry."
|
||||
#ifndef USE_MMAP
|
||||
" Try compiling dmidecode with -DUSE_MMAP."
|
||||
#endif
|
||||
"\n");
|
||||
return;
|
||||
}
|
||||
|
||||
data = buf;
|
||||
while (i < num && data+4 <= buf + len) /* 4 is the length of an SMBIOS structure header */
|
||||
while ((i < num || !num)
|
||||
&& data + 4 <= buf + len) /* 4 is the length of an SMBIOS structure header */
|
||||
{
|
||||
u8 *next;
|
||||
struct dmi_header h;
|
||||
@ -4372,7 +4411,7 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem)
|
||||
|
||||
to_dmi_header(&h, data);
|
||||
display = ((opt.type == NULL || opt.type[h.type])
|
||||
&& !((opt.flags & FLAG_QUIET) && (h.type > 39 && h.type <= 127))
|
||||
&& !((opt.flags & FLAG_QUIET) && (h.type == 126 || h.type == 127))
|
||||
&& !opt.string);
|
||||
|
||||
/*
|
||||
@ -4399,17 +4438,22 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem)
|
||||
h.handle, h.type, h.length);
|
||||
|
||||
/* assign vendor for vendor-specific decodes later */
|
||||
if (h.type == 0 && h.length >= 5)
|
||||
if (h.type == 1 && h.length >= 5)
|
||||
dmi_set_vendor(dmi_string(&h, data[0x04]));
|
||||
|
||||
/* Fixup a common mistake */
|
||||
if (h.type == 34)
|
||||
dmi_fixup_type_34(&h);
|
||||
|
||||
/* look for the next handle */
|
||||
next = data + h.length;
|
||||
while (next - buf + 1 < len && (next[0] != 0 || next[1] != 0))
|
||||
while ((unsigned long)(next - buf + 1) < len
|
||||
&& (next[0] != 0 || next[1] != 0))
|
||||
next++;
|
||||
next += 2;
|
||||
if (display)
|
||||
{
|
||||
if (next - buf <= len)
|
||||
if ((unsigned long)(next - buf) <= len)
|
||||
{
|
||||
if (opt.flags & FLAG_DUMP)
|
||||
{
|
||||
@ -4428,19 +4472,79 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem)
|
||||
|
||||
data = next;
|
||||
i++;
|
||||
|
||||
/* SMBIOS v3 requires stopping at this marker */
|
||||
if (h.type == 127 && (flags & FLAG_STOP_AT_EOT))
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* SMBIOS v3 64-bit entry points do not announce a structures count,
|
||||
* and only indicate a maximum size for the table.
|
||||
*/
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
{
|
||||
if (num && i != num)
|
||||
printf("Wrong DMI structures count: %d announced, "
|
||||
"only %d decoded.\n", num, i);
|
||||
if ((unsigned long)(data - buf) > len
|
||||
|| (num && (unsigned long)(data - buf) < len))
|
||||
printf("Wrong DMI structures length: %u bytes "
|
||||
"announced, structures occupy %lu bytes.\n",
|
||||
len, (unsigned long)(data - buf));
|
||||
}
|
||||
}
|
||||
|
||||
static void dmi_table(off_t base, u32 len, u16 num, u16 ver, const char *devmem,
|
||||
u32 flags)
|
||||
{
|
||||
u8 *buf;
|
||||
|
||||
if (ver > SUPPORTED_SMBIOS_VER && !(opt.flags & FLAG_QUIET))
|
||||
{
|
||||
printf("# SMBIOS implementations newer than version %u.%u are not\n"
|
||||
"# fully supported by this version of dmidecode.\n",
|
||||
SUPPORTED_SMBIOS_VER >> 8, SUPPORTED_SMBIOS_VER & 0xFF);
|
||||
}
|
||||
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
{
|
||||
if (i != num)
|
||||
printf("Wrong DMI structures count: %d announced, "
|
||||
"only %d decoded.\n", num, i);
|
||||
if (data - buf != len)
|
||||
printf("Wrong DMI structures length: %d bytes "
|
||||
"announced, structures occupy %d bytes.\n",
|
||||
len, (unsigned int)(data - buf));
|
||||
if (opt.type == NULL)
|
||||
{
|
||||
if (num)
|
||||
printf("%u structures occupying %u bytes.\n",
|
||||
num, len);
|
||||
if (!(opt.flags & FLAG_FROM_DUMP))
|
||||
printf("Table at 0x%08llX.\n",
|
||||
(unsigned long long)base);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* When we are reading the DMI table from sysfs, we want to print
|
||||
* the address of the table (done above), but the offset of the
|
||||
* data in the file is 0. When reading from /dev/mem, the offset
|
||||
* in the file is the address.
|
||||
*/
|
||||
if (flags & FLAG_NO_FILE_OFFSET)
|
||||
base = 0;
|
||||
|
||||
if ((buf = mem_chunk(base, len, devmem)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Table is unreachable, sorry."
|
||||
#ifndef USE_MMAP
|
||||
" Try compiling dmidecode with -DUSE_MMAP."
|
||||
#endif
|
||||
"\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (opt.flags & FLAG_DUMP_BIN)
|
||||
dmi_table_dump(buf, len);
|
||||
else
|
||||
dmi_table_decode(buf, len, num, ver, flags);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
@ -4459,7 +4563,61 @@ static void overwrite_dmi_address(u8 *buf)
|
||||
buf[0x0B] = 0;
|
||||
}
|
||||
|
||||
static int smbios_decode(u8 *buf, const char *devmem)
|
||||
/* Same thing for SMBIOS3 entry points */
|
||||
static void overwrite_smbios3_address(u8 *buf)
|
||||
{
|
||||
buf[0x05] += buf[0x10] + buf[0x11] + buf[0x12] + buf[0x13]
|
||||
+ buf[0x14] + buf[0x15] + buf[0x16] + buf[0x17] - 32;
|
||||
buf[0x10] = 32;
|
||||
buf[0x11] = 0;
|
||||
buf[0x12] = 0;
|
||||
buf[0x13] = 0;
|
||||
buf[0x14] = 0;
|
||||
buf[0x15] = 0;
|
||||
buf[0x16] = 0;
|
||||
buf[0x17] = 0;
|
||||
}
|
||||
|
||||
static int smbios3_decode(u8 *buf, const char *devmem, u32 flags)
|
||||
{
|
||||
u16 ver;
|
||||
u64 offset;
|
||||
|
||||
if (!checksum(buf, buf[0x06]))
|
||||
return 0;
|
||||
|
||||
ver = (buf[0x07] << 8) + buf[0x08];
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
printf("SMBIOS %u.%u.%u present.\n",
|
||||
buf[0x07], buf[0x08], buf[0x09]);
|
||||
|
||||
offset = QWORD(buf + 0x10);
|
||||
if (!(flags & FLAG_NO_FILE_OFFSET) && offset.h && sizeof(off_t) < 8)
|
||||
{
|
||||
fprintf(stderr, "64-bit addresses not supported, sorry.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
dmi_table(((off_t)offset.h << 32) | offset.l,
|
||||
WORD(buf + 0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT);
|
||||
|
||||
if (opt.flags & FLAG_DUMP_BIN)
|
||||
{
|
||||
u8 crafted[32];
|
||||
|
||||
memcpy(crafted, buf, 32);
|
||||
overwrite_smbios3_address(crafted);
|
||||
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
printf("# Writing %d bytes to %s.\n", crafted[0x06],
|
||||
opt.dumpfile);
|
||||
write_dump(0, crafted[0x06], crafted, opt.dumpfile, 1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int smbios_decode(u8 *buf, const char *devmem, u32 flags)
|
||||
{
|
||||
u16 ver;
|
||||
|
||||
@ -4491,7 +4649,7 @@ static int smbios_decode(u8 *buf, const char *devmem)
|
||||
ver >> 8, ver & 0xFF);
|
||||
|
||||
dmi_table(DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C),
|
||||
ver, devmem);
|
||||
ver, devmem, flags);
|
||||
|
||||
if (opt.flags & FLAG_DUMP_BIN)
|
||||
{
|
||||
@ -4509,7 +4667,7 @@ static int smbios_decode(u8 *buf, const char *devmem)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int legacy_decode(u8 *buf, const char *devmem)
|
||||
static int legacy_decode(u8 *buf, const char *devmem, u32 flags)
|
||||
{
|
||||
if (!checksum(buf, 0x0F))
|
||||
return 0;
|
||||
@ -4519,7 +4677,7 @@ static int legacy_decode(u8 *buf, const char *devmem)
|
||||
buf[0x0E] >> 4, buf[0x0E] & 0x0F);
|
||||
|
||||
dmi_table(DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C),
|
||||
((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem);
|
||||
((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem, flags);
|
||||
|
||||
if (opt.flags & FLAG_DUMP_BIN)
|
||||
{
|
||||
@ -4528,7 +4686,9 @@ static int legacy_decode(u8 *buf, const char *devmem)
|
||||
memcpy(crafted, buf, 16);
|
||||
overwrite_dmi_address(crafted);
|
||||
|
||||
printf("# Writing %d bytes to %s.\n", 0x0F, opt.dumpfile);
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
printf("# Writing %d bytes to %s.\n", 0x0F,
|
||||
opt.dumpfile);
|
||||
write_dump(0, 0x0F, crafted, opt.dumpfile, 1);
|
||||
}
|
||||
|
||||
@ -4540,7 +4700,7 @@ static int legacy_decode(u8 *buf, const char *devmem)
|
||||
*/
|
||||
#define EFI_NOT_FOUND (-1)
|
||||
#define EFI_NO_SMBIOS (-2)
|
||||
static int address_from_efi(size_t *address)
|
||||
static int address_from_efi(off_t *address)
|
||||
{
|
||||
FILE *efi_systab;
|
||||
const char *filename;
|
||||
@ -4564,12 +4724,13 @@ static int address_from_efi(size_t *address)
|
||||
{
|
||||
char *addrp = strchr(linebuf, '=');
|
||||
*(addrp++) = '\0';
|
||||
if (strcmp(linebuf, "SMBIOS") == 0)
|
||||
if (strcmp(linebuf, "SMBIOS3") == 0
|
||||
|| strcmp(linebuf, "SMBIOS") == 0)
|
||||
{
|
||||
*address = strtoul(addrp, NULL, 0);
|
||||
*address = strtoull(addrp, NULL, 0);
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
printf("# SMBIOS entry point at 0x%08lx\n",
|
||||
(unsigned long)*address);
|
||||
printf("# %s entry point at 0x%08llx\n",
|
||||
linebuf, (unsigned long long)*address);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
@ -4586,7 +4747,7 @@ int main(int argc, char * const argv[])
|
||||
{
|
||||
int ret = 0; /* Returned value */
|
||||
int found = 0;
|
||||
size_t fp;
|
||||
off_t fp;
|
||||
int efi;
|
||||
u8 *buf;
|
||||
|
||||
@ -4633,20 +4794,57 @@ int main(int argc, char * const argv[])
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
if (memcmp(buf, "_SM_", 4) == 0)
|
||||
if (memcmp(buf, "_SM3_", 5) == 0)
|
||||
{
|
||||
if (smbios_decode(buf, opt.dumpfile))
|
||||
if (smbios3_decode(buf, opt.dumpfile, 0))
|
||||
found++;
|
||||
}
|
||||
else if (memcmp(buf, "_SM_", 4) == 0)
|
||||
{
|
||||
if (smbios_decode(buf, opt.dumpfile, 0))
|
||||
found++;
|
||||
}
|
||||
else if (memcmp(buf, "_DMI_", 5) == 0)
|
||||
{
|
||||
if (legacy_decode(buf, opt.dumpfile))
|
||||
if (legacy_decode(buf, opt.dumpfile, 0))
|
||||
found++;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* First try EFI (ia64, Intel-based Mac) */
|
||||
/*
|
||||
* First try reading from sysfs tables. The entry point file could
|
||||
* contain one of several types of entry points, so read enough for
|
||||
* the largest one, then determine what type it contains.
|
||||
*/
|
||||
if (!(opt.flags & FLAG_NO_SYSFS)
|
||||
&& (buf = read_file(0x20, SYS_ENTRY_FILE)) != NULL)
|
||||
{
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
printf("Getting SMBIOS data from sysfs.\n");
|
||||
if (memcmp(buf, "_SM3_", 5) == 0)
|
||||
{
|
||||
if (smbios3_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET))
|
||||
found++;
|
||||
}
|
||||
else if (memcmp(buf, "_SM_", 4) == 0)
|
||||
{
|
||||
if (smbios_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET))
|
||||
found++;
|
||||
}
|
||||
else if (memcmp(buf, "_DMI_", 5) == 0)
|
||||
{
|
||||
if (legacy_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET))
|
||||
found++;
|
||||
}
|
||||
|
||||
if (found)
|
||||
goto done;
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
printf("Failed to get SMBIOS data from sysfs.\n");
|
||||
}
|
||||
|
||||
/* Next try EFI (ia64, Intel-based Mac) */
|
||||
efi = address_from_efi(&fp);
|
||||
switch (efi)
|
||||
{
|
||||
@ -4657,17 +4855,22 @@ int main(int argc, char * const argv[])
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
printf("Found SMBIOS entry point in EFI, reading table from %s.\n",
|
||||
opt.devmem);
|
||||
if ((buf = mem_chunk(fp, 0x20, opt.devmem)) == NULL)
|
||||
{
|
||||
ret = 1;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
if (smbios_decode(buf, opt.devmem))
|
||||
if (smbios_decode(buf, opt.devmem, 0))
|
||||
found++;
|
||||
goto done;
|
||||
|
||||
memory_scan:
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
printf("Scanning %s for entry point.\n", opt.devmem);
|
||||
/* Fallback to memory scan (x86, x86_64) */
|
||||
if ((buf = mem_chunk(0xF0000, 0x10000, opt.devmem)) == NULL)
|
||||
{
|
||||
@ -4677,9 +4880,17 @@ memory_scan:
|
||||
|
||||
for (fp = 0; fp <= 0xFFF0; fp += 16)
|
||||
{
|
||||
if (memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0)
|
||||
if (memcmp(buf + fp, "_SM3_", 5) == 0 && fp <= 0xFFE0)
|
||||
{
|
||||
if (smbios_decode(buf+fp, opt.devmem))
|
||||
if (smbios3_decode(buf + fp, opt.devmem, 0))
|
||||
{
|
||||
found++;
|
||||
fp += 16;
|
||||
}
|
||||
}
|
||||
else if (memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0)
|
||||
{
|
||||
if (smbios_decode(buf + fp, opt.devmem, 0))
|
||||
{
|
||||
found++;
|
||||
fp += 16;
|
||||
@ -4687,7 +4898,7 @@ memory_scan:
|
||||
}
|
||||
else if (memcmp(buf + fp, "_DMI_", 5) == 0)
|
||||
{
|
||||
if (legacy_decode(buf + fp, opt.devmem))
|
||||
if (legacy_decode(buf + fp, opt.devmem, 0))
|
||||
found++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2005-2008 Jean Delvare <khali@linux-fr.org>
|
||||
* Copyright (C) 2005-2008 Jean Delvare <jdelvare@suse.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -18,6 +18,8 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
|
||||
struct dmi_header
|
||||
{
|
||||
u8 type;
|
||||
@ -26,4 +28,5 @@ struct dmi_header
|
||||
u8 *data;
|
||||
};
|
||||
|
||||
int is_printable(const u8 *data, int len);
|
||||
const char *dmi_string(const struct dmi_header *dm, u8 s);
|
||||
|
||||
197
dmioem.c
197
dmioem.c
@ -2,7 +2,7 @@
|
||||
* Decoding of OEM-specific entries
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2007-2008 Jean Delvare <khali@linux-fr.org>
|
||||
* Copyright (C) 2007-2008 Jean Delvare <jdelvare@suse.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -30,7 +30,12 @@
|
||||
* Globals for vendor-specific decodes
|
||||
*/
|
||||
|
||||
enum DMI_VENDORS { VENDOR_UNKNOWN, VENDOR_HP };
|
||||
enum DMI_VENDORS
|
||||
{
|
||||
VENDOR_UNKNOWN,
|
||||
VENDOR_HP,
|
||||
VENDOR_ACER,
|
||||
};
|
||||
|
||||
static enum DMI_VENDORS dmi_vendor = VENDOR_UNKNOWN;
|
||||
|
||||
@ -41,20 +46,58 @@ static enum DMI_VENDORS dmi_vendor = VENDOR_UNKNOWN;
|
||||
*/
|
||||
void dmi_set_vendor(const char *s)
|
||||
{
|
||||
if (strcmp(s, "HP") == 0 || strcmp(s, "Hewlett-Packard") == 0)
|
||||
int len;
|
||||
|
||||
/*
|
||||
* Often DMI strings have trailing spaces. Ignore these
|
||||
* when checking for known vendor names.
|
||||
*/
|
||||
len = strlen(s);
|
||||
while (len && s[len - 1] == ' ')
|
||||
len--;
|
||||
|
||||
if (strncmp(s, "HP", len) == 0 || strncmp(s, "Hewlett-Packard", len) == 0)
|
||||
dmi_vendor = VENDOR_HP;
|
||||
else if (strncmp(s, "Acer", len) == 0)
|
||||
dmi_vendor = VENDOR_ACER;
|
||||
}
|
||||
|
||||
/*
|
||||
* HP-specific data structures are decoded here.
|
||||
*
|
||||
* Code contributed by John Cagle.
|
||||
* Code contributed by John Cagle and Tyler Bell.
|
||||
*/
|
||||
|
||||
static void dmi_print_hp_net_iface_rec(u8 id, u8 bus, u8 dev, const u8 *mac)
|
||||
{
|
||||
/* Some systems do not provide an id. nic_ctr provides an artificial
|
||||
* id, and assumes the records will be provided "in order". Also,
|
||||
* using 0xFF marker is not future proof. 256 NICs is a lot, but
|
||||
* 640K ought to be enough for anybody(said no one, ever).
|
||||
* */
|
||||
static u8 nic_ctr;
|
||||
|
||||
if (id == 0xFF)
|
||||
id = ++nic_ctr;
|
||||
|
||||
if (dev == 0x00 && bus == 0x00)
|
||||
printf("\tNIC %d: Disabled\n", id);
|
||||
else if (dev == 0xFF && bus == 0xFF)
|
||||
printf("\tNIC %d: Not Installed\n", id);
|
||||
else
|
||||
{
|
||||
printf("\tNIC %d: PCI device %02x:%02x.%x, "
|
||||
"MAC address %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
id, bus, dev >> 3, dev & 7,
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
}
|
||||
}
|
||||
|
||||
static int dmi_decode_hp(const struct dmi_header *h)
|
||||
{
|
||||
u8 *data = h->data;
|
||||
int nic, ptr;
|
||||
u32 feat;
|
||||
|
||||
switch (h->type)
|
||||
{
|
||||
@ -80,6 +123,19 @@ static int dmi_decode_hp(const struct dmi_header *h)
|
||||
*
|
||||
* This prints the BIOS NIC number,
|
||||
* PCI bus/device/function, and MAC address
|
||||
*
|
||||
* Type 209:
|
||||
* Offset | Name | Width | Description
|
||||
* -------------------------------------
|
||||
* 0x00 | Type | BYTE | 0xD1, MAC Info
|
||||
* 0x01 | Length | BYTE | Length of structure
|
||||
* 0x02 | Handle | WORD | Unique handle
|
||||
* 0x04 | Dev No | BYTE | PCI Device/Function No
|
||||
* 0x05 | Bus No | BYTE | PCI Bus
|
||||
* 0x06 | MAC | 6B | MAC addr
|
||||
* 0x0C | NIC #2 | 8B | Repeat 0x04-0x0B
|
||||
*
|
||||
* Type 221: is deprecated in the latest docs
|
||||
*/
|
||||
printf(h->type == 221 ?
|
||||
"HP BIOS iSCSI NIC PCI and MAC Information\n" :
|
||||
@ -88,25 +144,128 @@ static int dmi_decode_hp(const struct dmi_header *h)
|
||||
ptr = 4;
|
||||
while (h->length >= ptr + 8)
|
||||
{
|
||||
if (data[ptr] == 0x00 && data[ptr + 1] == 0x00)
|
||||
printf("\tNIC %d: Disabled\n", nic);
|
||||
else if (data[ptr] == 0xFF && data[ptr + 1] == 0xFF)
|
||||
printf("\tNIC %d: Not Installed\n", nic);
|
||||
else
|
||||
{
|
||||
printf("\tNIC %d: PCI device %02x:%02x.%x, "
|
||||
"MAC address %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
nic, data[ptr + 1],
|
||||
data[ptr] >> 3, data[ptr] & 7,
|
||||
data[ptr + 2], data[ptr + 3],
|
||||
data[ptr + 4], data[ptr + 5],
|
||||
data[ptr + 6], data[ptr + 7]);
|
||||
}
|
||||
dmi_print_hp_net_iface_rec(nic,
|
||||
data[ptr + 0x01],
|
||||
data[ptr],
|
||||
&data[ptr + 0x02]);
|
||||
nic++;
|
||||
ptr += 8;
|
||||
}
|
||||
break;
|
||||
|
||||
case 233:
|
||||
/*
|
||||
* Vendor Specific: HP ProLiant NIC MAC Information
|
||||
*
|
||||
* This prints the BIOS NIC number,
|
||||
* PCI bus/device/function, and MAC address
|
||||
*
|
||||
* Offset | Name | Width | Description
|
||||
* -------------------------------------
|
||||
* 0x00 | Type | BYTE | 0xE9, NIC structure
|
||||
* 0x01 | Length | BYTE | Length of structure
|
||||
* 0x02 | Handle | WORD | Unique handle
|
||||
* 0x04 | Grp No | WORD | 0 for single segment
|
||||
* 0x06 | Bus No | BYTE | PCI Bus
|
||||
* 0x07 | Dev No | BYTE | PCI Device/Function No
|
||||
* 0x08 | MAC | 32B | MAC addr padded w/ 0s
|
||||
* 0x28 | Port No| BYTE | Each NIC maps to a Port
|
||||
*/
|
||||
printf("HP BIOS PXE NIC PCI and MAC Information\n");
|
||||
if (h->length < 0x0E) break;
|
||||
/* If the record isn't long enough, we don't have an ID
|
||||
* use 0xFF to use the internal counter.
|
||||
* */
|
||||
nic = h->length > 0x28 ? data[0x28] : 0xFF;
|
||||
dmi_print_hp_net_iface_rec(nic, data[0x06], data[0x07],
|
||||
&data[0x08]);
|
||||
break;
|
||||
|
||||
case 212:
|
||||
/*
|
||||
* Vendor Specific: HP 64-bit CRU Information
|
||||
*
|
||||
* Source: hpwdt kernel driver
|
||||
*/
|
||||
printf("HP 64-bit CRU Information\n");
|
||||
if (h->length < 0x18) break;
|
||||
printf("\tSignature: 0x%08x", DWORD(data + 0x04));
|
||||
if (is_printable(data + 0x04, 4))
|
||||
printf(" (%c%c%c%c)", data[0x04], data[0x05],
|
||||
data[0x06], data[0x07]);
|
||||
printf("\n");
|
||||
if (DWORD(data + 0x04) == 0x55524324)
|
||||
{
|
||||
u64 paddr = QWORD(data + 0x08);
|
||||
paddr.l += DWORD(data + 0x14);
|
||||
if (paddr.l < DWORD(data + 0x14))
|
||||
paddr.h++;
|
||||
printf("\tPhysical Address: 0x%08x%08x\n",
|
||||
paddr.h, paddr.l);
|
||||
printf("\tLength: 0x%08x\n", DWORD(data + 0x10));
|
||||
}
|
||||
break;
|
||||
|
||||
case 219:
|
||||
/*
|
||||
* Vendor Specific: HP ProLiant Information
|
||||
*
|
||||
* Source: hpwdt kernel driver
|
||||
*/
|
||||
printf("HP ProLiant Information\n");
|
||||
if (h->length < 0x08) break;
|
||||
printf("\tPower Features: 0x%08x\n", DWORD(data + 0x04));
|
||||
if (h->length < 0x0C) break;
|
||||
printf("\tOmega Features: 0x%08x\n", DWORD(data + 0x08));
|
||||
if (h->length < 0x14) break;
|
||||
feat = DWORD(data + 0x10);
|
||||
printf("\tMisc. Features: 0x%08x\n", feat);
|
||||
printf("\t\tiCRU: %s\n", feat & 0x0001 ? "Yes" : "No");
|
||||
printf("\t\tUEFI: %s\n", feat & 0x0408 ? "Yes" : "No");
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Acer-specific data structures are decoded here.
|
||||
*/
|
||||
|
||||
static int dmi_decode_acer(const struct dmi_header *h)
|
||||
{
|
||||
u8 *data = h->data;
|
||||
u16 cap;
|
||||
|
||||
switch (h->type)
|
||||
{
|
||||
case 170:
|
||||
/*
|
||||
* Vendor Specific: Acer Hotkey Function
|
||||
*
|
||||
* Source: acer-wmi kernel driver
|
||||
*
|
||||
* Probably applies to some laptop models of other
|
||||
* brands, including Fujitsu-Siemens, Medion, Lenovo,
|
||||
* and eMachines.
|
||||
*/
|
||||
printf("Acer Hotkey Function\n");
|
||||
if (h->length < 0x0F) break;
|
||||
cap = WORD(data + 0x04);
|
||||
printf("\tFunction bitmap for Communication Button: 0x%04hx\n", cap);
|
||||
printf("\t\tWiFi: %s\n", cap & 0x0001 ? "Yes" : "No");
|
||||
printf("\t\t3G: %s\n", cap & 0x0040 ? "Yes" : "No");
|
||||
printf("\t\tWiMAX: %s\n", cap & 0x0080 ? "Yes" : "No");
|
||||
printf("\t\tBluetooth: %s\n", cap & 0x0800 ? "Yes" : "No");
|
||||
printf("\tFunction bitmap for Application Button: 0x%04hx\n", WORD(data + 0x06));
|
||||
printf("\tFunction bitmap for Media Button: 0x%04hx\n", WORD(data + 0x08));
|
||||
printf("\tFunction bitmap for Display Button: 0x%04hx\n", WORD(data + 0x0A));
|
||||
printf("\tFunction bitmap for Others Button: 0x%04hx\n", WORD(data + 0x0C));
|
||||
printf("\tCommunication Function Key Number: %d\n", data[0x0E]);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -123,6 +282,8 @@ int dmi_decode_oem(const struct dmi_header *h)
|
||||
{
|
||||
case VENDOR_HP:
|
||||
return dmi_decode_hp(h);
|
||||
case VENDOR_ACER:
|
||||
return dmi_decode_acer(h);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
2
dmioem.h
2
dmioem.h
@ -2,7 +2,7 @@
|
||||
* Decoding of OEM-specific entries
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2007-2008 Jean Delvare <khali@linux-fr.org>
|
||||
* Copyright (C) 2007-2008 Jean Delvare <jdelvare@suse.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
8
dmiopt.c
8
dmiopt.c
@ -2,7 +2,7 @@
|
||||
* Command line handling of dmidecode
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2005-2008 Jean Delvare <khali@linux-fr.org>
|
||||
* Copyright (C) 2005-2008 Jean Delvare <jdelvare@suse.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -225,8 +225,9 @@ int parse_command_line(int argc, char * const argv[])
|
||||
{ "dump", no_argument, NULL, 'u' },
|
||||
{ "dump-bin", required_argument, NULL, 'B' },
|
||||
{ "from-dump", required_argument, NULL, 'F' },
|
||||
{ "no-sysfs", no_argument, NULL, 'S' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ 0, 0, 0, 0 }
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
while ((option = getopt_long(argc, argv, optstring, longopts, NULL)) != -1)
|
||||
@ -262,6 +263,9 @@ int parse_command_line(int argc, char * const argv[])
|
||||
case 'u':
|
||||
opt.flags |= FLAG_DUMP;
|
||||
break;
|
||||
case 'S':
|
||||
opt.flags |= FLAG_NO_SYSFS;
|
||||
break;
|
||||
case 'V':
|
||||
opt.flags |= FLAG_VERSION;
|
||||
break;
|
||||
|
||||
5
dmiopt.h
5
dmiopt.h
@ -2,7 +2,7 @@
|
||||
* Command line handling of dmidecode
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2005-2008 Jean Delvare <khali@linux-fr.org>
|
||||
* Copyright (C) 2005-2008 Jean Delvare <jdelvare@suse.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -19,6 +19,8 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
|
||||
struct string_keyword
|
||||
{
|
||||
const char *keyword;
|
||||
@ -42,6 +44,7 @@ extern struct opt opt;
|
||||
#define FLAG_QUIET (1 << 3)
|
||||
#define FLAG_DUMP_BIN (1 << 4)
|
||||
#define FLAG_FROM_DUMP (1 << 5)
|
||||
#define FLAG_NO_SYSFS (1 << 6)
|
||||
|
||||
int parse_command_line(int argc, char * const argv[]);
|
||||
void print_help(void);
|
||||
|
||||
@ -52,7 +52,7 @@ for a more detailed output.
|
||||
.B biosdecode
|
||||
started its life as a part of
|
||||
.B dmidecode
|
||||
but as more entry point types were added, if was moved to a different
|
||||
but as more entry point types were added, it was moved to a different
|
||||
program.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
@ -25,8 +25,12 @@ and developed by the \s-1DMTF\s0 (Desktop Management Task Force).
|
||||
|
||||
As you run it,
|
||||
.B dmidecode
|
||||
will try to locate the \s-1DMI\s0 table. If it succeeds, it will then parse
|
||||
this table and display a list of records like this one:
|
||||
will try to locate the \s-1DMI\s0 table. It will first try to read the DMI table
|
||||
from sysfs, and next try reading directly from memory if sysfs access failed.
|
||||
If
|
||||
.B dmidecode
|
||||
succeeds in locating a valid DMI table, it will then parse this table
|
||||
and display a list of records like this one:
|
||||
|
||||
Handle 0x0002, DMI type 2, 8 bytes.
|
||||
Base Board Information
|
||||
@ -89,6 +93,13 @@ keywords is printed and
|
||||
.B dmidecode
|
||||
exits with an error.
|
||||
This option cannot be used more than once.
|
||||
|
||||
Note: on Linux, most of these strings can alternatively be read directly
|
||||
from
|
||||
.BR sysfs ,
|
||||
typically from files under
|
||||
.IR /sys/devices/virtual/dmi/id .
|
||||
Most of these files are even readable by regular users.
|
||||
.TP
|
||||
.BR "-t" ", " "--type TYPE"
|
||||
Only display the entries of type \fBTYPE\fR. \fBTYPE\fR can be either a
|
||||
@ -119,6 +130,10 @@ later.
|
||||
Read the DMI data from a binary file previously generated using
|
||||
\fB--dump-bin\fR.
|
||||
.TP
|
||||
.BR " " " " "--no-sysfs"
|
||||
Do not attempt to read DMI data from sysfs files. This is mainly useful for
|
||||
debugging.
|
||||
.TP
|
||||
.BR "-h" ", " "--help"
|
||||
Display usage information and exit
|
||||
.TP
|
||||
@ -234,6 +249,8 @@ The DMI table is located at offset 0x20.
|
||||
|
||||
.SH FILES
|
||||
.I /dev/mem
|
||||
.I /sys/firmware/dmi/tables/smbios_entry_point (Linux only)
|
||||
.I /sys/firmware/dmi/tables/DMI (Linux only)
|
||||
.SH BUGS
|
||||
More often than not, information contained in the \s-1DMI\s0 tables is inaccurate,
|
||||
incomplete or simply wrong.
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Compaq Ownership Tag
|
||||
*
|
||||
* Copyright (C) 2003-2005 Jean Delvare <khali@linux-fr.org>
|
||||
* Copyright (C) 2003-2005 Jean Delvare <jdelvare@suse.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -119,7 +119,7 @@ static int parse_command_line(int argc, char * const argv[])
|
||||
{ "dev-mem", required_argument, NULL, 'd' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ 0, 0, 0, 0 }
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
while ((option = getopt_long(argc, argv, optstring, longopts, NULL)) != -1)
|
||||
|
||||
68
util.c
68
util.c
@ -2,7 +2,7 @@
|
||||
* Common "util" functions
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2002-2010 Jean Delvare <khali@linux-fr>
|
||||
* Copyright (C) 2002-2015 Jean Delvare <jdelvare@suse.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -88,16 +88,71 @@ int checksum(const u8 *buf, size_t len)
|
||||
return (sum == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads all of file, up to max_len bytes.
|
||||
* A buffer of max_len bytes is allocated by this function, and
|
||||
* needs to be freed by the caller.
|
||||
* This provides a similar usage model to mem_chunk()
|
||||
*
|
||||
* Returns pointer to buffer of max_len bytes, or NULL on error
|
||||
*
|
||||
*/
|
||||
void *read_file(size_t max_len, const char *filename)
|
||||
{
|
||||
int fd;
|
||||
size_t r2 = 0;
|
||||
ssize_t r;
|
||||
u8 *p;
|
||||
|
||||
/*
|
||||
* Don't print error message on missing file, as we will try to read
|
||||
* files that may or may not be present.
|
||||
*/
|
||||
if ((fd = open(filename, O_RDONLY)) == -1)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
perror(filename);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if ((p = malloc(max_len)) == NULL)
|
||||
{
|
||||
perror("malloc");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
r = read(fd, p + r2, max_len - r2);
|
||||
if (r == -1)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
{
|
||||
close(fd);
|
||||
perror(filename);
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
r2 += r;
|
||||
}
|
||||
while (r != 0);
|
||||
|
||||
close(fd);
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a physical memory chunk into a memory buffer.
|
||||
* This function allocates memory.
|
||||
*/
|
||||
void *mem_chunk(size_t base, size_t len, const char *devmem)
|
||||
void *mem_chunk(off_t base, size_t len, const char *devmem)
|
||||
{
|
||||
void *p;
|
||||
int fd;
|
||||
#ifdef USE_MMAP
|
||||
size_t mmoffset;
|
||||
off_t mmoffset;
|
||||
void *mmp;
|
||||
#endif
|
||||
|
||||
@ -124,7 +179,7 @@ void *mem_chunk(size_t base, size_t len, const char *devmem)
|
||||
* but to workaround problems many people encountered when trying
|
||||
* to read from /dev/mem using regular read() calls.
|
||||
*/
|
||||
mmp = mmap(0, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset);
|
||||
mmp = mmap(NULL, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset);
|
||||
if (mmp == MAP_FAILED)
|
||||
goto try_read;
|
||||
|
||||
@ -138,9 +193,8 @@ void *mem_chunk(size_t base, size_t len, const char *devmem)
|
||||
|
||||
goto out;
|
||||
|
||||
#endif /* USE_MMAP */
|
||||
|
||||
try_read:
|
||||
#endif /* USE_MMAP */
|
||||
if (lseek(fd, base, SEEK_SET) == -1)
|
||||
{
|
||||
fprintf(stderr, "%s: ", devmem);
|
||||
@ -155,7 +209,9 @@ try_read:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef USE_MMAP
|
||||
out:
|
||||
#endif
|
||||
if (close(fd) == -1)
|
||||
perror(devmem);
|
||||
|
||||
|
||||
5
util.h
5
util.h
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org>
|
||||
* Copyright (C) 2003-2015 Jean Delvare <jdelvare@suse.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -25,6 +25,7 @@
|
||||
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
int checksum(const u8 *buf, size_t len);
|
||||
void *mem_chunk(size_t base, size_t len, const char *devmem);
|
||||
void *read_file(size_t len, const char *filename);
|
||||
void *mem_chunk(off_t base, size_t len, const char *devmem);
|
||||
int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, int add);
|
||||
u64 u64_range(u64 start, u64 end);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* IBM Vital Product Data decoder
|
||||
*
|
||||
* Copyright (C) 2003-2007 Jean Delvare <khali@linux-fr.org>
|
||||
* Copyright (C) 2003-2007 Jean Delvare <jdelvare@suse.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
4
vpdopt.c
4
vpdopt.c
@ -2,7 +2,7 @@
|
||||
* Command line handling of vpddecode
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2005-2007 Jean Delvare <khali@linux-fr.org>
|
||||
* Copyright (C) 2005-2007 Jean Delvare <jdelvare@suse.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -99,7 +99,7 @@ int parse_command_line(int argc, char * const argv[])
|
||||
{ "string", required_argument, NULL, 's' },
|
||||
{ "dump", no_argument, NULL, 'u' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ 0, 0, 0, 0 }
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
while ((option = getopt_long(argc, argv, optstring, longopts, NULL)) != -1)
|
||||
|
||||
2
vpdopt.h
2
vpdopt.h
@ -2,7 +2,7 @@
|
||||
* Command line handling of vpddecode
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2005-2006 Jean Delvare <khali@linux-fr.org>
|
||||
* Copyright (C) 2005-2006 Jean Delvare <jdelvare@suse.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
Loading…
Reference in New Issue
Block a user