aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware/dmi_scan.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/firmware/dmi_scan.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/firmware/dmi_scan.c')
-rw-r--r--drivers/firmware/dmi_scan.c87
1 files changed, 21 insertions, 66 deletions
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index fd3ae6290d7..bcb1126e3d0 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -6,7 +6,6 @@
6#include <linux/dmi.h> 6#include <linux/dmi.h>
7#include <linux/efi.h> 7#include <linux/efi.h>
8#include <linux/bootmem.h> 8#include <linux/bootmem.h>
9#include <linux/random.h>
10#include <asm/dmi.h> 9#include <asm/dmi.h>
11 10
12/* 11/*
@@ -16,7 +15,6 @@
16 */ 15 */
17static char dmi_empty_string[] = " "; 16static char dmi_empty_string[] = " ";
18 17
19static u16 __initdata dmi_ver;
20/* 18/*
21 * Catch too early calls to dmi_check_system(): 19 * Catch too early calls to dmi_check_system():
22 */ 20 */
@@ -113,18 +111,16 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
113 111
114 dmi_table(buf, dmi_len, dmi_num, decode, NULL); 112 dmi_table(buf, dmi_len, dmi_num, decode, NULL);
115 113
116 add_device_randomness(buf, dmi_len);
117
118 dmi_iounmap(buf, dmi_len); 114 dmi_iounmap(buf, dmi_len);
119 return 0; 115 return 0;
120} 116}
121 117
122static int __init dmi_checksum(const u8 *buf, u8 len) 118static int __init dmi_checksum(const u8 *buf)
123{ 119{
124 u8 sum = 0; 120 u8 sum = 0;
125 int a; 121 int a;
126 122
127 for (a = 0; a < len; a++) 123 for (a = 0; a < 15; a++)
128 sum += buf[a]; 124 sum += buf[a];
129 125
130 return sum == 0; 126 return sum == 0;
@@ -162,10 +158,8 @@ static void __init dmi_save_uuid(const struct dmi_header *dm, int slot, int inde
162 return; 158 return;
163 159
164 for (i = 0; i < 16 && (is_ff || is_00); i++) { 160 for (i = 0; i < 16 && (is_ff || is_00); i++) {
165 if (d[i] != 0x00) 161 if(d[i] != 0x00) is_ff = 0;
166 is_00 = 0; 162 if(d[i] != 0xFF) is_00 = 0;
167 if (d[i] != 0xFF)
168 is_ff = 0;
169 } 163 }
170 164
171 if (is_ff || is_00) 165 if (is_ff || is_00)
@@ -175,15 +169,7 @@ static void __init dmi_save_uuid(const struct dmi_header *dm, int slot, int inde
175 if (!s) 169 if (!s)
176 return; 170 return;
177 171
178 /* 172 sprintf(s, "%pUB", d);
179 * As of version 2.6 of the SMBIOS specification, the first 3 fields of
180 * the UUID are supposed to be little-endian encoded. The specification
181 * says that this is the defacto standard.
182 */
183 if (dmi_ver >= 0x0206)
184 sprintf(s, "%pUL", d);
185 else
186 sprintf(s, "%pUB", d);
187 173
188 dmi_ident[slot] = s; 174 dmi_ident[slot] = s;
189} 175}
@@ -415,57 +401,29 @@ static int __init dmi_present(const char __iomem *p)
415 u8 buf[15]; 401 u8 buf[15];
416 402
417 memcpy_fromio(buf, p, 15); 403 memcpy_fromio(buf, p, 15);
418 if (dmi_checksum(buf, 15)) { 404 if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) {
419 dmi_num = (buf[13] << 8) | buf[12]; 405 dmi_num = (buf[13] << 8) | buf[12];
420 dmi_len = (buf[7] << 8) | buf[6]; 406 dmi_len = (buf[7] << 8) | buf[6];
421 dmi_base = (buf[11] << 24) | (buf[10] << 16) | 407 dmi_base = (buf[11] << 24) | (buf[10] << 16) |
422 (buf[9] << 8) | buf[8]; 408 (buf[9] << 8) | buf[8];
423 409
410 /*
411 * DMI version 0.0 means that the real version is taken from
412 * the SMBIOS version, which we don't know at this point.
413 */
414 if (buf[14] != 0)
415 printk(KERN_INFO "DMI %d.%d present.\n",
416 buf[14] >> 4, buf[14] & 0xF);
417 else
418 printk(KERN_INFO "DMI present.\n");
424 if (dmi_walk_early(dmi_decode) == 0) { 419 if (dmi_walk_early(dmi_decode) == 0) {
425 if (dmi_ver)
426 pr_info("SMBIOS %d.%d present.\n",
427 dmi_ver >> 8, dmi_ver & 0xFF);
428 else {
429 dmi_ver = (buf[14] & 0xF0) << 4 |
430 (buf[14] & 0x0F);
431 pr_info("Legacy DMI %d.%d present.\n",
432 dmi_ver >> 8, dmi_ver & 0xFF);
433 }
434 dmi_dump_ids(); 420 dmi_dump_ids();
435 return 0; 421 return 0;
436 } 422 }
437 } 423 }
438 dmi_ver = 0;
439 return 1; 424 return 1;
440} 425}
441 426
442static int __init smbios_present(const char __iomem *p)
443{
444 u8 buf[32];
445 int offset = 0;
446
447 memcpy_fromio(buf, p, 32);
448 if ((buf[5] < 32) && dmi_checksum(buf, buf[5])) {
449 dmi_ver = (buf[6] << 8) + buf[7];
450
451 /* Some BIOS report weird SMBIOS version, fix that up */
452 switch (dmi_ver) {
453 case 0x021F:
454 case 0x0221:
455 pr_debug("SMBIOS version fixup(2.%d->2.%d)\n",
456 dmi_ver & 0xFF, 3);
457 dmi_ver = 0x0203;
458 break;
459 case 0x0233:
460 pr_debug("SMBIOS version fixup(2.%d->2.%d)\n", 51, 6);
461 dmi_ver = 0x0206;
462 break;
463 }
464 offset = 16;
465 }
466 return dmi_present(buf + offset);
467}
468
469void __init dmi_scan_machine(void) 427void __init dmi_scan_machine(void)
470{ 428{
471 char __iomem *p, *q; 429 char __iomem *p, *q;
@@ -483,7 +441,7 @@ void __init dmi_scan_machine(void)
483 if (p == NULL) 441 if (p == NULL)
484 goto error; 442 goto error;
485 443
486 rc = smbios_present(p); 444 rc = dmi_present(p + 0x10); /* offset of _DMI_ string */
487 dmi_iounmap(p, 32); 445 dmi_iounmap(p, 32);
488 if (!rc) { 446 if (!rc) {
489 dmi_available = 1; 447 dmi_available = 1;
@@ -501,12 +459,7 @@ void __init dmi_scan_machine(void)
501 goto error; 459 goto error;
502 460
503 for (q = p; q < p + 0x10000; q += 16) { 461 for (q = p; q < p + 0x10000; q += 16) {
504 if (memcmp(q, "_SM_", 4) == 0 && q - p <= 0xFFE0) 462 rc = dmi_present(q);
505 rc = smbios_present(q);
506 else if (memcmp(q, "_DMI_", 5) == 0)
507 rc = dmi_present(q);
508 else
509 continue;
510 if (!rc) { 463 if (!rc) {
511 dmi_available = 1; 464 dmi_available = 1;
512 dmi_iounmap(p, 0x10000); 465 dmi_iounmap(p, 0x10000);
@@ -632,12 +585,14 @@ int dmi_name_in_serial(const char *str)
632} 585}
633 586
634/** 587/**
635 * dmi_name_in_vendors - Check if string is in the DMI system or board vendor name 588 * dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information.
636 * @str: Case sensitive Name 589 * @str: Case sensitive Name
637 */ 590 */
638int dmi_name_in_vendors(const char *str) 591int dmi_name_in_vendors(const char *str)
639{ 592{
640 static int fields[] = { DMI_SYS_VENDOR, DMI_BOARD_VENDOR, DMI_NONE }; 593 static int fields[] = { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_SYS_VENDOR,
594 DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR,
595 DMI_BOARD_NAME, DMI_BOARD_VERSION, DMI_NONE };
641 int i; 596 int i;
642 for (i = 0; fields[i] != DMI_NONE; i++) { 597 for (i = 0; fields[i] != DMI_NONE; i++) {
643 int f = fields[i]; 598 int f = fields[i];