Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 5270 → Rev 6934

/drivers/ddk/linux/dmi.c
1,11 → 1,12
 
#include <linux/types.h>
#include <linux/string.h>
#include <linux/bug.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/dmi.h>
#include <asm/unaligned.h>
#include <syscall.h>
struct kobject *dmi_kobj;
 
static void *dmi_alloc(unsigned len)
{
19,7 → 20,12
*/
static const char dmi_empty_string[] = " ";
 
static u16 dmi_ver;
static u32 dmi_ver __initdata;
static u32 dmi_len;
static u16 dmi_num;
static u8 smbios_entry_point[32];
static int smbios_entry_point_size;
 
/*
* Catch too early calls to dmi_check_system():
*/
26,7 → 32,7
static int dmi_initialized;
 
/* DMI system identification string used during boot */
static char dmi_ids_string[128];
static char dmi_ids_string[128] __initdata;
 
static struct dmi_memdev_info {
const char *device;
80,7 → 86,7
* We have to be cautious here. We have seen BIOSes with DMI pointers
* pointing to completely the wrong place for example
*/
static void dmi_table(u8 *buf, int len, int num,
static void dmi_decode_table(u8 *buf,
void (*decode)(const struct dmi_header *, void *),
void *private_data)
{
88,10 → 94,13
int i = 0;
 
/*
* Stop when we see all the items the table claimed to have
* OR we run off the end of the table (also happens)
* Stop when we have seen all the items the table claimed to have
* (SMBIOS < 3.0 only) OR we reach an end-of-table marker (SMBIOS
* >= 3.0 only) OR we run off the end of the table (should never
* happen but sometimes does on bogus implementations.)
*/
while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) {
while ((!dmi_num || i < dmi_num) &&
(data - buf + sizeof(struct dmi_header)) <= dmi_len) {
const struct dmi_header *dm = (const struct dmi_header *)data;
 
/*
100,29 → 109,44
* table in dmi_decode or dmi_string
*/
data += dm->length;
while ((data - buf < len - 1) && (data[0] || data[1]))
while ((data - buf < dmi_len - 1) && (data[0] || data[1]))
data++;
if (data - buf < len - 1)
if (data - buf < dmi_len - 1)
decode(dm, private_data);
 
data += 2;
i++;
 
/*
* 7.45 End-of-Table (Type 127) [SMBIOS reference spec v3.0.0]
* For tables behind a 64-bit entry point, we have no item
* count and no exact table length, so stop on end-of-table
* marker. For tables behind a 32-bit entry point, we have
* seen OEM structures behind the end-of-table marker on
* some systems, so don't trust it.
*/
if (!dmi_num && dm->type == DMI_ENTRY_END_OF_TABLE)
break;
}
 
/* Trim DMI table length if needed */
if (dmi_len > data - buf)
dmi_len = data - buf;
}
 
static u32 dmi_base;
static u16 dmi_len;
static u16 dmi_num;
static phys_addr_t dmi_base;
 
static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
void *))
{
u8 *buf;
u32 orig_dmi_len = dmi_len;
 
buf = (u8*)MapIoMem(dmi_base, dmi_len, PG_SW);
if (buf == NULL)
return -1;
 
dmi_table(buf, dmi_len, dmi_num, decode, NULL);
dmi_decode_table(buf, decode, NULL);
 
FreeKernelSpace(buf);
 
192,7 → 216,7
* the UUID are supposed to be little-endian encoded. The specification
* says that this is the defacto standard.
*/
if (dmi_ver >= 0x0206)
if (dmi_ver >= 0x020600)
sprintf(s, "%pUL", d);
else
sprintf(s, "%pUB", d);
329,7 → 353,13
dmi_save_dev_onboard(*(d+1), *(u16 *)(d+2), *(d+4), *(d+5),
dmi_string_nosave(dm, *(d-1)));
dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1)));
}
 
