Blob Blame History Raw
--- a/dmidecode.py	2015-06-08 17:19:45.000000000 +0200
+++ b/dmidecode.py	2010-06-03 12:01:46.000000000 +0200
@@ -48,7 +48,7 @@
         elif type == DMIXML_DOC:
             self.restype = DMIXML_DOC
         else:
+            raise TypeError, "Invalid result type value"
-            raise TypeError("Invalid result type value")
         return True
 
     def QuerySection(self, sectname):
@@ -65,7 +65,7 @@
                                                           result_type=self.restype,
                                                           section=sectname) )
         else:
+            raise TypeError, "Invalid result type value"
-            raise TypeError("Invalid result type value")
 
         return ret
 
@@ -83,7 +83,7 @@
                                                           result_type=self.restype,
                                                           typeid=tpid))
         else:
+            raise TypeError, "Invalid result type value"
-            raise TypeError("Invalid result type value")
 
         return ret
 
--- a/examples/dmidump.py	2015-06-08 17:19:45.000000000 +0200
+++ b/examples/dmidump.py	2010-06-03 12:01:46.000000000 +0200
@@ -35,24 +35,24 @@
         "Simple function, dumping out warnings with a prefix if warnings are found and clearing warning buffer"
         warn = dmidecode.get_warnings()
         if warn:
+              print "### WARNING: %s" % warn
-              print("### WARNING: %s" % warn)
               dmidecode.clear_warnings()
 
 
 # Check if running as root .... provide a warning if not
 root_user = (os.getuid() == 0 and True or False)
 if not root_user:
+        print "####"
+        print "####  NOT RUNNING AS ROOT"
+        print "####"
+        print "#### The first run must always be done as root for this example to work."
+        print "#### When not run as root, quite some permission errors might appear"
+        print "####"
+        print "#### If this script is first run as root, it should be possible to run this script"
+        print "#### as an unprivileged user afterwards, with less warnings."
+        print "####"
+        print
+        print
-        print("####")
-        print("####  NOT RUNNING AS ROOT")
-        print("####")
-        print("#### The first run must always be done as root for this example to work.")
-        print("#### When not run as root, quite some permission errors might appear")
-        print("####")
-        print("#### If this script is first run as root, it should be possible to run this script")
-        print("#### as an unprivileged user afterwards, with less warnings.")
-        print("####")
-        print()
-        print()
 
 
 #. Test for presence of important functions using /dev/mem...  Using the legacy API
@@ -61,101 +61,101 @@
 #. for presence of the legacy API, which "under the hood" uses
 #. dmidecode.QuerySection(name), where name can be 'bios', 'system', etc.
 if root_user:
+        print "*** bios ***\n";      dmidecode.bios()
-        print("*** bios ***\n");      dmidecode.bios()
         print_warnings()
+        print "*** system ***\n";    dmidecode.system()
-        print("*** system ***\n");    dmidecode.system()
         print_warnings()
+        print "*** baseboard ***\n"; dmidecode.baseboard()
-        print("*** baseboard ***\n"); dmidecode.baseboard()
         print_warnings()
+        print "*** chassis ***\n";   dmidecode.chassis()
-        print("*** chassis ***\n");   dmidecode.chassis()
         print_warnings()
+        print "*** processor ***\n"; dmidecode.processor()
-        print("*** processor ***\n"); dmidecode.processor()
         print_warnings()
+        print "*** memory ***\n";    dmidecode.memory()
-        print("*** memory ***\n");    dmidecode.memory()
         print_warnings()
+        print "*** cache ***\n";     dmidecode.cache()
-        print("*** cache ***\n");     dmidecode.cache()
         print_warnings()
+        print "*** connector ***\n"; dmidecode.connector()
-        print("*** connector ***\n"); dmidecode.connector()
         print_warnings()
+        print "*** slot ***\n";      dmidecode.slot()
-        print("*** slot ***\n");      dmidecode.slot()
         print_warnings()
 
 
 #. Now test get/set of memory device file...
+print "*** get_dev()"
+print dmidecode.get_dev()
-print("*** get_dev()")
-print(dmidecode.get_dev())
 print_warnings()
+print "*** set_dev('dmidata.dump')"
+print dmidecode.set_dev("dmidata.dump");
-print("*** set_dev('dmidata.dump')")
-print(dmidecode.set_dev("dmidata.dump"));
 print_warnings()
+print "*** get_dev()"
+print dmidecode.get_dev()
-print("*** get_dev()")
-print(dmidecode.get_dev())
 print_warnings()
 
 #. Test taking a dump...
 if root_user:
+        print "*** Dumping DMI data to dump file"
+        print dmidecode.dump()
-        print("*** Dumping DMI data to dump file")
-        print(dmidecode.dump())
         print_warnings()
 
 #. Test reading the dump...  Using the preferred API
+print "*** bios ***\n";      pprint(dmidecode.QuerySection('bios'))
-print("*** bios ***\n");      pprint(dmidecode.QuerySection('bios'))
 print_warnings()
+print "*** system ***\n";    pprint(dmidecode.QuerySection('system'))
-print("*** system ***\n");    pprint(dmidecode.QuerySection('system'))
 print_warnings()
+print "*** baseboard ***\n"; pprint(dmidecode.QuerySection('baseboard'))
-print("*** baseboard ***\n"); pprint(dmidecode.QuerySection('baseboard'))
 print_warnings()
+print "*** chassis ***\n";   pprint(dmidecode.QuerySection('chassis'))
-print("*** chassis ***\n");   pprint(dmidecode.QuerySection('chassis'))
 print_warnings()
+print "*** processor ***\n"; pprint(dmidecode.QuerySection('processor'))
-print("*** processor ***\n"); pprint(dmidecode.QuerySection('processor'))
 print_warnings()
+print "*** memory ***\n";    pprint(dmidecode.QuerySection('memory'))
-print("*** memory ***\n");    pprint(dmidecode.QuerySection('memory'))
 print_warnings()
+print "*** cache ***\n";     pprint(dmidecode.QuerySection('cache'))
-print("*** cache ***\n");     pprint(dmidecode.QuerySection('cache'))
 print_warnings()
+print "*** connector ***\n"; pprint(dmidecode.QuerySection('connector'))
-print("*** connector ***\n"); pprint(dmidecode.QuerySection('connector'))
 print_warnings()
+print "*** slot ***\n";      pprint(dmidecode.QuerySection('slot'))
-print("*** slot ***\n");      pprint(dmidecode.QuerySection('slot'))
 print_warnings()
 
+print "*** Extracting memory information"
-print("*** Extracting memory information")
 for v in dmidecode.memory().values():
   if type(v) == dict and v['dmi_type'] == 17:
     pprint(v['data']['Size']),
 
+print "*** Querying for DMI type 3 and 7"
-print("*** Querying for DMI type 3 and 7")
 pprint(dmidecode.type(3))        # <-- Legacy API
 pprint(dmidecode.QueryTypeId(7)) # <-- preferred API
 print_warnings()
 
+print "*** Querying for the BIOS section"
-print("*** Querying for the BIOS section")
 pprint(dmidecode.QuerySection('bios'))
 print_warnings()
 
 #
 # Test XML stuff
 #
+print
+print
+print
+print "---------------------------------------"
+print "*** *** *** Testing XML API *** *** ***"
+print "---------------------------------------"
+print
+print
-print()
-print()
-print()
-print("---------------------------------------")
-print("*** *** *** Testing XML API *** *** ***")
-print("---------------------------------------")
-print()
-print()
 dmixml = dmidecode.dmidecodeXML()
 
 # Fetch all DMI data into a libxml2.xmlDoc object
+print "*** Getting all DMI data into a XML document variable"
-print("*** Getting all DMI data into a XML document variable")
 dmixml.SetResultType(dmidecode.DMIXML_DOC)  # Valid values: dmidecode.DMIXML_DOC, dmidecode.DMIXML_NODE
 xmldoc = dmixml.QuerySection('all')
 
 # Dump the XML to dmidump.xml - formated in UTF-8 decoding
+print "*** Dumping XML document to dmidump.xml"
-print("*** Dumping XML document to dmidump.xml")
 xmldoc.saveFormatFileEnc('dmidump.xml','UTF-8',1)
 
 # Do some XPath queries on the XML document
+print "*** Doing some XPath queries against the XML document"
-print("*** Doing some XPath queries against the XML document")
 dmixp = xmldoc.xpathNewContext()
 
 # What to look for - XPath expressions
@@ -168,12 +168,12 @@
 for k in keys:
 	data = dmixp.xpathEval(k)
 	for d in data:
+		print "%s: %s" % (k, d.get_content())
-		print("%s: %s" % (k, d.get_content()))
 
 del dmixp
 del xmldoc
 
 # Query for only a particular DMI TypeID - 0x04 - Processor
+print "*** Quering for Type ID 0x04 - Processor - dumping XML document to stdout"
-print("*** Quering for Type ID 0x04 - Processor - dumping XML document to stdout")
 dmixml.QueryTypeId(0x04).saveFormatFileEnc('-','UTF-8',1)
 print_warnings()
--- a/Makefile	2015-06-08 17:19:45.000000000 +0200
+++ b/Makefile	2010-06-03 12:01:46.000000000 +0200
@@ -38,19 +38,11 @@
 #. $AutoHeaderSerial::20100225                                                 $
 #. ******* AUTOHEADER END v1.2 *******
 
+VERSION := $(shell cd src;python -c "from setup_common import *; print get_version();")
-PY_BIN  := python2
-VERSION := $(shell cd src;$(PY_BIN) -c "from setup_common import *; print(get_version());")
 PACKAGE := python-dmidecode
+PY_VER  := $(shell python -c 'import sys; print "%d.%d"%sys.version_info[0:2]')
-PY_VER  := $(shell $(PY_BIN) -c 'import sys; print("%d.%d"%sys.version_info[0:2])')
-PY_MV   := $(shell echo $(PY_VER) | cut -b 1)
 PY      := python$(PY_VER)
+SO      := build/lib.linux-$(shell uname -m)-$(PY_VER)/dmidecodemod.so
-SO_PATH := build/lib.linux-$(shell uname -m)-$(PY_VER)
-ifeq ($(PY_MV),2)
-	SO  := $(SO_PATH)/dmidecodemod.so
-else
-	SOABI := $(shell $(PY_BIN) -c 'import sysconfig; print(sysconfig.get_config_var("SOABI"))')
-	SO  := $(SO_PATH)/dmidecodemod.$(SOABI).so
-endif
 SHELL	:= /bin/bash
 
 ###############################################################################
@@ -79,7 +71,6 @@
 	-rm -rf build
 	-rm -rf rpm
 	-rm -rf src/setup_common.py[oc]
-	-rm -rf __pycache__ src/__pycache__
 	-rm -rf $(PACKAGE)-$(VERSION) $(PACKAGE)-$(VERSION).tar.gz
 	$(MAKE) -C unit-tests clean
 
--- a/man/dmidecode.8	2015-06-08 17:19:45.000000000 +0200
+++ b/man/dmidecode.8	2010-06-03 12:01:46.000000000 +0200
@@ -1,4 +1,4 @@
+.TH DMIDECODE 8 "October 2008" "dmidecode"
-.TH DMIDECODE 8 "March 2012" "dmidecode"
 .SH NAME
 dmidecode \- \s-1DMI\s0 table decoder
 .SH SYNOPSIS
@@ -127,13 +127,6 @@
 .P
 Options --string, --type, --dump and --dump-bin
 determine the output format and are mutually exclusive.
-.P
-Please note in case of
-.B dmidecode
-is run on a system with BIOS that boasts new SMBIOS specification, which
-is not supported by the tool yet, it will print out relevant message in
-addition to requested data on the very top of the output. Thus informs the
-output data is not reliable.
 
 .SH "DMI TYPES"
 The \s-1SMBIOS\s0 specification defines the following \s-1DMI\s0 types:
@@ -145,7 +138,7 @@
 Type	Information
 0	BIOS
 1	System
+2	Base Board
-2	Baseboard
 3	Chassis
 4	Processor
 5	Memory Controller
@@ -183,9 +176,6 @@
 37	Memory Channel
 38	IPMI Device
 39	Power Supply
-40      Additional Information
-41      Onboard Devices Extended Information
-42      Management Controller Host Interface
 .TE
 
 Additionally, type 126 is used for disabled entries and type 127 is an
--- a/src/compat.h	2015-06-08 17:19:45.000000000 +0200
+++ b/src/compat.h	2010-06-03 12:01:46.000000000 +0200
@@ -40,19 +40,4 @@
 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
 #endif
 
-// Python 2 vs Python 3 compat
-#if PY_MAJOR_VERSION >= 3
-#define IS_PY3K
-#define MODINITERROR return NULL
-#define PYNUMBER_FROMLONG PyLong_FromLong
-#define PYTEXT_FROMSTRING PyUnicode_FromString
-#else
-#include <bytesobject.h>
-#define MODINITERROR return
-#define PYNUMBER_FROMLONG PyInt_FromLong
-#define PYTEXT_FROMSTRING PyString_FromString
-#define PyCapsule_New(pointer, name, destructor) \
-	    (PyCObject_FromVoidPtr(pointer, destructor))
-#endif
-
 #endif
--- a/src/config.h	2015-06-08 17:19:45.000000000 +0200
+++ b/src/config.h	2010-06-03 12:01:46.000000000 +0200
@@ -41,7 +41,7 @@
 #define CONFIG_H
 
 /* Default memory device file */
+#ifdef __BEOS__
-#if defined(__BEOS__) || defined(__HAIKU__)
 #define DEFAULT_MEM_DEV "/dev/misc/mem"
 #else
 #define DEFAULT_MEM_DEV "/dev/mem"
--- a/src/dmidecode.c	2017-10-31 09:06:07.030626683 +0100
+++ b/src/dmidecode.c	2017-10-31 09:06:30.316273129 +0100
@@ -2,9 +2,9 @@
 /*. ******* coding:utf-8 AUTOHEADER START v1.1 *******
  *. vim: fileencoding=utf-8 syntax=c sw=2 ts=2 et
  *.
+ *. © 2007-2009 Nima Talebi <nima@autonomy.net.au>
+ *. © 2009      David Sommerseth <davids@redhat.com>
+ *. © 2002-2008 Jean Delvare <khali@linux-fr.org>
- *. © 2007-2013 Nima Talebi <nima@autonomy.net.au>
- *. © 2009-2013 David Sommerseth <davids@redhat.com>
- *. © 2002-2010 Jean Delvare <khali@linux-fr.org>
  *. © 2000-2002 Alan Cox <alan@redhat.com>
  *.
  *. This file is part of Python DMI-Decode.
@@ -44,17 +44,17 @@
  * DMI Decode
  *
  * Unless specified otherwise, all references are aimed at the "System
+ * Management BIOS Reference Specification, Version 2.6" document,
+ * available from http://www.dmtf.org/standards/smbios/.
- * Management BIOS Reference Specification, Version 2.8.0" document,
- * available from http://www.dmtf.org/standards/smbios.
  *
  * Note to contributors:
  * Please reference every value you add or modify, especially if the
  * information does not come from the above mentioned specification.
  *
  * Additional references:
+ *  - Intel AP-485 revision 32
- *  - Intel AP-485 revision 36
  *    "Intel Processor Identification and the CPUID Instruction"
+ *    http://developer.intel.com/design/xeon/applnots/241618.htm
- *    http://www.intel.com/support/processors/sb/cs-009861.htm
  *  - DMTF Common Information Model
  *    CIM Schema version 2.19.1
  *    http://www.dmtf.org/standards/cim/
@@ -65,9 +65,6 @@
  *    "CPUID Specification"
  *    http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25481.pdf
  *  - BIOS Integrity Services Application Programming Interface version 1.0
- *  - DMTF DSP0239 version 1.1.0
- *    "Management Component Transport Protocol (MCTP) IDs and Codes"
- *    http://www.dmtf.org/standards/pmci
  *    http://www.intel.com/design/archives/wfm/downloads/bisspec.htm
  *
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -84,16 +81,14 @@
 #include "config.h"
 #include "types.h"
 #include "util.h"
+#include "dmixml.h"
 #include "dmidecode.h"
-#include "dmixml.h"
 #include "dmioem.h"
 #include "efi.h"
 #include "dmidump.h"
 
 #include "dmihelper.h"
 
-#define SUPPORTED_SMBIOS_VER 0x0207
-
 /*******************************************************************************
 ** Type-independant Stuff
 */
@@ -173,15 +168,12 @@
                 {"Management Device Threshold Data","ManagementDevice",     "type", "Threshold Data"},
                 {"Memory Channel",                  "MemoryChannel",        NULL, NULL},
                 {"IPMI Device",                     "IPMIdevice",           NULL, NULL},
+                {"Power Supply",                    "PowerSupply",          NULL, NULL}  /* 39 */
-                {"Power Supply",                    "PowerSupply",          NULL, NULL},    /* 39 */
-                {"Additional Information",          "AdditionalInfo",       NULL, NULL},
-                {"Onboard Device",                  "OnboardDevice",        NULL, NULL},    /* 41 */
-                {"Management Controller Host Interface", "MgmntCtrltHostIntf", NULL, NULL}, /* 42 */
                 /* *INDENT-ON* */
         };
         xmlNode *type_n = NULL;
 
+        if(code <= 39) {
-        if(code <= 42) {
                 type_n = xmlNewChild(node, NULL, (xmlChar *)types[code].tagname, NULL);
                 assert( type_n != NULL );
 
@@ -262,55 +254,8 @@
         dump_n = NULL;
 }
 
-
-/* shift is 0 if the value is in bytes, 1 if it is in kilobytes */
-static void dmi_add_memory_size(xmlNode *node, u64 code, int shift)
-{
-        unsigned long capacity;
-        u16 split[7];
-        static const char *unit[8] = {
-                "bytes", "kB", "MB", "GB", "TB", "PB", "EB", "ZB"
-        };
-        int i;
-
-        /*
-         * We split the overall size in powers of thousand: EB, PB, TB, GB,
-         * MB, kB and B. In practice, it is expected that only one or two
-         * (consecutive) of these will be non-zero.
-         */
-        split[0] = code.l & 0x3FFUL;
-        split[1] = (code.l >> 10) & 0x3FFUL;
-        split[2] = (code.l >> 20) & 0x3FFUL;
-        split[3] = ((code.h << 2) & 0x3FCUL) | (code.l >> 30);
-        split[4] = (code.h >> 8) & 0x3FFUL;
-        split[5] = (code.h >> 18) & 0x3FFUL;
-        split[6] = code.h >> 28;
-
-        /*
-         * Now we find the highest unit with a non-zero value. If the following
-         * is also non-zero, we use that as our base. If the following is zero,
-         * we simply display the highest unit.
-         */
-        for (i = 6; i > 0; i--) {
-                if (split[i])
-                        break;
-        }
-        if (i > 0 && split[i - 1]) {
-                i--;
-                capacity = split[i] + (split[i + 1] << 10);
-        } else {
-                capacity = split[i];
-        }
-
-        dmixml_AddAttribute(node, "unit", unit[i + shift]);
-        dmixml_AddTextContent(node, "%lu", capacity);
-}
-
-
-
-
 /*******************************************************************************
+** 3.3.1 BIOS Information (Type 0)
-** 7.1 BIOS Information (Type 0)
 */
 
 void dmi_bios_runtime_size(xmlNode *node, u32 code)
@@ -328,7 +273,7 @@
         }
 }
 
