def handle_register_HTD(self, register_packet):
        """
            Handle a Register HTD

            Always returns None
        """

        sata_header = register_packet.sata_header

        # Check if C bit is set to 0 -- see 11.2 Dl1 Note 1 -- no FIS is sent
        # I think we can ignore if C bit is set to 0 and go back to IDLE state
        # software reset could still happen -- not sure which bit is the SRST bit in the control register?
        if sata_header['C'] == 0:
            logger.debug(
                "Got HTD Register Packet but C bit is set to 0.  Ignoring.")
            return None

        # check if this is an NCQ command
        if sata_header[
                'command'] == NCQCommandType.ReadFPDMAQueued or sata_header[
                    'command'] == NCQCommandType.WriteFPDMAQueued:

            cmd = "READ"
            direction = G.SATA_OP.DIRECTION.READ
            if sata_header['command'] == NCQCommandType.WriteFPDMAQueued:
                cmd = "WRITE"
                direction = G.SATA_OP.DIRECTION.WRITE

            # NCQ uses features field for sector count
            logger.debug(
                "Got HTD Register Packet for NCQ %s -- TAG %d expecting %d bytes."
                % (cmd, sata_header['tag'],
                   sata_header['features'] * self.sector_size))

            #            if len(self.ncq_register_stack) > 0:
            #                logger.error("Our NCQ register stack will be greater than 1, so we have at least one outstanding NCQ register packet with NO Register ACK.  Stack size is %d" % len(self.ncq_register_stack))

            #            # add to our stack
            #            self.ncq_register_stack.append(register_packet)

            #No ACKS
            #            # change state to waiting for Register DTH
            #            self.STATE = self.WAIT_FOR_REGISTER_ACK
            #
            #            # deal with error checking when we get the Register DTH ACK back
            #            return None

            # check if the spot belonging to the associated TAG is empty
            if (not self.ncq_transactions_outstanding[sata_header['tag']]):
                # This TAG is not taken, so we just add
                self.ncq_transactions_outstanding[
                    sata_header['tag']] = register_packet

            else:
                logger.error(
                    "Received HTD NCQ Register Packet for TAG %d but it is already in use.  Using it anyway."
                    % sata_header['tag'])
                # still put it in there for now
                self.ncq_transactions_outstanding[
                    sata_header['tag']] = register_packet

                #don't need this if we accept the register packet anyway
                #return None

            # Associate this DTH Register packet
            # with the tag and prepare the disk sensor packet for aggregating data
            lba = sata_header['lba']

            # NOTE: NCQ uses features field instead of count for sector count
            sector_count = sata_header['features']

            disk_sensor_packet = DiskSensorPacket()
            disk_sensor_packet.sector = lba
            disk_sensor_packet.num_sectors = sector_count
            disk_sensor_packet.disk_operation = direction
            disk_sensor_packet.size = sector_count * self.sector_size
            disk_sensor_packet.data = ""

            self.ncq_data_outstanding[sata_header['tag']] = disk_sensor_packet

            # DO NOT set state to IDLE
            # Because now it looks like Register packets can come during other times
            # so we want to maintain the current state
            #            # set state to IDLE
            #
            #            self.STATE = self.DEVICE_IDLE

            return None

        # NCQ Management stuff
        elif sata_header['command'] == NCQCommandType.NCQQueueManagement:
            logger.debug(
                "Got Register Packet for NCQ Queue Management.  Ignoring for now."
            )
            # Don't need to change state
            return None

        # NON NCQ Register Packet
        else:
            logger.debug(
                "Got Non-NCQ HTD Register Packet, expected %d bytes." %
                (sata_header['count'] * self.sector_size))
            logger.debug("Command field is %d" % sata_header['command'])

            #            if len(self.ncq_register_stack) > 0:
            #                logger.error("Have more than 0 outstanding NCQ HTD Register Packets.  Non NCQ Register packets are not supposed to be sent while NCQ Register packets are still outstanding.  Size of stack is %d" % len(self.regular_register_stack))

            #            if len(self.regular_register_stack) > 0:
            #                logger.error("Will have more than one outstanding regular (non NCQ) HTD Register Packets.  Size of stack is %d" % len(self.regular_register_stack))

            # push this normal Register HTD packet on the stack
            self.regular_register_stack.append(register_packet)

            # prepare the disk sensor packet for aggregating data
            lba = sata_header['lba']
            sector_count = sata_header['count']
            direction = sata_header['direction']

            #             self.regular_disk_sensor_packet = DiskSensorPacket(lba,
            #                                          sector_count,
            #                                          direction,
            #                                          sector_count*self.sector_size,
            #                                          "")
            self.regular_disk_sensor_packet = DiskSensorPacket()
            self.regular_disk_sensor_packet.sector = lba
            self.regular_disk_sensor_packet.num_sectors = sector_count
            self.regular_disk_sensor_packet.disk_operation = direction
            self.regular_disk_sensor_packet.size = sector_count * self.sector_size
            self.regular_disk_sensor_packet.data = ""

            # Transition state now that we are waiting for data
            self.STATE = self.WAIT_FOR_NON_NCQ_DATA

            return None
