/**********************************************************************//** * Purpose : Turn Enable line high or low. * Parameters : none * Return : none *************************************************************************/ void DC_Motor::Enable( bool mEnable ) { if (mEnable) MotorOn(); else MotorOff(); }
/// 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; }
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); }
/** 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; }
/** 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; }
/** 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; }