+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+EmmcGetDeviceState (\r
+ IN MMC_HOST_INSTANCE *MmcHostInstance,\r
+ OUT EMMC_DEVICE_STATE *State\r
+ )\r
+{\r
+ EFI_MMC_HOST_PROTOCOL *Host;\r
+ EFI_STATUS Status;\r
+ UINT32 Data, RCA;\r
+\r
+ if (State == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Host = MmcHostInstance->MmcHost;\r
+ RCA = MmcHostInstance->CardInfo.RCA << RCA_SHIFT_OFFSET;\r
+ Status = Host->SendCommand (Host, MMC_CMD13, RCA);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "EmmcGetDeviceState(): Failed to get card status, Status=%r.\n", Status));\r
+ return Status;\r
+ }\r
+ Status = Host->ReceiveResponse (Host, MMC_RESPONSE_TYPE_R1, &Data);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "EmmcGetDeviceState(): Failed to get response of CMD13, Status=%r.\n", Status));\r
+ return Status;\r
+ }\r
+ if (Data & EMMC_SWITCH_ERROR) {\r
+ DEBUG ((EFI_D_ERROR, "EmmcGetDeviceState(): Failed to switch expected mode, Status=%r.\n", Status));\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ *State = DEVICE_STATE(Data);\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+EmmcSetEXTCSD (\r
+ IN MMC_HOST_INSTANCE *MmcHostInstance,\r
+ UINT32 ExtCmdIndex,\r
+ UINT32 Value\r
+ )\r
+{\r
+ EFI_MMC_HOST_PROTOCOL *Host;\r
+ EMMC_DEVICE_STATE State;\r
+ EFI_STATUS Status;\r
+ UINT32 Argument;\r
+\r
+ Host = MmcHostInstance->MmcHost;\r
+ Argument = EMMC_CMD6_ARG_ACCESS(3) | EMMC_CMD6_ARG_INDEX(ExtCmdIndex) |\r
+ EMMC_CMD6_ARG_VALUE(Value) | EMMC_CMD6_ARG_CMD_SET(1);\r
+ Status = Host->SendCommand (Host, MMC_CMD6, Argument);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "EmmcSetEXTCSD(): Failed to send CMD6, Status=%r.\n", Status));\r
+ return Status;\r
+ }\r
+ // Make sure device exiting prog mode\r
+ do {\r
+ Status = EmmcGetDeviceState (MmcHostInstance, &State);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "EmmcSetEXTCSD(): Failed to get device state, Status=%r.\n", Status));\r
+ return Status;\r
+ }\r
+ } while (State == EMMC_PRG_STATE);\r
+ return EFI_SUCCESS;\r
+}\r
+\r