Ejemplo n.º 1
0
/**********************************************************************//**
*  Purpose	  :  Turn Enable line high or low.
*  Parameters :  none
*  Return	  :  none
*************************************************************************/
void  DC_Motor::Enable( bool mEnable )
{
	if (mEnable)
		MotorOn();
	else
		MotorOff();
}
Ejemplo n.º 2
0
/// FIXME: Intelligente Motorverwaltung
int FloppyDrive::ReadSector(int driveNumber, uint8_t cylinder, uint8_t head, uint8_t sector)
{
	uint8_t cyl0, status;

	ReadTransfer();

	MotorOn(driveNumber);

	Seek(driveNumber, cylinder, head);

	for (int i = 0; i<5; i++)
	{
		SendCommand(CMD_READ);
		SendCommand((head<<2) | driveNumber);
		SendCommand(cylinder);
		SendCommand(head);
		SendCommand(sector);

		SendCommand(2);
		SendCommand(18);
		SendCommand(27);
		SendCommand(0xFF);

		WaitIRQ();

		uint8_t st0 = ReadData();  //st0
		ReadData();  //st1
		ReadData();  //st2
		ReadData();  //cylinder
		ReadData();  //head
		ReadData();  //sector
		ReadData();  //sectorsize

		Sense(&cyl0, &status);

		if((st0 & 0xC0) == 0)
		{
			MotorOff(driveNumber);
			return NO_ERROR;
		}
	}

	MotorOff(driveNumber);
	return ERR_TIMEOUT;
}
Ejemplo n.º 3
0
void FloppyDrive::Calibrate(int driveNumber)
{
	uint8_t st0, cyl0;

	Select(driveNumber);
	MotorOn(driveNumber);

	SendCommand(CMD_CALIBRATE);
	SendCommand(driveNumber);

	if(WaitIRQ() == ERR_TIMEOUT)
	{
		debug_printf("[ FDC ] Timeout while waiting for IRQ!\n");
	}

	//Sense(&st0, &cyl0);

	MotorOff(driveNumber);
}
Ejemplo n.º 4
0
/**
  Update the disk media properties and if necessary reinstall Block I/O interface.
 
  @param  FdcDev FDC_BLK_IO_DEV *: A pointer to FDC_BLK_IO_DEV
  
  @retval  EFI_SUCCESS:    Do the operation successfully
  @retval  EFI_DEVICE_ERROR: Fail to the operation

**/
EFI_STATUS
DetectMedia (
  IN FDC_BLK_IO_DEV  *FdcDev
  )
{
  EFI_STATUS  Status;
  BOOLEAN     Reset;
  BOOLEAN     ReadOnlyLastTime;
  BOOLEAN     MediaPresentLastTime;

  Reset                = FALSE;
  ReadOnlyLastTime     = FdcDev->BlkIo.Media->ReadOnly;
  MediaPresentLastTime = FdcDev->BlkIo.Media->MediaPresent;

  //
  // Check disk change
  //
  Status = DisketChanged (FdcDev);

  if (Status == EFI_MEDIA_CHANGED) {
    FdcDev->BlkIo.Media->MediaId++;
    FdcDev->BlkIo.Media->MediaPresent = TRUE;
    Reset = TRUE;
  } else if (Status == EFI_NO_MEDIA) {
    FdcDev->BlkIo.Media->MediaPresent = FALSE;
  } else if (Status != EFI_SUCCESS) {
    MotorOff (FdcDev);
    return Status;
    //
    // EFI_DEVICE_ERROR
    //
  }

  if (FdcDev->BlkIo.Media->MediaPresent) {
    //
    // Check disk write protected
    //
    Status = SenseDrvStatus (FdcDev, 0);
    if (Status == EFI_WRITE_PROTECTED) {
      FdcDev->BlkIo.Media->ReadOnly = TRUE;
    } else {
      FdcDev->BlkIo.Media->ReadOnly = FALSE;
    }
  }

  if (FdcDev->BlkIo.Media->MediaPresent && (ReadOnlyLastTime != FdcDev->BlkIo.Media->ReadOnly)) {
    Reset = TRUE;
  }

  if (MediaPresentLastTime != FdcDev->BlkIo.Media->MediaPresent) {
    Reset = TRUE;
  }

  if (Reset) {
    Status = gBS->ReinstallProtocolInterface (
                    FdcDev->Handle,
                    &gEfiBlockIoProtocolGuid,
                    &FdcDev->BlkIo,
                    &FdcDev->BlkIo
                    );

    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 5
0
/**
  Do recalibrate and check if the drive is present or not
  and set the media parameters if the driver is present.
  
  @param[in] FdcDev  A pointer to the FDC_BLK_IO_DEV

  @retval EFI_SUCCESS       The floppy disk drive is present
  @retval EFI_DEVICE_ERROR  The floppy disk drive is not present
**/
EFI_STATUS
FddIdentify (
  IN FDC_BLK_IO_DEV  *FdcDev
  )
{
  EFI_STATUS  Status;

  //
  // Set Floppy Disk Controller's motor on
  //
  Status = MotorOn (FdcDev);
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  Status = Recalibrate (FdcDev);

  if (EFI_ERROR (Status)) {
    MotorOff (FdcDev);
    FdcDev->ControllerState->NeedRecalibrate = TRUE;
    return EFI_DEVICE_ERROR;
  }
  //
  // Set Media Parameter
  //
  FdcDev->BlkIo.Media->RemovableMedia = TRUE;
  FdcDev->BlkIo.Media->MediaPresent   = TRUE;
  FdcDev->BlkIo.Media->MediaId = 0;

  //
  // Check Media
  //
  Status = DisketChanged (FdcDev);

  if (Status == EFI_NO_MEDIA) {
    FdcDev->BlkIo.Media->MediaPresent = FALSE;
  } else if ((Status != EFI_MEDIA_CHANGED) &&
             (Status != EFI_SUCCESS)) {
    MotorOff (FdcDev);
    return Status;
  }

  //
  // Check Disk Write Protected
  //
  Status = SenseDrvStatus (FdcDev, 0);

  if (Status == EFI_WRITE_PROTECTED) {
    FdcDev->BlkIo.Media->ReadOnly = TRUE;
  } else if (Status == EFI_SUCCESS) {
    FdcDev->BlkIo.Media->ReadOnly = FALSE;
  } else {
    return EFI_DEVICE_ERROR;
  }

  MotorOff (FdcDev);

  //
  // Set Media Default Type
  //
  FdcDev->BlkIo.Media->BlockSize  = DISK_1440K_BYTEPERSECTOR;
  FdcDev->BlkIo.Media->LastBlock  = DISK_1440K_EOT * 2 * (DISK_1440K_MAXTRACKNUM + 1) - 1;

  return EFI_SUCCESS;
}
Ejemplo n.º 6
0
/**
  Read or Write a number of blocks to floppy disk

  @param  This       Indicates a pointer to the calling context.
  @param  MediaId    Id of the media, changes every time the media is replaced.
  @param  Lba        The starting Logical Block Address to read from
  @param  BufferSize Size of Buffer, must be a multiple of device block size.
  @param  Operation  Specifies the read or write operation.
  @param  Buffer     A pointer to the destination buffer for the data. The caller is
                     responsible for either having implicit or explicit ownership of the buffer.

  @retval EFI_SUCCESS           The data was read correctly from the device.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing the read.
  @retval EFI_NO_MEDIA          There is no media in the device.
  @retval EFI_MEDIA_CHANGED     The MediaId does not matched the current device.
  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, 
                                or the buffer is not on proper alignment.
  @retval EFI_WRITE_PROTECTED   The device can not be written to.

**/
EFI_STATUS
FddReadWriteBlocks (
  IN  EFI_BLOCK_IO_PROTOCOL  *This,
  IN  UINT32                 MediaId,
  IN  EFI_LBA                Lba,
  IN  UINTN                  BufferSize,
  IN  BOOLEAN                Operation,
  OUT VOID                   *Buffer
  )
{
  EFI_BLOCK_IO_MEDIA  *Media;
  FDC_BLK_IO_DEV      *FdcDev;
  UINTN               BlockSize;
  UINTN               NumberOfBlocks;
  UINTN               BlockCount;
  EFI_STATUS          Status;
  EFI_LBA             Lba0;
  UINT8               *Pointer;

  //
  // Get the intrinsic block size
  //
  Media     = This->Media;
  BlockSize = Media->BlockSize;
  FdcDev    = FDD_BLK_IO_FROM_THIS (This);

  if (Operation == WRITE) {
    if (Lba == 0) {
      FdcFreeCache (FdcDev);
    }
  }

  //
  // Set the drive motor on
  //
  Status = MotorOn (FdcDev);
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }
  //
  // Check to see if media can be detected
  //
  Status = DetectMedia (FdcDev);
  if (EFI_ERROR (Status)) {
    MotorOff (FdcDev);
    FdcFreeCache (FdcDev);
    return EFI_DEVICE_ERROR;
  }
  //
  // Check to see if media is present
  //
  if (!(Media->MediaPresent)) {
    MotorOff (FdcDev);
    FdcFreeCache (FdcDev);
    return EFI_NO_MEDIA;
  }
  //
  // Check to see if media has been changed
  //
  if (MediaId != Media->MediaId) {
    MotorOff (FdcDev);
    FdcFreeCache (FdcDev);
    return EFI_MEDIA_CHANGED;
  }

  if (BufferSize == 0) {
    MotorOff (FdcDev);
    return EFI_SUCCESS;
  }

  if (Operation == WRITE) {
    if (Media->ReadOnly) {
      MotorOff (FdcDev);
      return EFI_WRITE_PROTECTED;
    }
  }
  //
  // Check the parameters for this read/write operation
  //
  if (Buffer == NULL) {
    MotorOff (FdcDev);
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize % BlockSize != 0) {
    MotorOff (FdcDev);
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Lba > Media->LastBlock) {
    MotorOff (FdcDev);
    return EFI_INVALID_PARAMETER;
  }

  if (((BufferSize / BlockSize) + Lba - 1) > Media->LastBlock) {
    MotorOff (FdcDev);
    return EFI_INVALID_PARAMETER;
  }

  if (Operation == READ) {
    //
    // See if the data that is being read is already in the cache
    //
    if (FdcDev->Cache != NULL) {
      if (Lba == 0 && BufferSize == BlockSize) {
        MotorOff (FdcDev);
        CopyMem ((UINT8 *) Buffer, (UINT8 *) FdcDev->Cache, BlockSize);
        return EFI_SUCCESS;
      }
    }
  }
  //
  // Set up Floppy Disk Controller
  //
  Status = Setup (FdcDev);
  if (EFI_ERROR (Status)) {
    MotorOff (FdcDev);
    return EFI_DEVICE_ERROR;
  }

  NumberOfBlocks  = BufferSize / BlockSize;
  Lba0            = Lba;
  Pointer         = Buffer;

  //
  // read blocks in the same cylinder.
  // in a cylinder , there are 18 * 2 = 36 blocks
  //
  BlockCount = GetTransferBlockCount (FdcDev, Lba, NumberOfBlocks);
  while ((BlockCount != 0) && !EFI_ERROR (Status)) {
    Status = ReadWriteDataSector (FdcDev, Buffer, Lba, BlockCount, Operation);
    if (EFI_ERROR (Status)) {
      MotorOff (FdcDev);
      FddReset (FdcDev);
      return EFI_DEVICE_ERROR;
    }

    Lba += BlockCount;
    NumberOfBlocks -= BlockCount;
    Buffer      = (VOID *) ((UINTN) Buffer + BlockCount * BlockSize);
    BlockCount  = GetTransferBlockCount (FdcDev, Lba, NumberOfBlocks);
  }

  Buffer = Pointer;

  //
  // Turn the motor off
  //
  MotorOff (FdcDev);

  if (Operation == READ) {
    //
    // Cache the data read
    //
    if (Lba0 == 0 && FdcDev->Cache == NULL) {
      FdcDev->Cache = AllocateCopyPool (BlockSize, Buffer);
    }
  }

  return EFI_SUCCESS;

}