+/* 3.3.1.1 */
-/* 7.1.1 */
 void dmi_bios_characteristics(xmlNode *node, u64 code)
 {
         static const char *characteristics[] = {
@@ -351,9 +296,9 @@
                 "EDD is supported",
                 "Japanese floppy for NEC 9800 1.2 MB is supported (int 13h)",
                 "Japanese floppy for Toshiba 1.2 MB is supported (int 13h)",
+                "5.25\"/360 KB floppy services are supported (int 13h)",
-                "5.25\"/360 kB floppy services are supported (int 13h)",
                 "5.25\"/1.2 MB floppy services are supported (int 13h)",
+                "3.5\"/720 KB floppy services are supported (int 13h)",
-                "3.5\"/720 kB floppy services are supported (int 13h)",
                 "3.5\"/2.88 MB floppy services are supported (int 13h)",
                 "Print screen service is supported (int 5h)",
                 "8042 keyboard services are supported (int 9h)",
@@ -362,7 +307,7 @@
                 "CGA/mono video services are supported (int 10h)",
                 "NEC PC-98"     /* 31 */
         };
+        dmixml_AddAttribute(node, "dmispec", "3.3.1.1");
-        dmixml_AddAttribute(node, "dmispec", "7.1.1");
         dmixml_AddAttribute(node, "flags", "0x%04x", code);
 
         if(code.l&(1<<3)) {
@@ -380,7 +325,7 @@
         }
 }
 
+/* 3.3.1.2.1 */
-/* 7.1.2.1 */
 void dmi_bios_characteristics_x1(xmlNode *node, u8 code)
 {
         int i = 0;
@@ -395,7 +340,7 @@
                 "Smart battery" /* 7 */
         };
 
+        dmixml_AddAttribute(node, "dmispec", "3.3.1.2.1");
-        dmixml_AddAttribute(node, "dmispec", "7.1.2.1");
         dmixml_AddAttribute(node, "flags", "0x%04x", code);
 
         for(i = 0; i <= 7; i++) {
@@ -404,29 +349,27 @@
         }
 }
 
+/* 3.3.1.2.2 */
-/* 7.1.2.2 */
 void dmi_bios_characteristics_x2(xmlNode *node, u8 code)
 {
         int i = 0;
         static const char *characteristics[] = {
                 "BIOS boot specification",      /* 0 */
                 "Function key-initiated network boot",
+                "Targeted content distribution" /* 2 */
-                "Targeted content distribution", /* 2 */
-                "UEFI is supported",
-                "System is a virtual machine"    /* 4 */
         };
 
+        dmixml_AddAttribute(node, "dmispec", "3.3.1.2.2");
-        dmixml_AddAttribute(node, "dmispec", "7.1.2.2");
         dmixml_AddAttribute(node, "flags", "0x%04x", code);
 
+        for(i = 0; i <= 2; i++) {
-        for(i = 0; i <= 4; i++) {
                 xmlNode *chr_n = dmixml_AddTextChild(node, "characteristic", characteristics[i]);
                 dmixml_AddAttribute(chr_n, "enabled", "%i", (code & (1 << i) ? 1: 0));
         }
 }
 
 /*******************************************************************************
+** 3.3.2 System Information (Type 1)
-** 7.2 System Information (Type 1)
 */
 
 void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver)
@@ -443,9 +386,9 @@
         }
 
         uuid_n = xmlNewChild(node, NULL, (xmlChar *) "SystemUUID", NULL);
+        dmixml_AddAttribute(uuid_n, "dmispec", "3.3.2");
-        dmixml_AddAttribute(uuid_n, "dmispec", "7.2");
 
