return EFI_NOT_READY;\r
}\r
\r
+/**\r
+ Update the SDMA address on the SDMA buffer boundary interrupt.\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
+\r
+ @retval EFI_SUCCESS Updated SDMA buffer address.\r
+ @retval Others Failed to update SDMA buffer address.\r
+**/\r
+EFI_STATUS\r
+SdMmcUpdateSdmaAddress (\r
+ IN SD_MMC_HC_PRIVATE_DATA *Private,\r
+ IN SD_MMC_HC_TRB *Trb\r
+ )\r
+{\r
+ UINT64 SdmaAddr;\r
+ EFI_STATUS Status;\r
+\r
+ SdmaAddr = SD_MMC_SDMA_ROUND_UP ((UINTN)Trb->DataPhy, SD_MMC_SDMA_BOUNDARY);\r
+\r
+ if (Private->ControllerVersion[Trb->Slot] >= SD_MMC_HC_CTRL_VER_400) {\r
+ Status = SdMmcHcRwMmio (\r
+ Private->PciIo,\r
+ Trb->Slot,\r
+ SD_MMC_HC_ADMA_SYS_ADDR,\r
+ FALSE,\r
+ sizeof (UINT64),\r
+ &SdmaAddr\r
+ );\r
+ } else {\r
+ Status = SdMmcHcRwMmio (\r
+ Private->PciIo,\r
+ Trb->Slot,\r
+ SD_MMC_HC_SDMA_ADDR,\r
+ FALSE,\r
+ sizeof (UINT32),\r
+ &SdmaAddr\r
+ );\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Trb->DataPhy = (UINT64)(UINTN)SdmaAddr;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Checks if the data transfer completed and performs any actions\r
+ neccessary to continue the data transfer such as SDMA system\r
+ address fixup or PIO data transfer.\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 Data transfer completed successfully.\r
+ @retval EFI_NOT_READY Data transfer completion still pending.\r
+ @retval Others Data transfer failed to complete.\r
+**/\r
+EFI_STATUS\r
+SdMmcCheckDataTransfer (\r
+ IN SD_MMC_HC_PRIVATE_DATA *Private,\r
+ IN SD_MMC_HC_TRB *Trb,\r
+ IN UINT16 IntStatus\r
+ )\r
+{\r
+ UINT16 Data16;\r
+ EFI_STATUS Status;\r
+\r
+ if ((IntStatus & BIT1) != 0) {\r
+ Data16 = BIT1;\r
+ Status = SdMmcHcRwMmio (\r
+ Private->PciIo,\r
+ Trb->Slot,\r
+ SD_MMC_HC_NOR_INT_STS,\r
+ FALSE,\r
+ sizeof (Data16),\r
+ &Data16\r
+ );\r
+ return Status;\r
+ }\r
+\r
+ if ((Trb->Mode == SdMmcSdmaMode) && ((IntStatus & BIT3) != 0)) {\r
+ Data16 = BIT3;\r
+ Status = SdMmcHcRwMmio (\r
+ Private->PciIo,\r
+ Trb->Slot,\r
+ SD_MMC_HC_NOR_INT_STS,\r
+ FALSE,\r
+ sizeof (Data16),\r
+ &Data16\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ Status = SdMmcUpdateSdmaAddress (Private, Trb);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ return EFI_NOT_READY;\r
+}\r
+\r
/**\r
Check the TRB execution result.\r
\r
EFI_STATUS Status;\r
EFI_SD_MMC_PASS_THRU_COMMAND_PACKET *Packet;\r
UINT16 IntStatus;\r
- UINT64 SdmaAddr;\r
UINT32 PioLength;\r
\r
Packet = Trb->Packet;\r
Status = SdMmcCheckCommandComplete (Private, Trb, IntStatus);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
- } else {\r
- //\r
- // If the command doesn't require data transfer skip the transfer\r
- // complete checking.\r
- //\r
- if ((Packet->SdMmcCmdBlk->CommandType != SdMmcCommandTypeAdtc) &&\r
- (Packet->SdMmcCmdBlk->ResponseType != SdMmcResponseTypeR1b) &&\r
- (Packet->SdMmcCmdBlk->ResponseType != SdMmcResponseTypeR5b)) {\r
- goto Done;\r
- }\r
}\r
}\r
\r
- //\r
- // Check Transfer Complete bit is set or not.\r
- //\r
- if ((IntStatus & BIT1) == BIT1) {\r
- goto Done;\r
- }\r
-\r
- //\r
- // Check if DMA interrupt is signalled for the SDMA transfer.\r
- //\r
- if ((Trb->Mode == SdMmcSdmaMode) && ((IntStatus & BIT3) == BIT3)) {\r
- //\r
- // Clear DMA interrupt bit.\r
- //\r
- IntStatus = BIT3;\r
- Status = SdMmcHcRwMmio (\r
- Private->PciIo,\r
- Trb->Slot,\r
- SD_MMC_HC_NOR_INT_STS,\r
- FALSE,\r
- sizeof (IntStatus),\r
- &IntStatus\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- //\r
- // Update SDMA Address register.\r
- //\r
- SdmaAddr = SD_MMC_SDMA_ROUND_UP ((UINTN)Trb->DataPhy, SD_MMC_SDMA_BOUNDARY);\r
-\r
- if (Private->ControllerVersion[Trb->Slot] >= SD_MMC_HC_CTRL_VER_400) {\r
- Status = SdMmcHcRwMmio (\r
- Private->PciIo,\r
- Trb->Slot,\r
- SD_MMC_HC_ADMA_SYS_ADDR,\r
- FALSE,\r
- sizeof (UINT64),\r
- &SdmaAddr\r
- );\r
- } else {\r
- Status = SdMmcHcRwMmio (\r
- Private->PciIo,\r
- Trb->Slot,\r
- SD_MMC_HC_SDMA_ADDR,\r
- FALSE,\r
- sizeof (UINT32),\r
- &SdmaAddr\r
- );\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- Trb->DataPhy = (UINT64)(UINTN)SdmaAddr;\r
+ if (Packet->SdMmcCmdBlk->CommandType == SdMmcCommandTypeAdtc ||\r
+ Packet->SdMmcCmdBlk->ResponseType == SdMmcResponseTypeR1b ||\r
+ Packet->SdMmcCmdBlk->ResponseType == SdMmcResponseTypeR5b) {\r
+ Status = SdMmcCheckDataTransfer (Private, Trb, IntStatus);\r
+ } else {\r
+ Status = EFI_SUCCESS;\r
}\r
\r
-\r
- Status = EFI_NOT_READY;\r
Done:\r
-\r
if (Status != EFI_NOT_READY) {\r
SdMmcHcLedOnOff (Private->PciIo, Trb->Slot, FALSE);\r
if (EFI_ERROR (Status)) {\r