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
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
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
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