Example #1
0
    def setParamMode(self, channel, persistent, mode):
        """Set the Configuration Parameter "Mode" of an analog input channel.
            
        This method calls the SetParam function of the module and sets the
        Configuration Parameter "Mode".
        
        Args:
            channel: IO channel number. Must be in the range 0 ... 3
            persistent: Store parameter permanently if true
            mode: Operation Mode as LCAI4Mode integer value
        
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel value is out of range    
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' % type(channel))

        if not isinstance(persistent, bool):
            raise TypeError('Expected persistent as bool, got %s' %
                            type(persistent))

        if not isinstance(mode, int):
            raise TypeError('Expected mode as int, got %s' % type(mode))

        if (channel >= self.nrOfChannels):
            raise ValueError('Channel out of range')

        data = bytearray([mode])
        cmd = Cmd(self.com)
        return cmd.setParam(_LCAI4ParamAddress.MODE, channel, persistent, data)
Example #2
0
    def calibrateIo(self, channel, persistent):
        """Calibration of the analog output channels.
            
        This method calls the CalibIo function of the module which executes
            calibration of the analog output channels.
        
        Args:
            channel: IO channel number. Must be in the range 0 ... 3
            persistent: Store calibration parameter permanently if true
            
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel value is out of range
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' % type(channel))

        if not isinstance(persistent, bool):
            raise TypeError('Expected persistent as bool, got %s' %
                            type(persistent))

        if (channel >= self.nrOfChannels):
            raise ValueError('Channel out of range')

        cmd = Cmd(self.com)
        return cmd.calibrateIo(channel, 0, persistent)
Example #3
0
    def getIo(self, channel, value):
        """Get the value or state of an analog input channel.
            
        This method calls the GetIo function of the module and returns
        the value or of the analog input channel.
        
        Args:
            channel: IO channel number. Must be in the range 0 ... 3
            value: Value object. Must be either ValueVOS4, ValueVOS2,
                ValueCUS4 or ValueANU2
            
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel value is out of range
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' % type(channel))

        if not isinstance(value, (ValueANU2, ValueVOS2, ValueVOS4, ValueCUS4)):
            raise TypeError('Expected value as ValueANU2 or ValueVOS2, \
                ValueVOS4 or ValueCUS4 got %s' % type(value))

        if (channel >= self.nrOfChannels):
            raise ValueError('Channel out of range')

        cmd = Cmd(self.com)
        return cmd.getIo(channel, value)
Example #4
0
    def setParamCalDefault(self, channel, persistent):
        """Set the Configuration Parameter "Cal" of an analog input to the
            default value.
            
        This method calls the SetParam function of the module and sets
        the Configuration Parameter "Cal" to the default value.
        
        Args:
            channel: IO channel number. Must be in the range 0 ... 3
            persistent: Store parameter permanently if true
            
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel value is out of range
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' % type(channel))

        if not isinstance(persistent, bool):
            raise TypeError('Expected persistent as bool, got %s' %
                            type(persistent))

        if (channel >= self.nrOfChannels):
            raise ValueError('Channel out of range')

        cmd = Cmd(self.com)
        return cmd.setParamDefault(_LCAI4ParamAddress.CAL, channel, persistent)
    def getIo(self, channel, value):
        """Get the value or state of one digital output channel.
            
        This method calls the GetIo function of the module and returns
        the value or state of the digital output channel.
        
        Args:
            channel: IO channel number. Must be in the range 0 ... 3
            value: Digital value object of type ValueDI1.
            
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel value is out of range
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' %
                            (type(channel)))

        if not isinstance(value, ValueDI1):
            raise TypeError('Expected value as ValueDI1, got %s' %
                            (type(value)))

        if (channel >= self.nrOfChannels):
            raise ValueError('Channel out of range')

        cmd = Cmd(self.com)
        return cmd.getIo(channel, value)
Example #6
0
    def page_0e_fill(self, dat_defs, microcode):
        # dat_defs must include mode, buf_offset, data_len, sas_expander_id.
        # Pass in the entire microcode buffer because we need the length.
        download_microcode = \
        {
         "page_code" :(  0   , 1*8, 0x0e),
         "sub_id"    :(  1   , 1*8, 0x00),
         "page_len"  :(  2   , 2*8, 0),
         "gen_code"  :(  4   , 4*8, 0),
         "mode"      :(  8   , 1*8, 0),
        #"buf_id"    :( 11   , 1*8, 0),
         "firmware_image_id":((11,7), 4  , 1),
         "sas_expander_id"  :((11,3), 4  , 0),
         "buf_offset":( 12   , 4*8, 0),
         "image_len" :( 16   , 4*8, 0),
         "data_len"  :( 20   , 4*8, 0),
         "data"      :[ 24   , 0  , 0],
         }
        data_len = dat_defs["data_len"]
        buf_offset = dat_defs["buf_offset"]

        page0e = self.parse(self.readpage(0x0e))["data"]
        desc = page0e.descriptors.val[0]
        #TODO
        if buf_offset != desc.expected_offset.val:
            print "buf_offset =", buf_offset, " expected", desc.expected_offset.val
        if (dat_defs["firmware_image_id"] <<
                4) + dat_defs["sas_expander_id"] != desc.expected_id.val:
            print "id = 0x%x%x, expected 0x%.2x" % (
                dat_defs["firmware_image_id"], dat_defs["sas_expander_id"],
                desc.expected_id.val)
        if desc.status.val is not 0x01:
            print "status =", desc.status.val

        download_microcode["data"][1] = 8 * data_len
        padded_len = (data_len + 3) / 4 * 4
        dat = [0] * (24 + padded_len)
        #         Cmd.fill(dat,
        #                  download_microcode,
        #                  {
        #                   "sub_id"    : sub_id,
        #                   "page_len"  : len(dat) - 4,
        #                   "mode"      : mode,
        #                   "buf_id"    : buf_id,
        #                   "buf_offset": buf_offset,
        #                   "image_len" : len(microcode),
        #                   "data_len"  : data_len,
        #                   "data"      : microcode[buf_offset:buf_offset+data_len],
        #                   })
        more_defs = {
            "page_len": len(dat) - 4,
            "image_len": len(microcode),
            "data": microcode[buf_offset:buf_offset + data_len],
            "gen_code": page0e.gen.val,
        }
        more_defs.update(dat_defs)
        Cmd.fill(dat, download_microcode, more_defs)
        return dat
Example #7
0
    def page_0e_fill(self, dat_defs, microcode):
        # dat_defs must include mode, buf_offset, data_len, sas_expander_id.
        # Pass in the entire microcode buffer because we need the length.
        download_microcode = \
        {
         "page_code" :(  0   , 1*8, 0x0e),
         "sub_id"    :(  1   , 1*8, 0x00),
         "page_len"  :(  2   , 2*8, 0),
         "gen_code"  :(  4   , 4*8, 0),
         "mode"      :(  8   , 1*8, 0),
        #"buf_id"    :( 11   , 1*8, 0),
         "firmware_image_id":((11,7), 4  , 1),
         "sas_expander_id"  :((11,3), 4  , 0),
         "buf_offset":( 12   , 4*8, 0),
         "image_len" :( 16   , 4*8, 0),
         "data_len"  :( 20   , 4*8, 0),
         "data"      :[ 24   , 0  , 0],
         }
        data_len   = dat_defs["data_len"]
        buf_offset = dat_defs["buf_offset"]

        page0e = self.parse(self.readpage(0x0e))["data"]
        desc = page0e.descriptors.val[0]
        #TODO
        if buf_offset != desc.expected_offset.val:
            print "buf_offset =", buf_offset, " expected", desc.expected_offset.val
        if (dat_defs["firmware_image_id"]<<4)+dat_defs["sas_expander_id"] != desc.expected_id.val:
            print "id = 0x%x%x, expected 0x%.2x" % (dat_defs["firmware_image_id"], dat_defs["sas_expander_id"], desc.expected_id.val)
        if desc.status.val is not 0x01:
            print "status =", desc.status.val

        download_microcode["data"][1] = 8*data_len
        padded_len = (data_len+3) / 4 * 4
        dat = [0] * (24 + padded_len)
#         Cmd.fill(dat,
#                  download_microcode,
#                  {
#                   "sub_id"    : sub_id,
#                   "page_len"  : len(dat) - 4,
#                   "mode"      : mode,
#                   "buf_id"    : buf_id,
#                   "buf_offset": buf_offset,
#                   "image_len" : len(microcode),
#                   "data_len"  : data_len,
#                   "data"      : microcode[buf_offset:buf_offset+data_len],
#                   })
        more_defs = {
            "page_len"  : len(dat) - 4,
            "image_len" : len(microcode),
            "data"      : microcode[buf_offset:buf_offset+data_len],
            "gen_code"  : page0e.gen.val,
            }
        more_defs.update(dat_defs)
        Cmd.fill(
            dat,
            download_microcode,
            more_defs)
        return dat
Example #8
0
    def parse_ex(self, data, expandernum):
        report_phy_status_head = \
        (
         (  0   , 1*8, "int", "pc"         , "PAGE CODE"),
         (  2   , 2*8, "int", "length"     , "PAGE LENGTH"),
         )
        phy_status_descriptor = \
        (
         (  0   , 1*8, "int", "phyid"            , "PHY ID"),
         (  1   , 1*8, "int", "linkrate"         , "Negotiated Physical Link Rate"),
         (  4   , 4*8, "int", "rxerrors"         , "SAS2 Rx Error Count"),
         (  8   , 4*8, "int", "invaliddwords"    , "Invalid Dword Count"),
         ( 12   , 4*8, "int", "disparityerrors"  , "Disparity Error Count"),
         ( 16   , 4*8, "int", "lossdwordsynchs"  , "Loss of Dword Synchronization Count"),
         ( 20   , 4*8, "int", "resetsfailed"     , "PHY Reset Failed Count"),
         ( 24   , 4*8, "int", "codeviolations"   , "Code Violation Error Count"),
         ( 28   , 2*8, "int", "prbserrors"       , "PRBS Error Count"),
         ( 30   , 2*8, "int", "testpatternerrors", "Test Pattern Error Count"),
         ( 32   , 2*8, "int", "crcerrors"        , "CRC Error Count"),
         ( 34   , 2*8, "int", "iccrcerrors"      , "In-connection CRC Error Count"),
         ( 36   , 1*8, "int", "phychanges"       , "PHY Change Count Register"),
         ( 37   , 1*8, "int", "ssplmonitor1"     , "SSPL Monitor 1"),
         ( 38   , 1*8, "int", "ssplmonitor2"     , "SSPL Monitor 2"),
         ( 40   , 4*8, "int", "connectstatus"    , "SSPL Connection Status"),
         ( 44   , 4*8, "int", "interruptstatus"  , "SLICE_TOP:SSPL - Interrupt Status 0"),
         )
        negotiated_physical_link_rate = \
        {
         0x00:("UNKNOWN", "PHY is enabled: unknown physical link rate*"),
         0x01:("DISABLE", "PHY is disabled"),
         0x02:("PHY_RESET_PROBLEM", "PHY is enabled; the PHY obtained dword synchronization for at least one physical link rate during the SAS speed negotiation sequence, but the SAS speed negotiation sequence failed. These failures may be Logged in the SMP REPORT PHY ERROR LOG function and/or the Protocol-Specific Port Log page."),
         0x03:("SPINUP_HOLD", "PHY is enabled; detected a SATA device and entered the SATA spinup hold state. The LINK RESET and HARD RESET operations in the SMP PHY CONTROL function may be used to release the PHY. This field shall be updated to this value at SATA spinup hold time if SATA spinup hold is supported."),
         0x04:("PORT_SELECTOR", "PHY is enabled; detected a SATA port selector. The physical link rate has not been negotiated since the last time the phy's SP state machine entered the SP0:OOB_COMINIT state. The SATA spinup hold state has not been entered since the last time the phy's SP state machine entered the SP0:OOB_COMINIT state. The value in this field may change to 3h, 8h, or 9h if attached to the active PHY of the SATA port selector. Presence of a SATA port selector is indicated by the ATTACHED SATA PORT SELECTOR bit."),
         0x08:("G1", "PHY is enabled; 1.5 Gbps physical link rate. This field shall be updated to this value after the speed negotiation sequence completes."),
         0x09:("G2", "PHY is enabled; 3.0 Gbps physical link rate. This field shall be updated to 9h after the speed negotiation sequence completes."),
         0x0a:("G3", "PHY is enabled; 6.0 Gbps physical link rate. This field shall be updated to ah after the speed negotiation sequence completes."),
         0x0b:("G4", "PHY is enabled; 12.0 Gbps physical link rate. This field shall be updated to bh after the speed negotiation sequence completes."),
         }

        bo = 0  # byte offset
        head = Cmd.extract(data[bo:], report_phy_status_head, bo)
        bo += 4

        descriptors = []
        while bo < 2 + head.length.val:
            descriptors.append(
                Cmd.extract(data[bo:], phy_status_descriptor, bo))
            bo += 48

        head.append(
            Cmd.Field(descriptors, 4, "descriptors",
                      "PHY Status Descriptor List"), "descriptors")
        head.append(
            Cmd.Field(expandernum, -1, "expandernum", "Expander Number"),
            "expandernum")
        return head
Example #9
0
    def getParamMode(self, channel, mode):
        """Get the Configuration Parameter "Mode" of the digital input
            channel.
            
        This method calls the GetParam function of the module and returns
            the Configuration Parameter "Mode".
          
        Args:
            channel: IO channel number. Must be in the range 0 ... 3
            mode: Operation Mode as a list with one LCDI4Mode integer value
            
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel value is out of range
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' % type(channel))

        if not isinstance(mode, list):
            raise TypeError('Expected mode as list, got %s' % type(mode))
        
        if len(mode) < 1:
            raise TypeError('Expected mode as list with 1 int, got %d' %
                len(mode))
        
        if not isinstance(mode[0], int):
            raise TypeError('Expected mode[0] as int, got %s' % type(mode[0]))

        if (channel >= self.nrOfChannels):
            raise ValueError('Channel out of range')     

        data = bytearray()
        cmd = Cmd(self.com)
        ret = cmd.getParam(_LCDI4ParamAddress.MODE, channel, data)

        if ret == IoReturn.IoReturn.IO_RETURN_OK:
            if data[0] == LCDI4Mode.INACTIVE:
                mode[0] = LCDI4Mode.INACTIVE
            elif data[0] == LCDI4Mode.REFLECT_VALUE:
                mode[0] = LCDI4Mode.REFLECT_VALUE
            elif data[0] == LCDI4Mode.RISING_EDGE:
                mode[0] = LCDI4Mode.RISING_EDGE
            elif data[0] == LCDI4Mode.FALLING_EDGE:
                mode[0] = LCDI4Mode.FALLING_EDGE
            elif data[0] == LCDI4Mode.COUNT:
                mode[0] = LCDI4Mode.COUNT
            else:
                mode[0] = LCDI4Mode.INACTIVE

        return ret
    def identify(self, options):

        if not isinstance(options, int):
            raise TypeError('Expected options as int, got %s' % type(options))

        if options > 0xFF:
            raise ValueError('Options out of range')

        self.id = LucidControlId()
        cmd = Cmd(self.com)
        return cmd.identify(options, self.id)
