+/**\r
+ Terminate any in-flight non-blocking I/O requests by signaling an EFI_ABORTED\r
+ in the TransactionStatus member of the EFI_BLOCK_IO2_TOKEN for the non-blocking\r
+ I/O. After that it is safe to free any Token or Buffer data structures that\r
+ were allocated to initiate the non-blockingI/O requests that were in-flight for\r
+ this device.\r
+\r
+ @param[in] AtaDevice The ATA child device involved for the operation.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AtaTerminateNonBlockingTask (\r
+ IN ATA_DEVICE *AtaDevice\r
+ )\r
+{\r
+ BOOLEAN SubTaskEmpty;\r
+ EFI_TPL OldTpl;\r
+ ATA_BUS_ASYN_TASK *AtaTask;\r
+ LIST_ENTRY *Entry;\r
+ LIST_ENTRY *List;\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+ //\r
+ // Abort all executing tasks from now.\r
+ //\r
+ AtaDevice->Abort = TRUE;\r
+\r
+ List = &AtaDevice->AtaTaskList;\r
+ for (Entry = GetFirstNode (List); !IsNull (List, Entry);) {\r
+ AtaTask = ATA_ASYN_TASK_FROM_ENTRY (Entry);\r
+ AtaTask->Token->TransactionStatus = EFI_ABORTED;\r
+ gBS->SignalEvent (AtaTask->Token->Event);\r
+\r
+ Entry = RemoveEntryList (Entry);\r
+ FreePool (AtaTask);\r
+ }\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ do {\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+ //\r
+ // Wait for executing subtasks done.\r
+ //\r
+ SubTaskEmpty = IsListEmpty (&AtaDevice->AtaSubTaskList);\r
+ gBS->RestoreTPL (OldTpl);\r
+ } while (!SubTaskEmpty);\r
+\r
+ //\r
+ // Aborting operation has been done. From now on, don't need to abort normal operation.\r
+ // \r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+ AtaDevice->Abort = FALSE;\r
+ gBS->RestoreTPL (OldTpl);\r
+}\r
+\r