static void __init count_mem_devices(const struct dmi_header *dm, void *v)
{
if (dm->type != DMI_ENTRY_MEM_DEVICE)
return;
dmi_memdev_nr++;
}
 
/*
429,11 → 459,13
*/
static int __init dmi_present(const u8 *buf)
{
int smbios_ver;
u32 smbios_ver;
 
if (memcmp(buf, "_SM_", 4) == 0 &&
buf[5] < 32 && dmi_checksum(buf, buf[5])) {
smbios_ver = (buf[6] << 8) + buf[7];
smbios_ver = get_unaligned_be16(buf + 6);
smbios_entry_point_size = buf[5];
memcpy(smbios_entry_point, buf, smbios_entry_point_size);
 
/* Some BIOS report weird SMBIOS version, fix that up */
switch (smbios_ver) {
455,21 → 487,25
buf += 16;
 
if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) {
dmi_num = (buf[13] << 8) | buf[12];
dmi_len = (buf[7] << 8) | buf[6];
dmi_base = (buf[11] << 24) | (buf[10] << 16) |
(buf[9] << 8) | buf[8];
if (smbios_ver)
dmi_ver = smbios_ver;
else
dmi_ver = (buf[14] & 0xF0) << 4 | (buf[14] & 0x0F);
dmi_ver <<= 8;
dmi_num = get_unaligned_le16(buf + 12);
dmi_len = get_unaligned_le16(buf + 6);
dmi_base = get_unaligned_le32(buf + 8);
 
if (dmi_walk_early(dmi_decode) == 0) {
if (smbios_ver) {
dmi_ver = smbios_ver;
pr_info("SMBIOS %d.%d present.\n",
dmi_ver >> 8, dmi_ver & 0xFF);
dmi_ver >> 16, (dmi_ver >> 8) & 0xFF);
} else {
dmi_ver = (buf[14] & 0xF0) << 4 |
(buf[14] & 0x0F);
smbios_entry_point_size = 15;
memcpy(smbios_entry_point, buf,
smbios_entry_point_size);
pr_info("Legacy DMI %d.%d present.\n",
dmi_ver >> 8, dmi_ver & 0xFF);
dmi_ver >> 16, (dmi_ver >> 8) & 0xFF);
}
dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string));
printk(KERN_DEBUG "DMI: %s\n", dmi_ids_string);
480,6 → 516,33
return 1;
}
 
/*
* Check for the SMBIOS 3.0 64-bit entry point signature. Unlike the legacy
* 32-bit entry point, there is no embedded DMI header (_DMI_) in here.
*/
static int __init dmi_smbios3_present(const u8 *buf)
{
if (memcmp(buf, "_SM3_", 5) == 0 &&
buf[6] < 32 && dmi_checksum(buf, buf[6])) {
dmi_ver = get_unaligned_be32(buf + 6) & 0xFFFFFF;
dmi_num = 0; /* No longer specified */
dmi_len = get_unaligned_le32(buf + 12);
dmi_base = get_unaligned_le64(buf + 16);
smbios_entry_point_size = buf[6];
memcpy(smbios_entry_point, buf, smbios_entry_point_size);
 
if (dmi_walk_early(dmi_decode) == 0) {
pr_info("SMBIOS %d.%d.%d present.\n",
dmi_ver >> 16, (dmi_ver >> 8) & 0xFF,
dmi_ver & 0xFF);
dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string));
pr_debug("DMI: %s\n", dmi_ids_string);
return 0;
}
}
return 1;
}
 
void __init dmi_scan_machine(void)
{
char __iomem *p, *q;
499,7 → 562,7
memset(buf, 0, 16);
for (q = p; q < p + 0x10000; q += 16) {
memcpy(buf + 16, q, 16);
if (!dmi_present(buf)) {
if (!dmi_smbios3_present(buf) || !dmi_present(buf)) {
dmi_available = 1;
goto out;
}