Status = EFI_TIMEOUT;\r
Delay = (UINT32) (DivU64x32 (Timeout, 1000) + 1);\r
do {\r
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;\r
- PortTfd = AhciReadReg (PciIo, (UINT32) Offset);\r
-\r
- if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) {\r
- Status = EFI_DEVICE_ERROR;\r
- break;\r
- }\r
Offset = FisBaseAddr + EFI_AHCI_PIO_FIS_OFFSET;\r
\r
Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, EFI_AHCI_FIS_PIO_SETUP, 0);\r
if (!EFI_ERROR (Status)) {\r
+ Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;\r
+ PortTfd = AhciReadReg (PciIo, (UINT32) Offset);\r
+ //\r
+ // PxTFD will be updated if there is a D2H or SetupFIS received. \r
+ // For PIO IN transfer, D2H means a device error. Therefore we only need to check the TFD after receiving a SetupFIS.\r
+ //\r
+ if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ break;\r
+ }\r
+\r
PrdCount = *(volatile UINT32 *) (&(AhciRegisters->AhciCmdList[0].AhciCmdPrdbc));\r
if (PrdCount == DataCount) {\r
break;\r