mirror of https://github.com/acidanthera/audk.git
Add BlockIO2 Protocol.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11606 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
c89ea31f52
commit
490b5ea10b
|
@ -184,9 +184,50 @@ AhciWaitMemSet (
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check the memory status to the test value.
|
||||||
|
|
||||||
|
@param[in] PciIo The PCI IO protocol instance.
|
||||||
|
@param[in] Offset The memory address to test.
|
||||||
|
@param[in] MaskValue The mask value of memory.
|
||||||
|
@param[in] TestValue The test value of memory.
|
||||||
|
@param[in, out] RetryTimes The retry times value for waitting memory set.
|
||||||
|
|
||||||
|
@retval EFI_NOTREADY The memory is not set.
|
||||||
|
@retval EFI_TIMEOUT The memory setting retry times out.
|
||||||
|
@retval EFI_SUCCESS The memory is correct set.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AhciCheckMemSet (
|
||||||
|
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
||||||
|
IN UINT32 Offset,
|
||||||
|
IN UINT32 MaskValue,
|
||||||
|
IN UINT32 TestValue,
|
||||||
|
IN UINTN *RetryTimes
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 Value;
|
||||||
|
|
||||||
|
(*RetryTimes) --;
|
||||||
|
|
||||||
|
Value = AhciReadReg (PciIo, Offset) & MaskValue;
|
||||||
|
|
||||||
|
if (Value == TestValue) {
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*RetryTimes) == 0) {
|
||||||
|
return EFI_TIMEOUT;
|
||||||
|
} else {
|
||||||
|
return EFI_NOT_READY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
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 transfered.
|
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.
|
||||||
|
@ -206,7 +247,7 @@ AhciCheckDeviceStatus (
|
||||||
IN UINT8 Port
|
IN UINT8 Port
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT32 Data;
|
UINT32 Data;
|
||||||
UINT32 Offset;
|
UINT32 Offset;
|
||||||
|
|
||||||
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SSTS;
|
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SSTS;
|
||||||
|
@ -214,7 +255,7 @@ AhciCheckDeviceStatus (
|
||||||
Data = AhciReadReg (PciIo, Offset) & EFI_AHCI_PORT_SSTS_DET_MASK;
|
Data = AhciReadReg (PciIo, Offset) & EFI_AHCI_PORT_SSTS_DET_MASK;
|
||||||
|
|
||||||
if (Data == EFI_AHCI_PORT_SSTS_DET_PCE) {
|
if (Data == EFI_AHCI_PORT_SSTS_DET_PCE) {
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EFI_NOT_READY;
|
return EFI_NOT_READY;
|
||||||
|
@ -240,7 +281,7 @@ AhciClearPortStatus (
|
||||||
|
|
||||||
//
|
//
|
||||||
// Clear any error status
|
// Clear any error status
|
||||||
//
|
//
|
||||||
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SERR;
|
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SERR;
|
||||||
AhciWriteReg (PciIo, Offset, AhciReadReg (PciIo, Offset));
|
AhciWriteReg (PciIo, Offset, AhciReadReg (PciIo, Offset));
|
||||||
|
|
||||||
|
@ -310,8 +351,8 @@ AhciEnableFisReceive (
|
||||||
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;
|
||||||
|
|
||||||
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;
|
||||||
|
@ -370,12 +411,12 @@ AhciDisableFisReceive (
|
||||||
AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_FRE));
|
AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_FRE));
|
||||||
|
|
||||||
return AhciWaitMemSet (
|
return AhciWaitMemSet (
|
||||||
PciIo,
|
PciIo,
|
||||||
Offset,
|
Offset,
|
||||||
EFI_AHCI_PORT_CMD_FR,
|
EFI_AHCI_PORT_CMD_FR,
|
||||||
0,
|
0,
|
||||||
Timeout
|
Timeout
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -412,7 +453,7 @@ AhciBuildCommand (
|
||||||
IN UINT64 DataLength
|
IN UINT64 DataLength
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT64 BaseAddr;
|
UINT64 BaseAddr;
|
||||||
UINT64 PrdtNumber;
|
UINT64 PrdtNumber;
|
||||||
UINT64 PrdtIndex;
|
UINT64 PrdtIndex;
|
||||||
UINTN RemainedData;
|
UINTN RemainedData;
|
||||||
|
@ -436,7 +477,7 @@ AhciBuildCommand (
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
|
@ -466,7 +507,7 @@ AhciBuildCommand (
|
||||||
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;
|
||||||
} else {
|
} else {
|
||||||
AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = EFI_AHCI_MAX_DATA_PER_PRDT - 1;
|
AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = EFI_AHCI_MAX_DATA_PER_PRDT - 1;
|
||||||
|
@ -475,7 +516,7 @@ AhciBuildCommand (
|
||||||
Data64.Uint64 = (UINT64)MemAddr;
|
Data64.Uint64 = (UINT64)MemAddr;
|
||||||
AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDba = Data64.Uint32.Lower32;
|
AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDba = Data64.Uint32.Lower32;
|
||||||
AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbau = Data64.Uint32.Upper32;
|
AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbau = Data64.Uint32.Upper32;
|
||||||
RemainedData -= EFI_AHCI_MAX_DATA_PER_PRDT;
|
RemainedData -= EFI_AHCI_MAX_DATA_PER_PRDT;
|
||||||
MemAddr += EFI_AHCI_MAX_DATA_PER_PRDT;
|
MemAddr += EFI_AHCI_MAX_DATA_PER_PRDT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,18 +584,21 @@ AhciBuildCommandFis (
|
||||||
/**
|
/**
|
||||||
Start a PIO data transfer on specific port.
|
Start a PIO data transfer on specific port.
|
||||||
|
|
||||||
@param PciIo The PCI IO protocol instance.
|
@param[in] PciIo The PCI IO protocol instance.
|
||||||
@param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
|
@param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
|
||||||
@param Port The number of port.
|
@param[in] Port The number of port.
|
||||||
@param PortMultiplier The timeout value of stop.
|
@param[in] PortMultiplier The timeout value of stop.
|
||||||
@param AtapiCommand The atapi command will be used for the transfer.
|
@param[in] AtapiCommand The atapi command will be used for the
|
||||||
@param AtapiCommandLength The length of the atapi command.
|
transfer.
|
||||||
@param Read The transfer direction.
|
@param[in] AtapiCommandLength The length of the atapi command.
|
||||||
@param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
|
@param[in] Read The transfer direction.
|
||||||
@param AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
|
@param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
|
||||||
@param MemoryAddr The pointer to the data buffer.
|
@param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
|
||||||
@param DataCount The data count to be transferred.
|
@param[in, out] MemoryAddr The pointer to the data buffer.
|
||||||
@param Timeout The timeout value of non data transfer.
|
@param[in] DataCount The data count to be transferred.
|
||||||
|
@param[in] Timeout The timeout value of non data transfer.
|
||||||
|
@param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
|
||||||
|
used by non-blocking mode.
|
||||||
|
|
||||||
@retval EFI_DEVICE_ERROR The PIO data transfer abort with error occurs.
|
@retval EFI_DEVICE_ERROR The PIO data transfer abort with error occurs.
|
||||||
@retval EFI_TIMEOUT The operation is time out.
|
@retval EFI_TIMEOUT The operation is time out.
|
||||||
|
@ -576,7 +620,8 @@ AhciPioTransfer (
|
||||||
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
|
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
|
||||||
IN OUT VOID *MemoryAddr,
|
IN OUT VOID *MemoryAddr,
|
||||||
IN UINT32 DataCount,
|
IN UINT32 DataCount,
|
||||||
IN UINT64 Timeout
|
IN UINT64 Timeout,
|
||||||
|
IN ATA_NONBLOCK_TASK *Task
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
@ -639,17 +684,17 @@ AhciPioTransfer (
|
||||||
);
|
);
|
||||||
|
|
||||||
Status = AhciStartCommand (
|
Status = AhciStartCommand (
|
||||||
PciIo,
|
PciIo,
|
||||||
Port,
|
Port,
|
||||||
0,
|
0,
|
||||||
Timeout
|
Timeout
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Checking the status and wait the driver sending data
|
// Check the status and wait the driver sending data
|
||||||
//
|
//
|
||||||
FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS);
|
FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS);
|
||||||
//
|
//
|
||||||
|
@ -668,7 +713,7 @@ AhciPioTransfer (
|
||||||
//
|
//
|
||||||
MicroSecondDelay(100);
|
MicroSecondDelay(100);
|
||||||
|
|
||||||
Delay--;
|
Delay--;
|
||||||
} while (Delay > 0);
|
} while (Delay > 0);
|
||||||
|
|
||||||
if (Delay == 0) {
|
if (Delay == 0) {
|
||||||
|
@ -689,30 +734,30 @@ AhciPioTransfer (
|
||||||
);
|
);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;
|
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;
|
||||||
Status = AhciWaitMemSet (
|
Status = AhciWaitMemSet (
|
||||||
PciIo,
|
PciIo,
|
||||||
Offset,
|
Offset,
|
||||||
EFI_AHCI_PORT_IS_PSS,
|
EFI_AHCI_PORT_IS_PSS,
|
||||||
EFI_AHCI_PORT_IS_PSS,
|
EFI_AHCI_PORT_IS_PSS,
|
||||||
Timeout
|
Timeout
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
AhciStopCommand (
|
AhciStopCommand (
|
||||||
PciIo,
|
PciIo,
|
||||||
Port,
|
Port,
|
||||||
Timeout
|
Timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
AhciDisableFisReceive (
|
AhciDisableFisReceive (
|
||||||
PciIo,
|
PciIo,
|
||||||
Port,
|
Port,
|
||||||
Timeout
|
Timeout
|
||||||
);
|
);
|
||||||
|
@ -730,29 +775,32 @@ Exit:
|
||||||
/**
|
/**
|
||||||
Start a DMA data transfer on specific port
|
Start a DMA data transfer on specific port
|
||||||
|
|
||||||
@param PciIo The PCI IO protocol instance.
|
@param[in] Instance The ATA_ATAPI_PASS_THRU_INSTANCE protocol instance.
|
||||||
@param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
|
@param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
|
||||||
@param Port The number of port.
|
@param[in] Port The number of port.
|
||||||
@param PortMultiplier The timeout value of stop.
|
@param[in] PortMultiplier The timeout value of stop.
|
||||||
@param AtapiCommand The atapi command will be used for the transfer.
|
@param[in] AtapiCommand The atapi command will be used for the
|
||||||
@param AtapiCommandLength The length of the atapi command.
|
transfer.
|
||||||
@param Read The transfer direction.
|
@param[in] AtapiCommandLength The length of the atapi command.
|
||||||
@param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
|
@param[in] Read The transfer direction.
|
||||||
@param AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
|
@param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
|
||||||
@param MemoryAddr The pointer to the data buffer.
|
@param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
|
||||||
@param DataCount The data count to be transferred.
|
@param[in, out] MemoryAddr The pointer to the data buffer.
|
||||||
@param Timeout The timeout value of non data transfer.
|
@param[in] DataCount The data count to be transferred.
|
||||||
|
@param[in] Timeout The timeout value of non data transfer.
|
||||||
|
@param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
|
||||||
|
used by non-blocking mode.
|
||||||
|
|
||||||
@retval EFI_DEVICE_ERROR The DMA data transfer abort with error occurs.
|
@retval EFI_DEVICE_ERROR The DMA data transfer abort with error occurs.
|
||||||
@retval EFI_TIMEOUT The operation is time out.
|
@retval EFI_TIMEOUT The operation is time out.
|
||||||
@retval EFI_UNSUPPORTED The device is not ready for transfer.
|
@retval EFI_UNSUPPORTED The device is not ready for transfer.
|
||||||
@retval EFI_SUCCESS The DMA data transfer executes successfully.
|
@retval EFI_SUCCESS The DMA data transfer executes successfully.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
AhciDmaTransfer (
|
AhciDmaTransfer (
|
||||||
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
|
||||||
IN EFI_AHCI_REGISTERS *AhciRegisters,
|
IN EFI_AHCI_REGISTERS *AhciRegisters,
|
||||||
IN UINT8 Port,
|
IN UINT8 Port,
|
||||||
IN UINT8 PortMultiplier,
|
IN UINT8 PortMultiplier,
|
||||||
|
@ -763,7 +811,8 @@ AhciDmaTransfer (
|
||||||
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
|
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
|
||||||
IN OUT VOID *MemoryAddr,
|
IN OUT VOID *MemoryAddr,
|
||||||
IN UINTN DataCount,
|
IN UINTN DataCount,
|
||||||
IN UINT64 Timeout
|
IN UINT64 Timeout,
|
||||||
|
IN ATA_NONBLOCK_TASK *Task
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
@ -775,141 +824,224 @@ AhciDmaTransfer (
|
||||||
EFI_AHCI_COMMAND_FIS CFis;
|
EFI_AHCI_COMMAND_FIS CFis;
|
||||||
EFI_AHCI_COMMAND_LIST CmdList;
|
EFI_AHCI_COMMAND_LIST CmdList;
|
||||||
|
|
||||||
if (Read) {
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||||
Flag = EfiPciIoOperationBusMasterWrite;
|
EFI_TPL OldTpl;
|
||||||
} else {
|
|
||||||
Flag = EfiPciIoOperationBusMasterRead;
|
Map = NULL;
|
||||||
|
PciIo = Instance->PciIo;
|
||||||
|
|
||||||
|
if (PciIo == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// construct command list and command table with pci bus address
|
// Before starting the Blocking BlockIO operation, push to finish all non-blocking
|
||||||
|
// BlockIO tasks.
|
||||||
|
// Delay 100us to simulate the blocking time out checking.
|
||||||
//
|
//
|
||||||
MapLength = DataCount;
|
while ((Task == NULL) && (!IsListEmpty (&Instance->NonBlockingTaskList))) {
|
||||||
Status = PciIo->Map (
|
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||||
PciIo,
|
AsyncNonBlockingTransferRoutine (NULL, Instance);
|
||||||
Flag,
|
gBS->RestoreTPL (OldTpl);
|
||||||
MemoryAddr,
|
//
|
||||||
&MapLength,
|
// Stall for 100us.
|
||||||
&PhyAddr,
|
//
|
||||||
&Map
|
MicroSecondDelay (100);
|
||||||
);
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status) || (DataCount != MapLength)) {
|
|
||||||
return EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
if ((Task == NULL) || ((Task != NULL) && (!Task->IsStart))) {
|
||||||
// Package read needed
|
//
|
||||||
//
|
// Mark the Task to indicate that it has been started.
|
||||||
AhciBuildCommandFis (&CFis, AtaCommandBlock);
|
//
|
||||||
|
if (Task != NULL) {
|
||||||
|
Task->IsStart = TRUE;
|
||||||
|
Task->RetryTimes = (UINT32) (DivU64x32(Timeout, 1000) + 1);
|
||||||
|
}
|
||||||
|
if (Read) {
|
||||||
|
Flag = EfiPciIoOperationBusMasterWrite;
|
||||||
|
} else {
|
||||||
|
Flag = EfiPciIoOperationBusMasterRead;
|
||||||
|
}
|
||||||
|
|
||||||
ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
|
//
|
||||||
|
// Construct command list and command table with pci bus address.
|
||||||
|
//
|
||||||
|
MapLength = DataCount;
|
||||||
|
Status = PciIo->Map (
|
||||||
|
PciIo,
|
||||||
|
Flag,
|
||||||
|
MemoryAddr,
|
||||||
|
&MapLength,
|
||||||
|
&PhyAddr,
|
||||||
|
&Map
|
||||||
|
);
|
||||||
|
|
||||||
CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;
|
if (EFI_ERROR (Status) || (DataCount != MapLength)) {
|
||||||
CmdList.AhciCmdW = Read ? 0 : 1;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
AhciBuildCommand (
|
if (Task != NULL) {
|
||||||
PciIo,
|
Task->Map = Map;
|
||||||
AhciRegisters,
|
}
|
||||||
Port,
|
//
|
||||||
PortMultiplier,
|
// Package read needed
|
||||||
&CFis,
|
//
|
||||||
&CmdList,
|
AhciBuildCommandFis (&CFis, AtaCommandBlock);
|
||||||
AtapiCommand,
|
|
||||||
AtapiCommandLength,
|
ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
|
||||||
0,
|
|
||||||
(VOID *)(UINTN)PhyAddr,
|
CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;
|
||||||
DataCount
|
CmdList.AhciCmdW = Read ? 0 : 1;
|
||||||
);
|
|
||||||
|
AhciBuildCommand (
|
||||||
Status = AhciStartCommand (
|
PciIo,
|
||||||
PciIo,
|
AhciRegisters,
|
||||||
Port,
|
Port,
|
||||||
0,
|
PortMultiplier,
|
||||||
Timeout
|
&CFis,
|
||||||
);
|
&CmdList,
|
||||||
if (EFI_ERROR (Status)) {
|
AtapiCommand,
|
||||||
goto Exit;
|
AtapiCommandLength,
|
||||||
}
|
0,
|
||||||
|
(VOID *)(UINTN)PhyAddr,
|
||||||
//
|
DataCount
|
||||||
// Wait device PRD processed
|
);
|
||||||
//
|
|
||||||
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;
|
Status = AhciStartCommand (
|
||||||
Status = AhciWaitMemSet (
|
PciIo,
|
||||||
PciIo,
|
Port,
|
||||||
Offset,
|
0,
|
||||||
EFI_AHCI_PORT_IS_DPS,
|
Timeout
|
||||||
EFI_AHCI_PORT_IS_DPS,
|
);
|
||||||
Timeout
|
if (EFI_ERROR (Status)) {
|
||||||
);
|
goto Exit;
|
||||||
|
}
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto Exit;
|
//
|
||||||
|
// Wait device PRD processed
|
||||||
|
//
|
||||||
|
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;
|
||||||
|
Status = AhciWaitMemSet (
|
||||||
|
PciIo,
|
||||||
|
Offset,
|
||||||
|
EFI_AHCI_PORT_IS_DPS,
|
||||||
|
EFI_AHCI_PORT_IS_DPS,
|
||||||
|
Timeout
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Wait for command compelte
|
// Wait for command compelte
|
||||||
//
|
//
|
||||||
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CI;
|
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CI;
|
||||||
Status = AhciWaitMemSet (
|
if (Task != NULL) {
|
||||||
PciIo,
|
//
|
||||||
Offset,
|
// For Non-blocking
|
||||||
0xFFFFFFFF,
|
//
|
||||||
0,
|
Status = AhciCheckMemSet (
|
||||||
Timeout
|
PciIo,
|
||||||
);
|
Offset,
|
||||||
|
0xFFFFFFFF,
|
||||||
|
0,
|
||||||
|
(UINTN *) (&Task->RetryTimes)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Status = AhciWaitMemSet (
|
||||||
|
PciIo,
|
||||||
|
Offset,
|
||||||
|
0xFFFFFFFF,
|
||||||
|
0,
|
||||||
|
Timeout
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;
|
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;
|
||||||
Status = AhciWaitMemSet (
|
|
||||||
PciIo,
|
if (Task != NULL) {
|
||||||
Offset,
|
//
|
||||||
EFI_AHCI_PORT_IS_DHRS,
|
// For Non-blocking
|
||||||
EFI_AHCI_PORT_IS_DHRS,
|
//
|
||||||
Timeout
|
Status = AhciCheckMemSet (
|
||||||
);
|
PciIo,
|
||||||
|
Offset,
|
||||||
|
EFI_AHCI_PORT_IS_DHRS,
|
||||||
|
EFI_AHCI_PORT_IS_DHRS,
|
||||||
|
(UINTN *) (&Task->RetryTimes)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Status = AhciWaitMemSet (
|
||||||
|
PciIo,
|
||||||
|
Offset,
|
||||||
|
EFI_AHCI_PORT_IS_DHRS,
|
||||||
|
EFI_AHCI_PORT_IS_DHRS,
|
||||||
|
Timeout
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
AhciStopCommand (
|
//
|
||||||
PciIo,
|
// For Blocking mode, the command should be stopped, the Fis should be disabled
|
||||||
Port,
|
// and the PciIo should be unmapped.
|
||||||
Timeout
|
// 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
|
||||||
|
// context cleanup, then set the packet's Asb status.
|
||||||
|
//
|
||||||
|
if (Task == NULL ||
|
||||||
|
((Task != NULL) && (Status != EFI_NOT_READY))
|
||||||
|
) {
|
||||||
|
AhciStopCommand (
|
||||||
|
PciIo,
|
||||||
|
Port,
|
||||||
|
Timeout
|
||||||
|
);
|
||||||
|
|
||||||
AhciDisableFisReceive (
|
AhciDisableFisReceive (
|
||||||
PciIo,
|
PciIo,
|
||||||
Port,
|
Port,
|
||||||
Timeout
|
Timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
|
PciIo->Unmap (
|
||||||
|
PciIo,
|
||||||
|
(Task != NULL) ? Task->Map : Map
|
||||||
|
);
|
||||||
|
|
||||||
|
if (Task != NULL) {
|
||||||
|
Task->Packet->Asb->AtaStatus = 0x01;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PciIo->Unmap (
|
|
||||||
PciIo,
|
|
||||||
Map
|
|
||||||
);
|
|
||||||
|
|
||||||
AhciDumpPortStatus (PciIo, Port, AtaStatusBlock);
|
AhciDumpPortStatus (PciIo, Port, AtaStatusBlock);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Start a non data transfer on specific port.
|
Start a non data transfer on specific port.
|
||||||
|
|
||||||
@param PciIo The PCI IO protocol instance.
|
@param[in] PciIo The PCI IO protocol instance.
|
||||||
@param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
|
@param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
|
||||||
@param Port The number of port.
|
@param[in] Port The number of port.
|
||||||
@param PortMultiplier The timeout value of stop.
|
@param[in] PortMultiplier The timeout value of stop.
|
||||||
@param AtapiCommand The atapi command will be used for the transfer.
|
@param[in] AtapiCommand The atapi command will be used for the
|
||||||
@param AtapiCommandLength The length of the atapi command.
|
transfer.
|
||||||
@param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
|
@param[in] AtapiCommandLength The length of the atapi command.
|
||||||
@param AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
|
@param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
|
||||||
@param Timeout The timeout value of non data transfer.
|
@param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
|
||||||
|
@param[in] Timeout The timeout value of non data transfer.
|
||||||
|
@param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
|
||||||
|
used by non-blocking mode.
|
||||||
|
|
||||||
@retval EFI_DEVICE_ERROR The non data transfer abort with error occurs.
|
@retval EFI_DEVICE_ERROR The non data transfer abort with error occurs.
|
||||||
@retval EFI_TIMEOUT The operation is time out.
|
@retval EFI_TIMEOUT The operation is time out.
|
||||||
|
@ -928,15 +1060,16 @@ AhciNonDataTransfer (
|
||||||
IN UINT8 AtapiCommandLength,
|
IN UINT8 AtapiCommandLength,
|
||||||
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 UINT64 Timeout
|
IN UINT64 Timeout,
|
||||||
)
|
IN ATA_NONBLOCK_TASK *Task
|
||||||
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINTN FisBaseAddr;
|
UINTN FisBaseAddr;
|
||||||
UINT32 Offset;
|
UINT32 Offset;
|
||||||
UINT32 Value;
|
UINT32 Value;
|
||||||
UINT32 Delay;
|
UINT32 Delay;
|
||||||
|
|
||||||
EFI_AHCI_COMMAND_FIS CFis;
|
EFI_AHCI_COMMAND_FIS CFis;
|
||||||
EFI_AHCI_COMMAND_LIST CmdList;
|
EFI_AHCI_COMMAND_LIST CmdList;
|
||||||
|
|
||||||
|
@ -961,18 +1094,18 @@ AhciNonDataTransfer (
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
Status = AhciStartCommand (
|
Status = AhciStartCommand (
|
||||||
PciIo,
|
PciIo,
|
||||||
Port,
|
Port,
|
||||||
0,
|
0,
|
||||||
Timeout
|
Timeout
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Wait device sends the Response Fis
|
// Wait device sends the Response Fis
|
||||||
//
|
//
|
||||||
|
@ -993,7 +1126,7 @@ AhciNonDataTransfer (
|
||||||
//
|
//
|
||||||
MicroSecondDelay(100);
|
MicroSecondDelay(100);
|
||||||
|
|
||||||
Delay --;
|
Delay --;
|
||||||
} while (Delay > 0);
|
} while (Delay > 0);
|
||||||
|
|
||||||
if (Delay == 0) {
|
if (Delay == 0) {
|
||||||
|
@ -1009,17 +1142,17 @@ AhciNonDataTransfer (
|
||||||
0xFFFFFFFF,
|
0xFFFFFFFF,
|
||||||
0,
|
0,
|
||||||
Timeout
|
Timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
AhciStopCommand (
|
AhciStopCommand (
|
||||||
PciIo,
|
PciIo,
|
||||||
Port,
|
Port,
|
||||||
Timeout
|
Timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
AhciDisableFisReceive (
|
AhciDisableFisReceive (
|
||||||
PciIo,
|
PciIo,
|
||||||
Port,
|
Port,
|
||||||
Timeout
|
Timeout
|
||||||
);
|
);
|
||||||
|
@ -1056,7 +1189,7 @@ AhciStopCommand (
|
||||||
Data = AhciReadReg (PciIo, Offset);
|
Data = AhciReadReg (PciIo, Offset);
|
||||||
|
|
||||||
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_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Data & EFI_AHCI_PORT_CMD_ST) != 0) {
|
if ((Data & EFI_AHCI_PORT_CMD_ST) != 0) {
|
||||||
|
@ -1064,22 +1197,22 @@ AhciStopCommand (
|
||||||
}
|
}
|
||||||
|
|
||||||
return AhciWaitMemSet (
|
return AhciWaitMemSet (
|
||||||
PciIo,
|
PciIo,
|
||||||
Offset,
|
Offset,
|
||||||
EFI_AHCI_PORT_CMD_CR,
|
EFI_AHCI_PORT_CMD_CR,
|
||||||
0,
|
0,
|
||||||
Timeout
|
Timeout
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Start command for give slot on specific port.
|
Start command for give slot on specific 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 CommandSlot The number of CommandSlot.
|
@param CommandSlot The number of Command Slot.
|
||||||
@param Timeout The timeout value of start.
|
@param Timeout The timeout value of start.
|
||||||
|
|
||||||
@retval EFI_DEVICE_ERROR The command start unsuccessfully.
|
@retval EFI_DEVICE_ERROR The command start unsuccessfully.
|
||||||
@retval EFI_TIMEOUT The operation is time out.
|
@retval EFI_TIMEOUT The operation is time out.
|
||||||
@retval EFI_SUCCESS The command start successfully.
|
@retval EFI_SUCCESS The command start successfully.
|
||||||
|
@ -1119,14 +1252,14 @@ AhciStartCommand (
|
||||||
Port,
|
Port,
|
||||||
Timeout
|
Timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
StartCmd = 0;
|
StartCmd = 0;
|
||||||
if ((PortStatus & EFI_AHCI_PORT_CMD_ALPE) != 0) {
|
if ((PortStatus & EFI_AHCI_PORT_CMD_ALPE) != 0) {
|
||||||
StartCmd = AhciReadReg (PciIo, Offset);
|
StartCmd = AhciReadReg (PciIo, Offset);
|
||||||
|
@ -1143,12 +1276,12 @@ AhciStartCommand (
|
||||||
AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_COL);
|
AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_COL);
|
||||||
|
|
||||||
AhciWaitMemSet (
|
AhciWaitMemSet (
|
||||||
PciIo,
|
PciIo,
|
||||||
Offset,
|
Offset,
|
||||||
EFI_AHCI_PORT_CMD_COL,
|
EFI_AHCI_PORT_CMD_COL,
|
||||||
0,
|
0,
|
||||||
Timeout
|
Timeout
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1190,8 +1323,8 @@ AhciPortReset (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT32 Offset;
|
UINT32 Offset;
|
||||||
|
|
||||||
AhciClearPortStatus (PciIo, Port);
|
AhciClearPortStatus (PciIo, Port);
|
||||||
|
|
||||||
AhciStopCommand (PciIo, Port, Timeout);
|
AhciStopCommand (PciIo, Port, Timeout);
|
||||||
|
@ -1205,14 +1338,14 @@ AhciPortReset (
|
||||||
AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_SCTL_DET_INIT);
|
AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_SCTL_DET_INIT);
|
||||||
|
|
||||||
//
|
//
|
||||||
// wait 5 milliseceond before de-assert DET
|
// wait 5 millisecond before de-assert DET
|
||||||
//
|
//
|
||||||
MicroSecondDelay (5000);
|
MicroSecondDelay (5000);
|
||||||
|
|
||||||
AhciAndReg (PciIo, Offset, (UINT32)EFI_AHCI_PORT_SCTL_MASK);
|
AhciAndReg (PciIo, Offset, (UINT32)EFI_AHCI_PORT_SCTL_MASK);
|
||||||
|
|
||||||
//
|
//
|
||||||
// wait 5 milliseceond before de-assert DET
|
// wait 5 millisecond before de-assert DET
|
||||||
//
|
//
|
||||||
MicroSecondDelay (5000);
|
MicroSecondDelay (5000);
|
||||||
|
|
||||||
|
@ -1226,7 +1359,7 @@ AhciPortReset (
|
||||||
EFI_AHCI_PORT_SSTS_DET_MASK,
|
EFI_AHCI_PORT_SSTS_DET_MASK,
|
||||||
EFI_AHCI_PORT_SSTS_DET_PCE,
|
EFI_AHCI_PORT_SSTS_DET_PCE,
|
||||||
Timeout
|
Timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -1240,11 +1373,10 @@ AhciPortReset (
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Do AHCI HBA reset.
|
Do AHCI HBA reset.
|
||||||
|
|
||||||
@param PciIo The PCI IO protocol instance.
|
@param PciIo The PCI IO protocol instance.
|
||||||
@param Timeout The timeout value of reset.
|
@param Timeout The timeout value of reset.
|
||||||
|
|
||||||
|
|
||||||
@retval EFI_DEVICE_ERROR AHCI controller is failed to complete hardware reset.
|
@retval EFI_DEVICE_ERROR AHCI controller is failed to complete hardware reset.
|
||||||
@retval EFI_TIMEOUT The reset operation is time out.
|
@retval EFI_TIMEOUT The reset operation is time out.
|
||||||
@retval EFI_SUCCESS AHCI controller is reset successfully.
|
@retval EFI_SUCCESS AHCI controller is reset successfully.
|
||||||
|
@ -1340,7 +1472,8 @@ AhciAtaSmartReturnStatusCheck (
|
||||||
0,
|
0,
|
||||||
&AtaCommandBlock,
|
&AtaCommandBlock,
|
||||||
AtaStatusBlock,
|
AtaStatusBlock,
|
||||||
ATA_ATAPI_TIMEOUT
|
ATA_ATAPI_TIMEOUT,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
@ -1390,7 +1523,7 @@ AhciAtaSmartSupport (
|
||||||
IN EFI_AHCI_REGISTERS *AhciRegisters,
|
IN EFI_AHCI_REGISTERS *AhciRegisters,
|
||||||
IN UINT8 Port,
|
IN UINT8 Port,
|
||||||
IN UINT8 PortMultiplier,
|
IN UINT8 PortMultiplier,
|
||||||
IN EFI_IDENTIFY_DATA *IdentifyData,
|
IN EFI_IDENTIFY_DATA *IdentifyData,
|
||||||
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
|
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -1430,7 +1563,8 @@ AhciAtaSmartSupport (
|
||||||
0,
|
0,
|
||||||
&AtaCommandBlock,
|
&AtaCommandBlock,
|
||||||
AtaStatusBlock,
|
AtaStatusBlock,
|
||||||
ATA_ATAPI_TIMEOUT
|
ATA_ATAPI_TIMEOUT,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -1455,7 +1589,8 @@ AhciAtaSmartSupport (
|
||||||
0,
|
0,
|
||||||
&AtaCommandBlock,
|
&AtaCommandBlock,
|
||||||
AtaStatusBlock,
|
AtaStatusBlock,
|
||||||
ATA_ATAPI_TIMEOUT
|
ATA_ATAPI_TIMEOUT,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
|
@ -1469,7 +1604,7 @@ AhciAtaSmartSupport (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DEBUG ((EFI_D_INFO, "Enabled S.M.A.R.T feature at port [%d] PortMultiplier [%d]!\n",
|
DEBUG ((EFI_D_INFO, "Enabled S.M.A.R.T feature at port [%d] PortMultiplier [%d]!\n",
|
||||||
Port, PortMultiplier));
|
Port, PortMultiplier));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1511,7 +1646,7 @@ AhciIdentify (
|
||||||
|
|
||||||
ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
|
ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
|
||||||
ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
|
ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
|
||||||
|
|
||||||
AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DRIVE;
|
AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DRIVE;
|
||||||
AtaCommandBlock.AtaSectorCount = 1;
|
AtaCommandBlock.AtaSectorCount = 1;
|
||||||
|
|
||||||
|
@ -1527,7 +1662,8 @@ AhciIdentify (
|
||||||
&AtaStatusBlock,
|
&AtaStatusBlock,
|
||||||
Buffer,
|
Buffer,
|
||||||
sizeof (EFI_IDENTIFY_DATA),
|
sizeof (EFI_IDENTIFY_DATA),
|
||||||
ATA_ATAPI_TIMEOUT
|
ATA_ATAPI_TIMEOUT,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -1565,7 +1701,7 @@ AhciIdentifyPacket (
|
||||||
if (PciIo == NULL || AhciRegisters == NULL) {
|
if (PciIo == NULL || AhciRegisters == NULL) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
|
ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
|
||||||
ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
|
ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
|
||||||
|
|
||||||
|
@ -1584,7 +1720,8 @@ AhciIdentifyPacket (
|
||||||
&AtaStatusBlock,
|
&AtaStatusBlock,
|
||||||
Buffer,
|
Buffer,
|
||||||
sizeof (EFI_IDENTIFY_DATA),
|
sizeof (EFI_IDENTIFY_DATA),
|
||||||
ATA_ATAPI_TIMEOUT
|
ATA_ATAPI_TIMEOUT,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -1623,7 +1760,7 @@ AhciDeviceSetFeature (
|
||||||
|
|
||||||
ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
|
ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
|
||||||
ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
|
ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
|
||||||
|
|
||||||
AtaCommandBlock.AtaCommand = ATA_CMD_SET_FEATURES;
|
AtaCommandBlock.AtaCommand = ATA_CMD_SET_FEATURES;
|
||||||
AtaCommandBlock.AtaFeatures = (UINT8) Feature;
|
AtaCommandBlock.AtaFeatures = (UINT8) Feature;
|
||||||
AtaCommandBlock.AtaFeaturesExp = (UINT8) (Feature >> 8);
|
AtaCommandBlock.AtaFeaturesExp = (UINT8) (Feature >> 8);
|
||||||
|
@ -1641,7 +1778,8 @@ AhciDeviceSetFeature (
|
||||||
0,
|
0,
|
||||||
&AtaCommandBlock,
|
&AtaCommandBlock,
|
||||||
&AtaStatusBlock,
|
&AtaStatusBlock,
|
||||||
ATA_ATAPI_TIMEOUT
|
ATA_ATAPI_TIMEOUT,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -1708,7 +1846,7 @@ AhciPacketCommandExecute (
|
||||||
Read = FALSE;
|
Read = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Length == 0) {
|
if (Length == 0) {
|
||||||
Status = AhciNonDataTransfer (
|
Status = AhciNonDataTransfer (
|
||||||
PciIo,
|
PciIo,
|
||||||
AhciRegisters,
|
AhciRegisters,
|
||||||
|
@ -1718,7 +1856,8 @@ AhciPacketCommandExecute (
|
||||||
Packet->CdbLength,
|
Packet->CdbLength,
|
||||||
&AtaCommandBlock,
|
&AtaCommandBlock,
|
||||||
&AtaStatusBlock,
|
&AtaStatusBlock,
|
||||||
Packet->Timeout
|
Packet->Timeout,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
|
@ -1742,7 +1881,8 @@ AhciPacketCommandExecute (
|
||||||
&AtaStatusBlock,
|
&AtaStatusBlock,
|
||||||
Buffer,
|
Buffer,
|
||||||
Length,
|
Length,
|
||||||
Packet->Timeout
|
Packet->Timeout,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Header file for AHCI mode of ATA host controller.
|
Header 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
|
||||||
|
@ -154,7 +154,7 @@ typedef union {
|
||||||
#define EFI_AHCI_PORT_SERR_BDE BIT19
|
#define EFI_AHCI_PORT_SERR_BDE BIT19
|
||||||
#define EFI_AHCI_PORT_SERR_DE BIT20
|
#define EFI_AHCI_PORT_SERR_DE BIT20
|
||||||
#define EFI_AHCI_PORT_SERR_CRCE BIT21
|
#define EFI_AHCI_PORT_SERR_CRCE BIT21
|
||||||
#define EFI_AHCI_PORT_SERR_HE BIT22
|
#define EFI_AHCI_PORT_SERR_HE BIT22
|
||||||
#define EFI_AHCI_PORT_SERR_LSE BIT23
|
#define EFI_AHCI_PORT_SERR_LSE BIT23
|
||||||
#define EFI_AHCI_PORT_SERR_TSTE BIT24
|
#define EFI_AHCI_PORT_SERR_TSTE BIT24
|
||||||
#define EFI_AHCI_PORT_SERR_UFT BIT25
|
#define EFI_AHCI_PORT_SERR_UFT BIT25
|
||||||
|
@ -348,117 +348,5 @@ AhciStopCommand (
|
||||||
IN UINT64 Timeout
|
IN UINT64 Timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
Start a non data transfer on specific port.
|
|
||||||
|
|
||||||
@param PciIo The PCI IO protocol instance.
|
|
||||||
@param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
|
|
||||||
@param Port The number of port.
|
|
||||||
@param PortMultiplier The timeout value of stop.
|
|
||||||
@param AtapiCommand The atapi command will be used for the transfer.
|
|
||||||
@param AtapiCommandLength The length of the atapi command.
|
|
||||||
@param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
|
|
||||||
@param AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
|
|
||||||
@param Timeout The timeout value of non data transfer.
|
|
||||||
|
|
||||||
@retval EFI_DEVICE_ERROR The non data transfer abort with error occurs.
|
|
||||||
@retval EFI_TIMEOUT The operation is time out.
|
|
||||||
@retval EFI_UNSUPPORTED The device is not ready for transfer.
|
|
||||||
@retval EFI_SUCCESS The non data transfer executes successfully.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
AhciNonDataTransfer (
|
|
||||||
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
|
||||||
IN EFI_AHCI_REGISTERS *AhciRegisters,
|
|
||||||
IN UINT8 Port,
|
|
||||||
IN UINT8 PortMultiplier,
|
|
||||||
IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
|
|
||||||
IN UINT8 AtapiCommandLength,
|
|
||||||
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
|
|
||||||
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
|
|
||||||
IN UINT64 Timeout
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Start a DMA data transfer on specific port
|
|
||||||
|
|
||||||
@param PciIo The PCI IO protocol instance.
|
|
||||||
@param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
|
|
||||||
@param Port The number of port.
|
|
||||||
@param PortMultiplier The timeout value of stop.
|
|
||||||
@param AtapiCommand The atapi command will be used for the transfer.
|
|
||||||
@param AtapiCommandLength The length of the atapi command.
|
|
||||||
@param Read The transfer direction.
|
|
||||||
@param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
|
|
||||||
@param AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
|
|
||||||
@param MemoryAddr The pointer to the data buffer.
|
|
||||||
@param DataCount The data count to be transferred.
|
|
||||||
@param Timeout The timeout value of non data transfer.
|
|
||||||
|
|
||||||
@retval EFI_DEVICE_ERROR The DMA data transfer abort with error occurs.
|
|
||||||
@retval EFI_TIMEOUT The operation is time out.
|
|
||||||
@retval EFI_UNSUPPORTED The device is not ready for transfer.
|
|
||||||
@retval EFI_SUCCESS The DMA data transfer executes successfully.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
AhciDmaTransfer (
|
|
||||||
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
|
||||||
IN EFI_AHCI_REGISTERS *AhciRegisters,
|
|
||||||
IN UINT8 Port,
|
|
||||||
IN UINT8 PortMultiplier,
|
|
||||||
IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
|
|
||||||
IN UINT8 AtapiCommandLength,
|
|
||||||
IN BOOLEAN Read,
|
|
||||||
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
|
|
||||||
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
|
|
||||||
IN OUT VOID *MemoryAddr,
|
|
||||||
IN UINTN DataCount,
|
|
||||||
IN UINT64 Timeout
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Start a PIO data transfer on specific port.
|
|
||||||
|
|
||||||
@param PciIo The PCI IO protocol instance.
|
|
||||||
@param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
|
|
||||||
@param Port The number of port.
|
|
||||||
@param PortMultiplier The timeout value of stop.
|
|
||||||
@param AtapiCommand The atapi command will be used for the transfer.
|
|
||||||
@param AtapiCommandLength The length of the atapi command.
|
|
||||||
@param Read The transfer direction.
|
|
||||||
@param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
|
|
||||||
@param AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
|
|
||||||
@param MemoryAddr The pointer to the data buffer.
|
|
||||||
@param DataCount The data count to be transferred.
|
|
||||||
@param Timeout The timeout value of non data transfer.
|
|
||||||
|
|
||||||
@retval EFI_DEVICE_ERROR The PIO data transfer abort with error occurs.
|
|
||||||
@retval EFI_TIMEOUT The operation is time out.
|
|
||||||
@retval EFI_UNSUPPORTED The device is not ready for transfer.
|
|
||||||
@retval EFI_SUCCESS The PIO data transfer executes successfully.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
AhciPioTransfer (
|
|
||||||
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
|
||||||
IN EFI_AHCI_REGISTERS *AhciRegisters,
|
|
||||||
IN UINT8 Port,
|
|
||||||
IN UINT8 PortMultiplier,
|
|
||||||
IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
|
|
||||||
IN UINT8 AtapiCommandLength,
|
|
||||||
IN BOOLEAN Read,
|
|
||||||
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
|
|
||||||
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
|
|
||||||
IN OUT VOID *MemoryAddr,
|
|
||||||
IN UINT32 DataCount,
|
|
||||||
IN UINT64 Timeout
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ ATA_ATAPI_PASS_THRU_INSTANCE gAtaAtapiPassThruInstanceTemplate = {
|
||||||
// bits.
|
// bits.
|
||||||
// Note that the driver doesn't support AtaPassThru non blocking I/O.
|
// Note that the driver doesn't support AtaPassThru non blocking I/O.
|
||||||
//
|
//
|
||||||
EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL,
|
EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL | EFI_ATA_PASS_THRU_ATTRIBUTES_NONBLOCKIO,
|
||||||
//
|
//
|
||||||
// IoAlign
|
// IoAlign
|
||||||
//
|
//
|
||||||
|
@ -98,7 +98,12 @@ ATA_ATAPI_PASS_THRU_INSTANCE gAtaAtapiPassThruInstanceTemplate = {
|
||||||
0, // PreviousPort
|
0, // PreviousPort
|
||||||
0, // PreviousPortMultiplier
|
0, // PreviousPortMultiplier
|
||||||
0, // PreviousTargetId
|
0, // PreviousTargetId
|
||||||
0 // PreviousLun
|
0, // PreviousLun
|
||||||
|
NULL, // Timer event
|
||||||
|
{ // NonBlocking TaskList
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ATAPI_DEVICE_PATH mAtapiDevicePathTemplate = {
|
ATAPI_DEVICE_PATH mAtapiDevicePathTemplate = {
|
||||||
|
@ -132,12 +137,304 @@ UINT8 mScsiId[TARGET_MAX_BYTES] = {
|
||||||
0xFF, 0xFF, 0xFF, 0xFF
|
0xFF, 0xFF, 0xFF, 0xFF
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sends an ATA command to an ATA device that is attached to the ATA controller. This function
|
||||||
|
supports both blocking I/O and non-blocking I/O. The blocking I/O functionality is required,
|
||||||
|
and the non-blocking I/O functionality is optional.
|
||||||
|
|
||||||
|
@param[in] Port The port number of the ATA device to send the command.
|
||||||
|
@param[in] PortMultiplierPort The port multiplier port number of the ATA device to send the command.
|
||||||
|
If there is no port multiplier, then specify 0.
|
||||||
|
@param[in, out] Packet A pointer to the ATA command to send to the ATA device specified by Port
|
||||||
|
and PortMultiplierPort.
|
||||||
|
@param[in] Instance Pointer to the ATA_ATAPI_PASS_THRU_INSTANCE.
|
||||||
|
@param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
|
||||||
|
used by non-blocking mode.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The ATA command was sent by the host. For
|
||||||
|
bi-directional commands, InTransferLength bytes
|
||||||
|
were transferred from InDataBuffer. For
|
||||||
|
write and bi-directional commands, OutTransferLength
|
||||||
|
bytes were transferred by OutDataBuffer.
|
||||||
|
@retval EFI_BAD_BUFFER_SIZE The ATA command was not executed. The number
|
||||||
|
of bytes that could be transferred is returned
|
||||||
|
in InTransferLength. For write and bi-directional
|
||||||
|
commands, OutTransferLength bytes were transferred
|
||||||
|
by OutDataBuffer.
|
||||||
|
@retval EFI_NOT_READY The ATA command could not be sent because
|
||||||
|
there are too many ATA commands already
|
||||||
|
queued. The caller may retry again later.
|
||||||
|
@retval EFI_DEVICE_ERROR A device error occurred while attempting
|
||||||
|
to send the ATA command.
|
||||||
|
@retval EFI_INVALID_PARAMETER Port, PortMultiplierPort, or the contents
|
||||||
|
of Acb are invalid. The ATA command was
|
||||||
|
not sent, so no additional status information
|
||||||
|
is available.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AtaPassThruPassThruExecute (
|
||||||
|
IN UINT16 Port,
|
||||||
|
IN UINT16 PortMultiplierPort,
|
||||||
|
IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET *Packet,
|
||||||
|
IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
|
||||||
|
IN ATA_NONBLOCK_TASK *Task OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_ATA_PASS_THRU_CMD_PROTOCOL Protocol;
|
||||||
|
EFI_ATA_HC_WORK_MODE Mode;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
Protocol = Packet->Protocol;
|
||||||
|
|
||||||
|
Mode = Instance->Mode;
|
||||||
|
switch (Mode) {
|
||||||
|
case EfiAtaIdeMode:
|
||||||
|
//
|
||||||
|
// Reassign IDE mode io port registers' base addresses
|
||||||
|
//
|
||||||
|
Status = GetIdeRegisterIoAddr (Instance->PciIo, Instance->IdeRegisters);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (Protocol) {
|
||||||
|
case EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA:
|
||||||
|
Status = AtaNonDataCommandIn (
|
||||||
|
Instance->PciIo,
|
||||||
|
&Instance->IdeRegisters[Port],
|
||||||
|
Packet->Acb,
|
||||||
|
Packet->Asb,
|
||||||
|
Packet->Timeout,
|
||||||
|
Task
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN:
|
||||||
|
Status = AtaPioDataInOut (
|
||||||
|
Instance->PciIo,
|
||||||
|
&Instance->IdeRegisters[Port],
|
||||||
|
Packet->InDataBuffer,
|
||||||
|
Packet->InTransferLength,
|
||||||
|
TRUE,
|
||||||
|
Packet->Acb,
|
||||||
|
Packet->Asb,
|
||||||
|
Packet->Timeout,
|
||||||
|
Task
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT:
|
||||||
|
Status = AtaPioDataInOut (
|
||||||
|
Instance->PciIo,
|
||||||
|
&Instance->IdeRegisters[Port],
|
||||||
|
Packet->OutDataBuffer,
|
||||||
|
Packet->OutTransferLength,
|
||||||
|
FALSE,
|
||||||
|
Packet->Acb,
|
||||||
|
Packet->Asb,
|
||||||
|
Packet->Timeout,
|
||||||
|
Task
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_IN:
|
||||||
|
Status = AtaUdmaInOut (
|
||||||
|
Instance,
|
||||||
|
&Instance->IdeRegisters[Port],
|
||||||
|
TRUE,
|
||||||
|
Packet->InDataBuffer,
|
||||||
|
Packet->InTransferLength,
|
||||||
|
Packet->Acb,
|
||||||
|
Packet->Asb,
|
||||||
|
Packet->Timeout,
|
||||||
|
Task
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_OUT:
|
||||||
|
Status = AtaUdmaInOut (
|
||||||
|
Instance,
|
||||||
|
&Instance->IdeRegisters[Port],
|
||||||
|
FALSE,
|
||||||
|
Packet->OutDataBuffer,
|
||||||
|
Packet->OutTransferLength,
|
||||||
|
Packet->Acb,
|
||||||
|
Packet->Asb,
|
||||||
|
Packet->Timeout,
|
||||||
|
Task
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EfiAtaAhciMode :
|
||||||
|
switch (Protocol) {
|
||||||
|
case EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA:
|
||||||
|
Status = AhciNonDataTransfer (
|
||||||
|
Instance->PciIo,
|
||||||
|
&Instance->AhciRegisters,
|
||||||
|
(UINT8)Port,
|
||||||
|
(UINT8)PortMultiplierPort,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
Packet->Acb,
|
||||||
|
Packet->Asb,
|
||||||
|
Packet->Timeout,
|
||||||
|
Task
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN:
|
||||||
|
Status = AhciPioTransfer (
|
||||||
|
Instance->PciIo,
|
||||||
|
&Instance->AhciRegisters,
|
||||||
|
(UINT8)Port,
|
||||||
|
(UINT8)PortMultiplierPort,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
TRUE,
|
||||||
|
Packet->Acb,
|
||||||
|
Packet->Asb,
|
||||||
|
Packet->InDataBuffer,
|
||||||
|
Packet->InTransferLength,
|
||||||
|
Packet->Timeout,
|
||||||
|
Task
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT:
|
||||||
|
Status = AhciPioTransfer (
|
||||||
|
Instance->PciIo,
|
||||||
|
&Instance->AhciRegisters,
|
||||||
|
(UINT8)Port,
|
||||||
|
(UINT8)PortMultiplierPort,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
Packet->Acb,
|
||||||
|
Packet->Asb,
|
||||||
|
Packet->OutDataBuffer,
|
||||||
|
Packet->OutTransferLength,
|
||||||
|
Packet->Timeout,
|
||||||
|
Task
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_IN:
|
||||||
|
Status = AhciDmaTransfer (
|
||||||
|
Instance,
|
||||||
|
&Instance->AhciRegisters,
|
||||||
|
(UINT8)Port,
|
||||||
|
(UINT8)PortMultiplierPort,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
TRUE,
|
||||||
|
Packet->Acb,
|
||||||
|
Packet->Asb,
|
||||||
|
Packet->InDataBuffer,
|
||||||
|
Packet->InTransferLength,
|
||||||
|
Packet->Timeout,
|
||||||
|
Task
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_OUT:
|
||||||
|
Status = AhciDmaTransfer (
|
||||||
|
Instance,
|
||||||
|
&Instance->AhciRegisters,
|
||||||
|
(UINT8)Port,
|
||||||
|
(UINT8)PortMultiplierPort,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
Packet->Acb,
|
||||||
|
Packet->Asb,
|
||||||
|
Packet->OutDataBuffer,
|
||||||
|
Packet->OutTransferLength,
|
||||||
|
Packet->Timeout,
|
||||||
|
Task
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Status = EFI_DEVICE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Call back function when the timer event is signaled.
|
||||||
|
|
||||||
|
@param[in] Event The Event this notify function registered to.
|
||||||
|
@param[in] Context Pointer to the context data registered to the
|
||||||
|
Event.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
AsyncNonBlockingTransferRoutine (
|
||||||
|
EFI_EVENT Event,
|
||||||
|
VOID* Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LIST_ENTRY *Entry;
|
||||||
|
LIST_ENTRY *EntryHeader;
|
||||||
|
ATA_NONBLOCK_TASK *Task;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
ATA_ATAPI_PASS_THRU_INSTANCE *Instance;
|
||||||
|
|
||||||
|
Instance = (ATA_ATAPI_PASS_THRU_INSTANCE *) Context;
|
||||||
|
EntryHeader = &Instance->NonBlockingTaskList;
|
||||||
|
//
|
||||||
|
// Get the Taks from the Taks List and execute it, until there is
|
||||||
|
// no task in the list or the device is busy with task (EFI_NOT_READY).
|
||||||
|
//
|
||||||
|
while (TRUE) {
|
||||||
|
if (!IsListEmpty (EntryHeader)) {
|
||||||
|
Entry = GetFirstNode (EntryHeader);
|
||||||
|
Task = ATA_NON_BLOCK_TASK_FROM_ENTRY (Entry);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = AtaPassThruPassThruExecute (
|
||||||
|
Task->Port,
|
||||||
|
Task->PortMultiplier,
|
||||||
|
Task->Packet,
|
||||||
|
Instance,
|
||||||
|
Task
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// If the data transfer meet a error which is not dumped into the status block
|
||||||
|
// set the Status block related bit.
|
||||||
|
//
|
||||||
|
if ((Status != EFI_NOT_READY) && (Status != EFI_SUCCESS)) {
|
||||||
|
Task->Packet->Asb->AtaStatus = 0x01;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// For Non blocking mode, the Status of EFI_NOT_READY means the operation
|
||||||
|
// is not finished yet. Other Status indicate the operation is either
|
||||||
|
// successful or failed.
|
||||||
|
//
|
||||||
|
if (Status != EFI_NOT_READY) {
|
||||||
|
RemoveEntryList (&Task->Link);
|
||||||
|
gBS->SignalEvent (Task->Event);
|
||||||
|
FreePool (Task);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The Entry Point of module.
|
The Entry Point of module.
|
||||||
|
|
||||||
@param[in] ImageHandle The firmware allocated handle for the EFI image.
|
@param[in] ImageHandle The firmware allocated handle for the EFI image.
|
||||||
@param[in] SystemTable A pointer to the EFI System Table.
|
@param[in] SystemTable A pointer to the EFI System Table.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The entry point is executed successfully.
|
@retval EFI_SUCCESS The entry point is executed successfully.
|
||||||
@retval other Some error occurs when executing this entry point.
|
@retval other Some error occurs when executing this entry point.
|
||||||
|
|
||||||
|
@ -266,7 +563,7 @@ AtaAtapiPassThruSupported (
|
||||||
//
|
//
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Close the I/O Abstraction(s) used to perform the supported test
|
// Close the I/O Abstraction(s) used to perform the supported test
|
||||||
//
|
//
|
||||||
|
@ -324,7 +621,7 @@ AtaAtapiPassThruSupported (
|
||||||
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
|
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
|
||||||
EFI_DEVICE_PATH_PROTOCOL.
|
EFI_DEVICE_PATH_PROTOCOL.
|
||||||
3. Prior to calling Start(), the Supported() function for the driver specified by This must
|
3. Prior to calling Start(), the Supported() function for the driver specified by This must
|
||||||
have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
|
have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
|
||||||
|
|
||||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||||
@param[in] ControllerHandle The handle of the controller to start. This handle
|
@param[in] ControllerHandle The handle of the controller to start. This handle
|
||||||
|
@ -333,7 +630,7 @@ AtaAtapiPassThruSupported (
|
||||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||||
parameter is ignored by device drivers, and is optional for bus
|
parameter is ignored by device drivers, and is optional for bus
|
||||||
drivers. For a bus driver, if this parameter is NULL, then handles
|
drivers. For a bus driver, if this parameter is NULL, then handles
|
||||||
for all the children of Controller are created by this driver.
|
for all the children of Controller are created by this driver.
|
||||||
If this parameter is not NULL and the first Device Path Node is
|
If this parameter is not NULL and the first Device Path Node is
|
||||||
not the End of Device Path Node, then only the handle for the
|
not the End of Device Path Node, then only the handle for the
|
||||||
child device specified by the first Device Path Node of
|
child device specified by the first Device Path Node of
|
||||||
|
@ -446,6 +743,28 @@ AtaAtapiPassThruStart (
|
||||||
Instance->AtaPassThru.Mode = &Instance->AtaPassThruMode;
|
Instance->AtaPassThru.Mode = &Instance->AtaPassThruMode;
|
||||||
Instance->ExtScsiPassThru.Mode = &Instance->ExtScsiPassThruMode;
|
Instance->ExtScsiPassThru.Mode = &Instance->ExtScsiPassThruMode;
|
||||||
InitializeListHead(&Instance->DeviceList);
|
InitializeListHead(&Instance->DeviceList);
|
||||||
|
InitializeListHead(&Instance->NonBlockingTaskList);
|
||||||
|
|
||||||
|
Instance->TimerEvent = NULL;
|
||||||
|
|
||||||
|
Status = gBS->CreateEvent (
|
||||||
|
EVT_TIMER | EVT_NOTIFY_SIGNAL,
|
||||||
|
TPL_NOTIFY,
|
||||||
|
AsyncNonBlockingTransferRoutine,
|
||||||
|
Instance,
|
||||||
|
&Instance->TimerEvent
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ErrorExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set 1ms timer.
|
||||||
|
//
|
||||||
|
Status = gBS->SetTimer (Instance->TimerEvent, TimerPeriodic, 10000);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ErrorExit;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Enumerate all inserted ATA devices.
|
// Enumerate all inserted ATA devices.
|
||||||
|
@ -475,6 +794,10 @@ ErrorExit:
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Instance->TimerEvent != NULL) {
|
||||||
|
gBS->CloseEvent (Instance->TimerEvent);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Remove all inserted ATA devices.
|
// Remove all inserted ATA devices.
|
||||||
//
|
//
|
||||||
|
@ -542,13 +865,22 @@ AtaAtapiPassThruStop (
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS(AtaPassThru);
|
Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (AtaPassThru);
|
||||||
PciIo = Instance->PciIo;
|
|
||||||
|
//
|
||||||
|
// Close Non-Blocking timer and free Task list.
|
||||||
|
//
|
||||||
|
if (Instance->TimerEvent != NULL) {
|
||||||
|
gBS->CloseEvent (Instance->TimerEvent);
|
||||||
|
Instance->TimerEvent = NULL;
|
||||||
|
}
|
||||||
|
DestroyAsynTaskList (Instance);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Disable this ATA host controller.
|
// Disable this ATA host controller.
|
||||||
//
|
//
|
||||||
|
PciIo = Instance->PciIo;
|
||||||
Status = PciIo->Attributes (
|
Status = PciIo->Attributes (
|
||||||
PciIo,
|
PciIo,
|
||||||
EfiPciIoAttributeOperationSupported,
|
EfiPciIoAttributeOperationSupported,
|
||||||
|
@ -672,7 +1004,7 @@ SearchDeviceInfoList (
|
||||||
}
|
}
|
||||||
|
|
||||||
Node = GetNextNode (&Instance->DeviceList, Node);
|
Node = GetNextNode (&Instance->DeviceList, Node);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -757,6 +1089,42 @@ DestroyDeviceInfoList (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Destroy all pending non blocking tasks.
|
||||||
|
|
||||||
|
@param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
DestroyAsynTaskList (
|
||||||
|
IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LIST_ENTRY *Entry;
|
||||||
|
LIST_ENTRY *DelEntry;
|
||||||
|
ATA_NONBLOCK_TASK *Task;
|
||||||
|
EFI_TPL OldTpl;
|
||||||
|
|
||||||
|
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||||
|
if (!IsListEmpty (&Instance->NonBlockingTaskList)) {
|
||||||
|
//
|
||||||
|
// Free the Subtask list.
|
||||||
|
//
|
||||||
|
for (Entry = (&Instance->NonBlockingTaskList)->ForwardLink;
|
||||||
|
Entry != (&Instance->NonBlockingTaskList);
|
||||||
|
) {
|
||||||
|
DelEntry = Entry;
|
||||||
|
Entry = Entry->ForwardLink;
|
||||||
|
Task = ATA_NON_BLOCK_TASK_FROM_ENTRY (DelEntry);
|
||||||
|
|
||||||
|
RemoveEntryList (DelEntry);
|
||||||
|
FreePool (Task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Enumerate all attached ATA devices at IDE mode or AHCI mode separately.
|
Enumerate all attached ATA devices at IDE mode or AHCI mode separately.
|
||||||
|
|
||||||
|
@ -863,17 +1231,16 @@ AtaPassThruPassThru (
|
||||||
IN UINT16 PortMultiplierPort,
|
IN UINT16 PortMultiplierPort,
|
||||||
IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET *Packet,
|
IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET *Packet,
|
||||||
IN EFI_EVENT Event OPTIONAL
|
IN EFI_EVENT Event OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
|
||||||
ATA_ATAPI_PASS_THRU_INSTANCE *Instance;
|
ATA_ATAPI_PASS_THRU_INSTANCE *Instance;
|
||||||
EFI_ATA_PASS_THRU_CMD_PROTOCOL Protocol;
|
|
||||||
EFI_ATA_HC_WORK_MODE Mode;
|
|
||||||
LIST_ENTRY *Node;
|
LIST_ENTRY *Node;
|
||||||
EFI_ATA_DEVICE_INFO *DeviceInfo;
|
EFI_ATA_DEVICE_INFO *DeviceInfo;
|
||||||
EFI_IDENTIFY_DATA *IdentifyData;
|
EFI_IDENTIFY_DATA *IdentifyData;
|
||||||
UINT64 Capacity;
|
UINT64 Capacity;
|
||||||
UINT32 MaxSectorCount;
|
UINT32 MaxSectorCount;
|
||||||
|
ATA_NONBLOCK_TASK *Task;
|
||||||
|
EFI_TPL OldTpl;
|
||||||
|
|
||||||
Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);
|
Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);
|
||||||
|
|
||||||
|
@ -940,173 +1307,37 @@ AtaPassThruPassThru (
|
||||||
return EFI_BAD_BUFFER_SIZE;
|
return EFI_BAD_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = EFI_UNSUPPORTED;
|
//
|
||||||
Protocol = Packet->Protocol;
|
// For non-blocking mode, queue the Task into the list.
|
||||||
|
//
|
||||||
|
if (Event != NULL) {
|
||||||
|
Task = AllocateZeroPool (sizeof (ATA_NONBLOCK_TASK));
|
||||||
|
if (Task == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
Task->Signature = ATA_NONBLOCKING_TASK_SIGNATURE;
|
||||||
|
Task->Port = Port;
|
||||||
|
Task->PortMultiplier = PortMultiplierPort;
|
||||||
|
Task->Packet = Packet;
|
||||||
|
Task->Event = Event;
|
||||||
|
Task->IsStart = FALSE;
|
||||||
|
Task->RetryTimes = 0;
|
||||||
|
|
||||||
Mode = Instance->Mode;
|
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||||
switch (Mode) {
|
InsertTailList (&Instance->NonBlockingTaskList, &Task->Link);
|
||||||
case EfiAtaIdeMode:
|
gBS->RestoreTPL (OldTpl);
|
||||||
//
|
|
||||||
// Reassign IDE mode io port registers' base addresses
|
|
||||||
//
|
|
||||||
Status = GetIdeRegisterIoAddr (Instance->PciIo, Instance->IdeRegisters);
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (Protocol) {
|
|
||||||
case EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA:
|
|
||||||
Status = AtaNonDataCommandIn(
|
|
||||||
Instance->PciIo,
|
|
||||||
&Instance->IdeRegisters[Port],
|
|
||||||
Packet->Acb,
|
|
||||||
Packet->Asb,
|
|
||||||
Packet->Timeout
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN:
|
|
||||||
Status = AtaPioDataInOut(
|
|
||||||
Instance->PciIo,
|
|
||||||
&Instance->IdeRegisters[Port],
|
|
||||||
Packet->InDataBuffer,
|
|
||||||
Packet->InTransferLength,
|
|
||||||
TRUE,
|
|
||||||
Packet->Acb,
|
|
||||||
Packet->Asb,
|
|
||||||
Packet->Timeout
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT:
|
|
||||||
Status = AtaPioDataInOut(
|
|
||||||
Instance->PciIo,
|
|
||||||
&Instance->IdeRegisters[Port],
|
|
||||||
Packet->OutDataBuffer,
|
|
||||||
Packet->OutTransferLength,
|
|
||||||
FALSE,
|
|
||||||
Packet->Acb,
|
|
||||||
Packet->Asb,
|
|
||||||
Packet->Timeout
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_IN:
|
|
||||||
Status = AtaUdmaInOut(
|
|
||||||
Instance->PciIo,
|
|
||||||
&Instance->IdeRegisters[Port],
|
|
||||||
TRUE,
|
|
||||||
Packet->InDataBuffer,
|
|
||||||
Packet->InTransferLength,
|
|
||||||
Packet->Acb,
|
|
||||||
Packet->Asb,
|
|
||||||
Packet->Timeout
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_OUT:
|
|
||||||
Status = AtaUdmaInOut(
|
|
||||||
Instance->PciIo,
|
|
||||||
&Instance->IdeRegisters[Port],
|
|
||||||
FALSE,
|
|
||||||
Packet->OutDataBuffer,
|
|
||||||
Packet->OutTransferLength,
|
|
||||||
Packet->Acb,
|
|
||||||
Packet->Asb,
|
|
||||||
Packet->Timeout
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EfiAtaAhciMode :
|
|
||||||
switch (Protocol) {
|
|
||||||
case EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA:
|
|
||||||
Status = AhciNonDataTransfer(
|
|
||||||
Instance->PciIo,
|
|
||||||
&Instance->AhciRegisters,
|
|
||||||
(UINT8)Port,
|
|
||||||
(UINT8)PortMultiplierPort,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
Packet->Acb,
|
|
||||||
Packet->Asb,
|
|
||||||
Packet->Timeout
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN:
|
|
||||||
Status = AhciPioTransfer(
|
|
||||||
Instance->PciIo,
|
|
||||||
&Instance->AhciRegisters,
|
|
||||||
(UINT8)Port,
|
|
||||||
(UINT8)PortMultiplierPort,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
TRUE,
|
|
||||||
Packet->Acb,
|
|
||||||
Packet->Asb,
|
|
||||||
Packet->InDataBuffer,
|
|
||||||
Packet->InTransferLength,
|
|
||||||
Packet->Timeout
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT:
|
|
||||||
Status = AhciPioTransfer(
|
|
||||||
Instance->PciIo,
|
|
||||||
&Instance->AhciRegisters,
|
|
||||||
(UINT8)Port,
|
|
||||||
(UINT8)PortMultiplierPort,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
FALSE,
|
|
||||||
Packet->Acb,
|
|
||||||
Packet->Asb,
|
|
||||||
Packet->OutDataBuffer,
|
|
||||||
Packet->OutTransferLength,
|
|
||||||
Packet->Timeout
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_IN:
|
|
||||||
Status = AhciDmaTransfer(
|
|
||||||
Instance->PciIo,
|
|
||||||
&Instance->AhciRegisters,
|
|
||||||
(UINT8)Port,
|
|
||||||
(UINT8)PortMultiplierPort,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
TRUE,
|
|
||||||
Packet->Acb,
|
|
||||||
Packet->Asb,
|
|
||||||
Packet->InDataBuffer,
|
|
||||||
Packet->InTransferLength,
|
|
||||||
Packet->Timeout
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_OUT:
|
|
||||||
Status = AhciDmaTransfer(
|
|
||||||
Instance->PciIo,
|
|
||||||
&Instance->AhciRegisters,
|
|
||||||
(UINT8)Port,
|
|
||||||
(UINT8)PortMultiplierPort,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
FALSE,
|
|
||||||
Packet->Acb,
|
|
||||||
Packet->Asb,
|
|
||||||
Packet->OutDataBuffer,
|
|
||||||
Packet->OutTransferLength,
|
|
||||||
Packet->Timeout
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
return EFI_SUCCESS;
|
||||||
Status = EFI_DEVICE_ERROR;
|
} else {
|
||||||
break;
|
return AtaPassThruPassThruExecute (
|
||||||
|
Port,
|
||||||
|
PortMultiplierPort,
|
||||||
|
Packet,
|
||||||
|
Instance,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1197,7 +1428,7 @@ AtaPassThruGetNextPort (
|
||||||
//
|
//
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
//
|
//
|
||||||
// Update the PreviousPort and PreviousPortMultiplier.
|
// Update the PreviousPort and PreviousPortMultiplier.
|
||||||
|
@ -1216,20 +1447,20 @@ Exit:
|
||||||
|
|
||||||
The GetNextDevice() function retrieves the port multiplier port number of an ATA device
|
The GetNextDevice() function retrieves the port multiplier port number of an ATA device
|
||||||
present on a port of an ATA controller.
|
present on a port of an ATA controller.
|
||||||
|
|
||||||
If PortMultiplierPort points to a port multiplier port number value that was returned on a
|
If PortMultiplierPort points to a port multiplier port number value that was returned on a
|
||||||
previous call to GetNextDevice(), then the port multiplier port number of the next ATA device
|
previous call to GetNextDevice(), then the port multiplier port number of the next ATA device
|
||||||
on the port of the ATA controller is returned in PortMultiplierPort, and EFI_SUCCESS is
|
on the port of the ATA controller is returned in PortMultiplierPort, and EFI_SUCCESS is
|
||||||
returned.
|
returned.
|
||||||
|
|
||||||
If PortMultiplierPort points to 0xFFFF, then the port multiplier port number of the first
|
If PortMultiplierPort points to 0xFFFF, then the port multiplier port number of the first
|
||||||
ATA device on port of the ATA controller is returned in PortMultiplierPort and
|
ATA device on port of the ATA controller is returned in PortMultiplierPort and
|
||||||
EFI_SUCCESS is returned.
|
EFI_SUCCESS is returned.
|
||||||
|
|
||||||
If PortMultiplierPort is not 0xFFFF and the value pointed to by PortMultiplierPort
|
If PortMultiplierPort is not 0xFFFF and the value pointed to by PortMultiplierPort
|
||||||
was not returned on a previous call to GetNextDevice(), then EFI_INVALID_PARAMETER
|
was not returned on a previous call to GetNextDevice(), then EFI_INVALID_PARAMETER
|
||||||
is returned.
|
is returned.
|
||||||
|
|
||||||
If PortMultiplierPort is the port multiplier port number of the last ATA device on the port of
|
If PortMultiplierPort is the port multiplier port number of the last ATA device on the port of
|
||||||
the ATA controller, then EFI_NOT_FOUND is returned.
|
the ATA controller, then EFI_NOT_FOUND is returned.
|
||||||
|
|
||||||
|
@ -1309,7 +1540,7 @@ AtaPassThruGetNextDevice (
|
||||||
//
|
//
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
//
|
//
|
||||||
// Update the PreviousPort and PreviousPortMultiplier.
|
// Update the PreviousPort and PreviousPortMultiplier.
|
||||||
|
@ -1377,7 +1608,7 @@ AtaPassThruBuildDevicePath (
|
||||||
if (Node == NULL) {
|
if (Node == NULL) {
|
||||||
return EFI_NOT_FOUND;
|
return EFI_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Instance->Mode == EfiAtaIdeMode) {
|
if (Instance->Mode == EfiAtaIdeMode) {
|
||||||
DevicePathNode = AllocateCopyPool (sizeof (ATAPI_DEVICE_PATH), &mAtapiDevicePathTemplate);
|
DevicePathNode = AllocateCopyPool (sizeof (ATAPI_DEVICE_PATH), &mAtapiDevicePathTemplate);
|
||||||
if (DevicePathNode == NULL) {
|
if (DevicePathNode == NULL) {
|
||||||
|
@ -1719,7 +1950,7 @@ ExtScsiPassThruPassThru (
|
||||||
can either be the list SCSI devices that are actually present on the SCSI channel, or the list of legal
|
can either be the list SCSI devices that are actually present on the SCSI channel, or the list of legal
|
||||||
Target Ids and LUNs for the SCSI channel. Regardless, the caller of this function must probe the
|
Target Ids and LUNs for the SCSI channel. Regardless, the caller of this function must probe the
|
||||||
Target ID and LUN returned to see if a SCSI device is actually present at that location on the SCSI
|
Target ID and LUN returned to see if a SCSI device is actually present at that location on the SCSI
|
||||||
channel.
|
channel.
|
||||||
|
|
||||||
@param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
|
@param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
|
||||||
@param Target On input, a pointer to the Target ID (an array of size
|
@param Target On input, a pointer to the Target ID (an array of size
|
||||||
|
@ -1840,7 +2071,7 @@ Exit:
|
||||||
Instance->PreviousLun = *Lun;
|
Instance->PreviousLun = *Lun;
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Used to allocate and build a device path node for a SCSI device on a SCSI channel.
|
Used to allocate and build a device path node for a SCSI device on a SCSI channel.
|
||||||
|
@ -2031,8 +2262,8 @@ ExtScsiPassThruResetChannel (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Resets a SCSI logical unit that is connected to a SCSI channel.
|
Resets a SCSI logical unit that is connected to a SCSI channel.
|
||||||
|
|
||||||
|
@ -2061,7 +2292,7 @@ ExtScsiPassThruResetTargetLun (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Used to retrieve the list of legal Target IDs for SCSI devices on a SCSI channel. These can either
|
Used to retrieve the list of legal Target IDs for SCSI devices on a SCSI channel. These can either
|
||||||
|
@ -2176,5 +2407,5 @@ Exit:
|
||||||
Instance->PreviousTargetId = *Target16;
|
Instance->PreviousTargetId = *Target16;
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Header file for ATA/ATAPI PASS THRU driver.
|
Header file for ATA/ATAPI PASS THRU driver.
|
||||||
|
|
||||||
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
|
||||||
|
@ -47,6 +47,9 @@ extern EFI_COMPONENT_NAME2_PROTOCOL gAtaAtapiPassThruComponentName2;
|
||||||
|
|
||||||
#define ATA_ATAPI_PASS_THRU_SIGNATURE SIGNATURE_32 ('a', 'a', 'p', 't')
|
#define ATA_ATAPI_PASS_THRU_SIGNATURE SIGNATURE_32 ('a', 'a', 'p', 't')
|
||||||
#define ATA_ATAPI_DEVICE_SIGNATURE SIGNATURE_32 ('a', 'd', 'e', 'v')
|
#define ATA_ATAPI_DEVICE_SIGNATURE SIGNATURE_32 ('a', 'd', 'e', 'v')
|
||||||
|
#define ATA_NONBLOCKING_TASK_SIGNATURE SIGNATURE_32 ('a', 't', 's', 'k')
|
||||||
|
|
||||||
|
typedef struct _ATA_NONBLOCK_TASK ATA_NONBLOCK_TASK;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EfiAtaIdeMode,
|
EfiAtaIdeMode,
|
||||||
|
@ -111,9 +114,33 @@ typedef struct {
|
||||||
//
|
//
|
||||||
UINT16 PreviousTargetId;
|
UINT16 PreviousTargetId;
|
||||||
UINT64 PreviousLun;
|
UINT64 PreviousLun;
|
||||||
|
|
||||||
|
//
|
||||||
|
// For Non-blocking.
|
||||||
|
//
|
||||||
|
EFI_EVENT TimerEvent;
|
||||||
|
LIST_ENTRY NonBlockingTaskList;
|
||||||
} ATA_ATAPI_PASS_THRU_INSTANCE;
|
} ATA_ATAPI_PASS_THRU_INSTANCE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Task for Non-blocking mode.
|
||||||
|
//
|
||||||
|
struct _ATA_NONBLOCK_TASK {
|
||||||
|
UINT32 Signature;
|
||||||
|
LIST_ENTRY Link;
|
||||||
|
|
||||||
|
UINT16 Port;
|
||||||
|
UINT16 PortMultiplier;
|
||||||
|
EFI_ATA_PASS_THRU_COMMAND_PACKET *Packet;
|
||||||
|
BOOLEAN IsStart;
|
||||||
|
EFI_EVENT Event;
|
||||||
|
UINT64 RetryTimes;
|
||||||
|
VOID *Map; // Pointer to map.
|
||||||
|
VOID *TableMap;// Pointer to PRD table map.
|
||||||
|
EFI_ATA_DMA_PRD *MapBaseAddress; // Pointer to range Base address for Map.
|
||||||
|
UINTN PageCount; // The page numbers used by PCIO freebuffer.
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Timeout value which uses 100ns as a unit.
|
// Timeout value which uses 100ns as a unit.
|
||||||
// It means 3 second span.
|
// It means 3 second span.
|
||||||
|
@ -142,6 +169,14 @@ typedef struct {
|
||||||
Link, \
|
Link, \
|
||||||
ATA_ATAPI_DEVICE_SIGNATURE \
|
ATA_ATAPI_DEVICE_SIGNATURE \
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#define ATA_NON_BLOCK_TASK_FROM_ENTRY(a) \
|
||||||
|
CR (a, \
|
||||||
|
ATA_NONBLOCK_TASK, \
|
||||||
|
Link, \
|
||||||
|
ATA_NONBLOCKING_TASK_SIGNATURE \
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Retrieves a Unicode string that is the user readable name of the driver.
|
Retrieves a Unicode string that is the user readable name of the driver.
|
||||||
|
|
||||||
|
@ -453,6 +488,18 @@ DestroyDeviceInfoList (
|
||||||
IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance
|
IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Destroy all pending non blocking tasks.
|
||||||
|
|
||||||
|
@param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
DestroyAsynTaskList (
|
||||||
|
IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Enumerate all attached ATA devices at IDE mode or AHCI mode separately.
|
Enumerate all attached ATA devices at IDE mode or AHCI mode separately.
|
||||||
|
|
||||||
|
@ -470,6 +517,21 @@ EnumerateAttachedDevice (
|
||||||
IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance
|
IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Call back funtion when the timer event is signaled.
|
||||||
|
|
||||||
|
@param[in] Event The Event this notify function registered to.
|
||||||
|
@param[in] Context Pointer to the context data registered to the
|
||||||
|
Event.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
AsyncNonBlockingTransferRoutine (
|
||||||
|
EFI_EVENT Event,
|
||||||
|
VOID* Context
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sends an ATA command to an ATA device that is attached to the ATA controller. This function
|
Sends an ATA command to an ATA device that is attached to the ATA controller. This function
|
||||||
supports both blocking I/O and non-blocking I/O. The blocking I/O functionality is required,
|
supports both blocking I/O and non-blocking I/O. The blocking I/O functionality is required,
|
||||||
|
@ -556,16 +618,16 @@ AtaPassThruGetNextPort (
|
||||||
|
|
||||||
The GetNextDevice() function retrieves the port multiplier port number of an ATA device
|
The GetNextDevice() function retrieves the port multiplier port number of an ATA device
|
||||||
present on a port of an ATA controller.
|
present on a port of an ATA controller.
|
||||||
|
|
||||||
If PortMultiplierPort points to a port multiplier port number value that was returned on a
|
If PortMultiplierPort points to a port multiplier port number value that was returned on a
|
||||||
previous call to GetNextDevice(), then the port multiplier port number of the next ATA device
|
previous call to GetNextDevice(), then the port multiplier port number of the next ATA device
|
||||||
on the port of the ATA controller is returned in PortMultiplierPort, and EFI_SUCCESS is
|
on the port of the ATA controller is returned in PortMultiplierPort, and EFI_SUCCESS is
|
||||||
returned.
|
returned.
|
||||||
|
|
||||||
If PortMultiplierPort points to 0xFFFF, then the port multiplier port number of the first
|
If PortMultiplierPort points to 0xFFFF, then the port multiplier port number of the first
|
||||||
ATA device on port of the ATA controller is returned in PortMultiplierPort and
|
ATA device on port of the ATA controller is returned in PortMultiplierPort and
|
||||||
EFI_SUCCESS is returned.
|
EFI_SUCCESS is returned.
|
||||||
|
|
||||||
If PortMultiplierPort is not 0xFFFF and the value pointed to by PortMultiplierPort
|
If PortMultiplierPort is not 0xFFFF and the value pointed to by PortMultiplierPort
|
||||||
was not returned on a previous call to GetNextDevice(), then EFI_INVALID_PARAMETER
|
was not returned on a previous call to GetNextDevice(), then EFI_INVALID_PARAMETER
|
||||||
is returned.
|
is returned.
|
||||||
|
@ -673,6 +735,7 @@ AtaPassThruBuildDevicePath (
|
||||||
@retval EFI_UNSUPPORTED This driver does not support the device path node type in DevicePath.
|
@retval EFI_UNSUPPORTED This driver does not support the device path node type in DevicePath.
|
||||||
@retval EFI_NOT_FOUND A valid translation from DevicePath to a port number and port multiplier
|
@retval EFI_NOT_FOUND A valid translation from DevicePath to a port number and port multiplier
|
||||||
port number does not exist.
|
port number does not exist.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
|
@ -809,7 +872,7 @@ ExtScsiPassThruPassThru (
|
||||||
can either be the list SCSI devices that are actually present on the SCSI channel, or the list of legal
|
can either be the list SCSI devices that are actually present on the SCSI channel, or the list of legal
|
||||||
Target Ids and LUNs for the SCSI channel. Regardless, the caller of this function must probe the
|
Target Ids and LUNs for the SCSI channel. Regardless, the caller of this function must probe the
|
||||||
Target ID and LUN returned to see if a SCSI device is actually present at that location on the SCSI
|
Target ID and LUN returned to see if a SCSI device is actually present at that location on the SCSI
|
||||||
channel.
|
channel.
|
||||||
|
|
||||||
@param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
|
@param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
|
||||||
@param Target On input, a pointer to the Target ID (an array of size
|
@param Target On input, a pointer to the Target ID (an array of size
|
||||||
|
@ -918,7 +981,7 @@ EFIAPI
|
||||||
ExtScsiPassThruResetChannel (
|
ExtScsiPassThruResetChannel (
|
||||||
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This
|
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Resets a SCSI logical unit that is connected to a SCSI channel.
|
Resets a SCSI logical unit that is connected to a SCSI channel.
|
||||||
|
|
||||||
|
@ -1003,5 +1066,231 @@ AhciModeInitialization (
|
||||||
IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance
|
IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Start a non data transfer on specific port.
|
||||||
|
|
||||||
|
@param[in] PciIo The PCI IO protocol instance.
|
||||||
|
@param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
|
||||||
|
@param[in] Port The number of port.
|
||||||
|
@param[in] PortMultiplier The timeout value of stop.
|
||||||
|
@param[in] AtapiCommand The atapi command will be used for the
|
||||||
|
transfer.
|
||||||
|
@param[in] AtapiCommandLength The length of the atapi command.
|
||||||
|
@param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
|
||||||
|
@param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
|
||||||
|
@param[in] Timeout The timeout value of non data transfer.
|
||||||
|
@param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
|
||||||
|
used by non-blocking mode.
|
||||||
|
|
||||||
|
@retval EFI_DEVICE_ERROR The non data transfer abort with error occurs.
|
||||||
|
@retval EFI_TIMEOUT The operation is time out.
|
||||||
|
@retval EFI_UNSUPPORTED The device is not ready for transfer.
|
||||||
|
@retval EFI_SUCCESS The non data transfer executes successfully.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AhciNonDataTransfer (
|
||||||
|
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
||||||
|
IN EFI_AHCI_REGISTERS *AhciRegisters,
|
||||||
|
IN UINT8 Port,
|
||||||
|
IN UINT8 PortMultiplier,
|
||||||
|
IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
|
||||||
|
IN UINT8 AtapiCommandLength,
|
||||||
|
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
|
||||||
|
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
|
||||||
|
IN UINT64 Timeout,
|
||||||
|
IN ATA_NONBLOCK_TASK *Task
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Start a DMA data transfer on specific port
|
||||||
|
|
||||||
|
@param[in] Instance The ATA_ATAPI_PASS_THRU_INSTANCE protocol instance.
|
||||||
|
@param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
|
||||||
|
@param[in] Port The number of port.
|
||||||
|
@param[in] PortMultiplier The timeout value of stop.
|
||||||
|
@param[in] AtapiCommand The atapi command will be used for the
|
||||||
|
transfer.
|
||||||
|
@param[in] AtapiCommandLength The length of the atapi command.
|
||||||
|
@param[in] Read The transfer direction.
|
||||||
|
@param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
|
||||||
|
@param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
|
||||||
|
@param[in, out] MemoryAddr The pointer to the data buffer.
|
||||||
|
@param[in] DataCount The data count to be transferred.
|
||||||
|
@param[in] Timeout The timeout value of non data transfer.
|
||||||
|
@param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
|
||||||
|
used by non-blocking mode.
|
||||||
|
|
||||||
|
@retval EFI_DEVICE_ERROR The DMA data transfer abort with error occurs.
|
||||||
|
@retval EFI_TIMEOUT The operation is time out.
|
||||||
|
@retval EFI_UNSUPPORTED The device is not ready for transfer.
|
||||||
|
@retval EFI_SUCCESS The DMA data transfer executes successfully.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AhciDmaTransfer (
|
||||||
|
IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
|
||||||
|
IN EFI_AHCI_REGISTERS *AhciRegisters,
|
||||||
|
IN UINT8 Port,
|
||||||
|
IN UINT8 PortMultiplier,
|
||||||
|
IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
|
||||||
|
IN UINT8 AtapiCommandLength,
|
||||||
|
IN BOOLEAN Read,
|
||||||
|
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
|
||||||
|
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
|
||||||
|
IN OUT VOID *MemoryAddr,
|
||||||
|
IN UINTN DataCount,
|
||||||
|
IN UINT64 Timeout,
|
||||||
|
IN ATA_NONBLOCK_TASK *Task
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Start a PIO data transfer on specific port.
|
||||||
|
|
||||||
|
@param[in] PciIo The PCI IO protocol instance.
|
||||||
|
@param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
|
||||||
|
@param[in] Port The number of port.
|
||||||
|
@param[in] PortMultiplier The timeout value of stop.
|
||||||
|
@param[in] AtapiCommand The atapi command will be used for the
|
||||||
|
transfer.
|
||||||
|
@param[in] AtapiCommandLength The length of the atapi command.
|
||||||
|
@param[in] Read The transfer direction.
|
||||||
|
@param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
|
||||||
|
@param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
|
||||||
|
@param[in, out] MemoryAddr The pointer to the data buffer.
|
||||||
|
@param[in] DataCount The data count to be transferred.
|
||||||
|
@param[in] Timeout The timeout value of non data transfer.
|
||||||
|
@param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
|
||||||
|
used by non-blocking mode.
|
||||||
|
|
||||||
|
@retval EFI_DEVICE_ERROR The PIO data transfer abort with error occurs.
|
||||||
|
@retval EFI_TIMEOUT The operation is time out.
|
||||||
|
@retval EFI_UNSUPPORTED The device is not ready for transfer.
|
||||||
|
@retval EFI_SUCCESS The PIO data transfer executes successfully.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AhciPioTransfer (
|
||||||
|
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
||||||
|
IN EFI_AHCI_REGISTERS *AhciRegisters,
|
||||||
|
IN UINT8 Port,
|
||||||
|
IN UINT8 PortMultiplier,
|
||||||
|
IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
|
||||||
|
IN UINT8 AtapiCommandLength,
|
||||||
|
IN BOOLEAN Read,
|
||||||
|
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
|
||||||
|
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
|
||||||
|
IN OUT VOID *MemoryAddr,
|
||||||
|
IN UINT32 DataCount,
|
||||||
|
IN UINT64 Timeout,
|
||||||
|
IN ATA_NONBLOCK_TASK *Task
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Send ATA command into device with NON_DATA protocol
|
||||||
|
|
||||||
|
@param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE
|
||||||
|
data structure.
|
||||||
|
@param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
|
||||||
|
@param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data
|
||||||
|
structure.
|
||||||
|
@param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
|
||||||
|
@param[in] Timeout The time to complete the command.
|
||||||
|
@param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
|
||||||
|
used by non-blocking mode.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Reading succeed
|
||||||
|
@retval EFI_ABORTED Command failed
|
||||||
|
@retval EFI_DEVICE_ERROR Device status error.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AtaNonDataCommandIn (
|
||||||
|
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
||||||
|
IN EFI_IDE_REGISTERS *IdeRegisters,
|
||||||
|
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
|
||||||
|
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
|
||||||
|
IN UINT64 Timeout,
|
||||||
|
IN ATA_NONBLOCK_TASK *Task
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
|
||||||
|
|
||||||
|
@param[in] Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
|
||||||
|
structure.
|
||||||
|
@param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
|
||||||
|
@param[in] Read Flag used to determine the data transfer
|
||||||
|
direction. Read equals 1, means data transferred
|
||||||
|
from device to host;Read equals 0, means data
|
||||||
|
transferred from host to device.
|
||||||
|
@param[in] DataBuffer A pointer to the source buffer for the data.
|
||||||
|
@param[in] DataLength The length of the data.
|
||||||
|
@param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
|
||||||
|
@param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
|
||||||
|
@param[in] Timeout The time to complete the command.
|
||||||
|
@param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
|
||||||
|
used by non-blocking mode.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS the operation is successful.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Build PRD table failed
|
||||||
|
@retval EFI_UNSUPPORTED Unknown channel or operations command
|
||||||
|
@retval EFI_DEVICE_ERROR Ata command execute failed
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AtaUdmaInOut (
|
||||||
|
IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
|
||||||
|
IN EFI_IDE_REGISTERS *IdeRegisters,
|
||||||
|
IN BOOLEAN Read,
|
||||||
|
IN VOID *DataBuffer,
|
||||||
|
IN UINT64 DataLength,
|
||||||
|
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
|
||||||
|
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
|
||||||
|
IN UINT64 Timeout,
|
||||||
|
IN ATA_NONBLOCK_TASK *Task
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function is used to send out ATA commands conforms to the PIO Data In Protocol.
|
||||||
|
|
||||||
|
@param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
|
||||||
|
structure.
|
||||||
|
@param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
|
||||||
|
@param[in, out] Buffer A pointer to the source buffer for the data.
|
||||||
|
@param[in] ByteCount The length of the data.
|
||||||
|
@param[in] Read Flag used to determine the data transfer direction.
|
||||||
|
Read equals 1, means data transferred from device
|
||||||
|
to host;Read equals 0, means data transferred
|
||||||
|
from host to device.
|
||||||
|
@param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
|
||||||
|
@param[in] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
|
||||||
|
@param[in] Timeout The time to complete the command.
|
||||||
|
@param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
|
||||||
|
used by non-blocking mode.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS send out the ATA command and device send required data successfully.
|
||||||
|
@retval EFI_DEVICE_ERROR command sent failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AtaPioDataInOut (
|
||||||
|
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
||||||
|
IN EFI_IDE_REGISTERS *IdeRegisters,
|
||||||
|
IN OUT VOID *Buffer,
|
||||||
|
IN UINT64 ByteCount,
|
||||||
|
IN BOOLEAN Read,
|
||||||
|
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
|
||||||
|
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
|
||||||
|
IN UINT64 Timeout,
|
||||||
|
IN ATA_NONBLOCK_TASK *Task
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Header file for AHCI mode of ATA host controller.
|
Header 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
|
||||||
|
@ -1123,16 +1123,20 @@ AtaIssueCommand (
|
||||||
/**
|
/**
|
||||||
This function is used to send out ATA commands conforms to the PIO Data In Protocol.
|
This function is used to send out ATA commands conforms to the PIO Data In Protocol.
|
||||||
|
|
||||||
@param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
|
@param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
|
||||||
@param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
|
structure.
|
||||||
@param Buffer A pointer to the source buffer for the data.
|
@param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
|
||||||
@param ByteCount The length of the data.
|
@param[in, out] Buffer A pointer to the source buffer for the data.
|
||||||
@param Read Flag used to determine the data transfer direction.
|
@param[in] ByteCount The length of the data.
|
||||||
Read equals 1, means data transferred from device to host;
|
@param[in] Read Flag used to determine the data transfer direction.
|
||||||
Read equals 0, means data transferred from host to device.
|
Read equals 1, means data transferred from device
|
||||||
@param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
|
to host;Read equals 0, means data transferred
|
||||||
@param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
|
from host to device.
|
||||||
@param Timeout The time to complete the command.
|
@param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
|
||||||
|
@param[in] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
|
||||||
|
@param[in] Timeout The time to complete the command.
|
||||||
|
@param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
|
||||||
|
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.
|
||||||
|
@ -1148,7 +1152,8 @@ AtaPioDataInOut (
|
||||||
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 UINT64 Timeout
|
IN UINT64 Timeout,
|
||||||
|
IN ATA_NONBLOCK_TASK *Task
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN WordCount;
|
UINTN WordCount;
|
||||||
|
@ -1248,17 +1253,24 @@ Exit:
|
||||||
//
|
//
|
||||||
DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);
|
DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Not support the Non-blocking now,just do the blocking process.
|
||||||
|
//
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Send ATA command into device with NON_DATA protocol
|
Send ATA command into device with NON_DATA protocol
|
||||||
|
|
||||||
@param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
|
@param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE
|
||||||
@param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
|
data structure.
|
||||||
@param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
|
@param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
|
||||||
@param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
|
@param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data
|
||||||
@param Timeout The time to complete the command.
|
structure.
|
||||||
|
@param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
|
||||||
|
@param[in] Timeout The time to complete the command.
|
||||||
|
@param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
|
||||||
|
used by non-blocking mode.
|
||||||
|
|
||||||
@retval EFI_SUCCESS Reading succeed
|
@retval EFI_SUCCESS Reading succeed
|
||||||
@retval EFI_ABORTED Command failed
|
@retval EFI_ABORTED Command failed
|
||||||
|
@ -1272,7 +1284,8 @@ AtaNonDataCommandIn (
|
||||||
IN EFI_IDE_REGISTERS *IdeRegisters,
|
IN EFI_IDE_REGISTERS *IdeRegisters,
|
||||||
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 UINT64 Timeout
|
IN UINT64 Timeout,
|
||||||
|
IN ATA_NONBLOCK_TASK *Task
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
@ -1310,24 +1323,123 @@ 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.
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Wait for memory to be set.
|
||||||
|
|
||||||
|
@param[in] PciIo The PCI IO protocol instance.
|
||||||
|
@param[in] PortNum The IDE Port number.
|
||||||
|
|
||||||
|
@retval EFI_DEVICE_ERROR The memory is not set.
|
||||||
|
@retval EFI_TIMEOUT The memory setting is time out.
|
||||||
|
@retval EFI_SUCCESS The memory is correct set.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
AtaUdmStatusWait (
|
||||||
|
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
||||||
|
IN UINT16 PortNum
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT8 RegisterValue;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINT64 Timeout;
|
||||||
|
|
||||||
|
Timeout = 2000;
|
||||||
|
|
||||||
|
while (TRUE) {
|
||||||
|
RegisterValue = IdeReadPortB (PciIo, PortNum);
|
||||||
|
|
||||||
|
if (((RegisterValue & BMIS_ERROR) != 0) || (Timeout == 0)) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "ATA UDMA operation fails\n"));
|
||||||
|
Status = EFI_DEVICE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((RegisterValue & BMIS_INTERRUPT) != 0) {
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
DEBUG ((DEBUG_INFO, "Task->RetryTimes = %x\n", Timeout));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Stall for 1 milliseconds.
|
||||||
|
//
|
||||||
|
MicroSecondDelay (1000);
|
||||||
|
Timeout--;
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check if the memory to be set.
|
||||||
|
|
||||||
|
@param[in] PciIo The PCI IO protocol instance.
|
||||||
|
@param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
|
||||||
|
used by non-blocking mode.
|
||||||
|
@param[in] PortForBit The bit to be checked.
|
||||||
|
|
||||||
|
@retval EFI_DEVICE_ERROR The memory setting met a issue.
|
||||||
|
@retval EFI_NOT_READY The memory is not set.
|
||||||
|
@retval EFI_TIMEOUT The memory setting is time out.
|
||||||
|
@retval EFI_SUCCESS The memory is correct set.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
AtaUdmStatusCheck (
|
||||||
|
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
||||||
|
IN ATA_NONBLOCK_TASK *Task,
|
||||||
|
IN UINT16 PortForBit
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT8 RegisterValue;
|
||||||
|
|
||||||
|
Task->RetryTimes--;
|
||||||
|
RegisterValue = IdeReadPortB(PciIo, PortForBit);
|
||||||
|
|
||||||
|
if ((RegisterValue & BMIS_ERROR) != 0) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "ATA UDMA operation fails\n"));
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((RegisterValue & BMIS_INTERRUPT) != 0) {
|
||||||
|
DEBUG ((DEBUG_INFO, "Task->RetryTimes = %x\n", Task->RetryTimes));
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Task->RetryTimes == 0) {
|
||||||
|
return EFI_TIMEOUT;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// The memory is not set.
|
||||||
|
//
|
||||||
|
return EFI_NOT_READY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
|
Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
|
||||||
|
|
||||||
@param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
|
@param[in] Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
|
||||||
@param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
|
structure.
|
||||||
@param Read Flag used to determine the data transfer direction.
|
@param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
|
||||||
Read equals 1, means data transferred from device to host;
|
@param[in] Read Flag used to determine the data transfer
|
||||||
Read equals 0, means data transferred from host to device.
|
direction. Read equals 1, means data transferred
|
||||||
@param DataBuffer A pointer to the source buffer for the data.
|
from device to host;Read equals 0, means data
|
||||||
@param DataLength The length of the data.
|
transferred from host to device.
|
||||||
@param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
|
@param[in] DataBuffer A pointer to the source buffer for the data.
|
||||||
@param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
|
@param[in] DataLength The length of the data.
|
||||||
@param Timeout The time to complete the command.
|
@param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
|
||||||
|
@param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
|
||||||
|
@param[in] Timeout The time to complete the command.
|
||||||
|
@param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
|
||||||
|
used by non-blocking mode.
|
||||||
|
|
||||||
@retval EFI_SUCCESS the operation is successful.
|
@retval EFI_SUCCESS the operation is successful.
|
||||||
@retval EFI_OUT_OF_RESOURCES Build PRD table failed
|
@retval EFI_OUT_OF_RESOURCES Build PRD table failed
|
||||||
|
@ -1338,14 +1450,15 @@ Exit:
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
AtaUdmaInOut (
|
AtaUdmaInOut (
|
||||||
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
|
||||||
IN EFI_IDE_REGISTERS *IdeRegisters,
|
IN EFI_IDE_REGISTERS *IdeRegisters,
|
||||||
IN BOOLEAN Read,
|
IN BOOLEAN Read,
|
||||||
IN VOID *DataBuffer,
|
IN VOID *DataBuffer,
|
||||||
IN UINT64 DataLength,
|
IN UINT64 DataLength,
|
||||||
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 UINT64 Timeout
|
IN UINT64 Timeout,
|
||||||
|
IN ATA_NONBLOCK_TASK *Task
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
@ -1353,18 +1466,16 @@ AtaUdmaInOut (
|
||||||
UINT16 IoPortForBmis;
|
UINT16 IoPortForBmis;
|
||||||
UINT16 IoPortForBmid;
|
UINT16 IoPortForBmid;
|
||||||
|
|
||||||
UINT8 RegisterValue;
|
|
||||||
|
|
||||||
EFI_ATA_DMA_PRD *PrdBaseAddr;
|
|
||||||
UINTN PrdTableNum;
|
|
||||||
UINTN PrdTableSize;
|
UINTN PrdTableSize;
|
||||||
EFI_PHYSICAL_ADDRESS PrdTableMapAddr;
|
EFI_PHYSICAL_ADDRESS PrdTableMapAddr;
|
||||||
VOID *PrdTableMap;
|
VOID *PrdTableMap;
|
||||||
|
EFI_ATA_DMA_PRD *PrdBaseAddr;
|
||||||
|
UINTN PrdTableNum;
|
||||||
|
|
||||||
|
UINT8 RegisterValue;
|
||||||
UINTN PageCount;
|
UINTN PageCount;
|
||||||
UINTN ByteCount;
|
UINTN ByteCount;
|
||||||
UINTN ByteRemaining;
|
UINTN ByteRemaining;
|
||||||
|
|
||||||
UINT8 DeviceControl;
|
UINT8 DeviceControl;
|
||||||
|
|
||||||
VOID *BufferMap;
|
VOID *BufferMap;
|
||||||
|
@ -1373,14 +1484,36 @@ AtaUdmaInOut (
|
||||||
|
|
||||||
UINT8 DeviceHead;
|
UINT8 DeviceHead;
|
||||||
UINT8 AtaCommand;
|
UINT8 AtaCommand;
|
||||||
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||||
|
EFI_TPL OldTpl;
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
PrdBaseAddr = NULL;
|
Status = EFI_SUCCESS;
|
||||||
|
PrdBaseAddr = NULL;
|
||||||
|
PrdTableMap = NULL;
|
||||||
|
BufferMap = NULL;
|
||||||
|
PageCount = 0;
|
||||||
|
PciIo = Instance->PciIo;
|
||||||
|
|
||||||
if ((PciIo == NULL) || (IdeRegisters == NULL) || (DataBuffer == NULL) || (AtaCommandBlock == NULL)) {
|
if ((PciIo == NULL) || (IdeRegisters == NULL) || (DataBuffer == NULL) || (AtaCommandBlock == NULL)) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Before starting the Blocking BlockIO operation, push to finish all non-blocking
|
||||||
|
// BlockIO tasks.
|
||||||
|
// Delay 1ms to simulate the blocking time out checking.
|
||||||
|
//
|
||||||
|
while ((Task == NULL) && (!IsListEmpty (&Instance->NonBlockingTaskList))) {
|
||||||
|
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||||
|
AsyncNonBlockingTransferRoutine (NULL, Instance);
|
||||||
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
//
|
||||||
|
// Stall for 1 milliseconds.
|
||||||
|
//
|
||||||
|
MicroSecondDelay (1000);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// The data buffer should be even alignment
|
// The data buffer should be even alignment
|
||||||
//
|
//
|
||||||
|
@ -1389,163 +1522,187 @@ AtaUdmaInOut (
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Calculate the number of PRD entry.
|
// Set relevant IO Port address.
|
||||||
// Every entry in PRD table can specify a 64K memory region.
|
|
||||||
//
|
//
|
||||||
PrdTableNum = (UINTN)(RShiftU64(DataLength, 16) + 1);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Make sure that the memory region of PRD table is not cross 64K boundary
|
|
||||||
//
|
|
||||||
PrdTableSize = PrdTableNum * sizeof (EFI_ATA_DMA_PRD);
|
|
||||||
if (PrdTableSize > 0x10000) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Allocate buffer for PRD table initialization.
|
|
||||||
//
|
|
||||||
PageCount = EFI_SIZE_TO_PAGES (PrdTableSize);
|
|
||||||
Status = PciIo->AllocateBuffer (
|
|
||||||
PciIo,
|
|
||||||
AllocateAnyPages,
|
|
||||||
EfiBootServicesData,
|
|
||||||
PageCount,
|
|
||||||
(VOID **)&PrdBaseAddr,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteCount = EFI_PAGES_TO_SIZE (PageCount);
|
|
||||||
Status = PciIo->Map (
|
|
||||||
PciIo,
|
|
||||||
EfiPciIoOperationBusMasterCommonBuffer,
|
|
||||||
PrdBaseAddr,
|
|
||||||
&ByteCount,
|
|
||||||
&PrdTableMapAddr,
|
|
||||||
&PrdTableMap
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status) || (ByteCount != EFI_PAGES_TO_SIZE (PageCount))) {
|
|
||||||
//
|
|
||||||
// If the data length actually mapped is not equal to the requested amount,
|
|
||||||
// it means the DMA operation may be broken into several discontinuous smaller chunks.
|
|
||||||
// Can't handle this case.
|
|
||||||
//
|
|
||||||
PciIo->FreeBuffer (PciIo, PageCount, PrdBaseAddr);
|
|
||||||
return EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
ZeroMem ((VOID *) ((UINTN) PrdBaseAddr), ByteCount);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Map the host address of DataBuffer to DMA master address.
|
|
||||||
//
|
|
||||||
if (Read) {
|
|
||||||
PciIoOperation = EfiPciIoOperationBusMasterWrite;
|
|
||||||
} else {
|
|
||||||
PciIoOperation = EfiPciIoOperationBusMasterRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteCount = (UINTN)DataLength;
|
|
||||||
Status = PciIo->Map (
|
|
||||||
PciIo,
|
|
||||||
PciIoOperation,
|
|
||||||
DataBuffer,
|
|
||||||
&ByteCount,
|
|
||||||
&BufferMapAddress,
|
|
||||||
&BufferMap
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status) || (ByteCount != DataLength)) {
|
|
||||||
PciIo->Unmap (PciIo, PrdTableMap);
|
|
||||||
PciIo->FreeBuffer (PciIo, PageCount, PrdBaseAddr);
|
|
||||||
return EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// According to Ata spec, it requires the buffer address and size to be even.
|
|
||||||
//
|
|
||||||
ASSERT ((BufferMapAddress & 0x1) == 0);
|
|
||||||
ASSERT ((ByteCount & 0x1) == 0);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Fill the PRD table with appropriate bus master address of data buffer and data length.
|
|
||||||
//
|
|
||||||
ByteRemaining = ByteCount;
|
|
||||||
while (ByteRemaining != 0) {
|
|
||||||
if (ByteRemaining <= 0x10000) {
|
|
||||||
PrdBaseAddr->RegionBaseAddr = (UINT32) ((UINTN) BufferMapAddress);
|
|
||||||
PrdBaseAddr->ByteCount = (UINT16) ByteRemaining;
|
|
||||||
PrdBaseAddr->EndOfTable = 0x8000;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrdBaseAddr->RegionBaseAddr = (UINT32) ((UINTN) BufferMapAddress);
|
|
||||||
PrdBaseAddr->ByteCount = (UINT16) 0x0;
|
|
||||||
|
|
||||||
ByteRemaining -= 0x10000;
|
|
||||||
BufferMapAddress += 0x10000;
|
|
||||||
PrdBaseAddr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Start to enable the DMA operation
|
|
||||||
//
|
|
||||||
DeviceHead = AtaCommandBlock->AtaDeviceHead;
|
|
||||||
AtaCommand = AtaCommandBlock->AtaCommand;
|
|
||||||
|
|
||||||
IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | DeviceHead));
|
|
||||||
|
|
||||||
//
|
|
||||||
// Enable interrupt to support UDMA
|
|
||||||
//
|
|
||||||
DeviceControl = 0;
|
|
||||||
IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);
|
|
||||||
|
|
||||||
IoPortForBmic = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMIC_OFFSET);
|
IoPortForBmic = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMIC_OFFSET);
|
||||||
IoPortForBmis = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);
|
IoPortForBmis = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);
|
||||||
IoPortForBmid = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMID_OFFSET);
|
IoPortForBmid = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMID_OFFSET);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Read BMIS register and clear ERROR and INTR bit
|
// For Blocking mode, start the command.
|
||||||
//
|
// For non-blocking mode, when the command is not started, start it, otherwise
|
||||||
RegisterValue = IdeReadPortB(PciIo, IoPortForBmis);
|
// go to check the status.
|
||||||
RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
|
//
|
||||||
IdeWritePortB(PciIo, IoPortForBmis, RegisterValue);
|
if (((Task != NULL) && (!Task->IsStart)) || (Task == NULL)) {
|
||||||
|
//
|
||||||
|
// Calculate the number of PRD entry.
|
||||||
|
// Every entry in PRD table can specify a 64K memory region.
|
||||||
|
//
|
||||||
|
PrdTableNum = (UINTN)(RShiftU64(DataLength, 16) + 1);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set the base address to BMID register
|
// Make sure that the memory region of PRD table is not cross 64K boundary
|
||||||
//
|
//
|
||||||
IdeWritePortDW(PciIo, IoPortForBmid, (UINT32)PrdTableMapAddr);
|
PrdTableSize = PrdTableNum * sizeof (EFI_ATA_DMA_PRD);
|
||||||
|
if (PrdTableSize > 0x10000) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set BMIC register to identify the operation direction
|
// Allocate buffer for PRD table initialization.
|
||||||
//
|
//
|
||||||
RegisterValue = IdeReadPortB(PciIo, IoPortForBmic);
|
PageCount = EFI_SIZE_TO_PAGES (PrdTableSize);
|
||||||
if (Read) {
|
Status = PciIo->AllocateBuffer (
|
||||||
RegisterValue |= BMIC_NREAD;
|
PciIo,
|
||||||
} else {
|
AllocateAnyPages,
|
||||||
RegisterValue &= ~((UINT8) BMIC_NREAD);
|
EfiBootServicesData,
|
||||||
|
PageCount,
|
||||||
|
(VOID **)&PrdBaseAddr,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteCount = EFI_PAGES_TO_SIZE (PageCount);
|
||||||
|
Status = PciIo->Map (
|
||||||
|
PciIo,
|
||||||
|
EfiPciIoOperationBusMasterCommonBuffer,
|
||||||
|
PrdBaseAddr,
|
||||||
|
&ByteCount,
|
||||||
|
&PrdTableMapAddr,
|
||||||
|
&PrdTableMap
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status) || (ByteCount != EFI_PAGES_TO_SIZE (PageCount))) {
|
||||||
|
//
|
||||||
|
// If the data length actually mapped is not equal to the requested amount,
|
||||||
|
// it means the DMA operation may be broken into several discontinuous smaller chunks.
|
||||||
|
// Can't handle this case.
|
||||||
|
//
|
||||||
|
PciIo->FreeBuffer (PciIo, PageCount, PrdBaseAddr);
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZeroMem ((VOID *) ((UINTN) PrdBaseAddr), ByteCount);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Map the host address of DataBuffer to DMA master address.
|
||||||
|
//
|
||||||
|
if (Read) {
|
||||||
|
PciIoOperation = EfiPciIoOperationBusMasterWrite;
|
||||||
|
} else {
|
||||||
|
PciIoOperation = EfiPciIoOperationBusMasterRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteCount = (UINTN)DataLength;
|
||||||
|
Status = PciIo->Map (
|
||||||
|
PciIo,
|
||||||
|
PciIoOperation,
|
||||||
|
DataBuffer,
|
||||||
|
&ByteCount,
|
||||||
|
&BufferMapAddress,
|
||||||
|
&BufferMap
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status) || (ByteCount != DataLength)) {
|
||||||
|
PciIo->Unmap (PciIo, PrdTableMap);
|
||||||
|
PciIo->FreeBuffer (PciIo, PageCount, PrdBaseAddr);
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// According to Ata spec, it requires the buffer address and size to be even.
|
||||||
|
//
|
||||||
|
ASSERT ((BufferMapAddress & 0x1) == 0);
|
||||||
|
ASSERT ((ByteCount & 0x1) == 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fill the PRD table with appropriate bus master address of data buffer and data length.
|
||||||
|
//
|
||||||
|
ByteRemaining = ByteCount;
|
||||||
|
while (ByteRemaining != 0) {
|
||||||
|
if (ByteRemaining <= 0x10000) {
|
||||||
|
PrdBaseAddr->RegionBaseAddr = (UINT32) ((UINTN) BufferMapAddress);
|
||||||
|
PrdBaseAddr->ByteCount = (UINT16) ByteRemaining;
|
||||||
|
PrdBaseAddr->EndOfTable = 0x8000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrdBaseAddr->RegionBaseAddr = (UINT32) ((UINTN) BufferMapAddress);
|
||||||
|
PrdBaseAddr->ByteCount = (UINT16) 0x0;
|
||||||
|
|
||||||
|
ByteRemaining -= 0x10000;
|
||||||
|
BufferMapAddress += 0x10000;
|
||||||
|
PrdBaseAddr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start to enable the DMA operation
|
||||||
|
//
|
||||||
|
DeviceHead = AtaCommandBlock->AtaDeviceHead;
|
||||||
|
AtaCommand = AtaCommandBlock->AtaCommand;
|
||||||
|
|
||||||
|
IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | DeviceHead));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Enable interrupt to support UDMA
|
||||||
|
//
|
||||||
|
DeviceControl = 0;
|
||||||
|
IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read BMIS register and clear ERROR and INTR bit
|
||||||
|
//
|
||||||
|
RegisterValue = IdeReadPortB(PciIo, IoPortForBmis);
|
||||||
|
RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
|
||||||
|
IdeWritePortB(PciIo, IoPortForBmis, RegisterValue);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set the base address to BMID register
|
||||||
|
//
|
||||||
|
IdeWritePortDW (PciIo, IoPortForBmid, (UINT32)PrdTableMapAddr);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set BMIC register to identify the operation direction
|
||||||
|
//
|
||||||
|
RegisterValue = IdeReadPortB(PciIo, IoPortForBmic);
|
||||||
|
if (Read) {
|
||||||
|
RegisterValue |= BMIC_NREAD;
|
||||||
|
} else {
|
||||||
|
RegisterValue &= ~((UINT8) BMIC_NREAD);
|
||||||
|
}
|
||||||
|
IdeWritePortB (PciIo, IoPortForBmic, RegisterValue);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Issue ATA command
|
||||||
|
//
|
||||||
|
Status = AtaIssueCommand (PciIo, IdeRegisters, AtaCommandBlock, Timeout);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
Status = EFI_DEVICE_ERROR;
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set START bit of BMIC register
|
||||||
|
//
|
||||||
|
RegisterValue = IdeReadPortB(PciIo, IoPortForBmic);
|
||||||
|
RegisterValue |= BMIC_START;
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
IdeWritePortB(PciIo, IoPortForBmic, RegisterValue);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Issue ATA command
|
|
||||||
//
|
|
||||||
Status = AtaIssueCommand (PciIo, IdeRegisters, AtaCommandBlock, Timeout);
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
Status = EFI_DEVICE_ERROR;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set START bit of BMIC register
|
|
||||||
//
|
|
||||||
RegisterValue = IdeReadPortB(PciIo, IoPortForBmic);
|
|
||||||
RegisterValue |= BMIC_START;
|
|
||||||
IdeWritePortB(PciIo, IoPortForBmic, RegisterValue);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check the INTERRUPT and ERROR bit of BMIS
|
// Check the INTERRUPT and ERROR bit of BMIS
|
||||||
|
@ -1553,70 +1710,72 @@ AtaUdmaInOut (
|
||||||
// it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
|
// 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.
|
// So set the variable Count to 2000, for about 2 second Timeout time.
|
||||||
//
|
//
|
||||||
Timeout = 2000;
|
if (Task != NULL) {
|
||||||
while (TRUE) {
|
Status = AtaUdmStatusCheck (PciIo, Task, IoPortForBmis);
|
||||||
RegisterValue = IdeReadPortB(PciIo, IoPortForBmis);
|
} else {
|
||||||
|
Status = AtaUdmStatusWait (PciIo, IoPortForBmis);
|
||||||
if (((RegisterValue & BMIS_ERROR) != 0) || (Timeout == 0)) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "ATA UDMA operation fails\n"));
|
|
||||||
Status = EFI_DEVICE_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((RegisterValue & BMIS_INTERRUPT) != 0) {
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// Stall for 1 milliseconds.
|
|
||||||
//
|
|
||||||
MicroSecondDelay (1000);
|
|
||||||
Timeout--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Read BMIS register and clear ERROR and INTR bit
|
// For blocking mode, clear registers and free buffers.
|
||||||
|
// For non blocking mode, when the related registers have been set or time
|
||||||
|
// out, or a error has been happened, it needs to clear the register and free
|
||||||
|
// buffer.
|
||||||
//
|
//
|
||||||
RegisterValue = IdeReadPortB(PciIo, IoPortForBmis);
|
if ((Task == NULL) || Status != EFI_NOT_READY) {
|
||||||
RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
|
//
|
||||||
IdeWritePortB(PciIo, IoPortForBmis, RegisterValue);
|
// Read BMIS register and clear ERROR and INTR bit
|
||||||
|
//
|
||||||
|
RegisterValue = IdeReadPortB (PciIo, IoPortForBmis);
|
||||||
|
RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
|
||||||
|
IdeWritePortB (PciIo, IoPortForBmis, RegisterValue);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Read Status Register of IDE device to clear interrupt
|
// Read Status Register of IDE device to clear interrupt
|
||||||
//
|
//
|
||||||
RegisterValue = IdeReadPortB(PciIo, IdeRegisters->CmdOrStatus);
|
RegisterValue = IdeReadPortB(PciIo, IdeRegisters->CmdOrStatus);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Clear START bit of BMIC register
|
// Clear START bit of BMIC register
|
||||||
//
|
//
|
||||||
RegisterValue = IdeReadPortB(PciIo, IoPortForBmic);
|
RegisterValue = IdeReadPortB(PciIo, IoPortForBmic);
|
||||||
RegisterValue &= ~((UINT8) BMIC_START);
|
RegisterValue &= ~((UINT8) BMIC_START);
|
||||||
IdeWritePortB(PciIo, IoPortForBmic, RegisterValue);
|
IdeWritePortB (PciIo, IoPortForBmic, RegisterValue);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Disable interrupt of Select device
|
// Disable interrupt of Select device
|
||||||
//
|
//
|
||||||
DeviceControl = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
|
DeviceControl = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
|
||||||
DeviceControl |= ATA_CTLREG_IEN_L;
|
DeviceControl |= ATA_CTLREG_IEN_L;
|
||||||
IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);
|
IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);
|
||||||
//
|
//
|
||||||
// Stall for 10 milliseconds.
|
// Stall for 10 milliseconds.
|
||||||
//
|
//
|
||||||
MicroSecondDelay (10000);
|
MicroSecondDelay (10000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
//
|
//
|
||||||
// Free all allocated resource
|
// Free all allocated resource
|
||||||
//
|
//
|
||||||
PciIo->Unmap (PciIo, PrdTableMap);
|
if ((Task == NULL) || Status != EFI_NOT_READY) {
|
||||||
PciIo->FreeBuffer (PciIo, PageCount, PrdBaseAddr);
|
if (Task != NULL) {
|
||||||
PciIo->Unmap (PciIo, BufferMap);
|
PciIo->Unmap (PciIo, Task->TableMap);
|
||||||
|
PciIo->FreeBuffer (PciIo, Task->PageCount, Task->MapBaseAddress);
|
||||||
//
|
PciIo->Unmap (PciIo, Task->Map);
|
||||||
// Dump All Ide registers to ATA_STATUS_BLOCK
|
} else {
|
||||||
//
|
PciIo->Unmap (PciIo, PrdTableMap);
|
||||||
DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);
|
PciIo->FreeBuffer (PciIo, PageCount, PrdBaseAddr);
|
||||||
|
PciIo->Unmap (PciIo, BufferMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Dump All Ide registers to ATA_STATUS_BLOCK
|
||||||
|
//
|
||||||
|
DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2021,7 +2180,8 @@ SetDeviceTransferMode (
|
||||||
&Instance->IdeRegisters[Channel],
|
&Instance->IdeRegisters[Channel],
|
||||||
&AtaCommandBlock,
|
&AtaCommandBlock,
|
||||||
AtaStatusBlock,
|
AtaStatusBlock,
|
||||||
ATA_ATAPI_TIMEOUT
|
ATA_ATAPI_TIMEOUT,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -2069,7 +2229,8 @@ SetDriveParameters (
|
||||||
&Instance->IdeRegisters[Channel],
|
&Instance->IdeRegisters[Channel],
|
||||||
&AtaCommandBlock,
|
&AtaCommandBlock,
|
||||||
AtaStatusBlock,
|
AtaStatusBlock,
|
||||||
ATA_ATAPI_TIMEOUT
|
ATA_ATAPI_TIMEOUT,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -2084,7 +2245,8 @@ SetDriveParameters (
|
||||||
&Instance->IdeRegisters[Channel],
|
&Instance->IdeRegisters[Channel],
|
||||||
&AtaCommandBlock,
|
&AtaCommandBlock,
|
||||||
AtaStatusBlock,
|
AtaStatusBlock,
|
||||||
ATA_ATAPI_TIMEOUT
|
ATA_ATAPI_TIMEOUT,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -2132,7 +2294,8 @@ IdeAtaSmartReturnStatusCheck (
|
||||||
&Instance->IdeRegisters[Channel],
|
&Instance->IdeRegisters[Channel],
|
||||||
&AtaCommandBlock,
|
&AtaCommandBlock,
|
||||||
AtaStatusBlock,
|
AtaStatusBlock,
|
||||||
ATA_ATAPI_TIMEOUT
|
ATA_ATAPI_TIMEOUT,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
@ -2212,7 +2375,8 @@ IdeAtaSmartSupport (
|
||||||
&Instance->IdeRegisters[Channel],
|
&Instance->IdeRegisters[Channel],
|
||||||
&AtaCommandBlock,
|
&AtaCommandBlock,
|
||||||
AtaStatusBlock,
|
AtaStatusBlock,
|
||||||
ATA_ATAPI_TIMEOUT
|
ATA_ATAPI_TIMEOUT,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
|
@ -2233,7 +2397,8 @@ IdeAtaSmartSupport (
|
||||||
&Instance->IdeRegisters[Channel],
|
&Instance->IdeRegisters[Channel],
|
||||||
&AtaCommandBlock,
|
&AtaCommandBlock,
|
||||||
AtaStatusBlock,
|
AtaStatusBlock,
|
||||||
ATA_ATAPI_TIMEOUT
|
ATA_ATAPI_TIMEOUT,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
Status = IdeAtaSmartReturnStatusCheck (
|
Status = IdeAtaSmartReturnStatusCheck (
|
||||||
|
@ -2254,6 +2419,7 @@ IdeAtaSmartSupport (
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sends out an ATA Identify Command to the specified device.
|
Sends out an ATA Identify Command to the specified device.
|
||||||
|
|
||||||
|
@ -2274,6 +2440,7 @@ IdeAtaSmartSupport (
|
||||||
@retval EFI_SUCCESS Identify ATA device successfully.
|
@retval EFI_SUCCESS Identify ATA device successfully.
|
||||||
@retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.
|
@retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.
|
||||||
@retval EFI_OUT_OF_RESOURCES Allocate memory failed.
|
@retval EFI_OUT_OF_RESOURCES Allocate memory failed.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
|
@ -2286,10 +2453,10 @@ AtaIdentify (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
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_DRIVE;
|
AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DRIVE;
|
||||||
AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
|
AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
|
||||||
|
|
||||||
|
@ -2301,7 +2468,8 @@ AtaIdentify (
|
||||||
TRUE,
|
TRUE,
|
||||||
&AtaCommandBlock,
|
&AtaCommandBlock,
|
||||||
AtaStatusBlock,
|
AtaStatusBlock,
|
||||||
ATA_ATAPI_TIMEOUT
|
ATA_ATAPI_TIMEOUT,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -2368,7 +2536,8 @@ AtaIdentifyPacket (
|
||||||
TRUE,
|
TRUE,
|
||||||
&AtaCommandBlock,
|
&AtaCommandBlock,
|
||||||
AtaStatusBlock,
|
AtaStatusBlock,
|
||||||
ATA_ATAPI_TIMEOUT
|
ATA_ATAPI_TIMEOUT,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -2425,7 +2594,7 @@ DetectAndConfigIdeDevice (
|
||||||
IdeInit = Instance->IdeControllerInit;
|
IdeInit = Instance->IdeControllerInit;
|
||||||
PciIo = Instance->PciIo;
|
PciIo = Instance->PciIo;
|
||||||
|
|
||||||
for (IdeDevice = 0; IdeDevice < EfiIdeMaxDevice; IdeDevice++) {
|
for (IdeDevice = 0; IdeDevice < EfiIdeMaxDevice; IdeDevice++) {
|
||||||
//
|
//
|
||||||
// Send ATA Device Execut Diagnostic command.
|
// Send ATA Device Execut Diagnostic command.
|
||||||
// This command should work no matter DRDY is ready or not
|
// This command should work no matter DRDY is ready or not
|
||||||
|
@ -2483,7 +2652,7 @@ DetectAndConfigIdeDevice (
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
DeviceType = EfiIdeHarddisk;
|
DeviceType = EfiIdeHarddisk;
|
||||||
Status = AtaIdentify (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
|
Status = AtaIdentify (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
@ -2491,12 +2660,11 @@ DetectAndConfigIdeDevice (
|
||||||
// No device is found at this port
|
// No device is found at this port
|
||||||
//
|
//
|
||||||
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"));
|
||||||
|
|
||||||
//
|
//
|
||||||
// If the device is a hard disk, then try to enable S.M.A.R.T feature
|
// If the device is a hard disk, then try to enable S.M.A.R.T feature
|
||||||
//
|
//
|
||||||
|
@ -2548,7 +2716,7 @@ DetectAndConfigIdeDevice (
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
|
// Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
|
||||||
// be set together. Only one DMA mode can be set to a device. If setting
|
// be set together. Only one DMA mode can be set to a device. If setting
|
||||||
|
@ -2559,7 +2727,7 @@ DetectAndConfigIdeDevice (
|
||||||
TransferMode.ModeCategory = EFI_ATA_MODE_UDMA;
|
TransferMode.ModeCategory = EFI_ATA_MODE_UDMA;
|
||||||
TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode);
|
TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode);
|
||||||
Status = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);
|
Status = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
DEBUG ((EFI_D_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
|
DEBUG ((EFI_D_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
|
||||||
continue;
|
continue;
|
||||||
|
@ -2568,13 +2736,13 @@ DetectAndConfigIdeDevice (
|
||||||
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 = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);
|
Status = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
DEBUG ((EFI_D_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
|
DEBUG ((EFI_D_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set Parameters for the device:
|
// Set Parameters for the device:
|
||||||
// 1) Init
|
// 1) Init
|
||||||
|
@ -2587,10 +2755,10 @@ DetectAndConfigIdeDevice (
|
||||||
DriveParameters.Sector = (UINT8) ((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->sectors_per_track;
|
DriveParameters.Sector = (UINT8) ((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->sectors_per_track;
|
||||||
DriveParameters.Heads = (UINT8) (((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->heads - 1);
|
DriveParameters.Heads = (UINT8) (((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->heads - 1);
|
||||||
DriveParameters.MultipleSector = (UINT8) ((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->multi_sector_cmd_max_sct_cnt;
|
DriveParameters.MultipleSector = (UINT8) ((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->multi_sector_cmd_max_sct_cnt;
|
||||||
|
|
||||||
Status = SetDriveParameters (Instance, IdeChannel, IdeDevice, &DriveParameters, NULL);
|
Status = SetDriveParameters (Instance, IdeChannel, IdeDevice, &DriveParameters, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set IDE controller Timing Blocks in the PCI Configuration Space
|
// Set IDE controller Timing Blocks in the PCI Configuration Space
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Header file for IDE mode of ATA host controller.
|
Header file for IDE 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
|
||||||
|
@ -200,94 +200,5 @@ AtaPacketCommandExecute (
|
||||||
IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
|
IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
Send ATA command into device with NON_DATA protocol
|
|
||||||
|
|
||||||
@param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
|
|
||||||
@param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
|
|
||||||
@param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
|
|
||||||
@param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
|
|
||||||
@param Timeout The time to complete the command.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Reading succeed
|
|
||||||
@retval EFI_ABORTED Command failed
|
|
||||||
@retval EFI_DEVICE_ERROR Device status error.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
AtaNonDataCommandIn (
|
|
||||||
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
|
||||||
IN EFI_IDE_REGISTERS *IdeRegisters,
|
|
||||||
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
|
|
||||||
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
|
|
||||||
IN UINT64 Timeout
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
|
|
||||||
|
|
||||||
@param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
|
|
||||||
@param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
|
|
||||||
@param Read Flag used to determine the data transfer direction.
|
|
||||||
Read equals 1, means data transferred from device to host;
|
|
||||||
Read equals 0, means data transferred from host to device.
|
|
||||||
@param DataBuffer A pointer to the source buffer for the data.
|
|
||||||
@param DataLength The length of the data.
|
|
||||||
@param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
|
|
||||||
@param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
|
|
||||||
@param Timeout The time to complete the command.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS the operation is successful.
|
|
||||||
@retval EFI_OUT_OF_RESOURCES Build PRD table failed
|
|
||||||
@retval EFI_UNSUPPORTED Unknown channel or operations command
|
|
||||||
@retval EFI_DEVICE_ERROR Ata command execute failed
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
AtaUdmaInOut (
|
|
||||||
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
|
||||||
IN EFI_IDE_REGISTERS *IdeRegisters,
|
|
||||||
IN BOOLEAN Read,
|
|
||||||
IN VOID *DataBuffer,
|
|
||||||
IN UINT64 DataLength,
|
|
||||||
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
|
|
||||||
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
|
|
||||||
IN UINT64 Timeout
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
This function is used to send out ATA commands conforms to the PIO Data In Protocol.
|
|
||||||
|
|
||||||
@param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
|
|
||||||
@param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
|
|
||||||
@param Buffer A pointer to the source buffer for the data.
|
|
||||||
@param ByteCount The length of the data.
|
|
||||||
@param Read Flag used to determine the data transfer direction.
|
|
||||||
Read equals 1, means data transferred from device to host;
|
|
||||||
Read equals 0, means data transferred from host to device.
|
|
||||||
@param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
|
|
||||||
@param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
|
|
||||||
@param Timeout The time to complete the command.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS send out the ATA command and device send required data successfully.
|
|
||||||
@retval EFI_DEVICE_ERROR command sent failed.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
AtaPioDataInOut (
|
|
||||||
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
|
||||||
IN EFI_IDE_REGISTERS *IdeRegisters,
|
|
||||||
IN OUT VOID *Buffer,
|
|
||||||
IN UINT64 ByteCount,
|
|
||||||
IN BOOLEAN Read,
|
|
||||||
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
|
|
||||||
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
|
|
||||||
IN UINT64 Timeout
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,13 @@ ATA_DEVICE gAtaDeviceTemplate = {
|
||||||
AtaBlockIoWriteBlocks,
|
AtaBlockIoWriteBlocks,
|
||||||
AtaBlockIoFlushBlocks
|
AtaBlockIoFlushBlocks
|
||||||
},
|
},
|
||||||
|
{ // BlockIo2
|
||||||
|
NULL,
|
||||||
|
AtaBlockIoResetEx,
|
||||||
|
AtaBlockIoReadBlocksEx,
|
||||||
|
AtaBlockIoWriteBlocksEx,
|
||||||
|
AtaBlockIoFlushBlocksEx
|
||||||
|
},
|
||||||
{ // BlockMedia
|
{ // BlockMedia
|
||||||
0, // MediaId
|
0, // MediaId
|
||||||
FALSE, // RemovableMedia
|
FALSE, // RemovableMedia
|
||||||
|
@ -75,7 +82,8 @@ ATA_DEVICE gAtaDeviceTemplate = {
|
||||||
FALSE, // Lba48Bit
|
FALSE, // Lba48Bit
|
||||||
NULL, // IdentifyData
|
NULL, // IdentifyData
|
||||||
NULL, // ControllerNameTable
|
NULL, // ControllerNameTable
|
||||||
{L'\0', } // ModelName
|
{L'\0', }, // ModelName
|
||||||
|
{NULL, NULL} // AtaTaskList
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -135,12 +143,34 @@ ReleaseAtaResources (
|
||||||
IN ATA_DEVICE *AtaDevice
|
IN ATA_DEVICE *AtaDevice
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
ATA_BUS_ASYN_TASK *Task;
|
||||||
|
LIST_ENTRY *Entry;
|
||||||
|
LIST_ENTRY *DelEntry;
|
||||||
|
EFI_TPL OldTpl;
|
||||||
|
|
||||||
FreeUnicodeStringTable (AtaDevice->ControllerNameTable);
|
FreeUnicodeStringTable (AtaDevice->ControllerNameTable);
|
||||||
FreeAlignedBuffer (AtaDevice->Asb, sizeof (*AtaDevice->Asb));
|
FreeAlignedBuffer (AtaDevice->Asb, sizeof (*AtaDevice->Asb));
|
||||||
FreeAlignedBuffer (AtaDevice->IdentifyData, sizeof (*AtaDevice->IdentifyData));
|
FreeAlignedBuffer (AtaDevice->IdentifyData, sizeof (*AtaDevice->IdentifyData));
|
||||||
if (AtaDevice->DevicePath != NULL) {
|
if (AtaDevice->DevicePath != NULL) {
|
||||||
FreePool (AtaDevice->DevicePath);
|
FreePool (AtaDevice->DevicePath);
|
||||||
}
|
}
|
||||||
|
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||||
|
if (!IsListEmpty (&AtaDevice->AtaTaskList)) {
|
||||||
|
//
|
||||||
|
// Free the Subtask list.
|
||||||
|
//
|
||||||
|
for(Entry = (&AtaDevice->AtaTaskList)->ForwardLink;
|
||||||
|
Entry != (&AtaDevice->AtaTaskList);
|
||||||
|
) {
|
||||||
|
DelEntry = Entry;
|
||||||
|
Entry = Entry->ForwardLink;
|
||||||
|
Task = ATA_AYNS_TASK_FROM_ENTRY (DelEntry);
|
||||||
|
|
||||||
|
RemoveEntryList (DelEntry);
|
||||||
|
FreeAtaSubTask (Task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gBS->RestoreTPL (OldTpl);
|
||||||
FreePool (AtaDevice);
|
FreePool (AtaDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,10 +248,11 @@ RegisterAtaDevice (
|
||||||
//
|
//
|
||||||
// Initializes ATA device structures and allocates the required buffer.
|
// Initializes ATA device structures and allocates the required buffer.
|
||||||
//
|
//
|
||||||
AtaDevice->BlockIo.Media = &AtaDevice->BlockMedia;
|
AtaDevice->BlockIo.Media = &AtaDevice->BlockMedia;
|
||||||
AtaDevice->AtaBusDriverData = AtaBusDriverData;
|
AtaDevice->BlockIo2.Media = &AtaDevice->BlockMedia;
|
||||||
AtaDevice->DevicePath = DevicePath;
|
AtaDevice->AtaBusDriverData = AtaBusDriverData;
|
||||||
AtaDevice->Port = Port;
|
AtaDevice->DevicePath = DevicePath;
|
||||||
|
AtaDevice->Port = Port;
|
||||||
AtaDevice->PortMultiplierPort = PortMultiplierPort;
|
AtaDevice->PortMultiplierPort = PortMultiplierPort;
|
||||||
AtaDevice->Asb = AllocateAlignedBuffer (AtaDevice, sizeof (*AtaDevice->Asb));
|
AtaDevice->Asb = AllocateAlignedBuffer (AtaDevice, sizeof (*AtaDevice->Asb));
|
||||||
if (AtaDevice->Asb == NULL) {
|
if (AtaDevice->Asb == NULL) {
|
||||||
|
@ -234,6 +265,11 @@ RegisterAtaDevice (
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initial Ata Task List
|
||||||
|
//
|
||||||
|
InitializeListHead (&AtaDevice->AtaTaskList);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Try to identify the ATA device via the ATA pass through command.
|
// Try to identify the ATA device via the ATA pass through command.
|
||||||
//
|
//
|
||||||
|
@ -241,7 +277,7 @@ RegisterAtaDevice (
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Build controller name for Component Name (2) protocol.
|
// Build controller name for Component Name (2) protocol.
|
||||||
//
|
//
|
||||||
|
@ -281,6 +317,8 @@ RegisterAtaDevice (
|
||||||
AtaDevice->DevicePath,
|
AtaDevice->DevicePath,
|
||||||
&gEfiBlockIoProtocolGuid,
|
&gEfiBlockIoProtocolGuid,
|
||||||
&AtaDevice->BlockIo,
|
&AtaDevice->BlockIo,
|
||||||
|
&gEfiBlockIo2ProtocolGuid,
|
||||||
|
&AtaDevice->BlockIo2,
|
||||||
&gEfiDiskInfoProtocolGuid,
|
&gEfiDiskInfoProtocolGuid,
|
||||||
&AtaDevice->DiskInfo,
|
&AtaDevice->DiskInfo,
|
||||||
NULL
|
NULL
|
||||||
|
@ -334,8 +372,11 @@ UnregisterAtaDevice (
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_BLOCK_IO_PROTOCOL *BlockIo;
|
EFI_BLOCK_IO_PROTOCOL *BlockIo;
|
||||||
|
EFI_BLOCK_IO2_PROTOCOL *BlockIo2;
|
||||||
ATA_DEVICE *AtaDevice;
|
ATA_DEVICE *AtaDevice;
|
||||||
EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;
|
EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;
|
||||||
|
BlockIo2 = NULL;
|
||||||
|
BlockIo = NULL;
|
||||||
|
|
||||||
Status = gBS->OpenProtocol (
|
Status = gBS->OpenProtocol (
|
||||||
Handle,
|
Handle,
|
||||||
|
@ -346,10 +387,30 @@ UnregisterAtaDevice (
|
||||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
//
|
||||||
|
// Locate BlockIo2 protocol
|
||||||
|
//
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
Handle,
|
||||||
|
&gEfiBlockIo2ProtocolGuid,
|
||||||
|
(VOID **) &BlockIo2,
|
||||||
|
This->DriverBindingHandle,
|
||||||
|
Controller,
|
||||||
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AtaDevice = ATA_DEVICE_FROM_BLOCK_IO (BlockIo);
|
//
|
||||||
|
// Get AtaDevice data.
|
||||||
|
//
|
||||||
|
if (BlockIo != NULL) {
|
||||||
|
AtaDevice = ATA_DEVICE_FROM_BLOCK_IO (BlockIo);
|
||||||
|
} else {
|
||||||
|
AtaDevice = ATA_DEVICE_FROM_BLOCK_IO2 (BlockIo2);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Close the child handle
|
// Close the child handle
|
||||||
|
@ -361,12 +422,18 @@ UnregisterAtaDevice (
|
||||||
Handle
|
Handle
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// The Ata Bus driver installs the BlockIo and BlockIo2 in the DriverBindingStart().
|
||||||
|
// Here should uninstall both of them.
|
||||||
|
//
|
||||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||||
Handle,
|
Handle,
|
||||||
&gEfiDevicePathProtocolGuid,
|
&gEfiDevicePathProtocolGuid,
|
||||||
AtaDevice->DevicePath,
|
AtaDevice->DevicePath,
|
||||||
&gEfiBlockIoProtocolGuid,
|
&gEfiBlockIoProtocolGuid,
|
||||||
&AtaDevice->BlockIo,
|
&AtaDevice->BlockIo,
|
||||||
|
&gEfiBlockIo2ProtocolGuid,
|
||||||
|
&AtaDevice->BlockIo2,
|
||||||
&gEfiDiskInfoProtocolGuid,
|
&gEfiDiskInfoProtocolGuid,
|
||||||
&AtaDevice->DiskInfo,
|
&AtaDevice->DiskInfo,
|
||||||
NULL
|
NULL
|
||||||
|
@ -385,7 +452,6 @@ UnregisterAtaDevice (
|
||||||
}
|
}
|
||||||
|
|
||||||
ReleaseAtaResources (AtaDevice);
|
ReleaseAtaResources (AtaDevice);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,7 +512,7 @@ AtaBusDriverBindingSupported (
|
||||||
EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;
|
EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru;
|
||||||
UINT16 Port;
|
UINT16 Port;
|
||||||
UINT16 PortMultiplierPort;
|
UINT16 PortMultiplierPort;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Test EFI_ATA_PASS_THRU_PROTOCOL on controller handle.
|
// Test EFI_ATA_PASS_THRU_PROTOCOL on controller handle.
|
||||||
//
|
//
|
||||||
|
@ -522,7 +588,7 @@ AtaBusDriverBindingSupported (
|
||||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||||
parameter is ignored by device drivers, and is optional for bus
|
parameter is ignored by device drivers, and is optional for bus
|
||||||
drivers. For a bus driver, if this parameter is NULL, then handles
|
drivers. For a bus driver, if this parameter is NULL, then handles
|
||||||
for all the children of Controller are created by this driver.
|
for all the children of Controller are created by this driver.
|
||||||
If this parameter is not NULL and the first Device Path Node is
|
If this parameter is not NULL and the first Device Path Node is
|
||||||
not the End of Device Path Node, then only the handle for the
|
not the End of Device Path Node, then only the handle for the
|
||||||
child device specified by the first Device Path Node of
|
child device specified by the first Device Path Node of
|
||||||
|
@ -589,7 +655,7 @@ AtaBusDriverBindingStart (
|
||||||
}
|
}
|
||||||
|
|
||||||
AtaBusDriverData->AtaPassThru = AtaPassThru;
|
AtaBusDriverData->AtaPassThru = AtaPassThru;
|
||||||
AtaBusDriverData->Controller = Controller;
|
AtaBusDriverData->Controller = Controller;
|
||||||
AtaBusDriverData->ParentDevicePath = ParentDevicePath;
|
AtaBusDriverData->ParentDevicePath = ParentDevicePath;
|
||||||
AtaBusDriverData->DriverBindingHandle = This->DriverBindingHandle;
|
AtaBusDriverData->DriverBindingHandle = This->DriverBindingHandle;
|
||||||
|
|
||||||
|
@ -628,7 +694,7 @@ AtaBusDriverBindingStart (
|
||||||
//
|
//
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
PortMultiplierPort = 0xFFFF;
|
PortMultiplierPort = 0xFFFF;
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
Status = AtaPassThru->GetNextDevice (AtaPassThru, Port, &PortMultiplierPort);
|
Status = AtaPassThru->GetNextDevice (AtaPassThru, Port, &PortMultiplierPort);
|
||||||
|
@ -649,7 +715,7 @@ AtaBusDriverBindingStart (
|
||||||
Status = RegisterAtaDevice (AtaBusDriverData,Port, PortMultiplierPort);
|
Status = RegisterAtaDevice (AtaBusDriverData,Port, PortMultiplierPort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
|
||||||
ErrorExit:
|
ErrorExit:
|
||||||
|
@ -789,7 +855,7 @@ AtaBlockIoReset (
|
||||||
|
|
||||||
AtaDevice = ATA_DEVICE_FROM_BLOCK_IO (This);
|
AtaDevice = ATA_DEVICE_FROM_BLOCK_IO (This);
|
||||||
|
|
||||||
Status = ResetAtaDevice (AtaDevice);
|
Status = ResetAtaDevice (AtaDevice);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
Status = EFI_DEVICE_ERROR;
|
Status = EFI_DEVICE_ERROR;
|
||||||
|
@ -803,13 +869,18 @@ AtaBlockIoReset (
|
||||||
/**
|
/**
|
||||||
Read/Write BufferSize bytes from Lba from/into Buffer.
|
Read/Write BufferSize bytes from Lba from/into Buffer.
|
||||||
|
|
||||||
@param This Indicates a pointer to the calling context.
|
@param[in] This Indicates a pointer to the calling context. Either be
|
||||||
@param MediaId The media ID that the read/write request is for.
|
block I/O or block I/O2.
|
||||||
@param Lba The starting logical block address to be read/written. The caller is
|
@param[in] MediaId The media ID that the read/write request is for.
|
||||||
responsible for reading/writing to only legitimate locations.
|
@param[in] Lba The starting logical block address to be read/written.
|
||||||
@param BufferSize Size of Buffer, must be a multiple of device block size.
|
The caller is responsible for reading/writing to only
|
||||||
@param Buffer A pointer to the destination/source buffer for the data.
|
legitimate locations.
|
||||||
@param IsWrite Indicates whether it is a write operation.
|
@param[in, out] Token A pointer to the token associated with the transaction.
|
||||||
|
@param[in] BufferSize Size of Buffer, must be a multiple of device block size.
|
||||||
|
@param[out] Buffer A pointer to the destination/source buffer for the data.
|
||||||
|
@param[in] IsBlockIo2 Indicate the calling is from BlockIO or BlockIO2. TURE is
|
||||||
|
from BlockIO2, FALSE is for BlockIO.
|
||||||
|
@param[in] IsWrite Indicates whether it is a write operation.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The data was read/written correctly to the device.
|
@retval EFI_SUCCESS The data was read/written correctly to the device.
|
||||||
@retval EFI_WRITE_PROTECTED The device can not be read/written to.
|
@retval EFI_WRITE_PROTECTED The device can not be read/written to.
|
||||||
|
@ -823,12 +894,14 @@ AtaBlockIoReset (
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
BlockIoReadWrite (
|
BlockIoReadWrite (
|
||||||
IN EFI_BLOCK_IO_PROTOCOL *This,
|
IN VOID *This,
|
||||||
IN UINT32 MediaId,
|
IN UINT32 MediaId,
|
||||||
IN EFI_LBA Lba,
|
IN EFI_LBA Lba,
|
||||||
IN UINTN BufferSize,
|
IN OUT EFI_BLOCK_IO2_TOKEN *Token,
|
||||||
OUT VOID *Buffer,
|
IN UINTN BufferSize,
|
||||||
IN BOOLEAN IsWrite
|
OUT VOID *Buffer,
|
||||||
|
IN BOOLEAN IsBlockIo2,
|
||||||
|
IN BOOLEAN IsWrite
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ATA_DEVICE *AtaDevice;
|
ATA_DEVICE *AtaDevice;
|
||||||
|
@ -839,21 +912,28 @@ BlockIoReadWrite (
|
||||||
UINTN NumberOfBlocks;
|
UINTN NumberOfBlocks;
|
||||||
UINTN IoAlign;
|
UINTN IoAlign;
|
||||||
|
|
||||||
//
|
if (IsBlockIo2) {
|
||||||
// Check parameters.
|
Media = ((EFI_BLOCK_IO2_PROTOCOL *) This)->Media;
|
||||||
//
|
AtaDevice = ATA_DEVICE_FROM_BLOCK_IO2 (This);
|
||||||
Media = This->Media;
|
} else {
|
||||||
|
Media = ((EFI_BLOCK_IO_PROTOCOL *) This)->Media;
|
||||||
|
AtaDevice = ATA_DEVICE_FROM_BLOCK_IO (This);
|
||||||
|
}
|
||||||
|
|
||||||
if (MediaId != Media->MediaId) {
|
if (MediaId != Media->MediaId) {
|
||||||
return EFI_MEDIA_CHANGED;
|
return EFI_MEDIA_CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check parameters.
|
||||||
|
//
|
||||||
if (Buffer == NULL) {
|
if (Buffer == NULL) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BufferSize == 0) {
|
if (BufferSize == 0) {
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockSize = Media->BlockSize;
|
BlockSize = Media->BlockSize;
|
||||||
if ((BufferSize % BlockSize) != 0) {
|
if ((BufferSize % BlockSize) != 0) {
|
||||||
|
@ -871,13 +951,11 @@ BlockIoReadWrite (
|
||||||
}
|
}
|
||||||
|
|
||||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||||
|
|
||||||
AtaDevice = ATA_DEVICE_FROM_BLOCK_IO (This);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Invoke low level AtaDevice Access Routine.
|
// Invoke low level AtaDevice Access Routine.
|
||||||
//
|
//
|
||||||
Status = AccessAtaDevice (AtaDevice, Buffer, Lba, NumberOfBlocks, IsWrite);
|
Status = AccessAtaDevice (AtaDevice, Buffer, Lba, NumberOfBlocks, IsWrite, Token);
|
||||||
|
|
||||||
gBS->RestoreTPL (OldTpl);
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
|
||||||
|
@ -914,7 +992,7 @@ AtaBlockIoReadBlocks (
|
||||||
OUT VOID *Buffer
|
OUT VOID *Buffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return BlockIoReadWrite (This, MediaId, Lba, BufferSize, Buffer, FALSE);
|
return BlockIoReadWrite ((VOID *) This, MediaId, Lba, NULL, BufferSize, Buffer, FALSE, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -948,7 +1026,7 @@ AtaBlockIoWriteBlocks (
|
||||||
IN VOID *Buffer
|
IN VOID *Buffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return BlockIoReadWrite (This, MediaId, Lba, BufferSize, Buffer, TRUE);
|
return BlockIoReadWrite ((VOID *) This, MediaId, Lba, NULL, BufferSize, Buffer, FALSE, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -974,7 +1052,147 @@ AtaBlockIoFlushBlocks (
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Reset the Block Device.
|
||||||
|
|
||||||
|
@param[in] This Indicates a pointer to the calling context.
|
||||||
|
@param[in] ExtendedVerification Driver may perform diagnostics on reset.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The device was reset.
|
||||||
|
@retval EFI_DEVICE_ERROR The device is not functioning properly and could
|
||||||
|
not be reset.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AtaBlockIoResetEx (
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *This,
|
||||||
|
IN BOOLEAN ExtendedVerification
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
ATA_DEVICE *AtaDevice;
|
||||||
|
EFI_TPL OldTpl;
|
||||||
|
|
||||||
|
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||||
|
|
||||||
|
AtaDevice = ATA_DEVICE_FROM_BLOCK_IO2 (This);
|
||||||
|
|
||||||
|
Status = ResetAtaDevice (AtaDevice);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
Status = EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Read BufferSize bytes from Lba into Buffer.
|
||||||
|
|
||||||
|
@param[in] This Indicates a pointer to the calling context.
|
||||||
|
@param[in] MediaId Id of the media, changes every time the media is replaced.
|
||||||
|
@param[in] Lba The starting Logical Block Address to read from.
|
||||||
|
@param[in, out] Token A pointer to the token associated with the transaction.
|
||||||
|
@param[in] BufferSize Size of Buffer, must be a multiple of device block size.
|
||||||
|
@param[out] Buffer A pointer to the destination buffer for the data. The caller is
|
||||||
|
responsible for either having implicit or explicit ownership of the buffer.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The read request was queued if Event is not NULL.
|
||||||
|
The data was read correctly from the device if
|
||||||
|
the Event is NULL.
|
||||||
|
@retval EFI_DEVICE_ERROR The device reported an error while performing
|
||||||
|
the read.
|
||||||
|
@retval EFI_NO_MEDIA There is no media in the device.
|
||||||
|
@retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
|
||||||
|
@retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
|
||||||
|
intrinsic block size of the device.
|
||||||
|
@retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
|
||||||
|
or the buffer is not on proper alignment.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
|
||||||
|
of resources.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AtaBlockIoReadBlocksEx (
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *This,
|
||||||
|
IN UINT32 MediaId,
|
||||||
|
IN EFI_LBA Lba,
|
||||||
|
IN OUT EFI_BLOCK_IO2_TOKEN *Token,
|
||||||
|
IN UINTN BufferSize,
|
||||||
|
OUT VOID *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return BlockIoReadWrite ((VOID *) This, MediaId, Lba, Token, BufferSize, Buffer, TRUE, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Write BufferSize bytes from Lba into Buffer.
|
||||||
|
|
||||||
|
@param[in] This Indicates a pointer to the calling context.
|
||||||
|
@param[in] MediaId The media ID that the write request is for.
|
||||||
|
@param[in] Lba The starting logical block address to be written. The
|
||||||
|
caller is responsible for writing to only legitimate
|
||||||
|
locations.
|
||||||
|
@param[in, out] Token A pointer to the token associated with the transaction.
|
||||||
|
@param[in] BufferSize Size of Buffer, must be a multiple of device block size.
|
||||||
|
@param[in] Buffer A pointer to the source buffer for the data.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The data was written correctly to the device.
|
||||||
|
@retval EFI_WRITE_PROTECTED The device can not be written to.
|
||||||
|
@retval EFI_DEVICE_ERROR The device reported an error while performing the write.
|
||||||
|
@retval EFI_NO_MEDIA There is no media in the device.
|
||||||
|
@retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
|
||||||
|
@retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
|
||||||
|
@retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
|
||||||
|
or the buffer is not on proper alignment.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AtaBlockIoWriteBlocksEx (
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *This,
|
||||||
|
IN UINT32 MediaId,
|
||||||
|
IN EFI_LBA Lba,
|
||||||
|
IN OUT EFI_BLOCK_IO2_TOKEN *Token,
|
||||||
|
IN UINTN BufferSize,
|
||||||
|
IN VOID *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return BlockIoReadWrite ((VOID *) This, MediaId, Lba, Token, BufferSize, Buffer, TRUE, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Flush the Block Device.
|
||||||
|
|
||||||
|
@param[in] This Indicates a pointer to the calling context.
|
||||||
|
@param[in, out] Token A pointer to the token associated with the transaction.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS All outstanding data was written to the device
|
||||||
|
@retval EFI_DEVICE_ERROR The device reported an error while writing back the data
|
||||||
|
@retval EFI_NO_MEDIA There is no media in the device.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AtaBlockIoFlushBlocksEx (
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *This,
|
||||||
|
IN OUT EFI_BLOCK_IO2_TOKEN *Token
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Signla event and return directly.
|
||||||
|
//
|
||||||
|
if (Token != NULL && Token->Event != NULL) {
|
||||||
|
Token->TransactionStatus = EFI_SUCCESS;
|
||||||
|
gBS->SignalEvent (Token->Event);
|
||||||
|
}
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
Provides inquiry information for the controller type.
|
Provides inquiry information for the controller type.
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include <Protocol/AtaPassThru.h>
|
#include <Protocol/AtaPassThru.h>
|
||||||
#include <Protocol/BlockIo.h>
|
#include <Protocol/BlockIo.h>
|
||||||
|
#include <Protocol/BlockIo2.h>
|
||||||
#include <Protocol/DiskInfo.h>
|
#include <Protocol/DiskInfo.h>
|
||||||
#include <Protocol/DevicePath.h>
|
#include <Protocol/DevicePath.h>
|
||||||
|
|
||||||
|
@ -59,13 +60,37 @@
|
||||||
//
|
//
|
||||||
// The maximum ATA transaction sector count in 48 bit addressing mode.
|
// The maximum ATA transaction sector count in 48 bit addressing mode.
|
||||||
//
|
//
|
||||||
#define MAX_48BIT_TRANSFER_BLOCK_NUM 0x10000
|
//#define MAX_48BIT_TRANSFER_BLOCK_NUM 0x10000
|
||||||
|
|
||||||
|
//
|
||||||
|
// BugBug: if the TransferLength is equal with 0x10000 (the 48bit max length),
|
||||||
|
// there is a bug that even the register interrupt bit has been sit, the buffer
|
||||||
|
// seems not ready. Change the Maximum Sector Numbers to 0xFFFF to work round
|
||||||
|
// this issue.
|
||||||
|
//
|
||||||
|
#define MAX_48BIT_TRANSFER_BLOCK_NUM 0xFFFF
|
||||||
|
|
||||||
//
|
//
|
||||||
// The maximum model name in ATA identify data
|
// The maximum model name in ATA identify data
|
||||||
//
|
//
|
||||||
#define MAX_MODEL_NAME_LEN 40
|
#define MAX_MODEL_NAME_LEN 40
|
||||||
|
|
||||||
|
#define ATA_TASK_SIGNATURE SIGNATURE_32 ('A', 'T', 'S', 'K')
|
||||||
|
#define ATA_DEVICE_SIGNATURE SIGNATURE_32 ('A', 'B', 'I', 'D')
|
||||||
|
|
||||||
|
#define IS_ALIGNED(addr, size) (((UINTN) (addr) & (size - 1)) == 0)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Task for the non blocking I/O
|
||||||
|
//
|
||||||
|
typedef struct {
|
||||||
|
UINT32 Signature;
|
||||||
|
EFI_BLOCK_IO2_TOKEN *Token;
|
||||||
|
UINTN *UnsignalledEventCount;
|
||||||
|
EFI_ATA_PASS_THRU_COMMAND_PACKET Packet;
|
||||||
|
BOOLEAN *IsError;// Indicate whether meeting error during source allocation for new task.
|
||||||
|
LIST_ENTRY TaskEntry;
|
||||||
|
} ATA_BUS_ASYN_TASK;
|
||||||
|
|
||||||
//
|
//
|
||||||
// ATA bus data structure for ATA controller
|
// ATA bus data structure for ATA controller
|
||||||
|
@ -77,46 +102,48 @@ typedef struct {
|
||||||
EFI_HANDLE DriverBindingHandle;
|
EFI_HANDLE DriverBindingHandle;
|
||||||
} ATA_BUS_DRIVER_DATA;
|
} ATA_BUS_DRIVER_DATA;
|
||||||
|
|
||||||
#define ATA_DEVICE_SIGNATURE SIGNATURE_32 ('A', 'B', 'I', 'D')
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// ATA device data structure for each child device
|
// ATA device data structure for each child device
|
||||||
//
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT32 Signature;
|
UINT32 Signature;
|
||||||
|
|
||||||
EFI_HANDLE Handle;
|
EFI_HANDLE Handle;
|
||||||
EFI_BLOCK_IO_PROTOCOL BlockIo;
|
EFI_BLOCK_IO_PROTOCOL BlockIo;
|
||||||
EFI_BLOCK_IO_MEDIA BlockMedia;
|
EFI_BLOCK_IO2_PROTOCOL BlockIo2;
|
||||||
EFI_DISK_INFO_PROTOCOL DiskInfo;
|
EFI_BLOCK_IO_MEDIA BlockMedia;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
EFI_DISK_INFO_PROTOCOL DiskInfo;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||||
|
|
||||||
ATA_BUS_DRIVER_DATA *AtaBusDriverData;
|
ATA_BUS_DRIVER_DATA *AtaBusDriverData;
|
||||||
UINT16 Port;
|
UINT16 Port;
|
||||||
UINT16 PortMultiplierPort;
|
UINT16 PortMultiplierPort;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Buffer for the execution of ATA pass through protocol
|
// Buffer for the execution of ATA pass through protocol
|
||||||
//
|
//
|
||||||
EFI_ATA_PASS_THRU_COMMAND_PACKET Packet;
|
EFI_ATA_PASS_THRU_COMMAND_PACKET Packet;
|
||||||
EFI_ATA_COMMAND_BLOCK Acb;
|
EFI_ATA_COMMAND_BLOCK Acb;
|
||||||
EFI_ATA_STATUS_BLOCK *Asb;
|
EFI_ATA_STATUS_BLOCK *Asb;
|
||||||
|
|
||||||
BOOLEAN UdmaValid;
|
BOOLEAN UdmaValid;
|
||||||
BOOLEAN Lba48Bit;
|
BOOLEAN Lba48Bit;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Cached data for ATA identify data
|
// Cached data for ATA identify data
|
||||||
//
|
//
|
||||||
ATA_IDENTIFY_DATA *IdentifyData;
|
ATA_IDENTIFY_DATA *IdentifyData;
|
||||||
|
|
||||||
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
|
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
|
||||||
CHAR16 ModelName[MAX_MODEL_NAME_LEN + 1];
|
CHAR16 ModelName[MAX_MODEL_NAME_LEN + 1];
|
||||||
|
|
||||||
|
LIST_ENTRY AtaTaskList;
|
||||||
} ATA_DEVICE;
|
} ATA_DEVICE;
|
||||||
|
|
||||||
#define ATA_DEVICE_FROM_BLOCK_IO(a) CR (a, ATA_DEVICE, BlockIo, ATA_DEVICE_SIGNATURE)
|
#define ATA_DEVICE_FROM_BLOCK_IO(a) CR (a, ATA_DEVICE, BlockIo, ATA_DEVICE_SIGNATURE)
|
||||||
#define ATA_DEVICE_FROM_DISK_INFO(a) CR (a, ATA_DEVICE, DiskInfo, ATA_DEVICE_SIGNATURE)
|
#define ATA_DEVICE_FROM_BLOCK_IO2(a) CR (a, ATA_DEVICE, BlockIo2, ATA_DEVICE_SIGNATURE)
|
||||||
|
#define ATA_DEVICE_FROM_DISK_INFO(a) CR (a, ATA_DEVICE, DiskInfo, ATA_DEVICE_SIGNATURE)
|
||||||
|
#define ATA_AYNS_TASK_FROM_ENTRY(a) CR (a, ATA_BUS_ASYN_TASK, TaskEntry, ATA_TASK_SIGNATURE)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Global Variables
|
// Global Variables
|
||||||
|
@ -125,6 +152,52 @@ extern EFI_DRIVER_BINDING_PROTOCOL gAtaBusDriverBinding;
|
||||||
extern EFI_COMPONENT_NAME_PROTOCOL gAtaBusComponentName;
|
extern EFI_COMPONENT_NAME_PROTOCOL gAtaBusComponentName;
|
||||||
extern EFI_COMPONENT_NAME2_PROTOCOL gAtaBusComponentName2;
|
extern EFI_COMPONENT_NAME2_PROTOCOL gAtaBusComponentName2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Allocates an aligned buffer for ATA device.
|
||||||
|
|
||||||
|
This function allocates an aligned buffer for the ATA device to perform
|
||||||
|
ATA pass through operations. The alignment requirement is from ATA pass
|
||||||
|
through interface.
|
||||||
|
|
||||||
|
@param AtaDevice The ATA child device involved for the operation.
|
||||||
|
@param BufferSize The request buffer size.
|
||||||
|
|
||||||
|
@return A pointer to the aligned buffer or NULL if the allocation fails.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID *
|
||||||
|
AllocateAlignedBuffer (
|
||||||
|
IN ATA_DEVICE *AtaDevice,
|
||||||
|
IN UINTN BufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Frees an aligned buffer for ATA device.
|
||||||
|
|
||||||
|
This function frees an aligned buffer for the ATA device to perform
|
||||||
|
ATA pass through operations.
|
||||||
|
|
||||||
|
@param Buffer The aligned buffer to be freed.
|
||||||
|
@param BufferSize The request buffer size.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
FreeAlignedBuffer (
|
||||||
|
IN VOID *Buffer,
|
||||||
|
IN UINTN BufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free SubTask.
|
||||||
|
|
||||||
|
@param[in, out] Task Pointer to task to be freed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
FreeAtaSubTask (
|
||||||
|
IN ATA_BUS_ASYN_TASK *Task
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Wrapper for EFI_ATA_PASS_THRU_PROTOCOL.ResetDevice().
|
Wrapper for EFI_ATA_PASS_THRU_PROTOCOL.ResetDevice().
|
||||||
|
@ -162,7 +235,6 @@ DiscoverAtaDevice (
|
||||||
IN OUT ATA_DEVICE *AtaDevice
|
IN OUT ATA_DEVICE *AtaDevice
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Read or write a number of blocks from ATA device.
|
Read or write a number of blocks from ATA device.
|
||||||
|
|
||||||
|
@ -170,11 +242,12 @@ DiscoverAtaDevice (
|
||||||
ATA device. It may separate the read/write request into several ATA pass through
|
ATA device. It may separate the read/write request into several ATA pass through
|
||||||
transactions.
|
transactions.
|
||||||
|
|
||||||
@param AtaDevice The ATA child device involved for the operation.
|
@param[in, out] AtaDevice The ATA child device involved for the operation.
|
||||||
@param Buffer The pointer to the current transaction buffer.
|
@param[in, out] Buffer The pointer to the current transaction buffer.
|
||||||
@param StartLba The starting logical block address to be accessed.
|
@param[in] StartLba The starting logical block address to be accessed.
|
||||||
@param NumberOfBlocks The block number or sector count of the transfer.
|
@param[in] NumberOfBlocks The block number or sector count of the transfer.
|
||||||
@param IsWrite Indicates whether it is a write operation.
|
@param[in] IsWrite Indicates whether it is a write operation.
|
||||||
|
@param[in, out] Token A pointer to the token associated with the transaction.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The data transfer is complete successfully.
|
@retval EFI_SUCCESS The data transfer is complete successfully.
|
||||||
@return others Some error occurs when transferring data.
|
@return others Some error occurs when transferring data.
|
||||||
|
@ -186,7 +259,8 @@ AccessAtaDevice(
|
||||||
IN OUT UINT8 *Buffer,
|
IN OUT UINT8 *Buffer,
|
||||||
IN EFI_LBA StartLba,
|
IN EFI_LBA StartLba,
|
||||||
IN UINTN NumberOfBlocks,
|
IN UINTN NumberOfBlocks,
|
||||||
IN BOOLEAN IsWrite
|
IN BOOLEAN IsWrite,
|
||||||
|
IN OUT EFI_BLOCK_IO2_TOKEN *Token
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -544,6 +618,111 @@ AtaBlockIoFlushBlocks (
|
||||||
IN EFI_BLOCK_IO_PROTOCOL *This
|
IN EFI_BLOCK_IO_PROTOCOL *This
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Reset the Block Device throught Block I/O2 protocol.
|
||||||
|
|
||||||
|
@param[in] This Indicates a pointer to the calling context.
|
||||||
|
@param[in] ExtendedVerification Driver may perform diagnostics on reset.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The device was reset.
|
||||||
|
@retval EFI_DEVICE_ERROR The device is not functioning properly and could
|
||||||
|
not be reset.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AtaBlockIoResetEx (
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *This,
|
||||||
|
IN BOOLEAN ExtendedVerification
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Read BufferSize bytes from Lba into Buffer.
|
||||||
|
|
||||||
|
@param[in] This Indicates a pointer to the calling context.
|
||||||
|
@param[in] MediaId Id of the media, changes every time the media is replaced.
|
||||||
|
@param[in] Lba The starting Logical Block Address to read from.
|
||||||
|
@param[in, out] Token A pointer to the token associated with the transaction.
|
||||||
|
@param[in] BufferSize Size of Buffer, must be a multiple of device block size.
|
||||||
|
@param[out] Buffer A pointer to the destination buffer for the data. The caller is
|
||||||
|
responsible for either having implicit or explicit ownership of the buffer.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The read request was queued if Event is not NULL.
|
||||||
|
The data was read correctly from the device if
|
||||||
|
the Event is NULL.
|
||||||
|
@retval EFI_DEVICE_ERROR The device reported an error while performing
|
||||||
|
the read.
|
||||||
|
@retval EFI_NO_MEDIA There is no media in the device.
|
||||||
|
@retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
|
||||||
|
@retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
|
||||||
|
intrinsic block size of the device.
|
||||||
|
@retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
|
||||||
|
or the buffer is not on proper alignment.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
|
||||||
|
of resources.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AtaBlockIoReadBlocksEx (
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *This,
|
||||||
|
IN UINT32 MediaId,
|
||||||
|
IN EFI_LBA Lba,
|
||||||
|
IN OUT EFI_BLOCK_IO2_TOKEN *Token,
|
||||||
|
IN UINTN BufferSize,
|
||||||
|
OUT VOID *Buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Write BufferSize bytes from Lba into Buffer.
|
||||||
|
|
||||||
|
@param[in] This Indicates a pointer to the calling context.
|
||||||
|
@param[in] MediaId The media ID that the write request is for.
|
||||||
|
@param[in] Lba The starting logical block address to be written. The
|
||||||
|
caller is responsible for writing to only legitimate
|
||||||
|
locations.
|
||||||
|
@param[in, out] Token A pointer to the token associated with the transaction.
|
||||||
|
@param[in] BufferSize Size of Buffer, must be a multiple of device block size.
|
||||||
|
@param[in] Buffer A pointer to the source buffer for the data.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The data was written correctly to the device.
|
||||||
|
@retval EFI_WRITE_PROTECTED The device can not be written to.
|
||||||
|
@retval EFI_DEVICE_ERROR The device reported an error while performing the write.
|
||||||
|
@retval EFI_NO_MEDIA There is no media in the device.
|
||||||
|
@retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
|
||||||
|
@retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
|
||||||
|
@retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
|
||||||
|
or the buffer is not on proper alignment.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AtaBlockIoWriteBlocksEx (
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *This,
|
||||||
|
IN UINT32 MediaId,
|
||||||
|
IN EFI_LBA Lba,
|
||||||
|
IN OUT EFI_BLOCK_IO2_TOKEN *Token,
|
||||||
|
IN UINTN BufferSize,
|
||||||
|
IN VOID *Buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Flush the Block Device.
|
||||||
|
|
||||||
|
@param[in] This Indicates a pointer to the calling context.
|
||||||
|
@param[in, out] Token A pointer to the token associated with the transaction.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS All outstanding data was written to the device
|
||||||
|
@retval EFI_DEVICE_ERROR The device reported an error while writing back the data
|
||||||
|
@retval EFI_NO_MEDIA There is no media in the device.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AtaBlockIoFlushBlocksEx (
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *This,
|
||||||
|
IN OUT EFI_BLOCK_IO2_TOKEN *Token
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Provides inquiry information for the controller type.
|
Provides inquiry information for the controller type.
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
# in UEFI spec 2.2. It installs Block IO and Disk Info protocol for each ATA device
|
# in UEFI spec 2.2. It installs Block IO and Disk Info protocol for each ATA device
|
||||||
# it enumerates and identifies successfully.
|
# it enumerates and identifies successfully.
|
||||||
#
|
#
|
||||||
# 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
|
||||||
|
@ -63,6 +63,7 @@
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiDiskInfoProtocolGuid # BY_START
|
gEfiDiskInfoProtocolGuid # BY_START
|
||||||
gEfiBlockIoProtocolGuid # BY_START
|
gEfiBlockIoProtocolGuid # BY_START
|
||||||
|
gEfiBlockIo2ProtocolGuid # BY_START
|
||||||
gEfiAtaPassThruProtocolGuid # TO_START
|
gEfiAtaPassThruProtocolGuid # TO_START
|
||||||
gEfiDevicePathProtocolGuid # TO_START
|
gEfiDevicePathProtocolGuid # TO_START
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
It transforms the high level identity, read/write, reset command to ATA pass
|
It transforms the high level identity, read/write, reset command to ATA pass
|
||||||
through command and protocol.
|
through command and 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
|
||||||
|
@ -75,14 +75,25 @@ UINTN mMaxTransferBlockNumber[] = {
|
||||||
for an ATA device. It assembles the ATA pass through command packet for ATA
|
for an ATA device. It assembles the ATA pass through command packet for ATA
|
||||||
transaction.
|
transaction.
|
||||||
|
|
||||||
@param AtaDevice The ATA child device involved for the operation.
|
@param[in, out] AtaDevice The ATA child device involved for the operation.
|
||||||
|
@param[in, out] TaskPacket Pointer to a Pass Thru Command Packet. Optional,
|
||||||
|
if it is NULL, blocking mode, and use the packet
|
||||||
|
in AtaDevice. If it is not NULL, non blocking mode,
|
||||||
|
and pass down this Packet.
|
||||||
|
@param[in] Event If Event is NULL, then blocking I/O is performed.
|
||||||
|
If Event is not NULL and non-blocking I/O is
|
||||||
|
supported,then non-blocking I/O is performed,
|
||||||
|
and Event will be signaled when the write
|
||||||
|
request is completed.
|
||||||
|
|
||||||
@return The return status from EFI_ATA_PASS_THRU_PROTOCOL.PassThru().
|
@return The return status from EFI_ATA_PASS_THRU_PROTOCOL.PassThru().
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
AtaDevicePassThru (
|
AtaDevicePassThru (
|
||||||
IN OUT ATA_DEVICE *AtaDevice
|
IN OUT ATA_DEVICE *AtaDevice,
|
||||||
|
IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET *TaskPacket, OPTIONAL
|
||||||
|
IN OUT EFI_EVENT Event OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
@ -90,12 +101,19 @@ AtaDevicePassThru (
|
||||||
EFI_ATA_PASS_THRU_COMMAND_PACKET *Packet;
|
EFI_ATA_PASS_THRU_COMMAND_PACKET *Packet;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Assemble packet
|
// Assemble packet. If it is non blocking mode, the Ata driver should keep each
|
||||||
|
// subtask and clean them when the event is signaled.
|
||||||
//
|
//
|
||||||
Packet = &AtaDevice->Packet;
|
if (TaskPacket != NULL) {
|
||||||
Packet->Asb = AtaDevice->Asb;
|
Packet = TaskPacket;
|
||||||
Packet->Acb = &AtaDevice->Acb;
|
Packet->Asb = AllocateAlignedBuffer (AtaDevice, sizeof (*AtaDevice->Asb));
|
||||||
Packet->Timeout = ATA_TIMEOUT;
|
CopyMem (Packet->Asb, AtaDevice->Asb, sizeof (*AtaDevice->Asb));
|
||||||
|
Packet->Acb = AllocateCopyPool(sizeof (EFI_ATA_COMMAND_BLOCK), &AtaDevice->Acb);
|
||||||
|
} else {
|
||||||
|
Packet = &AtaDevice->Packet;
|
||||||
|
Packet->Asb = AtaDevice->Asb;
|
||||||
|
Packet->Acb = &AtaDevice->Acb;
|
||||||
|
}
|
||||||
|
|
||||||
AtaPassThru = AtaDevice->AtaBusDriverData->AtaPassThru;
|
AtaPassThru = AtaDevice->AtaBusDriverData->AtaPassThru;
|
||||||
|
|
||||||
|
@ -104,7 +122,7 @@ AtaDevicePassThru (
|
||||||
AtaDevice->Port,
|
AtaDevice->Port,
|
||||||
AtaDevice->PortMultiplierPort,
|
AtaDevice->PortMultiplierPort,
|
||||||
Packet,
|
Packet,
|
||||||
NULL
|
Event
|
||||||
);
|
);
|
||||||
//
|
//
|
||||||
// Ensure ATA pass through caller and callee have the same
|
// Ensure ATA pass through caller and callee have the same
|
||||||
|
@ -257,6 +275,8 @@ IdentifyAtaDevice (
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUG ((EFI_D_INFO, "AtaBus - Identify Device (%x %x)\n", (UINTN)AtaDevice->Port, (UINTN)AtaDevice->PortMultiplierPort));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check whether the WORD 88 (supported UltraDMA by drive) is valid
|
// Check whether the WORD 88 (supported UltraDMA by drive) is valid
|
||||||
//
|
//
|
||||||
|
@ -319,7 +339,7 @@ IdentifyAtaDevice (
|
||||||
//
|
//
|
||||||
// Get ATA model name from identify data structure.
|
// Get ATA model name from identify data structure.
|
||||||
//
|
//
|
||||||
PrintAtaModelName (AtaDevice);
|
PrintAtaModelName (AtaDevice);
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -354,7 +374,7 @@ DiscoverAtaDevice (
|
||||||
//
|
//
|
||||||
Acb = ZeroMem (&AtaDevice->Acb, sizeof (*Acb));
|
Acb = ZeroMem (&AtaDevice->Acb, sizeof (*Acb));
|
||||||
Acb->AtaCommand = ATA_CMD_IDENTIFY_DRIVE;
|
Acb->AtaCommand = ATA_CMD_IDENTIFY_DRIVE;
|
||||||
Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort << 4));
|
Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort << 4));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Prepare for ATA pass through packet.
|
// Prepare for ATA pass through packet.
|
||||||
|
@ -363,11 +383,12 @@ DiscoverAtaDevice (
|
||||||
Packet->InDataBuffer = AtaDevice->IdentifyData;
|
Packet->InDataBuffer = AtaDevice->IdentifyData;
|
||||||
Packet->InTransferLength = sizeof (*AtaDevice->IdentifyData);
|
Packet->InTransferLength = sizeof (*AtaDevice->IdentifyData);
|
||||||
Packet->Protocol = EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN;
|
Packet->Protocol = EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN;
|
||||||
Packet->Length = EFI_ATA_PASS_THRU_LENGTH_BYTES | EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
|
Packet->Length = EFI_ATA_PASS_THRU_LENGTH_BYTES | EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
|
||||||
|
Packet->Timeout = ATA_TIMEOUT;
|
||||||
|
|
||||||
Retry = MAX_RETRY_TIMES;
|
Retry = MAX_RETRY_TIMES;
|
||||||
do {
|
do {
|
||||||
Status = AtaDevicePassThru (AtaDevice);
|
Status = AtaDevicePassThru (AtaDevice, NULL, NULL);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
//
|
//
|
||||||
// The command is issued successfully
|
// The command is issued successfully
|
||||||
|
@ -389,11 +410,20 @@ DiscoverAtaDevice (
|
||||||
ATA device. It chooses the appropriate ATA command and protocol to invoke PassThru
|
ATA device. It chooses the appropriate ATA command and protocol to invoke PassThru
|
||||||
interface of ATA pass through.
|
interface of ATA pass through.
|
||||||
|
|
||||||
@param AtaDevice The ATA child device involved for the operation.
|
@param[in, out] AtaDevice The ATA child device involved for the operation.
|
||||||
@param Buffer The pointer to the current transaction buffer.
|
@param[in, out] TaskPacket Pointer to a Pass Thru Command Packet. Optional,
|
||||||
@param StartLba The starting logical block address to be accessed.
|
if it is NULL, blocking mode, and use the packet
|
||||||
@param TransferLength The block number or sector count of the transfer.
|
in AtaDevice. If it is not NULL, non blocking mode,
|
||||||
@param IsWrite Indicates whether it is a write operation.
|
and pass down this Packet.
|
||||||
|
@param[in, out] Buffer The pointer to the current transaction buffer.
|
||||||
|
@param[in] StartLba The starting logical block address to be accessed.
|
||||||
|
@param[in] TransferLength The block number or sector count of the transfer.
|
||||||
|
@param[in] IsWrite Indicates whether it is a write operation.
|
||||||
|
@param[in] Event If Event is NULL, then blocking I/O is performed.
|
||||||
|
If Event is not NULL and non-blocking I/O is
|
||||||
|
supported,then non-blocking I/O is performed,
|
||||||
|
and Event will be signaled when the write
|
||||||
|
request is completed.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The data transfer is complete successfully.
|
@retval EFI_SUCCESS The data transfer is complete successfully.
|
||||||
@return others Some error occurs when transferring data.
|
@return others Some error occurs when transferring data.
|
||||||
|
@ -401,11 +431,13 @@ DiscoverAtaDevice (
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
TransferAtaDevice (
|
TransferAtaDevice (
|
||||||
IN OUT ATA_DEVICE *AtaDevice,
|
IN OUT ATA_DEVICE *AtaDevice,
|
||||||
IN OUT VOID *Buffer,
|
IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET *TaskPacket, OPTIONAL
|
||||||
IN EFI_LBA StartLba,
|
IN OUT VOID *Buffer,
|
||||||
IN UINT32 TransferLength,
|
IN EFI_LBA StartLba,
|
||||||
IN BOOLEAN IsWrite
|
IN UINT32 TransferLength,
|
||||||
|
IN BOOLEAN IsWrite,
|
||||||
|
IN EFI_EVENT Event OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_ATA_COMMAND_BLOCK *Acb;
|
EFI_ATA_COMMAND_BLOCK *Acb;
|
||||||
|
@ -425,7 +457,7 @@ TransferAtaDevice (
|
||||||
Acb->AtaSectorNumber = (UINT8) StartLba;
|
Acb->AtaSectorNumber = (UINT8) StartLba;
|
||||||
Acb->AtaCylinderLow = (UINT8) RShiftU64 (StartLba, 8);
|
Acb->AtaCylinderLow = (UINT8) RShiftU64 (StartLba, 8);
|
||||||
Acb->AtaCylinderHigh = (UINT8) RShiftU64 (StartLba, 16);
|
Acb->AtaCylinderHigh = (UINT8) RShiftU64 (StartLba, 16);
|
||||||
Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort << 4));
|
Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort << 4));
|
||||||
Acb->AtaSectorCount = (UINT8) TransferLength;
|
Acb->AtaSectorCount = (UINT8) TransferLength;
|
||||||
if (AtaDevice->Lba48Bit) {
|
if (AtaDevice->Lba48Bit) {
|
||||||
Acb->AtaSectorNumberExp = (UINT8) RShiftU64 (StartLba, 24);
|
Acb->AtaSectorNumberExp = (UINT8) RShiftU64 (StartLba, 24);
|
||||||
|
@ -439,7 +471,12 @@ TransferAtaDevice (
|
||||||
//
|
//
|
||||||
// Prepare for ATA pass through packet.
|
// Prepare for ATA pass through packet.
|
||||||
//
|
//
|
||||||
Packet = ZeroMem (&AtaDevice->Packet, sizeof (*Packet));
|
if (TaskPacket != NULL) {
|
||||||
|
Packet = ZeroMem (TaskPacket, sizeof (*Packet));
|
||||||
|
} else {
|
||||||
|
Packet = ZeroMem (&AtaDevice->Packet, sizeof (*Packet));
|
||||||
|
}
|
||||||
|
|
||||||
if (IsWrite) {
|
if (IsWrite) {
|
||||||
Packet->OutDataBuffer = Buffer;
|
Packet->OutDataBuffer = Buffer;
|
||||||
Packet->OutTransferLength = TransferLength;
|
Packet->OutTransferLength = TransferLength;
|
||||||
|
@ -447,10 +484,109 @@ TransferAtaDevice (
|
||||||
Packet->InDataBuffer = Buffer;
|
Packet->InDataBuffer = Buffer;
|
||||||
Packet->InTransferLength = TransferLength;
|
Packet->InTransferLength = TransferLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet->Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsWrite];
|
Packet->Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsWrite];
|
||||||
Packet->Length = EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
|
Packet->Length = EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
|
||||||
|
Packet->Timeout = ATA_TIMEOUT;
|
||||||
|
|
||||||
return AtaDevicePassThru (AtaDevice);
|
return AtaDevicePassThru (AtaDevice, TaskPacket, Event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free SubTask.
|
||||||
|
|
||||||
|
@param[in, out] Task Pointer to task to be freed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
FreeAtaSubTask (
|
||||||
|
IN ATA_BUS_ASYN_TASK *Task
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (Task->Packet.Asb != NULL) {
|
||||||
|
FreeAlignedBuffer (Task->Packet.Asb, sizeof (Task->Packet.Asb));
|
||||||
|
}
|
||||||
|
if (Task->Packet.Acb != NULL) {
|
||||||
|
FreePool (Task->Packet.Acb);
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePool (Task);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Call back funtion when the event is signaled.
|
||||||
|
|
||||||
|
@param[in] Event The Event this notify function registered to.
|
||||||
|
@param[in] Context Pointer to the context data registerd to the
|
||||||
|
Event.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
AtaNonBlockingCallBack (
|
||||||
|
IN EFI_EVENT Event,
|
||||||
|
IN VOID *Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ATA_BUS_ASYN_TASK *Task;
|
||||||
|
|
||||||
|
Task = (ATA_BUS_ASYN_TASK *) Context;
|
||||||
|
gBS->CloseEvent (Event);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check the command status.
|
||||||
|
// If there is error during the sub task source allocation, the error status
|
||||||
|
// should be returned to the caller directly, so here the Task->Token may already
|
||||||
|
// be deleted by the caller and no need to update the status.
|
||||||
|
//
|
||||||
|
if ((!(*Task->IsError)) && (Task->Packet.Asb->AtaStatus & 0x01) == 0x01) {
|
||||||
|
Task->Token->TransactionStatus = EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_INFO,
|
||||||
|
"NON-BLOCKING EVENT FINISHED!- STATUS = %r\n",
|
||||||
|
Task->Token->TransactionStatus
|
||||||
|
));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reduce the SubEventCount, till it comes to zero.
|
||||||
|
//
|
||||||
|
(*Task->UnsignalledEventCount) --;
|
||||||
|
DEBUG ((DEBUG_INFO, "UnsignalledEventCount = %x\n", *Task->UnsignalledEventCount));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove the SubTask from the Task list.
|
||||||
|
//
|
||||||
|
RemoveEntryList (&Task->TaskEntry);
|
||||||
|
if ((*Task->UnsignalledEventCount) == 0) {
|
||||||
|
//
|
||||||
|
// All Sub tasks are done, then signal the upper layyer event.
|
||||||
|
// Except there is error during the sub task source allocation.
|
||||||
|
//
|
||||||
|
if (!(*Task->IsError)) {
|
||||||
|
gBS->SignalEvent (Task->Token->Event);
|
||||||
|
DEBUG ((DEBUG_INFO, "Signal Up Level Event UnsignalledEventCount = %x!\n", *Task->UnsignalledEventCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePool (Task->UnsignalledEventCount);
|
||||||
|
FreePool (Task->IsError);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_INFO,
|
||||||
|
"PACKET INFO: Write=%s, Lenght=%x, LowCylinder=%x, HighCylinder=%x,SectionNumber=%x",
|
||||||
|
Task->Packet.OutDataBuffer != NULL ? L"YES" : L"NO",
|
||||||
|
Task->Packet.OutDataBuffer != NULL ? Task->Packet.OutTransferLength : Task->Packet.InTransferLength,
|
||||||
|
Task->Packet.Acb->AtaCylinderLow,
|
||||||
|
Task->Packet.Acb->AtaCylinderHigh,
|
||||||
|
Task->Packet.Acb->AtaSectorCount
|
||||||
|
));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Free the buffer of SubTask.
|
||||||
|
//
|
||||||
|
FreeAtaSubTask (Task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -460,11 +596,12 @@ TransferAtaDevice (
|
||||||
ATA device. It may separate the read/write request into several ATA pass through
|
ATA device. It may separate the read/write request into several ATA pass through
|
||||||
transactions.
|
transactions.
|
||||||
|
|
||||||
@param AtaDevice The ATA child device involved for the operation.
|
@param[in, out] AtaDevice The ATA child device involved for the operation.
|
||||||
@param Buffer The pointer to the current transaction buffer.
|
@param[in, out] Buffer The pointer to the current transaction buffer.
|
||||||
@param StartLba The starting logical block address to be accessed.
|
@param[in] StartLba The starting logical block address to be accessed.
|
||||||
@param NumberOfBlocks The block number or sector count of the transfer.
|
@param[in] NumberOfBlocks The block number or sector count of the transfer.
|
||||||
@param IsWrite Indicates whether it is a write operation.
|
@param[in] IsWrite Indicates whether it is a write operation.
|
||||||
|
@param[in, out] Token A pointer to the token associated with the transaction.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The data transfer is complete successfully.
|
@retval EFI_SUCCESS The data transfer is complete successfully.
|
||||||
@return others Some error occurs when transferring data.
|
@return others Some error occurs when transferring data.
|
||||||
|
@ -476,36 +613,146 @@ AccessAtaDevice(
|
||||||
IN OUT UINT8 *Buffer,
|
IN OUT UINT8 *Buffer,
|
||||||
IN EFI_LBA StartLba,
|
IN EFI_LBA StartLba,
|
||||||
IN UINTN NumberOfBlocks,
|
IN UINTN NumberOfBlocks,
|
||||||
IN BOOLEAN IsWrite
|
IN BOOLEAN IsWrite,
|
||||||
|
IN OUT EFI_BLOCK_IO2_TOKEN *Token
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINTN MaxTransferBlockNumber;
|
UINTN MaxTransferBlockNumber;
|
||||||
UINTN TransferBlockNumber;
|
UINTN TransferBlockNumber;
|
||||||
UINTN BlockSize;
|
UINTN BlockSize;
|
||||||
|
UINTN *EventCount;
|
||||||
|
UINTN TempCount;
|
||||||
|
ATA_BUS_ASYN_TASK *Task;
|
||||||
|
EFI_EVENT SubEvent;
|
||||||
|
UINTN Index;
|
||||||
|
BOOLEAN *IsError;
|
||||||
|
EFI_TPL OldTpl;
|
||||||
|
|
||||||
|
SubEvent = NULL;
|
||||||
|
TempCount = 0;
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
EventCount = AllocateZeroPool (sizeof (UINTN));
|
||||||
|
if (EventCount == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
IsError = AllocateZeroPool (sizeof (BOOLEAN));
|
||||||
|
if (IsError == NULL) {
|
||||||
|
goto EXIT;
|
||||||
|
}
|
||||||
|
*IsError = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initial the return status for Non Blocking.
|
||||||
|
//
|
||||||
|
if (Token != NULL && Token->Event != NULL) {
|
||||||
|
Token->TransactionStatus = EFI_SUCCESS;
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// Ensure AtaDevice->Lba48Bit is a valid boolean value
|
// Ensure AtaDevice->Lba48Bit is a valid boolean value
|
||||||
//
|
//
|
||||||
ASSERT ((UINTN) AtaDevice->Lba48Bit < 2);
|
ASSERT ((UINTN) AtaDevice->Lba48Bit < 2);
|
||||||
MaxTransferBlockNumber = mMaxTransferBlockNumber[AtaDevice->Lba48Bit];
|
MaxTransferBlockNumber = mMaxTransferBlockNumber[AtaDevice->Lba48Bit];
|
||||||
BlockSize = AtaDevice->BlockMedia.BlockSize;
|
BlockSize = AtaDevice->BlockMedia.BlockSize;
|
||||||
|
|
||||||
|
TempCount = (NumberOfBlocks + MaxTransferBlockNumber - 1) / MaxTransferBlockNumber;
|
||||||
|
*EventCount = TempCount;
|
||||||
|
Index = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (NumberOfBlocks > MaxTransferBlockNumber) {
|
if (NumberOfBlocks > MaxTransferBlockNumber) {
|
||||||
TransferBlockNumber = MaxTransferBlockNumber;
|
TransferBlockNumber = MaxTransferBlockNumber;
|
||||||
NumberOfBlocks -= MaxTransferBlockNumber;
|
NumberOfBlocks -= MaxTransferBlockNumber;
|
||||||
} else {
|
} else {
|
||||||
TransferBlockNumber = NumberOfBlocks;
|
TransferBlockNumber = NumberOfBlocks;
|
||||||
NumberOfBlocks = 0;
|
NumberOfBlocks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = TransferAtaDevice (AtaDevice, Buffer, StartLba, (UINT32) TransferBlockNumber, IsWrite);
|
//
|
||||||
if (EFI_ERROR (Status)) {
|
// Create sub event for the sub Ata task. Non-Blocking Mode.
|
||||||
return Status;
|
//
|
||||||
|
if (Token != NULL && Token->Event != NULL) {
|
||||||
|
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||||
|
Task = AllocateZeroPool (sizeof (ATA_BUS_ASYN_TASK));
|
||||||
|
if (Task == NULL) {
|
||||||
|
//
|
||||||
|
// If resource allocation fail, reduce the total sub event counts.
|
||||||
|
//
|
||||||
|
*EventCount = (*EventCount) - (TempCount - Index);
|
||||||
|
*IsError = TRUE;
|
||||||
|
Token->TransactionStatus = EFI_OUT_OF_RESOURCES;
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
|
||||||
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
goto EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Task->UnsignalledEventCount = EventCount;
|
||||||
|
Task->Token = Token;
|
||||||
|
Task->IsError = IsError;
|
||||||
|
|
||||||
|
InsertTailList (&AtaDevice->AtaTaskList, &Task->TaskEntry);
|
||||||
|
|
||||||
|
Status = gBS->CreateEvent (
|
||||||
|
EVT_NOTIFY_SIGNAL,
|
||||||
|
TPL_NOTIFY,
|
||||||
|
AtaNonBlockingCallBack,
|
||||||
|
Task,
|
||||||
|
&SubEvent
|
||||||
|
);
|
||||||
|
//
|
||||||
|
// If resource allocation fail, the un-signalled event count should equal to
|
||||||
|
// the original one minus the unassigned subtasks number.
|
||||||
|
//
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
*EventCount = (*EventCount) - (TempCount - Index);
|
||||||
|
*IsError = TRUE;
|
||||||
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
goto EXIT;
|
||||||
|
}
|
||||||
|
Index++;
|
||||||
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
|
||||||
|
DEBUG ((EFI_D_INFO, "NON-BLOCKING SET EVENT START: WRITE = %d\n", IsWrite));
|
||||||
|
Status = TransferAtaDevice (AtaDevice, &Task->Packet, Buffer, StartLba, (UINT32) TransferBlockNumber, IsWrite, SubEvent);
|
||||||
|
DEBUG ((
|
||||||
|
EFI_D_INFO,
|
||||||
|
"NON-BLOCKING SET EVENT END:StartLba=%x, TransferBlockNumbers=%x, Status=%r\n",
|
||||||
|
StartLba,
|
||||||
|
TransferBlockNumber,
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
}else {
|
||||||
|
//
|
||||||
|
// Blocking Mode.
|
||||||
|
//
|
||||||
|
DEBUG ((EFI_D_INFO, "BLOCKING BLOCK I/O START: WRITE = %d\n", IsWrite));
|
||||||
|
Status = TransferAtaDevice (AtaDevice, NULL, Buffer, StartLba, (UINT32) TransferBlockNumber, IsWrite, NULL);
|
||||||
|
DEBUG ((
|
||||||
|
EFI_D_INFO,
|
||||||
|
"BLOCKING BLOCK I/O FINISHE - StartLba = %x; TransferBlockNumbers = %x, status = %r\n",
|
||||||
|
StartLba,
|
||||||
|
TransferBlockNumber,
|
||||||
|
Status
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
StartLba += TransferBlockNumber;
|
StartLba += TransferBlockNumber;
|
||||||
Buffer += TransferBlockNumber * BlockSize;
|
Buffer += TransferBlockNumber * BlockSize;
|
||||||
} while (NumberOfBlocks > 0);
|
} while (NumberOfBlocks > 0);
|
||||||
|
|
||||||
|
EXIT:
|
||||||
|
|
||||||
|
if (*EventCount == 0) {
|
||||||
|
FreePool (EventCount);
|
||||||
|
FreePool (IsError);
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Decode an El Torito formatted CD-ROM
|
Decode an El Torito formatted CD-ROM
|
||||||
|
|
||||||
Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 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
|
||||||
|
@ -20,15 +20,16 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
Install child handles if the Handle supports El Torito format.
|
Install child handles if the Handle supports El Torito format.
|
||||||
|
|
||||||
@param[in] This Calling context.
|
@param[in] This Calling context.
|
||||||
@param[in] Handle Parent Handle
|
@param[in] Handle Parent Handle.
|
||||||
@param[in] DiskIo Parent DiskIo interface
|
@param[in] DiskIo Parent DiskIo interface.
|
||||||
@param[in] BlockIo Parent BlockIo interface
|
@param[in] BlockIo Parent BlockIo interface.
|
||||||
|
@param[in] BlockIo2 Parent BlockIo2 interface.
|
||||||
@param[in] DevicePath Parent Device Path
|
@param[in] DevicePath Parent Device Path
|
||||||
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Child handle(s) was added
|
@retval EFI_SUCCESS Child handle(s) was added.
|
||||||
@retval EFI_MEDIA_CHANGED Media changed Detected
|
@retval EFI_MEDIA_CHANGED Media changed Detected.
|
||||||
@retval other no child handle was added
|
@retval other no child handle was added.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
|
@ -37,6 +38,7 @@ PartitionInstallElToritoChildHandles (
|
||||||
IN EFI_HANDLE Handle,
|
IN EFI_HANDLE Handle,
|
||||||
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
||||||
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -59,6 +61,7 @@ PartitionInstallElToritoChildHandles (
|
||||||
|
|
||||||
Found = EFI_NOT_FOUND;
|
Found = EFI_NOT_FOUND;
|
||||||
Media = BlockIo->Media;
|
Media = BlockIo->Media;
|
||||||
|
|
||||||
VolSpaceSize = 0;
|
VolSpaceSize = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -256,6 +259,7 @@ PartitionInstallElToritoChildHandles (
|
||||||
Handle,
|
Handle,
|
||||||
DiskIo,
|
DiskIo,
|
||||||
BlockIo,
|
BlockIo,
|
||||||
|
BlockIo2,
|
||||||
DevicePath,
|
DevicePath,
|
||||||
(EFI_DEVICE_PATH_PROTOCOL *) &CdDev,
|
(EFI_DEVICE_PATH_PROTOCOL *) &CdDev,
|
||||||
Catalog->Boot.Lba,
|
Catalog->Boot.Lba,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Decode a hard disk partitioned with the GPT scheme in the UEFI 2.0
|
Decode a hard disk partitioned with the GPT scheme in the UEFI 2.0
|
||||||
specification.
|
specification.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 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
|
||||||
|
@ -16,11 +16,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
#include "Partition.h"
|
#include "Partition.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Install child handles if the Handle supports GPT partition structure.
|
Install child handles if the Handle supports GPT partition structure.
|
||||||
|
|
||||||
@param[in] BlockIo Parent BlockIo interface
|
@param[in] BlockIo Parent BlockIo interface.
|
||||||
@param[in] DiskIo Disk Io protocol.
|
@param[in] DiskIo Disk Io protocol.
|
||||||
@param[in] Lba The starting Lba of the Partition Table
|
@param[in] Lba The starting Lba of the Partition Table
|
||||||
@param[out] PartHeader Stores the partition table that is read
|
@param[out] PartHeader Stores the partition table that is read
|
||||||
|
@ -37,7 +36,6 @@ PartitionValidGptTable (
|
||||||
OUT EFI_PARTITION_TABLE_HEADER *PartHeader
|
OUT EFI_PARTITION_TABLE_HEADER *PartHeader
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Check if the CRC field in the Partition table header is valid
|
Check if the CRC field in the Partition table header is valid
|
||||||
for Partition entry array.
|
for Partition entry array.
|
||||||
|
@ -60,11 +58,11 @@ PartitionCheckGptEntryArrayCRC (
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Restore Partition Table to its alternate place
|
Restore Partition Table to its alternate place
|
||||||
(Primary -> Backup or Backup -> Primary)
|
(Primary -> Backup or Backup -> Primary).
|
||||||
|
|
||||||
@param[in] BlockIo Parent BlockIo interface
|
@param[in] BlockIo Parent BlockIo interface.
|
||||||
@param[in] DiskIo Disk Io Protocol.
|
@param[in] DiskIo Disk Io Protocol.
|
||||||
@param[in] PartHeader Partition table header structure
|
@param[in] PartHeader Partition table header structure.
|
||||||
|
|
||||||
@retval TRUE Restoring succeeds
|
@retval TRUE Restoring succeeds
|
||||||
@retval FALSE Restoring failed
|
@retval FALSE Restoring failed
|
||||||
|
@ -160,15 +158,16 @@ PartitionSetCrc (
|
||||||
/**
|
/**
|
||||||
Install child handles if the Handle supports GPT partition structure.
|
Install child handles if the Handle supports GPT partition structure.
|
||||||
|
|
||||||
@param[in] This - Calling context.
|
@param[in] This Calling context.
|
||||||
@param[in] Handle - Parent Handle
|
@param[in] Handle Parent Handle.
|
||||||
@param[in] DiskIo - Parent DiskIo interface
|
@param[in] DiskIo Parent DiskIo interface.
|
||||||
@param[in] BlockIo - Parent BlockIo interface
|
@param[in] BlockIo Parent BlockIo interface.
|
||||||
@param[in] DevicePath - Parent Device Path
|
@param[in] BlockIo2 Parent BlockIo2 interface.
|
||||||
|
@param[in] DevicePath Parent Device Path.
|
||||||
|
|
||||||
@retval EFI_SUCCESS Valid GPT disk
|
@retval EFI_SUCCESS Valid GPT disk.
|
||||||
@retval EFI_MEDIA_CHANGED Media changed Detected
|
@retval EFI_MEDIA_CHANGED Media changed Detected.
|
||||||
@retval other Not a valid GPT disk
|
@retval other Not a valid GPT disk.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
|
@ -177,6 +176,7 @@ PartitionInstallGptChildHandles (
|
||||||
IN EFI_HANDLE Handle,
|
IN EFI_HANDLE Handle,
|
||||||
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
||||||
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -191,6 +191,7 @@ PartitionInstallGptChildHandles (
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
EFI_STATUS GptValidStatus;
|
EFI_STATUS GptValidStatus;
|
||||||
HARDDRIVE_DEVICE_PATH HdDev;
|
HARDDRIVE_DEVICE_PATH HdDev;
|
||||||
|
UINT32 MediaId;
|
||||||
|
|
||||||
ProtectiveMbr = NULL;
|
ProtectiveMbr = NULL;
|
||||||
PrimaryHeader = NULL;
|
PrimaryHeader = NULL;
|
||||||
|
@ -200,6 +201,7 @@ PartitionInstallGptChildHandles (
|
||||||
|
|
||||||
BlockSize = BlockIo->Media->BlockSize;
|
BlockSize = BlockIo->Media->BlockSize;
|
||||||
LastBlock = BlockIo->Media->LastBlock;
|
LastBlock = BlockIo->Media->LastBlock;
|
||||||
|
MediaId = BlockIo->Media->MediaId;
|
||||||
|
|
||||||
DEBUG ((EFI_D_INFO, " BlockSize : %d \n", BlockSize));
|
DEBUG ((EFI_D_INFO, " BlockSize : %d \n", BlockSize));
|
||||||
DEBUG ((EFI_D_INFO, " LastBlock : %lx \n", LastBlock));
|
DEBUG ((EFI_D_INFO, " LastBlock : %lx \n", LastBlock));
|
||||||
|
@ -219,15 +221,16 @@ PartitionInstallGptChildHandles (
|
||||||
//
|
//
|
||||||
Status = DiskIo->ReadDisk (
|
Status = DiskIo->ReadDisk (
|
||||||
DiskIo,
|
DiskIo,
|
||||||
BlockIo->Media->MediaId,
|
MediaId,
|
||||||
0,
|
0,
|
||||||
BlockIo->Media->BlockSize,
|
BlockSize,
|
||||||
ProtectiveMbr
|
ProtectiveMbr
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
GptValidStatus = Status;
|
GptValidStatus = Status;
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Verify that the Protective MBR is valid
|
// Verify that the Protective MBR is valid
|
||||||
//
|
//
|
||||||
|
@ -302,7 +305,7 @@ PartitionInstallGptChildHandles (
|
||||||
|
|
||||||
Status = DiskIo->ReadDisk (
|
Status = DiskIo->ReadDisk (
|
||||||
DiskIo,
|
DiskIo,
|
||||||
BlockIo->Media->MediaId,
|
MediaId,
|
||||||
MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockSize),
|
MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockSize),
|
||||||
PrimaryHeader->NumberOfPartitionEntries * (PrimaryHeader->SizeOfPartitionEntry),
|
PrimaryHeader->NumberOfPartitionEntries * (PrimaryHeader->SizeOfPartitionEntry),
|
||||||
PartEntry
|
PartEntry
|
||||||
|
@ -369,17 +372,18 @@ PartitionInstallGptChildHandles (
|
||||||
DEBUG ((EFI_D_INFO, " End : %lx\n", MultU64x32 (PartEntry[Index].EndingLBA, BlockSize)));
|
DEBUG ((EFI_D_INFO, " End : %lx\n", MultU64x32 (PartEntry[Index].EndingLBA, BlockSize)));
|
||||||
|
|
||||||
Status = PartitionInstallChildHandle (
|
Status = PartitionInstallChildHandle (
|
||||||
This,
|
This,
|
||||||
Handle,
|
Handle,
|
||||||
DiskIo,
|
DiskIo,
|
||||||
BlockIo,
|
BlockIo,
|
||||||
DevicePath,
|
BlockIo2,
|
||||||
(EFI_DEVICE_PATH_PROTOCOL *) &HdDev,
|
DevicePath,
|
||||||
PartEntry[Index].StartingLBA,
|
(EFI_DEVICE_PATH_PROTOCOL *) &HdDev,
|
||||||
PartEntry[Index].EndingLBA,
|
PartEntry[Index].StartingLBA,
|
||||||
BlockSize,
|
PartEntry[Index].EndingLBA,
|
||||||
CompareGuid(&PartEntry[Index].PartitionTypeGUID, &gEfiPartTypeSystemPartGuid)
|
BlockSize,
|
||||||
);
|
CompareGuid(&PartEntry[Index].PartitionTypeGUID, &gEfiPartTypeSystemPartGuid)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG ((EFI_D_INFO, "Prepare to Free Pool\n"));
|
DEBUG ((EFI_D_INFO, "Prepare to Free Pool\n"));
|
||||||
|
@ -404,11 +408,10 @@ Done:
|
||||||
return GptValidStatus;
|
return GptValidStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Install child handles if the Handle supports GPT partition structure.
|
Install child handles if the Handle supports GPT partition structure.
|
||||||
|
|
||||||
@param[in] BlockIo Parent BlockIo interface
|
@param[in] BlockIo Parent BlockIo interface.
|
||||||
@param[in] DiskIo Disk Io protocol.
|
@param[in] DiskIo Disk Io protocol.
|
||||||
@param[in] Lba The starting Lba of the Partition Table
|
@param[in] Lba The starting Lba of the Partition Table
|
||||||
@param[out] PartHeader Stores the partition table that is read
|
@param[out] PartHeader Stores the partition table that is read
|
||||||
|
@ -428,9 +431,10 @@ PartitionValidGptTable (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT32 BlockSize;
|
UINT32 BlockSize;
|
||||||
EFI_PARTITION_TABLE_HEADER *PartHdr;
|
EFI_PARTITION_TABLE_HEADER *PartHdr;
|
||||||
|
UINT32 MediaId;
|
||||||
|
|
||||||
BlockSize = BlockIo->Media->BlockSize;
|
BlockSize = BlockIo->Media->BlockSize;
|
||||||
|
MediaId = BlockIo->Media->MediaId;
|
||||||
PartHdr = AllocateZeroPool (BlockSize);
|
PartHdr = AllocateZeroPool (BlockSize);
|
||||||
|
|
||||||
if (PartHdr == NULL) {
|
if (PartHdr == NULL) {
|
||||||
|
@ -442,7 +446,7 @@ PartitionValidGptTable (
|
||||||
//
|
//
|
||||||
Status = DiskIo->ReadDisk (
|
Status = DiskIo->ReadDisk (
|
||||||
DiskIo,
|
DiskIo,
|
||||||
BlockIo->Media->MediaId,
|
MediaId,
|
||||||
MultU64x32 (Lba, BlockSize),
|
MultU64x32 (Lba, BlockSize),
|
||||||
BlockSize,
|
BlockSize,
|
||||||
PartHdr
|
PartHdr
|
||||||
|
@ -472,12 +476,12 @@ PartitionValidGptTable (
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Check if the CRC field in the Partition table header is valid
|
Check if the CRC field in the Partition table header is valid
|
||||||
for Partition entry array.
|
for Partition entry array.
|
||||||
|
|
||||||
@param[in] BlockIo Parent BlockIo interface
|
@param[in] BlockIo Parent BlockIo interface
|
||||||
|
@param[in] BlockIo2 Parent BlockIo2 interface.
|
||||||
@param[in] DiskIo Disk Io Protocol.
|
@param[in] DiskIo Disk Io Protocol.
|
||||||
@param[in] PartHeader Partition table header structure
|
@param[in] PartHeader Partition table header structure
|
||||||
|
|
||||||
|
@ -535,11 +539,11 @@ PartitionCheckGptEntryArrayCRC (
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Restore Partition Table to its alternate place
|
Restore Partition Table to its alternate place
|
||||||
(Primary -> Backup or Backup -> Primary)
|
(Primary -> Backup or Backup -> Primary).
|
||||||
|
|
||||||
@param[in] BlockIo Parent BlockIo interface
|
@param[in] BlockIo Parent BlockIo interface.
|
||||||
@param[in] DiskIo Disk Io Protocol.
|
@param[in] DiskIo Disk Io Protocol.
|
||||||
@param[in] PartHeader Partition table header structure
|
@param[in] PartHeader Partition table header structure.
|
||||||
|
|
||||||
@retval TRUE Restoring succeeds
|
@retval TRUE Restoring succeeds
|
||||||
@retval FALSE Restoring failed
|
@retval FALSE Restoring failed
|
||||||
|
@ -557,11 +561,13 @@ PartitionRestoreGptTable (
|
||||||
EFI_PARTITION_TABLE_HEADER *PartHdr;
|
EFI_PARTITION_TABLE_HEADER *PartHdr;
|
||||||
EFI_LBA PEntryLBA;
|
EFI_LBA PEntryLBA;
|
||||||
UINT8 *Ptr;
|
UINT8 *Ptr;
|
||||||
|
UINT32 MediaId;
|
||||||
|
|
||||||
PartHdr = NULL;
|
PartHdr = NULL;
|
||||||
Ptr = NULL;
|
Ptr = NULL;
|
||||||
|
|
||||||
BlockSize = BlockIo->Media->BlockSize;
|
BlockSize = BlockIo->Media->BlockSize;
|
||||||
|
MediaId = BlockIo->Media->MediaId;
|
||||||
|
|
||||||
PartHdr = AllocateZeroPool (BlockSize);
|
PartHdr = AllocateZeroPool (BlockSize);
|
||||||
|
|
||||||
|
@ -583,8 +589,8 @@ PartitionRestoreGptTable (
|
||||||
|
|
||||||
Status = DiskIo->WriteDisk (
|
Status = DiskIo->WriteDisk (
|
||||||
DiskIo,
|
DiskIo,
|
||||||
BlockIo->Media->MediaId,
|
MediaId,
|
||||||
MultU64x32 (PartHdr->MyLBA, BlockIo->Media->BlockSize),
|
MultU64x32 (PartHdr->MyLBA, (UINT32) BlockSize),
|
||||||
BlockSize,
|
BlockSize,
|
||||||
PartHdr
|
PartHdr
|
||||||
);
|
);
|
||||||
|
@ -601,8 +607,8 @@ PartitionRestoreGptTable (
|
||||||
|
|
||||||
Status = DiskIo->ReadDisk (
|
Status = DiskIo->ReadDisk (
|
||||||
DiskIo,
|
DiskIo,
|
||||||
BlockIo->Media->MediaId,
|
MediaId,
|
||||||
MultU64x32(PartHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),
|
MultU64x32(PartHeader->PartitionEntryLBA, (UINT32) BlockSize),
|
||||||
PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
|
PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
|
||||||
Ptr
|
Ptr
|
||||||
);
|
);
|
||||||
|
@ -612,8 +618,8 @@ PartitionRestoreGptTable (
|
||||||
|
|
||||||
Status = DiskIo->WriteDisk (
|
Status = DiskIo->WriteDisk (
|
||||||
DiskIo,
|
DiskIo,
|
||||||
BlockIo->Media->MediaId,
|
MediaId,
|
||||||
MultU64x32(PEntryLBA, BlockIo->Media->BlockSize),
|
MultU64x32(PEntryLBA, (UINT32) BlockSize),
|
||||||
PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
|
PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
|
||||||
Ptr
|
Ptr
|
||||||
);
|
);
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
always on the first sector of a media. The first sector also contains
|
always on the first sector of a media. The first sector also contains
|
||||||
the legacy boot strap code.
|
the legacy boot strap code.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 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
|
||||||
|
@ -101,11 +101,12 @@ PartitionValidMbr (
|
||||||
/**
|
/**
|
||||||
Install child handles if the Handle supports MBR format.
|
Install child handles if the Handle supports MBR format.
|
||||||
|
|
||||||
@param This Calling context.
|
@param[in] This Calling context.
|
||||||
@param Handle Parent Handle.
|
@param[in] Handle Parent Handle.
|
||||||
@param DiskIo Parent DiskIo interface.
|
@param[in] DiskIo Parent DiskIo interface.
|
||||||
@param BlockIo Parent BlockIo interface.
|
@param[in] BlockIo Parent BlockIo interface.
|
||||||
@param DevicePath Parent Device Path.
|
@param[in] BlockIo2 Parent BlockIo2 interface.
|
||||||
|
@param[in] DevicePath Parent Device Path.
|
||||||
|
|
||||||
@retval EFI_SUCCESS A child handle was added.
|
@retval EFI_SUCCESS A child handle was added.
|
||||||
@retval EFI_MEDIA_CHANGED Media change was detected.
|
@retval EFI_MEDIA_CHANGED Media change was detected.
|
||||||
|
@ -118,6 +119,7 @@ PartitionInstallMbrChildHandles (
|
||||||
IN EFI_HANDLE Handle,
|
IN EFI_HANDLE Handle,
|
||||||
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
||||||
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -131,26 +133,33 @@ PartitionInstallMbrChildHandles (
|
||||||
UINT32 PartitionNumber;
|
UINT32 PartitionNumber;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
|
EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *LastDevicePathNode;
|
EFI_DEVICE_PATH_PROTOCOL *LastDevicePathNode;
|
||||||
|
UINT32 BlockSize;
|
||||||
|
UINT32 MediaId;
|
||||||
|
EFI_LBA LastBlock;
|
||||||
|
|
||||||
Found = EFI_NOT_FOUND;
|
Found = EFI_NOT_FOUND;
|
||||||
|
|
||||||
Mbr = AllocatePool (BlockIo->Media->BlockSize);
|
BlockSize = BlockIo->Media->BlockSize;
|
||||||
|
MediaId = BlockIo->Media->MediaId;
|
||||||
|
LastBlock = BlockIo->Media->LastBlock;
|
||||||
|
|
||||||
|
Mbr = AllocatePool (BlockSize);
|
||||||
if (Mbr == NULL) {
|
if (Mbr == NULL) {
|
||||||
return Found;
|
return Found;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = DiskIo->ReadDisk (
|
Status = DiskIo->ReadDisk (
|
||||||
DiskIo,
|
DiskIo,
|
||||||
BlockIo->Media->MediaId,
|
MediaId,
|
||||||
0,
|
0,
|
||||||
BlockIo->Media->BlockSize,
|
BlockSize,
|
||||||
Mbr
|
Mbr
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
Found = Status;
|
Found = Status;
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
if (!PartitionValidMbr (Mbr, BlockIo->Media->LastBlock)) {
|
if (!PartitionValidMbr (Mbr, LastBlock)) {
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -218,6 +227,7 @@ PartitionInstallMbrChildHandles (
|
||||||
Handle,
|
Handle,
|
||||||
DiskIo,
|
DiskIo,
|
||||||
BlockIo,
|
BlockIo,
|
||||||
|
BlockIo2,
|
||||||
DevicePath,
|
DevicePath,
|
||||||
(EFI_DEVICE_PATH_PROTOCOL *) &HdDev,
|
(EFI_DEVICE_PATH_PROTOCOL *) &HdDev,
|
||||||
HdDev.PartitionStart,
|
HdDev.PartitionStart,
|
||||||
|
@ -241,9 +251,9 @@ PartitionInstallMbrChildHandles (
|
||||||
|
|
||||||
Status = DiskIo->ReadDisk (
|
Status = DiskIo->ReadDisk (
|
||||||
DiskIo,
|
DiskIo,
|
||||||
BlockIo->Media->MediaId,
|
MediaId,
|
||||||
MultU64x32 (ExtMbrStartingLba, BlockIo->Media->BlockSize),
|
MultU64x32 (ExtMbrStartingLba, BlockSize),
|
||||||
BlockIo->Media->BlockSize,
|
BlockSize,
|
||||||
Mbr
|
Mbr
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
@ -274,17 +284,18 @@ PartitionInstallMbrChildHandles (
|
||||||
*((UINT32 *) &HdDev.Signature[0]) = 0;
|
*((UINT32 *) &HdDev.Signature[0]) = 0;
|
||||||
|
|
||||||
Status = PartitionInstallChildHandle (
|
Status = PartitionInstallChildHandle (
|
||||||
This,
|
This,
|
||||||
Handle,
|
Handle,
|
||||||
DiskIo,
|
DiskIo,
|
||||||
BlockIo,
|
BlockIo,
|
||||||
DevicePath,
|
BlockIo2,
|
||||||
(EFI_DEVICE_PATH_PROTOCOL *) &HdDev,
|
DevicePath,
|
||||||
HdDev.PartitionStart - ParentHdDev.PartitionStart,
|
(EFI_DEVICE_PATH_PROTOCOL *) &HdDev,
|
||||||
HdDev.PartitionStart - ParentHdDev.PartitionStart + HdDev.PartitionSize - 1,
|
HdDev.PartitionStart - ParentHdDev.PartitionStart,
|
||||||
MBR_SIZE,
|
HdDev.PartitionStart - ParentHdDev.PartitionStart + HdDev.PartitionSize - 1,
|
||||||
(BOOLEAN) (Mbr->Partition[0].OSIndicator == EFI_PARTITION)
|
MBR_SIZE,
|
||||||
);
|
(BOOLEAN) (Mbr->Partition[0].OSIndicator == EFI_PARTITION)
|
||||||
|
);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
Found = EFI_SUCCESS;
|
Found = EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,16 +40,15 @@ PARTITION_DETECT_ROUTINE mPartitionDetectRoutineTable[] = {
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Test to see if this driver supports ControllerHandle. Any ControllerHandle
|
Test to see if this driver supports ControllerHandle. Any ControllerHandle
|
||||||
than contains a BlockIo and DiskIo protocol can be supported.
|
than contains a BlockIo and DiskIo protocol or a BlockIo2 protocol can be
|
||||||
|
supported.
|
||||||
|
|
||||||
@param This Protocol instance pointer.
|
@param[in] This Protocol instance pointer.
|
||||||
@param ControllerHandle Handle of device to test
|
@param[in] ControllerHandle Handle of device to test.
|
||||||
@param RemainingDevicePath Optional parameter use to pick a specific child
|
@param[in] RemainingDevicePath Optional parameter use to pick a specific child
|
||||||
device to start.
|
device to start.
|
||||||
|
|
||||||
@retval EFI_SUCCESS This driver supports this device
|
@retval EFI_SUCCESS This driver supports this device
|
||||||
@retval EFI_ALREADY_STARTED This driver is already running on this device
|
@retval EFI_ALREADY_STARTED This driver is already running on this device
|
||||||
|
@ -86,7 +85,7 @@ PartitionDriverBindingSupported (
|
||||||
if (Node->DevPath.Type != MEDIA_DEVICE_PATH ||
|
if (Node->DevPath.Type != MEDIA_DEVICE_PATH ||
|
||||||
Node->DevPath.SubType != MEDIA_HARDDRIVE_DP ||
|
Node->DevPath.SubType != MEDIA_HARDDRIVE_DP ||
|
||||||
DevicePathNodeLength (&Node->DevPath) != sizeof (HARDDRIVE_DEVICE_PATH)) {
|
DevicePathNodeLength (&Node->DevPath) != sizeof (HARDDRIVE_DEVICE_PATH)) {
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +104,6 @@ PartitionDriverBindingSupported (
|
||||||
if (Status == EFI_ALREADY_STARTED) {
|
if (Status == EFI_ALREADY_STARTED) {
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -159,20 +157,39 @@ PartitionDriverBindingSupported (
|
||||||
ControllerHandle,
|
ControllerHandle,
|
||||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||||
);
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
ControllerHandle,
|
||||||
|
&gEfiBlockIo2ProtocolGuid,
|
||||||
|
NULL,
|
||||||
|
This->DriverBindingHandle,
|
||||||
|
ControllerHandle,
|
||||||
|
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// According to UEFI Spec 2.3.1, if a driver is written for a disk device,
|
||||||
|
// then the EFI_BLOCK_IO_PROTOCOL and EFI_BLOCK_IO2_PROTOCOAL must be implemented.
|
||||||
|
// Currently, SCSI disk driver only produce the EFI_BLOCK_IO_PROTOCOL, it will
|
||||||
|
// not be updated until the non blocking SCSI Pass Thru Protocol is provided.
|
||||||
|
// If there is no EFI_BLOCK_IO2_PROTOCOL, skip here.
|
||||||
|
//
|
||||||
|
}
|
||||||
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Start this driver on ControllerHandle by opening a Block IO and Disk IO
|
Start this driver on ControllerHandle by opening a Block IO or a Block IO2
|
||||||
protocol, reading Device Path, and creating a child handle with a
|
or both, and Disk IO protocol, reading Device Path, and creating a child
|
||||||
Disk IO and device path protocol.
|
handle with a Disk IO and device path protocol.
|
||||||
|
|
||||||
@param This Protocol instance pointer.
|
@param[in] This Protocol instance pointer.
|
||||||
@param ControllerHandle Handle of device to bind driver to
|
@param[in] ControllerHandle Handle of device to bind driver to
|
||||||
@param RemainingDevicePath Optional parameter use to pick a specific child
|
@param[in] RemainingDevicePath Optional parameter use to pick a specific child
|
||||||
device to start.
|
device to start.
|
||||||
|
|
||||||
@retval EFI_SUCCESS This driver is added to ControllerHandle
|
@retval EFI_SUCCESS This driver is added to ControllerHandle
|
||||||
@retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
|
@retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
|
||||||
|
@ -190,6 +207,7 @@ PartitionDriverBindingStart (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_STATUS OpenStatus;
|
EFI_STATUS OpenStatus;
|
||||||
EFI_BLOCK_IO_PROTOCOL *BlockIo;
|
EFI_BLOCK_IO_PROTOCOL *BlockIo;
|
||||||
|
EFI_BLOCK_IO2_PROTOCOL *BlockIo2;
|
||||||
EFI_DISK_IO_PROTOCOL *DiskIo;
|
EFI_DISK_IO_PROTOCOL *DiskIo;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
|
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
|
||||||
PARTITION_DETECT_ROUTINE *Routine;
|
PARTITION_DETECT_ROUTINE *Routine;
|
||||||
|
@ -211,6 +229,10 @@ PartitionDriverBindingStart (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Try to open BlockIO and BlockIO2. If BlockIO would be opened, continue,
|
||||||
|
// otherwise, return error.
|
||||||
|
//
|
||||||
Status = gBS->OpenProtocol (
|
Status = gBS->OpenProtocol (
|
||||||
ControllerHandle,
|
ControllerHandle,
|
||||||
&gEfiBlockIoProtocolGuid,
|
&gEfiBlockIoProtocolGuid,
|
||||||
|
@ -222,8 +244,27 @@ PartitionDriverBindingStart (
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
ControllerHandle,
|
||||||
|
&gEfiBlockIo2ProtocolGuid,
|
||||||
|
(VOID **) &BlockIo2,
|
||||||
|
This->DriverBindingHandle,
|
||||||
|
ControllerHandle,
|
||||||
|
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// According to UEFI Spec 2.3.1, if a driver is written for a disk device,
|
||||||
|
// then the EFI_BLOCK_IO_PROTOCOL and EFI_BLOCK_IO2_PROTOCOAL must be implemented.
|
||||||
|
// Currently, SCSI disk driver only produce the EFI_BLOCK_IO_PROTOCOL, it will
|
||||||
|
// not be updated until the non blocking SCSI Pass Thru Protocol is provided.
|
||||||
|
// If there is no EFI_BLOCK_IO2_PROTOCOL, skip here.
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the Device Path Protocol on ControllerHandle's handle
|
// Get the Device Path Protocol on ControllerHandle's handle.
|
||||||
//
|
//
|
||||||
Status = gBS->OpenProtocol (
|
Status = gBS->OpenProtocol (
|
||||||
ControllerHandle,
|
ControllerHandle,
|
||||||
|
@ -276,6 +317,7 @@ PartitionDriverBindingStart (
|
||||||
ControllerHandle,
|
ControllerHandle,
|
||||||
DiskIo,
|
DiskIo,
|
||||||
BlockIo,
|
BlockIo,
|
||||||
|
BlockIo2,
|
||||||
ParentDevicePath
|
ParentDevicePath
|
||||||
);
|
);
|
||||||
if (!EFI_ERROR (Status) || Status == EFI_MEDIA_CHANGED || Status == EFI_NO_MEDIA) {
|
if (!EFI_ERROR (Status) || Status == EFI_MEDIA_CHANGED || Status == EFI_NO_MEDIA) {
|
||||||
|
@ -306,6 +348,15 @@ PartitionDriverBindingStart (
|
||||||
This->DriverBindingHandle,
|
This->DriverBindingHandle,
|
||||||
ControllerHandle
|
ControllerHandle
|
||||||
);
|
);
|
||||||
|
//
|
||||||
|
// Close Parent BlockIO2 if has.
|
||||||
|
//
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
ControllerHandle,
|
||||||
|
&gEfiBlockIo2ProtocolGuid,
|
||||||
|
This->DriverBindingHandle,
|
||||||
|
ControllerHandle
|
||||||
|
);
|
||||||
|
|
||||||
gBS->CloseProtocol (
|
gBS->CloseProtocol (
|
||||||
ControllerHandle,
|
ControllerHandle,
|
||||||
|
@ -320,7 +371,6 @@ Exit:
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Stop this driver on ControllerHandle. Support stopping any child handles
|
Stop this driver on ControllerHandle. Support stopping any child handles
|
||||||
created by this driver.
|
created by this driver.
|
||||||
|
@ -347,10 +397,15 @@ PartitionDriverBindingStop (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
EFI_BLOCK_IO_PROTOCOL *BlockIo;
|
EFI_BLOCK_IO_PROTOCOL *BlockIo;
|
||||||
|
EFI_BLOCK_IO2_PROTOCOL *BlockIo2;
|
||||||
BOOLEAN AllChildrenStopped;
|
BOOLEAN AllChildrenStopped;
|
||||||
PARTITION_PRIVATE_DATA *Private;
|
PARTITION_PRIVATE_DATA *Private;
|
||||||
EFI_DISK_IO_PROTOCOL *DiskIo;
|
EFI_DISK_IO_PROTOCOL *DiskIo;
|
||||||
|
|
||||||
|
BlockIo = NULL;
|
||||||
|
BlockIo2 = NULL;
|
||||||
|
Private = NULL;
|
||||||
|
|
||||||
if (NumberOfChildren == 0) {
|
if (NumberOfChildren == 0) {
|
||||||
//
|
//
|
||||||
// Close the bus driver
|
// Close the bus driver
|
||||||
|
@ -361,6 +416,15 @@ PartitionDriverBindingStop (
|
||||||
This->DriverBindingHandle,
|
This->DriverBindingHandle,
|
||||||
ControllerHandle
|
ControllerHandle
|
||||||
);
|
);
|
||||||
|
//
|
||||||
|
// Close Parent BlockIO2 if has.
|
||||||
|
//
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
ControllerHandle,
|
||||||
|
&gEfiBlockIo2ProtocolGuid,
|
||||||
|
This->DriverBindingHandle,
|
||||||
|
ControllerHandle
|
||||||
|
);
|
||||||
|
|
||||||
gBS->CloseProtocol (
|
gBS->CloseProtocol (
|
||||||
ControllerHandle,
|
ControllerHandle,
|
||||||
|
@ -368,60 +432,91 @@ PartitionDriverBindingStop (
|
||||||
This->DriverBindingHandle,
|
This->DriverBindingHandle,
|
||||||
ControllerHandle
|
ControllerHandle
|
||||||
);
|
);
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
AllChildrenStopped = TRUE;
|
AllChildrenStopped = TRUE;
|
||||||
for (Index = 0; Index < NumberOfChildren; Index++) {
|
for (Index = 0; Index < NumberOfChildren; Index++) {
|
||||||
Status = gBS->OpenProtocol (
|
gBS->OpenProtocol (
|
||||||
ChildHandleBuffer[Index],
|
ChildHandleBuffer[Index],
|
||||||
&gEfiBlockIoProtocolGuid,
|
&gEfiBlockIoProtocolGuid,
|
||||||
(VOID **) &BlockIo,
|
(VOID **) &BlockIo,
|
||||||
This->DriverBindingHandle,
|
This->DriverBindingHandle,
|
||||||
ControllerHandle,
|
ControllerHandle,
|
||||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||||
);
|
);
|
||||||
if (!EFI_ERROR (Status)) {
|
//
|
||||||
|
// Try to locate BlockIo2.
|
||||||
|
//
|
||||||
|
gBS->OpenProtocol (
|
||||||
|
ChildHandleBuffer[Index],
|
||||||
|
&gEfiBlockIo2ProtocolGuid,
|
||||||
|
(VOID **) &BlockIo2,
|
||||||
|
This->DriverBindingHandle,
|
||||||
|
ControllerHandle,
|
||||||
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (BlockIo != NULL) {
|
||||||
Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (BlockIo);
|
Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (BlockIo);
|
||||||
|
} else if (BlockIo2 != NULL) {
|
||||||
|
Private = PARTITION_DEVICE_FROM_BLOCK_IO2_THIS (BlockIo2);
|
||||||
|
} else {
|
||||||
|
ASSERT (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
Status = gBS->CloseProtocol (
|
||||||
// All Software protocols have be freed from the handle so remove it.
|
ControllerHandle,
|
||||||
//
|
&gEfiDiskIoProtocolGuid,
|
||||||
|
This->DriverBindingHandle,
|
||||||
|
ChildHandleBuffer[Index]
|
||||||
|
);
|
||||||
|
//
|
||||||
|
// All Software protocols have be freed from the handle so remove it.
|
||||||
|
// Remove the BlockIo Protocol if has.
|
||||||
|
// Remove the BlockIo2 Protocol if has.
|
||||||
|
//
|
||||||
|
if (BlockIo2 != NULL) {
|
||||||
BlockIo->FlushBlocks (BlockIo);
|
BlockIo->FlushBlocks (BlockIo);
|
||||||
|
BlockIo2->FlushBlocksEx (BlockIo2, NULL);
|
||||||
Status = gBS->CloseProtocol (
|
|
||||||
ControllerHandle,
|
|
||||||
&gEfiDiskIoProtocolGuid,
|
|
||||||
This->DriverBindingHandle,
|
|
||||||
ChildHandleBuffer[Index]
|
|
||||||
);
|
|
||||||
|
|
||||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||||
ChildHandleBuffer[Index],
|
ChildHandleBuffer[Index],
|
||||||
&gEfiDevicePathProtocolGuid,
|
&gEfiDevicePathProtocolGuid,
|
||||||
Private->DevicePath,
|
Private->DevicePath,
|
||||||
&gEfiBlockIoProtocolGuid,
|
&gEfiBlockIoProtocolGuid,
|
||||||
&Private->BlockIo,
|
&Private->BlockIo,
|
||||||
Private->EspGuid,
|
&gEfiBlockIo2ProtocolGuid,
|
||||||
NULL,
|
&Private->BlockIo2,
|
||||||
NULL
|
Private->EspGuid,
|
||||||
);
|
NULL,
|
||||||
if (EFI_ERROR (Status)) {
|
NULL
|
||||||
gBS->OpenProtocol (
|
);
|
||||||
ControllerHandle,
|
} else {
|
||||||
&gEfiDiskIoProtocolGuid,
|
BlockIo->FlushBlocks (BlockIo);
|
||||||
(VOID **) &DiskIo,
|
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||||
This->DriverBindingHandle,
|
ChildHandleBuffer[Index],
|
||||||
ChildHandleBuffer[Index],
|
&gEfiDevicePathProtocolGuid,
|
||||||
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
Private->DevicePath,
|
||||||
);
|
&gEfiBlockIoProtocolGuid,
|
||||||
} else {
|
&Private->BlockIo,
|
||||||
FreePool (Private->DevicePath);
|
Private->EspGuid,
|
||||||
FreePool (Private);
|
NULL,
|
||||||
}
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
gBS->OpenProtocol (
|
||||||
|
ControllerHandle,
|
||||||
|
&gEfiDiskIoProtocolGuid,
|
||||||
|
(VOID **) &DiskIo,
|
||||||
|
This->DriverBindingHandle,
|
||||||
|
ChildHandleBuffer[Index],
|
||||||
|
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
FreePool (Private->DevicePath);
|
||||||
|
FreePool (Private);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
@ -551,11 +646,11 @@ PartitionReadBlocks (
|
||||||
Write by using the Disk IO protocol on the parent device. Lba addresses
|
Write by using the Disk IO protocol on the parent device. Lba addresses
|
||||||
must be converted to byte offsets.
|
must be converted to byte offsets.
|
||||||
|
|
||||||
@param This Protocol instance pointer.
|
@param[in] This Protocol instance pointer.
|
||||||
@param MediaId Id of the media, changes every time the media is replaced.
|
@param[in] MediaId Id of the media, changes every time the media is replaced.
|
||||||
@param Lba The starting Logical Block Address to read from
|
@param[in] Lba The starting Logical Block Address to read from
|
||||||
@param BufferSize Size of Buffer, must be a multiple of device block size.
|
@param[in] BufferSize Size of Buffer, must be a multiple of device block size.
|
||||||
@param Buffer Buffer containing read data
|
@param[in] Buffer Buffer containing data to be written to device.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The data was written correctly to the device.
|
@retval EFI_SUCCESS The data was written correctly to the device.
|
||||||
@retval EFI_WRITE_PROTECTED The device can not be written to.
|
@retval EFI_WRITE_PROTECTED The device can not be written to.
|
||||||
|
@ -574,7 +669,7 @@ PartitionWriteBlocks (
|
||||||
IN UINT32 MediaId,
|
IN UINT32 MediaId,
|
||||||
IN EFI_LBA Lba,
|
IN EFI_LBA Lba,
|
||||||
IN UINTN BufferSize,
|
IN UINTN BufferSize,
|
||||||
OUT VOID *Buffer
|
IN VOID *Buffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PARTITION_PRIVATE_DATA *Private;
|
PARTITION_PRIVATE_DATA *Private;
|
||||||
|
@ -622,25 +717,261 @@ PartitionFlushBlocks (
|
||||||
return Private->ParentBlockIo->FlushBlocks (Private->ParentBlockIo);
|
return Private->ParentBlockIo->FlushBlocks (Private->ParentBlockIo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Reset the Block Device throught Block I/O2 protocol.
|
||||||
|
|
||||||
|
@param This Protocol instance pointer.
|
||||||
|
@param ExtendedVerification Driver may perform diagnostics on reset.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The device was reset.
|
||||||
|
@retval EFI_DEVICE_ERROR The device is not functioning properly and could
|
||||||
|
not be reset.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
PartitionResetEx (
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *This,
|
||||||
|
IN BOOLEAN ExtendedVerification
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PARTITION_PRIVATE_DATA *Private;
|
||||||
|
|
||||||
|
Private = PARTITION_DEVICE_FROM_BLOCK_IO2_THIS (This);
|
||||||
|
|
||||||
|
return Private->ParentBlockIo2->Reset (
|
||||||
|
Private->ParentBlockIo2,
|
||||||
|
ExtendedVerification
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Read BufferSize bytes from Lba into Buffer.
|
||||||
|
|
||||||
|
This function reads the requested number of blocks from the device. All the
|
||||||
|
blocks are read, or an error is returned.
|
||||||
|
If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_or EFI_MEDIA_CHANGED is returned and
|
||||||
|
non-blocking I/O is being used, the Event associated with this request will
|
||||||
|
not be signaled.
|
||||||
|
|
||||||
|
@param[in] This Indicates a pointer to the calling context.
|
||||||
|
@param[in] MediaId Id of the media, changes every time the media is
|
||||||
|
replaced.
|
||||||
|
@param[in] Lba The starting Logical Block Address to read from.
|
||||||
|
@param[in, out] Token A pointer to the token associated with the transaction.
|
||||||
|
@param[in] BufferSize Size of Buffer, must be a multiple of device block size.
|
||||||
|
@param[out] Buffer A pointer to the destination buffer for the data. The
|
||||||
|
caller is responsible for either having implicit or
|
||||||
|
explicit ownership of the buffer.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The read request was queued if Token->Event is
|
||||||
|
not NULL.The data was read correctly from the
|
||||||
|
device if the Token->Event is NULL.
|
||||||
|
@retval EFI_DEVICE_ERROR The device reported an error while performing
|
||||||
|
the read.
|
||||||
|
@retval EFI_NO_MEDIA There is no media in the device.
|
||||||
|
@retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
|
||||||
|
@retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
|
||||||
|
intrinsic block size of the device.
|
||||||
|
@retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
|
||||||
|
or the buffer is not on proper alignment.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
|
||||||
|
of resources.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
PartitionReadBlocksEx (
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *This,
|
||||||
|
IN UINT32 MediaId,
|
||||||
|
IN EFI_LBA Lba,
|
||||||
|
IN OUT EFI_BLOCK_IO2_TOKEN *Token,
|
||||||
|
IN UINTN BufferSize,
|
||||||
|
OUT VOID *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PARTITION_PRIVATE_DATA *Private;
|
||||||
|
UINT64 Offset;
|
||||||
|
UINT32 UnderRun;
|
||||||
|
|
||||||
|
if (Token == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Private = PARTITION_DEVICE_FROM_BLOCK_IO2_THIS (This);
|
||||||
|
if (BufferSize % Private->BlockSize != 0) {
|
||||||
|
return EFI_BAD_BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Offset = MultU64x32 (Lba, Private->BlockSize) + Private->Start;
|
||||||
|
if (Offset + BufferSize > Private->End) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Since the BlockIO2 call Parent BlockIO2 directly, so here the offset must
|
||||||
|
// be multiple of BlockSize. If the Spec will be updated the DiskIO to support
|
||||||
|
// BlockIO2, this limitation will be removed and call DiskIO here.
|
||||||
|
//
|
||||||
|
Lba = DivU64x32Remainder (Offset, Private->BlockSize, &UnderRun);
|
||||||
|
if (UnderRun != 0) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Because some partitions have different block size from their parent
|
||||||
|
// device, in that case the Block I/O2 couldn't be called.
|
||||||
|
//
|
||||||
|
if (Private->BlockSize != Private->ParentBlockIo->Media->BlockSize) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Private->ParentBlockIo2->ReadBlocksEx (Private->ParentBlockIo2, MediaId, Lba, Token, BufferSize, Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Write BufferSize bytes from Lba into Buffer.
|
||||||
|
|
||||||
|
This function writes the requested number of blocks to the device. All blocks
|
||||||
|
are written, or an error is returned.If EFI_DEVICE_ERROR, EFI_NO_MEDIA,
|
||||||
|
EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED is returned and non-blocking I/O is
|
||||||
|
being used, the Event associated with this request will not be signaled.
|
||||||
|
|
||||||
|
@param[in] This Indicates a pointer to the calling context.
|
||||||
|
@param[in] MediaId The media ID that the write request is for.
|
||||||
|
@param[in] Lba The starting logical block address to be written. The
|
||||||
|
caller is responsible for writing to only legitimate
|
||||||
|
locations.
|
||||||
|
@param[in, out] Token A pointer to the token associated with the transaction.
|
||||||
|
@param[in] BufferSize Size of Buffer, must be a multiple of device block size.
|
||||||
|
@param[in] Buffer A pointer to the source buffer for the data.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The write request was queued if Event is not NULL.
|
||||||
|
The data was written correctly to the device if
|
||||||
|
the Event is NULL.
|
||||||
|
@retval EFI_WRITE_PROTECTED The device can not be written to.
|
||||||
|
@retval EFI_NO_MEDIA There is no media in the device.
|
||||||
|
@retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
|
||||||
|
@retval EFI_DEVICE_ERROR The device reported an error while performing the write.
|
||||||
|
@retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
|
||||||
|
@retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
|
||||||
|
or the buffer is not on proper alignment.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
|
||||||
|
of resources.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
PartitionWriteBlocksEx (
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *This,
|
||||||
|
IN UINT32 MediaId,
|
||||||
|
IN EFI_LBA Lba,
|
||||||
|
IN OUT EFI_BLOCK_IO2_TOKEN *Token,
|
||||||
|
IN UINTN BufferSize,
|
||||||
|
IN VOID *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PARTITION_PRIVATE_DATA *Private;
|
||||||
|
UINT64 Offset;
|
||||||
|
UINT32 UnderRun;
|
||||||
|
|
||||||
|
if (Token == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Private = PARTITION_DEVICE_FROM_BLOCK_IO2_THIS (This);
|
||||||
|
if (BufferSize % Private->BlockSize != 0) {
|
||||||
|
return EFI_BAD_BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Offset = MultU64x32 (Lba, Private->BlockSize) + Private->Start;
|
||||||
|
if (Offset + BufferSize > Private->End) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Since the BlockIO2 call Parent BlockIO2 directly, so here the offset must
|
||||||
|
// be multiple of BlockSize. If the Spec will be updated the DiskIO to support
|
||||||
|
// BlockIO2, this limitation will be removed and call DiskIO here.
|
||||||
|
//
|
||||||
|
Lba = DivU64x32Remainder (Offset, Private->BlockSize, &UnderRun);
|
||||||
|
if (UnderRun != 0) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Because some kinds of partition have different block size from their parent,
|
||||||
|
// in that case it couldn't call parent Block I/O2.
|
||||||
|
//
|
||||||
|
if (Private->BlockSize != Private->ParentBlockIo->Media->BlockSize) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Private->ParentBlockIo2->WriteBlocksEx (Private->ParentBlockIo2, MediaId, Lba, Token, BufferSize, Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Flush the Block Device.
|
||||||
|
|
||||||
|
If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED
|
||||||
|
is returned and non-blocking I/O is being used, the Event associated with
|
||||||
|
this request will not be signaled.
|
||||||
|
|
||||||
|
@param[in] This Indicates a pointer to the calling context.
|
||||||
|
@param[in,out] Token A pointer to the token associated with the transaction
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The flush request was queued if Event is not NULL.
|
||||||
|
All outstanding data was written correctly to the
|
||||||
|
device if the Event is NULL.
|
||||||
|
@retval EFI_DEVICE_ERROR The device reported an error while writting back
|
||||||
|
the data.
|
||||||
|
@retval EFI_WRITE_PROTECTED The device cannot be written to.
|
||||||
|
@retval EFI_NO_MEDIA There is no media in the device.
|
||||||
|
@retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
|
||||||
|
of resources.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
PartitionFlushBlocksEx (
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *This,
|
||||||
|
IN OUT EFI_BLOCK_IO2_TOKEN *Token
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PARTITION_PRIVATE_DATA *Private;
|
||||||
|
|
||||||
|
Private = PARTITION_DEVICE_FROM_BLOCK_IO2_THIS (This);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Because some kinds of partition have different block size from their parent,
|
||||||
|
// in that case it couldn't call parent Block I/O2.
|
||||||
|
//
|
||||||
|
if (Private->BlockSize != Private->ParentBlockIo->Media->BlockSize) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Private->ParentBlockIo2->FlushBlocksEx (Private->ParentBlockIo2, Token);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create a child handle for a logical block device that represents the
|
Create a child handle for a logical block device that represents the
|
||||||
bytes Start to End of the Parent Block IO device.
|
bytes Start to End of the Parent Block IO device.
|
||||||
|
|
||||||
@param[in] This Protocol instance pointer
|
@param[in] This Protocol instance pointer.
|
||||||
@param[in] ParentHandle Parent Handle for new child
|
@param[in] ParentHandle Parent Handle for new child.
|
||||||
@param[in] ParentDiskIo Parent DiskIo interface
|
@param[in] ParentDiskIo Parent DiskIo interface.
|
||||||
@param[in] ParentBlockIo Parent BlockIo interface
|
@param[in] ParentBlockIo Parent BlockIo interface.
|
||||||
@param[in] ParentDevicePath Parent Device Path
|
@param[in] ParentBlockIo2 Parent BlockIo2 interface.
|
||||||
@param[in] DevicePathNode Child Device Path node
|
@param[in] ParentDevicePath Parent Device Path.
|
||||||
@param[in] Start Start Block
|
@param[in] DevicePathNode Child Device Path node.
|
||||||
@param[in] End End Block
|
@param[in] Start Start Block.
|
||||||
@param[in] BlockSize Child block size
|
@param[in] End End Block.
|
||||||
@param[in] InstallEspGuid Flag to install EFI System Partition GUID on handle
|
@param[in] BlockSize Child block size.
|
||||||
|
@param[in] InstallEspGuid Flag to install EFI System Partition GUID on handle.
|
||||||
|
|
||||||
@retval EFI_SUCCESS A child handle was added
|
@retval EFI_SUCCESS A child handle was added.
|
||||||
@retval other A child handle was not added
|
@retval other A child handle was not added.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
|
@ -649,6 +980,7 @@ PartitionInstallChildHandle (
|
||||||
IN EFI_HANDLE ParentHandle,
|
IN EFI_HANDLE ParentHandle,
|
||||||
IN EFI_DISK_IO_PROTOCOL *ParentDiskIo,
|
IN EFI_DISK_IO_PROTOCOL *ParentDiskIo,
|
||||||
IN EFI_BLOCK_IO_PROTOCOL *ParentBlockIo,
|
IN EFI_BLOCK_IO_PROTOCOL *ParentBlockIo,
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *ParentBlockIo2,
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
|
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
|
||||||
IN EFI_LBA Start,
|
IN EFI_LBA Start,
|
||||||
|
@ -660,6 +992,7 @@ PartitionInstallChildHandle (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
PARTITION_PRIVATE_DATA *Private;
|
PARTITION_PRIVATE_DATA *Private;
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
Private = AllocateZeroPool (sizeof (PARTITION_PRIVATE_DATA));
|
Private = AllocateZeroPool (sizeof (PARTITION_PRIVATE_DATA));
|
||||||
if (Private == NULL) {
|
if (Private == NULL) {
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
@ -672,28 +1005,51 @@ PartitionInstallChildHandle (
|
||||||
|
|
||||||
Private->BlockSize = BlockSize;
|
Private->BlockSize = BlockSize;
|
||||||
Private->ParentBlockIo = ParentBlockIo;
|
Private->ParentBlockIo = ParentBlockIo;
|
||||||
|
Private->ParentBlockIo2 = ParentBlockIo2;
|
||||||
Private->DiskIo = ParentDiskIo;
|
Private->DiskIo = ParentDiskIo;
|
||||||
|
|
||||||
Private->BlockIo.Revision = ParentBlockIo->Revision;
|
if (Private->ParentBlockIo != NULL) {
|
||||||
|
Private->BlockIo.Revision = ParentBlockIo->Revision;
|
||||||
|
|
||||||
Private->BlockIo.Media = &Private->Media;
|
Private->BlockIo.Media = &Private->Media;
|
||||||
CopyMem (Private->BlockIo.Media, ParentBlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA));
|
CopyMem (Private->BlockIo.Media, ParentBlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA));
|
||||||
Private->Media.LogicalPartition = TRUE;
|
|
||||||
|
|
||||||
|
Private->BlockIo.Reset = PartitionReset;
|
||||||
|
Private->BlockIo.ReadBlocks = PartitionReadBlocks;
|
||||||
|
Private->BlockIo.WriteBlocks = PartitionWriteBlocks;
|
||||||
|
Private->BlockIo.FlushBlocks = PartitionFlushBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Private->ParentBlockIo2 != NULL) {
|
||||||
|
Private->BlockIo2.Media = &Private->Media2;
|
||||||
|
CopyMem (Private->BlockIo2.Media, ParentBlockIo2->Media, sizeof (EFI_BLOCK_IO_MEDIA));
|
||||||
|
|
||||||
|
Private->BlockIo2.Reset = PartitionResetEx;
|
||||||
|
Private->BlockIo2.ReadBlocksEx = PartitionReadBlocksEx;
|
||||||
|
Private->BlockIo2.WriteBlocksEx = PartitionWriteBlocksEx;
|
||||||
|
Private->BlockIo2.FlushBlocksEx = PartitionFlushBlocksEx;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Logical BlockIo instance doesn't have IoAlign restriction because it implements block io operation based on DiskIo
|
|
||||||
//
|
|
||||||
Private->Media.IoAlign = 0;
|
Private->Media.IoAlign = 0;
|
||||||
|
Private->Media.LogicalPartition = TRUE;
|
||||||
Private->Media.LastBlock = DivU64x32 (
|
Private->Media.LastBlock = DivU64x32 (
|
||||||
MultU64x32 (
|
MultU64x32 (
|
||||||
End - Start + 1,
|
End - Start + 1,
|
||||||
ParentBlockIo->Media->BlockSize
|
(ParentBlockIo != NULL) ? ParentBlockIo->Media->BlockSize : ParentBlockIo2->Media->BlockSize
|
||||||
),
|
),
|
||||||
BlockSize
|
BlockSize
|
||||||
) - 1;
|
) - 1;
|
||||||
|
|
||||||
Private->Media.BlockSize = (UINT32) BlockSize;
|
Private->Media.BlockSize = (UINT32) BlockSize;
|
||||||
|
|
||||||
|
//
|
||||||
|
// For BlockIO2, it should keep the same alignment with the parent BlockIO2's.
|
||||||
|
//
|
||||||
|
Private->Media2.LogicalPartition = TRUE;
|
||||||
|
Private->Media2.LastBlock = Private->Media.LastBlock;
|
||||||
|
Private->Media2.BlockSize = (UINT32) BlockSize;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Per UEFI Spec, LowestAlignedLba and LogicalBlocksPerPhysicalBlock must be 0
|
// Per UEFI Spec, LowestAlignedLba and LogicalBlocksPerPhysicalBlock must be 0
|
||||||
// for logical partitions.
|
// for logical partitions.
|
||||||
|
@ -703,12 +1059,7 @@ PartitionInstallChildHandle (
|
||||||
Private->BlockIo.Media->LogicalBlocksPerPhysicalBlock = 0;
|
Private->BlockIo.Media->LogicalBlocksPerPhysicalBlock = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Private->BlockIo.Reset = PartitionReset;
|
Private->DevicePath = AppendDevicePathNode (ParentDevicePath, DevicePathNode);
|
||||||
Private->BlockIo.ReadBlocks = PartitionReadBlocks;
|
|
||||||
Private->BlockIo.WriteBlocks = PartitionWriteBlocks;
|
|
||||||
Private->BlockIo.FlushBlocks = PartitionFlushBlocks;
|
|
||||||
|
|
||||||
Private->DevicePath = AppendDevicePathNode (ParentDevicePath, DevicePathNode);
|
|
||||||
|
|
||||||
if (Private->DevicePath == NULL) {
|
if (Private->DevicePath == NULL) {
|
||||||
FreePool (Private);
|
FreePool (Private);
|
||||||
|
@ -723,20 +1074,61 @@ PartitionInstallChildHandle (
|
||||||
//
|
//
|
||||||
Private->EspGuid = NULL;
|
Private->EspGuid = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create the new handle
|
// Create the new handle.
|
||||||
|
// BlockIO2 will be installed on the condition that the blocksize of parent BlockIO
|
||||||
|
// is same with the child BlockIO's. Instead of calling the DiskIO, the child BlockIO2
|
||||||
|
// directly call the parent BlockIO and doesn't handle the different block size issue.
|
||||||
|
// If SPEC will update the DiskIO to support the Non-Blocking model, the BlockIO2 will call
|
||||||
|
// DiskIO to handle the blocksize unequal issue and the limitation will be remove from
|
||||||
|
// here.
|
||||||
//
|
//
|
||||||
Private->Handle = NULL;
|
Private->Handle = NULL;
|
||||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
if ((Private->ParentBlockIo != NULL) &&
|
||||||
&Private->Handle,
|
(Private->ParentBlockIo2 != NULL) &&
|
||||||
&gEfiDevicePathProtocolGuid,
|
(Private->ParentBlockIo2->Media->BlockSize == BlockSize)
|
||||||
Private->DevicePath,
|
) {
|
||||||
&gEfiBlockIoProtocolGuid,
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
&Private->BlockIo,
|
&Private->Handle,
|
||||||
Private->EspGuid,
|
&gEfiDevicePathProtocolGuid,
|
||||||
NULL,
|
Private->DevicePath,
|
||||||
NULL
|
&gEfiBlockIoProtocolGuid,
|
||||||
);
|
&Private->BlockIo,
|
||||||
|
&gEfiBlockIo2ProtocolGuid,
|
||||||
|
&Private->BlockIo2,
|
||||||
|
Private->EspGuid,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
if (Private->ParentBlockIo != NULL) {
|
||||||
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
|
&Private->Handle,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
Private->DevicePath,
|
||||||
|
&gEfiBlockIoProtocolGuid,
|
||||||
|
&Private->BlockIo,
|
||||||
|
Private->EspGuid,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (Private->ParentBlockIo2 != NULL &&
|
||||||
|
Private->ParentBlockIo2->Media->BlockSize == BlockSize
|
||||||
|
) {
|
||||||
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
|
&Private->Handle,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
Private->DevicePath,
|
||||||
|
&gEfiBlockIo2ProtocolGuid,
|
||||||
|
&Private->BlockIo2,
|
||||||
|
Private->EspGuid,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
//
|
//
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
of the raw block devices media. Currently "El Torito CD-ROM", Legacy
|
of the raw block devices media. Currently "El Torito CD-ROM", Legacy
|
||||||
MBR, and GPT partition schemes are supported.
|
MBR, and GPT partition schemes are supported.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 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
|
||||||
|
@ -20,6 +20,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
#include <Uefi.h>
|
#include <Uefi.h>
|
||||||
#include <Protocol/BlockIo.h>
|
#include <Protocol/BlockIo.h>
|
||||||
|
#include <Protocol/BlockIo2.h>
|
||||||
#include <Guid/Gpt.h>
|
#include <Guid/Gpt.h>
|
||||||
#include <Protocol/ComponentName.h>
|
#include <Protocol/ComponentName.h>
|
||||||
#include <Protocol/DevicePath.h>
|
#include <Protocol/DevicePath.h>
|
||||||
|
@ -48,10 +49,13 @@ typedef struct {
|
||||||
EFI_HANDLE Handle;
|
EFI_HANDLE Handle;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||||
EFI_BLOCK_IO_PROTOCOL BlockIo;
|
EFI_BLOCK_IO_PROTOCOL BlockIo;
|
||||||
|
EFI_BLOCK_IO2_PROTOCOL BlockIo2;
|
||||||
EFI_BLOCK_IO_MEDIA Media;
|
EFI_BLOCK_IO_MEDIA Media;
|
||||||
|
EFI_BLOCK_IO_MEDIA Media2;//For BlockIO2
|
||||||
|
|
||||||
EFI_DISK_IO_PROTOCOL *DiskIo;
|
EFI_DISK_IO_PROTOCOL *DiskIo;
|
||||||
EFI_BLOCK_IO_PROTOCOL *ParentBlockIo;
|
EFI_BLOCK_IO_PROTOCOL *ParentBlockIo;
|
||||||
|
EFI_BLOCK_IO2_PROTOCOL *ParentBlockIo2;
|
||||||
UINT64 Start;
|
UINT64 Start;
|
||||||
UINT64 End;
|
UINT64 End;
|
||||||
UINT32 BlockSize;
|
UINT32 BlockSize;
|
||||||
|
@ -61,6 +65,7 @@ typedef struct {
|
||||||
} PARTITION_PRIVATE_DATA;
|
} PARTITION_PRIVATE_DATA;
|
||||||
|
|
||||||
#define PARTITION_DEVICE_FROM_BLOCK_IO_THIS(a) CR (a, PARTITION_PRIVATE_DATA, BlockIo, PARTITION_PRIVATE_DATA_SIGNATURE)
|
#define PARTITION_DEVICE_FROM_BLOCK_IO_THIS(a) CR (a, PARTITION_PRIVATE_DATA, BlockIo, PARTITION_PRIVATE_DATA_SIGNATURE)
|
||||||
|
#define PARTITION_DEVICE_FROM_BLOCK_IO2_THIS(a) CR (a, PARTITION_PRIVATE_DATA, BlockIo2, PARTITION_PRIVATE_DATA_SIGNATURE)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Global Variables
|
// Global Variables
|
||||||
|
@ -300,19 +305,20 @@ PartitionComponentNameGetControllerName (
|
||||||
Create a child handle for a logical block device that represents the
|
Create a child handle for a logical block device that represents the
|
||||||
bytes Start to End of the Parent Block IO device.
|
bytes Start to End of the Parent Block IO device.
|
||||||
|
|
||||||
@param[in] This Protocol instance pointer
|
@param[in] This Protocol instance pointer.
|
||||||
@param[in] ParentHandle Parent Handle for new child
|
@param[in] ParentHandle Parent Handle for new child.
|
||||||
@param[in] ParentDiskIo Parent DiskIo interface
|
@param[in] ParentDiskIo Parent DiskIo interface.
|
||||||
@param[in] ParentBlockIo Parent BlockIo interface
|
@param[in] ParentBlockIo Parent BlockIo interface.
|
||||||
@param[in] ParentDevicePath Parent Device Path
|
@param[in] ParentBlockIo2 Parent BlockIo2 interface.
|
||||||
@param[in] DevicePathNode Child Device Path node
|
@param[in] ParentDevicePath Parent Device Path.
|
||||||
@param[in] Start Start Block
|
@param[in] DevicePathNode Child Device Path node.
|
||||||
@param[in] End End Block
|
@param[in] Start Start Block.
|
||||||
@param[in] BlockSize Child block size
|
@param[in] End End Block.
|
||||||
@param[in] InstallEspGuid Flag to install EFI System Partition GUID on handle
|
@param[in] BlockSize Child block size.
|
||||||
|
@param[in] InstallEspGuid Flag to install EFI System Partition GUID on handle.
|
||||||
|
|
||||||
@retval EFI_SUCCESS A child handle was added
|
@retval EFI_SUCCESS A child handle was added.
|
||||||
@retval other A child handle was not added
|
@retval other A child handle was not added.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
|
@ -321,6 +327,7 @@ PartitionInstallChildHandle (
|
||||||
IN EFI_HANDLE ParentHandle,
|
IN EFI_HANDLE ParentHandle,
|
||||||
IN EFI_DISK_IO_PROTOCOL *ParentDiskIo,
|
IN EFI_DISK_IO_PROTOCOL *ParentDiskIo,
|
||||||
IN EFI_BLOCK_IO_PROTOCOL *ParentBlockIo,
|
IN EFI_BLOCK_IO_PROTOCOL *ParentBlockIo,
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *ParentBlockIo2,
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
|
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,
|
||||||
IN EFI_LBA Start,
|
IN EFI_LBA Start,
|
||||||
|
@ -332,15 +339,17 @@ PartitionInstallChildHandle (
|
||||||
/**
|
/**
|
||||||
Install child handles if the Handle supports GPT partition structure.
|
Install child handles if the Handle supports GPT partition structure.
|
||||||
|
|
||||||
@param[in] This - Calling context.
|
@param[in] This Calling context.
|
||||||
@param[in] Handle - Parent Handle
|
@param[in] Handle Parent Handle.
|
||||||
@param[in] DiskIo - Parent DiskIo interface
|
@param[in] DiskIo Parent DiskIo interface.
|
||||||
@param[in] BlockIo - Parent BlockIo interface
|
@param[in] BlockIo Parent BlockIo interface.
|
||||||
@param[in] DevicePath - Parent Device Path
|
@param[in] BlockIo2 Parent BlockIo2 interface.
|
||||||
|
@param[in] DevicePath Parent Device Path.
|
||||||
|
|
||||||
@retval EFI_SUCCESS Valid GPT disk
|
@retval EFI_SUCCESS Valid GPT disk.
|
||||||
@retval EFI_MEDIA_CHANGED Media changed Detected
|
@retval EFI_MEDIA_CHANGED Media changed Detected.
|
||||||
@retval other Not a valid GPT disk
|
@retval EFI_INVALID_PARAMETER If both BlockIo and BlockIo2 are NULL;
|
||||||
|
@retval other Not a valid GPT disk.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
|
@ -349,6 +358,7 @@ PartitionInstallGptChildHandles (
|
||||||
IN EFI_HANDLE Handle,
|
IN EFI_HANDLE Handle,
|
||||||
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
||||||
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -356,15 +366,16 @@ PartitionInstallGptChildHandles (
|
||||||
Install child handles if the Handle supports El Torito format.
|
Install child handles if the Handle supports El Torito format.
|
||||||
|
|
||||||
@param[in] This Calling context.
|
@param[in] This Calling context.
|
||||||
@param[in] Handle Parent Handle
|
@param[in] Handle Parent Handle.
|
||||||
@param[in] DiskIo Parent DiskIo interface
|
@param[in] DiskIo Parent DiskIo interface.
|
||||||
@param[in] BlockIo Parent BlockIo interface
|
@param[in] BlockIo Parent BlockIo interface.
|
||||||
|
@param[in] BlockIo2 Parent BlockIo2 interface.
|
||||||
@param[in] DevicePath Parent Device Path
|
@param[in] DevicePath Parent Device Path
|
||||||
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS Child handle(s) was added
|
@retval EFI_SUCCESS Child handle(s) was added.
|
||||||
@retval EFI_MEDIA_CHANGED Media changed Detected
|
@retval EFI_MEDIA_CHANGED Media changed Detected.
|
||||||
@retval other no child handle was added
|
@retval other no child handle was added.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
|
@ -373,17 +384,19 @@ PartitionInstallElToritoChildHandles (
|
||||||
IN EFI_HANDLE Handle,
|
IN EFI_HANDLE Handle,
|
||||||
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
||||||
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Install child handles if the Handle supports MBR format.
|
Install child handles if the Handle supports MBR format.
|
||||||
|
|
||||||
@param This Calling context.
|
@param[in] This Calling context.
|
||||||
@param Handle Parent Handle.
|
@param[in] Handle Parent Handle.
|
||||||
@param DiskIo Parent DiskIo interface.
|
@param[in] DiskIo Parent DiskIo interface.
|
||||||
@param BlockIo Parent BlockIo interface.
|
@param[in] BlockIo Parent BlockIo interface.
|
||||||
@param DevicePath Parent Device Path.
|
@param[in] BlockIo2 Parent BlockIo2 interface.
|
||||||
|
@param[in] DevicePath Parent Device Path.
|
||||||
|
|
||||||
@retval EFI_SUCCESS A child handle was added.
|
@retval EFI_SUCCESS A child handle was added.
|
||||||
@retval EFI_MEDIA_CHANGED Media change was detected.
|
@retval EFI_MEDIA_CHANGED Media change was detected.
|
||||||
|
@ -396,6 +409,7 @@ PartitionInstallMbrChildHandles (
|
||||||
IN EFI_HANDLE Handle,
|
IN EFI_HANDLE Handle,
|
||||||
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
||||||
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -406,6 +420,7 @@ EFI_STATUS
|
||||||
IN EFI_HANDLE Handle,
|
IN EFI_HANDLE Handle,
|
||||||
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
IN EFI_DISK_IO_PROTOCOL *DiskIo,
|
||||||
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
|
||||||
|
IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
# The partition of physical BlockIo device supported is one of legacy MBR, GPT,
|
# The partition of physical BlockIo device supported is one of legacy MBR, GPT,
|
||||||
# and "El Torito" partitions.
|
# and "El Torito" partitions.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2006 - 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
|
||||||
|
@ -70,5 +70,6 @@
|
||||||
gEfiDevicePathProtocolGuid ## BY_START
|
gEfiDevicePathProtocolGuid ## BY_START
|
||||||
gEfiDiskIoProtocolGuid ## BY_START
|
gEfiDiskIoProtocolGuid ## BY_START
|
||||||
gEfiBlockIoProtocolGuid ## TO_START
|
gEfiBlockIoProtocolGuid ## TO_START
|
||||||
|
gEfiBlockIo2ProtocolGuid ## TO_START
|
||||||
gEfiDevicePathProtocolGuid ## TO_START
|
gEfiDevicePathProtocolGuid ## TO_START
|
||||||
gEfiDiskIoProtocolGuid ## TO_START
|
gEfiDiskIoProtocolGuid ## TO_START
|
||||||
|
|
|
@ -894,6 +894,9 @@
|
||||||
## Include/Protocol/BlockIo.h
|
## Include/Protocol/BlockIo.h
|
||||||
gEfiBlockIoProtocolGuid = { 0x964E5B21, 0x6459, 0x11D2, { 0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }}
|
gEfiBlockIoProtocolGuid = { 0x964E5B21, 0x6459, 0x11D2, { 0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }}
|
||||||
|
|
||||||
|
## Include/Protocol/BlockIo2.h
|
||||||
|
gEfiBlockIo2ProtocolGuid = { 0xa77b2472, 0xe282, 0x4e9f, {0xa2, 0x45, 0xc2, 0xc0, 0xe2, 0x7b, 0xbc, 0xc1 }}
|
||||||
|
|
||||||
## Include/Protocol/UnicodeCollation.h
|
## Include/Protocol/UnicodeCollation.h
|
||||||
gEfiUnicodeCollationProtocolGuid = { 0x1D85CD7F, 0xF43D, 0x11D2, { 0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}
|
gEfiUnicodeCollationProtocolGuid = { 0x1D85CD7F, 0xF43D, 0x11D2, { 0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue