+/**\r
+ The function extracts device information from OpalDeviceList and creat SmmDeviceList used for S3.\r
+\r
+ @param[in] OpalDeviceList Opal device list created at POST which contains the information of OPAL_DISK_AND_PASSWORD_INFO\r
+ @param[in,out] SmmDeviceList Opal Smm device list to be created and used for unlocking devices at S3 resume.\r
+\r
+ @retval EFI_SUCCESS Create SmmDeviceList successfully.\r
+ @retval Others Other execution results.\r
+**/\r
+EFI_STATUS\r
+CreateSmmDeviceList (\r
+ IN LIST_ENTRY *OpalDeviceList,\r
+ IN OUT LIST_ENTRY *SmmDeviceList\r
+ )\r
+{\r
+ LIST_ENTRY *Entry;\r
+ OPAL_DISK_AND_PASSWORD_INFO *PciDev;\r
+ OPAL_SMM_DEVICE *SmmDev;\r
+\r
+ for (Entry = OpalDeviceList->ForwardLink; Entry != OpalDeviceList; Entry = Entry->ForwardLink) {\r
+ PciDev = BASE_CR (Entry, OPAL_DISK_AND_PASSWORD_INFO, Link);\r
+\r
+ SmmDev = AllocateZeroPool (sizeof (OPAL_SMM_DEVICE));\r
+ if (SmmDev == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ SmmDev->Signature = OPAL_SMM_DEVICE_SIGNATURE;\r
+\r
+ ExtractDeviceInfoFromDevicePath(&PciDev->OpalDevicePath, SmmDev);\r
+\r
+ SmmDev->PasswordLength = PciDev->PasswordLength;\r
+ CopyMem(&(SmmDev->Password), PciDev->Password, OPAL_PASSWORD_MAX_LENGTH);\r
+\r
+ SmmDev->Sscp.ReceiveData = SecurityReceiveData;\r
+ SmmDev->Sscp.SendData = SecuritySendData;\r
+\r
+ DEBUG ((DEBUG_INFO, "Opal SMM: Insert device node to SmmDeviceList:\n"));\r
+ DEBUG ((DEBUG_INFO, "DeviceType:%x, Bus:%d, Dev:%d, Fun:%d\n", \\r
+ SmmDev->DeviceType, SmmDev->BusNum, SmmDev->DevNum, SmmDev->FuncNum));\r
+ DEBUG ((DEBUG_INFO, "SataPort:%x, MultiplierPort:%x, NvmeNamespaceId:%x\n", \\r
+ SmmDev->SataPort, SmmDev->SataPortMultiplierPort, SmmDev->NvmeNamespaceId));\r
+\r
+ InsertHeadList (SmmDeviceList, &SmmDev->Link);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r