Example #11
0
    def parse_0e(self, data):
        download_microcode_head = \
        (
         (  0   , 1*8, "int", "pc"         , "page code"),
         (  1   , 1*8, "int", "secondaries", "number of secondary subenclosures"),
         (  2   , 2*8, "int", "length"     , "pagelength"),
         (  4   , 4*8, "int", "gen"        , "generation code"),
         (  8   , 0  , "str", "descriptors", "additional element descriptor list"),
         )
        descriptor_format = \
        (
         (  1   , 1*8, "int", "subid"            , "subenclosure identifier"),
         (  2   , 1*8, "int", "status"           , "subenclosure download microcode status"),
         (  3   , 1*8, "int", "additional_status", "subenclosure download microcode additional status"),
         (  4   , 4*8, "int", "maxsize"          , "subenclosure download microcode maximum size"),
         ( 11   , 1*8, "int", "expected_id"      , "subenclosure download microcode exected buffer id"),
         ( 12   , 4*8, "int", "expected_offset"  , "subenclosure download microcode expected buffer offset"),
         )
        status_text = \
        { # ses3r06.pdf table 52
         # Codes indicating interim status
         0x00: "No download microcode operation in progress.",
         0x01: "Download microcode operation in progress. The enclosure services process has received one or more Download Microcode Control diagnostic pages and is awaiting additional microcode data.",
         0x02: "Download microcode operation data transfer complete, currently updating non-volatile storage",
         0x03: "The enclosure services process is currently updating non-volatile storage with deferred microcode",
         # Codes indicating completion with no errors
         0x10: "Download microcode operation complete with no error. The enclosure services process begins using the new microcode after returning this status.",
         0x11: "Download microcode operation complete with no error. The enclosure services process (e.g., a standalone enclosure services process) begins using the new microcode after the next hard reset or power on.",
         0x12: "Download microcode operation complete with no error. The enclosure services process (e.g., an attached enclosure services process) begins using the new microcode after the next power on.",
         0x13: "Download microcode operation complete with no error. The enclosure services process (e.g., an attached enclosure services process) begins using the new microcode after: a) processing a Download Microcode Control diagnostic page specifying the active deferred microcode mode; b) hard reset; or c) power on.",
         # Codes indicating completion with errors
         0x80: "Error in one or more of the Download Microcode Control diagnostic page fields, new microcode discarded. The SUBENCLOSURE DOWNLOAD MICROCODE ADDITIONAL STATUS field shall be set to the offset of the lowest byte of the field in the Download Microcode Control diagnostic page that is in error.",
         0x81: "Microcode image error (e.g., a problem detected from a vendor specific check of the microcode image such as a checksum), new microcode discarded",
         0x82: "Download microcode timeout, new microcode discarded. The enclosure services process may discard microcode data after a vendor specific amount of time if it does not receive the entire microcode image.",
         0x83: "Internal error in the download microcode operation; new microcode image is needed before a hard reset or power on (e.g., a flash ROM write failed and no backup ROM image is available).",
         0x84: "Internal error in the download microcode operation; hard reset and power on safe (e.g., the enclosure services process will use a backup ROM image on hard reset or power on).",
         0x85: "Processed a Download Microcode Control diagnostic page with the DOWNLOAD MICROCODE MODE field set to 0Fh (i.e., activate deferred microcode) when there is no deferred microcode.",
         }

        bo = 0  # byte offset
        head = Cmd.extract(data[bo:], download_microcode_head, bo)
        bo += 8

        descriptors = []
        for encidx in range(1 + head.secondaries.val):  # @UnusedVariable
            descriptor = Cmd.extract(data[bo:], descriptor_format, bo)
            bo += 16
            descriptor.append(
                Cmd.Field(status_text[descriptor.status.val], -1,
                          "status_text", "status meaning"), "status_text")
            descriptors.append(descriptor)

        head.descriptors.val = descriptors
        return head