+        if(only0xFF )  {
-        if(only0xFF)  {
                 dmixml_AddAttribute(uuid_n, "unavailable", "1");
                 dmixml_AddTextContent(uuid_n, "Not Present");
                 return;
@@ -458,7 +401,7 @@
         }
 
         /*
+         * As off version 2.6 of the SMBIOS specification, the first 3
-         * As of version 2.6 of the SMBIOS specification, the first 3
          * fields of the UUID are supposed to be encoded on little-endian.
          * The specification says that this is the defacto standard,
          * however I've seen systems following RFC 4122 instead and use
@@ -478,7 +421,7 @@
         }
 }
 
+/* 3.3.2.1 */
-/* 7.2.2 */
 void dmi_system_wake_up_type(xmlNode *node, u8 code)
 {
         static const char *type[] = {
@@ -494,7 +437,7 @@
         };
         xmlNode *swut_n = xmlNewChild(node, NULL, (xmlChar *) "SystemWakeUpType", NULL);
         assert( swut_n != NULL );
+        dmixml_AddAttribute(swut_n, "dmispec", "3.3.2.1");
-        dmixml_AddAttribute(swut_n, "dmispec", "7.2.2");
         dmixml_AddAttribute(swut_n, "flags", "0x%04x", code);
 
         if(code <= 0x08) {
@@ -505,10 +448,10 @@
 }
 
 /*******************************************************************************
+** 3.3.3 Base Board Information (Type 2)
-** 7.3 Base Board Information (Type 2)
 */
 
+/* 3.3.3.1 */
-/* 7.3.1 */
 void dmi_base_board_features(xmlNode *node, u8 code)
 {
         static const char *features[] = {
@@ -521,7 +464,7 @@
 
         xmlNode *feat_n = xmlNewChild(node, NULL, (xmlChar *) "Features", NULL);
         assert( feat_n != NULL );
+        dmixml_AddAttribute(feat_n, "dmispec", "3.3.3.1");
-        dmixml_AddAttribute(feat_n, "dmispec", "7.3.1");
         dmixml_AddAttribute(feat_n, "flags", "0x%04x", code);
 
         if((code & 0x1F) != 0) {
@@ -539,7 +482,7 @@
 
 void dmi_base_board_type(xmlNode *node, const char *tagname, u8 code)
 {
+        /* 3.3.3.2 */
-        /* 7.3.2 */
         static const char *type[] = {
                 "Unknown",      /* 0x01 */
                 "Other",
@@ -557,7 +500,7 @@
         };
         xmlNode *type_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
         assert( type_n != NULL );
+        dmixml_AddAttribute(type_n, "dmispec", "3.3.3.2");
-        dmixml_AddAttribute(type_n, "dmispec", "7.3.2");
         dmixml_AddAttribute(type_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x0D) {
@@ -585,10 +528,10 @@
 }
 
 /*******************************************************************************
+** 3.3.4 Chassis Information (Type 3)
-** 7.4 Chassis Information (Type 3)
 */
 
+/* 3.3.4.1 */
-/* 7.4.1 */
 void dmi_chassis_type(xmlNode *node, u8 code)
 {
         static const char *type[] = {
@@ -624,11 +567,9 @@
         };
         xmlNode *type_n = xmlNewChild(node, NULL, (xmlChar *)"ChassisType", NULL);
         assert( type_n != NULL );
+        dmixml_AddAttribute(type_n, "dmispec", "3.3.4.1");
-        dmixml_AddAttribute(type_n, "dmispec", "7.4.1");
         dmixml_AddAttribute(type_n, "flags", "0x%04x", code);
 
-        code &= 0x7F; /* bits 6:0 are chassis type, 7th bit is the lock bit */
-
         if(code >= 0x01 && code <= 0x1B) {
                 dmixml_AddAttribute(type_n, "available", "1");
                 dmixml_AddTextContent(type_n, "%s", type[code - 0x01]);
@@ -645,25 +586,25 @@
         };
         xmlNode *lock_n = xmlNewChild(node, NULL, (xmlChar *) "ChassisLock", NULL);
         assert( lock_n != NULL );
+        dmixml_AddAttribute(lock_n, "dmispec", "3.3.4");
-        dmixml_AddAttribute(lock_n, "dmispec", "7.4.1");
         dmixml_AddAttribute(lock_n, "flags", "0x%04x", code);
         dmixml_AddTextContent(lock_n, "%s", lock[code]);
 }
 
+/* 3.3.4.2 */
-/* 7.4.2 */
 void dmi_chassis_state(xmlNode *node, const char *tagname, u8 code)
 {
         static const char *state[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
+                "Safe",         /* master.mif says OK */
-                "Safe",
                 "Warning",
                 "Critical",
                 "Non-recoverable"       /* 0x06 */
         };
         xmlNode *state_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
         assert( state_n != NULL );
+        dmixml_AddAttribute(state_n, "dmispec", "3.3.4.2");
-        dmixml_AddAttribute(state_n, "dmispec", "7.4.2");
         dmixml_AddAttribute(state_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x06) {
@@ -673,7 +614,7 @@
         }
 }
 
+/* 3.3.4.3 */
-/* 7.4.3 */
 void dmi_chassis_security_status(xmlNode *node, u8 code)
 {
         static const char *status[] = {
@@ -685,7 +626,7 @@
         };
         xmlNode *secstat_n = xmlNewChild(node, NULL, (xmlChar *) "SecurityStatus", NULL);
         assert( secstat_n != NULL );
+        dmixml_AddAttribute(secstat_n, "dmispec", "3.3.4.3");
-        dmixml_AddAttribute(secstat_n, "dmispec", "7.4.3");
         dmixml_AddAttribute(secstat_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x05) {
@@ -750,12 +691,12 @@
 }
 
 /*******************************************************************************
+** 3.3.5 Processor Information (Type 4)
-** 7.5 Processor Information (Type 4)
 */
 
 void dmi_processor_type(xmlNode *node, u8 code)
 {
+        /* 3.3.5.1 */
-        /* 7.5.1 */
         static const char *type[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -775,13 +716,13 @@
         }
 }
 
+void dmi_processor_family(xmlNode *node, const struct dmi_header *h)
-void dmi_processor_family(xmlNode *node, const struct dmi_header *h, u16 ver)
 {
         const u8 *data = h->data;
         unsigned int i, low, high;
         u16 code;
 
+        /* 3.3.5.2 */
-        /* 7.5.2 */
         static struct {
                 int value;
                 const char *name;
@@ -806,8 +747,8 @@
           { 0x11, "Pentium III" },
           { 0x12, "M1" },
           { 0x13, "M2" },
+          { 0x14, "Celeron M" }, /* From CIM_Processor.Family */
+          { 0x15, "Pentium 4 HT" }, /* From CIM_Processor.Family */
-          { 0x14, "Celeron M" },
-          { 0x15, "Pentium 4 HT" },
 
           { 0x18, "Duron" },
           { 0x19, "K5" },
@@ -825,10 +766,10 @@
           { 0x25, "Power PC 620" },
           { 0x26, "Power PC x704" },
           { 0x27, "Power PC 750" },
+          { 0x28, "Core Duo" }, /* From CIM_Processor.Family */
+          { 0x29, "Core Duo Mobile" }, /* From CIM_Processor.Family */
+          { 0x2A, "Core Solo Mobile" }, /* From CIM_Processor.Family */
+          { 0x2B, "Atom" }, /* From CIM_Processor.Family */
-          { 0x28, "Core Duo" },
-          { 0x29, "Core Duo Mobile" },
-          { 0x2A, "Core Solo Mobile" },
-          { 0x2B, "Atom" },
 
           { 0x30, "Alpha" },
           { 0x31, "Alpha 21064" },
@@ -838,14 +779,6 @@
           { 0x35, "Alpha 21164a" },
           { 0x36, "Alpha 21264" },
           { 0x37, "Alpha 21364" },
-          { 0x38, "Turion II Ultra Dual-Core Mobile M" },
-          { 0x39, "Turion II Dual-Core Mobile M" },
-          { 0x3A, "Athlon II Dual-Core M" },
-          { 0x3B, "Opteron 6100" },
-          { 0x3C, "Opteron 4100" },
-          { 0x3D, "Opteron 6200" },
-          { 0x3E, "Opteron 4200" },
-          { 0x3F, "FX" },
 
           { 0x40, "MIPS" },
           { 0x41, "MIPS R4000" },
@@ -853,16 +786,6 @@
           { 0x43, "MIPS R4400" },
           { 0x44, "MIPS R4600" },
           { 0x45, "MIPS R10000" },
-          { 0x46, "C-Series" },
-          { 0x47, "E-Series" },
-          { 0x48, "A-Series" },
-          { 0x49, "G-Series" },
-          { 0x4A, "Z-Series" },
-          { 0x4B, "R-Series" },
-          { 0x4C, "Opteron 4300" },
-          { 0x4D, "Opteron 6300" },
-          { 0x4E, "Opteron 3300" },
-          { 0x4F, "FirePro" },
 
           { 0x50, "SPARC" },
           { 0x51, "SuperSPARC" },
@@ -897,12 +820,12 @@
           { 0x87, "Dual-Core Opteron" },
           { 0x88, "Athlon 64 X2" },
           { 0x89, "Turion 64 X2" },
+          { 0x8A, "Quad-Core Opteron" }, /* From CIM_Processor.Family */
+          { 0x8B, "Third-Generation Opteron" }, /* From CIM_Processor.Family */
+          { 0x8C, "Phenom FX" }, /* From CIM_Processor.Family */
+          { 0x8D, "Phenom X4" }, /* From CIM_Processor.Family */
+          { 0x8E, "Phenom X2" }, /* From CIM_Processor.Family */
+          { 0x8F, "Athlon X2" }, /* From CIM_Processor.Family */
-          { 0x8A, "Quad-Core Opteron" },
-          { 0x8B, "Third-Generation Opteron" },
-          { 0x8C, "Phenom FX" },
-          { 0x8D, "Phenom X4" },
-          { 0x8E, "Phenom X2" },
-          { 0x8F, "Athlon X2" },
           { 0x90, "PA-RISC" },
           { 0x91, "PA-RISC 8500" },
           { 0x92, "PA-RISC 8000" },
@@ -912,21 +835,17 @@
           { 0x96, "PA-RISC 7100" },
 
           { 0xA0, "V30" },
+          { 0xA1, "Quad-Core Xeon 3200" }, /* From CIM_Processor.Family */
+          { 0xA2, "Dual-Core Xeon 3000" }, /* From CIM_Processor.Family */
+          { 0xA3, "Quad-Core Xeon 5300" }, /* From CIM_Processor.Family */
+          { 0xA4, "Dual-Core Xeon 5100" }, /* From CIM_Processor.Family */
+          { 0xA5, "Dual-Core Xeon 5000" }, /* From CIM_Processor.Family */
+          { 0xA6, "Dual-Core Xeon LV" }, /* From CIM_Processor.Family */
+          { 0xA7, "Dual-Core Xeon ULV" }, /* From CIM_Processor.Family */
+          { 0xA8, "Dual-Core Xeon 7100" }, /* From CIM_Processor.Family */
+          { 0xA9, "Quad-Core Xeon 5400" }, /* From CIM_Processor.Family */
+          { 0xAA, "Quad-Core Xeon" }, /* From CIM_Processor.Family */
+
-          { 0xA1, "Quad-Core Xeon 3200" },
-          { 0xA2, "Dual-Core Xeon 3000" },
-          { 0xA3, "Quad-Core Xeon 5300" },
-          { 0xA4, "Dual-Core Xeon 5100" },
-          { 0xA5, "Dual-Core Xeon 5000" },
-          { 0xA6, "Dual-Core Xeon LV" },
-          { 0xA7, "Dual-Core Xeon ULV" },
-          { 0xA8, "Dual-Core Xeon 7100" },
-          { 0xA9, "Quad-Core Xeon 5400" },
-          { 0xAA, "Quad-Core Xeon" },
-          { 0xAB, "Dual-Core Xeon 5200" },
-          { 0xAC, "Dual-Core Xeon 7200" },
-          { 0xAD, "Quad-Core Xeon 7300" },
-          { 0xAE, "Quad-Core Xeon 7400" },
-          { 0xAF, "Multi-Core Xeon 7400" },
           { 0xB0, "Pentium III Xeon" },
           { 0xB1, "Pentium III Speedstep" },
           { 0xB2, "Pentium 4" },
@@ -943,52 +862,24 @@
           { 0xBD, "Core Solo" },
           /* 0xBE handled as a special case */
           { 0xBF, "Core 2 Duo" },
+          { 0xC0, "Core 2 Solo" }, /* From CIM_Processor.Family */
+          { 0xC1, "Core 2 Extreme" }, /* From CIM_Processor.Family */
+          { 0xC2, "Core 2 Quad" }, /* From CIM_Processor.Family */
+          { 0xC3, "Core 2 Extreme Mobile" }, /* From CIM_Processor.Family */
+          { 0xC4, "Core 2 Duo Mobile" }, /* From CIM_Processor.Family */
+          { 0xC5, "Core 2 Solo Mobile" }, /* From CIM_Processor.Family */
+
-          { 0xC0, "Core 2 Solo" },
-          { 0xC1, "Core 2 Extreme" },
-          { 0xC2, "Core 2 Quad" },
-          { 0xC3, "Core 2 Extreme Mobile" },
-          { 0xC4, "Core 2 Duo Mobile" },
-          { 0xC5, "Core 2 Solo Mobile" },
-          { 0xC6, "Core i7" },
-          { 0xC7, "Dual-Core Celeron" },
           { 0xC8, "IBM390" },
           { 0xC9, "G4" },
           { 0xCA, "G5" },
           { 0xCB, "ESA/390 G6" },
           { 0xCC, "z/Architectur" },
-          { 0xCD, "Core i5" },
-          { 0xCE, "Core i3" },
 
           { 0xD2, "C7-M" },
           { 0xD3, "C7-D" },
           { 0xD4, "C7" },
           { 0xD5, "Eden" },
 
-          { 0xD6, "Multi-Core Xeon" },
-          { 0xD7, "Dual-Core Xeon 3xxx" },
-          { 0xD8, "Quad-Core Xeon 3xxx" },
-          { 0xD9, "Nano" },
-          { 0xDA, "Dual-Core Xeon 5xxx" },
-          { 0xDB, "Quad-Core Xeon 5xxx" },
-
-          { 0xDD, "Dual-Core Xeon 7xxx" },
-          { 0xDE, "Quad-Core Xeon 7xxx" },
-          { 0xDF, "Multi-Core Xeon 7xxx" },
-          { 0xE0, "Multi-Core Xeon 3400" },
-
-          { 0xE4, "Opteron 3000" },
-          { 0xE5, "Sempron II" },
-          { 0xE6, "Embedded Opteron Quad-Core" },
-          { 0xE7, "Phenom Triple-Core" },
-          { 0xE8, "Turion Ultra Dual-Core Mobile" },
-          { 0xE9, "Turion Dual-Core Mobile" },
-          { 0xEA, "Athlon Dual-Core" },
-          { 0xEB, "Sempron SI" },
-          { 0xEC, "Phenom II" },
-          { 0xED, "Athlon II" },
-          { 0xEE, "Six-Core Opteron" },
-          { 0xEF, "Sempron M" },
-
           { 0xFA, "i860" },
           { 0xFB, "i960" },
 
@@ -1018,18 +909,7 @@
 
         xmlNode *family_n = xmlNewChild(node, NULL, (xmlChar *) "Family", NULL);
         assert( family_n != NULL );
+        dmixml_AddAttribute(family_n, "dmispec", "3.3.3.5");
-        dmixml_AddAttribute(family_n, "dmispec", "7.5.2");
-
-        /* Special case for ambiguous value 0x30 (SMBIOS 2.0 only) */
-        if (ver == 0x0200 && data[0x06] == 0x30 && h->length >= 0x08) {
-                const char *manufacturer = dmi_string(h, data[0x07]);
-
-                if (strstr(manufacturer, "Intel") != NULL
-                    || strncasecmp(manufacturer, "Intel", 5) == 0) {
-                        dmixml_AddTextContent(family_n, "Pentium Pro");
-                        return;
-                }
-        }
 
         code = (data[0x06] == 0xFE && h->length >= 0x2A) ? WORD(data + 0x28) : data[0x06];
 
@@ -1086,7 +966,7 @@
 
 xmlNode *dmi_processor_id(xmlNode *node, const struct dmi_header *h)
 {
+        /* Intel AP-485 revision 31, table 3-4 */
-        /* Intel AP-485 revision 36, table 2-4 */
         static struct _cpuflags {
                 const char *flag;
                 const char *descr;
@@ -1116,13 +996,13 @@
                 {"DS", "DS (Debug store)"},
                 {"ACPI", "ACPI (ACPI supported)"},
                 {"MMX", "MMX (MMX technology supported)"},
+                {"FXSR", "FXSR (Fast floating-point save and restore)"},
-                {"FXSR", "FXSR (FXSAVE and FXSTOR instructions supported)"},
                 {"SSE", "SSE (Streaming SIMD extensions)"},
                 {"SSE2", "SSE2 (Streaming SIMD extensions 2)"},
                 {"SS", "SS (Self-snoop)"},
+                {"HTT", "HTT (Hyper-threading technology)"},
-                {"HTT", "HTT (Multi-threading)"},
                 {"TM", "TM (Thermal monitor supported)"},
+                {"IA64", "IA64 (IA64 capabilities)"},
-                {NULL, NULL},
                 {"PBE", "PBE (Pending break enabled)"}   /* 31 */
                 /* *INDENT-ON* */
         };
@@ -1136,7 +1016,7 @@
         assert( h && h->data );
         type = h->data[0x06];
         p = h->data + 8;
+        version = dmi_string(h, h->data[0x10]);
-        version = (char *) dmi_string(h, h->data[0x10]);
 
         /*
          ** Extra flags are now returned in the ECX register when one calls
@@ -1186,25 +1066,22 @@
                                             dx & 0xF);
                         return data_n;
                 }
+        } else if((type >= 0x0B && type <= 0x15)        /* Intel, Cyrix */
-        } else if(  (type >= 0x0B && type <= 0x15)      /* Intel, Cyrix */
                   ||(type >= 0x28 && type <= 0x2B)      /* Intel */
+                  ||(type >= 0xA1 && type <= 0xAA)      /* Intel */
+                  ||(type >= 0xB0 && type <= 0xB3)      /* Intel */
+                  ||type == 0xB5        /* Intel */
+                  || (type >= 0xB9 && type <= 0xC5)     /* Intel */
+                  ||(type >= 0xD2 && type <= 0xD5)      /* VIA */
-                  ||(type >= 0xA1 && type <= 0xB3)      /* Intel */
-                  ||type == 0xB5                        /* Intel */
-                  ||(type >= 0xB9 && type <= 0xC7)      /* Intel */
-                  ||(type >= 0xCD && type <= 0xCE)      /* Intel */
-                  ||(type >= 0xD2 && type <= 0xDB)      /* VIA, Intel */
-                  ||(type >= 0xDD && type <= 0xE0)      /* Intel */
                   ) {
 
                 sig = 1;
 
         } else if((type >= 0x18 && type <= 0x1D)  /* AMD */
                 ||type == 0x1F  /* AMD */
+                || (type >= 0x83 && type <= 0x8F)       /* AMD */
+                ||(type >= 0xB6 && type <= 0xB7)        /* AMD */
+                ||(type >= 0xE6 && type <= 0xEB)        /* AMD */
-                ||(type >= 0x38 && type <= 0x3E)       /* AMD */
-                ||(type >= 0x46 && type <= 0x49)       /* AMD */
-                ||(type >= 0x83 && type <= 0x8F)       /* AMD */
-                ||(type >= 0xB6 && type <= 0xB7)       /* AMD */
-                ||(type >= 0xE6 && type <= 0xEF)       /* AMD */
                 ) {
 
                 sig = 2;
@@ -1258,7 +1135,7 @@
 
         edx = DWORD(p + 4);
         flags_n = xmlNewChild(data_n, NULL, (xmlChar *) "cpu_flags", NULL);
+        if((edx & 0xFFEFFBFF) != 0) {
-        if((edx & 0xBFEFFBFF) != 0) {
                 int i;
 
                 for(i = 0; i <= 31; i++) {
@@ -1273,7 +1150,7 @@
         return data_n;
 }
 
+/* 3.3.5.4 */
-/* 7.5.4 */
 void dmi_processor_voltage(xmlNode *node, u8 code)
 {
         static const char *voltage[] = {
@@ -1284,7 +1161,7 @@
         int i;
         xmlNode *vltg_n = xmlNewChild(node, NULL, (xmlChar *) "Voltages", NULL);
         assert( vltg_n != NULL );
+        dmixml_AddAttribute(vltg_n, "dmispec", "3.3.5.4");
-        dmixml_AddAttribute(vltg_n, "dmispec", "7.5.4");
         dmixml_AddAttribute(vltg_n, "flags", "0x%04x", code);
 
         if(code & 0x80) {
@@ -1339,7 +1216,7 @@
 
 void dmi_processor_upgrade(xmlNode *node, u8 code)
 {
+        /* 3.3.5.5 */
-        /* 7.5.5 */
         static const char *upgrade[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -1364,35 +1241,14 @@
                 "Socket LGA775",        /* 0x15 */
                 "Socket S1",
                 "Socket AM2",
+                "Socket F (1207)"       /* 0x18 */
-                "Socket F (1207)",      /* 0x18 */
-                "Socket LGA1366",
-                "Socket G34",
-                "Socket AM3",
-                "Socket C32",
-                "Socket LGA1156",
-                "Socket LGA1567",
-                "Socket PGA988A",
-                "Socket BGA1288"        /* 0x20 */
-                "Socket rPGA988B",
-                "Socket BGA1023",
-                "Socket BGA1224",
-                "Socket BGA1155",
-                "Socket LGA1356",
-                "Socket LGA2011",
-                "Socket FS1",
-                "Socket FS2",
-                "Socket FM1",
-                "Socket FM2",
-                "Socket LGA2011-3",
-                "Socket LGA1356-3"      /* 0x2C */
-
         };
         xmlNode *upgr_n = xmlNewChild(node, NULL, (xmlChar *) "Upgrade", NULL);
         assert( upgr_n != NULL );
+        dmixml_AddAttribute(upgr_n, "dmispec", "3.3.5.5");
-        dmixml_AddAttribute(upgr_n, "dmispec", "7.5.5");
         dmixml_AddAttribute(upgr_n, "flags", "0x%04x", code);
 
+        if(code >= 0x01 && code <= 0x15) {
-        if(code >= 0x01 && code <= 0x2A) {
                 dmixml_AddTextContent(upgr_n, "%s", upgrade[code - 0x01]);
         } else {
                 dmixml_AddAttribute(upgr_n, "outofspec", "1");
@@ -1420,28 +1276,23 @@
         }
 }
 
+/* 3.3.5.9 */
-/* 7.5.9 */
 void dmi_processor_characteristics(xmlNode *node, u16 code)
 {
         static const char *characteristics[] = {
                 "Unknown",              /* 1 */
+                "64-bit capable"        /* 2 */
-                "64-bit capable",       /* 2 */
-                "Multi-Core",
-                "Hardware Thread",
-                "Execute Protection",
-                "Enhanced Virtualization",
-                "Power/Performance Control" /* 7 */
         };
 
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Characteristics", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.5.9");
-        dmixml_AddAttribute(data_n, "dmispec", "7.5.9");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
+        if((code & 0x0004) != 0) {
-        if((code & 0x00FC) != 0) {
                 int i;
 
+                for(i = 1; i <= 2; i++) {
-                for(i = 1; i <= 7; i++) {
                         if(code & (1 << i)) {
                                 dmixml_AddTextChild(data_n, "Flag", "%s", characteristics[i - 1]);
                         }
@@ -1450,12 +1301,12 @@
 }
 
 /*******************************************************************************
+** 3.3.6 Memory Controller Information (Type 5)
-** 7.6 Memory Controller Information (Type 5)
 */
 
 void dmi_memory_controller_ed_method(xmlNode *node, u8 code)
 {
+        /* 3.3.6.1 */
-        /* 7.6.1 */
         static const char *method[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -1468,7 +1319,7 @@
         };
         xmlNode *ercm_n = xmlNewChild(node, NULL, (xmlChar *) "CorrectionMethod", NULL);
         assert( ercm_n != NULL );
+        dmixml_AddAttribute(ercm_n, "dmispec", "3.3.6.1");
-        dmixml_AddAttribute(ercm_n, "dmispec", "7.6.1");
         dmixml_AddAttribute(ercm_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x08) {
@@ -1478,7 +1329,7 @@
         }
 }
 
+/* 3.3.6.2 */
-/* 7.6.2 */
 void dmi_memory_controller_ec_capabilities(xmlNode *node, const char *tagname, u8 code)
 {
         static const char *capabilities[] = {
@@ -1492,7 +1343,7 @@
 
         xmlNode *cap_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
         assert( cap_n != NULL );
+        dmixml_AddAttribute(cap_n, "dmispec", "3.3.6.2");
-        dmixml_AddAttribute(cap_n, "dmispec", "7.6.2");
         dmixml_AddAttribute(cap_n, "flags", "0x%04x", code);
 
         if((code & 0x3F) != 0) {
@@ -1509,7 +1360,7 @@
 
 void dmi_memory_controller_interleave(xmlNode *node, const char *tagname, u8 code)
 {
+        /* 3.3.6.3 */
-        /* 7.6.3 */
         static const char *interleave[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -1521,7 +1372,7 @@
         };
         xmlNode *mci_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
         assert( mci_n != NULL );
+        dmixml_AddAttribute(mci_n, "dmispec", "3.3.6.3");
-        dmixml_AddAttribute(mci_n, "dmispec", "7.6.3");
         dmixml_AddAttribute(mci_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x07) {
@@ -1531,7 +1382,7 @@
         }
 }
 
+/* 3.3.6.4 */
-/* 7.6.4 */
 void dmi_memory_controller_speeds(xmlNode *node, u16 code)
 {
         static struct {
@@ -1546,7 +1397,7 @@
         };
         xmlNode *mcs_n = xmlNewChild(node, NULL, (xmlChar *) "SupportedSpeeds", NULL);
         assert( mcs_n != NULL );
+        dmixml_AddAttribute(mcs_n, "dmispec", "3.3.6.4");
-        dmixml_AddAttribute(mcs_n, "dmispec", "7.6.4");
         dmixml_AddAttribute(mcs_n, "flags", "0x%04x", code);
 
         if((code & 0x001F) == 0) {
@@ -1578,10 +1429,10 @@
 }
 
 /*******************************************************************************
+** 3.3.7 Memory Module Information (Type 6)
-** 7.7 Memory Module Information (Type 6)
 */
 
+/* 3.3.7.1 */
-/* 7.7.1 */
 void dmi_memory_module_types(xmlNode *node, const char *tagname, u16 code)
 {
         static const char *types[] = {
@@ -1599,7 +1450,7 @@
         };
         xmlNode *mmt_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
         assert( mmt_n != NULL );
+        dmixml_AddAttribute(mmt_n, "dmispec", "3.3.7.1");
-        dmixml_AddAttribute(mmt_n, "dmispec", "7.7.1");
         dmixml_AddAttribute(mmt_n, "flags", "0x%04x", code);
 
         if((code & 0x07FF) != 0) {
@@ -1645,14 +1496,14 @@
         }
 }
 
+/* 3.3.7.2 */
-/* 7.7.2 */
 void dmi_memory_module_size(xmlNode *node, const char *tagname, u8 code)
 {
         int check_conn = 1;
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
         assert( data_n != NULL );
 
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.7.2");
-        dmixml_AddAttribute(data_n, "dmispec", "7.7.2");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         switch (code & 0x7F) {
@@ -1698,7 +1549,7 @@
 }
 
 /*******************************************************************************
+** 3.3.8 Cache Information (Type 7)
-** 7.8 Cache Information (Type 7)
 */
 static const char *dmi_cache_mode(u8 code)
 {
@@ -1723,7 +1574,7 @@
 
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "CacheLocation", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.8");
-        dmixml_AddAttribute(data_n, "dmispec", "7.8");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(location[code] != NULL) {
@@ -1737,7 +1588,7 @@
 {
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.8");
-        dmixml_AddAttribute(data_n, "dmispec", "7.8");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code & 0x8000) {
@@ -1749,7 +1600,7 @@
         }
 }
 
+/* 3.3.8.2 */
-/* 7.8.2 */
 void dmi_cache_types(xmlNode *node, const char *tagname, u16 code)
 {
         static const char *types[] = {
@@ -1764,7 +1615,7 @@
 
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.8.2");
-        dmixml_AddAttribute(data_n, "dmispec", "7.8.2");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
 
@@ -1781,7 +1632,7 @@
 
 void dmi_cache_ec_type(xmlNode *node, u8 code)
 {
+        /* 3.3.8.3 */
-        /* 7.8.3 */
         static const char *type[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -1792,7 +1643,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ErrorCorrectionType", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.8.3");
-        dmixml_AddAttribute(data_n, "dmispec", "7.8.3");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x06) {
@@ -1804,7 +1655,7 @@
 
 void dmi_cache_type(xmlNode *node, u8 code)
 {
+        /* 3.3.8.4 */
-        /* 7.8.4 */
         static const char *type[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -1814,7 +1665,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SystemType", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.8.4");
-        dmixml_AddAttribute(data_n, "dmispec", "7.8.4");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x05) {
@@ -1826,7 +1677,7 @@
 
 void dmi_cache_associativity(xmlNode *node, u8 code)
 {
+        /* 3.3.8.5 */
-        /* 7.8.5 */
         static const char *type[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -1835,20 +1686,14 @@
                 "4-way Set-associative",
                 "Fully Associative",
                 "8-way Set-associative",
+                "16-way Set-associative"        /* 0x08 */
-                "16-way Set-associative",       /* 0x08 */
-                "12-way Set-associative",
-                "24-way Set-associative",
-                "32-way Set-associative",
-                "48-way Set-associative",
-                "64-way Set-associative"        /* 0x0D */
-                "20-way Set-associative"        /* 0x0E */
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Associativity", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.8.5");
-        dmixml_AddAttribute(data_n, "dmispec", "7.8.5");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
+        if(code >= 0x01 && code <= 0x08) {
-        if(code >= 0x01 && code <= 0x0E) {
                 dmixml_AddTextContent(data_n, type[code - 0x01]);
         } else {
                 dmixml_AddAttribute(data_n, "outofspec", "1");
@@ -1856,12 +1701,12 @@
 }
 
 /*******************************************************************************
+** 3.3.9 Port Connector Information (Type 8)
-** 7.9 Port Connector Information (Type 8)
 */
 
 void dmi_port_connector_type(xmlNode *node, const char *tpref, u8 code)
 {
+        /* 3.3.9.2 */
-        /* 7.9.2 */
         static const char *type[] = {
                 "None",         /* 0x00 */
                 "Centronics",
@@ -1909,7 +1754,7 @@
 
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Connector", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.9.2");
-        dmixml_AddAttribute(data_n, "dmispec", "7.9.2");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
         dmixml_AddAttribute(data_n, "type", "%s", tpref);
 
@@ -1926,7 +1771,7 @@
 
 void dmi_port_type(xmlNode *node, u8 code)
 {
+        /* 3.3.9.3 */
-        /* 7.9.3 */
         static const char *type[] = {
                 "None",         /* 0x00 */
                 "Parallel Port XT/AT Compatible",
@@ -1970,7 +1815,7 @@
 
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "PortType", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.9.3");
-        dmixml_AddAttribute(data_n, "dmispec", "7.9.3");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code <= 0x21) {
@@ -1985,12 +1830,12 @@
 }
 
 /*******************************************************************************
+** 3.3.10 System Slots (Type 9)
-** 7.10 System Slots (Type 9)
 */
 
 void dmi_slot_type(xmlNode *node, u8 code)
 {
+        /* 3.3.10.1 */
-        /* 7.10.1 */
         static const char *type[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -2023,28 +1868,16 @@
                 "PCI Express x2",
                 "PCI Express x4",
                 "PCI Express x8",
+                "PCI Express x16"       /* 0xAA */
-                "PCI Express x16",      /* 0xAA */
-                "PCI Express 2",
-                "PCI Express 2 x1",
-                "PCI Express 2 x2",
-                "PCI Express 2 x4",
-                "PCI Express 2 x8",
-                "PCI Express 2 x16",    /* 0xB0 */
-                "PCI Express 3",
-                "PCI Express 3 x1",
-                "PCI Express 3 x2",
-                "PCI Express 3 x4",
-                "PCI Express 3 x8",
-                "PCI Express 3 x16"     /* 0xB6 */
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SlotType", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.10.1");
-        dmixml_AddAttribute(data_n, "dmispec", "7.10.1");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x13) {
                 dmixml_AddTextContent(data_n, "%s", type[code - 0x01]);
+        } else if(code >= 0xA0 && code <= 0xAA) {
-        } else if(code >= 0xA0 && code <= 0xB6) {
                 dmixml_AddTextContent(data_n, "%s", type_0xA0[code - 0xA0]);
         } else {
                 dmixml_AddAttribute(data_n, "outofspec", "1");
@@ -2053,7 +1886,7 @@
 
 void dmi_slot_bus_width(xmlNode *node, u8 code)
 {
+        /* 3.3.10.2 */
-        /* 7.10.2 */
         static const char *width[] = {
                 "",             /* 0x01, "Other" */
                 "",             /* "Unknown" */
@@ -2072,7 +1905,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SlotWidth", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.10.2");
-        dmixml_AddAttribute(data_n, "dmispec", "7.10.2");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if( (code >= 0x01) && (code <= 0x0E) ) {
@@ -2084,7 +1917,7 @@
 
 void dmi_slot_current_usage(xmlNode *node, u8 code)
 {
+        /* 3.3.10.3 */
-        /* 7.10.3 */
         static const char *usage[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -2094,7 +1927,7 @@
 
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "CurrentUsage", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.10.3");
-        dmixml_AddAttribute(data_n, "dmispec", "7.10.3");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
 
@@ -2105,7 +1938,7 @@
         }
 }
 
+/* 3.3.1O.4 */
-/* 7.1O.4 */
 void dmi_slot_length(xmlNode *node, u8 code)
 {
         static const char *length[] = {
@@ -2117,7 +1950,7 @@
 
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SlotLength", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.10.4");
-        dmixml_AddAttribute(data_n, "dmispec", "7.10.4");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x04) {
@@ -2127,7 +1960,7 @@
         }
 }
 
+/* 3.3.10.5 */
-/* 7.10.5 */
 void inline set_slottype(xmlNode *node, u8 type) {
         switch (type) {
         case 0x04:             /* MCA */
@@ -2150,21 +1983,8 @@
                 dmixml_AddAttribute(node, "slottype", "PCI-X");
                 break;
         case 0xA5:             /* PCI Express */
-        case 0xA6:             /* PCI Express */
-        case 0xA7:             /* PCI Express */
-        case 0xA8:             /* PCI Express */
-        case 0xA9:             /* PCI Express */
-        case 0xAA:             /* PCI Express */
                 dmixml_AddAttribute(node, "slottype", "PCI Express");
                 break;
-        case 0xAB:             /* PCI Express 2*/
-        case 0xAC:             /* PCI Express 2*/
-        case 0xAD:             /* PCI Express 2*/
-        case 0xAE:             /* PCI Express 2*/
-        case 0xAF:             /* PCI Express 2*/
-        case 0xB0:             /* PCI Express 2*/
-                dmixml_AddAttribute(node, "slottype", "PCI Express 2");
-                break;
         case 0x07:             /* PCMCIA */
                 dmixml_AddAttribute(node, "slottype", "PCMCIA");
                 break;
@@ -2176,7 +1996,7 @@
 void dmi_slot_id(xmlNode *node, u8 code1, u8 code2, u8 type)
 {
         xmlNode *slotid_n = xmlNewChild(node, NULL, (xmlChar *) "SlotID", NULL);
+        dmixml_AddAttribute(slotid_n, "dmispec", "3.3.10.5");
-        dmixml_AddAttribute(slotid_n, "dmispec", "7.10.5");
         dmixml_AddAttribute(slotid_n, "flags1", "0x%04x", code1);
         dmixml_AddAttribute(slotid_n, "flags2", "0x%04x", code2);
         dmixml_AddAttribute(slotid_n, "type", "0x%04x", type);
@@ -2195,17 +2015,6 @@
         case 0x12:             /* PCI-X */
         case 0x13:             /* AGP */
         case 0xA5:             /* PCI Express */
-        case 0xA6:             /* PCI Express */
-        case 0xA7:             /* PCI Express */
-        case 0xA8:             /* PCI Express */
-        case 0xA9:             /* PCI Express */
-        case 0xAA:             /* PCI Express */
-        case 0xAB:             /* PCI Express 2 */
-        case 0xAC:             /* PCI Express 2 */
-        case 0xAD:             /* PCI Express 2 */
-        case 0xAE:             /* PCI Express 2 */
-        case 0xAF:             /* PCI Express 2 */
-        case 0xB0:             /* PCI Express 2 */
                 dmixml_AddAttribute(slotid_n, "id", "%i", code1);
                 break;
         case 0x07:             /* PCMCIA */
@@ -2220,7 +2029,7 @@
 
 void dmi_slot_characteristics(xmlNode *node, u8 code1, u8 code2)
 {
+        /* 3.3.10.6 */
-        /* 7.10.6 */
         static const char *characteristics1[] = {
                 "5.0 V is provided",    /* 1 */
                 "3.3 V is provided",
@@ -2231,7 +2040,7 @@
                 "Modem ring resume is supported"        /* 7 */
         };
 
+        /* 3.3.10.7 */
-        /* 7.10.7 */
         static const char *characteristics2[] = {
                 "PME signal is supported",      /* 0 */
                 "Hot-plug devices are supported",
@@ -2239,7 +2048,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "SlotCharacteristics", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.10.6");
-        dmixml_AddAttribute(data_n, "dmispec", "7.10.6, 7.10.7");
         dmixml_AddAttribute(data_n, "flags1", "0x%04x", code1);
         dmixml_AddAttribute(data_n, "flags2", "0x%04x", code2);
 
@@ -2271,10 +2080,10 @@
 
 void dmi_slot_segment_bus_func(xmlNode *node, u16 code1, u8 code2, u8 code3)
 {
+        /* 3.3.10.8 */
-        /* 7.10.8 */
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "BusAddress", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.10.8");
-        dmixml_AddAttribute(data_n, "dmispec", "7.10.8");
 
         if(!(code1 == 0xFFFF && code2 == 0xFF && code3 == 0xFF)) {
                 dmixml_AddTextContent(data_n, "%04x:%02x:%02x.%x", code1, code2, code3 >> 3, code3 & 0x7);
@@ -2282,12 +2091,12 @@
 }
 
 /*******************************************************************************
+** 3.3.11 On Board Devices Information (Type 10)
-** 7.11 On Board Devices Information (Type 10)
 */
 
 void dmi_on_board_devices_type(xmlNode *node, u8 code)
 {
+        /* 3.3.11.1 */
-        /* 7.11.1 */
         static const char *type[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -2301,7 +2110,7 @@
                 "SAS Controller"        /* 0x0A */
         };
 
+        dmixml_AddAttribute(node, "dmispec", "3.3.11.1");
-        dmixml_AddAttribute(node, "dmispec", "7.11.1, 7.42.2");
         dmixml_AddAttribute(node, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x0A) {
@@ -2311,7 +2120,7 @@
         }
 }
 
+void dmi_on_board_devices(xmlNode *node, const char *tagname, struct dmi_header *h)
-void dmi_on_board_devices(xmlNode *node, const char *tagname, const struct dmi_header *h)
 {
         u8 *p = h->data + 4;
         u8 count = (h->length - 0x04) / 2;
@@ -2319,7 +2128,7 @@
 
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.11");
-        dmixml_AddAttribute(data_n, "dmispec", "7.11");
 
         for(i = 0; i < count; i++) {
                 xmlNode *dev_n = xmlNewChild(data_n, NULL, (xmlChar *) "Device", NULL);
@@ -2327,13 +2136,13 @@
 
                 dmi_on_board_devices_type(dev_n, p[2 * i] & 0x7F);
                 dmixml_AddAttribute(dev_n, "Enabled", "%i", ((p[2 * i] & 0x80) ? 1 : 0));
+                dmixml_AddTextChild(dev_n, "Description", "%s", dmi_string(h, p[2 * i + 1]));
-                dmixml_AddDMIstring(dev_n, "Description", h, p[2 * i + 1]);
                 dev_n = NULL;
         }
 }
 
 /*******************************************************************************
+ * 3.3.12 OEM Strings (Type 11)
- * 7.12 OEM Strings (Type 11)
  */
 
 void dmi_oem_strings(xmlNode *node, struct dmi_header *h)
@@ -2345,14 +2154,14 @@
         dmixml_AddAttribute(node, "count", "%i", count);
 
         for(i = 1; i <= count; i++) {
+                xmlNode *str_n = dmixml_AddTextChild(node, "Record", "%s", dmi_string(h, i));
-                xmlNode *str_n = dmixml_AddDMIstring(node, "Record", h, i);
                 assert( str_n != NULL );
                 dmixml_AddAttribute(str_n, "index", "%i", i);
         }
 }
 
 /*******************************************************************************
+** 3.3.13 System Configuration Options (Type 12)
-** 7.13 System Configuration Options (Type 12)
 */
 
 void dmi_system_configuration_options(xmlNode *node, struct dmi_header *h)
@@ -2363,11 +2172,11 @@
 
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Options", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.13");
-        dmixml_AddAttribute(data_n, "dmispec", "7.13");
         dmixml_AddAttribute(data_n, "count", "%i", count);
 
         for(i = 1; i <= count; i++) {
+                xmlNode *o_n = dmixml_AddTextChild(data_n, "Option", "%s", dmi_string(h, i));
-                xmlNode *o_n = dmixml_AddDMIstring(data_n, "Option", h, i);
                 assert( o_n != NULL );
 
                 dmixml_AddAttribute(o_n, "index", "%ld", i);
@@ -2375,10 +2184,10 @@
 }
 
 /*******************************************************************************
+** 3.3.14 BIOS Language Information (Type 13)
-** 7.14 BIOS Language Information (Type 13)
 */
 
+void dmi_bios_languages(xmlNode *node, struct dmi_header *h)
-void dmi_bios_languages(xmlNode *node, struct dmi_header *h, u8 brevity_code)
 {
         u8 *p = h->data + 4;
         u8 count = p[0x00];
@@ -2386,29 +2195,23 @@
 
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Installed", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.14");
-        dmixml_AddAttribute(data_n, "dmispec", "7.14");
         dmixml_AddAttribute(data_n, "count", "%i", count);
 
-        if (brevity_code & 0x01) {
-                dmixml_AddAttribute(data_n, "format", "Abbreviated");
-        } else {
-                dmixml_AddAttribute(data_n, "format", "Long");
-        }
-
         for(i = 1; i <= count; i++) {
+                xmlNode *l_n = dmixml_AddTextChild(data_n, "Language", "%s", dmi_string(h, i));
-                xmlNode *l_n = dmixml_AddDMIstring(data_n, "Language", h, i);
                 assert( l_n != NULL );
                 dmixml_AddAttribute(l_n, "index", "%i", i);
         }
 }
 
 /*******************************************************************************
+** 3.3.15 Group Associations (Type 14)
-** 7.15 Group Associations (Type 14)
 */
 
 void dmi_group_associations_items(xmlNode *node, u8 count, const u8 * p)
 {
+        dmixml_AddAttribute(node, "dmispec", "3.3.15");
-        dmixml_AddAttribute(node, "dmispec", "7.15");
         dmixml_AddAttribute(node, "items", "%i", count);
 
         int i;
@@ -2422,7 +2225,7 @@
 }
 
 /*******************************************************************************
+** 3.3.16 System Event Log (Type 15)
-** 7.16 System Event Log (Type 15)
 */
 
 void dmi_event_log_method(xmlNode *node, u8 code)
@@ -2437,7 +2240,7 @@
 
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "AccessMethod", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.16");
-        dmixml_AddAttribute(data_n, "dmispec", "7.16");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code <= 0x04) {
@@ -2463,9 +2266,10 @@
 
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Status", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.16");
-        dmixml_AddAttribute(data_n, "dmispec", "7.16");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
+        // FIXME: Should we use 0/1 instead of strings?
         dmixml_AddAttribute(data_n, "Full", "%s", full[(code >> 1) & 1]);
         dmixml_AddAttribute(data_n, "Valid", "%s", valid[(code >> 0) & 1]);
 }
@@ -2474,10 +2278,10 @@
 {
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Address", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.16.3");
-        dmixml_AddAttribute(data_n, "dmispec", "7.16.3");
         dmixml_AddAttribute(data_n, "method", "0x%04x", method);
 
+        /* 3.3.16.3 */
-        /* 7.16.3 */
         switch (method) {
         case 0x00:
         case 0x01:
@@ -2505,7 +2309,7 @@
 
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Format", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.16");
-        dmixml_AddAttribute(data_n, "dmispec", "7.16");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code <= 0x01) {
@@ -2519,7 +2323,7 @@
 
 void dmi_event_log_descriptor_type(xmlNode *node, u8 code)
 {
+        /* 3.3.16.6.1 */
-        /* 7.16.6.1 */
         static const char *type[] = {
                 NULL,           /* 0x00 */
                 "Single-bit ECC memory error",
@@ -2549,7 +2353,7 @@
 
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Descriptor", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.16.6.1");
-        dmixml_AddAttribute(data_n, "dmispec", "7.16.6.1");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code <= 0x17 && type[code] != NULL) {
@@ -2565,7 +2369,7 @@
 
 void dmi_event_log_descriptor_format(xmlNode *node, u8 code)
 {
+        /* 3.3.16.6.2 */
-        /* 7.16.6.2 */
         static const char *format[] = {
                 "None",         /* 0x00 */
                 "Handle",
@@ -2578,7 +2382,7 @@
 
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Format", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.16.6.2");
-        dmixml_AddAttribute(data_n, "dmispec", "7.16.6.2");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code <= 0x06) {
@@ -2592,10 +2396,10 @@
 
 void dmi_event_log_descriptors(xmlNode *node, u8 count, const u8 len, const u8 * p)
 {
+        /* 3.3.16.1 */
-        /* 7.16.1 */
         int i;
 
+        dmixml_AddAttribute(node, "dmispec", "3.3.16.1");
-        dmixml_AddAttribute(node, "dmispec", "7.16.1");
 
         for(i = 0; i < count; i++) {
                 if(len >= 0x02) {
@@ -2609,12 +2413,12 @@
 }
 
 /*******************************************************************************
+** 3.3.17 Physical Memory Array (Type 16)
-** 7.17 Physical Memory Array (Type 16)
 */
 
 void dmi_memory_array_location(xmlNode *node, u8 code)
 {
+        /* 3.3.17.1 */
-        /* 7.17.1 */
         static const char *location[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -2637,12 +2441,12 @@
 
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Location", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.17.1");
-        dmixml_AddAttribute(data_n, "dmispec", "7.17.1");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x0A) {
                 dmixml_AddTextContent(data_n, location[code - 0x01]);
+        } else if(code >= 0xA0 && code <= 0xA4) {
-        } else if(code >= 0xA0 && code <= 0xA3) {
                 dmixml_AddTextContent(data_n, location_0xA0[code - 0xA0]);
         } else {
                 dmixml_AddAttribute(data_n, "outofspec", "1");
@@ -2651,7 +2455,7 @@
 
 void dmi_memory_array_use(xmlNode *node, u8 code)
 {
+        /* 3.3.17.2 */
-        /* 7.17.2 */
         static const char *use[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -2663,7 +2467,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Use", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.17.2");
-        dmixml_AddAttribute(data_n, "dmispec", "7.17.2");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x07) {
@@ -2675,7 +2479,7 @@
 
 void dmi_memory_array_ec_type(xmlNode *node, u8 code)
 {
+        /* 3.3.17.3 */
-        /* 7.17.3 */
         static const char *type[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -2688,7 +2492,7 @@
 
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ErrorCorrectionType", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.17.3");
-        dmixml_AddAttribute(data_n, "dmispec", "7.17.3");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x07) {
@@ -2698,23 +2502,25 @@
         }
 }
 
+void dmi_memory_array_capacity(xmlNode *node, u32 code)
-void dmi_memory_array_capacity(xmlNode *node, struct dmi_header *h, const u8 *data)
 {
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "MaxCapacity", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
+        if(code == 0x8000000) {
+                dmixml_AddAttribute(data_n, "unknown", "1");
+        } else {
+                if((code & 0x000FFFFF) == 0) {
+                        dmixml_AddAttribute(data_n, "unit", "GB");
+                        dmixml_AddTextContent(data_n, "%i", code >> 20);
+                } else if((code & 0x000003FF) == 0) {
+                        dmixml_AddAttribute(data_n, "unit", "MB");
+                        dmixml_AddTextContent(data_n, "%i", code >> 10);
-        if(DWORD(data + 0x07) == 0x8000000) {
-                if( h->length < 0x17 ) {
-                        dmixml_AddAttribute(data_n, "unknown", "1");
                 } else {
+                        dmixml_AddAttribute(data_n, "unit", "KB");
+                        dmixml_AddTextContent(data_n, "%i", code);
-                        dmi_add_memory_size(data_n, QWORD(data + 0x0F), 0);
                 }
-        } else {
-                u64 capacity;
-
-                capacity.h = 0;
-                capacity.l = DWORD(data + 0x07);
-                dmi_add_memory_size(data_n, capacity, 1);
         }
 }
 
@@ -2733,7 +2539,7 @@
 }
 
 /*******************************************************************************
+** 3.3.18 Memory Device (Type 17)
-** 7.18 Memory Device (Type 17)
 */
 
 void dmi_memory_device_width(xmlNode *node, const char *tagname, u16 code)
@@ -2769,33 +2575,9 @@
         }
 }
 
-
-static void dmi_memory_device_extended_size(xmlNode *node, u32 code)
-{
-        xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Size", NULL);
-        assert( data_n != NULL );
-
-        code &= 0x7FFFFFFFUL;
-        dmixml_AddAttribute(data_n, "flags", "0x%08x", code);
-        dmixml_AddAttribute(data_n, "mode", "extended");
-
-        /* Use the most suitable unit depending on size */
-        if (code & 0x3FFUL) {
-                dmixml_AddAttribute(data_n, "unit", "MB");
-                dmixml_AddTextContent(data_n, "%lu", (unsigned long) code);
-        } else if (code & 0xFFFFFUL) {
-                dmixml_AddAttribute(data_n, "unit", "GB");
-                dmixml_AddTextContent(data_n, "%lu", (unsigned long) code >> 10);
-        } else {
-                dmixml_AddAttribute(data_n, "unit", "TB");
-                dmixml_AddTextContent(data_n, "%lu", (unsigned long) code >> 20);
-        }
-}
-
-
 void dmi_memory_device_form_factor(xmlNode *node, u8 code)
 {
+        /* 3.3.18.1 */
-        /* 7.18.1 */
         static const char *form_factor[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -2815,7 +2597,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "FormFactor", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.18.1");
-        dmixml_AddAttribute(data_n, "dmispec", "7.18.1");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x0F) {
@@ -2840,7 +2622,7 @@
 
 void dmi_memory_device_type(xmlNode *node, u8 code)
 {
+        /* 3.3.18.2 */
-        /* 7.18.2 */
         static const char *type[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -2861,19 +2643,14 @@
                 "RDRAM",
                 "DDR",
                 "DDR2",
+                "DDR2 FB-DIMM"  /* 0x14 */
-                "DDR2 FB-DIMM", /* 0x14 */
-                "Reserved",
-                "Reserved",
-                "Reserved",
-                "DDR3"
-                "FBD2"          /* 0x19 */
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.18.2");
-        dmixml_AddAttribute(data_n, "dmispec", "7.18.2");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
+        if(code >= 0x01 && code <= 0x14) {
-        if(code >= 0x01 && code <= 0x19) {
                 dmixml_AddTextContent(data_n, "%s", type[code - 0x01]);
         } else {
                 dmixml_AddAttribute(data_n, "outofspec", "1");
@@ -2882,7 +2659,7 @@
 
 void dmi_memory_device_type_detail(xmlNode *node, u16 code)
 {
+        /* 3.3.18.3 */
-        /* 7.18.3 */
         static const char *detail[] = {
                 "Other",        /* 1 */
                 "Unknown",
@@ -2895,19 +2672,16 @@
                 "EDO",
                 "Window DRAM",
                 "Cache DRAM",
+                "Non-Volatile"  /* 12 */
-                "Non-Volatile", /* 12 */
-                "Registered (Buffered)",
-                "Unbuffered (Unregistered)",  /* 14 */
-                "LRDIMM"                      /* 15 */
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "TypeDetails", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.18.3");
-        dmixml_AddAttribute(data_n, "dmispec", "7.18.3");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if((code & 0x1FFE) != 0) {
                 int i;
+                for(i = 1; i <= 12; i++) {
-                for(i = 1; i <= 14; i++) {
                         if(code & (1 << i)) {
                                 xmlNode *td_n = dmixml_AddTextChild(data_n, "flag", "%s", detail[i - 1]);
                                 assert( td_n != NULL );
@@ -2917,40 +2691,28 @@
         }
 }
 
+void dmi_memory_device_speed(xmlNode *node, u16 code)
-void dmi_memory_device_speed(xmlNode *node, const char *tag, u16 code)
 {
+        xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Speed", NULL);
-        xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tag, NULL);
         assert( data_n != NULL );
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code == 0) {
                 dmixml_AddAttribute(data_n, "unknown", "1");
         } else {
+                dmixml_AddAttribute(data_n, "speed_ns", "%.1f", (float) 1000 / code);
                 dmixml_AddAttribute(data_n, "unit", "MHz");
                 dmixml_AddTextContent(data_n, "%i", code);
         }
 }
 
-void dmi_memory_voltage_value(xmlNode *node, const char *tag, u16 code) {
-        xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tag, NULL);
-        assert( data_n != NULL );
-        dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
-
-        if (code == 0) {
-                dmixml_AddAttribute(data_n, "unknown", "1");
-        } else {
-                dmixml_AddAttribute(data_n, "unit", "V");
-                dmixml_AddTextContent(data_n, "%.3f", (float)(i16)code / 1000);
-        }
-}
-
 /*******************************************************************************
+* 3.3.19 32-bit Memory Error Information (Type 18)
-* 7.19 32-bit Memory Error Information (Type 18)
 */
 
 void dmi_memory_error_type(xmlNode *node, u8 code)
 {
+        /* 3.3.19.1 */
-        /* 7.19.1 */
         static const char *type[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -2969,7 +2731,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.19.1");
-        dmixml_AddAttribute(data_n, "dmispec", "7.19.1");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x0E) {
@@ -2981,7 +2743,7 @@
 
 void dmi_memory_error_granularity(xmlNode *node, u8 code)
 {
+        /* 3.3.19.2 */
-        /* 7.19.2 */
         static const char *granularity[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -2990,7 +2752,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Granularity", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.19.2");
-        dmixml_AddAttribute(data_n, "dmispec", "7.19.2");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x04) {
@@ -3002,7 +2764,7 @@
 
 void dmi_memory_error_operation(xmlNode *node, u8 code)
 {
+        /* 3.3.19.3 */
-        /* 7.19.3 */
         static const char *operation[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -3012,7 +2774,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Operation", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.19.3");
-        dmixml_AddAttribute(data_n, "dmispec", "7.19.3");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x05) {
@@ -3047,45 +2809,32 @@
 }
 
 /*******************************************************************************
+** 3.3.20 Memory Array Mapped Address (Type 19)
-** 7.20 Memory Array Mapped Address (Type 19)
 */
 
 void dmi_mapped_address_size(xmlNode *node, u32 code)
 {
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "RangeSize", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.19.2");
-        dmixml_AddAttribute(data_n, "dmispec", "7.20");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code == 0) {
                 dmixml_AddAttribute(data_n, "invalid", "1");
+        } else if((code & 0x000FFFFF) == 0) {
+                dmixml_AddAttribute(data_n, "unit", "GB");
+                dmixml_AddTextContent(data_n, "%i", code >> 20);
+        } else if((code & 0x000003FF) == 0) {
+                dmixml_AddAttribute(data_n, "unit", "MB");
+                dmixml_AddTextContent(data_n, "%i", code >> 10);
         } else {
+                dmixml_AddAttribute(data_n, "unit", "KB");
+                dmixml_AddTextContent(data_n, "%i", code);
-                u64 size;
-
-                size.h = 0;
-                size.l = code;
-                dmi_add_memory_size(data_n, size, 1);
-        }
-}
-
-void dmi_mapped_address_extended_size(xmlNode *node, u64 start, u64 end)
-{
-        xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "RangeSize", NULL);
-        assert( data_n != NULL );
-        dmixml_AddAttribute(data_n, "dmispec", "7.20");
-        dmixml_AddAttribute(data_n, "mode", "extended");
-        dmixml_AddAttribute(data_n, "start_address", "0x%08x%08x", start.h, start.l);
-        dmixml_AddAttribute(data_n, "end_address", "0x%08x%08x", end.h, end.l);
-
-        if(start.h == end.h && start.l == end.l) {
-                dmixml_AddAttribute(data_n, "invalid", "1");
-        } else {
-                dmi_add_memory_size(data_n, u64_range(start, end), 0);
         }
 }
 
 /*******************************************************************************
+** 3.3.21 Memory Device Mapped Address (Type 20)
-** 7.21 Memory Device Mapped Address (Type 20)
 */
 
 void dmi_mapped_address_row_position(xmlNode *node, u8 code)
@@ -3127,12 +2876,12 @@
 }
 
 /*******************************************************************************
+** 3.3.22 Built-in Pointing Device (Type 21)
-** 7.22 Built-in Pointing Device (Type 21)
 */
 
 void dmi_pointing_device_type(xmlNode *node, u8 code)
 {
+        /* 3.3.22.1 */
-        /* 7.22.1 */
         static const char *type[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -3146,7 +2895,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "DeviceType", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.22.1");
-        dmixml_AddAttribute(data_n, "dmispec", "7.22.1");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x09) {
@@ -3158,7 +2907,7 @@
 
 void dmi_pointing_device_interface(xmlNode *node, u8 code)
 {
+        /* 3.3.22.2 */
-        /* 7.22.2 */
         static const char *interface[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -3176,7 +2925,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "DeviceInterface", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.22.2");
-        dmixml_AddAttribute(data_n, "dmispec", "7.22.2");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x08) {
@@ -3189,12 +2938,12 @@
 }
 
 /*******************************************************************************
+** 3.3.23 Portable Battery (Type 22)
-** 7.23 Portable Battery (Type 22)
 */
 
 void dmi_battery_chemistry(xmlNode *node, u8 code)
 {
+        /* 3.3.23.1 */
-        /* 7.23.1 */
         static const char *chemistry[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -3207,7 +2956,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "BatteryChemistry", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.22.2");
-        dmixml_AddAttribute(data_n, "dmispec", "7.22.2");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x08) {
@@ -3256,7 +3005,7 @@
 }
 
 /*******************************************************************************
+** 3.3.24 System Reset (Type 23)
-** 7.24 System Reset (Type 23)
 */
 
 void dmi_system_reset_boot_option(xmlNode *node, const char *tagname, u8 code)
@@ -3305,7 +3054,7 @@
 }
 
 /*******************************************************************************
+ * 3.3.25 Hardware Security (Type 24)
- * 7.25 Hardware Security (Type 24)
  */
 
 void dmi_hardware_security_status(xmlNode *node, const char *tagname, u8 code)
@@ -3323,7 +3072,7 @@
 }
 
 /*******************************************************************************
+** 3.3.26 System Power Controls (Type 25)
-** 7.26 System Power Controls (Type 25)
 */
 
 #define DMI_POWER_CTRL_TIME_STR(dest, variant, data)         \
@@ -3332,11 +3081,11 @@
 
 void dmi_power_controls_power_on(xmlNode *node, const char *tagname, const u8 * p)
 {
+        /* 3.3.26.1 */
-        /* 7.26.1 */
         char timestr[5][5];
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.26.1");
-        dmixml_AddAttribute(data_n, "dmispec", "7.26.1");
         dmixml_AddAttribute(data_n, "flags", "0x%08x", p);
 
         DMI_POWER_CTRL_TIME_STR(timestr[0], dmi_bcd_range(p[0], 0x01, 0x12), p[0])
@@ -3351,12 +3100,12 @@
 }
 
 /*******************************************************************************
+* 3.3.27 Voltage Probe (Type 26)
-* 7.27 Voltage Probe (Type 26)
 */
 
 void dmi_voltage_probe_location(xmlNode *node, u8 code)
 {
+        /* 3.3.27.1 */
-        /* 7.27.1 */
         static const char *location[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -3372,7 +3121,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Location", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.27.1");
-        dmixml_AddAttribute(data_n, "dmispec", "7.27.1");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x0B) {
@@ -3384,7 +3133,7 @@
 
 void dmi_probe_status(xmlNode *node, u8 code)
 {
+        /* 3.3.27.1 */
-        /* 7.27.1 */
         static const char *status[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -3395,7 +3144,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Status", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.27.1");
-        dmixml_AddAttribute(data_n, "dmispec", "7.27.1");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x06) {
@@ -3448,12 +3197,12 @@
 }
 
 /*******************************************************************************
+** 3.3.28 Cooling Device (Type 27)
-** 7.28 Cooling Device (Type 27)
 */
 
 void dmi_cooling_device_type(xmlNode *node, u8 code)
 {
+        /* 3.3.28.1 */
-        /* 7.28.1 */
         static const char *type[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -3471,7 +3220,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.28.1", code);
-        dmixml_AddAttribute(data_n, "dmispec", "7.28.1", code);
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x09) {
@@ -3498,12 +3247,12 @@
 }
 
 /*******************************************************************************
+** 3.3.29 Temperature Probe (Type 28)
-** 7.29 Temperature Probe (Type 28)
 */
 
 void dmi_temperature_probe_location(xmlNode *node, u8 code)
 {
+        /* 3.3.29.1 */
-        /* 7.29.1 */
         static const char *location[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -3523,7 +3272,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Location", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.29.1", code);
-        dmixml_AddAttribute(data_n, "dmispec", "7.29.1", code);
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x0F) {
@@ -3562,7 +3311,7 @@
 }
 
 /*******************************************************************************
+** 3.3.30 Electrical Current Probe (Type 29)
-** 7.30 Electrical Current Probe (Type 29)
 */
 
 void dmi_current_probe_value(xmlNode *node, const char *tagname, u16 code)
@@ -3594,7 +3343,7 @@
 }
 
 /*******************************************************************************
+** 3.3.33 System Boot Information (Type 32)
-** 7.33 System Boot Information (Type 32)
 */
 
 void dmi_system_boot_status(xmlNode *node, u8 code)
@@ -3626,7 +3375,7 @@
 }
 
 /*******************************************************************************
+** 3.3.34 64-bit Memory Error Information (Type 33)
-** 7.34 64-bit Memory Error Information (Type 33)
 */
 
 void dmi_64bit_memory_error_address(xmlNode *node, const char *tagname, u64 code)
@@ -3642,12 +3391,12 @@
 }
 
 /*******************************************************************************
+** 3.3.35 Management Device (Type 34)
-** 7.35 Management Device (Type 34)
 */
 
 void dmi_management_device_type(xmlNode *node, u8 code)
 {
+        /* 3.3.35.1 */
-        /* 7.35.1 */
         static const char *type[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -3665,7 +3414,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.35.1", code);
-        dmixml_AddAttribute(data_n, "dmispec", "7.35.1", code);
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x0D) {
@@ -3677,7 +3426,7 @@
 
 void dmi_management_device_address_type(xmlNode *node, u8 code)
 {
+        /* 3.3.35.2 */
-        /* 7.35.2 */
         static const char *type[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -3687,7 +3436,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "AddressType", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.35.2", code);
-        dmixml_AddAttribute(data_n, "dmispec", "7.35.2", code);
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x05) {
@@ -3698,12 +3447,12 @@
 }
 
 /*******************************************************************************
+** 3.3.38 Memory Channel (Type 37)
-** 7.38 Memory Channel (Type 37)
 */
 
 void dmi_memory_channel_type(xmlNode *node, u8 code)
 {
+        /* 3.3.38.1 */
-        /* 7.38.1 */
         static const char *type[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -3712,7 +3461,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.38.1", code);
-        dmixml_AddAttribute(data_n, "dmispec", "7.38.1", code);
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x04) {
@@ -3736,12 +3485,12 @@
 }
 
 /*******************************************************************************
+** 3.3.39 IPMI Device Information (Type 38)
-** 7.39 IPMI Device Information (Type 38)
 */
 
 void dmi_ipmi_interface_type(xmlNode *node, u8 code)
 {
+        /* 3.3.39.1 and IPMI 2.0, appendix C1, table C1-2 */
-        /* 7.39.1 and IPMI 2.0, appendix C1, table C1-2 */
         static const char *type[] = {
                 "Unknown",      /* 0x00 */
                 "KCS (Keyboard Control Style)",
@@ -3751,7 +3500,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "InterfaceType", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.39.1", code);
-        dmixml_AddAttribute(data_n, "dmispec", "7.39.1", code);
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code <= 0x04) {
@@ -3798,7 +3547,7 @@
 }
 
 /*******************************************************************************
+** 3.3.40 System Power Supply (Type 39)
-** 7.40 System Power Supply (Type 39)
 */
 
 void dmi_power_supply_power(xmlNode *node, u16 code)
@@ -3817,7 +3566,7 @@
 
 void dmi_power_supply_type(xmlNode *node, u8 code)
 {
+        /* 3.3.40.1 */
-        /* 7.40.1 */
         static const char *type[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -3830,7 +3579,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.40.1");
-        dmixml_AddAttribute(data_n, "dmispec", "7.40.1");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x08) {
@@ -3842,7 +3591,7 @@
 
 void dmi_power_supply_status(xmlNode *node, u8 code)
 {
+        /* 3.3.40.1 */
-        /* 7.40.1 */
         static const char *status[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -3852,7 +3601,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Status", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.40.1");
-        dmixml_AddAttribute(data_n, "dmispec", "7.40.1");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
         dmixml_AddAttribute(data_n, "present", "1");
 
@@ -3865,7 +3614,7 @@
 
 void dmi_power_supply_range_switching(xmlNode *node, u8 code)
 {
+        /* 3.3.40.1 */
-        /* 7.40.1 */
         static const char *switching[] = {
                 "Other",        /* 0x01 */
                 "Unknown",
@@ -3876,7 +3625,7 @@
         };
         xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "VoltageRangeSwitching", NULL);
         assert( data_n != NULL );
+        dmixml_AddAttribute(data_n, "dmispec", "3.3.40.1");
-        dmixml_AddAttribute(data_n, "dmispec", "7.40.1");
         dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
 
         if(code >= 0x01 && code <= 0x06) {
@@ -3887,7 +3636,7 @@
 }
 
 /*
+** 3.3.41 Additional Information (Type 40)
-** 7.41 Additional Information (Type 40)
 **
 ** Proper support of this entry type would require redesigning a large part of
 ** the code, so I am waiting to see actual implementations of it to decide
@@ -3922,7 +3671,7 @@
                 dmixml_AddAttribute(data_n, "ReferenceHandle", "0x%04x", WORD(p + 0x01));
                 dmixml_AddAttribute(data_n, "ReferenceOffset", "0x%02x", p[0x03]);
 
+                str_n = dmixml_AddTextChild(data_n, "String", "%s", dmi_string(h, p[0x04]));
-                str_n = dmixml_AddDMIstring(data_n, "String", h, p[0x04]);
 
                 switch (length - 0x05) {
                 case 1:
@@ -3945,39 +3694,6 @@
         }
 }
 
-/*
- * 7.43 Management Controller Host Interface (Type 42)
- */
-
-xmlNode * dmi_management_controller_host_type(xmlNode *node, u8 code)
-{
-        /* DMTF DSP0239 (MCTP) version 1.1.0 */
-        static const char *type[] = {
-                "KCS: Keyboard Controller Style", /* 0x02 */
-                "8250 UART Register Compatible",
-                "16450 UART Register Compatible",
-                "16550/16550A UART Register Compatible",
-                "16650/16650A UART Register Compatible",
-                "16750/16750A UART Register Compatible",
-                "16850/16850A UART Register Compatible" /* 0x08 */
-        };
-        xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ManagementControllerHost", NULL);
-
-        assert( data_n != NULL );
-        dmixml_AddAttribute(data_n, "dmispec", "7.43");
-        dmixml_AddAttribute(data_n, "flags", "0x%04x", code);
-
-        if (code >= 0x02 && code <= 0x08) {
-                dmixml_AddTextChild(data_n, "Type", "%s", type[code - 0x01]);
-        } else if (code == 0xF0) {
-                dmixml_AddTextChild(data_n, "Type", "OEM");
-        } else {
-                dmixml_AddAttribute(data_n, "outofspec", "1");
-        }
-        return data_n;
-}
-
-
 /*******************************************************************************
 ** Main
 */
@@ -3997,14 +3713,14 @@
         dmixml_AddTextChild(sect_n, "DMIdescription", "%s", dmiMajor->desc);
 
         switch (h->type) {
+        case 0:                /* 3.3.1 BIOS Information */
-        case 0:                /* 7.1 BIOS Information */
                 if(h->length < 0x12) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "Vendor", "%s", dmi_string(h, data[0x04]));
+                dmixml_AddTextChild(sect_n, "Version", "%s", dmi_string(h, data[0x05]));
+                dmixml_AddTextChild(sect_n, "ReleaseDate", "%s", dmi_string(h, data[0x08]));
-                dmixml_AddDMIstring(sect_n, "Vendor", h, data[0x04]);
-                dmixml_AddDMIstring(sect_n, "Version", h, data[0x05]);
-                dmixml_AddDMIstring(sect_n, "ReleaseDate", h, data[0x08]);
 
                 /*
                  * On IA-64, the BIOS base address will read 0 because
@@ -4063,15 +3779,15 @@
                 }
                 break;
 
+        case 1:                /* 3.3.2 System Information */
-        case 1:                /* 7.2 System Information */
                 if(h->length < 0x08) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x04]));
+                dmixml_AddTextChild(sect_n, "ProductName", "%s", dmi_string(h, data[0x05]));
+                dmixml_AddTextChild(sect_n, "Version", "%s", dmi_string(h, data[0x06]));
+                dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07]));
-                dmixml_AddDMIstring(sect_n, "Manufacturer", h, data[0x04]);
-                dmixml_AddDMIstring(sect_n, "ProductName", h, data[0x05]);
-                dmixml_AddDMIstring(sect_n, "Version", h, data[0x06]);
-                dmixml_AddDMIstring(sect_n, "SerialNumber", h, data[0x07]);
 
                 if(h->length < 0x19) {
                         break;
@@ -4085,29 +3801,29 @@
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "SKUnumber", "%s", dmi_string(h, data[0x19]));
+                dmixml_AddTextChild(sect_n, "Family", "%s", dmi_string(h, data[0x1A]));
-                dmixml_AddDMIstring(sect_n, "SKUnumber", h, data[0x19]);
-                dmixml_AddDMIstring(sect_n, "Family", h, data[0x1A]);
                 break;
 
+        case 2:                /* 3.3.3 Base Board Information */
-        case 2:                /* 7.3 Base Board Information */
                 if(h->length < 0x08) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x04]));
+                dmixml_AddTextChild(sect_n, "ProductName", "%s", dmi_string(h, data[0x05]));
+                dmixml_AddTextChild(sect_n, "Version", "%s", dmi_string(h, data[0x06]));
+                dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07]));
-                dmixml_AddDMIstring(sect_n, "Manufacturer", h, data[0x04]);
-                dmixml_AddDMIstring(sect_n, "ProductName", h, data[0x05]);
-                dmixml_AddDMIstring(sect_n, "Version", h, data[0x06]);
-                dmixml_AddDMIstring(sect_n, "SerialNumber", h, data[0x07]);
 
                 if(h->length < 0x0F) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x08]));
-                dmixml_AddDMIstring(sect_n, "AssetTag", h, data[0x08]);
 
                 dmi_base_board_features(sect_n, data[0x09]);
 
+                dmixml_AddTextChild(sect_n, "ChassisLocation", "%s", dmi_string(h, data[0x0A]));
-                dmixml_AddDMIstring(sect_n, "ChassisLocation", h, data[0x0A]);
                 dmixml_AddTextChild(sect_n, "ChassisHandle", "0x%04x", WORD(data + 0x0B));
 
                 dmi_base_board_type(sect_n, "Type", data[0x0D]);
@@ -4119,17 +3835,17 @@
                 dmi_base_board_handles(sect_n, data[0x0E], data + 0x0F);
                 break;
 
+        case 3:                /* 3.3.4 Chassis Information */
-        case 3:                /* 7.4 Chassis Information */
                 if(h->length < 0x09) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x04]));
+                dmi_chassis_type(sect_n, data[0x05] & 0x7F);
-                dmixml_AddDMIstring(sect_n, "Manufacturer", h, data[0x04]);
-                dmi_chassis_type(sect_n, data[0x05]);
                 dmi_chassis_lock(sect_n, data[0x05] >> 7);
+                dmixml_AddTextChild(sect_n, "Version", "%s", dmi_string(h, data[0x06]));
+                dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07]));
+                dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x08]));
-                dmixml_AddDMIstring(sect_n, "Version", h, data[0x06]);
-                dmixml_AddDMIstring(sect_n, "SerialNumber", h, data[0x07]);
-                dmixml_AddDMIstring(sect_n, "AssetTag", h, data[0x08]);
 
                 if(h->length < 0x0D) {
                         break;
@@ -4163,29 +3879,24 @@
                 }
 
                 dmi_chassis_elements(sect_n, data[0x13], data[0x14], data + 0x15);
-                if (h->length < 0x16 + data[0x13] * data[0x14]) {
-                        break;
-                }
-                dmixml_AddDMIstring(sect_n, "SKUnumber", h, data[0x15 + data[0x13] * data[0x14]]);
-
                 break;
 
+        case 4:                /* 3.3.5 Processor Information */
-        case 4:                /* 7.5 Processor Information */
                 if(h->length < 0x1A) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "SocketDesignation", "%s", dmi_string(h, data[0x04]));
-                dmixml_AddDMIstring(sect_n, "SocketDesignation", h, data[0x04]);
                 dmi_processor_type(sect_n, data[0x05]);
+                dmi_processor_family(sect_n, h);
-                dmi_processor_family(sect_n, h, ver);
 
                 dmi_processor_id(sect_n, h);
 
                 sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Manufacturer", NULL);
                 assert( sub_n != NULL );
+                dmixml_AddTextChild(sub_n, "Vendor", dmi_string(h, data[0x07]));
-                dmixml_AddDMIstring(sub_n, "Vendor", h, data[0x07]);
 
+                dmixml_AddTextChild(sub_n, "Version", dmi_string(h, data[0x10]));
-                dmixml_AddDMIstring(sub_n, "Version", h, data[0x10]);
                 sub_n = NULL;
 
                 dmi_processor_voltage(sect_n, data[0x11]);
@@ -4251,9 +3962,9 @@
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x20]));
+                dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x21]));
+                dmixml_AddTextChild(sect_n, "PartNumber", "%s", dmi_string(h, data[0x22]));
-                dmixml_AddDMIstring(sect_n, "SerialNumber", h, data[0x20]);
-                dmixml_AddDMIstring(sect_n, "AssetTag", h, data[0x21]);
-                dmixml_AddDMIstring(sect_n, "PartNumber", h, data[0x22]);
 
                 if(h->length < 0x28) {
                         break;
@@ -4278,7 +3989,7 @@
                 sub_n = NULL;
                 break;
 
+        case 5:                /* 3.3.6 Memory Controller Information */
-        case 5:                /* 7.6 Memory Controller Information */
                 if(h->length < 0x0F) {
                         break;
                 }
@@ -4321,12 +4032,12 @@
                                                       data[0x0F + data[0x0E] * sizeof(u16)]);
                 break;
 
+        case 6:                /* 3.3.7 Memory Module Information */
-        case 6:                /* 7.7 Memory Module Information */
                 if(h->length < 0x0C) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "SocketDesignation", "%s", dmi_string(h, data[0x04]));
-                dmixml_AddDMIstring(sect_n, "SocketDesignation", h, data[0x04]);
                 dmi_memory_module_connections(sect_n, data[0x05]);
                 dmi_memory_module_speed(sect_n, "ModuleSpeed", data[0x06]);
                 dmi_memory_module_types(sect_n, "Type", WORD(data + 0x07));
@@ -4336,12 +4047,12 @@
                 dmi_memory_module_error(sect_n, data[0x0B]);
                 break;
 
+        case 7:                /* 3.3.8 Cache Information */
-        case 7:                /* 7.8 Cache Information */
                 if(h->length < 0x0F) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "SocketDesignation", dmi_string(h, data[0x04]));
-                dmixml_AddDMIstring(sect_n, "SocketDesignation", h, data[0x04]);
                 dmixml_AddAttribute(sect_n, "Enabled", "%i", (WORD(data + 0x05) & 0x0080 ? 1 : 0));
                 dmixml_AddAttribute(sect_n, "Socketed", "%i", (WORD(data + 0x05) & 0x0008 ? 1 : 0));
                 dmixml_AddAttribute(sect_n, "Level", "%ld", ((WORD(data + 0x05) & 0x0007) + 1));
@@ -4368,19 +4079,19 @@
                 dmi_cache_associativity(sect_n, data[0x12]);
                 break;
 
+        case 8:                /* 3.3.9 Port Connector Information */
-        case 8:                /* 7.9 Port Connector Information */
                 if(h->length < 0x09) {
                         break;
                 }
 
+                sub_n = dmixml_AddTextChild(sect_n, "DesignatorRef", dmi_string(h, data[0x04]));
-                sub_n = dmixml_AddDMIstring(sect_n, "DesignatorRef", h, data[0x04]);
                 assert( sub_n != NULL );
                 dmixml_AddAttribute(sub_n, "type", "internal");
                 sub_n = NULL;
 
                 dmi_port_connector_type(sect_n, "internal", data[0x05]);
 
+                sub_n = dmixml_AddTextChild(sect_n, "DesignatorRef", dmi_string(h, data[0x06]));
-                sub_n = dmixml_AddDMIstring(sect_n, "DesignatorRef", h, data[0x06]);
                 assert( sub_n != NULL );
                 dmixml_AddAttribute(sub_n, "type", "external");
                 sub_n = NULL;
@@ -4389,12 +4100,12 @@
                 dmi_port_type(sect_n, data[0x08]);
                 break;
 
+        case 9:                /* 3.3.10 System Slots */
-        case 9:                /* 7.10 System Slots */
                 if(h->length < 0x0C) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "Designation", "%s", dmi_string(h, data[0x04]));
-                dmixml_AddDMIstring(sect_n, "Designation", h, data[0x04]);
 
                 dmi_slot_bus_width(sect_n, data[0x06]);
                 dmi_slot_type(sect_n, data[0x05]);
@@ -4409,11 +4120,11 @@
                 }
                 break;
 
+        case 10:               /* 3.3.11 On Board Devices Information */
-        case 10:               /* 7.11 On Board Devices Information */
                 dmi_on_board_devices(sect_n, "dmi_on_board_devices", h);
                 break;
 
+        case 11:               /* 3.3.12 OEM Strings */
-        case 11:               /* 7.12 OEM Strings */
                 if(h->length < 0x05) {
                         break;
                 }
@@ -4421,7 +4132,7 @@
                 dmi_oem_strings(sect_n, h);
                 break;
 
+        case 12:               /* 3.3.13 System Configuration Options */
-        case 12:               /* 7.13 System Configuration Options */
                 if(h->length < 0x05) {
                         break;
                 }
@@ -4429,22 +4140,22 @@
                 dmi_system_configuration_options(sect_n, h);
                 break;
 
+        case 13:               /* 3.3.14 BIOS Language Information */
-        case 13:               /* 7.14 BIOS Language Information */
                 if(h->length < 0x16) {
                         break;
                 }
 
                 dmixml_AddAttribute(sect_n, "installable_languages", "%i", data[0x04]);
 
+                dmi_bios_languages(sect_n, h);
-                dmi_bios_languages(sect_n, h, data[0x05]);
                 break;
 
+        case 14:               /* 3.3.15 Group Associations */
-        case 14:               /* 7.15 Group Associations */
                 if(h->length < 0x05) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "Name", "%s", dmi_string(h, data[0x04]));
-                dmixml_AddDMIstring(sect_n, "Name", h, data[0x04]);
 
                 sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Groups", NULL);
                 assert( sub_n != NULL );
@@ -4452,7 +4163,7 @@
                 sub_n = NULL;
                 break;
 
+        case 15:               /* 3.3.16 System Event Log */
-        case 15:               /* 7.16 System Event Log */
                 // SysEventLog - sect_n
                 if(h->length < 0x14) {
                         break;
@@ -4509,7 +4220,7 @@
                 sub_n = NULL;
                 break;
 
+        case 16:               /* 3.3.17 Physical Memory Array */
-        case 16:               /* 7.17 Physical Memory Array */
                 if(h->length < 0x0F) {
                         break;
                 }
@@ -4518,11 +4229,11 @@
                 dmi_memory_array_location(sect_n, data[0x04]);
                 dmi_memory_array_use(sect_n, data[0x05]);
                 dmi_memory_array_ec_type(sect_n, data[0x06]);
+                dmi_memory_array_capacity(sect_n, DWORD(data + 0x07));
-                dmi_memory_array_capacity(sect_n, h, data);
                 dmi_memory_array_error_handle(sect_n, WORD(data + 0x0B));
                 break;
 
+        case 17:               /* 3.3.18 Memory Device */
-        case 17:               /* 7.18 Memory Device */
                 if(h->length < 0x15) {
                         break;
                 }
@@ -4532,15 +4243,11 @@
 
                 dmi_memory_device_width(sect_n, "TotalWidth", WORD(data + 0x08));
                 dmi_memory_device_width(sect_n, "DataWidth", WORD(data + 0x0A));
+                dmi_memory_device_size(sect_n, WORD(data + 0x0C));
-                if (h->length >= 0x20 && WORD(data + 0x0C) == 0x7FFF) {
-                        dmi_memory_device_extended_size(sect_n, WORD(data + 0x1C));
-                } else {
-                        dmi_memory_device_size(sect_n, WORD(data + 0x0C));
-                }
                 dmi_memory_device_form_factor(sect_n, data[0x0E]);
                 dmi_memory_device_set(sect_n, data[0x0F]);
+                dmixml_AddTextChild(sect_n, "Locator", dmi_string(h, data[0x10]));
+                dmixml_AddTextChild(sect_n, "BankLocator", dmi_string(h, data[0x11]));
-                dmixml_AddDMIstring(sect_n, "Locator", h, data[0x10]);
-                dmixml_AddDMIstring(sect_n, "BankLocator", h, data[0x11]);
 
                 dmi_memory_device_type(sect_n, data[0x12]);
                 dmi_memory_device_type_detail(sect_n, WORD(data + 0x13));
@@ -4549,43 +4256,20 @@
                         break;
                 }
 
+                dmi_memory_device_speed(sect_n, WORD(data + 0x15));
-                dmi_memory_device_speed(sect_n, "Speed", WORD(data + 0x15));
 
                 if(h->length < 0x1B) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x17]));
+                dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x18]));
+                dmixml_AddTextChild(sect_n, "AssetTag",     "%s", dmi_string(h, data[0x19]));
+                dmixml_AddTextChild(sect_n, "PartNumber",   "%s", dmi_string(h, data[0x1A]));
-                dmixml_AddDMIstring(sect_n, "Manufacturer", h, data[0x17]);
-                dmixml_AddDMIstring(sect_n, "SerialNumber", h, data[0x18]);
-                dmixml_AddDMIstring(sect_n, "AssetTag",     h, data[0x19]);
-                dmixml_AddDMIstring(sect_n, "PartNumber",   h, data[0x1A]);
-
-                if(h->length < 0x1C) {
-                        break;
-                }
-
-                dmixml_AddTextChild(sect_n, "Rank", "%u", data[0x1B] & 0x0F);
-
-                if(h->length < 0x22) {
-                        break;
-                }
-
-                dmi_memory_device_speed(sect_n, "CurrentClockSpeed", WORD(data + 0x20));
-
-                if(h->length < 0x28) {
-                        break;
-                }
-                sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "MemoryVoltage", NULL);
-                assert( sub_n != NULL );
-                dmi_memory_voltage_value(sub_n, "Minimum", WORD(data + 0x22));
-                dmi_memory_voltage_value(sub_n, "Maximum", WORD(data + 0x24));
-                dmi_memory_voltage_value(sub_n, "Current", WORD(data + 0x26));
-                sub_n = NULL;
-
                 break;
 
+        case 18:               /* 3.3.19 32-bit Memory Error Information */
+        case 33:               /* 3.3.34 64-bit Memory Error Information */
-        case 18:               /* 7.19 32-bit Memory Error Information */
-        case 33:               /* 7.34 64-bit Memory Error Information */
                 if( h->type == 18 ) {
                         dmixml_AddAttribute(sect_n, "bits", "32");
                 } else {
@@ -4616,32 +4300,23 @@
                 }
                 break;
 
+        case 19:               /* 3.3.20 Memory Array Mapped Address */
-        case 19:               /* 7.20 Memory Array Mapped Address */
                 if(h->length < 0x0F) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "StartAddress", "0x%08x%03x",
+                                    (DWORD(data + 0x04) >> 2),
+                                    (DWORD(data + 0x04) & 0x3) << 10);
+                dmixml_AddTextChild(sect_n, "EndAddress", "0x%08x%03x",
+                                    (DWORD(data + 0x08) >> 2),
+                                    ((DWORD(data + 0x08) & 0x3) << 10) + 0x3FF);
+                dmi_mapped_address_size(sect_n, DWORD(data + 0x08) - DWORD(data + 0x04) + 1);
-                if (h->length >= 0x1F && DWORD(data + 0x04) == 0xFFFFFFFF) {
-                        u64 start, end;
-
-                        start = QWORD(data + 0x0F);
-                        end = QWORD(data + 0x17);
-                        dmi_mapped_address_extended_size(sect_n, start, end);
-                } else {
-                        dmixml_AddTextChild(sect_n, "StartAddress", "0x%08x%03x",
-                                            (DWORD(data + 0x04) >> 2),
-                                            (DWORD(data + 0x04) & 0x3) << 10);
-                        dmixml_AddTextChild(sect_n, "EndAddress", "0x%08x%03x",
-                                            (DWORD(data + 0x08) >> 2),
-                                            ((DWORD(data + 0x08) & 0x3) << 10) + 0x3FF);
-                        dmi_mapped_address_size(sect_n, DWORD(data + 0x08) - DWORD(data + 0x04) + 1);
-                }
-
                 dmixml_AddTextChild(sect_n, "PhysicalArrayHandle", "0x%04x", WORD(data + 0x0C));
                 dmixml_AddTextChild(sect_n, "PartitionWidth", "%i", data[0x0F]);
                 break;
 
+        case 20:               /* 3.3.21 Memory Device Mapped Address */
-        case 20:               /* 7.21 Memory Device Mapped Address */
                 if(h->length < 0x13) {
                         break;
                 }
@@ -4665,7 +4340,7 @@
                 dmi_mapped_address_interleaved_data_depth(sect_n, data[0x12]);
                 break;
 
+        case 21:               /* 3.3.22 Built-in Pointing Device */
-        case 21:               /* 7.22 Built-in Pointing Device */
                 if(h->length < 0x07) {
                         break;
                 }
@@ -4675,23 +4350,23 @@
                 dmixml_AddTextChild(sect_n, "Buttons", "%i", data[0x06]);
                 break;
 
+        case 22:               /* 3.3.23 Portable Battery */
-        case 22:               /* 7.23 Portable Battery */
                 if(h->length < 0x10) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "Location", "%s", dmi_string(h, data[0x04]));
+                dmixml_AddTextChild(sect_n, "Manufacturer", "%s", dmi_string(h, data[0x05]));
-                dmixml_AddDMIstring(sect_n, "Location", h, data[0x04]);
-                dmixml_AddDMIstring(sect_n, "Manufacturer", h, data[0x05]);
 
                 if(data[0x06] || h->length < 0x1A) {
+                        dmixml_AddTextChild(sect_n, "ManufactureDate", "%s", dmi_string(h, data[0x06]));
-                        dmixml_AddDMIstring(sect_n, "ManufactureDate", h, data[0x06]);
                 }
 
                 if(data[0x07] || h->length < 0x1A) {
+                        dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07]));
-                        dmixml_AddDMIstring(sect_n, "SerialNumber", h, data[0x07]);
                 }
 
+                dmixml_AddTextChild(sect_n, "Name", "%s", dmi_string(h, data[0x08]));
-                dmixml_AddDMIstring(sect_n, "Name", h, data[0x08]);
 
                 if(data[0x09] != 0x02 || h->length < 0x1A) {
                         dmi_battery_chemistry(sect_n, data[0x09]);
@@ -4699,7 +4374,7 @@
 
                 dmi_battery_capacity(sect_n, WORD(data + 0x0A), (h->length < 0x1A ? 1 : data[0x15]));
                 dmi_battery_voltage(sect_n, WORD(data + 0x0C));
+                dmixml_AddTextChild(sect_n, "SBDSversion", "%s", dmi_string(h, data[0x0E]));
-                dmixml_AddDMIstring(sect_n, "SBDSversion", h, data[0x0E]);
 
                 dmi_battery_maximum_error(sect_n, data[0x0F]);
 
@@ -4717,13 +4392,13 @@
                                             (WORD(data + 0x12) & 0x1F));
                 }
                 if(data[0x09] == 0x02) {
+                        dmixml_AddTextChild(sect_n, "SBDSchemistry", "%s", dmi_string(h, data[0x14]));
-                        dmixml_AddDMIstring(sect_n, "SBDSchemistry", h, data[0x14]);
                 }
 
                 dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x16));
                 break;
 
+        case 23:               /* 3.3.24 System Reset */
-        case 23:               /* 7.24 System Reset */
                 if(h->length < 0x0D) {
                         break;
                 }
@@ -4752,7 +4427,7 @@
                 dmi_system_reset_timer(sect_n, "Timeout", WORD(data + 0x0B));
                 break;
 
+        case 24:               /* 3.3.25 Hardware Security */
-        case 24:               /* 7.25 Hardware Security */
                 if(h->length < 0x05) {
                         break;
                 }
@@ -4764,7 +4439,7 @@
 
                 break;
 
+        case 25:               /* 3.3.26 System Power Controls */
-        case 25:               /* 7.26 System Power Controls */
                 if(h->length < 0x09) {
                         break;
                 }
@@ -4772,14 +4447,14 @@
                 dmi_power_controls_power_on(sect_n, "NextSchedPowerOn", data + 0x04);
                 break;
 
+        case 26:               /* 3.3.27 Voltage Probe */
-        case 26:               /* 7.27 Voltage Probe */
                 dmixml_AddAttribute(sect_n, "probetype", "Voltage");
 
                 if(h->length < 0x14) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "Description", "%s", dmi_string(h, data[0x04]));
-                dmixml_AddDMIstring(sect_n, "Description", h, data[0x04]);
 
                 dmi_voltage_probe_location(sect_n, data[0x05] & 0x1f);
                 dmi_probe_status(sect_n, data[0x05] >> 5);
@@ -4800,7 +4475,7 @@
                 dmi_voltage_probe_value(sect_n, "NominalValue", WORD(data + 0x14));
                 break;
 
+        case 27:               /* 3.3.28 Cooling Device */
-        case 27:               /* 7.28 Cooling Device */
                 if(h->length < 0x0C) {
                         break;
                 }
@@ -4825,14 +4500,14 @@
                 dmi_cooling_device_speed(sect_n, WORD(data + 0x0C));
                 break;
 
+        case 28:               /* 3.3.29 Temperature Probe */
-        case 28:               /* 7.29 Temperature Probe */
                 dmixml_AddAttribute(sect_n, "probetype", "Temperature");
 
                 if(h->length < 0x14) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "Description", "%s", dmi_string(h, data[0x04]));
-                dmixml_AddDMIstring(sect_n, "Description", h, data[0x04]);
                 dmi_temperature_probe_location(sect_n,data[0x05] & 0x1F);
                 dmi_probe_status(sect_n, data[0x05] >> 5);
 
@@ -4851,14 +4526,14 @@
                 dmi_temperature_probe_value(sect_n, "NominalValue", WORD(data + 0x14));
                 break;
 
+        case 29:               /* 3.3.30 Electrical Current Probe */
-        case 29:               /* 7.30 Electrical Current Probe */
                 dmixml_AddAttribute(sect_n, "probetype", "Electrical Current");
 
                 if(h->length < 0x14) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "Description", dmi_string(h, data[0x04]));
-                dmixml_AddDMIstring(sect_n, "Description", h, data[0x04]);
                 dmi_voltage_probe_location(sect_n, data[5] & 0x1F);
                 dmi_probe_status(sect_n, data[0x05] >> 5);
 
@@ -4878,21 +4553,21 @@
                 dmi_current_probe_value(sect_n, "NominalValue", WORD(data + 0x14));
                 break;
 
+        case 30:               /* 3.3.31 Out-of-band Remote Access */
-        case 30:               /* 7.31 Out-of-band Remote Access */
                 if(h->length < 0x06) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "ManufacturerName", "%s", dmi_string(h, data[0x04]));
-                dmixml_AddDMIstring(sect_n, "ManufacturerName", h, data[0x04]);
                 dmixml_AddAttribute(sect_n, "InboundConnectionEnabled",  "%i", data[0x05] & (1 << 0) ? 1 : 0);
                 dmixml_AddAttribute(sect_n, "OutboundConnectionEnabled", "%i", data[0x05] & (1 << 1) ? 1 : 0);
                 break;
 
+        case 31:               /* 3.3.32 Boot Integrity Services Entry Point */
-        case 31:               /* 7.32 Boot Integrity Services Entry Point */
                 dmixml_AddAttribute(sect_n, "NOT_IMPLEMENTED", "1");
                 break;
 
+        case 32:               /* 3.3.33 System Boot Information */
-        case 32:               /* 7.33 System Boot Information */
                 if(h->length < 0x0B) {
                         break;
                 }
@@ -4900,27 +4575,27 @@
                 dmi_system_boot_status(sect_n, data[0x0A]);
                 break;
 
+        case 34:               /* 3.3.35 Management Device */
-        case 34:               /* 7.35 Management Device */
                 dmixml_AddAttribute(sect_n, "mgmtype", "");
 
                 if(h->length < 0x0B) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "Description", "%s", dmi_string(h, data[0x04]));
