From a9c5f00f4630a2d08cca5010d1c6c03f35a27306 Mon Sep 17 00:00:00 2001 From: luyf5 Date: Mon, 13 Sep 2021 14:37:18 +0800 Subject: [PATCH] Support Kent Changes are from: https://gitlab.icelab.lenovo.com/pygcon/pyghmi/commit/d09e23fea99664859bf00f3eae80d8720992d68c#dade58c051d057633b161944993db070adc93aa0 collection of M4 and Kent support - 12032015 https://gitlab.icelab.lenovo.com/pygcon/pyghmi/commit/aa741a6c25a0a3c3b3cb1cafda3d36c2e811a16e fix the issue #1, #2, #8 in the review process https://gitlab.icelab.lenovo.com/pygcon/pyghmi/commit/2cf9bab8cee7f53f85b573149105436608d7036a Fix bug 50752 [Kent2U4N_SW][LXCA]LED State on Light Path section does not correspond the real state and bug 50756 [Kent2U4N_SW][LXCA]Event name on Alerts page is not correct . https://gitlab.icelab.lenovo.com/pygcon/pyghmi/commit/c11863bdc8c67797403c27d19c045b85ccdf226f Port fix in v111 to master Change-Id: I7220b90baeb10e13f8e658505a41b358694eb8ac --- pyghmi/ipmi/oem/lenovo/handler.py | 54 +++++++++++++++++++++++++------ pyghmi/ipmi/private/constants.py | 22 ++++++------- 2 files changed, 56 insertions(+), 20 deletions(-) diff --git a/pyghmi/ipmi/oem/lenovo/handler.py b/pyghmi/ipmi/oem/lenovo/handler.py index 5930a713..f04e2424 100755 --- a/pyghmi/ipmi/oem/lenovo/handler.py +++ b/pyghmi/ipmi/oem/lenovo/handler.py @@ -124,6 +124,13 @@ led_status = { 0xFF: "On" } +ami_leds = { + "BMC_HEARTBEAT": 0x00, + "BMC_UID": 0x01, + "SYSTEM_FAULT": 0x02, + "HDD_FAULT": 0x03 +} + asrock_leds = { "SYSTEM_EVENT": 0x00, "BMC_UID": 0x01, @@ -137,6 +144,11 @@ asrock_led_status = { 0x01: "On" } +ami_led_status = { + 0x00: "Off", + 0x01: "On" +} + led_status_default = "Blink" mac_format = '{0:02x}:{1:02x}:{2:02x}:{3:02x}:{4:02x}:{5:02x}' categorie_items = ["cpu", "dimm", "firmware", "bios_version"] @@ -304,7 +316,7 @@ class OEMHandler(generic.OEMHandler): return super(OEMHandler, self).reseat_bay(bay) def get_ntp_enabled(self): - if self.has_tsm or self.has_asrock: + if self.has_tsm or self.has_ami or self.has_asrock: ntpres = self.ipmicmd.xraw_command(netfn=0x32, command=0xa7) return ntpres['data'][0] == '\x01' elif self.is_fpc: @@ -314,7 +326,7 @@ class OEMHandler(generic.OEMHandler): return None def get_ntp_servers(self): - if self.has_tsm or self.has_asrock: + if self.has_tsm or self.has_ami or self.has_asrock: srvs = [] ntpres = self.ipmicmd.xraw_command(netfn=0x32, command=0xa7) srvs.append(ntpres['data'][1:129].rstrip('\x00')) @@ -327,7 +339,7 @@ class OEMHandler(generic.OEMHandler): return None def set_ntp_enabled(self, enabled): - if self.has_tsm or self.has_asrock: + if self.has_tsm or self.has_ami or self.has_asrock: if enabled: self.ipmicmd.xraw_command( netfn=0x32, command=0xa8, data=(3, 1), timeout=15) @@ -343,7 +355,7 @@ class OEMHandler(generic.OEMHandler): return None def set_ntp_server(self, server, index=0): - if self.has_tsm or self.has_asrock: + if self.has_tsm or self.has_ami or self.has_asrock: if not (0 <= index <= 1): raise pygexc.InvalidParameterValue("Index must be 0 or 1") cmddata = bytearray((1 + index, )) @@ -442,7 +454,7 @@ class OEMHandler(generic.OEMHandler): return False def get_oem_inventory_descriptions(self): - if self.has_tsm or self.has_asrock: + if self.has_tsm or self.has_ami or self.has_asrock: # Thinkserver with TSM if not self.oem_inventory_info: self._collect_tsm_inventory() @@ -454,7 +466,7 @@ class OEMHandler(generic.OEMHandler): return () def get_oem_inventory(self): - if self.has_tsm or self.has_asrock: + if self.has_tsm or self.has_ami or self.has_asrock: self._collect_tsm_inventory() for compname in self.oem_inventory_info: yield (compname, self.oem_inventory_info[compname]) @@ -496,7 +508,7 @@ class OEMHandler(generic.OEMHandler): return () def get_inventory_of_component(self, component): - if self.has_tsm or self.has_asrock: + if self.has_tsm or self.has_ami or self.has_asrock: self._collect_tsm_inventory() return self.oem_inventory_info.get(component, None) if self.has_imm: @@ -600,7 +612,11 @@ class OEMHandler(generic.OEMHandler): led_set_status = led_status asrock = self.has_asrock - if asrock: + if self.has_ami: + cmd = 0x05 + led_set = ami_leds + led_set_status = ami_led_status + elif asrock: cmd = 0x50 led_set = asrock_leds led_set_status = asrock_led_status @@ -755,8 +771,28 @@ class OEMHandler(generic.OEMHandler): self._hasimm = (rdata[1] & 1 == 1) or (rdata[1] & 16 == 16) return self._hasimm + @property + def has_ami(self): + """True if this particular server is AMI based lenovo server + + """ + if(self.oemid['manufacturer_id'] == 19046 + and self.oemid['product_id'] == 13616): + try: + rsp = self.ipmicmd.xraw_command(netfn=0x3a, command=0x80) + except pygexc.IpmiException as ie: + if ie.ipmicode == 193: + return False + raise + rdata = bytearray(rsp['data'][:]) + if rdata[0] in range(5): + return True + else: + return False + return False + def get_oem_firmware(self, bmcver, components): - if self.has_tsm or self.has_asrock: + if self.has_tsm or self.has_ami or self.has_asrock: command = firmware.get_categories()["firmware"] fw_cmd = self.get_cmd_type("firmware", command) rsp = self.ipmicmd.xraw_command(**fw_cmd) diff --git a/pyghmi/ipmi/private/constants.py b/pyghmi/ipmi/private/constants.py index 3244650f..9c0084d0 100644 --- a/pyghmi/ipmi/private/constants.py +++ b/pyghmi/ipmi/private/constants.py @@ -388,11 +388,11 @@ generic_type_offsets = { 'desc': 'Redundant', 'severity': const.Health.Ok, 'deassertion_desc': 'Redundant lost', - 'deassertion_severity': const.Health.Ok, + 'deassertion_severity': const.Health.Critical, }, 1: { 'desc': 'Not redundant', # redundancy lost - 'severity': const.Health.Warning, + 'severity': const.Health.Critical, 'deassertion_desc': 'Redundancy restored', 'deassertion_severity': const.Health.Ok, }, @@ -404,7 +404,7 @@ generic_type_offsets = { }, 3: { 'desc': 'Not redundant', # down to non redundant - 'severity': const.Health.Ok, + 'severity': const.Health.Warning, 'deassertion_desc': 'Redundancy restored', 'deassertion_severity': const.Health.Ok, }, @@ -603,7 +603,7 @@ sensor_type_offsets = { }, 8: { 'desc': 'Disabled', - 'severity': const.Health.Warning, + 'severity': const.Health.Ok, 'deassertion_desc': 'Enabled', 'deassertion_severity': const.Health.Ok, }, @@ -761,13 +761,13 @@ sensor_type_offsets = { }, 4: { 'desc': 'Device disabled', - 'severity': const.Health.Warning, + 'severity': const.Health.Ok, 'deassertion_desc': 'Device enabled', 'deassertion_severity': const.Health.Ok, }, 5: { 'desc': 'Correctable memory error logging limit reached', - 'severity': const.Health.Critical, + 'severity': const.Health.Warning, 'deassertion_desc': 'Correctable memory error logging restored', 'deassertion_severity': const.Health.Ok, }, @@ -905,7 +905,7 @@ sensor_type_offsets = { }, 4: { 'desc': 'Event log full', - 'severity': const.Health.Warning, + 'severity': const.Health.Ok, 'deassertion_desc': 'Event log no longer full', 'deassertion_severity': const.Health.Ok, }, @@ -963,7 +963,7 @@ sensor_type_offsets = { 0x13: { # critical interrupt 0: { 'desc': 'Front panel diagnostic interrupt', - 'severity': const.Health.Ok, + 'severity': const.Health.Critical, 'deassertion_desc': 'Front panel diagnostic interrupt deasserted', 'deassertion_severity': const.Health.Ok, }, @@ -1442,19 +1442,19 @@ sensor_type_offsets = { }, 0x1: { 'desc': 'Watchdog hard reset', - 'severity': const.Health.Failed, + 'severity': const.Health.Ok, 'deassertion_desc': 'Watchdog hard reset deasserted', 'deassertion_severity': const.Health.Ok, }, 0x2: { 'desc': 'Watchdog power down', - 'severity': const.Health.Failed, + 'severity': const.Health.Ok, 'deassertion_desc': 'Watchdog power down deasserted', 'deassertion_severity': const.Health.Ok, }, 0x3: { 'desc': 'Watchdog power cycle', - 'severity': const.Health.Failed, + 'severity': const.Health.Ok, 'deassertion_desc': 'Watchdog power cycle deasserted', 'deassertion_severity': const.Health.Ok, },