HPE OEM type 242 displays the drive capacity using a function
initially designed to display memory sizes. While memory sizes are
traditionally expressed using power-of-2 units (KiB, MiB, GiB...),
the computer storage industry still uses power-of-10 units (kB, MB,
GB...) to express a drive's capacity.

Implement a new function displaying capacities using power-of-10
units and use it to display the drive capacity. That way, the number
displayed will match the expectations and hardware documentation.

Signed-off-by: Jean Delvare <jdelv...@suse.de>
---
Jerry, what do you think?

 dmidecode.c |   22 ++++++++++++++++++++++
 dmidecode.h |    1 +
 dmioem.c    |    4 ++--
 3 files changed, 25 insertions(+), 2 deletions(-)

--- dmidecode.orig/dmidecode.h
+++ dmidecode/dmidecode.h
@@ -50,6 +50,7 @@ extern enum cpuid_type cpuid_type;
 int is_printable(const u8 *data, int len);
 const char *dmi_string(const struct dmi_header *dm, u8 s);
 void dmi_print_memory_size(const char *attr, u64 code, int shift);
+void dmi_print_storage_size(const char *attr, u64 code, unsigned int shift);
 void dmi_print_cpuid(void (*print_cb)(const char *name, const char *format, 
...),
                     const char *label, enum cpuid_type sig, const u8 *p);
 
--- dmidecode.orig/dmidecode.c
+++ dmidecode/dmidecode.c
@@ -317,6 +317,28 @@ void dmi_print_memory_size(const char *a
        pr_attr(attr, "%lu %s", capacity, unit[i + shift]);
 }
 
+/* shift is 0 if the value is in bytes, 1 if it is in kB, 2 if it is in MB */
+void dmi_print_storage_size(const char *attr, u64 code, unsigned int shift)
+{
+       u64 div;
+       static const char *unit[8] = {
+               "bytes", "kB", "MB", "GB", "TB", "PB", "EB", "ZB"
+       };
+
+       /*
+        * We want to choose the unit which will let us display a number
+        * between 1.0 and 999.9.
+        */
+       div = 1;
+       while (code / div >= 1000 && shift + 1 < ARRAY_SIZE(unit))
+       {
+               shift++;
+               div *= 1000;
+       }
+
+       pr_attr(attr, "%.1f %s", (float)code / div, unit[shift]);
+}
+
 /*
  * 7.1 BIOS Information (Type 0)
  */
--- dmidecode.orig/dmioem.c
+++ dmidecode/dmioem.c
@@ -1645,9 +1645,9 @@ static int dmi_decode_hp(const struct dm
                        dmi_hp_242_hdd_type(data[0x06]);
                        pr_attr("ID", "%llx", QWORD(data + 0x07));
                        if (h->length < 0x3E)
-                               pr_attr("Capacity", "%u MB", DWORD(data + 
0x0F));
+                               dmi_print_storage_size("Capacity", DWORD(data + 
0x0F), 2);
                        else
-                               dmi_print_memory_size("Capacity", QWORD(data + 
0x2C), 0);
+                               dmi_print_storage_size("Capacity", QWORD(data + 
0x2C), 0);
                        /* NB: Poweron low QWORD good for 2,104,351,365,926,255 
years */
                        pr_attr("Poweron", "%ld hours", QWORD(data + 0x13));
                        if (data[0x24])


-- 
Jean Delvare
SUSE L3 Support

Reply via email to