コード例 #1
0
ファイル: ata.py プロジェクト: jmony/unununium
    def wait_not_busy(self, drq=None, drdy=None, dsc=None, error=None):
        '''Wait for BSY in the status register to be set to 0.
        
        The other parameters are used to check that the coresponding bit in the
        status register is in the given state (True or False; do not use
        integers). If not so, ATAError is raised.
        '''
        mask = 0x80
        value = 0x00

        for state, bit in [(drq, 0x08), (drdy, 0x40), (dsc, 0x10),
                           (error, 0x01)]:
            if state is not None:
                mask |= bit
                if state:
                    value |= bit

        start = uuutime.get_time()
        while uuutime.get_time() - start < self.busy_timeout:
            r = self.status_reg
            if error is False:
                if r & 0x81 == 0x01:
                    raise ATAError('status: 0x%02x' % r)
            if r & mask == value:
                return r
        raise TimeoutError(
            'Timeout waiting for ATA controller, status 0x%02x' % r)
コード例 #2
0
ファイル: floppy.py プロジェクト: jmony/unununium
 def _wait_not_busy(self):
     '''Wait until the floppy indicates it's not busy or positioning heads.'''
     start = uuutime.get_time()
     while uuutime.get_time() - start < _busy_timeout:
         msr = self._read_msr()
         msr &= 0x10
         if not msr:
             return
     raise TimeoutError(
         'timeout waiting for FDC to complete command. MSR: %x' % msr)
コード例 #3
0
ファイル: floppy.py プロジェクト: jmony/unununium
 def _wait_rqm(self):
     '''Wait for RQM to be set in the MSR.
     
     Returns the last value of the MSR, which can be used to check DIO.
     '''
     start = uuutime.get_time()
     while uuutime.get_time() - start < _data_timeout:
         msr = self._read_msr()
         if msr & _msr_rqm:
             return msr
     raise FloppyError('timeout waiting for MQR')
コード例 #4
0
ファイル: floppy.py プロジェクト: jmony/unununium
    def _check_interrupt_status(self):
        '''Execute check interrupt status command and return result.

        Result is a pair (st0, current cylinder).
        '''
        time = uuutime.get_time()
        msr = None
        # For some odd reason, sometimes my FDC will return only one byte from
        # this command, and assuming it returns st0, it doesn't indicate an
        # error. Retrying the command makes it work. If I add a 3s delay here,
        # the problem subsides. However, I can't find anything that
        # consistantly changes within that time that indicates the command
        # should be issued. <*****@*****.**>
        for retry in xrange(_int_status_retries):
            self._wait_not_busy()
            self._write_data(_cmd_int_status)
            st0 = self._read_data()
            try:
                # if this command is issued without pending interrupts, FDC treats it
                # as an invalid command.

                cyl = self._read_data()
            except StateError, x:
                self._check_st(st0)
                if retry == _int_status_retries - 1:
                    raise
                if _show_errors:
                    print 'int status failed, retrying: %r' % x
                continue
            return st0, cyl
コード例 #5
0
ファイル: floppy.py プロジェクト: jmony/unununium
    def read_sectors(self, first, count):
        'Read any number of sectors from the drive, and return them as a string.'

        if first < 0 or count < 0 or first + count > _total_sectors:
            raise ValueError('request for sectors beyond disk capacity')

        if count == 0:
            return ''

        result = ''
        self.set_motor(True)
        try:
            self._set_datarate(0)
            while count:
                while True:
                    # retry the command ignoring errors until the spinup
                    # time has passed. This way no time will be wasted by
                    # waiting too long, and no chance of error exists
                    # because reads are CRC checked.
                    try:
                        result += self._read_sector(*lba_to_chs(first))
                    except IncompleteError:
                        if uuutime.get_time(
                        ) - self.motor_on_at > _motor_spinup_time:
                            raise
                    else:
                        break
                first += 1
                count -= 1

            return result
        finally:
            self.set_motor(False)
