diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/firmware/dmi_scan.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/firmware/dmi_scan.c')
-rw-r--r-- | drivers/firmware/dmi_scan.c | 87 |
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 | */ |
17 | static char dmi_empty_string[] = " "; | 16 | static char dmi_empty_string[] = " "; |
18 | 17 | ||
19 | static 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 | ||
122 | static int __init dmi_checksum(const u8 *buf, u8 len) | 118 | static 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 | ||
442 | static 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 | |||
469 | void __init dmi_scan_machine(void) | 427 | void __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 | */ |
638 | int dmi_name_in_vendors(const char *str) | 591 | int 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]; |