In AtaAtapiPassThru driver

1.	move the non-blocking task related setting ahead to store the MapTable and PageCount in case there is a IO operation error happened then the error handler code could use those information to release the resource.
2.	Enlarge the TPL protective area to make sure the simulative delay time is accurate when there is mixing usage of Non blocking and blocking I/O.

Signed-off-by: qianouyang
Reviewed-by: erictian


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12712 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
qianouyang 2011-11-15 13:44:06 +00:00
parent 5d9f5dc1a0
commit 1aff716ac7
2 changed files with 159 additions and 158 deletions

View File

@ -1,14 +1,14 @@
/** @file /** @file
The file for AHCI mode of ATA host controller. The file for AHCI mode of ATA host controller.
Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/ **/
@ -33,7 +33,7 @@ AhciReadReg (
UINT32 Data; UINT32 Data;
ASSERT (PciIo != NULL); ASSERT (PciIo != NULL);
Data = 0; Data = 0;
PciIo->Mem.Read ( PciIo->Mem.Read (
@ -95,7 +95,7 @@ AhciAndReg (
) )
{ {
UINT32 Data; UINT32 Data;
ASSERT (PciIo != NULL); ASSERT (PciIo != NULL);
Data = AhciReadReg (PciIo, Offset); Data = AhciReadReg (PciIo, Offset);
@ -134,7 +134,7 @@ AhciOrReg (
/** /**
Wait for the value of the specified MMIO register set to the test value. Wait for the value of the specified MMIO register set to the test value.
@param PciIo The PCI IO protocol instance. @param PciIo The PCI IO protocol instance.
@param Offset The MMIO address to test. @param Offset The MMIO address to test.
@param MaskValue The mask value of memory. @param MaskValue The mask value of memory.
@ -155,7 +155,7 @@ AhciWaitMmioSet (
IN UINT64 Timeout IN UINT64 Timeout
) )
{ {
UINT32 Value; UINT32 Value;
UINT32 Delay; UINT32 Delay;
Delay = (UINT32) (DivU64x32 (Timeout, 1000) + 1); Delay = (UINT32) (DivU64x32 (Timeout, 1000) + 1);
@ -184,7 +184,7 @@ AhciWaitMmioSet (
/** /**
Wait for the value of the specified system memory set to the test value. Wait for the value of the specified system memory set to the test value.
@param Address The system memory address to test. @param Address The system memory address to test.
@param MaskValue The mask value of memory. @param MaskValue The mask value of memory.
@param TestValue The test value of memory. @param TestValue The test value of memory.
@ -203,7 +203,7 @@ AhciWaitMemSet (
IN UINT64 Timeout IN UINT64 Timeout
) )
{ {
UINT32 Value; UINT32 Value;
UINT32 Delay; UINT32 Delay;
Delay = (UINT32) (DivU64x32 (Timeout, 1000) + 1); Delay = (UINT32) (DivU64x32 (Timeout, 1000) + 1);
@ -238,7 +238,7 @@ AhciWaitMemSet (
/** /**
Check the memory status to the test value. Check the memory status to the test value.
@param[in] Address The memory address to test. @param[in] Address The memory address to test.
@param[in] MaskValue The mask value of memory. @param[in] MaskValue The mask value of memory.
@param[in] TestValue The test value of memory. @param[in] TestValue The test value of memory.
@ -263,7 +263,7 @@ AhciCheckMemSet (
if (RetryTimes != NULL) { if (RetryTimes != NULL) {
(*RetryTimes)--; (*RetryTimes)--;
} }
Value = *(volatile UINT32 *) Address; Value = *(volatile UINT32 *) Address;
Value &= MaskValue; Value &= MaskValue;
@ -279,13 +279,13 @@ AhciCheckMemSet (
} }
/** /**
Check if the device is still on port. It also checks if the AHCI controller Check if the device is still on port. It also checks if the AHCI controller
supports the address and data count will be transferred. supports the address and data count will be transferred.
@param PciIo The PCI IO protocol instance. @param PciIo The PCI IO protocol instance.
@param Port The number of port. @param Port The number of port.
@retval EFI_SUCCESS The device is attached to port and the transfer data is @retval EFI_SUCCESS The device is attached to port and the transfer data is
supported by AHCI controller. supported by AHCI controller.
@retval EFI_UNSUPPORTED The transfer address and count is not supported by AHCI @retval EFI_UNSUPPORTED The transfer address and count is not supported by AHCI
controller. controller.
@ -318,17 +318,17 @@ AhciCheckDeviceStatus (
Clear the port interrupt and error status. It will also clear Clear the port interrupt and error status. It will also clear
HBA interrupt status. HBA interrupt status.
@param PciIo The PCI IO protocol instance. @param PciIo The PCI IO protocol instance.
@param Port The number of port. @param Port The number of port.
**/ **/
VOID VOID
EFIAPI EFIAPI
AhciClearPortStatus ( AhciClearPortStatus (
IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT8 Port IN UINT8 Port
) )
{ {
UINT32 Offset; UINT32 Offset;
@ -388,7 +388,7 @@ AhciDumpPortStatus (
/** /**
Enable the FIS running for giving port. Enable the FIS running for giving port.
@param PciIo The PCI IO protocol instance. @param PciIo The PCI IO protocol instance.
@param Port The number of port. @param Port The number of port.
@param Timeout The timeout value of enabling FIS, uses 100ns as a unit. @param Timeout The timeout value of enabling FIS, uses 100ns as a unit.
@ -412,7 +412,7 @@ AhciEnableFisReceive (
AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_FRE); AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_FRE);
return AhciWaitMmioSet ( return AhciWaitMmioSet (
PciIo, PciIo,
Offset, Offset,
EFI_AHCI_PORT_CMD_FR, EFI_AHCI_PORT_CMD_FR,
EFI_AHCI_PORT_CMD_FR, EFI_AHCI_PORT_CMD_FR,
@ -439,7 +439,7 @@ AhciDisableFisReceive (
IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT8 Port, IN UINT8 Port,
IN UINT64 Timeout IN UINT64 Timeout
) )
{ {
UINT32 Offset; UINT32 Offset;
UINT32 Data; UINT32 Data;
@ -453,7 +453,7 @@ AhciDisableFisReceive (
if ((Data & (EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_CR)) != 0) { if ((Data & (EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_CR)) != 0) {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
// //
// Check if the Fis receive DMA engine for the port is running. // Check if the Fis receive DMA engine for the port is running.
// //
@ -476,7 +476,7 @@ AhciDisableFisReceive (
/** /**
Build the command list, command table and prepare the fis receiver. Build the command list, command table and prepare the fis receiver.
@param PciIo The PCI IO protocol instance. @param PciIo The PCI IO protocol instance.
@param AhciRegisters The pointer to the EFI_AHCI_REGISTERS. @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
@param Port The number of port. @param Port The number of port.
@ -489,7 +489,7 @@ AhciDisableFisReceive (
@param DataPhysicalAddr The pointer to the data buffer pci bus master address. @param DataPhysicalAddr The pointer to the data buffer pci bus master address.
@param DataLength The data count to be transferred. @param DataLength The data count to be transferred.
**/ **/
VOID VOID
EFIAPI EFIAPI
AhciBuildCommand ( AhciBuildCommand (
@ -504,7 +504,7 @@ AhciBuildCommand (
IN UINT8 CommandSlotNumber, IN UINT8 CommandSlotNumber,
IN OUT VOID *DataPhysicalAddr, IN OUT VOID *DataPhysicalAddr,
IN UINT64 DataLength IN UINT64 DataLength
) )
{ {
UINT64 BaseAddr; UINT64 BaseAddr;
UINT64 PrdtNumber; UINT64 PrdtNumber;
@ -516,7 +516,7 @@ AhciBuildCommand (
// //
// Filling the PRDT // Filling the PRDT
// //
PrdtNumber = (DataLength + EFI_AHCI_MAX_DATA_PER_PRDT - 1) / EFI_AHCI_MAX_DATA_PER_PRDT; PrdtNumber = (DataLength + EFI_AHCI_MAX_DATA_PER_PRDT - 1) / EFI_AHCI_MAX_DATA_PER_PRDT;
// //
@ -529,13 +529,13 @@ AhciBuildCommand (
Data64.Uint64 = (UINTN) (AhciRegisters->AhciRFis) + sizeof (EFI_AHCI_RECEIVED_FIS) * Port; Data64.Uint64 = (UINTN) (AhciRegisters->AhciRFis) + sizeof (EFI_AHCI_RECEIVED_FIS) * Port;
BaseAddr = Data64.Uint64; BaseAddr = Data64.Uint64;
ZeroMem ((VOID *)((UINTN) BaseAddr), sizeof (EFI_AHCI_RECEIVED_FIS)); ZeroMem ((VOID *)((UINTN) BaseAddr), sizeof (EFI_AHCI_RECEIVED_FIS));
ZeroMem (AhciRegisters->AhciCommandTable, sizeof (EFI_AHCI_COMMAND_TABLE)); ZeroMem (AhciRegisters->AhciCommandTable, sizeof (EFI_AHCI_COMMAND_TABLE));
CommandFis->AhciCFisPmNum = PortMultiplier; CommandFis->AhciCFisPmNum = PortMultiplier;
CopyMem (&AhciRegisters->AhciCommandTable->CommandFis, CommandFis, sizeof (EFI_AHCI_COMMAND_FIS)); CopyMem (&AhciRegisters->AhciCommandTable->CommandFis, CommandFis, sizeof (EFI_AHCI_COMMAND_FIS));
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD; Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
@ -554,11 +554,11 @@ AhciBuildCommand (
} else { } else {
AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_DLAE | EFI_AHCI_PORT_CMD_ATAPI)); AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_DLAE | EFI_AHCI_PORT_CMD_ATAPI));
} }
RemainedData = (UINTN) DataLength; RemainedData = (UINTN) DataLength;
MemAddr = (UINTN) DataPhysicalAddr; MemAddr = (UINTN) DataPhysicalAddr;
CommandList->AhciCmdPrdtl = (UINT32)PrdtNumber; CommandList->AhciCmdPrdtl = (UINT32)PrdtNumber;
for (PrdtIndex = 0; PrdtIndex < PrdtNumber; PrdtIndex++) { for (PrdtIndex = 0; PrdtIndex < PrdtNumber; PrdtIndex++) {
if (RemainedData < EFI_AHCI_MAX_DATA_PER_PRDT) { if (RemainedData < EFI_AHCI_MAX_DATA_PER_PRDT) {
AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = (UINT32)RemainedData - 1; AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = (UINT32)RemainedData - 1;
@ -584,7 +584,7 @@ AhciBuildCommand (
(VOID *) ((UINTN) AhciRegisters->AhciCmdList + (UINTN) CommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST)), (VOID *) ((UINTN) AhciRegisters->AhciCmdList + (UINTN) CommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST)),
CommandList, CommandList,
sizeof (EFI_AHCI_COMMAND_LIST) sizeof (EFI_AHCI_COMMAND_LIST)
); );
Data64.Uint64 = (UINT64)(UINTN) AhciRegisters->AhciCommandTablePciAddr; Data64.Uint64 = (UINT64)(UINTN) AhciRegisters->AhciCommandTablePciAddr;
AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtba = Data64.Uint32.Lower32; AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtba = Data64.Uint32.Lower32;
@ -595,7 +595,7 @@ AhciBuildCommand (
/** /**
Buid a command FIS. Buid a command FIS.
@param CmdFis A pointer to the EFI_AHCI_COMMAND_FIS data structure. @param CmdFis A pointer to the EFI_AHCI_COMMAND_FIS data structure.
@param AtaCommandBlock A pointer to the AhciBuildCommandFis data structure. @param AtaCommandBlock A pointer to the AhciBuildCommandFis data structure.
@ -613,7 +613,7 @@ AhciBuildCommandFis (
// //
// Indicator it's a command // Indicator it's a command
// //
CmdFis->AhciCFisCmdInd = 0x1; CmdFis->AhciCFisCmdInd = 0x1;
CmdFis->AhciCFisCmd = AtaCommandBlock->AtaCommand; CmdFis->AhciCFisCmd = AtaCommandBlock->AtaCommand;
CmdFis->AhciCFisFeature = AtaCommandBlock->AtaFeatures; CmdFis->AhciCFisFeature = AtaCommandBlock->AtaFeatures;
@ -636,7 +636,7 @@ AhciBuildCommandFis (
/** /**
Start a PIO data transfer on specific port. Start a PIO data transfer on specific port.
@param[in] PciIo The PCI IO protocol instance. @param[in] PciIo The PCI IO protocol instance.
@param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS. @param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
@param[in] Port The number of port. @param[in] Port The number of port.
@ -667,8 +667,8 @@ AhciPioTransfer (
IN UINT8 Port, IN UINT8 Port,
IN UINT8 PortMultiplier, IN UINT8 PortMultiplier,
IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL, IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
IN UINT8 AtapiCommandLength, IN UINT8 AtapiCommandLength,
IN BOOLEAN Read, IN BOOLEAN Read,
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
IN OUT VOID *MemoryAddr, IN OUT VOID *MemoryAddr,
@ -686,7 +686,7 @@ AhciPioTransfer (
EFI_PCI_IO_PROTOCOL_OPERATION Flag; EFI_PCI_IO_PROTOCOL_OPERATION Flag;
UINT32 Delay; UINT32 Delay;
EFI_AHCI_COMMAND_FIS CFis; EFI_AHCI_COMMAND_FIS CFis;
EFI_AHCI_COMMAND_LIST CmdList; EFI_AHCI_COMMAND_LIST CmdList;
UINT32 PortTfd; UINT32 PortTfd;
UINT32 PrdCount; UINT32 PrdCount;
@ -712,7 +712,7 @@ AhciPioTransfer (
if (EFI_ERROR (Status) || (DataCount != MapLength)) { if (EFI_ERROR (Status) || (DataCount != MapLength)) {
return EFI_BAD_BUFFER_SIZE; return EFI_BAD_BUFFER_SIZE;
} }
// //
// Package read needed // Package read needed
// //
@ -735,8 +735,8 @@ AhciPioTransfer (
0, 0,
(VOID *)(UINTN)PhyAddr, (VOID *)(UINTN)PhyAddr,
DataCount DataCount
); );
Status = AhciStartCommand ( Status = AhciStartCommand (
PciIo, PciIo,
Port, Port,
@ -819,7 +819,7 @@ Exit:
Port, Port,
Timeout Timeout
); );
AhciDisableFisReceive ( AhciDisableFisReceive (
PciIo, PciIo,
Port, Port,
@ -870,7 +870,7 @@ AhciDmaTransfer (
IN UINT8 PortMultiplier, IN UINT8 PortMultiplier,
IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL, IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
IN UINT8 AtapiCommandLength, IN UINT8 AtapiCommandLength,
IN BOOLEAN Read, IN BOOLEAN Read,
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
IN OUT VOID *MemoryAddr, IN OUT VOID *MemoryAddr,
@ -905,15 +905,15 @@ AhciDmaTransfer (
// BlockIO tasks. // BlockIO tasks.
// Delay 100us to simulate the blocking time out checking. // Delay 100us to simulate the blocking time out checking.
// //
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
while ((Task == NULL) && (!IsListEmpty (&Instance->NonBlockingTaskList))) { while ((Task == NULL) && (!IsListEmpty (&Instance->NonBlockingTaskList))) {
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
AsyncNonBlockingTransferRoutine (NULL, Instance); AsyncNonBlockingTransferRoutine (NULL, Instance);
gBS->RestoreTPL (OldTpl);
// //
// Stall for 100us. // Stall for 100us.
// //
MicroSecondDelay (100); MicroSecondDelay (100);
} }
gBS->RestoreTPL (OldTpl);
if ((Task == NULL) || ((Task != NULL) && (!Task->IsStart))) { if ((Task == NULL) || ((Task != NULL) && (!Task->IsStart))) {
// //
@ -1022,21 +1022,21 @@ Exit:
// //
// For Blocking mode, the command should be stopped, the Fis should be disabled // For Blocking mode, the command should be stopped, the Fis should be disabled
// and the PciIo should be unmapped. // and the PciIo should be unmapped.
// For non-blocking mode, only when a error is happened (if the return status is // For non-blocking mode, only when a error is happened (if the return status is
// EFI_NOT_READY that means the command doesn't finished, try again.), first do the // EFI_NOT_READY that means the command doesn't finished, try again.), first do the
// context cleanup, then set the packet's Asb status. // context cleanup, then set the packet's Asb status.
// //
if (Task == NULL || if (Task == NULL ||
((Task != NULL) && (Status != EFI_NOT_READY)) ((Task != NULL) && (Status != EFI_NOT_READY))
) { ) {
AhciStopCommand ( AhciStopCommand (
PciIo, PciIo,
Port, Port,
Timeout Timeout
); );
AhciDisableFisReceive ( AhciDisableFisReceive (
PciIo, PciIo,
Port, Port,
Timeout Timeout
); );
@ -1057,7 +1057,7 @@ Exit:
/** /**
Start a non data transfer on specific port. Start a non data transfer on specific port.
@param[in] PciIo The PCI IO protocol instance. @param[in] PciIo The PCI IO protocol instance.
@param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS. @param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
@param[in] Port The number of port. @param[in] Port The number of port.
@ -1076,7 +1076,7 @@ Exit:
@retval EFI_UNSUPPORTED The device is not ready for transfer. @retval EFI_UNSUPPORTED The device is not ready for transfer.
@retval EFI_SUCCESS The non data transfer executes successfully. @retval EFI_SUCCESS The non data transfer executes successfully.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
AhciNonDataTransfer ( AhciNonDataTransfer (
@ -1174,11 +1174,11 @@ Exit:
/** /**
Stop command running for giving port Stop command running for giving port
@param PciIo The PCI IO protocol instance. @param PciIo The PCI IO protocol instance.
@param Port The number of port. @param Port The number of port.
@param Timeout The timeout value of stop, uses 100ns as a unit. @param Timeout The timeout value of stop, uses 100ns as a unit.
@retval EFI_DEVICE_ERROR The command stop unsuccessfully. @retval EFI_DEVICE_ERROR The command stop unsuccessfully.
@retval EFI_TIMEOUT The operation is time out. @retval EFI_TIMEOUT The operation is time out.
@retval EFI_SUCCESS The command stop successfully. @retval EFI_SUCCESS The command stop successfully.
@ -1258,7 +1258,7 @@ AhciStartCommand (
); );
Status = AhciEnableFisReceive ( Status = AhciEnableFisReceive (
PciIo, PciIo,
Port, Port,
Timeout Timeout
); );
@ -1318,7 +1318,7 @@ AhciStartCommand (
@param PciIo The PCI IO protocol instance. @param PciIo The PCI IO protocol instance.
@param Port The number of port. @param Port The number of port.
@param Timeout The timeout value of reset, uses 100ns as a unit. @param Timeout The timeout value of reset, uses 100ns as a unit.
@retval EFI_DEVICE_ERROR The port reset unsuccessfully @retval EFI_DEVICE_ERROR The port reset unsuccessfully
@retval EFI_TIMEOUT The reset operation is time out. @retval EFI_TIMEOUT The reset operation is time out.
@retval EFI_SUCCESS The port reset successfully. @retval EFI_SUCCESS The port reset successfully.
@ -1397,7 +1397,7 @@ EFIAPI
AhciReset ( AhciReset (
IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT64 Timeout IN UINT64 Timeout
) )
{ {
UINT32 Delay; UINT32 Delay;
UINT32 Value; UINT32 Value;
@ -1544,7 +1544,7 @@ AhciAtaSmartSupport (
// //
// S.M.A.R.T is not supported by the device // S.M.A.R.T is not supported by the device
// //
DEBUG ((EFI_D_INFO, "S.M.A.R.T feature is not supported at port [%d] PortMultiplier [%d]!\n", DEBUG ((EFI_D_INFO, "S.M.A.R.T feature is not supported at port [%d] PortMultiplier [%d]!\n",
Port, PortMultiplier)); Port, PortMultiplier));
} else { } else {
// //
@ -1620,7 +1620,7 @@ AhciAtaSmartSupport (
/** /**
Send Buffer cmd to specific device. Send Buffer cmd to specific device.
@param PciIo The PCI IO protocol instance. @param PciIo The PCI IO protocol instance.
@param AhciRegisters The pointer to the EFI_AHCI_REGISTERS. @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
@param Port The number of port. @param Port The number of port.
@ -1640,7 +1640,7 @@ AhciIdentify (
IN EFI_AHCI_REGISTERS *AhciRegisters, IN EFI_AHCI_REGISTERS *AhciRegisters,
IN UINT8 Port, IN UINT8 Port,
IN UINT8 PortMultiplier, IN UINT8 PortMultiplier,
IN OUT EFI_IDENTIFY_DATA *Buffer IN OUT EFI_IDENTIFY_DATA *Buffer
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -1669,7 +1669,7 @@ AhciIdentify (
&AtaStatusBlock, &AtaStatusBlock,
Buffer, Buffer,
sizeof (EFI_IDENTIFY_DATA), sizeof (EFI_IDENTIFY_DATA),
ATA_ATAPI_TIMEOUT, ATA_ATAPI_TIMEOUT,
NULL NULL
); );
@ -1678,7 +1678,7 @@ AhciIdentify (
/** /**
Send Buffer cmd to specific device. Send Buffer cmd to specific device.
@param PciIo The PCI IO protocol instance. @param PciIo The PCI IO protocol instance.
@param AhciRegisters The pointer to the EFI_AHCI_REGISTERS. @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
@param Port The number of port. @param Port The number of port.
@ -1698,7 +1698,7 @@ AhciIdentifyPacket (
IN EFI_AHCI_REGISTERS *AhciRegisters, IN EFI_AHCI_REGISTERS *AhciRegisters,
IN UINT8 Port, IN UINT8 Port,
IN UINT8 PortMultiplier, IN UINT8 PortMultiplier,
IN OUT EFI_IDENTIFY_DATA *Buffer IN OUT EFI_IDENTIFY_DATA *Buffer
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -1736,7 +1736,7 @@ AhciIdentifyPacket (
/** /**
Send SET FEATURE cmd on specific device. Send SET FEATURE cmd on specific device.
@param PciIo The PCI IO protocol instance. @param PciIo The PCI IO protocol instance.
@param AhciRegisters The pointer to the EFI_AHCI_REGISTERS. @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
@param Port The number of port. @param Port The number of port.
@ -1785,7 +1785,7 @@ AhciDeviceSetFeature (
0, 0,
&AtaCommandBlock, &AtaCommandBlock,
&AtaStatusBlock, &AtaStatusBlock,
ATA_ATAPI_TIMEOUT, ATA_ATAPI_TIMEOUT,
NULL NULL
); );
@ -1793,12 +1793,12 @@ AhciDeviceSetFeature (
} }
/** /**
This function is used to send out ATAPI commands conforms to the Packet Command This function is used to send out ATAPI commands conforms to the Packet Command
with PIO Protocol. with PIO Protocol.
@param PciIo The PCI IO protocol instance. @param PciIo The PCI IO protocol instance.
@param AhciRegisters The pointer to the EFI_AHCI_REGISTERS. @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
@param Port The number of port. @param Port The number of port.
@param PortMultiplier The number of port multiplier. @param PortMultiplier The number of port multiplier.
@param Packet A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET structure. @param Packet A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET structure.
@ -1862,7 +1862,7 @@ AhciPacketCommandExecute (
Packet->CdbLength, Packet->CdbLength,
&AtaCommandBlock, &AtaCommandBlock,
&AtaStatusBlock, &AtaStatusBlock,
Packet->Timeout, Packet->Timeout,
NULL NULL
); );
} else { } else {
@ -1878,7 +1878,7 @@ AhciPacketCommandExecute (
&AtaStatusBlock, &AtaStatusBlock,
Buffer, Buffer,
Length, Length,
Packet->Timeout, Packet->Timeout,
NULL NULL
); );
} }
@ -1887,7 +1887,7 @@ AhciPacketCommandExecute (
/** /**
Allocate transfer-related data struct which is used at AHCI mode. Allocate transfer-related data struct which is used at AHCI mode.
@param PciIo The PCI IO protocol instance. @param PciIo The PCI IO protocol instance.
@param AhciRegisters The pointer to the EFI_AHCI_REGISTERS. @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
@ -1957,7 +1957,7 @@ AhciCreateTransferDescriptor (
if (EFI_ERROR (Status) || (Bytes != MaxReceiveFisSize)) { if (EFI_ERROR (Status) || (Bytes != MaxReceiveFisSize)) {
// //
// Map error or unable to map the whole RFis buffer into a contiguous region. // Map error or unable to map the whole RFis buffer into a contiguous region.
// //
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;
goto Error6; goto Error6;
@ -1989,7 +1989,7 @@ AhciCreateTransferDescriptor (
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
// //
// Free mapped resource. // Free mapped resource.
// //
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;
goto Error5; goto Error5;
@ -2045,7 +2045,7 @@ AhciCreateTransferDescriptor (
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
// //
// Free mapped resource. // Free mapped resource.
// //
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;
goto Error3; goto Error3;
@ -2085,7 +2085,7 @@ AhciCreateTransferDescriptor (
return EFI_SUCCESS; return EFI_SUCCESS;
// //
// Map error or unable to map the whole CmdList buffer into a contiguous region. // Map error or unable to map the whole CmdList buffer into a contiguous region.
// //
Error1: Error1:
PciIo->Unmap ( PciIo->Unmap (
@ -2127,8 +2127,8 @@ Error6:
/** /**
Initialize ATA host controller at AHCI mode. Initialize ATA host controller at AHCI mode.
The function is designed to initialize ATA host controller. The function is designed to initialize ATA host controller.
@param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance. @param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
**/ **/
@ -2164,7 +2164,7 @@ AhciModeInitialization (
PciIo = Instance->PciIo; PciIo = Instance->PciIo;
IdeInit = Instance->IdeControllerInit; IdeInit = Instance->IdeControllerInit;
Status = AhciReset (PciIo, EFI_AHCI_BUS_RESET_TIMEOUT); Status = AhciReset (PciIo, EFI_AHCI_BUS_RESET_TIMEOUT);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
@ -2187,10 +2187,10 @@ AhciModeInitialization (
// //
// Get the bit map of those ports exposed by this HBA. // Get the bit map of those ports exposed by this HBA.
// It indicates which ports that the HBA supports are available for software to use. // It indicates which ports that the HBA supports are available for software to use.
// //
PortImplementBitMap = AhciReadReg(PciIo, EFI_AHCI_PI_OFFSET); PortImplementBitMap = AhciReadReg(PciIo, EFI_AHCI_PI_OFFSET);
AhciRegisters = &Instance->AhciRegisters; AhciRegisters = &Instance->AhciRegisters;
Status = AhciCreateTransferDescriptor (PciIo, AhciRegisters); Status = AhciCreateTransferDescriptor (PciIo, AhciRegisters);
@ -2198,7 +2198,7 @@ AhciModeInitialization (
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
for (Port = 0; Port < MaxPortNumber; Port ++) { for (Port = 0; Port < MaxPortNumber; Port ++) {
if ((PortImplementBitMap & (BIT0 << Port)) != 0) { if ((PortImplementBitMap & (BIT0 << Port)) != 0) {
IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, Port); IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, Port);
@ -2249,7 +2249,7 @@ AhciModeInitialization (
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD; Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_FRE); AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_FRE);
Status = AhciWaitMmioSet ( Status = AhciWaitMmioSet (
PciIo, PciIo,
Offset, Offset,
EFI_AHCI_PORT_CMD_FR, EFI_AHCI_PORT_CMD_FR,
EFI_AHCI_PORT_CMD_FR, EFI_AHCI_PORT_CMD_FR,
@ -2302,7 +2302,7 @@ AhciModeInitialization (
MicroSecondDelay (1000); MicroSecondDelay (1000);
PhyDetectDelay--; PhyDetectDelay--;
} while (PhyDetectDelay > 0); } while (PhyDetectDelay > 0);
if (PhyDetectDelay == 0) { if (PhyDetectDelay == 0) {
continue; continue;
} }
@ -2312,7 +2312,7 @@ AhciModeInitialization (
// //
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SIG; Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SIG;
Status = AhciWaitMmioSet ( Status = AhciWaitMmioSet (
PciIo, PciIo,
Offset, Offset,
0x0000FFFF, 0x0000FFFF,
0x00000101, 0x00000101,
@ -2343,7 +2343,7 @@ AhciModeInitialization (
} else { } else {
continue; continue;
} }
DEBUG ((EFI_D_INFO, "port [%d] port mulitplier [%d] has a [%a]\n", DEBUG ((EFI_D_INFO, "port [%d] port mulitplier [%d] has a [%a]\n",
Port, 0, DeviceType == EfiIdeCdrom ? "cdrom" : "harddisk")); Port, 0, DeviceType == EfiIdeCdrom ? "cdrom" : "harddisk"));
// //
@ -2401,7 +2401,7 @@ AhciModeInitialization (
TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode); TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode);
} else if (SupportedModes->MultiWordDmaMode.Valid) { } else if (SupportedModes->MultiWordDmaMode.Valid) {
TransferMode.ModeCategory = EFI_ATA_MODE_MDMA; TransferMode.ModeCategory = EFI_ATA_MODE_MDMA;
TransferMode.ModeNumber = (UINT8) SupportedModes->MultiWordDmaMode.Mode; TransferMode.ModeNumber = (UINT8) SupportedModes->MultiWordDmaMode.Mode;
} }
Status = AhciDeviceSetFeature (PciIo, AhciRegisters, Port, 0, 0x03, (UINT32)(*(UINT8 *)&TransferMode)); Status = AhciDeviceSetFeature (PciIo, AhciRegisters, Port, 0, 0x03, (UINT32)(*(UINT8 *)&TransferMode));

View File

@ -1,14 +1,14 @@
/** @file /** @file
Header file for AHCI mode of ATA host controller. Header file for AHCI mode of ATA host controller.
Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/ **/
@ -18,7 +18,7 @@
read a one-byte data from a IDE port. read a one-byte data from a IDE port.
@param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
@param Port The IDE Port number @param Port The IDE Port number
@return the one-byte data read from IDE port @return the one-byte data read from IDE port
**/ **/
@ -514,7 +514,7 @@ DRQReady (
} }
/** /**
This function is used to poll for the DRQ bit set in the Alternate Status Register. This function is used to poll for the DRQ bit set in the Alternate Status Register.
DRQ is set when the device is ready to transfer data. So this function is called after DRQ is set when the device is ready to transfer data. So this function is called after
the command is sent to the device and before required data is transferred. the command is sent to the device and before required data is transferred.
@param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure. @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
@ -582,7 +582,7 @@ DRQReady2 (
/** /**
This function is used to poll for the DRDY bit set in the Status Register. DRDY This function is used to poll for the DRDY bit set in the Status Register. DRDY
bit is set when the device is ready to accept command. Most ATA commands must be bit is set when the device is ready to accept command. Most ATA commands must be
sent after DRDY set except the ATAPI Packet Command. sent after DRDY set except the ATAPI Packet Command.
@param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure. @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
@ -644,8 +644,8 @@ DRDYReady (
} }
/** /**
This function is used to poll for the DRDY bit set in the Alternate Status Register. This function is used to poll for the DRDY bit set in the Alternate Status Register.
DRDY bit is set when the device is ready to accept command. Most ATA commands must DRDY bit is set when the device is ready to accept command. Most ATA commands must
be sent after DRDY set except the ATAPI Packet Command. be sent after DRDY set except the ATAPI Packet Command.
@param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure. @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
@ -802,7 +802,7 @@ WaitForBSYClear2 (
} }
/** /**
Get IDE i/o port registers' base addresses by mode. Get IDE i/o port registers' base addresses by mode.
In 'Compatibility' mode, use fixed addresses. In 'Compatibility' mode, use fixed addresses.
In Native-PCI mode, get base addresses from BARs in the PCI IDE controller's In Native-PCI mode, get base addresses from BARs in the PCI IDE controller's
@ -825,7 +825,7 @@ WaitForBSYClear2 (
|___________|_______________|_______________| |___________|_______________|_______________|
Table 1. Compatibility resource mappings Table 1. Compatibility resource mappings
b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs
in IDE controller's PCI Configuration Space, shown in the Table 2 below. in IDE controller's PCI Configuration Space, shown in the Table 2 below.
___________________________________________________ ___________________________________________________
@ -842,7 +842,7 @@ WaitForBSYClear2 (
@param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
@param[in, out] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to @param[in, out] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
store the IDE i/o port registers' base addresses store the IDE i/o port registers' base addresses
@retval EFI_UNSUPPORTED Return this value when the BARs is not IO type @retval EFI_UNSUPPORTED Return this value when the BARs is not IO type
@retval EFI_SUCCESS Get the Base address successfully @retval EFI_SUCCESS Get the Base address successfully
@retval Other Read the pci configureation data error @retval Other Read the pci configureation data error
@ -944,7 +944,7 @@ GetIdeRegisterIoAddr (
/** /**
This function is used to implement the Soft Reset on the specified device. But, This function is used to implement the Soft Reset on the specified device. But,
the ATA Soft Reset mechanism is so strong a reset method that it will force the ATA Soft Reset mechanism is so strong a reset method that it will force
resetting on both devices connected to the same cable. resetting on both devices connected to the same cable.
It is called by IdeBlkIoReset(), a interface function of Block It is called by IdeBlkIoReset(), a interface function of Block
@ -996,7 +996,7 @@ AtaSoftReset (
// //
// Wait for at least 10 ms to check BSY status, we use 10 ms // Wait for at least 10 ms to check BSY status, we use 10 ms
// for better compatibility // for better compatibility
// //
MicroSecondDelay (10000); MicroSecondDelay (10000);
// //
@ -1114,14 +1114,14 @@ AtaIssueCommand (
@param[in] Timeout The time to complete the command, uses 100ns as a unit. @param[in] Timeout The time to complete the command, uses 100ns as a unit.
@param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
used by non-blocking mode. used by non-blocking mode.
@retval EFI_SUCCESS send out the ATA command and device send required data successfully. @retval EFI_SUCCESS send out the ATA command and device send required data successfully.
@retval EFI_DEVICE_ERROR command sent failed. @retval EFI_DEVICE_ERROR command sent failed.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
AtaPioDataInOut ( AtaPioDataInOut (
IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_PCI_IO_PROTOCOL *PciIo,
IN EFI_IDE_REGISTERS *IdeRegisters, IN EFI_IDE_REGISTERS *IdeRegisters,
IN OUT VOID *Buffer, IN OUT VOID *Buffer,
@ -1180,7 +1180,7 @@ AtaPioDataInOut (
// Poll DRQ bit set, data transfer can be performed only when DRQ is ready // Poll DRQ bit set, data transfer can be performed only when DRQ is ready
// //
Status = DRQReady2 (PciIo, IdeRegisters, Timeout); Status = DRQReady2 (PciIo, IdeRegisters, Timeout);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR; Status = EFI_DEVICE_ERROR;
goto Exit; goto Exit;
} }
@ -1256,7 +1256,7 @@ Exit:
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
AtaNonDataCommandIn ( AtaNonDataCommandIn (
IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_PCI_IO_PROTOCOL *PciIo,
IN EFI_IDE_REGISTERS *IdeRegisters, IN EFI_IDE_REGISTERS *IdeRegisters,
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
@ -1288,7 +1288,7 @@ AtaNonDataCommandIn (
Status = EFI_DEVICE_ERROR; Status = EFI_DEVICE_ERROR;
goto Exit; goto Exit;
} }
Status = CheckStatusRegister (PciIo, IdeRegisters); Status = CheckStatusRegister (PciIo, IdeRegisters);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR; Status = EFI_DEVICE_ERROR;
@ -1300,7 +1300,7 @@ Exit:
// Dump All Ide registers to ATA_STATUS_BLOCK // Dump All Ide registers to ATA_STATUS_BLOCK
// //
DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock); DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);
// //
// Not support the Non-blocking now,just do the blocking process. // Not support the Non-blocking now,just do the blocking process.
// //
@ -1309,7 +1309,7 @@ Exit:
/** /**
Wait for memory to be set. Wait for memory to be set.
@param[in] PciIo The PCI IO protocol instance. @param[in] PciIo The PCI IO protocol instance.
@param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure. @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
@ -1322,7 +1322,7 @@ EFI_STATUS
AtaUdmStatusWait ( AtaUdmStatusWait (
IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_PCI_IO_PROTOCOL *PciIo,
IN EFI_IDE_REGISTERS *IdeRegisters IN EFI_IDE_REGISTERS *IdeRegisters
) )
{ {
UINT8 RegisterValue; UINT8 RegisterValue;
EFI_STATUS Status; EFI_STATUS Status;
@ -1362,7 +1362,7 @@ AtaUdmStatusWait (
/** /**
Check if the memory to be set. Check if the memory to be set.
@param[in] PciIo The PCI IO protocol instance. @param[in] PciIo The PCI IO protocol instance.
@param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
used by non-blocking mode. used by non-blocking mode.
@ -1495,15 +1495,15 @@ AtaUdmaInOut (
// BlockIO tasks. // BlockIO tasks.
// Delay 1ms to simulate the blocking time out checking. // Delay 1ms to simulate the blocking time out checking.
// //
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
while ((Task == NULL) && (!IsListEmpty (&Instance->NonBlockingTaskList))) { while ((Task == NULL) && (!IsListEmpty (&Instance->NonBlockingTaskList))) {
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
AsyncNonBlockingTransferRoutine (NULL, Instance); AsyncNonBlockingTransferRoutine (NULL, Instance);
gBS->RestoreTPL (OldTpl);
// //
// Stall for 1 milliseconds. // Stall for 1 milliseconds.
// //
MicroSecondDelay (1000); MicroSecondDelay (1000);
} }
gBS->RestoreTPL (OldTpl);
// //
// The data buffer should be even alignment // The data buffer should be even alignment
@ -1520,10 +1520,10 @@ AtaUdmaInOut (
IoPortForBmid = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMID_OFFSET); IoPortForBmid = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMID_OFFSET);
// //
// For Blocking mode, start the command. // For Blocking mode, start the command.
// For non-blocking mode, when the command is not started, start it, otherwise // For non-blocking mode, when the command is not started, start it, otherwise
// go to check the status. // go to check the status.
// //
if (((Task != NULL) && (!Task->IsStart)) || (Task == NULL)) { if (((Task != NULL) && (!Task->IsStart)) || (Task == NULL)) {
// //
// Calculate the number of PRD entry. // Calculate the number of PRD entry.
@ -1663,6 +1663,20 @@ AtaUdmaInOut (
} }
IdeWritePortB (PciIo, IoPortForBmic, RegisterValue); IdeWritePortB (PciIo, IoPortForBmic, RegisterValue);
if (Task != NULL) {
//
// Max transfer number of sectors for one command is 65536(32Mbyte),
// it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
// So set the variable Count to 2000, for about 2 second Timeout time.
//
Task->RetryTimes = 2000;
Task->Map = BufferMap;
Task->TableMap = PrdTableMap;
Task->MapBaseAddress = PrdBaseAddr;
Task->PageCount = PageCount;
Task->IsStart = TRUE;
}
// //
// Issue ATA command // Issue ATA command
// //
@ -1685,19 +1699,6 @@ AtaUdmaInOut (
RegisterValue |= BMIC_START; RegisterValue |= BMIC_START;
IdeWritePortB(PciIo, IoPortForBmic, RegisterValue); IdeWritePortB(PciIo, IoPortForBmic, RegisterValue);
if (Task != NULL) {
//
// Max transfer number of sectors for one command is 65536(32Mbyte),
// it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
// So set the variable Count to 2000, for about 2 second Timeout time.
//
Task->RetryTimes = 2000;
Task->Map = BufferMap;
Task->TableMap = PrdTableMap;
Task->MapBaseAddress = PrdBaseAddr;
Task->PageCount = PageCount;
Task->IsStart = TRUE;
}
} }
// //
@ -1771,7 +1772,7 @@ Exit:
// //
DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock); DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);
} }
return Status; return Status;
} }
@ -1805,8 +1806,8 @@ AtaPacketReadPendingData (
while ((TempWordBuffer & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) { while ((TempWordBuffer & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {
IdeReadPortWMultiple ( IdeReadPortWMultiple (
PciIo, PciIo,
IdeRegisters->Data, IdeRegisters->Data,
1, 1,
&TempWordBuffer &TempWordBuffer
); );
TempWordBuffer = IdeReadPortB (PciIo, IdeRegisters->AltOrDev); TempWordBuffer = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
@ -1816,7 +1817,7 @@ AtaPacketReadPendingData (
} }
/** /**
This function is called by AtaPacketCommandExecute(). This function is called by AtaPacketCommandExecute().
It is used to transfer data between host and device. The data direction is specified It is used to transfer data between host and device. The data direction is specified
by the fourth parameter. by the fourth parameter.
@ -1856,7 +1857,7 @@ AtaPacketReadWrite (
if (ByteCount == 0) { if (ByteCount == 0) {
return EFI_SUCCESS; return EFI_SUCCESS;
} }
PtrBuffer = Buffer; PtrBuffer = Buffer;
RequiredWordCount = (UINT32)RShiftU64(ByteCount, 1); RequiredWordCount = (UINT32)RShiftU64(ByteCount, 1);
// //
@ -1911,7 +1912,7 @@ AtaPacketReadWrite (
PtrBuffer += WordCount; PtrBuffer += WordCount;
ActualWordCount += WordCount; ActualWordCount += WordCount;
} }
if (Read) { if (Read) {
// //
// In the case where the drive wants to send more data than we need to read, // In the case where the drive wants to send more data than we need to read,
@ -1936,7 +1937,7 @@ AtaPacketReadWrite (
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
return Status; return Status;
} }
@ -1991,7 +1992,7 @@ AtaPacketRequestSense (
} }
/** /**
This function is used to send out ATAPI commands conforms to the Packet Command This function is used to send out ATAPI commands conforms to the Packet Command
with PIO Data In Protocol. with PIO Data In Protocol.
@param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
@ -2071,7 +2072,7 @@ AtaPacketCommandExecute (
// Send out ATAPI command packet // Send out ATAPI command packet
// //
for (Count = 0; Count < 6; Count++) { for (Count = 0; Count < 6; Count++) {
IdeWritePortW (PciIo, IdeRegisters->Data, *((UINT16*)PacketCommand + Count)); IdeWritePortW (PciIo, IdeRegisters->Data, *((UINT16*)PacketCommand + Count));
// //
// Stall for 10 microseconds. // Stall for 10 microseconds.
// //
@ -2212,7 +2213,7 @@ SetDriveParameters (
EFI_ATA_COMMAND_BLOCK AtaCommandBlock; EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK)); ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
AtaCommandBlock.AtaCommand = ATA_CMD_INIT_DRIVE_PARAM; AtaCommandBlock.AtaCommand = ATA_CMD_INIT_DRIVE_PARAM;
AtaCommandBlock.AtaSectorCount = DriveParameters->Sector; AtaCommandBlock.AtaSectorCount = DriveParameters->Sector;
AtaCommandBlock.AtaDeviceHead = (UINT8) ((Device << 0x4) + DriveParameters->Heads); AtaCommandBlock.AtaDeviceHead = (UINT8) ((Device << 0x4) + DriveParameters->Heads);
@ -2225,7 +2226,7 @@ SetDriveParameters (
&Instance->IdeRegisters[Channel], &Instance->IdeRegisters[Channel],
&AtaCommandBlock, &AtaCommandBlock,
AtaStatusBlock, AtaStatusBlock,
ATA_ATAPI_TIMEOUT, ATA_ATAPI_TIMEOUT,
NULL NULL
); );
@ -2241,7 +2242,7 @@ SetDriveParameters (
&Instance->IdeRegisters[Channel], &Instance->IdeRegisters[Channel],
&AtaCommandBlock, &AtaCommandBlock,
AtaStatusBlock, AtaStatusBlock,
ATA_ATAPI_TIMEOUT, ATA_ATAPI_TIMEOUT,
NULL NULL
); );
@ -2347,7 +2348,7 @@ IdeAtaSmartSupport (
// //
// S.M.A.R.T is not supported by the device // S.M.A.R.T is not supported by the device
// //
DEBUG ((EFI_D_INFO, "S.M.A.R.T feature is not supported at [%a] channel [%a] device!\n", DEBUG ((EFI_D_INFO, "S.M.A.R.T feature is not supported at [%a] channel [%a] device!\n",
(Channel == 1) ? "secondary" : "primary", (Device == 1) ? "slave" : "master")); (Channel == 1) ? "secondary" : "primary", (Device == 1) ? "slave" : "master"));
} else { } else {
// //
@ -2407,7 +2408,7 @@ IdeAtaSmartSupport (
} }
} }
DEBUG ((EFI_D_INFO, "Enabled S.M.A.R.T feature at [%a] channel [%a] device!\n", DEBUG ((EFI_D_INFO, "Enabled S.M.A.R.T feature at [%a] channel [%a] device!\n",
(Channel == 1) ? "secondary" : "primary", (Device == 1) ? "slave" : "master")); (Channel == 1) ? "secondary" : "primary", (Device == 1) ? "slave" : "master"));
} }
@ -2478,19 +2479,19 @@ AtaIdentify (
to fill in the Media data structure of the Block I/O Protocol interface. to fill in the Media data structure of the Block I/O Protocol interface.
There are 5 steps to reach such objective: There are 5 steps to reach such objective:
1. Sends out the ATAPI Identify Command to the specified device. 1. Sends out the ATAPI Identify Command to the specified device.
Only ATAPI device responses to this command. If the command succeeds, Only ATAPI device responses to this command. If the command succeeds,
it returns the Identify data structure which filled with information it returns the Identify data structure which filled with information
about the device. Since the ATAPI device contains removable media, about the device. Since the ATAPI device contains removable media,
the only meaningful information is the device module name. the only meaningful information is the device module name.
2. Sends out ATAPI Inquiry Packet Command to the specified device. 2. Sends out ATAPI Inquiry Packet Command to the specified device.
This command will return inquiry data of the device, which contains This command will return inquiry data of the device, which contains
the device type information. the device type information.
3. Allocate sense data space for future use. We don't detect the media 3. Allocate sense data space for future use. We don't detect the media
presence here to improvement boot performance, especially when CD presence here to improvement boot performance, especially when CD
media is present. The media detection will be performed just before media is present. The media detection will be performed just before
each BLK_IO read/write each BLK_IO read/write
@param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure. @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
@param Channel The channel number of device. @param Channel The channel number of device.
@param Device The device number of device. @param Device The device number of device.
@ -2517,7 +2518,7 @@ AtaIdentifyPacket (
EFI_ATA_COMMAND_BLOCK AtaCommandBlock; EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK)); ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DEVICE; AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DEVICE;
AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4); AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
@ -2596,7 +2597,7 @@ DetectAndConfigIdeDevice (
// This command should work no matter DRDY is ready or not // This command should work no matter DRDY is ready or not
// //
IdeWritePortB (PciIo, IdeRegisters->CmdOrStatus, ATA_CMD_EXEC_DRIVE_DIAG); IdeWritePortB (PciIo, IdeRegisters->CmdOrStatus, ATA_CMD_EXEC_DRIVE_DIAG);
Status = WaitForBSYClear (PciIo, IdeRegisters, 350000000); Status = WaitForBSYClear (PciIo, IdeRegisters, 350000000);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG((EFI_D_ERROR, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status)); DEBUG((EFI_D_ERROR, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status));
@ -2660,7 +2661,7 @@ DetectAndConfigIdeDevice (
continue; continue;
} }
DEBUG ((EFI_D_INFO, "[%a] channel [%a] [%a] device\n", DEBUG ((EFI_D_INFO, "[%a] channel [%a] [%a] device\n",
(IdeChannel == 1) ? "secondary" : "primary ", (IdeDevice == 1) ? "slave " : "master", (IdeChannel == 1) ? "secondary" : "primary ", (IdeDevice == 1) ? "slave " : "master",
DeviceType == EfiIdeCdrom ? "cdrom " : "harddisk")); DeviceType == EfiIdeCdrom ? "cdrom " : "harddisk"));
// //
@ -2781,9 +2782,9 @@ DetectAndConfigIdeDevice (
/** /**
Initialize ATA host controller at IDE mode. Initialize ATA host controller at IDE mode.
The function is designed to initialize ATA host controller. The function is designed to initialize ATA host controller.
@param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance. @param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
**/ **/