|
Packit Service |
e18529 |
/*
|
|
Packit Service |
e18529 |
* Decoding of OEM-specific entries
|
|
Packit Service |
e18529 |
* This file is part of the dmidecode project.
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* Copyright (C) 2007-2008 Jean Delvare <jdelvare@suse.de>
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit Service |
e18529 |
* it under the terms of the GNU General Public License as published by
|
|
Packit Service |
e18529 |
* the Free Software Foundation; either version 2 of the License, or
|
|
Packit Service |
e18529 |
* (at your option) any later version.
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
e18529 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
e18529 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
e18529 |
* GNU General Public License for more details.
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
e18529 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
e18529 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
Packit Service |
e18529 |
*/
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
#include <stdio.h>
|
|
Packit Service |
e18529 |
#include <string.h>
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
#include "types.h"
|
|
Packit Service |
e18529 |
#include "dmidecode.h"
|
|
Packit Service |
e18529 |
#include "dmioem.h"
|
|
Packit Service |
a1ff7a |
#include "dmioutput.h"
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
/*
|
|
Packit Service |
e18529 |
* Globals for vendor-specific decodes
|
|
Packit Service |
e18529 |
*/
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
enum DMI_VENDORS
|
|
Packit Service |
e18529 |
{
|
|
Packit Service |
e18529 |
VENDOR_UNKNOWN,
|
|
Packit Service |
e18529 |
VENDOR_ACER,
|
|
Packit Service |
e18529 |
VENDOR_HP,
|
|
Packit Service |
e18529 |
VENDOR_HPE,
|
|
Packit Service |
e18529 |
VENDOR_IBM,
|
|
Packit Service |
e18529 |
VENDOR_LENOVO,
|
|
Packit Service |
e18529 |
};
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
static enum DMI_VENDORS dmi_vendor = VENDOR_UNKNOWN;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
/*
|
|
Packit Service |
e18529 |
* Remember the system vendor for later use. We only actually store the
|
|
Packit Service |
e18529 |
* value if we know how to decode at least one specific entry type for
|
|
Packit Service |
e18529 |
* that vendor.
|
|
Packit Service |
e18529 |
*/
|
|
Packit Service |
e18529 |
void dmi_set_vendor(const char *s)
|
|
Packit Service |
e18529 |
{
|
|
Packit Service |
e18529 |
int len;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
/*
|
|
Packit Service |
e18529 |
* Often DMI strings have trailing spaces. Ignore these
|
|
Packit Service |
e18529 |
* when checking for known vendor names.
|
|
Packit Service |
e18529 |
*/
|
|
Packit Service |
e18529 |
len = strlen(s);
|
|
Packit Service |
e18529 |
while (len && s[len - 1] == ' ')
|
|
Packit Service |
e18529 |
len--;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
if (strncmp(s, "Acer", len) == 0)
|
|
Packit Service |
e18529 |
dmi_vendor = VENDOR_ACER;
|
|
Packit Service |
e18529 |
else if (strncmp(s, "HP", len) == 0 || strncmp(s, "Hewlett-Packard", len) == 0)
|
|
Packit Service |
e18529 |
dmi_vendor = VENDOR_HP;
|
|
Packit Service |
e18529 |
else if (strncmp(s, "HPE", len) == 0 || strncmp(s, "Hewlett Packard Enterprise", len) == 0)
|
|
Packit Service |
e18529 |
dmi_vendor = VENDOR_HPE;
|
|
Packit Service |
e18529 |
else if (strncmp(s, "IBM", len) == 0)
|
|
Packit Service |
e18529 |
dmi_vendor = VENDOR_IBM;
|
|
Packit Service |
e18529 |
else if (strncmp(s, "LENOVO", len) == 0)
|
|
Packit Service |
e18529 |
dmi_vendor = VENDOR_LENOVO;
|
|
Packit Service |
e18529 |
}
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
/*
|
|
Packit Service |
e18529 |
* Acer-specific data structures are decoded here.
|
|
Packit Service |
e18529 |
*/
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
static int dmi_decode_acer(const struct dmi_header *h)
|
|
Packit Service |
e18529 |
{
|
|
Packit Service |
e18529 |
u8 *data = h->data;
|
|
Packit Service |
e18529 |
u16 cap;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
switch (h->type)
|
|
Packit Service |
e18529 |
{
|
|
Packit Service |
e18529 |
case 170:
|
|
Packit Service |
e18529 |
/*
|
|
Packit Service |
e18529 |
* Vendor Specific: Acer Hotkey Function
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* Source: acer-wmi kernel driver
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* Probably applies to some laptop models of other
|
|
Packit Service |
e18529 |
* brands, including Fujitsu-Siemens, Medion, Lenovo,
|
|
Packit Service |
e18529 |
* and eMachines.
|
|
Packit Service |
e18529 |
*/
|
|
Packit Service |
a1ff7a |
pr_handle_name("Acer Hotkey Function");
|
|
Packit Service |
e18529 |
if (h->length < 0x0F) break;
|
|
Packit Service |
e18529 |
cap = WORD(data + 0x04);
|
|
Packit Service |
46ab7f |
pr_attr("Function bitmap for Communication Button", "0x%04hx", cap);
|
|
Packit Service |
a7a251 |
pr_subattr("WiFi", "%s", cap & 0x0001 ? "Yes" : "No");
|
|
Packit Service |
a7a251 |
pr_subattr("3G", "%s", cap & 0x0040 ? "Yes" : "No");
|
|
Packit Service |
a7a251 |
pr_subattr("WiMAX", "%s", cap & 0x0080 ? "Yes" : "No");
|
|
Packit Service |
a7a251 |
pr_subattr("Bluetooth", "%s", cap & 0x0800 ? "Yes" : "No");
|
|
Packit Service |
46ab7f |
pr_attr("Function bitmap for Application Button", "0x%04hx", WORD(data + 0x06));
|
|
Packit Service |
46ab7f |
pr_attr("Function bitmap for Media Button", "0x%04hx", WORD(data + 0x08));
|
|
Packit Service |
46ab7f |
pr_attr("Function bitmap for Display Button", "0x%04hx", WORD(data + 0x0A));
|
|
Packit Service |
46ab7f |
pr_attr("Function bitmap for Others Button", "0x%04hx", WORD(data + 0x0C));
|
|
Packit Service |
46ab7f |
pr_attr("Communication Function Key Number", "%d", data[0x0E]);
|
|
Packit Service |
e18529 |
break;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
default:
|
|
Packit Service |
e18529 |
return 0;
|
|
Packit Service |
e18529 |
}
|
|
Packit Service |
e18529 |
return 1;
|
|
Packit Service |
e18529 |
}
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
/*
|
|
Packit Service |
e18529 |
* HPE-specific data structures are decoded here.
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* Code contributed by John Cagle and Tyler Bell.
|
|
Packit Service |
e18529 |
*/
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
static void dmi_print_hp_net_iface_rec(u8 id, u8 bus, u8 dev, const u8 *mac)
|
|
Packit Service |
e18529 |
{
|
|
Packit Service |
e18529 |
/* Some systems do not provide an id. nic_ctr provides an artificial
|
|
Packit Service |
e18529 |
* id, and assumes the records will be provided "in order". Also,
|
|
Packit Service |
e18529 |
* using 0xFF marker is not future proof. 256 NICs is a lot, but
|
|
Packit Service |
e18529 |
* 640K ought to be enough for anybody(said no one, ever).
|
|
Packit Service |
e18529 |
* */
|
|
Packit Service |
e18529 |
static u8 nic_ctr;
|
|
Packit Service |
46ab7f |
char attr[8];
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
if (id == 0xFF)
|
|
Packit Service |
e18529 |
id = ++nic_ctr;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
46ab7f |
sprintf(attr, "NIC %hu", id);
|
|
Packit Service |
e18529 |
if (dev == 0x00 && bus == 0x00)
|
|
Packit Service |
46ab7f |
pr_attr(attr, "Disabled");
|
|
Packit Service |
e18529 |
else if (dev == 0xFF && bus == 0xFF)
|
|
Packit Service |
46ab7f |
pr_attr(attr, "Not Installed");
|
|
Packit Service |
e18529 |
else
|
|
Packit Service |
e18529 |
{
|
|
Packit Service |
46ab7f |
pr_attr(attr, "PCI device %02x:%02x.%x, "
|
|
Packit Service |
46ab7f |
"MAC address %02X:%02X:%02X:%02X:%02X:%02X",
|
|
Packit Service |
46ab7f |
bus, dev >> 3, dev & 7,
|
|
Packit Service |
e18529 |
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
|
Packit Service |
e18529 |
}
|
|
Packit Service |
e18529 |
}
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
static int dmi_decode_hp(const struct dmi_header *h)
|
|
Packit Service |
e18529 |
{
|
|
Packit Service |
e18529 |
u8 *data = h->data;
|
|
Packit Service |
e18529 |
int nic, ptr;
|
|
Packit Service |
e18529 |
u32 feat;
|
|
Packit Service |
e18529 |
const char *company = (dmi_vendor == VENDOR_HP) ? "HP" : "HPE";
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
switch (h->type)
|
|
Packit Service |
e18529 |
{
|
|
Packit Service |
e18529 |
case 204:
|
|
Packit Service |
e18529 |
/*
|
|
Packit Service |
e18529 |
* Vendor Specific: HPE ProLiant System/Rack Locator
|
|
Packit Service |
e18529 |
*/
|
|
Packit Service |
a1ff7a |
pr_handle_name("%s ProLiant System/Rack Locator", company);
|
|
Packit Service |
e18529 |
if (h->length < 0x0B) break;
|
|
Packit Service |
46ab7f |
pr_attr("Rack Name", "%s", dmi_string(h, data[0x04]));
|
|
Packit Service |
46ab7f |
pr_attr("Enclosure Name", "%s", dmi_string(h, data[0x05]));
|
|
Packit Service |
46ab7f |
pr_attr("Enclosure Model", "%s", dmi_string(h, data[0x06]));
|
|
Packit Service |
46ab7f |
pr_attr("Enclosure Serial", "%s", dmi_string(h, data[0x0A]));
|
|
Packit Service |
46ab7f |
pr_attr("Enclosure Bays", "%d", data[0x08]);
|
|
Packit Service |
46ab7f |
pr_attr("Server Bay", "%s", dmi_string(h, data[0x07]));
|
|
Packit Service |
46ab7f |
pr_attr("Bays Filled", "%d", data[0x09]);
|
|
Packit Service |
e18529 |
break;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
case 209:
|
|
Packit Service |
e18529 |
case 221:
|
|
Packit Service |
e18529 |
/*
|
|
Packit Service |
e18529 |
* Vendor Specific: HPE ProLiant NIC MAC Information
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* This prints the BIOS NIC number,
|
|
Packit Service |
e18529 |
* PCI bus/device/function, and MAC address
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* Type 209:
|
|
Packit Service |
e18529 |
* Offset | Name | Width | Description
|
|
Packit Service |
e18529 |
* -------------------------------------
|
|
Packit Service |
e18529 |
* 0x00 | Type | BYTE | 0xD1, MAC Info
|
|
Packit Service |
e18529 |
* 0x01 | Length | BYTE | Length of structure
|
|
Packit Service |
e18529 |
* 0x02 | Handle | WORD | Unique handle
|
|
Packit Service |
e18529 |
* 0x04 | Dev No | BYTE | PCI Device/Function No
|
|
Packit Service |
e18529 |
* 0x05 | Bus No | BYTE | PCI Bus
|
|
Packit Service |
e18529 |
* 0x06 | MAC | 6B | MAC addr
|
|
Packit Service |
e18529 |
* 0x0C | NIC #2 | 8B | Repeat 0x04-0x0B
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* Type 221: is deprecated in the latest docs
|
|
Packit Service |
e18529 |
*/
|
|
Packit Service |
a1ff7a |
pr_handle_name("%s %s", company, h->type == 221 ?
|
|
Packit Service |
a1ff7a |
"BIOS iSCSI NIC PCI and MAC Information" :
|
|
Packit Service |
a1ff7a |
"BIOS PXE NIC PCI and MAC Information");
|
|
Packit Service |
e18529 |
nic = 1;
|
|
Packit Service |
e18529 |
ptr = 4;
|
|
Packit Service |
e18529 |
while (h->length >= ptr + 8)
|
|
Packit Service |
e18529 |
{
|
|
Packit Service |
e18529 |
dmi_print_hp_net_iface_rec(nic,
|
|
Packit Service |
e18529 |
data[ptr + 0x01],
|
|
Packit Service |
e18529 |
data[ptr],
|
|
Packit Service |
e18529 |
&data[ptr + 0x02]);
|
|
Packit Service |
e18529 |
nic++;
|
|
Packit Service |
e18529 |
ptr += 8;
|
|
Packit Service |
e18529 |
}
|
|
Packit Service |
e18529 |
break;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
case 233:
|
|
Packit Service |
e18529 |
/*
|
|
Packit Service |
e18529 |
* Vendor Specific: HPE ProLiant NIC MAC Information
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* This prints the BIOS NIC number,
|
|
Packit Service |
e18529 |
* PCI bus/device/function, and MAC address
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* Offset | Name | Width | Description
|
|
Packit Service |
e18529 |
* -------------------------------------
|
|
Packit Service |
e18529 |
* 0x00 | Type | BYTE | 0xE9, NIC structure
|
|
Packit Service |
e18529 |
* 0x01 | Length | BYTE | Length of structure
|
|
Packit Service |
e18529 |
* 0x02 | Handle | WORD | Unique handle
|
|
Packit Service |
e18529 |
* 0x04 | Grp No | WORD | 0 for single segment
|
|
Packit Service |
e18529 |
* 0x06 | Bus No | BYTE | PCI Bus
|
|
Packit Service |
e18529 |
* 0x07 | Dev No | BYTE | PCI Device/Function No
|
|
Packit Service |
e18529 |
* 0x08 | MAC | 32B | MAC addr padded w/ 0s
|
|
Packit Service |
e18529 |
* 0x28 | Port No| BYTE | Each NIC maps to a Port
|
|
Packit Service |
e18529 |
*/
|
|
Packit Service |
a1ff7a |
pr_handle_name("%s BIOS PXE NIC PCI and MAC Information",
|
|
Packit Service |
a1ff7a |
company);
|
|
Packit Service |
e18529 |
if (h->length < 0x0E) break;
|
|
Packit Service |
e18529 |
/* If the record isn't long enough, we don't have an ID
|
|
Packit Service |
e18529 |
* use 0xFF to use the internal counter.
|
|
Packit Service |
e18529 |
* */
|
|
Packit Service |
e18529 |
nic = h->length > 0x28 ? data[0x28] : 0xFF;
|
|
Packit Service |
e18529 |
dmi_print_hp_net_iface_rec(nic, data[0x06], data[0x07],
|
|
Packit Service |
e18529 |
&data[0x08]);
|
|
Packit Service |
e18529 |
break;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
case 212:
|
|
Packit Service |
e18529 |
/*
|
|
Packit Service |
e18529 |
* Vendor Specific: HPE 64-bit CRU Information
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* Source: hpwdt kernel driver
|
|
Packit Service |
e18529 |
*/
|
|
Packit Service |
a1ff7a |
pr_handle_name("%s 64-bit CRU Information", company);
|
|
Packit Service |
e18529 |
if (h->length < 0x18) break;
|
|
Packit Service |
e18529 |
if (is_printable(data + 0x04, 4))
|
|
Packit Service |
46ab7f |
pr_attr("Signature", "0x%08x (%c%c%c%c)",
|
|
Packit Service |
46ab7f |
DWORD(data + 0x04),
|
|
Packit Service |
46ab7f |
data[0x04], data[0x05],
|
|
Packit Service |
e18529 |
data[0x06], data[0x07]);
|
|
Packit Service |
46ab7f |
else
|
|
Packit Service |
46ab7f |
pr_attr("Signature", "0x%08x", DWORD(data + 0x04));
|
|
Packit Service |
e18529 |
if (DWORD(data + 0x04) == 0x55524324)
|
|
Packit Service |
e18529 |
{
|
|
Packit Service |
e18529 |
u64 paddr = QWORD(data + 0x08);
|
|
Packit Service |
e18529 |
paddr.l += DWORD(data + 0x14);
|
|
Packit Service |
e18529 |
if (paddr.l < DWORD(data + 0x14))
|
|
Packit Service |
e18529 |
paddr.h++;
|
|
Packit Service |
46ab7f |
pr_attr("Physical Address", "0x%08x%08x",
|
|
Packit Service |
e18529 |
paddr.h, paddr.l);
|
|
Packit Service |
46ab7f |
pr_attr("Length", "0x%08x", DWORD(data + 0x10));
|
|
Packit Service |
e18529 |
}
|
|
Packit Service |
e18529 |
break;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
case 219:
|
|
Packit Service |
e18529 |
/*
|
|
Packit Service |
e18529 |
* Vendor Specific: HPE ProLiant Information
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* Source: hpwdt kernel driver
|
|
Packit Service |
e18529 |
*/
|
|
Packit Service |
a1ff7a |
pr_handle_name("%s ProLiant Information", company);
|
|
Packit Service |
e18529 |
if (h->length < 0x08) break;
|
|
Packit Service |
46ab7f |
pr_attr("Power Features", "0x%08x", DWORD(data + 0x04));
|
|
Packit Service |
e18529 |
if (h->length < 0x0C) break;
|
|
Packit Service |
46ab7f |
pr_attr("Omega Features", "0x%08x", DWORD(data + 0x08));
|
|
Packit Service |
e18529 |
if (h->length < 0x14) break;
|
|
Packit Service |
e18529 |
feat = DWORD(data + 0x10);
|
|
Packit Service |
46ab7f |
pr_attr("Misc. Features", "0x%08x", feat);
|
|
Packit Service |
a7a251 |
pr_subattr("iCRU", "%s", feat & 0x0001 ? "Yes" : "No");
|
|
Packit Service |
a7a251 |
pr_subattr("UEFI", "%s", feat & 0x1400 ? "Yes" : "No");
|
|
Packit Service |
e18529 |
break;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
default:
|
|
Packit Service |
e18529 |
return 0;
|
|
Packit Service |
e18529 |
}
|
|
Packit Service |
e18529 |
return 1;
|
|
Packit Service |
e18529 |
}
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
static int dmi_decode_ibm_lenovo(const struct dmi_header *h)
|
|
Packit Service |
e18529 |
{
|
|
Packit Service |
e18529 |
u8 *data = h->data;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
switch (h->type)
|
|
Packit Service |
e18529 |
{
|
|
Packit Service |
e18529 |
case 131:
|
|
Packit Service |
e18529 |
/*
|
|
Packit Service |
e18529 |
* Vendor Specific: ThinkVantage Technologies feature bits
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* Source: Compal hel81 Service Manual Software Specification,
|
|
Packit Service |
e18529 |
* documented under "System Management BIOS(SM BIOS)
|
|
Packit Service |
e18529 |
* version 2.4 or greater"
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* Offset | Name | Width | Description
|
|
Packit Service |
e18529 |
* ----------------------------------------------
|
|
Packit Service |
e18529 |
* 0x00 | Type | BYTE | 0x83
|
|
Packit Service |
e18529 |
* 0x01 | Length | BYTE | 0x16
|
|
Packit Service |
e18529 |
* 0x02 | Handle | WORD | Varies
|
|
Packit Service |
e18529 |
* 0x04 | Version | BYTE | 0x01
|
|
Packit Service |
e18529 |
* 0x05 | TVT Structure | BYTEx16 | Each of the 128 bits represents a TVT feature:
|
|
Packit Service |
e18529 |
* | | | - bit 127 means diagnostics (PC Doctor) is available
|
|
Packit Service |
e18529 |
* | | | (http://www.pc-doctor.com/company/pr-articles/45-lenovo-introduces-thinkvantage-toolbox)
|
|
Packit Service |
e18529 |
* | | | - the rest (126-0) are reserved/unknown
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* It must also be followed by a string containing
|
|
Packit Service |
e18529 |
* "TVT-Enablement". There exist other type 131 records
|
|
Packit Service |
e18529 |
* with different length and a different string, for
|
|
Packit Service |
e18529 |
* other purposes.
|
|
Packit Service |
e18529 |
*/
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
if (h->length != 0x16
|
|
Packit Service |
e18529 |
|| strcmp(dmi_string(h, 1), "TVT-Enablement") != 0)
|
|
Packit Service |
e18529 |
return 0;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
a1ff7a |
pr_handle_name("ThinkVantage Technologies");
|
|
Packit Service |
46ab7f |
pr_attr("Version", "%u", data[0x04]);
|
|
Packit Service |
46ab7f |
pr_attr("Diagnostics", "%s",
|
|
Packit Service |
e18529 |
data[0x14] & 0x80 ? "Available" : "No");
|
|
Packit Service |
e18529 |
break;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
case 135:
|
|
Packit Service |
e18529 |
/*
|
|
Packit Service |
e18529 |
* Vendor Specific: Device Presence Detection bits
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* Source: Compal hel81 Service Manual Software Specification,
|
|
Packit Service |
e18529 |
* documented as "SMBIOS Type 135: Bulk for Lenovo
|
|
Packit Service |
e18529 |
* Mobile PC Unique OEM Data" under appendix D.
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* Offset | Name | Width | Description
|
|
Packit Service |
e18529 |
* ---------------------------------------------------
|
|
Packit Service |
e18529 |
* 0x00 | Type | BYTE | 0x87
|
|
Packit Service |
e18529 |
* 0x01 | Length | BYTE | 0x0A
|
|
Packit Service |
e18529 |
* 0x02 | Handle | WORD | Varies
|
|
Packit Service |
e18529 |
* 0x04 | Signature | WORD | 0x5054 (ASCII for "TP")
|
|
Packit Service |
e18529 |
* 0x06 | OEM struct offset | BYTE | 0x07
|
|
Packit Service |
e18529 |
* 0x07 | OEM struct number | BYTE | 0x03, for this structure
|
|
Packit Service |
e18529 |
* 0x08 | OEM struct revision | BYTE | 0x01, for this format
|
|
Packit Service |
e18529 |
* 0x09 | Device presence bits | BYTE | Each of the 8 bits indicates device presence:
|
|
Packit Service |
e18529 |
* | | | - bit 0 indicates the presence of a fingerprint reader
|
|
Packit Service |
e18529 |
* | | | - the rest (7-1) are reserved/unknown
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* Other OEM struct number+rev combinations have been
|
|
Packit Service |
e18529 |
* seen in the wild but we don't know how to decode
|
|
Packit Service |
e18529 |
* them.
|
|
Packit Service |
e18529 |
*/
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
if (h->length < 0x0A || data[0x04] != 'T' || data[0x05] != 'P')
|
|
Packit Service |
e18529 |
return 0;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
/* Bail out if not the expected format */
|
|
Packit Service |
e18529 |
if (data[0x06] != 0x07 || data[0x07] != 0x03 || data[0x08] != 0x01)
|
|
Packit Service |
e18529 |
return 0;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
a1ff7a |
pr_handle_name("ThinkPad Device Presence Detection");
|
|
Packit Service |
46ab7f |
pr_attr("Fingerprint Reader", "%s",
|
|
Packit Service |
e18529 |
data[0x09] & 0x01 ? "Present" : "No");
|
|
Packit Service |
e18529 |
break;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
case 140:
|
|
Packit Service |
e18529 |
/*
|
|
Packit Service |
e18529 |
* Vendor Specific: ThinkPad Embedded Controller Program
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* Source: some guesswork, and publicly available information;
|
|
Packit Service |
e18529 |
* Lenovo's BIOS update READMEs often contain the ECP IDs
|
|
Packit Service |
e18529 |
* which match the first string in this type.
|
|
Packit Service |
e18529 |
*
|
|
Packit Service |
e18529 |
* Offset | Name | Width | Description
|
|
Packit Service |
e18529 |
* ----------------------------------------------------
|
|
Packit Service |
e18529 |
* 0x00 | Type | BYTE | 0x8C
|
|
Packit Service |
e18529 |
* 0x01 | Length | BYTE |
|
|
Packit Service |
e18529 |
* 0x02 | Handle | WORD | Varies
|
|
Packit Service |
e18529 |
* 0x04 | Signature | BYTEx6 | ASCII for "LENOVO"
|
|
Packit Service |
e18529 |
* 0x0A | OEM struct offset | BYTE | 0x0B
|
|
Packit Service |
e18529 |
* 0x0B | OEM struct number | BYTE | 0x07, for this structure
|
|
Packit Service |
e18529 |
* 0x0C | OEM struct revision | BYTE | 0x01, for this format
|
|
Packit Service |
e18529 |
* 0x0D | ECP version ID | STRING |
|
|
Packit Service |
e18529 |
* 0x0E | ECP release date | STRING |
|
|
Packit Service |
e18529 |
*/
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
if (h->length < 0x0F || memcmp(data + 4, "LENOVO", 6) != 0)
|
|
Packit Service |
e18529 |
return 0;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
/* Bail out if not the expected format */
|
|
Packit Service |
e18529 |
if (data[0x0A] != 0x0B || data[0x0B] != 0x07 || data[0x0C] != 0x01)
|
|
Packit Service |
e18529 |
return 0;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
a1ff7a |
pr_handle_name("ThinkPad Embedded Controller Program");
|
|
Packit Service |
46ab7f |
pr_attr("Version ID", "%s", dmi_string(h, 1));
|
|
Packit Service |
46ab7f |
pr_attr("Release Date", "%s", dmi_string(h, 2));
|
|
Packit Service |
e18529 |
break;
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
default:
|
|
Packit Service |
e18529 |
return 0;
|
|
Packit Service |
e18529 |
}
|
|
Packit Service |
e18529 |
return 1;
|
|
Packit Service |
e18529 |
}
|
|
Packit Service |
e18529 |
|
|
Packit Service |
e18529 |
/*
|
|
Packit Service |
e18529 |
* Dispatch vendor-specific entries decoding
|
|
Packit Service |
e18529 |
* Return 1 if decoding was successful, 0 otherwise
|
|
Packit Service |
e18529 |
*/
|
|
Packit Service |
e18529 |
int dmi_decode_oem(const struct dmi_header *h)
|
|
Packit Service |
e18529 |
{
|
|
Packit Service |
e18529 |
switch (dmi_vendor)
|
|
Packit Service |
e18529 |
{
|
|
Packit Service |
e18529 |
case VENDOR_HP:
|
|
Packit Service |
e18529 |
case VENDOR_HPE:
|
|
Packit Service |
e18529 |
return dmi_decode_hp(h);
|
|
Packit Service |
e18529 |
case VENDOR_ACER:
|
|
Packit Service |
e18529 |
return dmi_decode_acer(h);
|
|
Packit Service |
e18529 |
case VENDOR_IBM:
|
|
Packit Service |
e18529 |
case VENDOR_LENOVO:
|
|
Packit Service |
e18529 |
return dmi_decode_ibm_lenovo(h);
|
|
Packit Service |
e18529 |
default:
|
|
Packit Service |
e18529 |
return 0;
|
|
Packit Service |
e18529 |
}
|
|
Packit Service |
e18529 |
}
|