Example #12
0
    def parse_0e(self, data):
        download_microcode_head = \
        (
         (  0   , 1*8, "int", "pc"         , "page code"),
         (  1   , 1*8, "int", "secondaries", "number of secondary subenclosures"),
         (  2   , 2*8, "int", "length"     , "pagelength"),
         (  4   , 4*8, "int", "gen"        , "generation code"),
         (  8   , 0  , "str", "descriptors", "additional element descriptor list"),
         )
        descriptor_format = \
        (
         (  1   , 1*8, "int", "subid"            , "subenclosure identifier"),
         (  2   , 1*8, "int", "status"           , "subenclosure download microcode status"),
         (  3   , 1*8, "int", "additional_status", "subenclosure download microcode additional status"),
         (  4   , 4*8, "int", "maxsize"          , "subenclosure download microcode maximum size"),
         ( 11   , 1*8, "int", "expected_id"      , "subenclosure download microcode exected buffer id"),
         ( 12   , 4*8, "int", "expected_offset"  , "subenclosure download microcode expected buffer offset"),
         )
        status_text = \
        { # ses3r06.pdf table 52
         # Codes indicating interim status
         0x00: "No download microcode operation in progress.",
         0x01: "Download microcode operation in progress. The enclosure services process has received one or more Download Microcode Control diagnostic pages and is awaiting additional microcode data.",
         0x02: "Download microcode operation data transfer complete, currently updating non-volatile storage",
         0x03: "The enclosure services process is currently updating non-volatile storage with deferred microcode",
         # Codes indicating completion with no errors
         0x10: "Download microcode operation complete with no error. The enclosure services process begins using the new microcode after returning this status.",
         0x11: "Download microcode operation complete with no error. The enclosure services process (e.g., a standalone enclosure services process) begins using the new microcode after the next hard reset or power on.",
         0x12: "Download microcode operation complete with no error. The enclosure services process (e.g., an attached enclosure services process) begins using the new microcode after the next power on.",
         0x13: "Download microcode operation complete with no error. The enclosure services process (e.g., an attached enclosure services process) begins using the new microcode after: a) processing a Download Microcode Control diagnostic page specifying the active deferred microcode mode; b) hard reset; or c) power on.",
         # Codes indicating completion with errors
         0x80: "Error in one or more of the Download Microcode Control diagnostic page fields, new microcode discarded. The SUBENCLOSURE DOWNLOAD MICROCODE ADDITIONAL STATUS field shall be set to the offset of the lowest byte of the field in the Download Microcode Control diagnostic page that is in error.",
         0x81: "Microcode image error (e.g., a problem detected from a vendor specific check of the microcode image such as a checksum), new microcode discarded",
         0x82: "Download microcode timeout, new microcode discarded. The enclosure services process may discard microcode data after a vendor specific amount of time if it does not receive the entire microcode image.",
         0x83: "Internal error in the download microcode operation; new microcode image is needed before a hard reset or power on (e.g., a flash ROM write failed and no backup ROM image is available).",
         0x84: "Internal error in the download microcode operation; hard reset and power on safe (e.g., the enclosure services process will use a backup ROM image on hard reset or power on).",
         0x85: "Processed a Download Microcode Control diagnostic page with the DOWNLOAD MICROCODE MODE field set to 0Fh (i.e., activate deferred microcode) when there is no deferred microcode.",
         }

        bo = 0  # byte offset
        head = Cmd.extract(data[bo:], download_microcode_head, bo)
        bo += 8

        descriptors = []
        for encidx in range(1+head.secondaries.val):  # @UnusedVariable
            descriptor = Cmd.extract(data[bo:], descriptor_format, bo)
            bo += 16
            descriptor.append(Cmd.Field(status_text[descriptor.status.val], -1, "status_text", "status meaning"), "status_text")
            descriptors.append(descriptor)

        head.descriptors.val = descriptors
        return head
Example #13
0
    def parse_07(self, data):
        element_descriptor_head = \
        (
         (  0   , 1*8, "int", "pc"        , "page code"),
         (  2   , 2*8, "int", "length"    , "pagelength"),
         (  4   , 4*8, "int", "gen"       , "generation code"),
         (  8   , 0  , "str", "enclosures", "enclosure descriptor list"),
         )
        descriptor_head = \
        (
         (  0   , 2*8, "str", None    , "reserved"),
         (  2   , 2*8, "int", "length", "descriptor length"),
         )
        # This must be lists instead of tuples so we can modify the length.
        descriptor_text = \
        [
         [  0   , 0*8, "str", "text", "type descriptor text"],
         ]

        if not self.page01:
            # We need the information from SES page 0x01 before we can
            # parse this page.
            return None

        bo = 0  # byte offset
        head = Cmd.extract(data[bo:], element_descriptor_head, bo)
        bo += 8

        enclosures07 = []
        for enclosure01 in self.page01.enclosures.val:
            typelist07 = []
            for typedef01 in enclosure01.typedesc.val:
                ellist07 = []
                for elnum in range(1 +
                                   typedef01.possible.val):  # @UnusedVariable
                    length = Cmd.extract(data[bo:], descriptor_head,
                                         bo).length.val
                    bo += 4
                    descriptor_text[0][1] = length * 8
                    ellist07.append(Cmd.extract(data[bo:], descriptor_text,
                                                bo))
                    bo += length
                typelist07.append({
                    "type": typedef01.type.val,
                    "text": typedef01.text.val,
                    "elements": ellist07,
                })
            enclosures07.append(typelist07)
        head.enclosures = Cmd.Field(enclosures07, 8, "enclosures",
                                    "list of enclosures")
        return head
        pass
Example #14
0
    def getIoGroup(self, channels, values):
        """Get the values of a group of analog input channels.
            
        This method calls the GetIoGroup function of the module and
            returns the values of a group of analog input channels.
        
        Args:
            channels: Tuple with 4 boolean values (one for each channel).
                A channel is only read if the corresponding channel is
                true.
            values: Value objects
                A tuple with 4 value objects. The value objects must be
                either ValueVOS4, ValueVOS2, ValueCUS4 or ValueANU2.
                The function fills the objects with read data.
            
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel value is out of range
        """
        if not isinstance(channels, tuple):
            raise TypeError('Expected channels as a tuple with 4 channels \
                (bools), got %s' % type(channels))

        if (len(channels) < 4):
            raise TypeError('Expected 4 channels, got %d' % len(channels))

        for x in range(4):
            if not isinstance(channels[x], int):
                raise TypeError('Expected channel as bool, got %s' %
                                type(channels[x]))

        if not isinstance(values, tuple):
            raise TypeError(
                'Expected values as a tuple with 4 values, got %s' %
                type(values))

        if (len(values) < 4):
            raise TypeError('Expected 4 values, got %d' % len(values))

        for x in range(4):
            if not isinstance(values[x],
                              (ValueANU2, ValueVOS2, ValueVOS4, ValueCUS4)):
                raise TypeError('Expected value as ValueANU2 or ValueVOS2, \
                    ValueVOS4 or ValueCUS4 got %s' % type(values[x]))

        cmd = Cmd(self.com)
        return cmd.getIoGroup(channels, values)
Example #15
0
    def parse_05(self, data):
        """
        return a ListDict of Fields, including "enclosures": list of enclosures
        an enclosure is a dictionary with "subid": enclosure number and "types": list of types
        a type is a dictionary with "type": element type and "elements": list of status elements, starting with the overall status element
        a status element is a list of Fields
        """
        threshold_in = \
        (
         (  0   , 1*8, "int", "pc"        , "page code"),
         (( 1,4), 1  , "int", "invop"     , "invalid operation requested"),
         (  2   , 2*8, "int", "length"    , "pagelength"),
         (  4   , 4*8, "int", "gen"       , "generation code"),
         (  8   , 0  , "str", "enclosures", "enclosure descriptor list"),
         )
        threshold_descriptor = \
        (
         (  0   , 1*8, "int", "hicrit", "high critical threshold"),
         (  1   , 1*8, "int", "hiwarn", "high warning threshold"),
         (  2   , 1*8, "int", "lowarn", "low warning threshold"),
         (  3   , 1*8, "int", "locrit", "low critical threshold"),
         )

        if not self.page01:
            # We need the information from SES page 0x01 before we can
            # parse this page.
            return None

        bo = 0  # byte offset
        head = Cmd.extract(data[bo:], threshold_in, bo)
        bo += 8

        enclosures05 = []
        for enclosure01 in self.page01.enclosures.val:
            typelist05 = []
            for typedef01 in enclosure01.typedesc.val:
                ellist05 = []
                for elnum in range(1 +
                                   typedef01.possible.val):  # @UnusedVariable
                    ellist05.append(
                        Cmd.extract(data[bo:], threshold_descriptor, bo))
                    bo += 4
                typelist05.append({
                    "type": typedef01.type.val,
                    "text": typedef01.text.val,
                    "elements": ellist05,
                })
            enclosures05.append(typelist05)
        head.enclosures = Cmd.Field(enclosures05, 8, "enclosures",
                                    "list of enclosures")
        return head
Example #16
0
    def parse_ex(self, data, expandernum):
        report_phy_status_head = \
        (
         (  0   , 1*8, "int", "pc"         , "PAGE CODE"),
         (  2   , 2*8, "int", "length"     , "PAGE LENGTH"),
         )
        phy_status_descriptor = \
        (
         (  0   , 1*8, "int", "phyid"            , "PHY ID"),
         (  1   , 1*8, "int", "linkrate"         , "Negotiated Physical Link Rate"),
         (  4   , 4*8, "int", "rxerrors"         , "SAS2 Rx Error Count"),
         (  8   , 4*8, "int", "invaliddwords"    , "Invalid Dword Count"),
         ( 12   , 4*8, "int", "disparityerrors"  , "Disparity Error Count"),
         ( 16   , 4*8, "int", "lossdwordsynchs"  , "Loss of Dword Synchronization Count"),
         ( 20   , 4*8, "int", "resetsfailed"     , "PHY Reset Failed Count"),
         ( 24   , 4*8, "int", "codeviolations"   , "Code Violation Error Count"),
         ( 28   , 2*8, "int", "prbserrors"       , "PRBS Error Count"),
         ( 30   , 2*8, "int", "testpatternerrors", "Test Pattern Error Count"),
         ( 32   , 2*8, "int", "crcerrors"        , "CRC Error Count"),
         ( 34   , 2*8, "int", "iccrcerrors"      , "In-connection CRC Error Count"),
         ( 36   , 1*8, "int", "phychanges"       , "PHY Change Count Register"),
         ( 37   , 1*8, "int", "ssplmonitor1"     , "SSPL Monitor 1"),
         ( 38   , 1*8, "int", "ssplmonitor2"     , "SSPL Monitor 2"),
         ( 40   , 4*8, "int", "connectstatus"    , "SSPL Connection Status"),
         ( 44   , 4*8, "int", "interruptstatus"  , "SLICE_TOP:SSPL - Interrupt Status 0"),
         )
        negotiated_physical_link_rate = \
        {
         0x00:("UNKNOWN", "PHY is enabled: unknown physical link rate*"),
         0x01:("DISABLE", "PHY is disabled"),
         0x02:("PHY_RESET_PROBLEM", "PHY is enabled; the PHY obtained dword synchronization for at least one physical link rate during the SAS speed negotiation sequence, but the SAS speed negotiation sequence failed. These failures may be Logged in the SMP REPORT PHY ERROR LOG function and/or the Protocol-Specific Port Log page."),
         0x03:("SPINUP_HOLD", "PHY is enabled; detected a SATA device and entered the SATA spinup hold state. The LINK RESET and HARD RESET operations in the SMP PHY CONTROL function may be used to release the PHY. This field shall be updated to this value at SATA spinup hold time if SATA spinup hold is supported."),
         0x04:("PORT_SELECTOR", "PHY is enabled; detected a SATA port selector. The physical link rate has not been negotiated since the last time the phy's SP state machine entered the SP0:OOB_COMINIT state. The SATA spinup hold state has not been entered since the last time the phy's SP state machine entered the SP0:OOB_COMINIT state. The value in this field may change to 3h, 8h, or 9h if attached to the active PHY of the SATA port selector. Presence of a SATA port selector is indicated by the ATTACHED SATA PORT SELECTOR bit."),
         0x08:("G1", "PHY is enabled; 1.5 Gbps physical link rate. This field shall be updated to this value after the speed negotiation sequence completes."),
         0x09:("G2", "PHY is enabled; 3.0 Gbps physical link rate. This field shall be updated to 9h after the speed negotiation sequence completes."),
         0x0a:("G3", "PHY is enabled; 6.0 Gbps physical link rate. This field shall be updated to ah after the speed negotiation sequence completes."),
         0x0b:("G4", "PHY is enabled; 12.0 Gbps physical link rate. This field shall be updated to bh after the speed negotiation sequence completes."),
         }

        bo = 0  # byte offset
        head = Cmd.extract(data[bo:], report_phy_status_head, bo)
        bo += 4

        descriptors = []
        while bo < 2+head.length.val:
            descriptors.append(Cmd.extract(data[bo:], phy_status_descriptor, bo))
            bo += 48

        head.append(Cmd.Field(descriptors, 4, "descriptors", "PHY Status Descriptor List"), "descriptors")
        head.append(Cmd.Field(expandernum, -1, "expandernum", "Expander Number"), "expandernum")
        return head
