+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;\r
+\r
+ BlockCount = 1;\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, "InitializeMmcDevice(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, "InitializeMmcDevice(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, "InitializeMmcDevice(): 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, "InitializeMmcDevice(MMC_CMD16): Error MmcHostInstance->BlockIo.Media->BlockSize: %d and Error = %r\n",\r
+ 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