3 * Copyright (c) 2011-2013, ARM Limited. All rights reserved.
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include <Protocol/MmcHost.h>
16 #include <Library/DebugLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/TimerLib.h>
22 #define MAX_RETRY_COUNT 1000
23 #define CMD_RETRY_COUNT 20
27 IN MMC_HOST_INSTANCE
*MmcHostInstance
,
31 MmcHostInstance
->State
= State
;
32 return MmcHostInstance
->MmcHost
->NotifyState (MmcHostInstance
->MmcHost
, State
);
49 // The MMC register bits [23:8] indicate the working range of the card
50 for (Loop
= 8; Loop
< 24; Loop
++) {
51 if (Ocr
& (1 << Loop
)) {
52 if (MinV
> Volts
) MinV
= Volts
;
53 if (MaxV
< Volts
) MaxV
= Volts
+ 1;
58 DEBUG ((EFI_D_ERROR
, "- PrintOCR Ocr (0x%X)\n",Ocr
));
59 DEBUG ((EFI_D_ERROR
, "\t- Card operating voltage: %d.%d to %d.%d\n", MinV
/10, MinV
% 10, MaxV
/10, MaxV
% 10));
60 if (((Ocr
>> 29) & 3) == 0) {
61 DEBUG ((EFI_D_ERROR
, "\t- AccessMode: Byte Mode\n"));
63 DEBUG ((EFI_D_ERROR
, "\t- AccessMode: Block Mode (0x%X)\n", ((Ocr
>> 29) & 3)));
66 if (Ocr
& MMC_OCR_POWERUP
) {
67 DEBUG ((EFI_D_ERROR
, "\t- PowerUp\n"));
69 DEBUG ((EFI_D_ERROR
, "\t- Voltage Not Supported\n"));
77 DEBUG ((EFI_D_ERROR
, "- PrintCID\n"));
78 DEBUG ((EFI_D_ERROR
, "\t- Manufacturing date: %d/%d\n", (Cid
[0] >> 8) & 0xF, (Cid
[0] >> 12) & 0xFF));
79 DEBUG ((EFI_D_ERROR
, "\t- Product serial number: 0x%X%X\n", Cid
[1] & 0xFFFFFF, (Cid
[0] >> 24) & 0xFF));
80 DEBUG ((EFI_D_ERROR
, "\t- Product revision: %d\n", Cid
[1] >> 24));
81 //DEBUG ((EFI_D_ERROR, "\t- Product name: %s\n", (char*)(Cid + 2)));
82 DEBUG ((EFI_D_ERROR
, "\t- OEM ID: %c%c\n", (Cid
[3] >> 8) & 0xFF, (Cid
[3] >> 16) & 0xFF));
85 #if !defined(MDEPKG_NDEBUG)
86 CONST CHAR8
* mStrUnit
[] = { "100kbit/s", "1Mbit/s", "10Mbit/s", "100MBit/s",
87 "Unknown", "Unknown", "Unknown", "Unknown" };
88 CONST CHAR8
* mStrValue
[] = { "1.0", "1.2", "1.3", "1.5", "2.0", "2.5", "3.0", "3.5", "4.0", "4.5", "5.0",
89 "Unknown", "Unknown", "Unknown", "Unknown" };
99 if (((Csd
[2] >> 30) & 0x3) == 0) {
100 DEBUG ((EFI_D_ERROR
, "- PrintCSD Version 1.01-1.10/Version 2.00/Standard Capacity\n"));
101 } else if (((Csd
[2] >> 30) & 0x3) == 1) {
102 DEBUG ((EFI_D_ERROR
, "- PrintCSD Version 2.00/High Capacity\n"));
104 DEBUG ((EFI_D_ERROR
, "- PrintCSD Version Higher than v3.3\n"));
107 DEBUG ((EFI_D_ERROR
, "\t- Supported card command class: 0x%X\n", MMC_CSD_GET_CCC(Csd
)));
108 DEBUG ((EFI_D_ERROR
, "\t- Speed: %a %a\n",mStrValue
[(MMC_CSD_GET_TRANSPEED(Csd
) >> 3) & 0xF],mStrUnit
[MMC_CSD_GET_TRANSPEED(Csd
) & 7]));
109 DEBUG ((EFI_D_ERROR
, "\t- Maximum Read Data Block: %d\n",2 << (MMC_CSD_GET_READBLLEN(Csd
)-1)));
110 DEBUG ((EFI_D_ERROR
, "\t- Maximum Write Data Block: %d\n",2 << (MMC_CSD_GET_WRITEBLLEN(Csd
)-1)));
112 if (!MMC_CSD_GET_FILEFORMATGRP (Csd
)) {
113 Value
= MMC_CSD_GET_FILEFORMAT (Csd
);
114 if (Value
== 0) DEBUG ((EFI_D_ERROR
, "\t- Format (0): Hard disk-like file system with partition table\n"));
115 else if (Value
== 1) DEBUG ((EFI_D_ERROR
, "\t- Format (1): DOS FAT (floppy-like) with boot sector only (no partition table)\n"));
116 else if (Value
== 2) DEBUG ((EFI_D_ERROR
, "\t- Format (2): Universal File Format\n"));
117 else DEBUG ((EFI_D_ERROR
, "\t- Format (3): Others/Unknown\n"));
119 DEBUG ((EFI_D_ERROR
, "\t- Format: Reserved\n"));
128 DEBUG ((EFI_D_ERROR
, "- PrintRCA: 0x%X\n", Rca
));
129 DEBUG ((EFI_D_ERROR
, "\t- Status: 0x%X\n", Rca
& 0xFFFF));
130 DEBUG ((EFI_D_ERROR
, "\t- RCA: 0x%X\n", (Rca
>> 16) & 0xFFFF));
138 DEBUG ((EFI_D_INFO
, "Response: 0x%X\n", Response
));
139 if (Response
& MMC_R0_READY_FOR_DATA
) {
140 DEBUG ((EFI_D_INFO
, "\t- READY_FOR_DATA\n"));
143 if (((Response
>> 9) & 0xF) == 0) DEBUG ((EFI_D_INFO
, "\t- State: Idle\n"));
144 else if (((Response
>> 9) & 0xF) == 1) DEBUG ((EFI_D_INFO
, "\t- State: Ready\n"));
145 else if (((Response
>> 9) & 0xF) == 2) DEBUG ((EFI_D_INFO
, "\t- State: Ident\n"));
146 else if (((Response
>> 9) & 0xF) == 3) DEBUG ((EFI_D_INFO
, "\t- State: StandBy\n"));
147 else if (((Response
>> 9) & 0xF) == 4) DEBUG ((EFI_D_INFO
, "\t- State: Tran\n"));
148 else if (((Response
>> 9) & 0xF) == 5) DEBUG ((EFI_D_INFO
, "\t- State: Data\n"));
149 else if (((Response
>> 9) & 0xF) == 6) DEBUG ((EFI_D_INFO
, "\t- State: Rcv\n"));
150 else if (((Response
>> 9) & 0xF) == 7) DEBUG ((EFI_D_INFO
, "\t- State: Prg\n"));
151 else if (((Response
>> 9) & 0xF) == 8) DEBUG ((EFI_D_INFO
, "\t- State: Dis\n"));
152 else DEBUG ((EFI_D_INFO
, "\t- State: Reserved\n"));
158 IN MMC_HOST_INSTANCE
*MmcHostInstance
164 EFI_MMC_HOST_PROTOCOL
*MmcHost
;
166 Status
= EFI_SUCCESS
;
167 MmcHost
= MmcHostInstance
->MmcHost
;
170 if (MmcHost
== NULL
) {
171 return EFI_INVALID_PARAMETER
;
173 if (MmcHostInstance
->State
!= MmcHwInitializationState
) {
174 //Get the Status of the card.
175 CmdArg
= MmcHostInstance
->CardInfo
.RCA
<< 16;
176 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD13
, CmdArg
);
177 if (EFI_ERROR (Status
)) {
178 DEBUG ((EFI_D_ERROR
, "MmcGetCardStatus(MMC_CMD13): Error and Status = %r\n", Status
));
183 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_R1
, Response
);
184 PrintResponseR1 (Response
[0]);
192 MmcIdentificationMode (
193 IN MMC_HOST_INSTANCE
*MmcHostInstance
201 EFI_MMC_HOST_PROTOCOL
*MmcHost
;
203 MmcHost
= MmcHostInstance
->MmcHost
;
207 if (MmcHost
== NULL
) {
208 return EFI_INVALID_PARAMETER
;
211 // We can get into this function if we restart the identification mode
212 if (MmcHostInstance
->State
== MmcHwInitializationState
) {
213 // Initialize the MMC Host HW
214 Status
= MmcNotifyState (MmcHostInstance
, MmcHwInitializationState
);
215 if (EFI_ERROR (Status
)) {
216 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode() : Error MmcHwInitializationState\n"));
221 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD0
, 0);
222 if (EFI_ERROR (Status
)) {
223 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode(MMC_CMD0): Error\n"));
227 Status
= MmcNotifyState (MmcHostInstance
, MmcIdleState
);
228 if (EFI_ERROR (Status
)) {
229 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode() : Error MmcIdleState\n"));
233 // Are we using SDIO ?
234 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD5
, 0);
235 if (Status
== EFI_SUCCESS
) {
236 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode(MMC_CMD5): Error - SDIO not supported.\n"));
237 return EFI_UNSUPPORTED
;
240 // Check which kind of card we are using. Ver2.00 or later SD Memory Card (PL180 is SD v1.1)
241 CmdArg
= (0x0UL
<< 12 | BIT8
| 0xCEUL
<< 0);
242 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD8
, CmdArg
);
243 if (Status
== EFI_SUCCESS
) {
244 DEBUG ((EFI_D_ERROR
, "Card is SD2.0 => Supports high capacity\n"));
246 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_R7
, Response
);
247 PrintResponseR1 (Response
[0]);
248 //check if it is valid response
249 if (Response
[0] != CmdArg
) {
250 DEBUG ((EFI_D_ERROR
, "The Card is not usable\n"));
251 return EFI_UNSUPPORTED
;
254 DEBUG ((EFI_D_ERROR
, "Not a SD2.0 Card\n"));
257 // We need to wait for the MMC or SD card is ready => (gCardInfo.OCRData.PowerUp == 1)
258 Timeout
= MAX_RETRY_COUNT
;
259 while (Timeout
> 0) {
260 // SD Card or MMC Card ? CMD55 indicates to the card that the next command is an application specific command
261 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD55
, 0);
262 if (Status
== EFI_SUCCESS
) {
263 DEBUG ((EFI_D_INFO
, "Card should be SD\n"));
265 MmcHostInstance
->CardInfo
.CardType
= SD_CARD_2
;
267 MmcHostInstance
->CardInfo
.CardType
= SD_CARD
;
270 // Note: The first time CmdArg will be zero
271 CmdArg
= ((UINTN
*) &(MmcHostInstance
->CardInfo
.OCRData
))[0];
275 Status
= MmcHost
->SendCommand (MmcHost
, MMC_ACMD41
, CmdArg
);
276 if (!EFI_ERROR (Status
)) {
277 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_OCR
, Response
);
278 ((UINT32
*) &(MmcHostInstance
->CardInfo
.OCRData
))[0] = Response
[0];
281 DEBUG ((EFI_D_INFO
, "Card should be MMC\n"));
282 MmcHostInstance
->CardInfo
.CardType
= MMC_CARD
;
284 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD1
, 0x800000);
285 if (!EFI_ERROR (Status
)) {
286 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_OCR
, Response
);
287 ((UINT32
*) &(MmcHostInstance
->CardInfo
.OCRData
))[0] = Response
[0];
291 if (!EFI_ERROR (Status
)) {
292 if (!MmcHostInstance
->CardInfo
.OCRData
.PowerUp
) {
293 MicroSecondDelay (1);
296 if ((MmcHostInstance
->CardInfo
.CardType
== SD_CARD_2
) && (MmcHostInstance
->CardInfo
.OCRData
.AccessMode
& BIT1
)) {
297 MmcHostInstance
->CardInfo
.CardType
= SD_CARD_2_HIGH
;
298 DEBUG ((EFI_D_ERROR
, "High capacity card.\n"));
300 break; // The MMC/SD card is ready. Continue the Identification Mode
303 MicroSecondDelay (1);
309 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode(): No Card\n"));
312 PrintOCR (Response
[0]);
315 Status
= MmcNotifyState (MmcHostInstance
, MmcReadyState
);
316 if (EFI_ERROR (Status
)) {
317 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode() : Error MmcReadyState\n"));
321 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD2
, 0);
322 if (EFI_ERROR (Status
)) {
323 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode(MMC_CMD2): Error\n"));
326 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_CID
, Response
);
329 Status
= MmcNotifyState (MmcHostInstance
, MmcIdentificationState
);
330 if (EFI_ERROR (Status
)) {
331 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode() : Error MmcIdentificationState\n"));
336 // Note, SD specifications say that "if the command execution causes a state change, it
337 // will be visible to the host in the response to the next command"
338 // The status returned for this CMD3 will be 2 - identification
341 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD3
, CmdArg
);
342 if (EFI_ERROR (Status
)) {
343 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode(MMC_CMD3): Error\n"));
347 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_RCA
, Response
);
348 PrintRCA (Response
[0]);
350 // For MMC card, RCA is assigned by CMD3 while CMD3 dumps the RCA for SD card
351 if (MmcHostInstance
->CardInfo
.CardType
!= MMC_CARD
) {
352 MmcHostInstance
->CardInfo
.RCA
= Response
[0] >> 16;
354 MmcHostInstance
->CardInfo
.RCA
= CmdArg
;
357 Status
= MmcNotifyState (MmcHostInstance
, MmcStandByState
);
358 if (EFI_ERROR (Status
)) {
359 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode() : Error MmcStandByState\n"));
366 EFI_STATUS
InitializeMmcDevice (
367 IN MMC_HOST_INSTANCE
*MmcHostInstance
372 UINTN CardSize
, NumBlocks
, BlockSize
, CmdArg
;
373 EFI_MMC_HOST_PROTOCOL
*MmcHost
;
377 MmcHost
= MmcHostInstance
->MmcHost
;
379 MmcIdentificationMode (MmcHostInstance
);
381 //Send a command to get Card specific data
382 CmdArg
= MmcHostInstance
->CardInfo
.RCA
<< 16;
383 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD9
, CmdArg
);
384 if (EFI_ERROR (Status
)) {
385 DEBUG((EFI_D_ERROR
, "InitializeMmcDevice(MMC_CMD9): Error, Status=%r\n", Status
));
389 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_CSD
, Response
);
392 if (MmcHostInstance
->CardInfo
.CardType
== SD_CARD_2_HIGH
) {
393 CardSize
= HC_MMC_CSD_GET_DEVICESIZE (Response
);
394 NumBlocks
= ((CardSize
+ 1) * 1024);
395 BlockSize
= 1 << MMC_CSD_GET_READBLLEN (Response
);
397 CardSize
= MMC_CSD_GET_DEVICESIZE (Response
);
398 NumBlocks
= (CardSize
+ 1) * (1 << (MMC_CSD_GET_DEVICESIZEMULT (Response
) + 2));
399 BlockSize
= 1 << MMC_CSD_GET_READBLLEN (Response
);
402 //For >=2G card, BlockSize may be 1K, but the transfer size is 512 bytes.
403 if (BlockSize
> 512) {
404 NumBlocks
= MultU64x32 (NumBlocks
, BlockSize
/512);
408 MmcHostInstance
->BlockIo
.Media
->LastBlock
= (NumBlocks
- 1);
409 MmcHostInstance
->BlockIo
.Media
->BlockSize
= BlockSize
;
410 MmcHostInstance
->BlockIo
.Media
->ReadOnly
= MmcHost
->IsReadOnly (MmcHost
);
411 MmcHostInstance
->BlockIo
.Media
->MediaPresent
= TRUE
;
412 MmcHostInstance
->BlockIo
.Media
->MediaId
++;
414 CmdArg
= MmcHostInstance
->CardInfo
.RCA
<< 16;
415 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD7
, CmdArg
);
416 if (EFI_ERROR (Status
)) {
417 DEBUG((EFI_D_ERROR
, "InitializeMmcDevice(MMC_CMD7): Error and Status = %r\n", Status
));
421 Status
= MmcNotifyState (MmcHostInstance
, MmcTransferState
);
422 if (EFI_ERROR (Status
)) {
423 DEBUG((EFI_D_ERROR
, "InitializeMmcDevice(): Error MmcTransferState\n"));
428 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD16
, MmcHostInstance
->BlockIo
.Media
->BlockSize
);
429 if (EFI_ERROR (Status
)) {
430 DEBUG((EFI_D_ERROR
, "InitializeMmcDevice(MMC_CMD16): Error MmcHostInstance->BlockIo.Media->BlockSize: %d and Error = %r\n",
431 MmcHostInstance
->BlockIo
.Media
->BlockSize
, Status
));
435 // Block Count (not used). Could return an error for SD card
436 if (MmcHostInstance
->CardInfo
.CardType
== MMC_CARD
) {
437 MmcHost
->SendCommand (MmcHost
, MMC_CMD23
, BlockCount
);
446 IN EFI_BLOCK_IO_PROTOCOL
*This
,
447 IN BOOLEAN ExtendedVerification
450 MMC_HOST_INSTANCE
*MmcHostInstance
;
452 MmcHostInstance
= MMC_HOST_INSTANCE_FROM_BLOCK_IO_THIS (This
);
454 if (MmcHostInstance
->MmcHost
== NULL
) {
459 // If a card is not present then clear all media settings
460 if (!MmcHostInstance
->MmcHost
->IsCardPresent (MmcHostInstance
->MmcHost
)) {
461 MmcHostInstance
->BlockIo
.Media
->MediaPresent
= FALSE
;
462 MmcHostInstance
->BlockIo
.Media
->LastBlock
= 0;
463 MmcHostInstance
->BlockIo
.Media
->BlockSize
= 512; // Should be zero but there is a bug in DiskIo
464 MmcHostInstance
->BlockIo
.Media
->ReadOnly
= FALSE
;
466 // Indicate that the driver requires initialization
467 MmcHostInstance
->State
= MmcHwInitializationState
;
472 // Implement me. Either send a CMD0 (could not work for some MMC host) or just turn off/turn
473 // on power and restart Identification mode
479 EFI_MMC_HOST_PROTOCOL
*MmcHost
482 if (!MmcHost
->IsCardPresent (MmcHost
)) {
489 #define MMCI0_BLOCKLEN 512
490 #define MMCI0_TIMEOUT 10000
494 IN EFI_BLOCK_IO_PROTOCOL
*This
,
507 MMC_HOST_INSTANCE
*MmcHostInstance
;
508 EFI_MMC_HOST_PROTOCOL
*MmcHost
;
509 UINTN BytesRemainingToBeTransfered
;
513 MmcHostInstance
= MMC_HOST_INSTANCE_FROM_BLOCK_IO_THIS (This
);
514 ASSERT (MmcHostInstance
!= NULL
);
515 MmcHost
= MmcHostInstance
->MmcHost
;
518 if (This
->Media
->MediaId
!= MediaId
) {
519 return EFI_MEDIA_CHANGED
;
522 if ((MmcHost
== NULL
) || (Buffer
== NULL
)) {
523 return EFI_INVALID_PARAMETER
;
526 // Check if a Card is Present
527 if (!MmcHostInstance
->BlockIo
.Media
->MediaPresent
) {
531 // All blocks must be within the device
532 if ((Lba
+ (BufferSize
/ This
->Media
->BlockSize
)) > (This
->Media
->LastBlock
+ 1)) {
533 return EFI_INVALID_PARAMETER
;
536 if ((Transfer
== MMC_IOBLOCKS_WRITE
) && (This
->Media
->ReadOnly
== TRUE
)) {
537 return EFI_WRITE_PROTECTED
;
540 // Reading 0 Byte is valid
541 if (BufferSize
== 0) {
545 // The buffer size must be an exact multiple of the block size
546 if ((BufferSize
% This
->Media
->BlockSize
) != 0) {
547 return EFI_BAD_BUFFER_SIZE
;
550 // Check the alignment
551 if ((This
->Media
->IoAlign
> 2) && (((UINTN
)Buffer
& (This
->Media
->IoAlign
- 1)) != 0)) {
552 return EFI_INVALID_PARAMETER
;
555 BytesRemainingToBeTransfered
= BufferSize
;
556 while (BytesRemainingToBeTransfered
> 0) {
558 // Check if the Card is in Ready status
559 CmdArg
= MmcHostInstance
->CardInfo
.RCA
<< 16;
562 while( (!(Response
[0] & MMC_R0_READY_FOR_DATA
))
563 && (MMC_R0_CURRENTSTATE (Response
) != MMC_R0_STATE_TRAN
)
565 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD13
, CmdArg
);
566 if (!EFI_ERROR (Status
)) {
567 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_R1
, Response
);
572 DEBUG ((EFI_D_ERROR
, "The Card is busy\n"));
573 return EFI_NOT_READY
;
576 //Set command argument based on the card access mode (Byte mode or Block mode)
577 if (MmcHostInstance
->CardInfo
.OCRData
.AccessMode
& BIT1
) {
580 CmdArg
= Lba
* This
->Media
->BlockSize
;
583 if (Transfer
== MMC_IOBLOCKS_READ
) {
584 // Read a single block
587 // Write a single block
590 Status
= MmcHost
->SendCommand (MmcHost
, Cmd
, CmdArg
);
591 if (EFI_ERROR (Status
)) {
592 DEBUG ((EFI_D_ERROR
, "MmcIoBlocks(MMC_CMD%d): Error %r\n", Cmd
, Status
));
596 if (Transfer
== MMC_IOBLOCKS_READ
) {
597 // Read one block of Data
598 Status
= MmcHost
->ReadBlockData (MmcHost
, Lba
, This
->Media
->BlockSize
, Buffer
);
599 if (EFI_ERROR (Status
)) {
600 DEBUG ((EFI_D_BLKIO
, "MmcIoBlocks(): Error Read Block Data and Status = %r\n", Status
));
603 Status
= MmcNotifyState (MmcHostInstance
, MmcProgrammingState
);
604 if (EFI_ERROR (Status
)) {
605 DEBUG ((EFI_D_ERROR
, "MmcIoBlocks() : Error MmcProgrammingState\n"));
609 // Write one block of Data
610 Status
= MmcHost
->WriteBlockData (MmcHost
, Lba
, This
->Media
->BlockSize
, Buffer
);
611 if (EFI_ERROR (Status
)) {
612 DEBUG ((EFI_D_BLKIO
, "MmcIoBlocks(): Error Write Block Data and Status = %r\n", Status
));
617 // Command 12 - Stop transmission (ends read)
618 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD12
, 0);
619 if (!EFI_ERROR (Status
)) {
620 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_R1b
, Response
);
623 // Command 13 - Read status and wait for programming to complete (return to tran)
624 Timeout
= MMCI0_TIMEOUT
;
625 CmdArg
= MmcHostInstance
->CardInfo
.RCA
<< 16;
627 while( (!(Response
[0] & MMC_R0_READY_FOR_DATA
))
628 && (MMC_R0_CURRENTSTATE (Response
) != MMC_R0_STATE_TRAN
)
630 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD13
, CmdArg
);
631 if (!EFI_ERROR (Status
)) {
632 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_R1
, Response
);
633 if ((Response
[0] & MMC_R0_READY_FOR_DATA
)) {
634 break; // Prevents delay once finished
637 NanoSecondDelay (100);
640 Status
= MmcNotifyState (MmcHostInstance
, MmcTransferState
);
641 if (EFI_ERROR (Status
)) {
642 DEBUG ((EFI_D_ERROR
, "MmcIoBlocks() : Error MmcTransferState\n"));
646 BytesRemainingToBeTransfered
-= This
->Media
->BlockSize
;
648 Buffer
= (UINT8
*)Buffer
+ This
->Media
->BlockSize
;
657 IN EFI_BLOCK_IO_PROTOCOL
*This
,
664 return MmcIoBlocks (This
, MMC_IOBLOCKS_READ
, MediaId
, Lba
, BufferSize
, Buffer
);
670 IN EFI_BLOCK_IO_PROTOCOL
*This
,
677 return MmcIoBlocks (This
, MMC_IOBLOCKS_WRITE
, MediaId
, Lba
, BufferSize
, Buffer
);
683 IN EFI_BLOCK_IO_PROTOCOL
*This