Example #17
0
 def getParamCountTime(self, channel, countTime):
     """Get the Configuration Parameter "Count Time" of the digital input
         channel.
         
     This method calls the GetParam function of the module and returns
         the Configuration Parameter "Count Time".
       
     Args:
         channel: IO channel number. Must be in the range 0 ... 3
         countTime: Parameter "Count Time" as a list containing one
             integer value in microseconds
         
     Returns:
         IO_RETURN_OK in case of success, otherwise detailed IoReturn
         error code.
     
     Raises:
         TypeError: Passed argument types are wrong
         ValueError: Channel value is out of range
     """        
     if not isinstance(channel, int):
         raise TypeError('Expected channel as int, got %s' % 
             type(channel))
         
     if not isinstance(countTime, list):
         raise TypeError('Expected countTime as list, got %s' %
             type(countTime))
     
     if len(countTime) < 1:
         raise TypeError('Expected countTime as list with 1 int, got %d' %
             len(countTime))
     
     if not isinstance(countTime[0], int):
         raise TypeError('Expected countTime[0] as int, got %s' %
             type(countTime[0]))
         
     if (channel >= self.nrOfChannels):
         raise ValueError('Channel out of range')     
     
     data = bytearray()
     cmd = Cmd(self.com)
     ret = cmd.getParam(_LCDI4ParamAddress.COUNT_TIME, channel, data)
 
     if ret == IoReturn.IoReturn.IO_RETURN_OK:
         countTime[0] = struct.unpack("<I", buffer(data))[0]
     else:
         countTime[0] = 0
         
     return ret
    def getParamFlagCanRetrigger(self, channel, canRetrigger):
        """Get the Configuration Parameter Flag "Can Retrigger".
        
        This method calls the GetParam function of the module and
        returns the Configuration Flag "Can Retrigger".
        
        Args:
            channel: IO channel number. Must be in the range 0 ... 3
            canRetrigger: Parameter Flag "Can Retrigger" as a list containing
                one boolean value
                
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel value is out of range
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' %
                            (type(channel)))

        if not isinstance(canRetrigger, list):
            raise TypeError('Expected canRetrigger as list, got %s' %
                            type(canRetrigger))

        if len(canRetrigger) < 1:
            raise TypeError(
                'Expected canRetrigger as list with 1 bool, got %d' %
                len(canRetrigger))

        if not isinstance(canRetrigger[0], int):
            raise TypeError('Expected canRetrigger[0] as bool, got %s' %
                            type(canRetrigger[0]))

        if (channel >= self.nrOfChannels):
            raise ValueError('Channel out of range')

        data = bytearray()
        cmd = Cmd(self.com)
        ret = cmd.getParam(_LCDO4ParamAddress.FLAGS, channel, data)

        if ret == IoReturn.IoReturn.IO_RETURN_OK:
            if data[0] & _LCDO4Flag.CAN_RETRIGGER:
                canRetrigger[0] = True
            else:
                canRetrigger[0] = False
        return ret
    def setIoGroup(self, channels, values):
        """Write values or states of a group of output channels.
        
        This method calls the SetIoGroup function of the module and
            writes the values or states of a group of output channels.
            
        Args:
            channels: Tuple with 4 boolean values (one for each channel).
                A channel is only written if the corresponding channel is
                true.
            values: Digital values.
                A tuple with 4 digital value objects. The values of the
                objects are written to the output channels.
            
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel value is out of range
        """
        if not isinstance(channels, tuple):
            raise TypeError('Expected channels as tuple with 4 channels \
                (bools), got %s' % (type(channels)))

        if (len(channels) < 4):
            raise TypeError('Expected 4 channels, got %d' % (len(channels)))

        for x in range(4):
            if not isinstance(channels[x], int):
                raise TypeError('Expected channel as bool, got %s' %
                                (type(channels[x])))

        if not isinstance(values, tuple):
            raise TypeError('Expected values as tuple with 4 values, got %s' %
                            (type(values)))

        if (len(values) < 4):
            raise TypeError('Expected 4 values, got %d' % (len(values)))

        for x in range(4):
            if not isinstance(values[x], ValueDI1):
                raise TypeError('Expected values as ValueDI1, got %s' %
                                (type(values[x])))

        cmd = Cmd(self.com)
        return cmd.setIoGroup(channels, values)
Example #20
0
    def parse_05(self, data):
        """
        return a ListDict of Fields, including "enclosures": list of enclosures
        an enclosure is a dictionary with "subid": enclosure number and "types": list of types
        a type is a dictionary with "type": element type and "elements": list of status elements, starting with the overall status element
        a status element is a list of Fields
        """
        threshold_in = \
        (
         (  0   , 1*8, "int", "pc"        , "page code"),
         (( 1,4), 1  , "int", "invop"     , "invalid operation requested"),
         (  2   , 2*8, "int", "length"    , "pagelength"),
         (  4   , 4*8, "int", "gen"       , "generation code"),
         (  8   , 0  , "str", "enclosures", "enclosure descriptor list"),
         )
        threshold_descriptor = \
        (
         (  0   , 1*8, "int", "hicrit", "high critical threshold"),
         (  1   , 1*8, "int", "hiwarn", "high warning threshold"),
         (  2   , 1*8, "int", "lowarn", "low warning threshold"),
         (  3   , 1*8, "int", "locrit", "low critical threshold"),
         )

        if not self.page01:
            # We need the information from SES page 0x01 before we can
            # parse this page.
            return None

        bo = 0  # byte offset
        head = Cmd.extract(data[bo:], threshold_in, bo)
        bo += 8

        enclosures05 = []
        for enclosure01 in self.page01.enclosures.val:
            typelist05 = []
            for typedef01 in enclosure01.typedesc.val:
                ellist05 = []
                for elnum in range(1+typedef01.possible.val):  # @UnusedVariable
                    ellist05.append(Cmd.extract(data[bo:], threshold_descriptor, bo))
                    bo += 4
                typelist05.append({
                                   "type":typedef01.type.val,
                                   "text":typedef01.text.val,
                                   "elements":ellist05,
                                   })
            enclosures05.append(typelist05)
        head.enclosures = Cmd.Field(enclosures05, 8, "enclosures", "list of enclosures")
        return head
Example #21
0
    def parse_07(self, data):
        element_descriptor_head = \
        (
         (  0   , 1*8, "int", "pc"        , "page code"),
         (  2   , 2*8, "int", "length"    , "pagelength"),
         (  4   , 4*8, "int", "gen"       , "generation code"),
         (  8   , 0  , "str", "enclosures", "enclosure descriptor list"),
         )
        descriptor_head = \
        (
         (  0   , 2*8, "str", None    , "reserved"),
         (  2   , 2*8, "int", "length", "descriptor length"),
         )
        # This must be lists instead of tuples so we can modify the length.
        descriptor_text = \
        [
         [  0   , 0*8, "str", "text", "type descriptor text"],
         ]

        if not self.page01:
            # We need the information from SES page 0x01 before we can
            # parse this page.
            return None

        bo = 0  # byte offset
        head = Cmd.extract(data[bo:], element_descriptor_head, bo)
        bo += 8

        enclosures07 = []
        for enclosure01 in self.page01.enclosures.val:
            typelist07 = []
            for typedef01 in enclosure01.typedesc.val:
                ellist07 = []
                for elnum in range(1+typedef01.possible.val):  # @UnusedVariable
                    length = Cmd.extract(data[bo:], descriptor_head, bo).length.val
                    bo += 4
                    descriptor_text[0][1] = length*8
                    ellist07.append(Cmd.extract(data[bo:], descriptor_text, bo))
                    bo += length
                typelist07.append({
                                   "type":typedef01.type.val,
                                   "text":typedef01.text.val,
                                   "elements":ellist07,
                                   })
            enclosures07.append(typelist07)
        head.enclosures = Cmd.Field(enclosures07, 8, "enclosures", "list of enclosures")
        return head
        pass
    def setParamFlagCanCancel(self, channel, persistent, canCancel):
        """Set the Configuration Parameter Flag "Can Cancel".
        
        This method calls the SetParam function of the module and
        sets the Configuration Flag "Can Cancel".
        
         Args:
            channel: IO channel number. Must be in the range 0 ... 3
            persistent: Store parameter permanently if true
            canCancel: Parameter Flag "Can Cancel" as boolean
            
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel value is out of range
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' %
                            (type(channel)))

        if not isinstance(persistent, bool):
            raise TypeError('Expected persistent as bool, got %s' %
                            (type(persistent)))

        if not isinstance(canCancel, bool):
            raise TypeError('Expected canCancel as bool, got %s' %
                            (type(canCancel)))

        if (channel >= self.nrOfChannels):
            raise ValueError('Channel out of range')

        # Read current flags
        data = bytearray()
        cmd = Cmd(self.com)
        ret = cmd.getParam(_LCDO4ParamAddress.FLAGS, channel, data)

        if ret == IoReturn.IoReturn.IO_RETURN_OK:
            data[0] &= ~_LCDO4Flag.CAN_CANCEL
            if (canCancel == True):
                data[0] |= _LCDO4Flag.CAN_CANCEL

            ret = cmd.setParam(_LCDO4ParamAddress.FLAGS, channel, persistent,
                               data)

        return ret
Example #23
0
    def getParamScanInterval(self, channel, scanInterval):
        """Get the Configuration Parameter "Scan Interval" of the analog input
            channel.
            
        This method calls the GetParam function of the module and returns
            the Configuration Parameter "Scan Interval".
          
        Args:
            channel: IO channel number. Must be in the range 0 ... 3
            scanInterval: Scan Interval as a list containing one integer value
                in milliseconds
            
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel value is out of range
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' % type(channel))

        if not isinstance(scanInterval, list):
            raise TypeError('Expected scanInterval as list, got %s' %
                            type(scanInterval))

        if len(scanInterval) < 1:
            raise TypeError(
                'Expected scanInterval as list with 1 int, got %d' %
                len(scanInterval))

        if not isinstance(scanInterval[0], int):
            raise TypeError('Expected scanInterval[0] as int, got %s' %
                            type(scanInterval[0]))

        if (channel >= self.nrOfChannels):
            raise ValueError('Channel out of range')

        data = bytearray()
        cmd = Cmd(self.com)
        ret = cmd.getParam(_LCAI4ParamAddress.SCAN_INTERVAL, channel, data)

        if ret == IoReturn.IoReturn.IO_RETURN_OK:
            scanInterval[0] = struct.unpack("<H", buffer(data))[0]
        else:
            scanInterval[0] = 0
        return ret
Example #24
0
def main(input_args=None):
    # 设置传入参数
    parser = OptionParser(usage="usage:%prog [-options] class [args...]")

    parser.add_option("-v",
                      "--version",
                      action="store_true",
                      default=False,
                      dest="version_flag",
                      help="print version and exit.")
    parser.add_option("--cp",
                      action="store",
                      type="string",
                      dest="cpOption",
                      help="classpath")
    parser.add_option("--classpath",
                      action="store",
                      type="string",
                      dest="cpOption",
                      help="classpath")
    parser.add_option("--Xjre",
                      action="store",
                      type="string",
                      dest="XjreOption",
                      help="path to jre")
    # 解析参数
    (options, args) = parser.parse_args(input_args)
    if options:
        cmd = Cmd(options, args)

        if not options.version_flag:
            # 启动JVM
            start_JVM(cmd)
Example #25
0
    def getParamFlagResetCounterRead(self, channel, resetCounterRead):
        """Get the Configuration Parameter Flag "Reset Counter on Read".
        
        This method calls the GetParam function of the module and
        returns the Configuration Flag "Reset Counter on Read".
        
        Args:
            channel: IO channel number. Must be in the range 0 ... 3
            resetCounterRead: Parameter Flag "Reset Counter on Read"
                as a list containing one boolean value
            
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel value is out of range
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' % type(channel))

        if not isinstance(resetCounterRead, list):
            raise TypeError('Expected resetCounterRead as list, got %s' %
                type(resetCounterRead))
            
        if len(resetCounterRead) < 1:
            raise TypeError('Expected resetCounterRead as list with 1 bool, \
                got %d' % len(resetCounterRead))
        
        if not isinstance(resetCounterRead[0], int):
            raise TypeError('Expected resetCounterRead[0] as bool, got %s' %
                type(resetCounterRead[0]))

        if (channel >= self.nrOfChannels):
            raise ValueError('Channel out of range')

        data = bytearray()
        cmd = Cmd(self.com)
        ret = cmd.getParam(_LCDI4ParamAddress.FLAGS, channel, data)

        if ret == IoReturn.IoReturn.IO_RETURN_OK:
            if data[0] & _LCDI4Flag.RESET_COUNTER_READ:
                resetCounterRead[0] = True
            else:
                resetCounterRead[0] = False
        return ret
Example #26
0
    def getParamOffset(self, channel, offset):
        """Get the Configuration Parameter "Offset" of the analog output
            channel.
            
        This method calls the GetParam function of the module and returns
            the Configuration Parameter "Offset".
          
        Args:
            channel: IO channel number. Must be in the range 0 ... 3
            offset: Offset as a list containing one integer value
                representing the offset voltage in millivolt.
            
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel value is out of range
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' % type(channel))

        if not isinstance(offset, list):
            raise TypeError('Expected offset as list, got %s' % type(offset))

        if len(offset) < 1:
            raise TypeError('Expected offset as list with 1 int, got %d' %
                            len(offset))

        if not isinstance(offset[0], int):
            raise TypeError('Expected offset[0] as int, got %s' %
                            type(offset[0]))

        if (channel >= self.nrOfChannels):
            raise ValueError('Channel out of range')

        data = bytearray()
        cmd = Cmd(self.com)
        ret = cmd.getParam(_LCAO4ParamAddress.OFFSET, channel, data)

        if ret == IoReturn.IoReturn.IO_RETURN_OK:
            offset[0] = struct.unpack("<h", buffer(data))[0]
        else:
            offset[0] = 0
        return ret
Example #27
0
    def getParamCalUrs(self, channel, calUrs):
        """Get the Configuration Parameter "CalUrs" of the RTD input
            channel.
            
        This method calls the GetParam function of the module and returns
            the Configuration Parameter "CalUrs".
          
        Args:
            channel: IO channel number. Must be in the range 0 ... 3
            calUrs: Calibration value URS as a list containing one integer value
            
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel value is out of range
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' % type(channel))

        if not isinstance(calUrs, list):
            raise TypeError('Expected calUrs as list, got %s' % type(calUrs))

        if len(calUrs) < 1:
            raise TypeError('Expected calUrs as list with 1 int, got %d' %
                            len(calUrs))

        if not isinstance(calUrs[0], int):
            raise TypeError('Expected calUrs[0] as int, got %s' %
                            type(calUrs[0]))

        if (channel >= self.nrOfChannels):
            raise ValueError('Channel out of range')

        data = bytearray()
        cmd = Cmd(self.com)
        ret = cmd.getParam(_LCRT4ParamAddress.CAL_URS, channel, data)

        if ret == IoReturn.IoReturn.IO_RETURN_OK:
            calUrs[0] = struct.unpack("<h", buffer(data))[0]
        else:
            calUrs[0] = 0
        return ret
Example #28
0
 def _getsespage(self, page, length):
     # uses pt
     cmd = Cmd("rdr", {"pcv": 1, "page_code": page, "alloc": length})
     #for q in cmd.cdb: print "%.2x" % q,
     #print
     cdb = CDB(cmd.cdb)
     cdb.set_data_in(length)
     self.pt.sendcdb(cdb)
     return cdb.buf
    def getParamOnDelay(self, channel, onDelay):
        """Get the Configuration Parameter "On Delay" of the digital output
            channel.
            
        This method calls the GetParam function of the module and returns
            the Configuration Parameter "On Delay".
          
        Args:
            channel: IO channel number. Must be in the range 0 ... 3
            onDelay: Parameter "On Delay" as a list containing one integer
                value in microseconds
            
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel value is out of range
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' %
                            (type(channel)))

        if not isinstance(onDelay, list):
            raise TypeError('Expected onDelay as list, got %s' % type(onDelay))

        if len(onDelay) < 1:
            raise TypeError('Expected onDelay as list with 1 int, got %d' %
                            len(onDelay))

        if not isinstance(onDelay[0], int):
            raise TypeError('Expected onDelay[0] as int, got %s' %
                            type(onDelay[0]))

        data = bytearray()
        cmd = Cmd(self.com)
        ret = cmd.getParam(_LCDO4ParamAddress.ON_DELAY, channel, data)

        if ret == IoReturn.IoReturn.IO_RETURN_OK:
            onDelay[0] = struct.unpack("<I", buffer(data))[0]
        else:
            onDelay[0] = 0
        return ret
    def setParamCycleTime(self, channel, persistent, cycleTime):
        """Set the Configuration Parameter "Cycle Time" of a digital
            output channel.
            
        This method calls the SetParam function of the module and sets the
        Configuration Parameter "Cycle Time".
        
        Args:
            channel: IO channel number. Must be in the range 0 ... 3
            persistent: Store parameter permanently if true
            cycleTime: Parameter "Cycle Time" in microseconds
        
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel or cycleTime value is out of range
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' %
                            (type(channel)))

        if not isinstance(persistent, bool):
            raise TypeError('Expected persistent as bool, got %s' %
                            (type(persistent)))

        if not isinstance(cycleTime, int):
            raise TypeError('Expected cycleTime as int, got %s' %
                            (type(cycleTime)))

        if (channel >= self.nrOfChannels):
            raise ValueError('Channel out of range')

        if (cycleTime < 0) | (cycleTime >= pow(2, 32)):
            raise ValueError('Cycle Time out of range')

        data = bytearray(struct.pack("<I", cycleTime))
        cmd = Cmd(self.com)

        return cmd.setParam(_LCDO4ParamAddress.CYCLE_TIME, channel, persistent,
                            data)
    def getParamValue(self, channel, value):
        """Get the Configuration Parameter "Value" of a digital
            output channel.
            
        This method calls the GetParam function of the module and returns
        the value of the Configuration Parameter "Value".
        
        The Configuration Parameter "Value" contains the current value
        or state of the output channel.
        
        It is recommended to call getIo instead of this method.
        
        Args:
            channel: IO channel number. Must be in the range 0 ... 3
            value: Digital value object of type ValueDI1.
            
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel value is out of range
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' %
                            (type(channel)))

        if not isinstance(value, ValueDI1):
            raise TypeError('Expected value as ValueDI1, got %s' %
                            (type(value)))

        if (channel >= self.nrOfChannels):
            raise ValueError('Channel out of range')

        data = bytearray()
        cmd = Cmd(self.com)
        ret = cmd.getParam(_LCDO4ParamAddress.VALUE, channel, data)

        if ret == IoReturn.IoReturn.IO_RETURN_OK:
            value._setData(data)
        return ret
Example #32
0
    def setParamScanInterval(self, channel, persistent, scanInterval):
        """Set the Configuration Parameter "Scan Interval" of an analog
            input channel.
            
        This method calls the SetParam function of the module and sets the
        Configuration Parameter "Scan Interval".
        
        Args:
            channel: IO channel number. Must be in the range 0 ... 3
            persistent: Store parameter permanently if true
            scanInterval: Parameter "Scan Interval" in milliseconds.
                Value range 0 ... 0xFFFF
        
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel or scanInterval value is out of range
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' % type(channel))

        if not isinstance(persistent, bool):
            raise TypeError('Expected persistent as bool, got %s' %
                            type(persistent))

        if not isinstance(scanInterval, int):
            raise TypeError('Expected scanInterval as int, got %s' %
                            type(scanInterval))

        if (channel >= self.nrOfChannels):
            raise ValueError('Channel out of range')

        if (scanInterval < 0) | (scanInterval >= pow(2, 16)):
            raise ValueError('Scan Interval out of range')

        data = bytearray(struct.pack("<H", scanInterval))
        cmd = Cmd(self.com)
        return cmd.setParam(_LCAI4ParamAddress.SCAN_INTERVAL, channel,
                            persistent, data)
