dmidecode-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [dmidecode] [PATCH v2 3/4] dmioem: Decode HPE OEM Record 203


From: Jerry Hoemann
Subject: Re: [dmidecode] [PATCH v2 3/4] dmioem: Decode HPE OEM Record 203
Date: Tue, 12 Jan 2021 11:35:44 -0700

On Tue, Jan 12, 2021 at 06:01:43PM +0100, Jean Delvare wrote:
> Hi Jerry,
> 
> Thanks for the updated patches. Here's my review:
> 
> On Tue, 12 Jan 2021 01:05:04 -0700, Jerry Hoemann wrote:
> > HP Device Correlation Record (Type 203)
> > 
> > Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
> > ---
> >  dmioem.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 180 insertions(+)
> > 
> > diff --git a/dmioem.c b/dmioem.c
> > index 4a7ff2b..2f38229 100644
> > --- a/dmioem.c
> > +++ b/dmioem.c
> > @@ -204,6 +204,106 @@ static void dmi_hp_240_attr(const char *fname, u64 
> > code)
> >     pr_attr(fname, "%s", attr);
> >  }
> >  
> > +static void dmi_hp_203_assoc_hndl(const char *fname, u16 num)
> > +{
> > +   char val[20];
> > +
> > +   if (opt.flags & FLAG_QUIET)
> > +           return;
> > +
> > +   if (num == 0xFFFE)
> > +           strcpy(val, "N/A");
> > +   else
> > +           sprintf(val, "0x%04X", num);
> > +   pr_attr(fname, "%s", val);
> 
> My preference (which would align this code with what is done elsewhere
> in dmidecode) would be:
> 
>       if (num == 0xFFFE)
>               pr_attr(fname, "N/A");
>       else
>               pr_attr(fname, "0x%04X", num);
> 
> This avoids the intermediate buffer and double printf.

Yes. This is better.  I will fix.

> 
> > +}
> > +
> > +static void dmi_hp_203_pciinfo(const char *fname, u16 num)
> > +{
> > +   char val[20];
> > +
> > +   if (num == 0xFFFF)
> > +           strcpy(val, "Device Not Present");
> > +   else
> > +           sprintf(val, "0x%04X", num);
> > +   pr_attr(fname, "%s", val);
> 
> Same idea here.

Ditto.

> 
> > +}
> > +
> > +static void dmi_hp_203_bayenc(const char *fname, u8 num)
> > +{
> > +   static char val[20];
> > +
> > +   switch (num) {
> > +   case 0x00:
> > +           strcpy(val, "Unknown");
> > +           break;
> > +   case 0xff:
> > +           strcpy(val, "Do Not Display");
> > +           break;
> > +   default:
> > +           sprintf(val, "0x%02X", num);
> > +   }
> > +   pr_attr(fname, "%s", val);
> 
> And here. BTW is it the common practice to use hexadecimal values to
> refer to enclosure numbers?

Good point.  Prior change + decimal for this one.


> 
> > +}
> > +
> > +static void dmi_hp_203_devtyp(const char *fname, unsigned int code)
> > +{
> > +   const char *str = "Reserved";
> > +   static const char * const type[] = {
> > +   /* 0x00 */ "Unknown",
> > +   /* 0x01 */ "Reserved",
> > +   /* 0x02 */ "Reserved",
> > +   /* 0x03 */ "Flexible LOM",
> > +   /* 0x04 */ "Embedded LOM",
> > +   /* 0x05 */ "NIC in a Slot",
> > +   /* 0x06 */ "Storage Controller",
> > +   /* 0x07 */ "Smart Array Storage Controller",
> > +   /* 0x08 */ "USB Hard Disk",
> > +   /* 0x09 */ "Other PCI Device",
> > +   /* 0x0A */ "RAM Disk",
> > +   /* 0x0B */ "Firmware Volume",
> > +   /* 0x0C */ "UEFI Shell",
> > +   /* 0x0D */ "Generic UEFI USB Boot Entry",
> > +   /* 0x0E */ "Dynamic Smart Array Controller",
> > +   /* 0x0F */ "File",
> > +   /* 0x10 */ "NVME Hard Drive",
> > +   /* 0x11 */ "NVDIMM"
> > +   };
> > +
> > +   if (code < ARRAY_SIZE(type))
> > +           str = type[code];
> > +
> > +   pr_attr(fname, "%s", str);
> > +}
> > +
> > +static void dmi_hp_203_devloc(const char *fname, unsigned int code)
> > +{
> > +   static const char *str = "Reserved";
> > +   static const char * const location[] = {
> > +   /* 0x00 */ "Unknown",
> > +   /* 0x01 */ "Embedded",
> > +   /* 0x02 */ "iLO Virtual Media",
> > +   /* 0x03 */ "Front USB Port",
> > +   /* 0x04 */ "Rear USB Port",
> > +   /* 0x05 */ "Internal USB",
> > +   /* 0x06 */ "Internal SD Card",
> > +   /* 0x07 */ "Internal Virutal USB (Embedded NAND)",
> > +   /* 0x08 */ "Embedded SATA Port",
> > +   /* 0x09 */ "Embedded Smart Array",
> > +   /* 0x0A */ "PCI Slot",
> > +   /* 0x0B */ "RAM Memory",
> > +   /* 0x0C */ "USB",
> > +   /* 0x0D */ "Dynamic Smart Array Controller",
> > +   /* 0x0E */ "URL",
> > +   /* 0x0F */ "NVMe Drive Bay",
> > +   };
> > +
> > +   if (code < ARRAY_SIZE(location))
> > +           str = location[code];
> > +
> > +   pr_attr(fname, "%s", str);
> > +}
> > +
> >  static int dmi_decode_hp(const struct dmi_header *h)
> >  {
> >     u8 *data = h->data;
> > @@ -218,6 +318,86 @@ static int dmi_decode_hp(const struct dmi_header *h)
> >  
> >     switch (h->type)
> >     {
> > +           case 203:
> > +                   /*
> > +                    * Vendor Specific: HP Device Correlation Record
> > +                    *
> > +                    * Offset |  Name        | Width | Description
> > +                    * -------------------------------------
> > +                    *  0x00  | Type         | BYTE  | 0xCB, Correlation 
> > Record
> > +                    *  0x01  | Length       | BYTE  | Length of structure
> > +                    *  0x02  | Handle       | WORD  | Unique handle
> > +                    *  0x04  | Assoc Device | WORD  | Handle of Associated 
> > Type 9 or Type 41 Record
> > +                    *  0x06  | Assoc SMBus  | WORD  | Handle of Associated 
> > Type 228 SMBus Segment Record
> > +                    *  0x08  | PCI Vendor ID| WORD  | PCI Vendor ID of 
> > device 0xFFFF -> not present.
> > +                    *  0x0A  | PCI Device ID| WORD  | PCI Device ID of 
> > device 0xFFFF -> not present.
> > +                    *  0x0C  | PCI SubVendor| WORD  | PCI Sub Vendor ID of 
> > device 0xFFFF -> not present.
> > +                    *  0x0E  | PCI SubDevice| WORD  | PCI Sub Device ID of 
> > device 0xFFFF -> not present.
> > +                    *  0x10  | Class Code   | BYTE  | PCI Class Code of 
> > Endpoint. 0xFF if device not present.
> > +                    *  0x11  | Class SubCode| BYTE  | PCI Sub Class Code 
> > of Endpoint. 0xFF if device not present.
> > +                    *  0x12  | Parent Handle| WORD  |
> > +                    *  0x14  | Flags        | WORD  |
> > +                    *  0x16  | Device Type  | BYTE  | UEFI only.
> > +                    *  0x17  | Device Loc   | BYTE  | Device Location.
> > +                    *  0x18  | Dev Instance | BYTE  | Device Instance
> > +                    *  0x19  | Sub Instance | BYTE  | NIC Port # or NVMe 
> > Drive Bay
> > +                    *  0x1A  | Bay          | BYTE  |
> > +                    *  0x1B  | Enclosure    | BYTE  |
> > +                    *  0x1C  | UEFI Dev Path| STRING| String number for 
> > UEFI Device Path
> > +                    *  0x1D  | Struct Name  | STRING| String number for 
> > UEFI Device Structured Name
> > +                    *  0x1E  | Device Name  | STRING| String number for 
> > UEFI Device Name
> > +                    *  0x1F  | UEFI Location| STRING| String number for 
> > UEFI Location
> > +                    *  0x20  | Assoc Handle | WORD  | Type 9 Handle.  
> > Defined if Flags[0] == 1.
> > +                    *  0x22  | Part Number  | STRING| PCI Device Part 
> > Number
> > +                    *  0x23  | Serial Number| STRING| PCI Device Serial 
> > Number
> > +                    *  0x24  | Seg Number   | WORD  | Segment Group 
> > number. 0 -> Single group topology
> > +                    *  0x26  | Bus Number   | BYTE  | PCI Device Bus Number
> > +                    *  0x27  | Func Number  | BTYE  | PCI Device and 
> > Function Number
> > +                    */
> > +                   if (gen < G9) break;
> > +                   if (h->length < 0x1F) break;
> > +                   pr_handle_name("%s HP Device Correlation Record", 
> > company);
> > +                   dmi_hp_203_assoc_hndl("Associated Device Record", 
> > WORD(data + 0x04));
> > +                   dmi_hp_203_assoc_hndl("Associated SMBus Record",  
> > WORD(data + 0x08));
> 
> I think you mean data + 0x06 here?

Good catch.  Will fix.


> 
> > +                   if (WORD(data + 0x08) == 0xffff && WORD(data + 0x0A) == 
> > 0xffff &&
> > +                       WORD(data + 0x0C) == 0xffff && WORD(data + 0x0E) == 
> > 0xffff &&
> > +                       data[0x10] == 0xFF && data[0x11] == 0xFF) {
> > +                           pr_attr("PCI Device Info", "%s", "Device Not 
> > Present");
> 
> You can skip the %s.

Will fix.

> 
> > +                   } else {
> > +                           dmi_hp_203_pciinfo("PCI Vendor ID", WORD(data + 
> > 0x08));
> > +                           dmi_hp_203_pciinfo("PCI Device ID", WORD(data + 
> > 0x0A));
> > +                           dmi_hp_203_pciinfo("PCI Sub Vendor ID", 
> > WORD(data + 0x0C));
> > +                           dmi_hp_203_pciinfo("PCI Sub Device ID", 
> > WORD(data + 0x0E));
> > +                           dmi_hp_203_pciinfo("PCI Class Code", 
> > (char)data[0x10]);
> > +                           dmi_hp_203_pciinfo("PCI Sub Class Code", 
> > (char)data[0x11]);
> 
> I took a quick look at the PCI spec out of curiosity. It turns our that
> PCI Class Code 0xFF is legal, it means "Device does not fit in any
> defined classes". Therefore you shouldn't special-case it.
> 
> I suppose the same holds for the PCI Sub Class Code, because its
> meaning depends on the Class Code, and while there is no class using
> 0xFF as a sub class today, there's also nothing preventing it from
> happening in the future.
> 
> So I think both should be printed with a straight pr_attr().

The documentation for the OEM 203 record states:
        PCI Class Code of Endpoint. 0xFF if device not present.
Similar statement for SubClass.

So while what you say above may be true in general for PCI [Sub] Class,
it doesn't appear to be how HPE firmware is handling this field.

> 
> > +                   }
> > +                   dmi_hp_203_assoc_hndl("Parent Handle", WORD(data + 
> > 0x12));
> > +                   pr_attr("Flags", "0x%04X", WORD(data + 0x14));
> > +                   dmi_hp_203_devtyp("Device Type", data[0x16]);
> > +                   dmi_hp_203_devloc("Device Location", data[0x17]);
> > +                   pr_attr("Device Instance", "0x%02X", data[0x18]);
> > +                   pr_attr("Device Sub-Instance", "0x%02X", data[0x19]);
> 
> Is hexadecimal appropriate/common to designate instance numbers?

I can change to decimal.

> 
> > +                   dmi_hp_203_bayenc("Bay", data[0x1A]);
> > +                   dmi_hp_203_bayenc("Enclosure", data[0x1B]);
> > +                   pr_attr("Device Path", "%s", dmi_string(h, data[0x1C]));
> > +                   pr_attr("Structured Name", "%s", dmi_string(h, 
> > data[0x1D]));
> > +                   pr_attr("Device Name", "%s", dmi_string(h, data[0x1E]));
> > +                   if (h->length < 0x24) break;
> 
> I think you said you would test for length < 0x22 too?

Yes, I think above is overly conservative and will not decode some fields
on some system.  I'll look into more.


> 
> > +                   pr_attr("UEFI Location", "%s", dmi_string(h, 
> > data[0x1F]));
> > +                   if (!(opt.flags & FLAG_QUIET)) {
> > +                           if (WORD(data + 0x14) & 1)
> > +                                   pr_attr("Associated Real/Phys Handle", 
> > "0x%04X", WORD(data + 0x20));
> > +                           else
> > +                                   pr_attr("Associated Real/Phys Handle", 
> > "N/A");
> > +                   }
> 
> > +                   pr_attr("PCI Part Number", "%s", dmi_string(h, 
> > data[0x22]));
> > +                   pr_attr("Serial Number", "%s", dmi_string(h, 
> > data[0x23]));
> > +                   if (h->length < 0x28) break;
> > +                   pr_attr("Segment Group Number", "0x%04X", WORD(data + 
> > 0x24));
> > +                   pr_attr("PCI Device", "%02X:%02X.%X",
> > +                                   data[0x26], data[0x27] >> 3, data[0x27] 
> > & 7);
> 
> Yes, that's what I had in mind. Except that I would use %x instead of %X
> so that lower-case letters are used, same as lspci is using (and also
> what we do in function dmi_print_hp_net_iface_rec).


Do you in general have a preference on the capitialization of hex numbers?
My prior submit was inconsistent, so I made version 2 of the patches to
use capital X for hex formatting which seems to be more prevalent in
other parts of dmidecode.

Or is PCI device like above an exception?


> 
> > +                   break;
> > +
> >             case 204:
> >                     /*
> >                      * Vendor Specific: HPE ProLiant System/Rack Locator
> 
> Thanks,
> -- 
> Jean Delvare
> SUSE L3 Support

-- 

-----------------------------------------------------------------------------
Jerry Hoemann                  Software Engineer   Hewlett Packard Enterprise
-----------------------------------------------------------------------------



reply via email to

[Prev in Thread] Current Thread [Next in Thread]