From 0f397ac0d9b04086c846637aafae2b01aa3ecbb7 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Wed, 26 Feb 2020 11:03:54 -0500 Subject: [PATCH] Support non-zero LUN Some sensors may have non-zero LUN. Support this behavior. Change-Id: Ibad7a1c378ef0ef5955fa81e3f110db0e8c42e90 --- pyghmi/ipmi/command.py | 15 ++++++++++----- pyghmi/ipmi/private/localsession.py | 3 ++- pyghmi/ipmi/private/session.py | 15 +++++++++------ pyghmi/ipmi/sdr.py | 1 + 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/pyghmi/ipmi/command.py b/pyghmi/ipmi/command.py index 00fe7460..5b3d43ca 100644 --- a/pyghmi/ipmi/command.py +++ b/pyghmi/ipmi/command.py @@ -425,7 +425,7 @@ class Command(object): return {'bootdev': bootdev} def xraw_command(self, netfn, command, bridge_request=(), data=(), - delay_xmit=None, retry=True, timeout=None): + delay_xmit=None, retry=True, timeout=None, lun=0): """Send raw ipmi command to BMC, raising exception on error This is identical to raw_command, except it raises exceptions @@ -448,7 +448,8 @@ class Command(object): rsp = self.ipmi_session.raw_command(netfn=netfn, command=command, bridge_request=bridge_request, data=data, delay_xmit=delay_xmit, - retry=retry, timeout=timeout) + retry=retry, timeout=timeout, + lun=lun) if 'error' in rsp: raise exc.IpmiException(rsp['error'], rsp['code']) rsp['data'] = buffer(rsp['data']) @@ -473,7 +474,7 @@ class Command(object): return self._oem.get_description() def raw_command(self, netfn, command, bridge_request=(), data=(), - delay_xmit=None, retry=True, timeout=None): + delay_xmit=None, retry=True, timeout=None, lun=0): """Send raw ipmi command to BMC This allows arbitrary IPMI bytes to be issued. This is commonly used @@ -494,7 +495,8 @@ class Command(object): rsp = self.ipmi_session.raw_command(netfn=netfn, command=command, bridge_request=bridge_request, data=data, delay_xmit=delay_xmit, - retry=retry, timeout=timeout) + retry=retry, timeout=timeout, + lun=lun) return rsp def get_power(self): @@ -740,7 +742,10 @@ class Command(object): self.init_sdr() for sensor in self._sdr.get_sensor_numbers(): if self._sdr.sensors[sensor].name == sensorname: - rsp = self.raw_command(command=0x2d, netfn=4, data=(sensor,)) + currsensor = self._sdr.sensors[sensor] + rsp = self.raw_command(command=0x2d, netfn=4, + lun=currsensor.sensor_lun, + data=(currsensor.sensor_number,)) if 'error' in rsp: raise exc.IpmiException(rsp['error'], rsp['code']) return self._sdr.sensors[sensor].decode_sensor_reading( diff --git a/pyghmi/ipmi/private/localsession.py b/pyghmi/ipmi/private/localsession.py index 7e23c4a8..dfa9be13 100644 --- a/pyghmi/ipmi/private/localsession.py +++ b/pyghmi/ipmi/private/localsession.py @@ -113,9 +113,10 @@ class Session(object): retry=True, delay_xmit=None, timeout=None, - waitall=False): + waitall=False, lun=0): self.addr.channel = CURRCHAN self.addr.addr_type = ADDRTYPE + self.addr.lun = lun self.req.addr_len = ctypes.sizeof(IpmiSystemInterfaceAddr) self.req.addr = ctypes.pointer(self.addr) self.req.msg.netfn = netfn diff --git a/pyghmi/ipmi/private/session.py b/pyghmi/ipmi/private/session.py index a29ca3e3..40dd5e1a 100644 --- a/pyghmi/ipmi/private/session.py +++ b/pyghmi/ipmi/private/session.py @@ -652,7 +652,8 @@ class Session(object): if self._lookup_request_entry(entry): self.request_entry.remove(entry) - def _make_ipmi_payload(self, netfn, command, bridge_request=None, data=()): + def _make_ipmi_payload(self, netfn, command, bridge_request=None, data=(), + lun=0): """This function generates the core ipmi payload that would be applicable for any channel (including KCS) @@ -690,7 +691,7 @@ class Session(object): # figure 13-4, first two bytes are rsaddr and # netfn, for non-bridge request, rsaddr is always 0x20 since we are # addressing BMC while rsaddr is specified forbridge request - header = bytearray((rsaddr, netfn << 2)) + header = bytearray((rsaddr, (netfn << 2) | lun)) reqbody = bytearray((rqaddr, self.seqlun, command)) + data headsum = bytearray((_checksum(*header),)) @@ -755,7 +756,8 @@ class Session(object): retry=True, delay_xmit=None, timeout=None, - callback=None): + callback=None, + lun=0): if not self.logged: if (self.logoutexpiry is not None and _monotonic_time() > self.logoutexpiry): @@ -773,7 +775,7 @@ class Session(object): self._send_ipmi_net_payload(netfn, command, data, bridge_request=bridge_request, retry=retry, delay_xmit=delay_xmit, - timeout=timeout) + timeout=timeout, lun=lun) if retry: # in retry case, let the retry timers indicate wait time timeout = None @@ -799,7 +801,8 @@ class Session(object): def _send_ipmi_net_payload(self, netfn=None, command=None, data=(), code=0, bridge_request=None, - retry=None, delay_xmit=None, timeout=None): + retry=None, delay_xmit=None, timeout=None, + lun=0): if retry is None: retry = not self.servermode if self.servermode: @@ -811,7 +814,7 @@ class Session(object): else: data = bytearray(data) ipmipayload = self._make_ipmi_payload(netfn, command, bridge_request, - data) + data, lun) payload_type = constants.payload_types['ipmi'] self.send_payload(payload=ipmipayload, payload_type=payload_type, retry=retry, delay_xmit=delay_xmit, timeout=timeout) diff --git a/pyghmi/ipmi/sdr.py b/pyghmi/ipmi/sdr.py index 7dd9fdb5..6e19d89d 100644 --- a/pyghmi/ipmi/sdr.py +++ b/pyghmi/ipmi/sdr.py @@ -349,6 +349,7 @@ class SDREntry(object): # event only, compact and full are very similar # this function handles the common aspects of compact and full # offsets from spec, minus 6 + self.sensor_lun = entry[1] self.sensor_number = entry[2] self.entity = ipmiconst.entity_ids.get( entry[3], 'Unknown entity {0}'.format(entry[3]))