Example #33
0
    def execute(self, command):
        """
        Send a CLI command through SES page 0xe8.
        """
        cmd = Cmd.clicommandout(self.expanderid, command)
        cdb = CDB(cmd.cdb)
        cdb.set_data_out(cmd.dat)
        self.pt.sendcdb(cdb)

        page = self.ses.parse(self.ses.readpage(0xe8))
        return page["data"].response.val
Example #34
0
    def execute(self, command):
        """
        Send a CLI command through SES page 0xe8.
        """
        cmd = Cmd.clicommandout(self.expanderid, command)
        cdb = CDB(cmd.cdb)
        cdb.set_data_out(cmd.dat)
        self.pt.sendcdb(cdb)

        page = self.ses.parse(self.ses.readpage(0xe8))
        return page["data"].response.val
Example #35
0
    def setParamNrSamples(self, channel, persistent, nrSamples):
        """Set the Configuration Parameter "Number of Samples" of an analog
            input channel.
            
        This method calls the SetParam function of the module and sets the
        Configuration Parameter "Number of Samples".
        
        Args:
            channel: IO channel number. Must be in the range 0 ... 3
            persistent: Store parameter permanently if true
            nrSamples: Parameter "Number of Samples"
        
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel or nrSamples value is out of range
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' % type(channel))

        if not isinstance(persistent, bool):
            raise TypeError('Expected persistent as bool, got %s' %
                            type(persistent))

        if not isinstance(nrSamples, int):
            raise TypeError('Expected nrSamples as int, got %s' %
                            type(nrSamples))

        if (channel >= self.nrOfChannels):
            raise ValueError('Channel out of range')

        if (nrSamples < 0):
            raise ValueError('nrSamples out of range')

        data = bytearray(struct.pack("<H", nrSamples))
        cmd = Cmd(self.com)
        return cmd.setParam(_LCAI4ParamAddress.NR_SAMPLES, channel, persistent,
                            data)
Example #36
0
    def setParamOffset(self, channel, persistent, offset):
        """Set the Configuration Parameter "Offset" of an analog
            input channel.
            
        This method calls the SetParam function of the module and sets the
        Configuration Parameter "Offset".
        
        Args:
            channel: IO channel number. Must be in the range 0 ... 3
            persistent: Store parameter permanently if true
            offset: Parameter "Offset" 
        
        Returns:
            IO_RETURN_OK in case of success, otherwise detailed IoReturn
            error code.
        
        Raises:
            TypeError: Passed argument types are wrong
            ValueError: Channel or offset value is out of range
        """
        if not isinstance(channel, int):
            raise TypeError('Expected channel as int, got %s' % type(channel))

        if not isinstance(persistent, bool):
            raise TypeError('Expected persistent as bool, got %s' %
                            type(persistent))

        if not isinstance(offset, int):
            raise TypeError('Expected offset as int, got %s' % type(offset))

        if (channel >= self.nrOfChannels):
            raise ValueError('Channel out of range')

        if (offset < (-pow(2, 15))) | (offset >= pow(2, 16)):
            raise ValueError('Offset out of range')

        data = bytearray(struct.pack("<h", offset))
        cmd = Cmd(self.com)
        return cmd.setParam(_LCAI4ParamAddress.OFFSET, channel, persistent,
                            data)
Example #37
0
    def parse_80(self, data):
        eventlogin_head = \
        (
         (  0   , 1*8, "int", "pc"         , "page code"),
         (  2   , 2*8, "int", "length"     , "pagelength"),
         (( 5,1), 1  , "int", "notavail"   , "buffer not available"),
         (( 5,0), 1  , "int", "stop"       , "stop"),
         (  6   , 0  , "str", "log"        , "log data"),
         )

        bo = 0  # byte offset
        head = Cmd.extract(data[bo:], eventlogin_head, bo)
        bo += 6

        head.log.val = data[bo:]
        return head
Example #38
0
    def parse_e8(self, data):
        clicommandin_head = \
        (
         (  0   , 1*8, "int", "pc"         , "page code"),
         (  2   , 2*8, "int", "length"     , "pagelength"),
         (  4   , 1*8, "int", "expanderid" , "expander id"),
         (  5   , 0  , "str", "response"   , "cli response"),
         )
        expander_id = \
        {
         0x01: "SBB Canister A",
         0x02: "SBB Canister B",
         0x03: "FEM Canister A SAS Expander 1",
         0x04: "FEM Canister A SAS Expander 2",
         0x05: "FEM Canister B SAS Expander 1",
         0x06: "FEM Canister B SAS Expander 2",
         }

        bo = 0  # byte offset
        head = Cmd.extract(data[bo:], clicommandin_head, bo)
        bo += 5

        head.response.val = data[bo:]
        return head
Example #39
0
    def page_02_fill(self, filter_func, params):
        """
        Build page 0x02 data.
        Call filter_func for each element, passing in
          element type
          element number
          element fields
          default control values
          the opaque "params" that were passed in to us
        If the filter_func wants this element modified, it returns the
        default control values, modified however it wants.  If it
        doesn't want to modify this element, it returns None.
        This function returns the entire page 0x02 data.
        """
        page_02_head = \
        {
         "PAGE CODE"               : (  0   , 1*8, 0x02),
         "INFO"                    : (( 1,3), 1  , 0),
         "NON-CRIT"                : (( 1,2), 1  , 0),
         "CRIT"                    : (( 1,1), 1  , 0),
         "UNRECOV"                 : (( 1,0), 1  , 0),
         "PAGE LENGTH"             : (  2   , 2*8, 0),
         "EXPECTED GENERATION CODE": (  4   , 4*8, 0),
         }
        control_element_head = \
        {
         "SELECT"  : (( 0,7), 1  , 0),
         "PRDFAIL" : (( 0,6), 1  , 0),
         "DISABLE" : (( 0,5), 1  , 0),
         "RST SWAP": (( 0,4), 1  , 0),
         }
        page_02_specific_control = \
        {
         0x01: {  # Device Slot
                  "RQST ACTIVE"  : (( 2,7), 1  , 0),
                  "DO NOT REMOVE": (( 2,6), 1  , 0),
                  "RQST MISSING" : (( 2,4), 1  , 0),
                  "RQST INSERT"  : (( 2,3), 1  , 0),
                  "RQST REMOVE"  : (( 2,2), 1  , 0),
                  "RQST IDENT"   : (( 2,1), 1  , 0),
                  "RQST FAULT"   : (( 3,5), 1  , 0),
                  "DEVICE OFF"   : (( 3,4), 1  , 0),
                  "ENABLE BYP A" : (( 3,3), 1  , 0),
                  "ENABLE BYP B" : (( 3,2), 1  , 0),
                },
         0x02: {  # Power Supply
                  "RQST IDENT": (( 1,7), 1  , 0),
                  "RQST FAIL" : (( 3,6), 1  , 0),
                  "RQST ON"   : (( 3,5), 1  , 0),
                },
         0x03: {  # Cooling
                  "RQST IDENT"          : (( 1,7), 1  , 0),
                  "RQST FAIL"           : (( 3,6), 1  , 0),
                  "RQST ON"             : (( 3,5), 1  , 0),
                  "REQUESTED SPEED CODE": (( 3,2), 3  , 0),
                },
         0x04: {  # Temperature Sensor
                  "RQST IDENT": (( 1,7), 1  , 0),
                  "RQST FAIL" : (( 1,6), 1  , 0),
                },
         0x07: {  # Enclosure Services Controller Electronics
                  "RQST IDENT"    : (( 1,7), 1  , 0),
                  "RQST FAIL"     : (( 1,6), 1  , 0),
                  "SELECT ELEMENT": (( 2,0), 1  , 0),
                },
         0x0c: {  # Display
                  "RQST IDENT"       : (( 1,7), 1  , 0),
                  "RQST FAIL"        : (( 1,6), 1  , 0),
                  "DISPLAY MODE"     : (( 1,1), 2  , 0),
                  "DISPLAY CHARACTER": (  2   , 2*8, 0),
                },
         0x0e: {  # Enclosure
                  "RQST IDENT"         : (( 1,7), 1  , 0),
                  "POWER CYCLE REQUEST": (( 2,7), 2  , 0),
                  "POWER CYCLE DELAY"  : (( 2,5), 6  , 0),
                  "POWER OFF DURATION" : (( 3,7), 6  , 0),
                  "REQUEST FAILURE"    : (( 3,1), 1  , 0),
                  "REQUEST WARNING"    : (( 3,0), 1  , 0),
                },
         0x17: {  # Array Device Slot
                  "RQST OK"             : (( 1,7), 1  , 0),
                  "RQST RSVD DEVICE"    : (( 1,6), 1  , 0),
                  "RQST HOT SPARE"      : (( 1,5), 1  , 0),
                  "RQST CONS CHECK"     : (( 1,4), 1  , 0),
                  "RQST IN CRIT ARRAY"  : (( 1,3), 1  , 0),
                  "RQST IN FAILED ARRAY": (( 1,2), 1  , 0),
                  "RQST REBUILD/REMAP"  : (( 1,1), 1  , 0),
                  "RQST R/R ABORT"      : (( 1,0), 1  , 0),
                  "RQST ACTIVE"         : (( 2,7), 1  , 0),
                  "DO NOT REMOVE"       : (( 2,6), 1  , 0),
                  "RQST MISSING"        : (( 2,4), 1  , 0),
                  "RQST INSERT"         : (( 2,3), 1  , 0),
                  "RQST REMOVE"         : (( 2,2), 1  , 0),
                  "RQST IDENT"          : (( 2,1), 1  , 0),
                  "RQST FAULT"          : (( 3,5), 1  , 0),
                  "DEVICE OFF"          : (( 3,4), 1  , 0),
                  "ENABLE BYP A"        : (( 3,3), 1  , 0),
                  "ENABLE BYP B"        : (( 3,2), 1  , 0),
                },
         0x18: {  # SAS Expander
                  "RQST IDENT": (( 1,7), 1  , 0),
                  "RQST FAIL" : (( 1,6), 1  , 0),
                },
         0x19: {  # SAS Connector
                  "RQST IDENT": (( 1,7), 1  , 0),
                  "RQST FAIL" : (( 3,6), 1  , 0),
                },
         }

        if not self.page01:
            self.parse(self.readpage(0x01))
        if not self.page02:
            self.parse(self.readpage(0x02))

        dat = [0] * 8
        for enclosure in self.page02.enclosures.val:
            for typ in enclosure:
                elnum = -1
                for element in typ["elements"]:
                    defaults = {}
                    defaults["SELECT"  ] = 1  # select this element
                    defaults["PRDFAIL" ] = element.prdfail.val
                    defaults["DISABLE" ] = element.disabled.val
                    defaults["RST SWAP"] = 0  # do not reset
                    set_values = filter_func(typ["type"], elnum, element, defaults, params)
                    eldat = [0] * 4
                    if set_values:
                        d = control_element_head
                        d.update(page_02_specific_control[typ["type"]])
                        Cmd.fill(eldat, d, set_values)
                    dat += eldat
                    elnum += 1
        Cmd.fill(dat, page_02_head,
                 {"PAGE LENGTH":len(dat)-4,
                  "EXPECTED GENERATION CODE":self.page02.gen.val}
                 )
        return dat
Example #40
0
    def parse_02(self, data):
        """
        return a ListDict of Fields, including "enclosures": list of enclosures
        an enclosure is a dictionary with "subid": enclosure number and "types": list of types
        a type is a dictionary with "type": element type and "elements": list of status elements, starting with the overall status element
        a status element is a list of Fields
        """
        enclosure_status = \
        (
         (  0   , 1*8, "int", "pc"        , "page code"),
         (( 1,4), 1  , "int", "invop"     , "invop"),
         (( 1,3), 1  , "int", "info"      , "info"),
         (( 1,2), 1  , "int", "non_crit"  , "non-crit"),
         (( 1,1), 1  , "int", "crit"      , "crit"),
         (( 1,0), 1  , "int", "unrecov"   , "unrecov"),
         (  2   , 2*8, "int", "length"    , "pagelength"),
         (  4   , 4*8, "int", "gen"       , "generation code"),
         (  8   , 0  , "str", "enclosures", "enclosure descriptor list"),
         )
        status_element = \
        (
         (( 0,6), 1  , "int", "prdfail" , "prdfail"),
         (( 0,5), 1  , "int", "disabled", "disabled"),
         (( 0,4), 1  , "int", "swap"    , "swap"),
         (( 0,3), 4  , "int", "elstat"  , "element status code"),
         (  1   , 3*8, "int", "status"  , "element type specific status information"),
         )
        specific_status = \
        {
         0x01: (  # Device Slot
                  (  1   , 1*8, "int", "slot_address"         , "SLOT ADDRESS"),
                  (( 2,7), 1  , "int", "app_client_bypassed_a", "APP CLIENT BYPASSED A"),
                  (( 2,6), 1  , "int", "do_not_remove"        , "DO NOT REMOVE"),
                  (( 2,5), 1  , "int", "enclosure_bypassed_a" , "ENCLOSURE BYPASSED A"),
                  (( 2,4), 1  , "int", "enclosure_bypassed_b" , "ENCLOSURE BYPASSED B"),
                  (( 2,3), 1  , "int", "ready_to_insert"      , "READY TO INSERT"),
                  (( 2,2), 1  , "int", "rmv"                  , "RMV"),
                  (( 2,1), 1  , "int", "ident"                , "IDENT"),
                  (( 2,0), 1  , "int", "report"               , "REPORT"),
                  (( 3,7), 1  , "int", "app_client_bypassed_b", "APP CLIENT BYPASSED B"),
                  (( 3,6), 1  , "int", "fault_sensed"         , "FAULT SENSED"),
                  (( 3,5), 1  , "int", "fault_reqstd"         , "FAULT REQSTD"),
                  (( 3,4), 1  , "int", "device_off"           , "DEVICE OFF"),
                  (( 3,3), 1  , "int", "bypassed_a"           , "BYPASSED A"),
                  (( 3,2), 1  , "int", "bypassed_b"           , "BYPASSED B"),
                  (( 3,1), 1  , "int", "device_bypassed_a"    , "DEVICE BYPASSED A"),
                  (( 3,0), 1  , "int", "device_bypassed_b"    , "DEVICE BYPASSED B"),
                ),
         0x02: (  # Power Supply
                  (( 1,7), 1  , "int", "ident"           , "IDENT"),
                  (( 2,3), 1  , "int", "dc_over_voltage" , "DC OVER VOLTAGE"),
                  (( 2,2), 1  , "int", "dc_under_voltage", "DC UNDER VOLTAGE"),
                  (( 2,1), 1  , "int", "dc_over_current" , "DC OVER CURRENT"),
                  (( 3,7), 1  , "int", "hot_swap"        , "HOT SWAP"),
                  (( 3,6), 1  , "int", "fail"            , "FAIL"),
                  (( 3,5), 1  , "int", "rqsted_on"       , "RQSTED ON"),
                  (( 3,4), 1  , "int", "off"             , "OFF"),
                  (( 3,3), 1  , "int", "overtmp_fail"    , "OVERTMP FAIL"),
                  (( 3,2), 1  , "int", "temp_warn"       , "TEMP WARN"),
                  (( 3,1), 1  , "int", "ac_fail"         , "AC FAIL"),
                  (( 3,0), 1  , "int", "dc_fail"         , "DC FAIL"),
                ),
         0x03: (  # Cooling
                  (( 1,7), 1  , "int", "ident"     , "IDENT"),
                  (( 1,2),11  , "int", "fan_speed" , "ACTUAL FAN SPEED"), # units of 10 RPM
                  (( 3,7), 1  , "int", None        , "HOT SWAP"),
                  (( 3,6), 1  , "int", "fail"      , "FAIL"),
                  (( 3,5), 1  , "int", None        , "RQSTED ON"),
                  (( 3,4), 1  , "int", "off"       , "OFF"),
                  (( 3,2), 3  , "int", "speed_code", "ACTUAL SPEED CODE"),
                ),
         0x04: (  # Temperature Sensor
                  (( 1,7), 1  , "int", None, "IDENT"),
                  (( 1,6), 1  , "int", None, "FAIL"),
                  (  2   , 1*8, "int", None, "TEMPERATURE"),
                  (( 3,3), 1  , "int", None, "OT FAILURE"),
                  (( 3,2), 1  , "int", None, "OT WARNING"),
                  (( 3,1), 1  , "int", None, "UT FAILURE"),
                  (( 3,0), 1  , "int", None, "UT WARNING"),
                ),
         0x07: (  # Enclosure Services Controller Electronics
                  (( 1,7), 1  , "int", None, "IDENT"),
                  (( 1,6), 1  , "int", None, "FAIL"),
                  (( 2,0), 1  , "int", None, "REPORT"),
                  (( 3,7), 1  , "int", None, "HOT SWAP"),
                ),
         0x0c: (  # Display
                  (( 1,7), 1  , "int", None, "IDENT"),
                  (( 1,6), 1  , "int", None, "FAIL"),
                  (( 1,1), 2  , "int", None, "DISPLAY MODE STATUS"),
                  (  2   , 2*8, "int", None, "DISPLAY CHARACTER STATUS"),
                ),
         0x0e: (  # Enclosure
                  (( 1,7), 1  , "int", None, "IDENT"),
                  (( 2,7), 6  , "int", None, "TIME UNTIL POWER CYCLE"),
                  (( 2,1), 1  , "int", None, "FAILURE INDICATION"),
                  (( 2,0), 1  , "int", None, "WARNING INDICATION"),
                  (( 3,7), 6  , "int", None, "REQUESTED POWER OFF DURATION"),
                  (( 3,1), 1  , "int", None, "FAILURE REQUESTED"),
                  (( 3,0), 1  , "int", None, "WARNING REQUESTED"),
                ),
         0x17: (  # Array Device Slot
                  (( 1,7), 1  , "int", None, "OK"),
                  (( 1,6), 1  , "int", None, "RSVD DEVICE"),
                  (( 1,5), 1  , "int", None, "HOT SPARE"),
                  (( 1,4), 1  , "int", None, "CONS CHK"),
                  (( 1,3), 1  , "int", None, "IN CRIT ARRAY"),
                  (( 1,2), 1  , "int", None, "IN FAILED ARRAY"),
                  (( 1,1), 1  , "int", None, "REBUILD/REMAP"),
                  (( 1,0), 1  , "int", None, "R/R ABORT"),
                  (( 2,7), 1  , "int", None, "APP CLIENT BYPASSED A"),
                  (( 2,6), 1  , "int", None, "DO NOT REMOVE"),
                  (( 2,5), 1  , "int", None, "ENCLOSURE BYPASSED A"),
                  (( 2,4), 1  , "int", None, "ENCLOSURE BYPASSED B"),
                  (( 2,3), 1  , "int", None, "READY TO INSERT"),
                  (( 2,2), 1  , "int", None, "RMV"),
                  (( 2,1), 1  , "int", None, "IDENT"),
                  (( 2,0), 1  , "int", None, "REPORT"),
                  (( 3,7), 1  , "int", None, "APP CLIENT BYPASSED B"),
                  (( 3,6), 1  , "int", None, "FAULT SENSED"),
                  (( 3,5), 1  , "int", None, "FAULT REQSTD"),
                  (( 3,4), 1  , "int", None, "DEVICE OFF"),
                  (( 3,3), 1  , "int", None, "BYPASSED A"),
                  (( 3,2), 1  , "int", None, "BYPASSED B"),
                  (( 3,1), 1  , "int", None, "DEVICE BYPASSED A"),
                  (( 3,0), 1  , "int", None, "DEVICE BYPASSED B"),
                ),
         0x18: (  # SAS Expander
                  (( 1,7), 1  , "int", None, "IDENT"),
                  (( 1,6), 1  , "int", None, "FAIL"),
                ),
         0x19: (  # SAS Connector
                  (( 1,7), 1  , "int", None, "IDENT"),
                  (( 1,6), 7  , "int", None, "CONNECTOR TYPE"),
                  (  2   , 1*8, "int", None, "CONNECTOR PHYSICAL LINK"),
                  (( 3,6), 1  , "int", None, "FAIL"),
                ),
         #01 array
         #18 sas expander
         #sas connector (external ports)
         #19 sas connector (hdd ports)
         #0e enclosure
         #04 temperature sensor
         #02 power supply
         #03 cooling
         #0c display
         #07?SEP
         }

        if not self.page01:
            # We need the information from SES page 0x01 before we can
            # parse this page.
            return None

        bo = 0  # byte offset
        head = Cmd.extract(data[bo:], enclosure_status, bo)
        bo += 8

        enclosures02 = []
        for enclosure01 in self.page01.enclosures.val:
            typelist02 = []
            for typedef01 in enclosure01.typedesc.val:
                ellist02 = []
                for elnum in range(1+typedef01.possible.val):
                    fieldlist = Cmd.extract(data[bo:], status_element, bo)
                    if typedef01.type.val in specific_status and elnum > 0:
                        fieldlist += Cmd.extract(data[bo:], specific_status[typedef01.type.val], bo+1)
                        pass
                    ellist02.append(fieldlist)
                    bo += 4
                typelist02.append({
                                   "type":typedef01.type.val,
                                   "text":typedef01.text.val,
                                   "elements":ellist02,
                                   })
            enclosures02.append(typelist02)
        head.enclosures = Cmd.Field(enclosures02, 8, "enclosures", "list of enclosures")
        #head.append(Cmd.Field(enclosures02, 8, "enclosures", "list of enclosures"), "enclosures")
        self.page02 = head
        return head
Example #41
0
    def parse_0a(self, data):
        additional_element_head = \
        (
         (  0   , 1*8, "int", "pc"         , "page code"),
         (  2   , 2*8, "int", "length"     , "pagelength"),
         (  4   , 4*8, "int", "gen"        , "generation code"),
         (  8   , 0  , "str", "descriptors", "additional element descriptor list"),
         )

        descriptor_head = \
        (
         (( 0,7), 1  , "int", "invalid" , "invalid"),
         (( 0,4), 1  , "int", "eip"     , "element index present"),
         (( 0,3), 4  , "int", "protocol", "protocol identifier"),
         (  1   , 1*8, "int", "length"  , "additional element status descriptor length"),
         )
        descriptor_eip1 = \
        (
         (( 0,0), 1  , "int", "eiioe", "element index includes overall elements"),
         (  1   , 1*8, "int", "index", "element index"),
         )

        sas_specific_head = \
        (
         (  0   , 1*8, "int", "numphys", "number of phy descriptors"),
         (( 1,7), 2  , "int", "type"   , "descriptor type (00b)"),
         (( 1,0), 1  , "int", "notall" , "not all phys"),
        #(  2   , 0  , "str", "phydescriptors", "phy descriptor list"),
         )
        sas_specific_eip1 = \
        (
         (  1   , 1*8, "int", "slotnum", "device slot number"),
        #(  4   , 0  , "str", "phydescriptors", "phy descriptor list"),
         )

        phy_descriptor = \
        (
         (( 0,6), 3  , "int", "type"    , "device type"),
         (( 2,3), 1  , "int", "ssp_init", "ssp initiator port"),
         (( 2,2), 1  , "int", "stp_init", "stp initiator port"),
         (( 2,1), 1  , "int", "smp_init", "smp initiator port"),
         (( 3,7), 1  , "int", "selector", "sata port selector"),
         (( 3,3), 1  , "int", "ssp_targ", "ssp target port"),
         (( 3,2), 1  , "int", "stp_targ", "stp target port"),
         (( 3,1), 1  , "int", "smp_targ", "smp target port"),
         (( 3,0), 1  , "int", "device"  , "sata device"),
         (  4   , 8*8, "int", "attached_sas_addr", "attached sas_specific address"),
         ( 12   , 8*8, "int", "sas_addr", "sas_specific address"),
         ( 20   , 1*8, "int", "phy_id"  , "phy identifier"),
         )

        if not self.page01:
            # We need the information from SES page 0x01 before we can
            # parse this page.
            return None

        bo = 0  # byte offset
        head = Cmd.extract(data[bo:], additional_element_head, bo)
        bo += 8

        endbo = bo-4 + head.length.val
        descriptors = []
        while bo < endbo:
            # Retrieve a descriptor header.
            dhead = Cmd.extract(data[bo:], descriptor_head, bo)
            bo += 2
            if dhead.eip.val:
                dhead += Cmd.extract(data[bo:], descriptor_eip1, bo)
                bo += 2
                index_remaining = dhead.index.val
                foundit = False
                for enclosure in self.page01.enclosures.val:
                    for typedef in enclosure.typedesc.val:
                        if index_remaining > typedef.possible.val + dhead.eiioe.val:
                            index_remaining -= typedef.possible.val + dhead.eiioe.val
                        else:
                            foundit = True
                            break
                    if foundit:
                        break
                dhead.index.val = (enclosure.subid.val, typedef.type.val, index_remaining-dhead.eiioe.val)

            if dhead.protocol.val != 0x06:
                return None  # Only SAS protocol is supported.

            sas_specific = Cmd.extract(data[bo:], sas_specific_head, bo)
            bo += 2
            if dhead.eip.val:
                sas_specific += Cmd.extract(data[bo:], sas_specific_eip1, bo)
                bo += 2

            phylist = []
            phybo = bo
            for phynum in range(sas_specific.numphys.val):  # @UnusedVariable
                phylist.append(Cmd.extract(data[bo:], phy_descriptor, bo))
                bo += 28
            sas_specific.append(Cmd.Field(phylist, phybo, "phydescriptors", "phy descriptor list"), "phydescriptors")
            descriptor = dhead + sas_specific
            descriptors.append(descriptor)

        head.descriptors.val = descriptors
        return head
Example #42
0
 def parse_01(self, data):
     """
     return a ListDict of Fields, including "enclosures": list of enclosures
     an enclosure is a ListDict of Fields, including "typedesc": list of type descriptors
     a type descriptor is a ListDict of Fields, including "text": type descriptor text
     """
     configuration = \
     (
      (  0   , 1*8, "int", "pc",          "page code"),
      (  1   , 1*8, "int", "secondaries", "number of secondary subenclosures"),
      (  2   , 2*8, "int", "length",      "pagelength"),
      (  4   , 4*8, "int", "gen",         "generation code"),
      (  8   , 0  , "str", "enclosures" , "enclosure descriptor list"),
      )
     enclosure_descriptor = \
     (
      (( 0,6), 3  , "int", None,      "relative enclosure services process identifier"),
      (( 0,2), 3  , "int", None,      "number of enclosure services processes"),
      (  1   , 1*8, "int", "subid",   "subenclosure identifier"),
      (  2   , 1*8, "int", "number",  "number of type descriptor headers"),
      (  3   , 1*8, "int", "length",  "enclosure descriptor length"),
      (  4   , 8*8, "int", "logid",   "enclosure logical identifier"),
      ( 12   , 8*8, "str", "vendor",  "enclosure vendor identification"),
      ( 20   ,16*8, "str", "product", "product identification"),
      ( 36   , 4*8, "str", "revision","product revision level"),
      ( 40   , 0  , "str", None,      "vendor specific enclosure information"),
      (  0   , 0  , "str", "typedesc", "list of type descriptor"),  # placeholder
      )
     type_descriptor_header = \
     (
      (  0   , 1*8, "int", "type",     "element type"),
      (  1   , 1*8, "int", "possible", "number of possible elements"),
      (  2   , 1*8, "int", "subid",    "subenclosure identifier"),
      (  3   , 1*8, "int", "desclen",  "type descriptor text length"),
      (  0   , 0  , "str", "text"    , "type descriptor text"),  # placeholder
      )
     # This must be lists instead of tuples so we can modify the length.
     type_descriptor_text = \
     [
      [  0   , 0*8, "str", "text", "type descriptor text"],
      ]
     # Table 60 in ses3r06.pdf
     element_type_codes = \
     {
      0x00: "Unspecified",
      0x01: "Device Slot",
      0x02: "Power Supply",
      0x03: "Cooling",
      0x04: "Temperature Sensor",
      0x05: "Door",
      0x06: "Audible Alarm",
      0x07: "Enclosure Services Controller Electronics",
      0x08: "SCC Controller Electronics",
      0x09: "Nonvolatile Cache",
      0x0a: "Invalid Operation Reason",
      0x0b: "Uninterruptible Power Supply",
      0x0c: "Display",
      0x0d: "Key Pad Entry",
      0x0e: "Enclosure",
      0x0f: "SCSI Port/Transceiver",
      0x10: "Language",
      0x11: "Communication Port",
      0x12: "Voltage Sensor",
      0x13: "Current Sensor",
      0x14: "SCSI Target Port",
      0x15: "SCSI Initiator Port",
      0x16: "Simple Subenclosure",
      0x17: "Array Device Slot",
      0x18: "SAS Expander",
      0x19: "SAS Connector",
      }
     bo = 0   # byte offset
     head = Cmd.extract(data[bo:], configuration, bo)
     bo += 8
     enclosures = []
     enctypecounts = []   # number of types for each enclosure
     numenclosures = 1+head.secondaries.val  # total number of enclosures
     # Loop through the enclosures, retrieving headers.
     for encidx in range(numenclosures):
         # An enclosure is a ListDict of Fields.
         enclosure = Cmd.extract(data[bo:], enclosure_descriptor, bo)
         enclosures.append(enclosure)
         enctypecounts.append(enclosure.number.val)
         bo += 4+enclosure.length.val
     # Loop again through enclosures, retrieving lists of type descriptors.
     for encidx in range(numenclosures):
         typeheaders = []
         typedescbo  = bo
         for typenum in range(enctypecounts[encidx]):
             # A typeheader is a ListDict of Fields.
             # typeheaders is a list of them.
             typeheader = Cmd.extract(data[bo:], type_descriptor_header, bo)
             bo += 4
             # Does the text have a default value?
             if typeheader.type.val in element_type_codes:
                 typeheader.text.val = element_type_codes[typeheader.type.val]
             # Add it to the list.
             typeheaders.append(typeheader)
         # Replace the placeholder for the list of type descriptors.
         enclosures[encidx].typedesc.val = typeheaders
         enclosures[encidx].typedesc.bo  = typedescbo
     # Loop yet again through enclosures, retrieving type descriptor texts.
     for encidx in range(numenclosures):
         for typenum in range(enctypecounts[encidx]):
             thislen = enclosures[encidx].typedesc.val[typenum].desclen.val
             type_descriptor_text[0][1] = thislen*8  # ugly, set the number of bits to extract
             # Replace the placeholder for the type descriptor text.
             enclosures[encidx].typedesc.val[typenum].text = Cmd.extract(data[bo:], type_descriptor_text, bo).text
             bo += thislen
     head.enclosures.val = enclosures
     self.page01 = head
     return head