+/**\r
+ Aborts the asynchronous PassThru requests.\r
+\r
+ @param[in] Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA\r
+ data structure.\r
+\r
+ @retval EFI_SUCCESS The asynchronous PassThru requests have been aborted.\r
+ @return EFI_DEVICE_ERROR Fail to abort all the asynchronous PassThru requests.\r
+\r
+**/\r
+EFI_STATUS\r
+AbortAsyncPassThruTasks (\r
+ IN NVME_CONTROLLER_PRIVATE_DATA *Private\r
+ )\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *NextLink;\r
+ NVME_BLKIO2_SUBTASK *Subtask;\r
+ NVME_BLKIO2_REQUEST *BlkIo2Request;\r
+ NVME_PASS_THRU_ASYNC_REQ *AsyncRequest;\r
+ EFI_BLOCK_IO2_TOKEN *Token;\r
+ EFI_TPL OldTpl;\r
+ EFI_STATUS Status;\r
+\r
+ PciIo = Private->PciIo;\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+ //\r
+ // Cancel the unsubmitted subtasks.\r
+ //\r
+ for (Link = GetFirstNode (&Private->UnsubmittedSubtasks);\r
+ !IsNull (&Private->UnsubmittedSubtasks, Link);\r
+ Link = NextLink) {\r
+ NextLink = GetNextNode (&Private->UnsubmittedSubtasks, Link);\r
+ Subtask = NVME_BLKIO2_SUBTASK_FROM_LINK (Link);\r
+ BlkIo2Request = Subtask->BlockIo2Request;\r
+ Token = BlkIo2Request->Token;\r
+\r
+ BlkIo2Request->UnsubmittedSubtaskNum--;\r
+ if (Subtask->IsLast) {\r
+ BlkIo2Request->LastSubtaskSubmitted = TRUE;\r
+ }\r
+ Token->TransactionStatus = EFI_ABORTED;\r
+\r
+ RemoveEntryList (Link);\r
+ InsertTailList (&BlkIo2Request->SubtasksQueue, Link);\r
+ gBS->SignalEvent (Subtask->Event);\r
+ }\r
+\r
+ //\r
+ // Cleanup the resources for the asynchronous PassThru requests.\r
+ //\r
+ for (Link = GetFirstNode (&Private->AsyncPassThruQueue);\r
+ !IsNull (&Private->AsyncPassThruQueue, Link);\r
+ Link = NextLink) {\r
+ NextLink = GetNextNode (&Private->AsyncPassThruQueue, Link);\r
+ AsyncRequest = NVME_PASS_THRU_ASYNC_REQ_FROM_THIS (Link);\r
+\r
+ if (AsyncRequest->MapData != NULL) {\r
+ PciIo->Unmap (PciIo, AsyncRequest->MapData);\r
+ }\r
+ if (AsyncRequest->MapMeta != NULL) {\r
+ PciIo->Unmap (PciIo, AsyncRequest->MapMeta);\r
+ }\r
+ if (AsyncRequest->MapPrpList != NULL) {\r
+ PciIo->Unmap (PciIo, AsyncRequest->MapPrpList);\r
+ }\r
+ if (AsyncRequest->PrpListHost != NULL) {\r
+ PciIo->FreeBuffer (\r
+ PciIo,\r
+ AsyncRequest->PrpListNo,\r
+ AsyncRequest->PrpListHost\r
+ );\r
+ }\r
+\r
+ RemoveEntryList (Link);\r
+ gBS->SignalEvent (AsyncRequest->CallerEvent);\r
+ FreePool (AsyncRequest);\r
+ }\r
+\r
+ if (IsListEmpty (&Private->AsyncPassThruQueue) &&\r
+ IsListEmpty (&Private->UnsubmittedSubtasks)) {\r
+ Status = EFI_SUCCESS;\r
+ } else {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ return Status;\r
+}\r
+\r
+\r