diff options
-rw-r--r-- | drivers/firmware/dmi_scan.c | 31 | ||||
-rw-r--r-- | include/linux/dmi.h | 2 |
2 files changed, 33 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); | ||
diff --git a/include/linux/dmi.h b/include/linux/dmi.h index 46e151172d95..7f5929123b69 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h | |||
@@ -113,6 +113,7 @@ extern int dmi_walk(void (*decode)(const struct dmi_header *, void *), | |||
113 | void *private_data); | 113 | void *private_data); |
114 | extern bool dmi_match(enum dmi_field f, const char *str); | 114 | extern bool dmi_match(enum dmi_field f, const char *str); |
115 | extern void dmi_memdev_name(u16 handle, const char **bank, const char **device); | 115 | extern void dmi_memdev_name(u16 handle, const char **bank, const char **device); |
116 | extern u64 dmi_memdev_size(u16 handle); | ||
116 | 117 | ||
117 | #else | 118 | #else |
118 | 119 | ||
@@ -142,6 +143,7 @@ static inline bool dmi_match(enum dmi_field f, const char *str) | |||
142 | { return false; } | 143 | { return false; } |
143 | static inline void dmi_memdev_name(u16 handle, const char **bank, | 144 | static inline void dmi_memdev_name(u16 handle, const char **bank, |
144 | const char **device) { } | 145 | const char **device) { } |
146 | static inline u64 dmi_memdev_size(u16 handle) { return ~0ul; } | ||
145 | static inline const struct dmi_system_id * | 147 | static inline const struct dmi_system_id * |
146 | dmi_first_match(const struct dmi_system_id *list) { return NULL; } | 148 | dmi_first_match(const struct dmi_system_id *list) { return NULL; } |
147 | 149 | ||