- Status = AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisD2H);\r
- }\r
+ if (!Task->IsStart) {\r
+ AhciBuildCommand (\r
+ PciIo,\r
+ AhciRegisters,\r
+ Port,\r
+ PortMultiplier,\r
+ &CFis,\r
+ &CmdList,\r
+ AtapiCommand,\r
+ AtapiCommandLength,\r
+ 0,\r
+ (VOID *)(UINTN)PhyAddr,\r
+ DataCount\r
+ );\r
+\r
+ Status = AhciStartCommand (\r
+ PciIo,\r
+ Port,\r
+ 0,\r
+ Timeout\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Task->IsStart = TRUE;\r
+ }\r
+ }\r
+ if (Task->IsStart) {\r
+ Status = AhciCheckFisReceived (PciIo, Port, SataFisD2H);\r
+ if (Status == EFI_DEVICE_ERROR) {\r
+ DEBUG ((DEBUG_ERROR, "DMA command failed at retry: %d\n", Task->RetryTimes));\r
+ Status = AhciRecoverPortError (PciIo, Port);\r
+ //\r
+ // If recovery passed mark the Task as not started and change the status\r
+ // to EFI_NOT_READY. This will make the higher level call this function again\r
+ // and on next call the command will be re-issued due to IsStart being FALSE.\r
+ // This also makes the next condition decrement the RetryTimes.\r
+ //\r
+ if (Status == EFI_SUCCESS) {\r
+ Task->IsStart = FALSE;\r
+ Status = EFI_NOT_READY;\r
+ }\r
+ }\r