aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware/dmi_scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firmware/dmi_scan.c')
-rw-r--r--drivers/firmware/dmi_scan.c31
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;
32static struct dmi_memdev_info { 32static 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;
37static int dmi_memdev_nr; 38static 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}
1067EXPORT_SYMBOL_GPL(dmi_memdev_name); 1084EXPORT_SYMBOL_GPL(dmi_memdev_name);
1085
1086u64 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}
1098EXPORT_SYMBOL_GPL(dmi_memdev_size);