mirror of https://github.com/acidanthera/audk.git
1. fix AtaPassThru.PassThru() sct failure
2. avoid reenumerate existing device to reduce boot time at AtaBus. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11232 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
f877f3006e
commit
e519983a6c
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
The file for AHCI mode of ATA host controller.
|
The file for AHCI mode of ATA host controller.
|
||||||
|
|
||||||
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -256,6 +256,42 @@ AhciClearPortStatus (
|
||||||
AhciWriteReg (PciIo, EFI_AHCI_IS_OFFSET, AhciReadReg (PciIo, EFI_AHCI_IS_OFFSET));
|
AhciWriteReg (PciIo, EFI_AHCI_IS_OFFSET, AhciReadReg (PciIo, EFI_AHCI_IS_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function is used to dump the Status Registers and if there is ERR bit set
|
||||||
|
in the Status Register, the Error Register's value is also be dumped.
|
||||||
|
|
||||||
|
@param PciIo The PCI IO protocol instance.
|
||||||
|
@param Port The number of port.
|
||||||
|
@param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
AhciDumpPortStatus (
|
||||||
|
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
||||||
|
IN UINT8 Port,
|
||||||
|
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 Offset;
|
||||||
|
UINT32 Data;
|
||||||
|
|
||||||
|
ASSERT (PciIo != NULL);
|
||||||
|
|
||||||
|
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;
|
||||||
|
Data = AhciReadReg (PciIo, Offset);
|
||||||
|
|
||||||
|
if (AtaStatusBlock != NULL) {
|
||||||
|
ZeroMem (AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
|
||||||
|
|
||||||
|
AtaStatusBlock->AtaStatus = (UINT8)Data;
|
||||||
|
if ((AtaStatusBlock->AtaStatus & BIT0) != 0) {
|
||||||
|
AtaStatusBlock->AtaError = (UINT8)(Data >> 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Enable the FIS running for giving port.
|
Enable the FIS running for giving port.
|
||||||
|
|
||||||
|
@ -621,7 +657,7 @@ AhciPioTransfer (
|
||||||
//
|
//
|
||||||
Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);
|
Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);
|
||||||
do {
|
do {
|
||||||
Value = *(UINT32 *) (FisBaseAddr + EFI_AHCI_PIO_FIS_OFFSET);
|
Value = *(volatile UINT32 *) (FisBaseAddr + EFI_AHCI_PIO_FIS_OFFSET);
|
||||||
|
|
||||||
if ((Value & EFI_AHCI_FIS_TYPE_MASK) == EFI_AHCI_FIS_PIO_SETUP) {
|
if ((Value & EFI_AHCI_FIS_TYPE_MASK) == EFI_AHCI_FIS_PIO_SETUP) {
|
||||||
break;
|
break;
|
||||||
|
@ -686,6 +722,8 @@ Exit:
|
||||||
Map
|
Map
|
||||||
);
|
);
|
||||||
|
|
||||||
|
AhciDumpPortStatus (PciIo, Port, AtaStatusBlock);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -855,6 +893,8 @@ Exit:
|
||||||
Map
|
Map
|
||||||
);
|
);
|
||||||
|
|
||||||
|
AhciDumpPortStatus (PciIo, Port, AtaStatusBlock);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -942,7 +982,7 @@ AhciNonDataTransfer (
|
||||||
//
|
//
|
||||||
Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);
|
Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);
|
||||||
do {
|
do {
|
||||||
Value = *(UINT32 *) (FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET);
|
Value = *(volatile UINT32 *) (FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET);
|
||||||
|
|
||||||
if ((Value & EFI_AHCI_FIS_TYPE_MASK) == EFI_AHCI_FIS_REGISTER_D2H) {
|
if ((Value & EFI_AHCI_FIS_TYPE_MASK) == EFI_AHCI_FIS_REGISTER_D2H) {
|
||||||
break;
|
break;
|
||||||
|
@ -984,6 +1024,8 @@ Exit:
|
||||||
Timeout
|
Timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
|
AhciDumpPortStatus (PciIo, Port, AtaStatusBlock);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1082,17 +1124,6 @@ AhciStartCommand (
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Setting the command
|
|
||||||
//
|
|
||||||
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SACT;
|
|
||||||
AhciAndReg (PciIo, Offset, 0);
|
|
||||||
AhciOrReg (PciIo, Offset, CmdSlotBit);
|
|
||||||
|
|
||||||
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CI;
|
|
||||||
AhciAndReg (PciIo, Offset, 0);
|
|
||||||
AhciOrReg (PciIo, Offset, CmdSlotBit);
|
|
||||||
|
|
||||||
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;
|
||||||
PortStatus = AhciReadReg (PciIo, Offset);
|
PortStatus = AhciReadReg (PciIo, Offset);
|
||||||
|
|
||||||
|
@ -1124,6 +1155,17 @@ AhciStartCommand (
|
||||||
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_ST | StartCmd);
|
AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_ST | StartCmd);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Setting the command
|
||||||
|
//
|
||||||
|
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SACT;
|
||||||
|
AhciAndReg (PciIo, Offset, 0);
|
||||||
|
AhciOrReg (PciIo, Offset, CmdSlotBit);
|
||||||
|
|
||||||
|
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CI;
|
||||||
|
AhciAndReg (PciIo, Offset, 0);
|
||||||
|
AhciOrReg (PciIo, Offset, CmdSlotBit);
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
This file implements protocol interfaces: Driver Binding protocol,
|
This file implements protocol interfaces: Driver Binding protocol,
|
||||||
Block IO protocol and DiskInfo protocol.
|
Block IO protocol and DiskInfo protocol.
|
||||||
|
|
||||||
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -173,15 +173,43 @@ RegisterAtaDevice (
|
||||||
ATA_DEVICE *AtaDevice;
|
ATA_DEVICE *AtaDevice;
|
||||||
EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;
|
EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *NewDevicePathNode;
|
EFI_DEVICE_PATH_PROTOCOL *NewDevicePathNode;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
|
||||||
|
EFI_HANDLE DeviceHandle;
|
||||||
|
|
||||||
|
AtaDevice = NULL;
|
||||||
NewDevicePathNode = NULL;
|
NewDevicePathNode = NULL;
|
||||||
|
DevicePath = NULL;
|
||||||
|
RemainingDevicePath = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Build device path
|
||||||
|
//
|
||||||
|
AtaPassThru = AtaBusDriverData->AtaPassThru;
|
||||||
|
Status = AtaPassThru->BuildDevicePath (AtaPassThru, Port, PortMultiplierPort, &NewDevicePathNode);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
DevicePath = AppendDevicePathNode (AtaBusDriverData->ParentDevicePath, NewDevicePathNode);
|
||||||
|
if (DevicePath == NULL) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceHandle = NULL;
|
||||||
|
Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle);
|
||||||
|
if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(RemainingDevicePath)) {
|
||||||
|
Status = EFI_ALREADY_STARTED;
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate ATA device from the template.
|
// Allocate ATA device from the template.
|
||||||
//
|
//
|
||||||
AtaDevice = AllocateCopyPool (sizeof (gAtaDeviceTemplate), &gAtaDeviceTemplate);
|
AtaDevice = AllocateCopyPool (sizeof (gAtaDeviceTemplate), &gAtaDeviceTemplate);
|
||||||
if (AtaDevice == NULL) {
|
if (AtaDevice == NULL) {
|
||||||
return EFI_OUT_OF_RESOURCES;
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -189,6 +217,7 @@ RegisterAtaDevice (
|
||||||
//
|
//
|
||||||
AtaDevice->BlockIo.Media = &AtaDevice->BlockMedia;
|
AtaDevice->BlockIo.Media = &AtaDevice->BlockMedia;
|
||||||
AtaDevice->AtaBusDriverData = AtaBusDriverData;
|
AtaDevice->AtaBusDriverData = AtaBusDriverData;
|
||||||
|
AtaDevice->DevicePath = DevicePath;
|
||||||
AtaDevice->Port = Port;
|
AtaDevice->Port = Port;
|
||||||
AtaDevice->PortMultiplierPort = PortMultiplierPort;
|
AtaDevice->PortMultiplierPort = PortMultiplierPort;
|
||||||
AtaDevice->Asb = AllocateAlignedBuffer (AtaDevice, sizeof (*AtaDevice->Asb));
|
AtaDevice->Asb = AllocateAlignedBuffer (AtaDevice, sizeof (*AtaDevice->Asb));
|
||||||
|
@ -235,15 +264,6 @@ RegisterAtaDevice (
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Build device path
|
|
||||||
//
|
|
||||||
AtaPassThru = AtaBusDriverData->AtaPassThru;
|
|
||||||
Status = AtaPassThru->BuildDevicePath (AtaPassThru, Port, PortMultiplierPort, &NewDevicePathNode);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Update to AHCI interface GUID based on device path node. The default one
|
// Update to AHCI interface GUID based on device path node. The default one
|
||||||
// is IDE interface GUID copied from template.
|
// is IDE interface GUID copied from template.
|
||||||
|
@ -252,11 +272,6 @@ RegisterAtaDevice (
|
||||||
CopyGuid (&AtaDevice->DiskInfo.Interface, &gEfiDiskInfoAhciInterfaceGuid);
|
CopyGuid (&AtaDevice->DiskInfo.Interface, &gEfiDiskInfoAhciInterfaceGuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
AtaDevice->DevicePath = AppendDevicePathNode (AtaBusDriverData->ParentDevicePath, NewDevicePathNode);
|
|
||||||
if (AtaDevice->DevicePath == NULL) {
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
&AtaDevice->Handle,
|
&AtaDevice->Handle,
|
||||||
&gEfiDevicePathProtocolGuid,
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
@ -279,13 +294,13 @@ RegisterAtaDevice (
|
||||||
AtaDevice->Handle,
|
AtaDevice->Handle,
|
||||||
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
||||||
);
|
);
|
||||||
|
|
||||||
Done:
|
Done:
|
||||||
if (NewDevicePathNode != NULL) {
|
if (NewDevicePathNode != NULL) {
|
||||||
FreePool (NewDevicePathNode);
|
FreePool (NewDevicePathNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status) && (AtaDevice != NULL)) {
|
||||||
ReleaseAtaResources (AtaDevice);
|
ReleaseAtaResources (AtaDevice);
|
||||||
DEBUG ((DEBUG_ERROR | DEBUG_INIT, "Failed to initialize Port %x PortMultiplierPort %x, status = %r\n", Port, PortMultiplierPort, Status));
|
DEBUG ((DEBUG_ERROR | DEBUG_INIT, "Failed to initialize Port %x PortMultiplierPort %x, status = %r\n", Port, PortMultiplierPort, Status));
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
This file defines common data structures, macro definitions and some module
|
This file defines common data structures, macro definitions and some module
|
||||||
internal function header files.
|
internal function header files.
|
||||||
|
|
||||||
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
//
|
//
|
||||||
// Time out value for ATA pass through protocol
|
// Time out value for ATA pass through protocol
|
||||||
//
|
//
|
||||||
#define ATA_TIMEOUT EFI_TIMER_PERIOD_SECONDS (1)
|
#define ATA_TIMEOUT EFI_TIMER_PERIOD_SECONDS (3)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Maximum number of times to retry ATA command
|
// Maximum number of times to retry ATA command
|
||||||
|
|
Loading…
Reference in New Issue