// Untested ...\r
//#define USE_STREAM\r
\r
-#define MAX_RETRY_COUNT 200\r
+#define MAX_RETRY_COUNT 1000\r
+#define CMD_RETRY_COUNT 20\r
\r
EFI_STATUS\r
MmcNotifyState (\r
}\r
\r
VOID PrintOCR(UINT32 ocr) {\r
- float minv, maxv, volts;\r
- int loop;\r
+ UINTN minv, maxv, volts;\r
+ UINTN loop;\r
\r
- minv = 3.6;\r
- maxv = 2.0;\r
- volts = 2.0;\r
+ minv = 36; // 3.6\r
+ maxv = 20; // 2.0\r
+ volts = 20; // 2.0\r
\r
// The MMC register bits [23:8] indicate the working range of the card\r
for (loop = 8; loop < 24; loop++) {\r
if (ocr & (1 << loop)) {\r
if (minv > volts) minv = volts;\r
- if (maxv < volts) maxv = volts + 0.1;\r
+ if (maxv < volts) maxv = volts + 1;\r
}\r
- volts = volts + 0.1;\r
+ volts = volts + 1;\r
}\r
\r
DEBUG((EFI_D_ERROR, "- PrintOCR ocr (0x%X)\n",ocr));\r
- //DEBUG((EFI_D_ERROR, "\t- Card operating voltage: %fV to %fV\n", minv, maxv));\r
+ DEBUG((EFI_D_ERROR, "\t- Card operating voltage: %d.%d to %d.%d\n", minv/10, minv % 10, maxv/10, maxv % 10));\r
if (((ocr >> 29) & 3) == 0)\r
DEBUG((EFI_D_ERROR, "\t- AccessMode: Byte Mode\n"));\r
else\r
}\r
\r
VOID PrintResponseR1(UINT32 response) {\r
- DEBUG((EFI_D_ERROR, "Response: 0x%X\n",response));\r
- if (response & (1 << 8)) DEBUG((EFI_D_ERROR, "\t- READY_FOR_DATA\n"));\r
-\r
- if (((response >> 9) & 0xF) == 0) DEBUG((EFI_D_ERROR, "\t- State: Idle\n"));\r
- else if (((response >> 9) & 0xF) == 1) DEBUG((EFI_D_ERROR, "\t- State: Ready\n"));\r
- else if (((response >> 9) & 0xF) == 2) DEBUG((EFI_D_ERROR, "\t- State: Ident\n"));\r
- else if (((response >> 9) & 0xF) == 3) DEBUG((EFI_D_ERROR, "\t- State: StandBy\n"));\r
- else if (((response >> 9) & 0xF) == 4) DEBUG((EFI_D_ERROR, "\t- State: Tran\n"));\r
- else if (((response >> 9) & 0xF) == 5) DEBUG((EFI_D_ERROR, "\t- State: Data\n"));\r
- else if (((response >> 9) & 0xF) == 6) DEBUG((EFI_D_ERROR, "\t- State: Rcv\n"));\r
- else if (((response >> 9) & 0xF) == 7) DEBUG((EFI_D_ERROR, "\t- State: Prg\n"));\r
- else if (((response >> 9) & 0xF) == 8) DEBUG((EFI_D_ERROR, "\t- State: Dis\n"));\r
- else DEBUG((EFI_D_ERROR, "\t- State: Reserved\n"));\r
+ DEBUG((EFI_D_INFO, "Response: 0x%X\n",response));\r
+ if (response & (1 << 8)) DEBUG((EFI_D_INFO, "\t- READY_FOR_DATA\n"));\r
+\r
+ if (((response >> 9) & 0xF) == 0) DEBUG((EFI_D_INFO, "\t- State: Idle\n"));\r
+ else if (((response >> 9) & 0xF) == 1) DEBUG((EFI_D_INFO, "\t- State: Ready\n"));\r
+ else if (((response >> 9) & 0xF) == 2) DEBUG((EFI_D_INFO, "\t- State: Ident\n"));\r
+ else if (((response >> 9) & 0xF) == 3) DEBUG((EFI_D_INFO, "\t- State: StandBy\n"));\r
+ else if (((response >> 9) & 0xF) == 4) DEBUG((EFI_D_INFO, "\t- State: Tran\n"));\r
+ else if (((response >> 9) & 0xF) == 5) DEBUG((EFI_D_INFO, "\t- State: Data\n"));\r
+ else if (((response >> 9) & 0xF) == 6) DEBUG((EFI_D_INFO, "\t- State: Rcv\n"));\r
+ else if (((response >> 9) & 0xF) == 7) DEBUG((EFI_D_INFO, "\t- State: Prg\n"));\r
+ else if (((response >> 9) & 0xF) == 8) DEBUG((EFI_D_INFO, "\t- State: Dis\n"));\r
+ else DEBUG((EFI_D_INFO, "\t- State: Reserved\n"));\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MmcGetCardStatus(\r
+ MMC_HOST_INSTANCE *MmcHostInstance\r
+ ){\r
+ EFI_STATUS Status=EFI_SUCCESS;\r
+ UINT32 Response[4];\r
+ UINTN CmdArg;\r
+ EFI_MMC_HOST_PROTOCOL *MmcHost;\r
+\r
+ MmcHost = MmcHostInstance->MmcHost;\r
+ CmdArg = 0;\r
+\r
+ if (MmcHost == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ if(MmcHostInstance->State != MmcHwInitializationState){\r
+ //Get the Status of the card.\r
+ CmdArg = MmcHostInstance->CardInfo.RCA << 16;\r
+ Status = MmcHost->SendCommand(MMC_CMD13, CmdArg);\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG((EFI_D_ERROR, "MmcGetCardStatus(MMC_CMD13): Error and Status = %r\n", Status));\r
+ ASSERT(0);\r
+ return Status;\r
+ }\r
+\r
+ //Read Response\r
+ MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_R1,Response);\r
+ PrintResponseR1(Response[0]);\r
+ }\r
+\r
+ return Status;\r
}\r
\r
EFI_STATUS\r
) {\r
EFI_STATUS Status;\r
UINT32 Response[4];\r
- UINTN timer;\r
+ UINTN Timeout;\r
UINTN CmdArg;\r
BOOLEAN bHCS;\r
EFI_MMC_HOST_PROTOCOL *MmcHost;\r
+ UINTN CmdRetryCnt;\r
\r
MmcHost = MmcHostInstance->MmcHost;\r
CmdArg = 0;\r
bHCS = TRUE;\r
MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_R7,Response);\r
PrintResponseR1(Response[0]);\r
+ //check if it is valid response\r
+ if(Response[0] != CmdArg){\r
+ DEBUG ((EFI_D_ERROR, "The Card is not usable\n"));\r
+ return EFI_UNSUPPORTED;\r
+ }\r
} else {\r
DEBUG ((EFI_D_ERROR, "Not a SD2.0 Card\n"));\r
}\r
\r
// We need to wait for the MMC or SD card is ready => (gCardInfo.OCRData.Busy == 1)\r
- timer = MAX_RETRY_COUNT;\r
- while (timer > 0) {\r
+ Timeout = MAX_RETRY_COUNT;\r
+ while (Timeout > 0) {\r
// SD Card or MMC Card ? CMD55 indicates to the card that the next command is an application specific command\r
Status = MmcHost->SendCommand(MMC_CMD55, 0);\r
if (Status == EFI_SUCCESS) {\r
CmdArg |= BIT30;\r
}\r
Status = MmcHost->SendCommand(MMC_ACMD41, CmdArg);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG((EFI_D_ERROR, "MmcIdentificationMode(ACMD41): Error\n"));\r
- return Status;\r
+ if (!EFI_ERROR(Status)) {\r
+ MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_OCR,Response);\r
+ ((UINT32 *) &(MmcHostInstance->CardInfo.OCRData))[0] = Response[0];\r
}\r
- MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_OCR,Response);\r
- ((UINT32 *) &(MmcHostInstance->CardInfo.OCRData))[0] = Response[0];\r
} else {\r
DEBUG ((EFI_D_INFO, "Card should be MMC\n"));\r
MmcHostInstance->CardInfo.CardType = MMC_CARD;\r
\r
Status = MmcHost->SendCommand(MMC_CMD1, 0x800000);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG((EFI_D_ERROR, "MmcIdentificationMode(ACMD41): Error\n"));\r
- return Status;\r
+ if (!EFI_ERROR(Status)) {\r
+ MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_OCR,Response);\r
+ ((UINT32 *) &(MmcHostInstance->CardInfo.OCRData))[0] = Response[0];\r
}\r
- MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_OCR,Response);\r
- ((UINT32 *) &(MmcHostInstance->CardInfo.OCRData))[0] = Response[0];\r
}\r
\r
- if (MmcHostInstance->CardInfo.OCRData.Busy == 0) {\r
- MicroSecondDelay(10*1000);\r
- timer--;\r
+ if (!EFI_ERROR(Status)) {\r
+ if (MmcHostInstance->CardInfo.OCRData.Busy == 0) {\r
+ MicroSecondDelay(1);\r
+ Timeout--;\r
+ } else {\r
+ if ((MmcHostInstance->CardInfo.CardType == SD_CARD_2) && (MmcHostInstance->CardInfo.OCRData.AccessMode & BIT1)) {\r
+ MmcHostInstance->CardInfo.CardType = SD_CARD_2_HIGH;\r
+ DEBUG ((EFI_D_ERROR, "High capacity card.\n"));\r
+ }\r
+ break; // The MMC/SD card is ready. Continue the Identification Mode\r
+ }\r
} else {\r
- if ((MmcHostInstance->CardInfo.CardType == SD_CARD_2) && (MmcHostInstance->CardInfo.OCRData.AccessMode & BIT1)) {\r
- MmcHostInstance->CardInfo.CardType = SD_CARD_2_HIGH;\r
- DEBUG ((EFI_D_ERROR, "High capacity card.\n"));\r
- }\r
- break; // The MMC/SD card is ready. Continue the Identification Mode\r
+ MicroSecondDelay(1);\r
+ Timeout--;\r
}\r
}\r
\r
- if (timer == 0) {\r
+ if (Timeout == 0) {\r
DEBUG((EFI_D_ERROR, "MmcIdentificationMode(): No Card\n"));\r
ASSERT(0);\r
return EFI_NO_MEDIA;\r
}\r
\r
CmdArg = 0;\r
- Status = MmcHost->SendCommand(MMC_CMD3, CmdArg);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD3): Error\n"));\r
- return Status;\r
+ CmdRetryCnt = CMD_RETRY_COUNT;\r
+ //Keep sending CMD 3 until card enters to Standby mode and Card status is ready\r
+ while((MMC_R0_CURRENTSTATE(Response) != MMC_R0_STATE_STDBY) && CmdRetryCnt-- ){\r
+ Status = MmcHost->SendCommand(MMC_CMD3, CmdArg);\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD3): Error\n"));\r
+ return Status;\r
+ }\r
+ MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_RCA,Response);\r
+ PrintRCA(Response[0]);\r
}\r
- MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_RCA,Response);\r
- PrintRCA(Response[0]);\r
\r
// For MMC card, RCA is assigned by CMD3 while CMD3 dumps the RCA for SD card\r
if (MmcHostInstance->CardInfo.CardType != MMC_CARD) {\r
UINT32 Response[4];\r
EFI_STATUS Status;\r
UINTN CardSize, NumBlocks, BlockSize, CmdArg;\r
- UINTN timer;\r
+ UINTN Timeout;\r
UINTN Cmd;\r
MMC_HOST_INSTANCE *MmcHostInstance;\r
EFI_MMC_HOST_PROTOCOL *MmcHost;\r
if (MmcHostInstance->State == MmcHwInitializationState) {\r
MmcIdentificationMode (MmcHostInstance);\r
\r
+ //Send a command to get Card specific data\r
CmdArg = MmcHostInstance->CardInfo.RCA << 16;\r
Status = MmcHost->SendCommand(MMC_CMD9, CmdArg);\r
if (EFI_ERROR(Status)) {\r
- DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD9): Error\n"));\r
+ DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD9): Error, Status=%r\n", Status));\r
ASSERT(0);\r
return Status;\r
}\r
+ //Read Response\r
MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_CSD,Response);\r
PrintCSD(Response);\r
\r
-\r
if (MmcHostInstance->CardInfo.CardType == SD_CARD_2_HIGH) {\r
ASSERT(0); //TODO: Implementation needed\r
CardSize = MMC_CSD_GET_DEVICESIZE(Response);\r
CmdArg = MmcHostInstance->CardInfo.RCA << 16;\r
Status = MmcHost->SendCommand(MMC_CMD7, CmdArg);\r
if (EFI_ERROR(Status)) {\r
- DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD7): Error\n"));\r
+ DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD7): Error and Status = %r\n", Status));\r
ASSERT(0);\r
return Status;\r
}\r
- \r
+\r
Status = MmcNotifyState (MmcHostInstance, MmcTransferState);\r
if (EFI_ERROR(Status)) {\r
DEBUG((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcTransferState\n"));\r
\r
BytesRemainingToBeTransfered = BufferSize;\r
while (BytesRemainingToBeTransfered > 0) {\r
+\r
+ //Check if the Card is in Ready status\r
+ CmdArg = MmcHostInstance->CardInfo.RCA << 16;\r
+ Response[0] = 0;\r
+ Timeout = 20;\r
+ while((Response[0] & (1 << 8)) && Timeout-- ){\r
+ Status = MmcHost->SendCommand(MMC_CMD13, CmdArg);\r
+ if (!EFI_ERROR(Status)){\r
+ MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_R1,Response);\r
+ }\r
+ }\r
+\r
// Set Block Length\r
Status = MmcHost->SendCommand(MMC_CMD16, This->Media->BlockSize);\r
if (EFI_ERROR(Status)) {\r
- DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD16): Error This->Media->BlockSize:%d\n",This->Media->BlockSize));\r
- ASSERT(0);\r
+ DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD16): Error This->Media->BlockSize:%d and Error = %r\n",This->Media->BlockSize, Status));\r
return Status;\r
}\r
\r
}\r
Status = MmcHost->SendCommand(Cmd, CmdArg);\r
if (EFI_ERROR(Status)) {\r
- DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD%d): Error\n",Cmd));\r
- ASSERT(0);\r
+ DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD%d): Error %r\n",Cmd, Status));\r
return Status;\r
}\r
\r
// Read one block of Data\r
Status = MmcHost->ReadBlockData(Lba,This->Media->BlockSize,Buffer);\r
if (EFI_ERROR(Status)) {\r
- DEBUG((EFI_D_BLKIO, "MmcIdentificationMode(): Error Read Block Data"));\r
- ASSERT(0);\r
+ DEBUG((EFI_D_BLKIO, "MmcIdentificationMode(): Error Read Block Data and Status = %r\n", Status));\r
return Status;\r
}\r
#else\r
// Write one block of Data\r
Status = MmcHost->WriteBlockData(Lba,This->Media->BlockSize,Buffer);\r
if (EFI_ERROR(Status)) {\r
- DEBUG((EFI_D_BLKIO, "MmcIdentificationMode(): Error Write Block Data"));\r
- ASSERT(0);\r
+ DEBUG((EFI_D_BLKIO, "MmcIdentificationMode(): Error Write Block Data and Status = %r\n", Status));\r
return Status;\r
}\r
#else\r
MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_R1b,Response);\r
\r
// Command 13 - Read status and wait for programming to complete (return to tran)\r
- timer = MMCI0_TIMEOUT;\r
- while ((MMC_R0_CURRENTSTATE(Response) != MMC_R0_STATE_TRAN) && timer) {\r
- MmcHost->SendCommand(MMC_CMD13, 0);\r
+ Timeout = MMCI0_TIMEOUT;\r
+ CmdArg = MmcHostInstance->CardInfo.RCA << 16;\r
+ while ((MMC_R0_CURRENTSTATE(Response) != MMC_R0_STATE_TRAN) && Timeout) {\r
+ MmcHost->SendCommand(MMC_CMD13, CmdArg);\r
MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_R1,Response);\r
NanoSecondDelay(100);\r
- timer--;\r
+ Timeout--;\r
}\r
\r
Status = MmcNotifyState (MmcHostInstance, MmcTransferState);\r