Bläddra i källkod

EmbeddedPkg/MmcDxe: Wait for the MMC controller to be in Transfer Mode

The MMC controller might be ready for data but not be in a 'ready' state
to send or receive commands.
This fix waits for the MMC controller to be in the correct state.



git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11726 6f19259b-4bc3-4df7-8a09-765794883524
oliviermartin 13 år sedan
förälder
incheckning
b9d5fe03e6
2 ändrade filer med 17 tillägg och 5 borttagningar
  1. 2 0
      EmbeddedPkg/Universal/MmcDxe/Mmc.h
  2. 15 5
      EmbeddedPkg/Universal/MmcDxe/MmcBlockIo.c

+ 2 - 0
EmbeddedPkg/Universal/MmcDxe/Mmc.h

@@ -41,6 +41,8 @@
 #define MMC_CSD_GET_DEVICESIZE(csd)         (((Response[2] >> 30) & 0x3) | ((Response[1] & 0x3FF) << 2))
 #define MMC_CSD_GET_DEVICESIZEMULT(csd)     ((Response[2] >> 15) & 0x7)
 
+#define MMC_R0_READY_FOR_DATA               (1 << 8)
+
 #define MMC_R0_CURRENTSTATE(Response)       ((Response[0] >> 9) & 0xF)
 
 #define MMC_R0_STATE_IDLE       0

+ 15 - 5
EmbeddedPkg/Universal/MmcDxe/MmcBlockIo.c

@@ -476,13 +476,18 @@ EFI_STATUS MmcIoBlocks (
 		CmdArg = MmcHostInstance->CardInfo.RCA << 16;
 		Response[0] = 0;
 		Timeout = 20;
-    	while((Response[0] & (1 << 8)) && Timeout-- ){
+    	while(!(Response[0] & MMC_R0_READY_FOR_DATA) && (MMC_R0_CURRENTSTATE(Response) != MMC_R0_STATE_TRAN) && Timeout--) {
     		Status = MmcHost->SendCommand(MMC_CMD13, CmdArg);
     		if (!EFI_ERROR(Status)){
     			MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_R1,Response);
     		}
     	}
 
+    	if (0 == Timeout) {
+      		DEBUG((EFI_D_ERROR, "The Card is busy\n"));
+      		return EFI_NOT_READY;
+    }
+
         // Set Block Length
         Status = MmcHost->SendCommand(MMC_CMD16, This->Media->BlockSize);
         if (EFI_ERROR(Status)) {
@@ -554,14 +559,19 @@ EFI_STATUS MmcIoBlocks (
 
         // Command 12 - Stop transmission (ends read)
         Status = MmcHost->SendCommand(MMC_CMD12, 0);
-        MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_R1b,Response);
+    	if (!EFI_ERROR(Status)) {
+        	MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_R1b,Response);
+    	}
 
         // Command 13 - Read status and wait for programming to complete (return to tran)
         Timeout = MMCI0_TIMEOUT;
         CmdArg = MmcHostInstance->CardInfo.RCA << 16;
-        while ((MMC_R0_CURRENTSTATE(Response) != MMC_R0_STATE_TRAN) && Timeout) {
-            MmcHost->SendCommand(MMC_CMD13, CmdArg);
-            MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_R1,Response);
+    	Response[0] = 0;
+    	while(!(Response[0] & MMC_R0_READY_FOR_DATA) && (MMC_R0_CURRENTSTATE(Response) != MMC_R0_STATE_TRAN) && Timeout--) {
+      		Status = MmcHost->SendCommand(MMC_CMD13, CmdArg);
+      		if (!EFI_ERROR(Status)) {
+            	MmcHost->ReceiveResponse(MMC_RESPONSE_TYPE_R1,Response);
+      		}
             NanoSecondDelay(100);
             Timeout--;
         }