/** @file\r
Header file for AHCI mode of ATA host controller.\r
\r
- Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
IN UINT64 Timeout\r
)\r
{\r
- UINT32 Delay;\r
+ UINT64 Delay;\r
UINT8 StatusRegister;\r
+ BOOLEAN InfiniteWait;\r
\r
ASSERT (PciIo != NULL);\r
ASSERT (IdeRegisters != NULL);\r
\r
- Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
+ if (Timeout == 0) {\r
+ InfiniteWait = TRUE;\r
+ } else {\r
+ InfiniteWait = FALSE;\r
+ }\r
+\r
+ Delay = DivU64x32(Timeout, 1000) + 1;\r
do {\r
StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);\r
\r
\r
Delay--;\r
\r
- } while (Delay > 0);\r
+ } while (InfiniteWait || (Delay > 0));\r
\r
return EFI_TIMEOUT;\r
}\r
IN UINT64 Timeout\r
)\r
{\r
- UINT32 Delay;\r
+ UINT64 Delay;\r
UINT8 AltRegister;\r
+ BOOLEAN InfiniteWait;\r
\r
ASSERT (PciIo != NULL);\r
ASSERT (IdeRegisters != NULL);\r
\r
- Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
+ if (Timeout == 0) {\r
+ InfiniteWait = TRUE;\r
+ } else {\r
+ InfiniteWait = FALSE;\r
+ }\r
+\r
+ Delay = DivU64x32(Timeout, 1000) + 1;\r
do {\r
AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);\r
\r
\r
Delay--;\r
\r
- } while (Delay > 0);\r
+ } while (InfiniteWait || (Delay > 0));\r
\r
return EFI_TIMEOUT;\r
}\r
@param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.\r
@param Timeout The time to complete the command, uses 100ns as a unit.\r
\r
- @retval EFI_SUCCESS DRQ bit set within the time out.\r
- @retval EFI_TIMEOUT DRQ bit not set within the time out.\r
- @retval EFI_ABORTED DRQ bit not set caused by the command abort.\r
+ @retval EFI_SUCCESS BSY bit cleared and DRQ bit set within the\r
+ timeout.\r
+\r
+ @retval EFI_TIMEOUT BSY bit not cleared within the timeout.\r
+\r
+ @retval EFI_ABORTED Polling abandoned due to command abort.\r
+\r
+ @retval EFI_DEVICE_ERROR Polling abandoned due to a non-abort error.\r
+\r
+ @retval EFI_NOT_READY BSY bit cleared within timeout, and device\r
+ reported "command complete" by clearing DRQ\r
+ bit.\r
\r
@note Read Status Register will clear interrupt status.\r
\r
IN UINT64 Timeout\r
)\r
{\r
- UINT32 Delay;\r
+ UINT64 Delay;\r
UINT8 StatusRegister;\r
UINT8 ErrorRegister;\r
+ BOOLEAN InfiniteWait;\r
\r
ASSERT (PciIo != NULL);\r
ASSERT (IdeRegisters != NULL);\r
\r
- Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
+ if (Timeout == 0) {\r
+ InfiniteWait = TRUE;\r
+ } else {\r
+ InfiniteWait = FALSE;\r
+ }\r
+\r
+ Delay = DivU64x32(Timeout, 1000) + 1;\r
do {\r
//\r
// Read Status Register will clear interrupt\r
MicroSecondDelay (100);\r
\r
Delay--;\r
- } while (Delay > 0);\r
+ } while (InfiniteWait || (Delay > 0));\r
\r
return EFI_TIMEOUT;\r
}\r
@param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.\r
@param Timeout The time to complete the command, uses 100ns as a unit.\r
\r
- @retval EFI_SUCCESS DRQ bit set within the time out.\r
- @retval EFI_TIMEOUT DRQ bit not set within the time out.\r
- @retval EFI_ABORTED DRQ bit not set caused by the command abort.\r
+ @retval EFI_SUCCESS BSY bit cleared and DRQ bit set within the\r
+ timeout.\r
+\r
+ @retval EFI_TIMEOUT BSY bit not cleared within the timeout.\r
+\r
+ @retval EFI_ABORTED Polling abandoned due to command abort.\r
+\r
+ @retval EFI_DEVICE_ERROR Polling abandoned due to a non-abort error.\r
+\r
+ @retval EFI_NOT_READY BSY bit cleared within timeout, and device\r
+ reported "command complete" by clearing DRQ\r
+ bit.\r
+\r
@note Read Alternate Status Register will not clear interrupt status.\r
\r
**/\r
IN UINT64 Timeout\r
)\r
{\r
- UINT32 Delay;\r
+ UINT64 Delay;\r
UINT8 AltRegister;\r
UINT8 ErrorRegister;\r
+ BOOLEAN InfiniteWait;\r
\r
ASSERT (PciIo != NULL);\r
ASSERT (IdeRegisters != NULL);\r
\r
- Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
+ if (Timeout == 0) {\r
+ InfiniteWait = TRUE;\r
+ } else {\r
+ InfiniteWait = FALSE;\r
+ }\r
+\r
+ Delay = DivU64x32(Timeout, 1000) + 1;\r
\r
do {\r
//\r
MicroSecondDelay (100);\r
\r
Delay--;\r
- } while (Delay > 0);\r
+ } while (InfiniteWait || (Delay > 0));\r
\r
return EFI_TIMEOUT;\r
}\r
IN UINT64 Timeout\r
)\r
{\r
- UINT32 Delay;\r
+ UINT64 Delay;\r
UINT8 StatusRegister;\r
UINT8 ErrorRegister;\r
+ BOOLEAN InfiniteWait;\r
\r
ASSERT (PciIo != NULL);\r
ASSERT (IdeRegisters != NULL);\r
\r
- Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
+ if (Timeout == 0) {\r
+ InfiniteWait = TRUE;\r
+ } else {\r
+ InfiniteWait = FALSE;\r
+ }\r
+\r
+ Delay = DivU64x32(Timeout, 1000) + 1;\r
do {\r
StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);\r
//\r
MicroSecondDelay (100);\r
\r
Delay--;\r
- } while (Delay > 0);\r
+ } while (InfiniteWait || (Delay > 0));\r
\r
return EFI_TIMEOUT;\r
}\r
IN UINT64 Timeout\r
)\r
{\r
- UINT32 Delay;\r
+ UINT64 Delay;\r
UINT8 AltRegister;\r
UINT8 ErrorRegister;\r
+ BOOLEAN InfiniteWait;\r
\r
ASSERT (PciIo != NULL);\r
ASSERT (IdeRegisters != NULL);\r
\r
- Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
+ if (Timeout == 0) {\r
+ InfiniteWait = TRUE;\r
+ } else {\r
+ InfiniteWait = FALSE;\r
+ }\r
+\r
+ Delay = DivU64x32(Timeout, 1000) + 1;\r
do {\r
AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);\r
//\r
MicroSecondDelay (100);\r
\r
Delay--;\r
- } while (Delay > 0);\r
+ } while (InfiniteWait || (Delay > 0));\r
\r
return EFI_TIMEOUT;\r
}\r
IN UINT64 Timeout\r
)\r
{\r
- UINT32 Delay;\r
+ UINT64 Delay;\r
UINT8 StatusRegister;\r
+ BOOLEAN InfiniteWait;\r
\r
ASSERT (PciIo != NULL);\r
ASSERT (IdeRegisters != NULL);\r
\r
- Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
+ if (Timeout == 0) {\r
+ InfiniteWait = TRUE;\r
+ } else {\r
+ InfiniteWait = FALSE;\r
+ }\r
+\r
+ Delay = DivU64x32(Timeout, 1000) + 1;\r
do {\r
StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);\r
\r
\r
Delay--;\r
\r
- } while (Delay > 0);\r
+ } while (InfiniteWait || (Delay > 0));\r
\r
return EFI_TIMEOUT;\r
}\r
IN UINT64 Timeout\r
)\r
{\r
- UINT32 Delay;\r
+ UINT64 Delay;\r
UINT8 AltStatusRegister;\r
+ BOOLEAN InfiniteWait;\r
\r
ASSERT (PciIo != NULL);\r
ASSERT (IdeRegisters != NULL);\r
\r
- Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
+ if (Timeout == 0) {\r
+ InfiniteWait = TRUE;\r
+ } else {\r
+ InfiniteWait = FALSE;\r
+ }\r
+\r
+ Delay = DivU64x32(Timeout, 1000) + 1;\r
do {\r
AltStatusRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);\r
\r
\r
Delay--;\r
\r
- } while (Delay > 0);\r
+ } while (InfiniteWait || (Delay > 0));\r
\r
return EFI_TIMEOUT;\r
}\r
\r
@param[in] PciIo The PCI IO protocol instance.\r
@param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.\r
+ @param[in] Timeout The time to complete the command, uses 100ns as a unit.\r
\r
@retval EFI_DEVICE_ERROR The memory is not set.\r
@retval EFI_TIMEOUT The memory setting is time out.\r
**/\r
EFI_STATUS\r
AtaUdmStatusWait (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN EFI_IDE_REGISTERS *IdeRegisters\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN EFI_IDE_REGISTERS *IdeRegisters,\r
+ IN UINT64 Timeout\r
)\r
{\r
UINT8 RegisterValue;\r
EFI_STATUS Status;\r
UINT16 IoPortForBmis;\r
- UINT64 Timeout;\r
+ UINT64 Delay;\r
+ BOOLEAN InfiniteWait;\r
\r
- Timeout = 2000;\r
+ if (Timeout == 0) {\r
+ InfiniteWait = TRUE;\r
+ } else {\r
+ InfiniteWait = FALSE;\r
+ }\r
+\r
+ Delay = DivU64x32 (Timeout, 1000) + 1;\r
\r
- while (TRUE) {\r
+ do {\r
Status = CheckStatusRegister (PciIo, IdeRegisters);\r
if (EFI_ERROR (Status)) {\r
Status = EFI_DEVICE_ERROR;\r
break;\r
}\r
//\r
- // Stall for 1 milliseconds.\r
+ // Stall for 100 microseconds.\r
//\r
- MicroSecondDelay (1000);\r
- Timeout--;\r
- }\r
+ MicroSecondDelay (100);\r
+ Delay--;\r
+ } while (InfiniteWait || (Delay > 0));\r
\r
return Status;\r
}\r
return EFI_SUCCESS;\r
}\r
\r
- if (Task->RetryTimes == 0) {\r
+ if (!Task->InfiniteWait && (Task->RetryTimes == 0)) {\r
return EFI_TIMEOUT;\r
} else {\r
//\r
UINTN PrdTableSize;\r
EFI_PHYSICAL_ADDRESS PrdTableMapAddr;\r
VOID *PrdTableMap;\r
- EFI_ATA_DMA_PRD *PrdBaseAddr;\r
+ EFI_PHYSICAL_ADDRESS PrdTableBaseAddr;\r
EFI_ATA_DMA_PRD *TempPrdBaseAddr;\r
UINTN PrdTableNum;\r
\r
EFI_PCI_IO_PROTOCOL *PciIo;\r
EFI_TPL OldTpl;\r
\r
+ UINTN AlignmentMask;\r
+ UINTN RealPageCount;\r
+ EFI_PHYSICAL_ADDRESS BaseAddr;\r
+ EFI_PHYSICAL_ADDRESS BaseMapAddr;\r
\r
Status = EFI_SUCCESS;\r
- PrdBaseAddr = NULL;\r
PrdTableMap = NULL;\r
BufferMap = NULL;\r
PageCount = 0;\r
+ RealPageCount = 0;\r
+ BaseAddr = 0;\r
PciIo = Instance->PciIo;\r
\r
if ((PciIo == NULL) || (IdeRegisters == NULL) || (DataBuffer == NULL) || (AtaCommandBlock == NULL)) {\r
\r
//\r
// Allocate buffer for PRD table initialization.\r
+ // Note Ide Bus Master spec said the descriptor table must be aligned on a 4 byte\r
+ // boundary and the table cannot cross a 64K boundary in memory.\r
+ //\r
+ PageCount = EFI_SIZE_TO_PAGES (PrdTableSize);\r
+ RealPageCount = PageCount + EFI_SIZE_TO_PAGES (SIZE_64KB);\r
+\r
+ //\r
+ // Make sure that PageCount plus EFI_SIZE_TO_PAGES (SIZE_64KB) does not overflow.\r
//\r
- PageCount = EFI_SIZE_TO_PAGES (PrdTableSize);\r
+ ASSERT (RealPageCount > PageCount);\r
+\r
Status = PciIo->AllocateBuffer (\r
PciIo,\r
AllocateAnyPages,\r
EfiBootServicesData,\r
- PageCount,\r
- (VOID **)&PrdBaseAddr,\r
+ RealPageCount,\r
+ (VOID **)&BaseAddr,\r
0\r
);\r
if (EFI_ERROR (Status)) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- ByteCount = EFI_PAGES_TO_SIZE (PageCount);\r
+ ByteCount = EFI_PAGES_TO_SIZE (RealPageCount);\r
Status = PciIo->Map (\r
PciIo,\r
EfiPciIoOperationBusMasterCommonBuffer,\r
- PrdBaseAddr,\r
+ (VOID*)(UINTN)BaseAddr,\r
&ByteCount,\r
- &PrdTableMapAddr,\r
+ &BaseMapAddr,\r
&PrdTableMap\r
);\r
- if (EFI_ERROR (Status) || (ByteCount != EFI_PAGES_TO_SIZE (PageCount))) {\r
+ if (EFI_ERROR (Status) || (ByteCount != EFI_PAGES_TO_SIZE (RealPageCount))) {\r
//\r
// If the data length actually mapped is not equal to the requested amount,\r
// it means the DMA operation may be broken into several discontinuous smaller chunks.\r
// Can't handle this case.\r
//\r
- PciIo->FreeBuffer (PciIo, PageCount, PrdBaseAddr);\r
+ PciIo->FreeBuffer (PciIo, RealPageCount, (VOID*)(UINTN)BaseAddr);\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- ZeroMem ((VOID *) ((UINTN) PrdBaseAddr), ByteCount);\r
+ ZeroMem ((VOID *) ((UINTN) BaseAddr), ByteCount);\r
+\r
+ //\r
+ // Calculate the 64K align address as PRD Table base address.\r
+ //\r
+ AlignmentMask = SIZE_64KB - 1;\r
+ PrdTableBaseAddr = ((UINTN) BaseAddr + AlignmentMask) & ~AlignmentMask;\r
+ PrdTableMapAddr = ((UINTN) BaseMapAddr + AlignmentMask) & ~AlignmentMask;\r
\r
//\r
// Map the host address of DataBuffer to DMA master address.\r
);\r
if (EFI_ERROR (Status) || (ByteCount != DataLength)) {\r
PciIo->Unmap (PciIo, PrdTableMap);\r
- PciIo->FreeBuffer (PciIo, PageCount, PrdBaseAddr);\r
+ PciIo->FreeBuffer (PciIo, RealPageCount, (VOID*)(UINTN)BaseAddr);\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
// Fill the PRD table with appropriate bus master address of data buffer and data length.\r
//\r
ByteRemaining = ByteCount;\r
- TempPrdBaseAddr = PrdBaseAddr;\r
+ TempPrdBaseAddr = (EFI_ATA_DMA_PRD*)(UINTN)PrdTableBaseAddr;\r
while (ByteRemaining != 0) {\r
if (ByteRemaining <= 0x10000) {\r
TempPrdBaseAddr->RegionBaseAddr = (UINT32) ((UINTN) BufferMapAddress);\r
IdeWritePortB (PciIo, IoPortForBmic, RegisterValue);\r
\r
if (Task != NULL) {\r
- //\r
- // Max transfer number of sectors for one command is 65536(32Mbyte),\r
- // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).\r
- // So set the variable Count to 2000, for about 2 second Timeout time.\r
- //\r
- Task->RetryTimes = 2000;\r
Task->Map = BufferMap;\r
Task->TableMap = PrdTableMap;\r
- Task->MapBaseAddress = PrdBaseAddr;\r
- Task->PageCount = PageCount;\r
+ Task->MapBaseAddress = (EFI_ATA_DMA_PRD*)(UINTN)BaseAddr;\r
+ Task->PageCount = RealPageCount;\r
Task->IsStart = TRUE;\r
}\r
\r
\r
//\r
// Check the INTERRUPT and ERROR bit of BMIS\r
- // Max transfer number of sectors for one command is 65536(32Mbyte),\r
- // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).\r
- // So set the variable Count to 2000, for about 2 second Timeout time.\r
//\r
if (Task != NULL) {\r
Status = AtaUdmStatusCheck (PciIo, Task, IdeRegisters);\r
} else {\r
- Status = AtaUdmStatusWait (PciIo, IdeRegisters);\r
+ Status = AtaUdmStatusWait (PciIo, IdeRegisters, Timeout);\r
}\r
\r
//\r
PciIo->Unmap (PciIo, Task->Map);\r
} else {\r
PciIo->Unmap (PciIo, PrdTableMap);\r
- PciIo->FreeBuffer (PciIo, PageCount, PrdBaseAddr);\r
+ PciIo->FreeBuffer (PciIo, RealPageCount, (VOID*)(UINTN)BaseAddr);\r
PciIo->Unmap (PciIo, BufferMap);\r
}\r
\r
IN EFI_PCI_IO_PROTOCOL *PciIo,\r
IN EFI_IDE_REGISTERS *IdeRegisters,\r
IN OUT VOID *Buffer,\r
- IN UINT64 ByteCount,\r
+ IN OUT UINT32 *ByteCount,\r
IN BOOLEAN Read,\r
IN UINT64 Timeout\r
)\r
EFI_STATUS Status;\r
UINT16 *PtrBuffer;\r
\r
+ PtrBuffer = Buffer;\r
+ RequiredWordCount = *ByteCount >> 1;\r
+\r
//\r
// No data transfer is premitted.\r
//\r
- if (ByteCount == 0) {\r
+ if (RequiredWordCount == 0) {\r
return EFI_SUCCESS;\r
}\r
\r
- PtrBuffer = Buffer;\r
- RequiredWordCount = (UINT32)RShiftU64(ByteCount, 1);\r
//\r
- // ActuralWordCount means the word count of data really transferred.\r
+ // ActualWordCount means the word count of data really transferred.\r
//\r
ActualWordCount = 0;\r
\r
//\r
Status = DRQReady2 (PciIo, IdeRegisters, Timeout);\r
if (EFI_ERROR (Status)) {\r
- return CheckStatusRegister (PciIo, IdeRegisters);\r
+ if (Status == EFI_NOT_READY) {\r
+ //\r
+ // Device provided less data than we intended to read, or wanted less\r
+ // data than we intended to write, but it may still be successful.\r
+ //\r
+ break;\r
+ } else {\r
+ return Status;\r
+ }\r
}\r
\r
//\r
return EFI_DEVICE_ERROR;\r
}\r
\r
- return Status;\r
-}\r
-\r
-/**\r
- Sumbit ATAPI request sense command.\r
-\r
- @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance\r
- @param[in] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to\r
- store the IDE i/o port registers' base addresses\r
- @param[in] Channel The channel number of device.\r
- @param[in] Device The device number of device.\r
- @param[in] SenseData A pointer to store sense data.\r
- @param[in] SenseDataLength The sense data length.\r
- @param[in] Timeout The timeout value to execute this cmd, uses 100ns as a unit.\r
-\r
- @retval EFI_SUCCESS Send out the ATAPI packet command successfully.\r
- @retval EFI_DEVICE_ERROR The device failed to send data.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AtaPacketRequestSense (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN EFI_IDE_REGISTERS *IdeRegisters,\r
- IN UINT8 Channel,\r
- IN UINT8 Device,\r
- IN VOID *SenseData,\r
- IN UINT8 SenseDataLength,\r
- IN UINT64 Timeout\r
- )\r
-{\r
- EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET Packet;\r
- UINT8 Cdb[12];\r
- EFI_STATUS Status;\r
-\r
- ZeroMem (&Packet, sizeof (EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));\r
- ZeroMem (Cdb, 12);\r
-\r
- Cdb[0] = ATA_CMD_REQUEST_SENSE;\r
- Cdb[4] = SenseDataLength;\r
-\r
- Packet.Timeout = Timeout;\r
- Packet.Cdb = Cdb;\r
- Packet.CdbLength = 12;\r
- Packet.DataDirection = EFI_EXT_SCSI_DATA_DIRECTION_READ;\r
- Packet.InDataBuffer = SenseData;\r
- Packet.InTransferLength = SenseDataLength;\r
-\r
- Status = AtaPacketCommandExecute (PciIo, IdeRegisters, Channel, Device, &Packet);\r
-\r
+ *ByteCount = ActualWordCount << 1;\r
return Status;\r
}\r
\r
IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet\r
)\r
{\r
- EFI_STATUS PacketCommandStatus;\r
EFI_ATA_COMMAND_BLOCK AtaCommandBlock;\r
EFI_STATUS Status;\r
UINT8 Count;\r
// Read/Write the data of ATAPI Command\r
//\r
if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {\r
- PacketCommandStatus = AtaPacketReadWrite (\r
- PciIo,\r
- IdeRegisters,\r
- Packet->InDataBuffer,\r
- Packet->InTransferLength,\r
- TRUE,\r
- Packet->Timeout\r
- );\r
+ Status = AtaPacketReadWrite (\r
+ PciIo,\r
+ IdeRegisters,\r
+ Packet->InDataBuffer,\r
+ &Packet->InTransferLength,\r
+ TRUE,\r
+ Packet->Timeout\r
+ );\r
} else {\r
- PacketCommandStatus = AtaPacketReadWrite (\r
- PciIo,\r
- IdeRegisters,\r
- Packet->OutDataBuffer,\r
- Packet->OutTransferLength,\r
- FALSE,\r
- Packet->Timeout\r
- );\r
+ Status = AtaPacketReadWrite (\r
+ PciIo,\r
+ IdeRegisters,\r
+ Packet->OutDataBuffer,\r
+ &Packet->OutTransferLength,\r
+ FALSE,\r
+ Packet->Timeout\r
+ );\r
}\r
\r
- if (!EFI_ERROR (PacketCommandStatus)) {\r
- return PacketCommandStatus;\r
- }\r
-\r
- //\r
- // Return SenseData if PacketCommandStatus matches\r
- // the following return codes.\r
- //\r
- if ((PacketCommandStatus == EFI_BAD_BUFFER_SIZE) ||\r
- (PacketCommandStatus == EFI_DEVICE_ERROR) ||\r
- (PacketCommandStatus == EFI_TIMEOUT)) {\r
-\r
- //\r
- // avoid submit request sense command continuously.\r
- //\r
- if ((Packet->SenseData == NULL) || (((UINT8 *)Packet->Cdb)[0] == ATA_CMD_REQUEST_SENSE)) {\r
- return PacketCommandStatus;\r
- }\r
-\r
- AtaPacketRequestSense (\r
- PciIo,\r
- IdeRegisters,\r
- Channel,\r
- Device,\r
- Packet->SenseData,\r
- Packet->SenseDataLength,\r
- Packet->Timeout\r
- );\r
- }\r
-\r
- return PacketCommandStatus;\r
+ return Status;\r
}\r
\r
\r
PciIo = Instance->PciIo;\r
\r
for (IdeDevice = 0; IdeDevice < EfiIdeMaxDevice; IdeDevice++) {\r
+ //\r
+ // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.\r
+ //\r
+ IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)((IdeDevice << 4) | 0xe0));\r
+\r
//\r
// Send ATA Device Execut Diagnostic command.\r
// This command should work no matter DRDY is ready or not\r