-                dmixml_AddDMIstring(sect_n, "Description", h, data[0x04]);
                 dmi_management_device_type(sect_n, data[0x05]);
                 dmixml_AddTextChild(sect_n, "Address", "0x%08x", DWORD(data + 0x06));
                 dmi_management_device_address_type(sect_n, data[0x0A]);
                 break;
 
+        case 35:               /* 3.3.36 Management Device Component */
-        case 35:               /* 7.36 Management Device Component */
                 dmixml_AddAttribute(sect_n, "mgmtype", "Component");
 
                 if(h->length < 0x0B) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "Description", dmi_string(h, data[0x04]));
-                dmixml_AddDMIstring(sect_n, "Description", h, data[0x04]);
                 dmixml_AddTextChild(sect_n, "ManagementDeviceHandle", "0x%04x", WORD(data + 0x05));
                 dmixml_AddTextChild(sect_n, "ComponentHandle", "0x%04x", WORD(data + 0x07));
 
@@ -4929,7 +4604,7 @@
                 }
                 break;
 
+        case 36:               /* 3.3.37 Management Device Threshold Data */
-        case 36:               /* 7.37 Management Device Threshold Data */
                 dmixml_AddAttribute(sect_n, "mgmtype", "Threshold Data");
 
                 if(h->length < 0x10) {
@@ -4974,7 +4649,7 @@
                 sub_n = NULL;
                 break;
 
+        case 37:               /* 3.3.38 Memory Channel */
-        case 37:               /* 7.38 Memory Channel */
                 if(h->length < 0x07) {
                         break;
                 }
@@ -4995,7 +4670,7 @@
                 sub_n = NULL;
                 break;
 
+        case 38:               /* 3.3.39 IPMI Device Information */
-        case 38:               /* 7.39 IPMI Device Information */
                 /*
                  * We use the word "Version" instead of "Revision", conforming to
                  * the IPMI specification.
@@ -5021,7 +4696,7 @@
                 sub_n = NULL;
 
                 dmi_ipmi_base_address(sect_n, data[0x04], data + 0x08,
+                                      h->length < 0x12 ? 0 : (data[0x10] >> 5) & 1);
-                                      h->length < 0x11 ? 0 : (data[0x10] >> 4) & 1);
 
                 if(h->length < 0x12) {
                         break;
@@ -5050,7 +4725,7 @@
                 sub_n = NULL;
                 break;
 
+        case 39:               /* 3.3.40 System Power Supply */
-        case 39:               /* 7.40 System Power Supply */
                 if(h->length < 0x10) {
                         break;
                 }
@@ -5059,13 +4734,13 @@
                         dmixml_AddAttribute(sect_n, "UnitGroup", "%i", data[0x04]);
                 }
 