示例#2
0
    def handle_register_HTD(self, register_packet):
        """
            Handle a Register HTD

            Always returns None
        """

        sata_header = register_packet.sata_header

        # Check if C bit is set to 0 -- see 11.2 Dl1 Note 1 -- no FIS is sent
        # I think we can ignore if C bit is set to 0 and go back to IDLE state
        # software reset could still happen -- not sure which bit is the SRST bit in the control register?
        if sata_header['C'] == 0:
            logger.debug("Got HTD Register Packet but C bit is set to 0.  Ignoring.")
            return None

        # check if this is an NCQ command
        if sata_header['command'] == NCQCommandType.ReadFPDMAQueued or sata_header['command'] == NCQCommandType.WriteFPDMAQueued:

            cmd = "READ"
            direction = G.SATA_OP.DIRECTION.READ
            if sata_header['command'] == NCQCommandType.WriteFPDMAQueued:
                cmd = "WRITE"
                direction = G.SATA_OP.DIRECTION.WRITE

            # NCQ uses features field for sector count
            logger.debug("Got HTD Register Packet for NCQ %s -- TAG %d expecting %d bytes." % (cmd, sata_header['tag'], sata_header['features']*self.sector_size))

            #            if len(self.ncq_register_stack) > 0:
            #                logger.error("Our NCQ register stack will be greater than 1, so we have at least one outstanding NCQ register packet with NO Register ACK.  Stack size is %d" % len(self.ncq_register_stack))

            #            # add to our stack
            #            self.ncq_register_stack.append(register_packet)

            #No ACKS
            #            # change state to waiting for Register DTH
            #            self.STATE = self.WAIT_FOR_REGISTER_ACK
            #
            #            # deal with error checking when we get the Register DTH ACK back
            #            return None

            # check if the spot belonging to the associated TAG is empty
            if (not self.ncq_transactions_outstanding[sata_header['tag']]):
                # This TAG is not taken, so we just add
                self.ncq_transactions_outstanding[sata_header['tag']] = register_packet

            else:
                logger.error("Received HTD NCQ Register Packet for TAG %d but it is already in use.  Using it anyway." % sata_header['tag'])
                # still put it in there for now
                self.ncq_transactions_outstanding[sata_header['tag']] = register_packet

                #don't need this if we accept the register packet anyway
                #return None


            # Associate this DTH Register packet
            # with the tag and prepare the disk sensor packet for aggregating data
            lba = sata_header['lba']

            # NOTE: NCQ uses features field instead of count for sector count
            sector_count = sata_header['features']


            disk_sensor_packet = DiskSensorPacket()
            disk_sensor_packet.sector = lba
            disk_sensor_packet.num_sectors =  sector_count
            disk_sensor_packet.disk_operation = direction
            disk_sensor_packet.size = sector_count*self.sector_size
            disk_sensor_packet.data = ""

            self.ncq_data_outstanding[sata_header['tag']] = disk_sensor_packet

            # DO NOT set state to IDLE
            # Because now it looks like Register packets can come during other times
            # so we want to maintain the current state
            #            # set state to IDLE
            #
            #            self.STATE = self.DEVICE_IDLE

            return None



        # NCQ Management stuff
        elif sata_header['command'] == NCQCommandType.NCQQueueManagement:
            logger.debug("Got Register Packet for NCQ Queue Management.  Ignoring for now.")
            # Don't need to change state
            return None

        # NON NCQ Register Packet
        else:
            logger.debug("Got Non-NCQ HTD Register Packet, expected %d bytes." % (sata_header['count']*self.sector_size))
            logger.debug("Command field is %d" % sata_header['command'])

            #            if len(self.ncq_register_stack) > 0:
            #                logger.error("Have more than 0 outstanding NCQ HTD Register Packets.  Non NCQ Register packets are not supposed to be sent while NCQ Register packets are still outstanding.  Size of stack is %d" % len(self.regular_register_stack))


            #            if len(self.regular_register_stack) > 0:
            #                logger.error("Will have more than one outstanding regular (non NCQ) HTD Register Packets.  Size of stack is %d" % len(self.regular_register_stack))

            # push this normal Register HTD packet on the stack
            self.regular_register_stack.append(register_packet)


            # prepare the disk sensor packet for aggregating data
            lba = sata_header['lba']
            sector_count = sata_header['count']
            direction = sata_header['direction']

            #             self.regular_disk_sensor_packet = DiskSensorPacket(lba,
            #                                          sector_count,
            #                                          direction,
            #                                          sector_count*self.sector_size,
            #                                          "")
            self.regular_disk_sensor_packet = DiskSensorPacket()
            self.regular_disk_sensor_packet.sector = lba
            self.regular_disk_sensor_packet.num_sectors = sector_count
            self.regular_disk_sensor_packet.disk_operation = direction
            self.regular_disk_sensor_packet.size = sector_count*self.sector_size
            self.regular_disk_sensor_packet.data = ""

            # Transition state now that we are waiting for data
            self.STATE = self.WAIT_FOR_NON_NCQ_DATA

            return None