+++ /dev/null
-/** @file\r
-\r
-CEATA specific functions implementation\r
-\r
-Copyright (c) 2013-2015 Intel Corporation.\r
-\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "SDMediaDevice.h"\r
-\r
-/**\r
- Send RW_MULTIPLE_REGISTER command\r
-\r
- @param CardData Pointer to CARD_DATA.\r
- @param Address Register address.\r
- @param ByteCount Buffer size.\r
- @param Write TRUE means write, FALSE means read.\r
- @param Buffer Buffer pointer.\r
-\r
- @retval EFI_SUCCESS Success\r
- @retval EFI_DEVICE_ERROR Hardware Error\r
- @retval EFI_INVALID_PARAMETER Parameter is error\r
- @retval EFI_NO_MEDIA No media\r
- @retval EFI_MEDIA_CHANGED Media Change\r
- @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
-\r
-**/\r
-EFI_STATUS\r
-ReadWriteMultipleRegister (\r
- IN CARD_DATA *CardData,\r
- IN UINT16 Address,\r
- IN UINT8 ByteCount,\r
- IN BOOLEAN Write,\r
- IN UINT8 *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 Argument;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- if ((Address % 4 != 0) || (ByteCount % 4 != 0)) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Exit;\r
- }\r
-\r
- Argument = (Address << 16) | ByteCount;\r
- if (Write) {\r
- Argument |= BIT31;\r
- }\r
-\r
-\r
- if (Write) {\r
- CopyMem (CardData->AlignedBuffer, Buffer, ByteCount);\r
-\r
- Status = SendCommand (\r
- CardData,\r
- RW_MULTIPLE_REGISTER,\r
- Argument,\r
- OutData,\r
- CardData->AlignedBuffer,\r
- ByteCount,\r
- ResponseR1b,\r
- TIMEOUT_DATA,\r
- (UINT32*)&(CardData->CardStatus)\r
- );\r
- } else {\r
- Status = SendCommand (\r
- CardData,\r
- RW_MULTIPLE_REGISTER,\r
- Argument,\r
- InData,\r
- CardData->AlignedBuffer,\r
- ByteCount,\r
- ResponseR1,\r
- TIMEOUT_DATA,\r
- (UINT32*)&(CardData->CardStatus)\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- CopyMem (Buffer, CardData->AlignedBuffer, ByteCount);\r
- }\r
-\r
- }\r
-Exit:\r
- return Status;\r
-}\r
-\r
-/**\r
- Send ReadWriteMultipleBlock command with RW_MULTIPLE_REGISTER command\r
-\r
- @param CardData Pointer to CARD_DATA.\r
- @param DataUnitCount Buffer size in 512 bytes unit.\r
- @param Write TRUE means write, FALSE means read.\r
- @param Buffer Buffer pointer.\r
-\r
- @retval EFI_SUCCESS Success\r
- @retval EFI_DEVICE_ERROR Hardware Error\r
- @retval EFI_INVALID_PARAMETER Parameter is error\r
- @retval EFI_NO_MEDIA No media\r
- @retval EFI_MEDIA_CHANGED Media Change\r
- @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
-\r
-**/\r
-EFI_STATUS\r
-ReadWriteMultipleBlock (\r
- IN CARD_DATA *CardData,\r
- IN UINT16 DataUnitCount,\r
- IN BOOLEAN Write,\r
- IN UINT8 *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_SD_HOST_IO_PROTOCOL *SDHostIo;\r
- UINT32 TransferLength;\r
-\r
- Status = EFI_SUCCESS;\r
- SDHostIo = CardData->SDHostIo;\r
-\r
- TransferLength = DataUnitCount * DATA_UNIT_SIZE;\r
- if (TransferLength > SDHostIo->HostCapability.BoundarySize) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Write) {\r
- CopyMem (CardData->AlignedBuffer, Buffer, TransferLength);\r
-\r
- Status = SendCommand (\r
- CardData,\r
- RW_MULTIPLE_BLOCK,\r
- (DataUnitCount | BIT31),\r
- OutData,\r
- CardData->AlignedBuffer,\r
- TransferLength,\r
- ResponseR1b,\r
- TIMEOUT_DATA,\r
- (UINT32*)&(CardData->CardStatus)\r
- );\r
- } else {\r
- Status = SendCommand (\r
- CardData,\r
- RW_MULTIPLE_BLOCK,\r
- DataUnitCount,\r
- InData,\r
- CardData->AlignedBuffer,\r
- TransferLength,\r
- ResponseR1,\r
- TIMEOUT_DATA,\r
- (UINT32*)&(CardData->CardStatus)\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- CopyMem (Buffer, CardData->AlignedBuffer, TransferLength);\r
- }\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Send software reset\r
-\r
- @param CardData Pointer to CARD_DATA.\r
-\r
- @retval EFI_SUCCESS Success\r
- @retval EFI_DEVICE_ERROR Hardware Error\r
- @retval EFI_INVALID_PARAMETER Parameter is error\r
- @retval EFI_NO_MEDIA No media\r
- @retval EFI_MEDIA_CHANGED Media Change\r
- @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
-\r
-**/\r
-EFI_STATUS\r
-SoftwareReset (\r
- IN CARD_DATA *CardData\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 Data;\r
- UINT32 TimeOut;\r
-\r
- Data = BIT2;\r
-\r
- Status = FastIO (CardData, Reg_Control, &Data, TRUE);\r
- if (EFI_ERROR (Status)) {\r
- goto Exit;\r
- }\r
-\r
- TimeOut = 5 * 1000;\r
-\r
- do {\r
- gBS->Stall (1 * 1000);\r
- Status = FastIO (CardData, Reg_Control, &Data, FALSE);\r
- if (EFI_ERROR (Status)) {\r
- goto Exit;\r
- }\r
- if ((Data & BIT2) == BIT2) {\r
- break;\r
- }\r
-\r
- TimeOut--;\r
- } while (TimeOut > 0);\r
-\r
- if (TimeOut == 0) {\r
- Status = EFI_TIMEOUT;\r
- goto Exit;\r
- }\r
-\r
- Data &= ~BIT2;\r
- Status = FastIO (CardData, Reg_Control, &Data, TRUE);\r
-\r
- TimeOut = 5 * 1000;\r
-\r
- do {\r
- gBS->Stall (1 * 1000);\r
- Status = FastIO (CardData, Reg_Control, &Data, FALSE);\r
- if (EFI_ERROR (Status)) {\r
- goto Exit;\r
- }\r
- if ((Data & BIT2) != BIT2) {\r
- break;\r
- }\r
-\r
- TimeOut--;\r
- } while (TimeOut > 0);\r
-\r
-\r
- if (TimeOut == 0) {\r
- Status = EFI_TIMEOUT;\r
- goto Exit;\r
- }\r
-\r
-\r
-Exit:\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- SendATACommand specificed in Taskfile\r
-\r
- @param CardData Pointer to CARD_DATA.\r
- @param TaskFile Pointer to TASK_FILE.\r
- @param Write TRUE means write, FALSE means read.\r
- @param Buffer If NULL, means no data transfer, neither read nor write.\r
- @param SectorCount Buffer size in 512 bytes unit.\r
-\r
- @retval EFI_SUCCESS Success\r
- @retval EFI_DEVICE_ERROR Hardware Error\r
- @retval EFI_INVALID_PARAMETER Parameter is error\r
- @retval EFI_NO_MEDIA No media\r
- @retval EFI_MEDIA_CHANGED Media Change\r
- @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
-\r
-**/\r
-EFI_STATUS\r
-SendATACommand (\r
- IN CARD_DATA *CardData,\r
- IN TASK_FILE *TaskFile,\r
- IN BOOLEAN Write,\r
- IN UINT8 *Buffer,\r
- IN UINT16 SectorCount\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 Data;\r
- UINT32 TimeOut;\r
-\r
- //\r
- //Write register\r
- //\r
- Status = ReadWriteMultipleRegister (\r
- CardData,\r
- 0,\r
- sizeof (TASK_FILE),\r
- TRUE,\r
- (UINT8*)TaskFile\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG((EFI_D_ERROR, "ReadWriteMultipleRegister 0x%x\n", Status));\r
- goto Exit;\r
- }\r
-\r
- TimeOut = 5000;\r
- do {\r
- gBS->Stall (1 * 1000);\r
- Data = 0;\r
- Status = FastIO (\r
- CardData,\r
- Reg_Command_Status,\r
- &Data,\r
- FALSE\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (((Data & BIT7) == 0) && ((Data & BIT6) == BIT6)) {\r
- break;\r
- }\r
-\r
- TimeOut --;\r
- } while (TimeOut > 0);\r
-\r
- if (TimeOut == 0) {\r
- DEBUG((EFI_D_ERROR, "ReadWriteMultipleRegister FastIO EFI_TIMEOUT 0x%x\n", Data));\r
- Status = EFI_TIMEOUT;\r
- goto Exit;\r
- }\r
-\r
-\r
- if (Buffer != NULL) {\r
- Status = ReadWriteMultipleBlock (\r
- CardData,\r
- SectorCount,\r
- Write,\r
- (UINT8*)Buffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG((EFI_D_ERROR, "ReadWriteMultipleBlock EFI_TIMEOUT 0x%x\n", Status));\r
- goto Exit;\r
- }\r
-\r
- TimeOut = 5 * 1000;\r
- do {\r
- gBS->Stall (1 * 1000);\r
-\r
- Data = 0;\r
- Status = FastIO (\r
- CardData,\r
- Reg_Command_Status,\r
- &Data,\r
- FALSE\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (((Data & BIT7) == 0) && ((Data & BIT3) == 0)) {\r
- break;\r
- }\r
-\r
- TimeOut --;\r
- } while (TimeOut > 0);\r
- if (TimeOut == 0) {\r
- DEBUG((EFI_D_ERROR, "ReadWriteMultipleBlock FastIO EFI_TIMEOUT 0x%x\n", Data));\r
- Status = EFI_TIMEOUT;\r
- goto Exit;\r
- }\r
-\r
-\r
- if (((Data & BIT6) == BIT6) && (Data & BIT0) == 0) {\r
- Status = EFI_SUCCESS;\r
- } else {\r
- Status = EFI_DEVICE_ERROR;\r
- }\r
- }\r
-\r
-Exit:\r
- if (EFI_ERROR (Status)) {\r
- SoftwareReset (CardData);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- IDENTIFY_DEVICE command\r
-\r
- @param CardData Pointer to CARD_DATA.\r
-\r
- @retval EFI_SUCCESS Success\r
- @retval EFI_DEVICE_ERROR Hardware Error\r
- @retval EFI_INVALID_PARAMETER Parameter is error\r
- @retval EFI_NO_MEDIA No media\r
- @retval EFI_MEDIA_CHANGED Media Change\r
- @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
-\r
-**/\r
-EFI_STATUS\r
-IndentifyDevice (\r
- IN CARD_DATA *CardData\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));\r
-\r
- //\r
- //The host only supports nIEN = 0\r
- //\r
- CardData->TaskFile.Command_Status = IDENTIFY_DEVICE;\r
-\r
-\r
- Status = SendATACommand (\r
- CardData,\r
- &CardData->TaskFile,\r
- FALSE,\r
- (UINT8*)&(CardData->IndentifyDeviceData),\r
- 1\r
- );\r
-\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- FLUSH_CACHE_EXT command\r
-\r
- @param CardData Pointer to CARD_DATA.\r
-\r
- @retval EFI_SUCCESS Success\r
- @retval EFI_DEVICE_ERROR Hardware Error\r
- @retval EFI_INVALID_PARAMETER Parameter is error\r
- @retval EFI_NO_MEDIA No media\r
- @retval EFI_MEDIA_CHANGED Media Change\r
- @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
-\r
-**/\r
-EFI_STATUS\r
-FlushCache (\r
- IN CARD_DATA *CardData\r
- )\r
-{\r
-\r
- //\r
- //Hitachi CE-ATA will always make the busy high after\r
- //receving this command\r
- //\r
-/*\r
- EFI_STATUS Status;\r
- ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));\r
- //\r
- //The host only supports nIEN = 0\r
- //\r
- CardData->TaskFile.Command_Status = FLUSH_CACHE_EXT;\r
-\r
- Status = SendATACommand (\r
- CardData,\r
- &CardData->TaskFile,\r
- FALSE,\r
- NULL,\r
- 0\r
- );\r
-*/\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- STANDBY_IMMEDIATE command\r
-\r
- @param CardData Pointer to CARD_DATA.\r
-\r
- @retval EFI_SUCCESS Success\r
- @retval EFI_DEVICE_ERROR Hardware Error\r
- @retval EFI_INVALID_PARAMETER Parameter is error\r
- @retval EFI_NO_MEDIA No media\r
- @retval EFI_MEDIA_CHANGED Media Change\r
- @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
-\r
-**/\r
-EFI_STATUS\r
-StandByImmediate (\r
- IN CARD_DATA *CardData\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));\r
- //\r
- //The host only supports nIEN = 0\r
- //\r
- CardData->TaskFile.Command_Status = STANDBY_IMMEDIATE;\r
-\r
-\r
- Status = SendATACommand (\r
- CardData,\r
- &CardData->TaskFile,\r
- FALSE,\r
- NULL,\r
- 0\r
- );\r
- return Status;\r
-}\r
-\r
-/**\r
- READ_DMA_EXT command\r
-\r
- @param CardData Pointer to CARD_DATA.\r
- @param LBA The starting logical block address to read from on the device.\r
- @param Buffer A pointer to the destination buffer for the data. The caller\r
- is responsible for either having implicit or explicit ownership\r
- of the buffer.\r
- @param SectorCount Size in 512 bytes unit.\r
-\r
- @retval EFI_SUCCESS Success\r
- @retval EFI_DEVICE_ERROR Hardware Error\r
- @retval EFI_INVALID_PARAMETER Parameter is error\r
- @retval EFI_NO_MEDIA No media\r
- @retval EFI_MEDIA_CHANGED Media Change\r
- @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
-\r
-**/\r
-EFI_STATUS\r
-ReadDMAExt (\r
- IN CARD_DATA *CardData,\r
- IN EFI_LBA LBA,\r
- IN UINT8 *Buffer,\r
- IN UINT16 SectorCount\r
- )\r
-{\r
-\r
- EFI_STATUS Status;\r
-\r
- ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));\r
- //\r
- //The host only supports nIEN = 0\r
- //\r
- CardData->TaskFile.Command_Status = READ_DMA_EXT;\r
-\r
- CardData->TaskFile.SectorCount = (UINT8)SectorCount;\r
- CardData->TaskFile.SectorCount_Exp = (UINT8)(SectorCount >> 8);\r
-\r
- CardData->TaskFile.LBALow = (UINT8)LBA;\r
- CardData->TaskFile.LBAMid = (UINT8)RShiftU64(LBA, 8);\r
- CardData->TaskFile.LBAHigh = (UINT8)RShiftU64(LBA, 16);\r
-\r
- CardData->TaskFile.LBALow_Exp = (UINT8)RShiftU64(LBA, 24);\r
- CardData->TaskFile.LBAMid_Exp = (UINT8)RShiftU64(LBA, 32);\r
- CardData->TaskFile.LBAHigh_Exp = (UINT8)RShiftU64(LBA, 40);\r
-\r
- Status = SendATACommand (\r
- CardData,\r
- &CardData->TaskFile,\r
- FALSE,\r
- Buffer,\r
- SectorCount\r
- );\r
- return Status;\r
-\r
-}\r
-\r
-/**\r
- WRITE_DMA_EXT command\r
-\r
- @param CardData Pointer to CARD_DATA.\r
- @param LBA The starting logical block address to read from on the device.\r
- @param Buffer A pointer to the destination buffer for the data. The caller\r
- is responsible for either having implicit or explicit ownership\r
- of the buffer.\r
- @param SectorCount Size in 512 bytes unit.\r
-\r
- @retval EFI_SUCCESS Success\r
- @retval EFI_DEVICE_ERROR Hardware Error\r
- @retval EFI_INVALID_PARAMETER Parameter is error\r
- @retval EFI_NO_MEDIA No media\r
- @retval EFI_MEDIA_CHANGED Media Change\r
- @retval EFI_BAD_BUFFER_SIZE Buffer size is bad\r
-\r
-**/\r
-EFI_STATUS\r
-WriteDMAExt (\r
- IN CARD_DATA *CardData,\r
- IN EFI_LBA LBA,\r
- IN UINT8 *Buffer,\r
- IN UINT16 SectorCount\r
- )\r
-{\r
-\r
- EFI_STATUS Status;\r
-\r
- ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));\r
- //\r
- //The host only supports nIEN = 0\r
- //\r
- CardData->TaskFile.Command_Status = WRITE_DMA_EXT;\r
-\r
- CardData->TaskFile.SectorCount = (UINT8)SectorCount;\r
- CardData->TaskFile.SectorCount_Exp = (UINT8)(SectorCount >> 8);\r
-\r
- CardData->TaskFile.LBALow = (UINT8)LBA;\r
- CardData->TaskFile.LBAMid = (UINT8)RShiftU64(LBA, 8);\r
- CardData->TaskFile.LBAHigh = (UINT8)RShiftU64(LBA, 16);\r
-\r
- CardData->TaskFile.LBALow_Exp = (UINT8)RShiftU64(LBA, 24);\r
- CardData->TaskFile.LBAMid_Exp = (UINT8)RShiftU64(LBA, 32);\r
- CardData->TaskFile.LBAHigh_Exp = (UINT8)RShiftU64(LBA, 40);\r
-\r
- Status = SendATACommand (\r
- CardData,\r
- &CardData->TaskFile,\r
- TRUE,\r
- Buffer,\r
- SectorCount\r
- );\r
- return Status;\r
-\r
-}\r
-\r
-\r
-/**\r
- Judge whether it is CE-ATA device or not.\r
-\r
- @param CardData Pointer to CARD_DATA.\r
-\r
- @retval TRUE\r
- @retval FALSE\r
-\r
-**/\r
-BOOLEAN\r
-IsCEATADevice (\r
- IN CARD_DATA *CardData\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- Status = ReadWriteMultipleRegister (\r
- CardData,\r
- 0,\r
- sizeof (TASK_FILE),\r
- FALSE,\r
- (UINT8*)&CardData->TaskFile\r
- );\r
- if (EFI_ERROR (Status)) {\r
- //\r
- //To bring back the normal MMC card to work\r
- //\r
- CardData->SDHostIo->ResetSDHost (CardData->SDHostIo, Reset_DAT_CMD);\r
- return FALSE;\r
- }\r
-\r
- if (CardData->TaskFile.LBAMid == CE_ATA_SIG_CE &&\r
- CardData->TaskFile.LBAHigh == CE_ATA_SIG_AA\r
- ) {\r
- //\r
- //Disable Auto CMD for CE-ATA\r
- //\r
- CardData->SDHostIo->EnableAutoStopCmd (CardData->SDHostIo, FALSE);\r
-\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-\r
-\r