+                dmixml_AddTextChild(sect_n, "Location",        "%s", dmi_string(h, data[0x05]));
+                dmixml_AddTextChild(sect_n, "Name",            "%s", dmi_string(h, data[0x06]));
+                dmixml_AddTextChild(sect_n, "Manufacturer",    "%s", dmi_string(h, data[0x07]));
+                dmixml_AddTextChild(sect_n, "SerialNumber",    "%s", dmi_string(h, data[0x08]));
+                dmixml_AddTextChild(sect_n, "AssetTag",        "%s", dmi_string(h, data[0x09]));
+                dmixml_AddTextChild(sect_n, "ModelPartNumber", "%s", dmi_string(h, data[0x0A]));
+                dmixml_AddTextChild(sect_n, "Revision",        "%s", dmi_string(h, data[0x0B]));
-                dmixml_AddDMIstring(sect_n, "Location",        h, data[0x05]);
-                dmixml_AddDMIstring(sect_n, "Name",            h, data[0x06]);
-                dmixml_AddDMIstring(sect_n, "Manufacturer",    h, data[0x07]);
-                dmixml_AddDMIstring(sect_n, "SerialNumber",    h, data[0x08]);
-                dmixml_AddDMIstring(sect_n, "AssetTag",        h, data[0x09]);
-                dmixml_AddDMIstring(sect_n, "ModelPartNumber", h, data[0x0A]);
-                dmixml_AddDMIstring(sect_n, "Revision",        h, data[0x0B]);
 
                 dmi_power_supply_power(sect_n, WORD(data + 0x0C));
 
