예제 #1
0
 def _GetFlashId(self, dctl):
     if self.chipgen == 0:
         info = []
         for ch in [0, 1, 3, 7]:
             # TODO: send nand reset command first?
             # 4-byte fid, 2 per channel
             cdb = [0] * 16
             cdb[0] = 0xD0
             cdb[1] = ch
             cdb[2] = 0xF0
             cdb[3] = 0x90
             cdb[4] = 0xF1
             cdb[5] = 1
             cdb[6] = 0
             cdb[7] = 0xF2
             cdb[8] = 4
             data = [0] * 512
             data = scsi.ScsiRequest(dctl, cdb, data)
             if _verbose:
                 open("_alc_D0%02X.bin" % ch, "wb+").write(bytearray(data))
             info += data[0:16]
             info += data[0x80:0x80 + 16]
         return info
     else:
         cdb = [0] * 16
         cdb[0] = 0xFA
         cdb[1] = 0
         data = [0] * 512
         info = scsi.ScsiRequest(dctl, cdb, data)
         if _verbose: open("_alc_FA00.bin", "wb+").write(bytearray(info))
         return info
예제 #2
0
    def _GetFirmwareVersion(self, dctl):
        version = -1
        cdb = scsi.CDB(cdb=[0xFA, 0x0E])
        data = [0] * 512
        data = scsi.ScsiRequest(dctl, cdb.data, data)

        if data[6] >= 0xF0:
            version = (data[6] << 24) | (data[4] << 16) | (
                data[5] << 8) | data[7]
        elif data[6] == 0x36:
            version = (data[6] << 24) | (data[7] << 16) | (
                data[4] << 8) | data[5]
        else:
            version = (data[6] << 8) | data[7]

        data = [0] * 512 * 18
        cdb = scsi.CDB(cdb=[0xFA, 0x10])
        cdb.PB(2, len(data) / 512).PB(4, 0xC0)
        data = scsi.ScsiRequest(dctl, cdb.data, data, mayFail=True)

        if data != None:
            if _verbose: open("_alc_FA10.bin", "wb+").write(bytearray(data))
            if data[0xFFB] == 0x51:
                version |= data[0xFFA] << 32
        else:
            if _verbose:
                print("%s: Command 0x%02X%02X failed (norm for old chips)" %
                      (Name(), cdb.data[0], cdb.data[1]))

        return version
예제 #3
0
    def Detect(self, dctl, force=False):

        cdb = [0] * 16
        cdb[0] = 0x9A
        data = [0] * 512
        info = scsi.ScsiRequest(dctl, cdb, data)
        if info == None:
            if _verbose:
                print("%s: Command 0x%02X failed" % (Name(), cdb[0]))
            return False

        if _verbose: open("_alc_9A.bin", "wb+").write(bytearray(info))

        self.chipver = info[4] * 256 + info[5]

        for chip in knownControllers:
            if chip.Chip == self.chipver:
                self.chips.append(chip)
                self.chipgen = chip.Gen

        if info[0x2B] == 0xAA:
            self.fwloaded = info[0x2C] != 0
            self.fwversionold = info[0x2D] * 256 + info[0x2E]
            # 0x2E is always zero?

        if self.chipver in [0x0C0E, 0xAA06]:
            self.badblocks = info[0x25]
        elif self.fwloaded:
            self.badblocks = info[0x25] * 4

        return True
예제 #4
0
 def _GetFlashId(self, dctl):
     cdb = [0] * 12
     cdb[0] = 6
     cdb[1] = 0x56  # also 4, but unavailable on newer firmwares
     data = [0] * 512
     info = scsi.ScsiRequest(dctl, cdb, data)
     return info
예제 #5
0
 def _GetFlashId(self, dctl):
     cdb = [0] * 16
     cdb[0] = 0xF0
     cdb[1] = 0x06
     cdb[11] = 1  # sectors
     data = [0] * 512
     info = scsi.ScsiRequest(dctl, cdb, data)
     return info
예제 #6
0
    def ProcessDevice(self, dctl, report):

        cdb = [0] * 16
        cdb[0] = 0xFA
        cdb[1] = 0x0E
        data = [0] * 512
        info = scsi.ScsiRequest(dctl, cdb, data)
        if info == None:
            if _verbose:
                print("%s: Command 0x%02X%02X failed" %
                      (Name(), cdb[0], cdb[1]))
        else:
            if _verbose: open("_alc_FA0E.bin", "wb+").write(bytearray(info))
            self.chiprev = info[0xB]

        report.append(("Controller", self.ControllerName()))

        if self.fwloaded:
            if self.chipgen == 0:
                self.fwversion = self.fwversionold
                self.fwversionstr = "%02d%02d" % (self.fwversionold >> 8,
                                                  self.fwversionold & 255)
            else:
                self.fwversion = self._GetFirmwareVersion(dctl)
                if self.fwversion <= 0xFFFF:
                    self.fwversionstr = "%04X" % self.fwversion
                else:
                    self.fwversionstr = "%08X" % (self.fwversion & 0xFFFFFFFF)
                if (self.fwversion & 0xFF000000) == 0xF0000000:
                    self.fwversionstr += "_%02X" (self.fwversion >> 32)
        else:
            self.fwversionstr = "Not loaded"

        report.append(("Firmware", self.fwversionstr))

        flashinfo = self._GetFlashId(dctl)
        if flashinfo != None:
            #TODO: 8-byte entries on old versions?
            flashids = [flashinfo[i * 16:i * 16 + 6] for i in range(8)]
            # pick a non-zero entry
            for flash in flashids:
                if flash[:6] != [0, 0, 0, 0, 0, 0]:
                    break
            else:
                flash = flashids[0]
            report.append(("Flash ID", flash, "fid"))
        else:
            report.append(("Flash ID", "Unavailable"))

        return report
예제 #7
0
 def _GetInfoPage(self, dctl, kind="", size=512 + 16):
     cdb = [0] * 12
     cdb[0] = 6
     cdb[1] = 5
     if kind != "":
         for i in range(min(len(kind), 10)):
             cdb[2 + i] = ord(kind[i])
     data = [0] * (size)
     info = scsi.ScsiRequest(dctl, cdb, data)
     if info != None:
         #open("_ph_0605%s.bin"%kind, "wb+").write(bytearray(info))
         if _verbose == True:
             if len(info) == 512 + 16:
                 if info[512] != ord('I') or info[513] != ord('F'):
                     print("* Warning: Strange info page mark")
     return info
예제 #8
0
    def Detect(self, dctl, force=False):

        cdb = [0] * 16
        cdb[0] = 0xF0
        cdb[1] = 0x2A
        cdb[11] = 1  # sectors
        data = [0] * 512
        info = scsi.ScsiRequest(dctl, cdb, data)
        if info == None:
            return False

        #open("_smi_F02A.bin", "wb+").write(bytearray(info))

        if info[0x1AE] == ord('S') and info[0x1AF] == ord('M'):
            self.model = "".join([chr(x) for x in info[0x1AE:0x1AE + 8]
                                  ]).split('\0')[0]
            self.version = "".join([chr(x)
                                    for x in info[0x190:0x1AE]]).split('\0')[0]
        else:
            return False

        return True