mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-25 14:44:28 +02:00
Introduce tow non-blocking task lists to AtaBus. One maintains the sub-task which is related to running Ata Task and the other is for waiting Ata Task. And it will not pass any task to AtaAtapiPassThru until the previous Ata task has been finished or met error.
Signed-off-by: qianouyang Reviewed-by: czhang46 erictian git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13105 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
be30ddf795
commit
58727f29ea
@ -2,7 +2,7 @@
|
||||
This file implements ATA_PASSTHRU_PROCTOCOL and EXT_SCSI_PASSTHRU_PROTOCOL interfaces
|
||||
for managed ATA controllers.
|
||||
|
||||
Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@ -408,23 +408,24 @@ AsyncNonBlockingTransferRoutine (
|
||||
);
|
||||
|
||||
//
|
||||
// If the data transfer meet a error which is not dumped into the status block
|
||||
// set the Status block related bit.
|
||||
// If the data transfer meet a error, remove all tasks in the list since these tasks are
|
||||
// associated with one task from Ata Bus and signal the event with error status.
|
||||
//
|
||||
if ((Status != EFI_NOT_READY) && (Status != EFI_SUCCESS)) {
|
||||
Task->Packet->Asb->AtaStatus = 0x01;
|
||||
DestroyAsynTaskList (Instance, TRUE);
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// 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.
|
||||
// is not finished yet. Otherwise the operation is successful.
|
||||
//
|
||||
if (Status != EFI_NOT_READY) {
|
||||
if (Status == EFI_NOT_READY) {
|
||||
break;
|
||||
} else {
|
||||
RemoveEntryList (&Task->Link);
|
||||
gBS->SignalEvent (Task->Event);
|
||||
FreePool (Task);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -872,7 +873,7 @@ AtaAtapiPassThruStop (
|
||||
gBS->CloseEvent (Instance->TimerEvent);
|
||||
Instance->TimerEvent = NULL;
|
||||
}
|
||||
DestroyAsynTaskList (Instance);
|
||||
DestroyAsynTaskList (Instance, FALSE);
|
||||
|
||||
//
|
||||
// Disable this ATA host controller.
|
||||
@ -1090,12 +1091,15 @@ DestroyDeviceInfoList (
|
||||
Destroy all pending non blocking tasks.
|
||||
|
||||
@param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
|
||||
@param[in] IsSigEvent Indicate whether signal the task event when remove the
|
||||
task.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
DestroyAsynTaskList (
|
||||
IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance
|
||||
IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
|
||||
IN BOOLEAN IsSigEvent
|
||||
)
|
||||
{
|
||||
LIST_ENTRY *Entry;
|
||||
@ -1116,6 +1120,10 @@ DestroyAsynTaskList (
|
||||
Task = ATA_NON_BLOCK_TASK_FROM_ENTRY (DelEntry);
|
||||
|
||||
RemoveEntryList (DelEntry);
|
||||
if (IsSigEvent) {
|
||||
Task->Packet->Asb->AtaStatus = 0x01;
|
||||
gBS->SignalEvent (Task->Event);
|
||||
}
|
||||
FreePool (Task);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
Header file for ATA/ATAPI PASS THRU driver.
|
||||
|
||||
Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@ -492,12 +492,15 @@ DestroyDeviceInfoList (
|
||||
Destroy all pending non blocking tasks.
|
||||
|
||||
@param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
|
||||
@param[in] IsSigEvent Indicate whether signal the task event when remove the
|
||||
task.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
DestroyAsynTaskList (
|
||||
IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance
|
||||
IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
|
||||
IN BOOLEAN IsSigEvent
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -4,7 +4,7 @@
|
||||
This file implements protocol interfaces: Driver Binding protocol,
|
||||
Block IO protocol and DiskInfo protocol.
|
||||
|
||||
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@ -87,7 +87,8 @@ ATA_DEVICE gAtaDeviceTemplate = {
|
||||
NULL, // IdentifyData
|
||||
NULL, // ControllerNameTable
|
||||
{L'\0', }, // ModelName
|
||||
{NULL, NULL} // AtaTaskList
|
||||
{NULL, NULL}, // AtaTaskList
|
||||
{NULL, NULL} // AtaSubTaskList
|
||||
};
|
||||
|
||||
/**
|
||||
@ -147,7 +148,8 @@ ReleaseAtaResources (
|
||||
IN ATA_DEVICE *AtaDevice
|
||||
)
|
||||
{
|
||||
ATA_BUS_ASYN_TASK *Task;
|
||||
ATA_BUS_ASYN_SUB_TASK *SubTask;
|
||||
ATA_BUS_ASYN_TASK *AtaTask;
|
||||
LIST_ENTRY *Entry;
|
||||
LIST_ENTRY *DelEntry;
|
||||
EFI_TPL OldTpl;
|
||||
@ -159,6 +161,21 @@ ReleaseAtaResources (
|
||||
FreePool (AtaDevice->DevicePath);
|
||||
}
|
||||
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||
if (!IsListEmpty (&AtaDevice->AtaSubTaskList)) {
|
||||
//
|
||||
// Free the Subtask list.
|
||||
//
|
||||
for(Entry = AtaDevice->AtaSubTaskList.ForwardLink;
|
||||
Entry != (&AtaDevice->AtaSubTaskList);
|
||||
) {
|
||||
DelEntry = Entry;
|
||||
Entry = Entry->ForwardLink;
|
||||
SubTask = ATA_AYNS_SUB_TASK_FROM_ENTRY (DelEntry);
|
||||
|
||||
RemoveEntryList (DelEntry);
|
||||
FreeAtaSubTask (SubTask);
|
||||
}
|
||||
}
|
||||
if (!IsListEmpty (&AtaDevice->AtaTaskList)) {
|
||||
//
|
||||
// Free the Subtask list.
|
||||
@ -168,10 +185,10 @@ ReleaseAtaResources (
|
||||
) {
|
||||
DelEntry = Entry;
|
||||
Entry = Entry->ForwardLink;
|
||||
Task = ATA_AYNS_TASK_FROM_ENTRY (DelEntry);
|
||||
AtaTask = ATA_AYNS_TASK_FROM_ENTRY (DelEntry);
|
||||
|
||||
RemoveEntryList (DelEntry);
|
||||
FreeAtaSubTask (Task);
|
||||
FreePool (AtaTask);
|
||||
}
|
||||
}
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
@ -273,6 +290,7 @@ RegisterAtaDevice (
|
||||
// Initial Ata Task List
|
||||
//
|
||||
InitializeListHead (&AtaDevice->AtaTaskList);
|
||||
InitializeListHead (&AtaDevice->AtaSubTaskList);
|
||||
|
||||
//
|
||||
// Try to identify the ATA device via the ATA pass through command.
|
||||
|
@ -4,7 +4,7 @@
|
||||
This file defines common data structures, macro definitions and some module
|
||||
internal function header files.
|
||||
|
||||
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@ -35,6 +35,7 @@
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
#include <Library/TimerLib.h>
|
||||
|
||||
#include <IndustryStandard/Atapi.h>
|
||||
|
||||
@ -78,21 +79,9 @@
|
||||
|
||||
#define ATA_TASK_SIGNATURE SIGNATURE_32 ('A', 'T', 'S', 'K')
|
||||
#define ATA_DEVICE_SIGNATURE SIGNATURE_32 ('A', 'B', 'I', 'D')
|
||||
|
||||
#define ATA_SUB_TASK_SIGNATURE SIGNATURE_32 ('A', 'S', 'T', 'S')
|
||||
#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
|
||||
//
|
||||
@ -140,12 +129,41 @@ typedef struct {
|
||||
CHAR16 ModelName[MAX_MODEL_NAME_LEN + 1];
|
||||
|
||||
LIST_ENTRY AtaTaskList;
|
||||
LIST_ENTRY AtaSubTaskList;
|
||||
} ATA_DEVICE;
|
||||
|
||||
//
|
||||
// Sub-Task for the non blocking I/O
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
ATA_DEVICE *AtaDevice;
|
||||
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_SUB_TASK;
|
||||
|
||||
//
|
||||
// Task for the non blocking I/O
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
EFI_BLOCK_IO2_TOKEN *Token;
|
||||
ATA_DEVICE *AtaDevice;
|
||||
UINT8 *Buffer;
|
||||
EFI_LBA StartLba;
|
||||
UINTN NumberOfBlocks;
|
||||
BOOLEAN IsWrite;
|
||||
LIST_ENTRY TaskEntry;
|
||||
} ATA_BUS_ASYN_TASK;
|
||||
|
||||
#define ATA_DEVICE_FROM_BLOCK_IO(a) CR (a, ATA_DEVICE, BlockIo, 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_DEVICE_FROM_STORAGE_SECURITY(a) CR (a, ATA_DEVICE, StorageSecurity, ATA_DEVICE_SIGNATURE)
|
||||
#define ATA_AYNS_SUB_TASK_FROM_ENTRY(a) CR (a, ATA_BUS_ASYN_SUB_TASK, TaskEntry, ATA_SUB_TASK_SIGNATURE)
|
||||
#define ATA_AYNS_TASK_FROM_ENTRY(a) CR (a, ATA_BUS_ASYN_TASK, TaskEntry, ATA_TASK_SIGNATURE)
|
||||
|
||||
//
|
||||
@ -199,7 +217,7 @@ FreeAlignedBuffer (
|
||||
VOID
|
||||
EFIAPI
|
||||
FreeAtaSubTask (
|
||||
IN OUT ATA_BUS_ASYN_TASK *Task
|
||||
IN OUT ATA_BUS_ASYN_SUB_TASK *Task
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -54,7 +54,7 @@
|
||||
BaseLib
|
||||
UefiDriverEntryPoint
|
||||
DebugLib
|
||||
|
||||
TimerLib
|
||||
|
||||
[Guids]
|
||||
gEfiDiskInfoIdeInterfaceGuid # CONSUMES ## GUID
|
||||
|
@ -10,7 +10,7 @@
|
||||
for Security Protocol Specific layout. This implementation uses big endian for
|
||||
Cylinder register.
|
||||
|
||||
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@ -527,7 +527,7 @@ TransferAtaDevice (
|
||||
VOID
|
||||
EFIAPI
|
||||
FreeAtaSubTask (
|
||||
IN OUT ATA_BUS_ASYN_TASK *Task
|
||||
IN OUT ATA_BUS_ASYN_SUB_TASK *Task
|
||||
)
|
||||
{
|
||||
if (Task->Packet.Asb != NULL) {
|
||||
@ -555,11 +555,17 @@ AtaNonBlockingCallBack (
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
ATA_BUS_ASYN_TASK *Task;
|
||||
ATA_BUS_ASYN_SUB_TASK *Task;
|
||||
ATA_BUS_ASYN_TASK *AtaTask;
|
||||
ATA_DEVICE *AtaDevice;
|
||||
LIST_ENTRY *Entry;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Task = (ATA_BUS_ASYN_TASK *) Context;
|
||||
Task = (ATA_BUS_ASYN_SUB_TASK *) Context;
|
||||
gBS->CloseEvent (Event);
|
||||
|
||||
AtaDevice = Task->AtaDevice;
|
||||
|
||||
//
|
||||
// Check the command status.
|
||||
// If there is error during the sub task source allocation, the error status
|
||||
@ -597,6 +603,31 @@ AtaNonBlockingCallBack (
|
||||
|
||||
FreePool (Task->UnsignalledEventCount);
|
||||
FreePool (Task->IsError);
|
||||
|
||||
|
||||
//
|
||||
// Finish all subtasks and move to the next task in AtaTaskList.
|
||||
//
|
||||
if (!IsListEmpty (&AtaDevice->AtaTaskList)) {
|
||||
Entry = GetFirstNode (&AtaDevice->AtaTaskList);
|
||||
AtaTask = ATA_AYNS_TASK_FROM_ENTRY (Entry);
|
||||
DEBUG ((EFI_D_BLKIO, "Start to embark a new Ata Task\n"));
|
||||
DEBUG ((EFI_D_BLKIO, "AtaTask->NumberOfBlocks = %x; AtaTask->Token=%x\n", AtaTask->NumberOfBlocks, AtaTask->Token));
|
||||
Status = AccessAtaDevice (
|
||||
AtaTask->AtaDevice,
|
||||
AtaTask->Buffer,
|
||||
AtaTask->StartLba,
|
||||
AtaTask->NumberOfBlocks,
|
||||
AtaTask->IsWrite,
|
||||
AtaTask->Token
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
AtaTask->Token->TransactionStatus = Status;
|
||||
gBS->SignalEvent (AtaTask->Token->Event);
|
||||
}
|
||||
RemoveEntryList (Entry);
|
||||
FreePool (AtaTask);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG ((
|
||||
@ -647,9 +678,10 @@ AccessAtaDevice(
|
||||
UINTN MaxTransferBlockNumber;
|
||||
UINTN TransferBlockNumber;
|
||||
UINTN BlockSize;
|
||||
ATA_BUS_ASYN_SUB_TASK *SubTask;
|
||||
UINTN *EventCount;
|
||||
UINTN TempCount;
|
||||
ATA_BUS_ASYN_TASK *Task;
|
||||
ATA_BUS_ASYN_TASK *AtaTask;
|
||||
EFI_EVENT SubEvent;
|
||||
UINTN Index;
|
||||
BOOLEAN *IsError;
|
||||
@ -660,8 +692,9 @@ AccessAtaDevice(
|
||||
EventCount = NULL;
|
||||
IsError = NULL;
|
||||
Index = 0;
|
||||
Task = NULL;
|
||||
SubTask = NULL;
|
||||
SubEvent = NULL;
|
||||
AtaTask = NULL;
|
||||
|
||||
//
|
||||
// Ensure AtaDevice->Lba48Bit is a valid boolean value
|
||||
@ -674,8 +707,28 @@ AccessAtaDevice(
|
||||
// Initial the return status and shared account for Non Blocking.
|
||||
//
|
||||
if ((Token != NULL) && (Token->Event != NULL)) {
|
||||
Token->TransactionStatus = EFI_SUCCESS;
|
||||
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||
if (!IsListEmpty (&AtaDevice->AtaSubTaskList)) {
|
||||
AtaTask = AllocateZeroPool (sizeof (ATA_BUS_ASYN_TASK));
|
||||
if (AtaTask == NULL) {
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
AtaTask->AtaDevice = AtaDevice;
|
||||
AtaTask->Buffer = Buffer;
|
||||
AtaTask->IsWrite = IsWrite;
|
||||
AtaTask->NumberOfBlocks = NumberOfBlocks;
|
||||
AtaTask->Signature = ATA_TASK_SIGNATURE;
|
||||
AtaTask->StartLba = StartLba;
|
||||
AtaTask->Token = Token;
|
||||
|
||||
InsertTailList (&AtaDevice->AtaTaskList, &AtaTask->TaskEntry);
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
Token->TransactionStatus = EFI_SUCCESS;
|
||||
EventCount = AllocateZeroPool (sizeof (UINTN));
|
||||
if (EventCount == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
@ -686,10 +739,20 @@ AccessAtaDevice(
|
||||
FreePool (EventCount);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
DEBUG ((EFI_D_BLKIO, "Allocation IsError Addr=%x\n", IsError));
|
||||
*IsError = FALSE;
|
||||
|
||||
TempCount = (NumberOfBlocks + MaxTransferBlockNumber - 1) / MaxTransferBlockNumber;
|
||||
*EventCount = TempCount;
|
||||
DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, NumberOfBlocks=%x\n", NumberOfBlocks));
|
||||
DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, MaxTransferBlockNumber=%x\n", MaxTransferBlockNumber));
|
||||
DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, EventCount=%x\n", TempCount));
|
||||
}else {
|
||||
while (!IsListEmpty (&AtaDevice->AtaTaskList) || !IsListEmpty (&AtaDevice->AtaSubTaskList)) {
|
||||
//
|
||||
// Stall for 100us.
|
||||
//
|
||||
MicroSecondDelay (100);
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
@ -705,27 +768,29 @@ AccessAtaDevice(
|
||||
// Create sub event for the sub ata task. Non-blocking mode.
|
||||
//
|
||||
if ((Token != NULL) && (Token->Event != NULL)) {
|
||||
Task = NULL;
|
||||
SubTask = NULL;
|
||||
SubEvent = NULL;
|
||||
|
||||
Task = AllocateZeroPool (sizeof (ATA_BUS_ASYN_TASK));
|
||||
if (Task == NULL) {
|
||||
SubTask = AllocateZeroPool (sizeof (ATA_BUS_ASYN_SUB_TASK));
|
||||
if (SubTask == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||
Task->UnsignalledEventCount = EventCount;
|
||||
Task->Token = Token;
|
||||
Task->IsError = IsError;
|
||||
InsertTailList (&AtaDevice->AtaTaskList, &Task->TaskEntry);
|
||||
SubTask->UnsignalledEventCount = EventCount;
|
||||
SubTask->Signature = ATA_SUB_TASK_SIGNATURE;
|
||||
SubTask->AtaDevice = AtaDevice;
|
||||
SubTask->Token = Token;
|
||||
SubTask->IsError = IsError;
|
||||
InsertTailList (&AtaDevice->AtaSubTaskList, &SubTask->TaskEntry);
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_NOTIFY,
|
||||
AtaNonBlockingCallBack,
|
||||
Task,
|
||||
SubTask,
|
||||
&SubEvent
|
||||
);
|
||||
//
|
||||
@ -737,11 +802,12 @@ AccessAtaDevice(
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
Status = TransferAtaDevice (AtaDevice, &Task->Packet, Buffer, StartLba, (UINT32) TransferBlockNumber, IsWrite, SubEvent);
|
||||
Status = TransferAtaDevice (AtaDevice, &SubTask->Packet, Buffer, StartLba, (UINT32) TransferBlockNumber, IsWrite, SubEvent);
|
||||
} else {
|
||||
//
|
||||
// Blocking Mode.
|
||||
//
|
||||
DEBUG ((EFI_D_BLKIO, "Blocking AccessAtaDevice, TransferBlockNumber=%x; StartLba = %x\n", TransferBlockNumber, StartLba));
|
||||
Status = TransferAtaDevice (AtaDevice, NULL, Buffer, StartLba, (UINT32) TransferBlockNumber, IsWrite, NULL);
|
||||
}
|
||||
|
||||
@ -770,15 +836,14 @@ EXIT:
|
||||
FreePool (IsError);
|
||||
}
|
||||
|
||||
if (Task != NULL) {
|
||||
RemoveEntryList (&Task->TaskEntry);
|
||||
FreeAtaSubTask (Task);
|
||||
if (SubTask != NULL) {
|
||||
RemoveEntryList (&SubTask->TaskEntry);
|
||||
FreeAtaSubTask (SubTask);
|
||||
}
|
||||
|
||||
if (SubEvent != NULL) {
|
||||
gBS->CloseEvent (SubEvent);
|
||||
}
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user