@@ -5108,7 +4783,7 @@
                 sub_n = NULL;
                 break;
 
+        case 40:               /* 3.3.41 Additional Information */
-        case 40:               /* 7.41 Additional Information */
                 dmixml_AddAttribute(sect_n, "subtype", "AdditionalInformation");
 
                 if(h->length < 0x0B) {
@@ -5118,12 +4793,14 @@
                 dmi_additional_info(sect_n, h);
                 break;
 
+        case 41:               /* 3.3.42 Onboard Device Extended Information */
+                dmixml_AddAttribute(sect_n, "subtype", "OnboardDeviceExtendedInformation");
+
-        case 41:               /* 7.42 Onboard Device Extended Information */
                 if(h->length < 0x0B) {
                         break;
                 }
 
+                dmixml_AddTextChild(sect_n, "ReferenceDesignation", "%s", dmi_string(h, data[0x04]));
-                dmixml_AddDMIstring(sect_n, "ReferenceDesignation", h, data[0x04]);
 
                 sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "OnboardDevice", NULL);
                 dmi_on_board_devices_type(sub_n, data[0x05] & 0x7F);
@@ -5134,30 +4811,8 @@
                 sub_n = NULL;
                 break;
 
+        case 126:              /* 3.3.43 Inactive */
+        case 127:              /* 3.3.44 End Of Table */
-        case 42:               /* 7.43 Management Controller Host Interface */
-                if (h->length < 0x05) {
-                        break;
-                }
-
-                sub_n = dmi_management_controller_host_type(sect_n, data[0x04]);
-                /*
-                 * There you have a type-dependent, variable-length
-                 * part in the middle of the structure, with no
-                 * length specifier, so no easy way to decode the
-                 * common, final part of the structure. What a pity.
-                 */
-                if (h->length < 0x09) {
-                        break;
-                }
-                if (data[0x04] == 0xF0)  {         /* OEM */
-                        dmixml_AddTextChild(sub_n, "VendorID", "0x%02X%02X%02X%02X\n",
-                                            data[0x05], data[0x06], data[0x07],
-                                            data[0x08]);
-                }
-                sub_n = NULL;
-                break;
-        case 126:              /* 7.43 Inactive */
-        case 127:              /* 7.44 End Of Table */
                 break;
 
         default:
