+/**\r
+ Get Active Data Removal Mechanism Value.\r
+\r
+ @param[in] Session The session info for one opal device.\r
+ @param[in] GeneratedSid Generated SID of disk\r
+ @param[in] SidLength Length of generatedSid in bytes\r
+ @param[out] ActiveDataRemovalMechanism Return the active data removal mechanism.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+OpalUtilGetActiveDataRemovalMechanism (\r
+ OPAL_SESSION *Session,\r
+ const VOID *GeneratedSid,\r
+ UINT32 SidLength,\r
+ UINT8 *ActiveDataRemovalMechanism\r
+ )\r
+{\r
+ TCG_RESULT Ret;\r
+ UINT8 MethodStatus;\r
+\r
+ NULL_CHECK(Session);\r
+ NULL_CHECK(GeneratedSid);\r
+ NULL_CHECK(ActiveDataRemovalMechanism);\r
+\r
+ Ret = OpalStartSession(\r
+ Session,\r
+ OPAL_UID_ADMIN_SP,\r
+ TRUE,\r
+ SidLength,\r
+ GeneratedSid,\r
+ OPAL_ADMIN_SP_ANYBODY_AUTHORITY,\r
+ &MethodStatus\r
+ );\r
+ if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
+ DEBUG ((DEBUG_INFO, "Start session with admin SP as SID authority failed: Ret=%d MethodStatus=%u\n", Ret, MethodStatus));\r
+ if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
+ Ret = TcgResultFailure;\r
+ }\r
+ return Ret;\r
+ }\r
+\r
+ Ret = OpalPyrite2GetActiveDataRemovalMechanism (\r
+ Session,\r
+ ActiveDataRemovalMechanism\r
+ );\r
+\r
+ if (Ret != TcgResultSuccess) {\r
+ DEBUG ((DEBUG_INFO, "Pyrite2 Get Active Data Removal Mechanism failed: Ret=%d\n", Ret));\r
+ }\r
+\r
+ OpalEndSession(Session);\r
+\r
+ return Ret;\r
+}\r
+\r
+/**\r
+ Calculate the estimated time.\r
+\r
+ @param[in] IsMinite Whether the input time value is minute type or second type.\r
+ @param[in] Time The input time value.\r
+\r
+**/\r
+UINT32\r
+CalculateDataRemovalTime (\r
+ IN BOOLEAN IsMinute,\r
+ IN UINT16 Time\r
+ )\r
+{\r
+ if (IsMinute) {\r
+ return Time * 2 * 60;\r
+ } else {\r
+ return Time * 2;\r
+ }\r
+}\r
+\r
+/**\r
+ Return the estimated time for specific type.\r
+\r
+ @param[in] Index The input data removal type.\r
+ @param[in] Descriptor DATA_REMOVAL_FEATURE_DESCRIPTOR\r
+\r
+**/\r
+UINT32\r
+GetDataRemovalTime (\r
+ IN UINT8 Index,\r
+ IN DATA_REMOVAL_FEATURE_DESCRIPTOR *Descriptor\r
+ )\r
+{\r
+ switch (Index) {\r
+ case OverwriteDataErase:\r
+ return CalculateDataRemovalTime (Descriptor->FormatBit0, SwapBytes16 (Descriptor->TimeBit0));\r
+\r
+ case BlockErase:\r
+ return CalculateDataRemovalTime (Descriptor->FormatBit1, SwapBytes16 (Descriptor->TimeBit1));\r
+\r
+ case CryptoErase:\r
+ return CalculateDataRemovalTime (Descriptor->FormatBit2, SwapBytes16 (Descriptor->TimeBit2));\r
+\r
+ case Unmap:\r
+ return CalculateDataRemovalTime (Descriptor->FormatBit3, SwapBytes16 (Descriptor->TimeBit3));\r
+\r
+ case ResetWritePointers:\r
+ return CalculateDataRemovalTime (Descriptor->FormatBit4, SwapBytes16 (Descriptor->TimeBit4));\r
+\r
+ case VendorSpecificErase:\r
+ return CalculateDataRemovalTime (Descriptor->FormatBit5, SwapBytes16 (Descriptor->TimeBit5));\r
+\r
+ default:\r
+ return 0;\r
+ }\r
+}\r
+\r
+/**\r
+ Get the supported Data Removal Mechanism list.\r
+\r
+ @param[in] Session The session info for one opal device.\r
+ @param[out] RemovalMechanismLists Return the supported data removal mechanism lists.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+OpalUtilGetDataRemovalMechanismLists (\r
+ IN OPAL_SESSION *Session,\r
+ OUT UINT32 *RemovalMechanismLists\r
+ )\r
+{\r
+ TCG_RESULT Ret;\r
+ UINTN DataSize;\r
+ DATA_REMOVAL_FEATURE_DESCRIPTOR Descriptor;\r
+ UINT8 Index;\r
+ UINT8 BitValue;\r
+\r
+ NULL_CHECK(Session);\r
+ NULL_CHECK(RemovalMechanismLists);\r
+\r
+ DataSize = sizeof (Descriptor);\r
+ Ret = OpalGetFeatureDescriptor (Session, TCG_FEATURE_DATA_REMOVAL, &DataSize, &Descriptor);\r
+ if (Ret != TcgResultSuccess) {\r
+ return TcgResultFailure;\r
+ }\r
+\r
+ ASSERT (Descriptor.RemovalMechanism != 0);\r
+\r
+ for (Index = 0; Index < ResearvedMechanism; Index ++) {\r
+ BitValue = (BOOLEAN) BitFieldRead8 (Descriptor.RemovalMechanism, Index, Index);\r
+\r
+ if (BitValue == 0) {\r
+ RemovalMechanismLists[Index] = 0;\r
+ } else {\r
+ RemovalMechanismLists[Index] = GetDataRemovalTime (Index, &Descriptor);\r
+ }\r
+ }\r
+\r
+ return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+ Get revert timeout value.\r
+\r
+ @param[in] Session The session info for one opal device.\r
+\r
+**/\r
+UINT32\r
+GetRevertTimeOut (\r
+ IN OPAL_SESSION *Session\r
+ )\r
+{\r
+ TCG_RESULT TcgResult;\r
+ OPAL_DISK_SUPPORT_ATTRIBUTE SupportedAttributes;\r
+ UINT16 BaseComId;\r
+ UINT32 MsidLength;\r
+ UINT8 Msid[OPAL_MSID_LENGHT];\r
+ UINT32 RemovalMechanishLists[ResearvedMechanism];\r
+ UINT8 ActiveDataRemovalMechanism;\r
+\r
+ TcgResult = OpalGetSupportedAttributesInfo (Session, &SupportedAttributes, &BaseComId);\r
+ if (TcgResult != TcgResultSuccess || SupportedAttributes.DataRemoval == 0) {\r
+ return 0;\r
+ }\r
+\r
+ TcgResult = OpalUtilGetMsid (Session, Msid, OPAL_MSID_LENGHT, &MsidLength);\r
+ if (TcgResult != TcgResultSuccess) {\r
+ return 0;\r
+ }\r
+\r
+ TcgResult = OpalUtilGetDataRemovalMechanismLists (Session, RemovalMechanishLists);\r
+ if (TcgResult != TcgResultSuccess) {\r
+ return 0;\r
+ }\r
+\r
+ TcgResult = OpalUtilGetActiveDataRemovalMechanism (Session, Msid, MsidLength, &ActiveDataRemovalMechanism);\r
+ if (TcgResult != TcgResultSuccess) {\r
+ return 0;\r
+ }\r
+\r
+ return RemovalMechanishLists[ActiveDataRemovalMechanism];\r
+}\r