From 2ab748f4cefd3eee4d07a9d7df0a4ab1b3189d3c Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Tue, 20 Apr 2021 11:01:03 -0400 Subject: [PATCH] Improve dense PSU support Add inventory for SMM managed PSUs Further, support sensors for the 9-PSU variants Change-Id: I17d4058926884925f3f19557982e87ffcf397946 --- pyghmi/ipmi/oem/lenovo/handler.py | 15 +++- pyghmi/ipmi/oem/lenovo/nextscale.py | 108 ++++++++++++++++++++++++---- 2 files changed, 107 insertions(+), 16 deletions(-) diff --git a/pyghmi/ipmi/oem/lenovo/handler.py b/pyghmi/ipmi/oem/lenovo/handler.py index 18a68a02..79291130 100755 --- a/pyghmi/ipmi/oem/lenovo/handler.py +++ b/pyghmi/ipmi/oem/lenovo/handler.py @@ -413,6 +413,8 @@ class OEMHandler(generic.OEMHandler): return iter(self.oem_inventory_info) elif self.has_imm: return self.immhandler.get_hw_descriptions() + elif self.is_fpc: + return self.smmhandler.get_inventory_descriptions(self.is_fpc) return () def get_oem_inventory(self): @@ -423,6 +425,11 @@ class OEMHandler(generic.OEMHandler): elif self.has_imm: for inv in self.immhandler.get_hw_inventory(): yield inv + elif self.is_fpc: + for compname in self.smmhandler.get_inventory_descriptions( + self.ipmicmd, self.is_fpc): + yield (compname, self.smmhandler.get_inventory_of_component( + self.ipmicmd, compname)) def get_sensor_data(self): if self.has_imm: @@ -430,7 +437,8 @@ class OEMHandler(generic.OEMHandler): yield self.immhandler.get_oem_sensor_reading(name, self.ipmicmd) elif self.is_fpc: - for name in nextscale.get_sensor_names(self._fpc_variant): + for name in nextscale.get_sensor_names(self.ipmicmd, + self._fpc_variant): yield nextscale.get_sensor_reading(name, self.ipmicmd, self._fpc_variant) @@ -438,7 +446,8 @@ class OEMHandler(generic.OEMHandler): if self.has_imm: return self.immhandler.get_oem_sensor_descriptions(self.ipmicmd) elif self.is_fpc: - return nextscale.get_sensor_descriptions(self._fpc_variant) + return nextscale.get_sensor_descriptions( + self.ipmicmd, self._fpc_variant) return () def get_sensor_reading(self, sensorname): @@ -456,6 +465,8 @@ class OEMHandler(generic.OEMHandler): return self.oem_inventory_info.get(component, None) if self.has_imm: return self.immhandler.get_component_inventory(component) + if self.is_fpc: + return self.smmhandler.get_inventory_of_component(component) def _collect_tsm_inventory(self): self.oem_inventory_info = {} diff --git a/pyghmi/ipmi/oem/lenovo/nextscale.py b/pyghmi/ipmi/oem/lenovo/nextscale.py index f7f64cbc..db1d570e 100644 --- a/pyghmi/ipmi/oem/lenovo/nextscale.py +++ b/pyghmi/ipmi/oem/lenovo/nextscale.py @@ -37,6 +37,24 @@ except NameError: pass +psutypes = { + 0x63: 'CFF v3 550W PT', + 0x64: 'CFF v3 750W PT', + 0x65: 'CFF v3 750W TT', + 0x66: 'CFF v3 1100W PT', + 0x67: 'CFF v3 1600W PT', + 0x68: 'CFF v3 2000W PT', + 0x6B: 'CFF v4 500W PT', + 0x6C: 'CFF v4 750W PT', + 0x6D: 'CFF v4 750W TT', + 0x6E: 'CFF v4 1100W PT', + 0x6F: 'CFF v4 1100W -48Vdc', + 0x70: 'CFF v4 1100W 200-277Vac/240-380Vdc', + 0x71: 'CFF v4 1800W PT', + 0x72: 'CFF v4 2400W PT', +} + + def fromstring(inputdata): if b'!entity' in inputdata.lower(): raise Exception('!ENTITY not supported in this interface') @@ -158,6 +176,18 @@ def fpc_read_powerbank(ipmicmd): return struct.unpack_from('= 100.0 return 'complete' + def get_inventory_descriptions(self, ipmicmd, variant): + psucount = get_psu_count(ipmicmd, variant) + for idx in range(psucount): + yield 'PSU {}'.format(idx + 1) + + def get_inventory_of_component(self, ipmicmd, component): + psuidx = int(component.replace('PSU ', '')) + return self.get_psu_info(ipmicmd, psuidx) + + def get_psu_info(self, ipmicmd, psunum): + psuinfo = ipmicmd.xraw_command(0x34, 0x6, data=(psunum,)) + psuinfo = bytearray(psuinfo['data']) + psutype = struct.unpack('