]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/Universal/MmcDxe/MmcBlockIo.c
EmbeddedPkg/MmcDxe: Fix the CMD3 sequence
[mirror_edk2.git] / EmbeddedPkg / Universal / MmcDxe / MmcBlockIo.c
index cd04369652faccac3cd2a69a424857fb957b85fb..38998c893fcde0bc8f13bdb24636e99daaf40b56 100644 (file)
@@ -333,19 +333,21 @@ MmcIdentificationMode (
     return Status;\r
   }\r
 \r
-  CmdArg = 0;\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
+  // Note, SD specifications say that "if the command execution causes a state change, it\r
+  // will be visible to the host in the response to the next command"\r
+  // The status returned for this CMD3 will be 2 - identification\r
+  //\r
+  CmdArg = 1;\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
 \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
     MmcHostInstance->CardInfo.RCA = Response[0] >> 16;\r
@@ -424,7 +426,7 @@ MmcIoBlocks (
   UINT32                  Response[4];\r
   EFI_STATUS              Status;\r
   UINTN                   CardSize, NumBlocks, BlockSize, CmdArg;\r
-  UINTN                   Timeout;\r
+  INTN                    Timeout;\r
   UINTN                   Cmd;\r
   MMC_HOST_INSTANCE       *MmcHostInstance;\r
   EFI_MMC_HOST_PROTOCOL   *MmcHost;\r
@@ -436,7 +438,7 @@ MmcIoBlocks (
   MmcHost = MmcHostInstance->MmcHost;\r
   ASSERT(MmcHost);\r
 \r
-  if (MmcHost == 0) {\r
+  if ((MmcHost == 0)|| (Buffer == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -445,7 +447,7 @@ MmcIoBlocks (
     return EFI_NO_MEDIA;\r
   }\r
 \r
-  // If the driver has not been initialized yet then go into Iddentification Mode\r
+  // If the driver has not been initialized yet then go into Identification Mode\r
   if (MmcHostInstance->State == MmcHwInitializationState) {\r
     MmcIdentificationMode (MmcHostInstance);\r
 \r
@@ -508,14 +510,24 @@ MmcIoBlocks (
     }\r
   }\r
 \r
-  if (Lba > This->Media->LastBlock) {\r
-      ASSERT(0);\r
-      return EFI_INVALID_PARAMETER;\r
+  // All blocks must be within the device\r
+  if ((Lba + (BufferSize / This->Media->BlockSize)) > (This->Media->LastBlock + 1)){\r
+    ASSERT(0);\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if ((BufferSize % This->Media->BlockSize) != 0) {\r
-      ASSERT(0);\r
-      return EFI_BAD_BUFFER_SIZE;\r
+  // The buffer size must not be zero and it must be an exact multiple of the block size\r
+  if ((BufferSize == 0) || ((BufferSize % This->Media->BlockSize) != 0)) {\r
+    ASSERT(0);\r
+    return EFI_BAD_BUFFER_SIZE;\r
+  }\r
+\r
+  if (This->Media->MediaId != MediaId) {\r
+    return EFI_MEDIA_CHANGED;\r
+  }\r
+\r
+  if((Transfer == MMC_IOBLOCKS_WRITE) && (This->Media->ReadOnly == TRUE)) {\r
+    return EFI_WRITE_PROTECTED;\r
   }\r
 \r
   BytesRemainingToBeTransfered = BufferSize;\r