@@ -5199,7 +4854,6 @@
 
 static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver, const char *devmem, xmlNode *xmlnode)
 {
-        static u8 version_added = 0;
         u8 *buf;
         u8 *data;
         int i = 0;
@@ -5230,12 +4884,6 @@
                 return;
         }
 
-        // FIXME: This is hackerish ... rather try to avoid looping dmi_table() calls too much
-        if( version_added == 0 ) {
-                dmixml_AddAttribute(xmlnode, "smbios_version", "%u.%u", ver >> 8, ver & 0xFF);
-                version_added = 1;
-        }
-
         data = buf;
         while(i < num && data + 4 <= buf + len) {       /* 4 is the length of an SMBIOS structure header */
 
@@ -5405,7 +5053,7 @@
                         ver = 0x0206;
                         break;
                 }
+                //printf(">>%d @ %d, %d<<\n", DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C));
-                // printf(">>%d @ %d, %d<<\n", DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C));
                 dmi_table(logp, type, DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), ver, devmem,
                           xmlnode);
         }
--- a/src/dmidecodemodule.c	2015-06-08 17:19:45.000000000 +0200
+++ b/src/dmidecodemodule.c	2010-06-03 12:01:46.000000000 +0200
@@ -53,17 +53,6 @@
 #include "dmidump.h"
 #include <mcheck.h>
 
