MdeModulePkg/AtaBus&AtaAtapiPassThru: Update ATA drivers to follow UEFI2.4 new request in which it requests ResetEx() to terminate any in-flight non-blocking IO request with EFI_ABORTED transaction status.

Signed-off-by: Tian, Feng <feng.tian@intel.com>
reviewed-by: Ni, Ruiyu <ruiyu.ni@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14761 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Tian, Feng 2013-10-10 05:57:50 +00:00 committed by erictian
parent 5bcb62a409
commit 71fd9fae8b
4 changed files with 120 additions and 25 deletions

View File

@ -1764,7 +1764,10 @@ AtaPassThruResetPort (
IN UINT16 Port IN UINT16 Port
) )
{ {
return EFI_UNSUPPORTED; //
// Return success directly then upper layer driver could think reset port operation is done.
//
return EFI_SUCCESS;
} }
/** /**
@ -1806,7 +1809,10 @@ AtaPassThruResetDevice (
IN UINT16 PortMultiplierPort IN UINT16 PortMultiplierPort
) )
{ {
return EFI_UNSUPPORTED; //
// Return success directly then upper layer driver could think reset device operation is done.
//
return EFI_SUCCESS;
} }
/** /**
@ -2274,7 +2280,10 @@ ExtScsiPassThruResetChannel (
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This
) )
{ {
return EFI_UNSUPPORTED; //
// Return success directly then upper layer driver could think reset channel operation is done.
//
return EFI_SUCCESS;
} }
/** /**
@ -2304,7 +2313,10 @@ ExtScsiPassThruResetTargetLun (
IN UINT64 Lun IN UINT64 Lun
) )
{ {
return EFI_UNSUPPORTED; //
// Return success directly then upper layer driver could think reset target LUN operation is done.
//
return EFI_SUCCESS;
} }
/** /**

View File

@ -90,7 +90,8 @@ ATA_DEVICE gAtaDeviceTemplate = {
NULL, // ControllerNameTable NULL, // ControllerNameTable
{L'\0', }, // ModelName {L'\0', }, // ModelName
{NULL, NULL}, // AtaTaskList {NULL, NULL}, // AtaTaskList
{NULL, NULL} // AtaSubTaskList {NULL, NULL}, // AtaSubTaskList
FALSE // Abort
}; };
/** /**
@ -172,7 +173,7 @@ ReleaseAtaResources (
) { ) {
DelEntry = Entry; DelEntry = Entry;
Entry = Entry->ForwardLink; Entry = Entry->ForwardLink;
SubTask = ATA_AYNS_SUB_TASK_FROM_ENTRY (DelEntry); SubTask = ATA_ASYN_SUB_TASK_FROM_ENTRY (DelEntry);
RemoveEntryList (DelEntry); RemoveEntryList (DelEntry);
FreeAtaSubTask (SubTask); FreeAtaSubTask (SubTask);
@ -187,7 +188,7 @@ ReleaseAtaResources (
) { ) {
DelEntry = Entry; DelEntry = Entry;
Entry = Entry->ForwardLink; Entry = Entry->ForwardLink;
AtaTask = ATA_AYNS_TASK_FROM_ENTRY (DelEntry); AtaTask = ATA_ASYN_TASK_FROM_ENTRY (DelEntry);
RemoveEntryList (DelEntry); RemoveEntryList (DelEntry);
FreePool (AtaTask); FreePool (AtaTask);
@ -1217,6 +1218,8 @@ AtaBlockIoResetEx (
AtaDevice = ATA_DEVICE_FROM_BLOCK_IO2 (This); AtaDevice = ATA_DEVICE_FROM_BLOCK_IO2 (This);
AtaTerminateNonBlockingTask (AtaDevice);
Status = ResetAtaDevice (AtaDevice); Status = ResetAtaDevice (AtaDevice);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {

View File

@ -4,7 +4,7 @@
This file defines common data structures, macro definitions and some module This file defines common data structures, macro definitions and some module
internal function header files. internal function header files.
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> Copyright (c) 2009 - 2013, 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
@ -148,6 +148,7 @@ typedef struct {
LIST_ENTRY AtaTaskList; LIST_ENTRY AtaTaskList;
LIST_ENTRY AtaSubTaskList; LIST_ENTRY AtaSubTaskList;
BOOLEAN Abort;
} ATA_DEVICE; } ATA_DEVICE;
// //
@ -181,8 +182,8 @@ typedef struct {
#define ATA_DEVICE_FROM_BLOCK_IO2(a) CR (a, ATA_DEVICE, BlockIo2, 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_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_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_ASYN_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) #define ATA_ASYN_TASK_FROM_ENTRY(a) CR (a, ATA_BUS_ASYN_TASK, TaskEntry, ATA_TASK_SIGNATURE)
// //
// Global Variables // Global Variables
@ -301,6 +302,7 @@ AccessAtaDevice(
IN BOOLEAN IsWrite, IN BOOLEAN IsWrite,
IN OUT EFI_BLOCK_IO2_TOKEN *Token IN OUT EFI_BLOCK_IO2_TOKEN *Token
); );
/** /**
Trust transfer data from/to ATA device. Trust transfer data from/to ATA device.
@ -804,6 +806,22 @@ AtaBlockIoFlushBlocksEx (
IN OUT EFI_BLOCK_IO2_TOKEN *Token IN OUT EFI_BLOCK_IO2_TOKEN *Token
); );
/**
Terminate any in-flight non-blocking I/O requests by signaling an EFI_ABORTED
in the TransactionStatus member of the EFI_BLOCK_IO2_TOKEN for the non-blocking
I/O. After that it is safe to free any Token or Buffer data structures that
were allocated to initiate the non-blockingI/O requests that were in-flight for
this device.
@param[in] AtaDevice The ATA child device involved for the operation.
**/
VOID
EFIAPI
AtaTerminateNonBlockingTask (
IN ATA_DEVICE *AtaDevice
);
/** /**
Provides inquiry information for the controller type. Provides inquiry information for the controller type.

View File

@ -582,6 +582,62 @@ FreeAtaSubTask (
FreePool (Task); FreePool (Task);
} }
/**
Terminate any in-flight non-blocking I/O requests by signaling an EFI_ABORTED
in the TransactionStatus member of the EFI_BLOCK_IO2_TOKEN for the non-blocking
I/O. After that it is safe to free any Token or Buffer data structures that
were allocated to initiate the non-blockingI/O requests that were in-flight for
this device.
@param[in] AtaDevice The ATA child device involved for the operation.
**/
VOID
EFIAPI
AtaTerminateNonBlockingTask (
IN ATA_DEVICE *AtaDevice
)
{
BOOLEAN SubTaskEmpty;
EFI_TPL OldTpl;
ATA_BUS_ASYN_TASK *AtaTask;
LIST_ENTRY *Entry;
LIST_ENTRY *List;
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
//
// Abort all executing tasks from now.
//
AtaDevice->Abort = TRUE;
List = &AtaDevice->AtaTaskList;
for (Entry = GetFirstNode (List); !IsNull (List, Entry);) {
AtaTask = ATA_ASYN_TASK_FROM_ENTRY (Entry);
AtaTask->Token->TransactionStatus = EFI_ABORTED;
gBS->SignalEvent (AtaTask->Token->Event);
Entry = RemoveEntryList (Entry);
FreePool (AtaTask);
}
gBS->RestoreTPL (OldTpl);
do {
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
//
// Wait for executing subtasks done.
//
SubTaskEmpty = IsListEmpty (&AtaDevice->AtaSubTaskList);
gBS->RestoreTPL (OldTpl);
} while (!SubTaskEmpty);
//
// Aborting operation has been done. From now on, don't need to abort normal operation.
//
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
AtaDevice->Abort = FALSE;
gBS->RestoreTPL (OldTpl);
}
/** /**
Call back funtion when the event is signaled. Call back funtion when the event is signaled.
@ -617,6 +673,11 @@ AtaNonBlockingCallBack (
if ((!(*Task->IsError)) && ((Task->Packet.Asb->AtaStatus & 0x01) == 0x01)) { if ((!(*Task->IsError)) && ((Task->Packet.Asb->AtaStatus & 0x01) == 0x01)) {
Task->Token->TransactionStatus = EFI_DEVICE_ERROR; Task->Token->TransactionStatus = EFI_DEVICE_ERROR;
} }
if (AtaDevice->Abort) {
Task->Token->TransactionStatus = EFI_ABORTED;
}
DEBUG (( DEBUG ((
EFI_D_BLKIO, EFI_D_BLKIO,
"NON-BLOCKING EVENT FINISHED!- STATUS = %r\n", "NON-BLOCKING EVENT FINISHED!- STATUS = %r\n",
@ -652,7 +713,7 @@ AtaNonBlockingCallBack (
// //
if (!IsListEmpty (&AtaDevice->AtaTaskList)) { if (!IsListEmpty (&AtaDevice->AtaTaskList)) {
Entry = GetFirstNode (&AtaDevice->AtaTaskList); Entry = GetFirstNode (&AtaDevice->AtaTaskList);
AtaTask = ATA_AYNS_TASK_FROM_ENTRY (Entry); AtaTask = ATA_ASYN_TASK_FROM_ENTRY (Entry);
DEBUG ((EFI_D_BLKIO, "Start to embark a new Ata Task\n")); 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)); DEBUG ((EFI_D_BLKIO, "AtaTask->NumberOfBlocks = %x; AtaTask->Token=%x\n", AtaTask->NumberOfBlocks, AtaTask->Token));
Status = AccessAtaDevice ( Status = AccessAtaDevice (
@ -750,6 +811,7 @@ AccessAtaDevice(
// //
if ((Token != NULL) && (Token->Event != NULL)) { if ((Token != NULL) && (Token->Event != NULL)) {
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
if (!IsListEmpty (&AtaDevice->AtaSubTaskList)) { if (!IsListEmpty (&AtaDevice->AtaSubTaskList)) {
AtaTask = AllocateZeroPool (sizeof (ATA_BUS_ASYN_TASK)); AtaTask = AllocateZeroPool (sizeof (ATA_BUS_ASYN_TASK));
if (AtaTask == NULL) { if (AtaTask == NULL) {
@ -788,7 +850,7 @@ AccessAtaDevice(
DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, NumberOfBlocks=%x\n", NumberOfBlocks)); DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, NumberOfBlocks=%x\n", NumberOfBlocks));
DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, MaxTransferBlockNumber=%x\n", MaxTransferBlockNumber)); DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, MaxTransferBlockNumber=%x\n", MaxTransferBlockNumber));
DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, EventCount=%x\n", TempCount)); DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, EventCount=%x\n", TempCount));
}else { } else {
while (!IsListEmpty (&AtaDevice->AtaTaskList) || !IsListEmpty (&AtaDevice->AtaSubTaskList)) { while (!IsListEmpty (&AtaDevice->AtaTaskList) || !IsListEmpty (&AtaDevice->AtaSubTaskList)) {
// //
// Stall for 100us. // Stall for 100us.