diff options
Diffstat (limited to 'drivers/firmware/dmi_scan.c')
-rw-r--r-- | drivers/firmware/dmi_scan.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index e763e1484331..35c6c74c9304 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
@@ -32,6 +32,7 @@ static char dmi_ids_string[128] __initdata; | |||
32 | static struct dmi_memdev_info { | 32 | static struct dmi_memdev_info { |
33 | const char *device; | 33 | const char *device; |
34 | const char *bank; | 34 | const char *bank; |
35 | u64 size; /* bytes */ | ||
35 | u16 handle; | 36 | u16 handle; |
36 | } *dmi_memdev; | 37 | } *dmi_memdev; |
37 | static int dmi_memdev_nr; | 38 | static int dmi_memdev_nr; |
@@ -386,6 +387,8 @@ static void __init save_mem_devices(const struct dmi_header *dm, void *v) | |||
386 | { | 387 | { |
387 | const char *d = (const char *)dm; | 388 | const char *d = (const char *)dm; |
388 | static int nr; | 389 | static int nr; |
390 | u64 bytes; | ||
391 | u16 size; | ||
389 | 392 | ||
390 | if (dm->type != DMI_ENTRY_MEM_DEVICE || dm->length < 0x12) | 393 | if (dm->type != DMI_ENTRY_MEM_DEVICE || dm->length < 0x12) |
391 | return; | 394 | return; |
@@ -396,6 +399,20 @@ static void __init save_mem_devices(const struct dmi_header *dm, void *v) | |||
396 | dmi_memdev[nr].handle = get_unaligned(&dm->handle); | 399 | dmi_memdev[nr].handle = get_unaligned(&dm->handle); |
397 | dmi_memdev[nr].device = dmi_string(dm, d[0x10]); | 400 | dmi_memdev[nr].device = dmi_string(dm, d[0x10]); |
398 | dmi_memdev[nr].bank = dmi_string(dm, d[0x11]); | 401 | dmi_memdev[nr].bank = dmi_string(dm, d[0x11]); |
402 | |||
403 | size = get_unaligned((u16 *)&d[0xC]); | ||
404 | if (size == 0) | ||
405 | bytes = 0; | ||
406 | else if (size == 0xffff) | ||
407 | bytes = ~0ull; | ||
408 | else if (size & 0x8000) | ||
409 | bytes = (u64)(size & 0x7fff) << 10; | ||
410 | else if (size != 0x7fff) | ||
411 | bytes = (u64)size << 20; | ||
412 | else | ||
413 | bytes = (u64)get_unaligned((u32 *)&d[0x1C]) << 20; | ||
414 | |||
415 | dmi_memdev[nr].size = bytes; | ||
399 | nr++; | 416 | nr++; |
400 | } | 417 | } |
401 | 418 | ||
@@ -1065,3 +1082,17 @@ void dmi_memdev_name(u16 handle, const char **bank, const char **device) | |||
1065 | } | 1082 | } |
1066 | } | 1083 | } |
1067 | EXPORT_SYMBOL_GPL(dmi_memdev_name); | 1084 | EXPORT_SYMBOL_GPL(dmi_memdev_name); |
1085 | |||
1086 | u64 dmi_memdev_size(u16 handle) | ||
1087 | { | ||
1088 | int n; | ||
1089 | |||
1090 | if (dmi_memdev) { | ||
1091 | for (n = 0; n < dmi_memdev_nr; n++) { | ||
1092 | if (handle == dmi_memdev[n].handle) | ||
1093 | return dmi_memdev[n].size; | ||
1094 | } | ||
1095 | } | ||
1096 | return ~0ull; | ||
1097 | } | ||
1098 | EXPORT_SYMBOL_GPL(dmi_memdev_size); | ||