+EFI_STATUS InitializeMmcDevice (\r
+ IN MMC_HOST_INSTANCE *MmcHostInstance\r
+ )\r
+{\r
+ UINT32 Response[4];\r
+ EFI_STATUS Status;\r
+ UINTN CardSize, NumBlocks, BlockSize, CmdArg;\r
+ EFI_MMC_HOST_PROTOCOL *MmcHost;\r
+ UINTN BlockCount = 1;\r
+ \r
+ MmcHost = MmcHostInstance->MmcHost;\r
+\r
+ MmcIdentificationMode (MmcHostInstance);\r
+\r
+ //Send a command to get Card specific data\r
+ CmdArg = MmcHostInstance->CardInfo.RCA << 16;\r
+ Status = MmcHost->SendCommand (MmcHost, MMC_CMD9, CmdArg);\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD9): Error, Status=%r\n", Status));\r
+ return Status;\r
+ }\r
+ //Read Response\r
+ MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_CSD,Response);\r
+ PrintCSD(Response);\r
+\r
+ if (MmcHostInstance->CardInfo.CardType == SD_CARD_2_HIGH) {\r
+ CardSize = HC_MMC_CSD_GET_DEVICESIZE(Response);\r
+ NumBlocks = ((CardSize + 1) * 1024);\r
+ BlockSize = 1 << MMC_CSD_GET_READBLLEN(Response);\r
+ } else {\r
+ CardSize = MMC_CSD_GET_DEVICESIZE(Response);\r
+ NumBlocks = (CardSize + 1) * (1 << (MMC_CSD_GET_DEVICESIZEMULT(Response) + 2));\r
+ BlockSize = 1 << MMC_CSD_GET_READBLLEN(Response);\r
+ }\r
+\r
+ //For >=2G card, BlockSize may be 1K, but the transfer size is 512 bytes.\r
+ if (BlockSize > 512) {\r
+ NumBlocks = MultU64x32(NumBlocks, BlockSize/512);\r
+ BlockSize = 512;\r
+ }\r
+\r
+ MmcHostInstance->BlockIo.Media->LastBlock = (NumBlocks - 1);\r
+ MmcHostInstance->BlockIo.Media->BlockSize = BlockSize;\r
+ MmcHostInstance->BlockIo.Media->ReadOnly = MmcHost->IsReadOnly (MmcHost);\r
+ MmcHostInstance->BlockIo.Media->MediaPresent = TRUE;\r
+ MmcHostInstance->BlockIo.Media->MediaId++;\r
+\r
+ CmdArg = MmcHostInstance->CardInfo.RCA << 16;\r
+ Status = MmcHost->SendCommand (MmcHost, MMC_CMD7, CmdArg);\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD7): Error and Status = %r\n", Status));\r
+ return Status;\r
+ }\r
+\r
+ Status = MmcNotifyState (MmcHostInstance, MmcTransferState);\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcTransferState\n"));\r
+ return Status;\r
+ }\r
+\r
+ // Set Block Length\r
+ Status = MmcHost->SendCommand (MmcHost, MMC_CMD16, MmcHostInstance->BlockIo.Media->BlockSize);\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD16): Error MmcHostInstance->BlockIo.Media->BlockSize: %d and Error = %r\n",MmcHostInstance->BlockIo.Media->BlockSize, Status));\r
+ return Status;\r
+ }\r
+\r
+ // Block Count (not used). Could return an error for SD card\r
+ if (MmcHostInstance->CardInfo.CardType == MMC_CARD) {\r
+ MmcHost->SendCommand (MmcHost, MMC_CMD23, BlockCount);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r