-#if (PY_VERSION_HEX < 0x03030000)
-char *PyUnicode_AsUTF8(PyObject *unicode) {
-        PyObject *as_bytes = PyUnicode_AsUTF8String(unicode);
-        if (!as_bytes) {
-                return NULL;
-        }
-
-        return PyBytes_AsString(as_bytes);
-}
-#endif
-
 static void init(options *opt)
 {
         opt->devmem = DEFAULT_MEM_DEV;
@@ -481,12 +470,7 @@
 
 static PyObject *dmidecode_get_section(PyObject *self, PyObject *args)
 {
+        char *section = PyString_AsString(args);
-        char *section = NULL;
-        if (PyUnicode_Check(args)) {
-                section = PyUnicode_AsUTF8(args);
-        } else if (PyBytes_Check(args)) {
-                section = PyBytes_AsString(args);
-        }
 
         if( section != NULL ) {
                 return dmidecode_get_group(global_options, section);
@@ -604,7 +588,7 @@
 static PyObject *dmidecode_get_dev(PyObject * self, PyObject * null)
 {
         PyObject *dev = NULL;
+        dev = PyString_FromString((global_options->dumpfile != NULL
-        dev = PYTEXT_FROMSTRING((global_options->dumpfile != NULL
                                    ? global_options->dumpfile : global_options->devmem));
         Py_INCREF(dev);
         return dev;
@@ -612,14 +596,9 @@
 
 static PyObject *dmidecode_set_dev(PyObject * self, PyObject * arg)
 {
+        if(PyString_Check(arg)) {
-        char *f = NULL;
-        if(PyUnicode_Check(arg)) {
-                f = PyUnicode_AsUTF8(arg);
-        } else if(PyBytes_Check(arg)) {
-                f = PyBytes_AsString(arg);
-        }
-        if(f) {
                 struct stat buf;
+                char *f = PyString_AsString(arg);
 
                 if( (f != NULL) && (global_options->dumpfile != NULL )
                     && (strcmp(global_options->dumpfile, f) == 0) ) {
@@ -659,17 +638,12 @@
 
 static PyObject *dmidecode_set_pythonxmlmap(PyObject * self, PyObject * arg)
 {
+        if(PyString_Check(arg)) {
-        char *fname = NULL;
-
-        if (PyUnicode_Check(arg)) {
-                fname = PyUnicode_AsUTF8(arg);
-        } else if (PyBytes_Check(arg)) {
-                fname = PyBytes_AsString(arg);
-        }
-        if (fname) {
                 struct stat fileinfo;
+                char *fname = PyString_AsString(arg);
 
                 memset(&fileinfo, 0, sizeof(struct stat));
+
                 if( stat(fname, &fileinfo) != 0 ) {
                         PyReturnError(PyExc_IOError, "Could not access the file '%s'", fname);
                 }
@@ -690,7 +664,7 @@
 
         warn = log_retrieve(global_options->logdata, LOG_WARNING);
         if( warn ) {
+                ret = PyString_FromString(warn);
-                ret = PYTEXT_FROMSTRING(warn);
                 free(warn);
         } else {
                 ret = Py_None;
@@ -737,7 +711,7 @@
         {(char *)"pythonmap", dmidecode_set_pythonxmlmap, METH_O,
          (char *) "Use another python dict map definition. The default file is " PYTHON_XML_MAP},
 
+        {(char *)"xmlapi", dmidecode_xmlapi, METH_KEYWORDS,
-        {(char *)"xmlapi", dmidecode_xmlapi, METH_VARARGS | METH_KEYWORDS,
          (char *) "Internal API for retrieving data as raw XML data"},
 
 
@@ -752,9 +726,6 @@
 
 void destruct_options(void *ptr)
 {
-#ifdef IS_PY3K
-        ptr = PyCapsule_GetPointer(ptr, NULL);
-#endif
         options *opt = (options *) ptr;
 
         if( opt->mappingxml != NULL ) {
@@ -792,25 +763,8 @@
         free(ptr);
 }
 
-#ifdef IS_PY3K
-static struct PyModuleDef dmidecodemod_def = {
-    PyModuleDef_HEAD_INIT,
-    "dmidecodemod",
-    NULL,
-    -1,
-    DMIDataMethods,
-    NULL,
-    NULL,
-    NULL,
-    NULL
-};
 
+PyMODINIT_FUNC initdmidecodemod(void)
-PyMODINIT_FUNC
-PyInit_dmidecodemod(void)
-#else
-PyMODINIT_FUNC
-initdmidecodemod(void)
-#endif
 {
         char *dmiver = NULL;
         PyObject *module = NULL;
@@ -823,29 +777,19 @@
         opt = (options *) malloc(sizeof(options)+2);
         memset(opt, 0, sizeof(options)+2);
         init(opt);
-#ifdef IS_PY3K
-        module = PyModule_Create(&dmidecodemod_def);
-#else
         module = Py_InitModule3((char *)"dmidecodemod", DMIDataMethods,
                                 "Python extension module for dmidecode");
-#endif
-        if (module == NULL)
-                MODINITERROR;
 
+        version = PyString_FromString(VERSION);
-        version = PYTEXT_FROMSTRING(VERSION);
         Py_INCREF(version);
         PyModule_AddObject(module, "version", version);
 
         opt->dmiversion_n = dmidecode_get_version(opt);
         dmiver = dmixml_GetContent(opt->dmiversion_n);
+        PyModule_AddObject(module, "dmi", dmiver ? PyString_FromString(dmiver) : Py_None);
-        PyModule_AddObject(module, "dmi", dmiver ? PYTEXT_FROMSTRING(dmiver) : Py_None);
 
         // Assign this options struct to the module as well with a destructor, that way it will
         // clean up the memory for us.
+        PyModule_AddObject(module, "options", PyCObject_FromVoidPtr(opt, destruct_options));
-        // TODO: destructor has wrong type under py3?
-        PyModule_AddObject(module, "options", PyCapsule_New(opt, NULL, destruct_options));
         global_options = opt;
-#ifdef IS_PY3K
-        return module;
-#endif
 }
--- a/src/dmihelper.h	2015-06-08 17:19:45.000000000 +0200
+++ b/src/dmihelper.h	2010-06-03 12:01:46.000000000 +0200
@@ -65,52 +65,50 @@
 } dmi_codes_major;
 
 static const dmi_codes_major dmiCodesMajor[] = {
+        {0, "3.3.1", "BIOS Information", "BIOSinfo"},
+        {1, "3.3.2", "System Information", "SystemInfo"},
+        {2, "3.3.3", "Base Board Information", "BaseBoardInfo"},
+        {3, "3.3.4", "Chassis Information", "ChassisInfo"},
+        {4, "3.3.5", "Processor Information", "ProcessorInfo"},
+        {5, "3.3.6", "Memory Controller Information", "MemoryCtrlInfo"},
+        {6, "3.3.7", "Memory Module Information", "MemoryModuleInfo"},
+        {7, "3.3.8", "Cache Information", "CacheInfo"},
+        {8, "3.3.9", "Port Connector Information", "PortConnectorInfo"},
+        {9, "3.3.10", "System Slots", "SystemSlots"},
+        {10, "3.3.11", "On Board Devices Information", "OnBoardDevicesInfo"},
+        {11, "3.3.12", "OEM Strings", "OEMstrings"},
+        {12, "3.3.13", "System Configuration Options", "SysConfigOptions"},
+        {13, "3.3.14", "BIOS Language Information", "BIOSlanguage"},
+        {14, "3.3.15", "Group Associations", "GroupAssoc"},
+        {15, "3.3.16", "System Event Log", "SysEventLog"},
+        {16, "3.3.17", "Physical Memory Array", "PhysicalMemoryArray"},
+        {17, "3.3.18", "Memory Device", "MemoryDevice"},
+        {18, "3.3.19", "32-bit Memory Error Information", "MemoryErrorInfo"},
+        {19, "3.3.20", "Memory Array Mapped Address", "MemoryArrayMappedAddress"},
+        {20, "3.3.21", "Memory Device Mapped Address", "MemoryDeviceMappedAddress"},
+        {21, "3.3.22", "Built-in Pointing Device", "BuiltIntPointingDevice"},
+        {22, "3.3.23", "Portable Battery", "PortableBattery"},
+        {23, "3.3.24", "System Reset", "SystemReset"},
+        {24, "3.3.25", "Hardware Security", "HardwareSecurity"},
+        {25, "3.3.26", "System Power Controls", "SystemPowerCtrls"},
+        {26, "3.3.27", "Voltage Probe", "Probe"},
+        {27, "3.3.28", "Cooling Device", "CoolingDevice"},
+        {28, "3.3.29", "Temperature Probe", "Probe"},
+        {29, "3.3.30", "Electrical Current Probe", "Probe"},
+        {30, "3.3.31", "Out-of-band Remote Access", "RemoteAccess"},
+        {31, "3.3.32", "Boot Integrity Services Entry Point", "BootIntegrity"},
+        {32, "3.3.33", "System Boot Information", "SystemBootInfo"},
+        {33, "3.3.34", "64-bit Memory Error Information", "MemoryErrorInfo"},
+        {34, "3.3.35", "Management Device", "ManagementDevice"},
+        {35, "3.3.36", "Management Device Component", "ManagementDevice"},
+        {36, "3.3.37", "Management Device Threshold Data", "ManagementDevice"},
+        {37, "3.3.38", "Memory Channel", "MemoryChannel"},
+        {38, "3.3.39", "IPMI Device Information", "IPMIdeviceInfo"},
+        {39, "3.3.40", "System Power Supply", "SystemPowerSupply"},
+        {40, "3.3.41", "-------------------", "Unknown"},
+        {41, "3.3.42", "-------------------", "Unknown"},
+        {126, "3.3.41", "Inactive", "Inactive"},
+        {127, "3.3.42", "End Of Table", "EndOfTable"},
-        {0, "7.1", "BIOS Information", "BIOSinfo"},
-        {1, "7.2", "System Information", "SystemInfo"},
-        {2, "7.3", "Base Board Information", "BaseBoardInfo"},
-        {3, "7.4", "Chassis Information", "ChassisInfo"},
-        {4, "7.5", "Processor Information", "ProcessorInfo"},
-        {5, "7.6", "Memory Controller Information", "MemoryCtrlInfo"},
-        {6, "7.7", "Memory Module Information", "MemoryModuleInfo"},
-        {7, "7.8", "Cache Information", "CacheInfo"},
-        {8, "7.9", "Port Connector Information", "PortConnectorInfo"},
-        {9, "7.10", "System Slots", "SystemSlots"},
-        {10, "7.11", "On Board Devices Information", "OnBoardDevicesInfo"},
-        {11, "7.12", "OEM Strings", "OEMstrings"},
-        {12, "7.13", "System Configuration Options", "SysConfigOptions"},
-        {13, "7.14", "BIOS Language Information", "BIOSlanguage"},
-        {14, "7.15", "Group Associations", "GroupAssoc"},
-        {15, "7.16", "System Event Log", "SysEventLog"},
-        {16, "7.17", "Physical Memory Array", "PhysicalMemoryArray"},
-        {17, "7.18", "Memory Device", "MemoryDevice"},
-        {18, "7.19", "32-bit Memory Error Information", "MemoryErrorInfo"},
-        {19, "7.20", "Memory Array Mapped Address", "MemoryArrayMappedAddress"},
-        {20, "7.21", "Memory Device Mapped Address", "MemoryDeviceMappedAddress"},
-        {21, "7.22", "Built-in Pointing Device", "BuiltIntPointingDevice"},
-        {22, "7.23", "Portable Battery", "PortableBattery"},
-        {23, "7.24", "System Reset", "SystemReset"},
-        {24, "7.25", "Hardware Security", "HardwareSecurity"},
-        {25, "7.26", "System Power Controls", "SystemPowerCtrls"},
-        {26, "7.27", "Voltage Probe", "Probe"},
-        {27, "7.28", "Cooling Device", "CoolingDevice"},
-        {28, "7.29", "Temperature Probe", "Probe"},
-        {29, "7.30", "Electrical Current Probe", "Probe"},
-        {30, "7.31", "Out-of-band Remote Access", "RemoteAccess"},
-        {31, "7.32", "Boot Integrity Services Entry Point", "BootIntegrity"},
-        {32, "7.33", "System Boot Information", "SystemBootInfo"},
-        {33, "7.34", "64-bit Memory Error Information", "MemoryErrorInfo"},
-        {34, "7.35", "Management Device", "ManagementDevice"},
-        {35, "7.36", "Management Device Component", "ManagementDevice"},
-        {36, "7.37", "Management Device Threshold Data", "ManagementDevice"},
-        {37, "7.38", "Memory Channel", "MemoryChannel"},
-        {38, "7.39", "IPMI Device Information", "IPMIdeviceInfo"},
-        {39, "7.40", "System Power Supply", "SystemPowerSupply"},
-        {40, "7.41", "-------------------", "Unknown"},
-        {41, "7.42", "Onboard Device Extended Information", "OnBoardDevicesExtendedInfo"},
-        {41, "7.43", "Management Controller Host Interface", "MgmntCtrltHostIntf"},
-        {126, "7.44", "Inactive", "Inactive"},
-        {127, "7.45", "End Of Table", "EndOfTable"},
-
         {-1, NULL, NULL, NULL}
 };
 
--- a/src/dmioem.c	2015-06-08 17:19:45.000000000 +0200
+++ b/src/dmioem.c	2017-10-31 09:06:30.317273114 +0100
@@ -93,7 +93,7 @@
                  */
                 printf(h->type == 221 ?
                        "HP BIOS iSCSI NIC PCI and MAC Information\n" :
+                       "HP BIOS NIC PCI and MAC Information\n");
-                       "HP BIOS NIC PXE PCI and MAC Information\n");
                 nic = 1;
                 ptr = 4;
                 while(h->length >= ptr + 8) {
--- a/src/dmixml.c	2015-06-08 17:19:45.000000000 +0200
+++ b/src/dmixml.c	2010-06-03 12:01:46.000000000 +0200
@@ -41,7 +41,6 @@
 #include <libxml/xpath.h>
 #include <libxml/xmlstring.h>
 
-#include "dmidecode.h"
 #include "dmilog.h"
 #include "dmixml.h"
 
@@ -164,47 +163,6 @@
         return res;
 }
 
-/**
- * A variant of dmixml_AddTextChild() which will do dmi_string() decoding instead of a plain string.
- * If the dmi_string() function returns NULL, it will instead add a XML node attribute 'badindex'
- * @author David Sommerseth <davids@redhat.com>
- * @param xmlNode*       Pointer to the current node which will get the text child
- * @param const char*    Name of the new tag
- * @param const struct dmi_header* Pointer to the DMI table header
- * @param u8             DMI table index of the information to be extracted and used in the XML node 
- * @return xmlNode*      Pointer to the new tag. On errors the return value will be NULL.  On fatal
- *                       errors and assert() call will be done.
- */
-xmlNode *dmixml_AddDMIstring(xmlNode *node, const char *tagname, const struct dmi_header *dm, u8 s) {
-        xmlChar *tagname_s = NULL;
-        xmlNode *res = NULL;
-        const char *dmistr;
-
-        if( (node == NULL) || (tagname == NULL) ) {
-                return NULL;
-        }
-
-        tagname_s = xmlCharStrdup(tagname);
-        assert( tagname_s != NULL );
-
-        if(s == 0) {
-                res = xmlNewChild(node, NULL, tagname_s, NULL);
-                dmixml_AddAttribute(res, "not_specified", "1");
-                return res;
-        }
-
-        dmistr = dmi_string(dm, s);
-        if( dmistr == NULL ) {
-		res = xmlNewChild(node, NULL, tagname_s, NULL);
-                dmixml_AddAttribute(res, "badindex", "1");
-        } else {
-                xmlChar *val_s =  xmlCharStrdup(dmistr);
-                res = xmlNewTextChild(node, NULL, tagname_s, val_s);
-                free(val_s);
-        }
-        return res;
-}
-
 /**
  * Adds a text node child to the given  XML node.  If input is NULL, the tag contents will be empty.
  * @author David Sommerseth <davids@redhat.com>
--- a/src/dmixml.h	2015-06-08 17:19:45.000000000 +0200
+++ b/src/dmixml.h	2010-06-03 12:01:46.000000000 +0200
@@ -32,11 +32,8 @@
 
 #define foreach_xmlnode(n, itn) for( itn = n; itn != NULL; itn = itn->next )
 
-struct dmi_header;
-
 xmlAttr *dmixml_AddAttribute(xmlNode *node, const char *atrname, const char *fmt, ...);
 xmlNode *dmixml_AddTextChild(xmlNode *node, const char *tagname, const char *fmt, ...);
-xmlNode *dmixml_AddDMIstring(xmlNode *node, const char *tagname, const struct dmi_header *dm, u8 s);
 xmlNode *dmixml_AddTextContent(xmlNode *node, const char *fmt, ...);
 
 char *dmixml_GetAttrValue(xmlNode *node, const char *key);
--- a/src/pymap.xml	2015-06-08 17:19:45.000000000 +0200
+++ b/src/pymap.xml	2010-06-03 12:01:46.000000000 +0200
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
+ # 2007-2009 (C) Nima Talebi <nima@autonomy.net.au>
+ # 2009      (C) David Sommerseth <davids@redhat.com>
- # 2007-2013 (C) Nima Talebi <nima@autonomy.net.au>
- # 2009-2013 (C) David Sommerseth <davids@redhat.com>
  #
  # This file is part of Python DMI-Decode.
  #
@@ -68,7 +68,7 @@
           <Map keytype="constant" key="ROM Size" valuetype="string"
               value="concat(ROMsize,' ',ROMsize/@unit)"/>
           <Map keytype="constant" key="Address" valuetype="string" value="Address"/>
+          <Map keytype="constant" key="Relase Date" valuetype="string" value="ReleaseDate"/>
-          <Map keytype="constant" key="Release Date" valuetype="string" value="ReleaseDate"/>
         </Map>
         <Map keytype="constant" key="dmi_type"   valuetype="integer" value="@type"/>
         <Map keytype="constant" key="dmi_handle" valuetype="string"  value="@handle"/>
@@ -755,37 +755,12 @@
           <Map keytype="constant" key="Specification Version" valuetype="string" value="@spec_version"/>
         </Map>
       </Map>
+
     </TypeMap>
 
     <!-- FIXME : Type 39 : Power Supply -->
     <TypeMap id="0x27">
     </TypeMap>
-
-    <!-- FIXME : Type 40 : Additional information -->
-    <TypeMap id="0x28">
-    </TypeMap>
-
-    <!-- Type 41 : Onboard Device Extended Information -->
-    <TypeMap id="0x29">
-      <Map rootpath="/dmidecode/OnBoardDevicesExtendedInfo" keytype="string" key="@handle" valuetype="dict">
-        <Map keytype="constant" key="dmi_type"   valuetype="integer" value="@type"/>
-        <Map keytype="constant" key="dmi_handle" valuetype="string"  value="@handle"/>
-        <Map keytype="constant" key="dmi_size"   valuetype="integer" value="@size"/>
-        <Map keytype="constant" key="data" valuetype="dict">
-          <Map keytype="constant" key="Reference Designation"
-               valuetype="string" value="ReferenceDesignation"/>
-          <Map keytype="constant" key="Device Type"
-               valuetype="string" value="OnboardDevice/Type"/>
-          <Map keytype="constant" key="Bus Address"
-               valuetype="string" value="OnboardDevice/BusAddress"/>
-        </Map>
-      </Map>
-    </TypeMap>
-
-    <!-- FIXME : Type 42 : Management Controller Host Interface -->
-    <TypeMap id="0x2A">
-    </TypeMap>
-
   </TypeMapping>
 
   <GroupMapping>
@@ -883,7 +858,6 @@
       <TypeMap id="0x27"/>
       <TypeMap id="0x28"/>
       <TypeMap id="0x29"/>
-      <TypeMap id="0x2A"/>
     </Mapping>
   </GroupMapping>
 
--- a/src/setup_common.py	2015-06-08 17:19:45.000000000 +0200
+++ b/src/setup_common.py	2010-06-03 12:01:46.000000000 +0200
@@ -26,19 +26,17 @@
 #   are deemed to be part of the source code.
 #
 
+import commands, sys
-import subprocess, sys
-if sys.version_info[0] < 3:
-    import commands as subprocess
 from os import path as os_path
 from distutils.sysconfig import get_python_lib
 
 # libxml2 - C flags
 def libxml2_include(incdir):
+    (res, libxml2_cflags) = commands.getstatusoutput("xml2-config --cflags")
-    (res, libxml2_cflags) = subprocess.getstatusoutput("xml2-config --cflags")
     if res != 0:
+        print "Could not build python-dmidecode."
+        print "Could not run xml2-config, is libxml2 installed?"
+        print "Also the development libraries?"
-        print("Could not build python-dmidecode.")
-        print("Could not run xml2-config, is libxml2 installed?")
-        print("Also the development libraries?")
         sys.exit(1)
 
     # Parse the xml2-config --cflags response
@@ -54,11 +52,11 @@
     if os_path.exists("/etc/debian_version"): #. XXX: Debian Workaround...
         libdir.append("/usr/lib/pymodules/python%d.%d"%sys.version_info[0:2])
 
+    (res, libxml2_libs) = commands.getstatusoutput("xml2-config --libs")
-    (res, libxml2_libs) = subprocess.getstatusoutput("xml2-config --libs")
     if res != 0:
+        print "Could not build python-dmidecode."
+        print "Could not run xml2-config, is libxml2 installed?"
+        print "Also the development libraries?"
-        print("Could not build python-dmidecode.")
-        print("Could not run xml2-config, is libxml2 installed?")
-        print("Also the development libraries?")
         sys.exit(1)
 
     # Parse the xml2-config --libs response
--- a/src/util.c	2015-06-08 17:19:45.000000000 +0200
+++ b/src/util.c	2017-10-31 09:06:30.311273205 +0100
@@ -95,7 +95,7 @@
 static Log_t *sigill_logobj = NULL;
 
 void sigill_handler(int ignore_this) {
+	sigill_error = 1;
-        sigill_error = 1;
         if( sigill_logobj ) {
                 log_append(sigill_logobj, LOGFL_NODUPS, LOG_WARNING,
                            "SIGILL signal caught in mem_chunk()");
@@ -119,19 +119,19 @@
         void *mmp;
 #endif
         sigill_logobj = logp;
+	signal(SIGILL, sigill_handler);
-        signal(SIGILL, sigill_handler);
         if(sigill_error || (fd = open(devmem, O_RDONLY)) == -1) {
+		log_append(logp, LOGFL_NORMAL, LOG_WARNING,
-                log_append(logp, LOGFL_NORMAL, LOG_WARNING,
                            "Failed to open memory buffer (%s): %s",
                            devmem, strerror(errno));
+		p = NULL;
-                p = NULL;
                 goto exit;
         }
 
         if(sigill_error || (p = malloc(len)) == NULL) {
+		log_append(logp, LOGFL_NORMAL, LOG_WARNING,"malloc: %s", strerror(errno));
+		p = NULL;
+		goto exit;
-                log_append(logp, LOGFL_NORMAL, LOG_WARNING,"malloc: %s", strerror(errno));
-                p = NULL;
-                goto exit;
         }
 #ifdef USE_MMAP
 #ifdef _SC_PAGESIZE
@@ -148,37 +148,37 @@
         if(sigill_error || (mmp == MAP_FAILED)) {
                 log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (mmap): %s", devmem, strerror(errno));
                 free(p);
+		p = NULL;
+		goto exit;
-                p = NULL;
-                goto exit;
         }
 
         memcpy(p, (u8 *) mmp + mmoffset, len);
+	if (sigill_error) {
-        if (sigill_error) {
                 log_append(logp, LOGFL_NODUPS, LOG_WARNING,
                            "Failed to do memcpy() due to SIGILL signal");
+		free(p);
+		p = NULL;
+		goto exit;
+	}
-                free(p);
-                p = NULL;
-                goto exit;
-        }
 
         if(sigill_error || (munmap(mmp, mmoffset + len) == -1)) {
                 log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (munmap): %s", devmem, strerror(errno));
+		free(p);
+		p = NULL;
+		goto exit;
-                free(p);
-                p = NULL;
-                goto exit;
         }
 #else /* USE_MMAP */
         if(sigill_error || (lseek(fd, base, SEEK_SET) == -1)) {
                 log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (lseek): %s", devmem, strerror(errno));
                 free(p);
                 p = NULL;
+		goto exit;
-                goto exit;
         }
 
         if(sigill_error || (myread(logp, fd, p, len, devmem) == -1)) {
                 free(p);
+		p = NULL;
+		goto exit;
-                p = NULL;
-                goto exit;
         }
 #endif /* USE_MMAP */
 
@@ -186,23 +186,8 @@
                 perror(devmem);
 
  exit:
+	signal(SIGILL, SIG_DFL);
-        signal(SIGILL, SIG_DFL);
         sigill_logobj = NULL;
         return p;
 }
 
-/* Returns end - start + 1, assuming start < end */
-u64 u64_range(u64 start, u64 end)
-{
-	u64 res;
-
-	res.h = end.h - start.h;
-	res.l = end.l - start.l;
-
-	if (end.l < start.l)
-		res.h--;
-	if (++res.l == 0)
-		res.h++;
-
-	return res;
-}
--- a/src/util.h	2015-06-08 17:19:45.000000000 +0200
+++ b/src/util.h	2010-06-03 12:01:46.000000000 +0200
@@ -29,4 +29,3 @@
 int checksum(const u8 * buf, size_t len);
 void *mem_chunk(Log_t *logp, size_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);
--- a/src/version.h	2015-06-08 17:19:45.000000000 +0200
+++ b/src/version.h	2010-06-03 12:01:46.000000000 +0200
@@ -1 +1 @@
+#define VERSION "3.10.13"
-#define VERSION "3.12.2"
--- a/src/xmlpythonizer.c	2015-06-08 17:19:45.000000000 +0200
+++ b/src/xmlpythonizer.c	2010-06-03 12:01:46.000000000 +0200
@@ -85,7 +85,6 @@
 #include "dmilog.h"
 #include "xmlpythonizer.h"
 #include "version.h"
-#include "compat.h"
 
 
 /**
@@ -647,7 +646,7 @@
         switch( val_m->type_value ) {
         case ptzINT:
         case ptzLIST_INT:
+                value = PyInt_FromLong(atoi(workstr));
-                value = PYNUMBER_FROMLONG(atoi(workstr));
                 break;
 
         case ptzFLOAT:
@@ -662,7 +661,7 @@
 
         case ptzSTR:
         case ptzLIST_STR:
+                value = PyString_FromString(workstr);
-                value = PyBytes_FromString(workstr);
                 break;
 
         default:
@@ -851,7 +850,7 @@
         switch( map_p->type_value ) {
         case ptzCONST:
                 if( _get_key_value(logp, key, 256, map_p, xpctx, 0) != NULL ) {
+                        value = PyString_FromString(map_p->value);
-                        value = PyBytes_FromString(map_p->value);
                         PyADD_DICT_VALUE(retdata, key, value);
                 } else {
                         PyReturnError(PyExc_ValueError, "Could not get key value: %s [%i] (Defining key: %s)",
--- a/unit-tests/Makefile	2015-06-08 17:19:45.000000000 +0200
+++ b/unit-tests/Makefile	2010-06-03 12:01:46.000000000 +0200
@@ -1,7 +1,5 @@
-PY_BIN := python2
-
 test :
+	python unit -vv
-	$(PY_BIN) unit -vv
 
 clean :
 	rm -f *.{py[oc],o,so} *~
--- a/unit-tests/unit	2015-06-08 17:19:45.000000000 +0200
+++ b/unit-tests/unit	2010-06-03 12:01:46.000000000 +0200
@@ -2,9 +2,8 @@
 #.awk '$0 ~ /case [0-9]+: .. 3/ { sys.stdout.write($2 }' src/dmidecode.c|tr ':\n' ', '
 
 from pprint import pprint
+import os, sys, random, tempfile, time
+import commands
-import os, sys, subprocess, random, tempfile, time
-if sys.version_info[0] < 3:
-    import commands as subprocess
 from getopt import getopt
 
 # Setup temporary sys.path() with our build dir
@@ -33,7 +32,7 @@
             COLOR = True
         elif o in ("-h", "--help"):
             HELP = True
+except getopt.GetoptError, err:
-except getopt.GetoptError as err:
     # print help information and exit:
     HELP = True
     ERROR = True
@@ -139,7 +138,7 @@
 ################################################################################
 
 #. Let's ignore warnings from the module for the test units...
+err = open('/dev/null', 'a+', 0)
-err = open('/dev/null', 'a+', 1)
 os.dup2(err.fileno(), sys.stderr.fileno())
 
 vwrite(LINE, 1)
@@ -209,7 +208,7 @@
                     "Skip testing API function, missing root privileges: dmidecode.dump()"
                     ), 1)
 
+    types = range(0, 42)+range(126, 128)
-    types = list(range(0, 42))+list(range(126, 128))
     bad_types = [-1, -1000, 256]
     sections = [
         "bios",
@@ -264,7 +263,7 @@
                         test(output is not False)
                         if output:
                             vwrite("     * %s\n"%black(output.keys()), 1)
+                    except LookupError, e:
-                    except LookupError as e:
                         failed(e, 1)
 
                 for i in bad_types:
@@ -280,15 +279,15 @@
                     try:
                         output = dmidecode.type(i)
                         if dmidecode_bin:
+                            _output = commands.getoutput("dmidecode -t %d"%i).strip().split('\n')
-                            _output = subprocess.getoutput("dmidecode -t %d"%i).strip().split('\n')
                             test(len(_output) == 1 and len(output) == 0 or True)
                         else:
                             test(output is not False)
                         if output:
                             vwrite("     * %s\n"%output.keys(), 1)
+                    except IOError, e:
-                    except IOError as e:
                         failed(e, 1)
+                    except LookupError, e:
-                    except LookupError as e:
                         failed(e, 1)
 
 
@@ -331,7 +330,7 @@
                     try:
                         output_node = dmixml.QueryTypeId(i)
                         test(isinstance(output_node, libxml2.xmlNode))
+                    except Exception, e:
-                    except Exception as e:
                         failed(e, 1)
                     except:
                         failed()
@@ -348,7 +347,7 @@
                     try:
                         output_doc = dmixml.QuerySection(section)
                         test(isinstance(output_doc, libxml2.xmlDoc))
+                    except Exception, e:
-                    except Exception as e:
                         failed(e, 1)
                     except:
                         failed()
@@ -356,9 +355,9 @@
         except IOError:
             skipped()
 
+except ImportError, err:
-except ImportError as err:
     failed()
+    print err
-    print(err)
 
 vwrite(LINE, 1)
 vwrite("Devices : %s\n"%cyan(len(devices)), 1)