コード例 #6
0
ファイル: floppy.py プロジェクト: jmony/unununium
class Drive(block_device.BlockDevice, vfs.Node):

    allow_write = True
    allow_read = True
    block_size = 512
    _current_cyl = None
    _need_calibrate = True

    def __init__(self):
        self.irq = 6
        irq.monitor(self.irq)
        self.motor_on = False
        self._reset()
        super(Drive, self).__init__()
        self.filesystem = self

    def read_sectors(self, first, count):
        'Read any number of sectors from the drive, and return them as a string.'

        if first < 0 or count < 0 or first + count > _total_sectors:
            raise ValueError('request for sectors beyond disk capacity')

        if count == 0:
            return ''

        result = ''
        self.set_motor(True)
        try:
            self._set_datarate(0)
            while count:
                while True:
                    # retry the command ignoring errors until the spinup
                    # time has passed. This way no time will be wasted by
                    # waiting too long, and no chance of error exists
                    # because reads are CRC checked.
                    try:
                        result += self._read_sector(*lba_to_chs(first))
                    except IncompleteError:
                        if uuutime.get_time(
                        ) - self.motor_on_at > _motor_spinup_time:
                            raise
                    else:
                        break
                first += 1
                count -= 1

            return result
        finally:
            self.set_motor(False)

    def write_sectors(self, first, data):
        'Write any number of sectors from the drive. `data` must be a multiple of 512 bytes in length.'

        if (len(data) % self.block_size):
            raise ValueError(
                'data must be a multiple of the block size in length')
        count = len(data) / self.block_size

        if first < 0 or count < 0 or first + count > _total_sectors:
            raise ValueError('request for sectors beyond disk capacity')

        self.set_motor(True)
        try:
            self._set_datarate(0)
            data_pos = 0
            while count:
                this_data = data[data_pos:data_pos + 512]
                self._write_sector(lba_to_chs(first), this_data)
                first += 1
                count -= 1
                data_pos += 512
        finally:
            self.set_motor(False)

    def set_motor(self, state):
        if state and (self.motor_on is False):
            io.outb(_dor_port, _dor_not_reset | _dor_dma | _dor_mota)
            self.motor_on_at = uuutime.get_time()
            self.motor_on = True


#        elif (not state) and (self.motor_on is True):
#            io.outb( _dor_port, _dor_not_reset )
#            del self.motor_on_at
#            self.motor_on = False

    def _reset(self):
        io.outb(_dor_port, 0)
        io.outb(_dor_port, _dor_not_reset)
        self._set_datarate(0)
        for _ in xrange(4):
            self._check_interrupt_status()

    def _write_sector(self, (cyl, head, sector), data):
        if len(data) != 512:
            raise ValueError('data length must be exactly 512 bytes')
        io.string_to_mem(_buffer_address, data)
        for retry in xrange(_rw_retries):
            self._seek_heads(cyl)
            self._program_dma(0x4a, self.block_size, _buffer_address)
            while uuutime.get_time() - self.motor_on_at < _motor_spinup_time:
                pass
            self._wait_not_busy()
            irq.reset(self.irq)
            self._write_data(_cmd_write_sectors)
            self._write_sector_id(cyl, head, sector)
            irq.sleep_until(self.irq)
            st0, st1, st2, _, _, _, _ = self._read_result()
            try:
                self._check_st(st0, st1, st2)
            except FloppyError, x:
                if retry == _rw_retries - 1:
                    raise
                if _show_errors:
                    print 'error writing %i %i %i:' % (cyl, head,
                                                       sector), x, '(retrying)'
            else:
                return
コード例 #7
0
ファイル: floppy.py プロジェクト: jmony/unununium
 def set_motor(self, state):
     if state and (self.motor_on is False):
         io.outb(_dor_port, _dor_not_reset | _dor_dma | _dor_mota)
         self.motor_on_at = uuutime.get_time()
         self.motor_on = True