DEBUG ((DebugLevel, "CommandComplete: %d\n", Trb->CommandComplete));\r
DEBUG ((DebugLevel, "Timeout: %ld\n", Trb->Timeout));\r
DEBUG ((DebugLevel, "Retries: %d\n", Trb->Retries));\r
+ DEBUG ((DebugLevel, "PioModeTransferCompleted: %d\n", Trb->PioModeTransferCompleted));\r
+ DEBUG ((DebugLevel, "PioBlockIndex: %d\n", Trb->PioBlockIndex));\r
DEBUG ((DebugLevel, "Adma32Desc: %p\n", Trb->Adma32Desc));\r
DEBUG ((DebugLevel, "Adma64V3Desc: %p\n", Trb->Adma64V3Desc));\r
DEBUG ((DebugLevel, "Adma64V4Desc: %p\n", Trb->Adma64V4Desc));\r
Trb->CommandComplete = FALSE;\r
Trb->Timeout = Packet->Timeout;\r
Trb->Retries = SD_MMC_TRB_RETRIES;\r
+ Trb->PioModeTransferCompleted = FALSE;\r
+ Trb->PioBlockIndex = 0;\r
Trb->Private = Private;\r
\r
if ((Packet->InTransferLength != 0) && (Packet->InDataBuffer != NULL)) {\r
return EFI_NOT_READY;\r
}\r
\r
+/**\r
+ Transfers data from card using PIO method.\r
+\r
+ @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.\r
+ @param[in] Trb The pointer to the SD_MMC_HC_TRB instance.\r
+ @param[in] IntStatus Snapshot of the normal interrupt status register.\r
+\r
+ @retval EFI_SUCCESS PIO transfer completed successfully.\r
+ @retval EFI_NOT_READY PIO transfer completion still pending.\r
+ @retval Others PIO transfer failed to complete.\r
+**/\r
+EFI_STATUS\r
+SdMmcTransferDataWithPio (\r
+ IN SD_MMC_HC_PRIVATE_DATA *Private,\r
+ IN SD_MMC_HC_TRB *Trb,\r
+ IN UINT16 IntStatus\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT16 Data16;\r
+ UINT32 BlockCount;\r
+ EFI_PCI_IO_PROTOCOL_WIDTH Width;\r
+ UINTN Count;\r
+\r
+ BlockCount = (Trb->DataLen / Trb->BlockSize);\r
+ if (Trb->DataLen % Trb->BlockSize != 0) {\r
+ BlockCount += 1;\r
+ }\r
+\r
+ if (Trb->PioBlockIndex >= BlockCount) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ switch (Trb->BlockSize % sizeof (UINT32)) {\r
+ case 0:\r
+ Width = EfiPciIoWidthFifoUint32;\r
+ Count = Trb->BlockSize / sizeof (UINT32);\r
+ break;\r
+ case 2:\r
+ Width = EfiPciIoWidthFifoUint16;\r
+ Count = Trb->BlockSize / sizeof (UINT16);\r
+ break;\r
+ case 1:\r
+ case 3:\r
+ default:\r
+ Width = EfiPciIoWidthFifoUint8;\r
+ Count = Trb->BlockSize;\r
+ break;\r
+ }\r
+\r
+ if (Trb->Read) {\r
+ if ((IntStatus & BIT5) == 0) {\r
+ return EFI_NOT_READY;\r
+ }\r
+ Data16 = BIT5;\r
+ SdMmcHcRwMmio (Private->PciIo, Trb->Slot, SD_MMC_HC_NOR_INT_STS, FALSE, sizeof (Data16), &Data16);\r
+\r
+ Status = Private->PciIo->Mem.Read (\r
+ Private->PciIo,\r
+ Width,\r
+ Trb->Slot,\r
+ SD_MMC_HC_BUF_DAT_PORT,\r
+ Count,\r
+ (VOID*)((UINT8*)Trb->Data + (Trb->BlockSize * Trb->PioBlockIndex))\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ Trb->PioBlockIndex++;\r
+ } else {\r
+ if ((IntStatus & BIT4) == 0) {\r
+ return EFI_NOT_READY;\r
+ }\r
+ Data16 = BIT4;\r
+ SdMmcHcRwMmio (Private->PciIo, Trb->Slot, SD_MMC_HC_NOR_INT_STS, FALSE, sizeof (Data16), &Data16);\r
+\r
+ Status = Private->PciIo->Mem.Write (\r
+ Private->PciIo,\r
+ Width,\r
+ Trb->Slot,\r
+ SD_MMC_HC_BUF_DAT_PORT,\r
+ Count,\r
+ (VOID*)((UINT8*)Trb->Data + (Trb->BlockSize * Trb->PioBlockIndex))\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ Trb->PioBlockIndex++;\r
+ }\r
+\r
+ if (Trb->PioBlockIndex >= BlockCount) {\r
+ Trb->PioModeTransferCompleted = TRUE;\r
+ return EFI_SUCCESS;\r
+ } else {\r
+ return EFI_NOT_READY;\r
+ }\r
+}\r
+\r
/**\r
Update the SDMA address on the SDMA buffer boundary interrupt.\r
\r
return Status;\r
}\r
\r
+ if (Trb->Mode == SdMmcPioMode && !Trb->PioModeTransferCompleted) {\r
+ Status = SdMmcTransferDataWithPio (Private, Trb, IntStatus);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
if ((Trb->Mode == SdMmcSdmaMode) && ((IntStatus & BIT3) != 0)) {\r
Data16 = BIT3;\r
Status = SdMmcHcRwMmio (\r
EFI_STATUS Status;\r
EFI_SD_MMC_PASS_THRU_COMMAND_PACKET *Packet;\r
UINT16 IntStatus;\r
- UINT32 PioLength;\r
\r
Packet = Trb->Packet;\r
//\r
(Packet->SdMmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK)) ||\r
((Private->Slot[Trb->Slot].CardType == SdCardType) &&\r
(Packet->SdMmcCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK))) {\r
- //\r
- // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,\r
- // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.\r
- // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.\r
- //\r
- if ((IntStatus & BIT5) == BIT5) {\r
- //\r
- // Clear Buffer Read Ready interrupt at first.\r
- //\r
- IntStatus = BIT5;\r
- SdMmcHcRwMmio (Private->PciIo, Trb->Slot, SD_MMC_HC_NOR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus);\r
- //\r
- // Read data out from Buffer Port register\r
- //\r
- for (PioLength = 0; PioLength < Trb->DataLen; PioLength += 4) {\r
- SdMmcHcRwMmio (Private->PciIo, Trb->Slot, SD_MMC_HC_BUF_DAT_PORT, TRUE, 4, (UINT8*)Trb->Data + PioLength);\r
- }\r
- Status = EFI_SUCCESS;\r
- goto Done;\r
- }\r
+ Status = SdMmcTransferDataWithPio (Private, Trb, IntStatus);\r
+ goto Done;\r
}\r
\r
if (!Trb->CommandComplete) {\r