+++ /dev/null
-/** @file\r
- Implementation of the EFI Block IO Protocol for ISA Floppy driver\r
-\r
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "IsaFloppy.h"\r
-\r
-/**\r
- Reset the Block Device.\r
-\r
- @param This Indicates a pointer to the calling context.\r
- @param ExtendedVerification Driver may perform diagnostics on reset.\r
-\r
- @retval EFI_SUCCESS The device was reset.\r
- @retval EFI_DEVICE_ERROR The device is not functioning properly and could\r
- not be reset.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FdcReset (\r
- IN EFI_BLOCK_IO_PROTOCOL *This,\r
- IN BOOLEAN ExtendedVerification\r
- )\r
-{\r
- FDC_BLK_IO_DEV *FdcDev;\r
-\r
- //\r
- // Reset the Floppy Disk Controller\r
- //\r
- FdcDev = FDD_BLK_IO_FROM_THIS (This);\r
-\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_PROGRESS_CODE,\r
- EFI_P_PC_RESET | EFI_PERIPHERAL_REMOVABLE_MEDIA,\r
- FdcDev->DevicePath\r
- );\r
-\r
- return FddReset (FdcDev);\r
-}\r
-\r
-/**\r
- Flush the Block Device.\r
-\r
- @param This Indicates a pointer to the calling context.\r
-\r
- @retval EFI_SUCCESS All outstanding data was written to the device\r
- @retval EFI_DEVICE_ERROR The device reported an error while writting back the data\r
- @retval EFI_NO_MEDIA There is no media in the device.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FddFlushBlocks (\r
- IN EFI_BLOCK_IO_PROTOCOL *This\r
- )\r
-{\r
- //\r
- // Not supported yet\r
- //\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Common report status code interface.\r
-\r
- @param This Pointer of FDC_BLK_IO_DEV instance\r
- @param Read Read or write operation when error occurrs\r
-**/\r
-VOID\r
-FddReportStatus (\r
- IN EFI_BLOCK_IO_PROTOCOL *This,\r
- IN BOOLEAN Read\r
- )\r
-{\r
- FDC_BLK_IO_DEV *FdcDev;\r
-\r
- FdcDev = FDD_BLK_IO_FROM_THIS (This);\r
-\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_ERROR_CODE,\r
- ((Read) ? EFI_P_EC_INPUT_ERROR : EFI_P_EC_OUTPUT_ERROR) | EFI_PERIPHERAL_REMOVABLE_MEDIA,\r
- FdcDev->DevicePath\r
- );\r
-}\r
-\r
-/**\r
- Read BufferSize bytes from Lba into Buffer.\r
-\r
- @param This Indicates a pointer to the calling context.\r
- @param MediaId Id of the media, changes every time the media is replaced.\r
- @param Lba The starting Logical Block Address to read from\r
- @param BufferSize Size of Buffer, must be a multiple of device block size.\r
- @param Buffer A pointer to the destination buffer for the data. The caller is\r
- responsible for either having implicit or explicit ownership of the buffer.\r
-\r
- @retval EFI_SUCCESS The data was read correctly from the device.\r
- @retval EFI_DEVICE_ERROR The device reported an error while performing the read.\r
- @retval EFI_NO_MEDIA There is no media in the device.\r
- @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.\r
- @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.\r
- @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,\r
- or the buffer is not on proper alignment.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FddReadBlocks (\r
- IN EFI_BLOCK_IO_PROTOCOL *This,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA Lba,\r
- IN UINTN BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- Status = FddReadWriteBlocks (This, MediaId, Lba, BufferSize, READ, Buffer);\r
-\r
- if (EFI_ERROR (Status)) {\r
- FddReportStatus (This, TRUE);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Write BufferSize bytes from Lba into Buffer.\r
-\r
- @param This Indicates a pointer to the calling context.\r
- @param MediaId The media ID that the write request is for.\r
- @param Lba The starting logical block address to be written. The caller is\r
- responsible for writing to only legitimate locations.\r
- @param BufferSize Size of Buffer, must be a multiple of device block size.\r
- @param Buffer A pointer to the source buffer for the data.\r
-\r
- @retval EFI_SUCCESS The data was written correctly to the device.\r
- @retval EFI_WRITE_PROTECTED The device can not be written to.\r
- @retval EFI_DEVICE_ERROR The device reported an error while performing the write.\r
- @retval EFI_NO_MEDIA There is no media in the device.\r
- @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.\r
- @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.\r
- @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,\r
- or the buffer is not on proper alignment.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FddWriteBlocks (\r
- IN EFI_BLOCK_IO_PROTOCOL *This,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA Lba,\r
- IN UINTN BufferSize,\r
- IN VOID *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- Status = FddReadWriteBlocks (This, MediaId, Lba, BufferSize, WRITE, Buffer);\r
-\r
- if (EFI_ERROR (Status)) {\r
- FddReportStatus (This, FALSE);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Read or Write a number of blocks to floppy disk\r
-\r
- @param This Indicates a pointer to the calling context.\r
- @param MediaId Id of the media, changes every time the media is replaced.\r
- @param Lba The starting Logical Block Address to read from\r
- @param BufferSize Size of Buffer, must be a multiple of device block size.\r
- @param Operation Specifies the read or write operation.\r
- @param Buffer A pointer to the destination buffer for the data. The caller is\r
- responsible for either having implicit or explicit ownership of the buffer.\r
-\r
- @retval EFI_SUCCESS The data was read correctly from the device.\r
- @retval EFI_DEVICE_ERROR The device reported an error while performing the read.\r
- @retval EFI_NO_MEDIA There is no media in the device.\r
- @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.\r
- @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.\r
- @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,\r
- or the buffer is not on proper alignment.\r
- @retval EFI_WRITE_PROTECTED The device can not be written to.\r
-\r
-**/\r
-EFI_STATUS\r
-FddReadWriteBlocks (\r
- IN EFI_BLOCK_IO_PROTOCOL *This,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA Lba,\r
- IN UINTN BufferSize,\r
- IN BOOLEAN Operation,\r
- OUT VOID *Buffer\r
- )\r
-{\r
- EFI_BLOCK_IO_MEDIA *Media;\r
- FDC_BLK_IO_DEV *FdcDev;\r
- UINTN BlockSize;\r
- UINTN NumberOfBlocks;\r
- UINTN BlockCount;\r
- EFI_STATUS Status;\r
- EFI_LBA Lba0;\r
- UINT8 *Pointer;\r
-\r
- //\r
- // Get the intrinsic block size\r
- //\r
- Media = This->Media;\r
- BlockSize = Media->BlockSize;\r
- FdcDev = FDD_BLK_IO_FROM_THIS (This);\r
-\r
- if (Operation == WRITE) {\r
- if (Lba == 0) {\r
- FdcFreeCache (FdcDev);\r
- }\r
- }\r
-\r
- //\r
- // Set the drive motor on\r
- //\r
- Status = MotorOn (FdcDev);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Check to see if media can be detected\r
- //\r
- Status = DetectMedia (FdcDev);\r
- if (EFI_ERROR (Status)) {\r
- MotorOff (FdcDev);\r
- FdcFreeCache (FdcDev);\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Check to see if media is present\r
- //\r
- if (!(Media->MediaPresent)) {\r
- MotorOff (FdcDev);\r
- FdcFreeCache (FdcDev);\r
- return EFI_NO_MEDIA;\r
- }\r
- //\r
- // Check to see if media has been changed\r
- //\r
- if (MediaId != Media->MediaId) {\r
- MotorOff (FdcDev);\r
- FdcFreeCache (FdcDev);\r
- return EFI_MEDIA_CHANGED;\r
- }\r
-\r
- if (BufferSize == 0) {\r
- MotorOff (FdcDev);\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (Operation == WRITE) {\r
- if (Media->ReadOnly) {\r
- MotorOff (FdcDev);\r
- return EFI_WRITE_PROTECTED;\r
- }\r
- }\r
- //\r
- // Check the parameters for this read/write operation\r
- //\r
- if (Buffer == NULL) {\r
- MotorOff (FdcDev);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (BufferSize % BlockSize != 0) {\r
- MotorOff (FdcDev);\r
- return EFI_BAD_BUFFER_SIZE;\r
- }\r
-\r
- if (Lba > Media->LastBlock) {\r
- MotorOff (FdcDev);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (((BufferSize / BlockSize) + Lba - 1) > Media->LastBlock) {\r
- MotorOff (FdcDev);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Operation == READ) {\r
- //\r
- // See if the data that is being read is already in the cache\r
- //\r
- if (FdcDev->Cache != NULL) {\r
- if (Lba == 0 && BufferSize == BlockSize) {\r
- MotorOff (FdcDev);\r
- CopyMem ((UINT8 *) Buffer, (UINT8 *) FdcDev->Cache, BlockSize);\r
- return EFI_SUCCESS;\r
- }\r
- }\r
- }\r
- //\r
- // Set up Floppy Disk Controller\r
- //\r
- Status = Setup (FdcDev);\r
- if (EFI_ERROR (Status)) {\r
- MotorOff (FdcDev);\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- NumberOfBlocks = BufferSize / BlockSize;\r
- Lba0 = Lba;\r
- Pointer = Buffer;\r
-\r
- //\r
- // read blocks in the same cylinder.\r
- // in a cylinder , there are 18 * 2 = 36 blocks\r
- //\r
- BlockCount = GetTransferBlockCount (FdcDev, Lba, NumberOfBlocks);\r
- while ((BlockCount != 0) && !EFI_ERROR (Status)) {\r
- Status = ReadWriteDataSector (FdcDev, Buffer, Lba, BlockCount, Operation);\r
- if (EFI_ERROR (Status)) {\r
- MotorOff (FdcDev);\r
- FddReset (FdcDev);\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- Lba += BlockCount;\r
- NumberOfBlocks -= BlockCount;\r
- Buffer = (VOID *) ((UINTN) Buffer + BlockCount * BlockSize);\r
- BlockCount = GetTransferBlockCount (FdcDev, Lba, NumberOfBlocks);\r
- }\r
-\r
- Buffer = Pointer;\r
-\r
- //\r
- // Turn the motor off\r
- //\r
- MotorOff (FdcDev);\r
-\r
- if (Operation == READ) {\r
- //\r
- // Cache the data read\r
- //\r
- if (Lba0 == 0 && FdcDev->Cache == NULL) {\r
- FdcDev->Cache = AllocateCopyPool (BlockSize, Buffer);\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-/**\r
- Free cache for a floppy disk.\r
-\r
- @param FdcDev A Pointer to FDC_BLK_IO_DEV instance\r
-\r
-**/\r
-VOID\r
-FdcFreeCache (\r
- IN FDC_BLK_IO_DEV *FdcDev\r
- )\r
-{\r
- if (FdcDev->Cache != NULL) {\r
- FreePool (FdcDev->Cache);\r
- FdcDev->Cache = NULL;\r
- }\r
-}\r