]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.c
SecurityPkg: Apply uncrustify changes
[mirror_edk2.git] / SecurityPkg / Tcg / Opal / OpalPassword / OpalDriver.c
CommitLineData
112e584b
SZ
1/** @file\r
2 Entrypoint of Opal UEFI Driver and contains all the logic to\r
3 register for new Opal device instances.\r
4\r
d72d8561 5Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>\r
289b714b 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
112e584b
SZ
7\r
8**/\r
9\r
10// This UEFI driver consumes EFI_STORAGE_SECURITY_PROTOCOL instances and installs an\r
11// HII GUI to manage Opal features if the device is Opal capable\r
12// If the Opal device is being managed by the UEFI Driver, it shall provide a popup\r
13// window during boot requesting a user password\r
14\r
15#include "OpalDriver.h"\r
16#include "OpalHii.h"\r
17\r
c411b485 18EFI_GUID mOpalDeviceLockBoxGuid = OPAL_DEVICE_LOCKBOX_GUID;\r
112e584b 19\r
c411b485
MK
20BOOLEAN mOpalEndOfDxe = FALSE;\r
21OPAL_REQUEST_VARIABLE *mOpalRequestVariable = NULL;\r
22UINTN mOpalRequestVariableSize = 0;\r
23CHAR16 mPopUpString[100];\r
112e584b 24\r
c411b485 25OPAL_DRIVER mOpalDriver;\r
112e584b
SZ
26\r
27//\r
28// Globals\r
29//\r
c411b485 30EFI_DRIVER_BINDING_PROTOCOL gOpalDriverBinding = {\r
112e584b
SZ
31 OpalEfiDriverBindingSupported,\r
32 OpalEfiDriverBindingStart,\r
33 OpalEfiDriverBindingStop,\r
34 0x1b,\r
35 NULL,\r
36 NULL\r
37};\r
38\r
39/**\r
40\r
41 The function determines the available actions for the OPAL_DISK provided.\r
42\r
43 @param[in] SupportedAttributes The supported attributes for the device.\r
44 @param[in] LockingFeature The locking status for the device.\r
45 @param[in] OwnerShip The ownership for the device.\r
46 @param[out] AvalDiskActions Pointer to fill-out with appropriate disk actions.\r
47\r
48**/\r
49TCG_RESULT\r
50EFIAPI\r
c411b485
MK
51OpalSupportGetAvailableActions (\r
52 IN OPAL_DISK_SUPPORT_ATTRIBUTE *SupportedAttributes,\r
53 IN TCG_LOCKING_FEATURE_DESCRIPTOR *LockingFeature,\r
54 IN UINT16 OwnerShip,\r
55 OUT OPAL_DISK_ACTIONS *AvalDiskActions\r
112e584b
SZ
56 )\r
57{\r
c411b485 58 BOOLEAN ExistingPassword;\r
112e584b 59\r
c411b485 60 NULL_CHECK (AvalDiskActions);\r
112e584b 61\r
c411b485
MK
62 AvalDiskActions->AdminPass = 1;\r
63 AvalDiskActions->UserPass = 0;\r
112e584b 64 AvalDiskActions->DisableUser = 0;\r
c411b485 65 AvalDiskActions->Unlock = 0;\r
112e584b
SZ
66\r
67 //\r
68 // Revert is performed on locking sp, so only allow if locking sp is enabled\r
69 //\r
70 if (LockingFeature->LockingEnabled) {\r
71 AvalDiskActions->Revert = 1;\r
72 }\r
73\r
74 //\r
40d32e79 75 // Psid revert is available for any device with media encryption support or pyrite 2.0 type support.\r
112e584b 76 //\r
40d32e79 77 if (SupportedAttributes->PyriteSscV2 || SupportedAttributes->MediaEncryption) {\r
112e584b 78 //\r
40d32e79 79 // Only allow psid revert if media encryption is enabled or pyrite 2.0 type support..\r
112e584b
SZ
80 // Otherwise, someone who steals a disk can psid revert the disk and the user Data is still\r
81 // intact and accessible\r
82 //\r
c411b485 83 AvalDiskActions->PsidRevert = 1;\r
112e584b
SZ
84 AvalDiskActions->RevertKeepDataForced = 0;\r
85\r
86 //\r
87 // Secure erase is performed by generating a new encryption key\r
88 // this is only available if encryption is supported\r
89 //\r
90 AvalDiskActions->SecureErase = 1;\r
91 } else {\r
c411b485 92 AvalDiskActions->PsidRevert = 0;\r
112e584b
SZ
93 AvalDiskActions->SecureErase = 0;\r
94\r
95 //\r
96 // If no media encryption is supported, then a revert (using password) will not\r
97 // erase the Data (since you can't generate a new encryption key)\r
98 //\r
99 AvalDiskActions->RevertKeepDataForced = 1;\r
100 }\r
101\r
102 if (LockingFeature->Locked) {\r
103 AvalDiskActions->Unlock = 1;\r
104 } else {\r
105 AvalDiskActions->Unlock = 0;\r
106 }\r
107\r
108 //\r
109 // Only allow user to set password if an admin password exists\r
110 //\r
c411b485 111 ExistingPassword = OpalUtilAdminPasswordExists (OwnerShip, LockingFeature);\r
112e584b
SZ
112 AvalDiskActions->UserPass = ExistingPassword;\r
113\r
114 //\r
115 // This will still show up even if there isn't a user, which is fine\r
116 //\r
117 AvalDiskActions->DisableUser = ExistingPassword;\r
118\r
119 return TcgResultSuccess;\r
120}\r
121\r
122/**\r
123 Enable Opal Feature for the input device.\r
124\r
125 @param[in] Session The opal session for the opal device.\r
126 @param[in] Msid Msid\r
127 @param[in] MsidLength Msid Length\r
128 @param[in] Password Admin password\r
129 @param[in] PassLength Length of password in bytes\r
130\r
131**/\r
132TCG_RESULT\r
133EFIAPI\r
134OpalSupportEnableOpalFeature (\r
c411b485
MK
135 IN OPAL_SESSION *Session,\r
136 IN VOID *Msid,\r
137 IN UINT32 MsidLength,\r
138 IN VOID *Password,\r
139 IN UINT32 PassLength\r
112e584b
SZ
140 )\r
141{\r
c411b485
MK
142 TCG_RESULT Ret;\r
143\r
144 NULL_CHECK (Session);\r
145 NULL_CHECK (Msid);\r
146 NULL_CHECK (Password);\r
147\r
148 Ret = OpalUtilSetAdminPasswordAsSid (\r
149 Session,\r
150 Msid,\r
151 MsidLength,\r
152 Password,\r
153 PassLength\r
154 );\r
112e584b
SZ
155 if (Ret == TcgResultSuccess) {\r
156 //\r
157 // Enable global locking range\r
158 //\r
c411b485
MK
159 Ret = OpalUtilSetOpalLockingRange (\r
160 Session,\r
161 Password,\r
162 PassLength,\r
163 OPAL_LOCKING_SP_LOCKING_GLOBALRANGE,\r
164 0,\r
165 0,\r
166 TRUE,\r
167 TRUE,\r
168 FALSE,\r
169 FALSE\r
170 );\r
112e584b
SZ
171 }\r
172\r
173 return Ret;\r
174}\r
175\r
176/**\r
177 Update password for the Opal disk.\r
178\r
179 @param[in, out] OpalDisk The disk to update password.\r
180 @param[in] Password The input password.\r
181 @param[in] PasswordLength The input password length.\r
182\r
183**/\r
184VOID\r
185OpalSupportUpdatePassword (\r
c411b485
MK
186 IN OUT OPAL_DISK *OpalDisk,\r
187 IN VOID *Password,\r
188 IN UINT32 PasswordLength\r
112e584b
SZ
189 )\r
190{\r
191 CopyMem (OpalDisk->Password, Password, PasswordLength);\r
c411b485 192 OpalDisk->PasswordLength = (UINT8)PasswordLength;\r
112e584b
SZ
193}\r
194\r
195/**\r
196 Extract device info from the device path.\r
197\r
198 @param[in] DevicePath Device path info for the device.\r
199 @param[out] DevInfoLength Device information length needed.\r
200 @param[out] DevInfo Device information extracted.\r
201\r
112e584b 202**/\r
a3efbc29 203VOID\r
112e584b
SZ
204ExtractDeviceInfoFromDevicePath (\r
205 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
a3efbc29
HW
206 OUT UINT32 *DevInfoLength,\r
207 OUT OPAL_DEVICE_LOCKBOX_DATA *DevInfo OPTIONAL\r
112e584b
SZ
208 )\r
209{\r
c411b485
MK
210 EFI_DEVICE_PATH_PROTOCOL *TmpDevPath;\r
211 EFI_DEVICE_PATH_PROTOCOL *TmpDevPath2;\r
212 PCI_DEVICE_PATH *PciDevPath;\r
213 UINT8 DeviceType;\r
214 UINT8 BusNum;\r
215 OPAL_PCI_DEVICE *PciDevice;\r
112e584b
SZ
216\r
217 ASSERT (DevicePath != NULL);\r
218 ASSERT (DevInfoLength != NULL);\r
219\r
c411b485 220 DeviceType = OPAL_DEVICE_TYPE_UNKNOWN;\r
112e584b
SZ
221 *DevInfoLength = 0;\r
222\r
223 TmpDevPath = DevicePath;\r
224\r
225 //\r
226 // Get device type.\r
227 //\r
228 while (!IsDevicePathEnd (TmpDevPath)) {\r
a3efbc29 229 if ((TmpDevPath->Type == MESSAGING_DEVICE_PATH) &&\r
c411b485
MK
230 ((TmpDevPath->SubType == MSG_SATA_DP) || (TmpDevPath->SubType == MSG_NVME_NAMESPACE_DP)))\r
231 {\r
112e584b 232 if (DevInfo != NULL) {\r
c411b485 233 DevInfo->DevicePathLength = (UINT32)GetDevicePathSize (DevicePath);\r
a3efbc29 234 CopyMem (DevInfo->DevicePath, DevicePath, DevInfo->DevicePathLength);\r
112e584b 235 }\r
a3efbc29 236\r
c411b485
MK
237 DeviceType = (TmpDevPath->SubType == MSG_SATA_DP) ? OPAL_DEVICE_TYPE_ATA : OPAL_DEVICE_TYPE_NVME;\r
238 *DevInfoLength = sizeof (OPAL_DEVICE_LOCKBOX_DATA) + (UINT32)GetDevicePathSize (DevicePath);\r
112e584b
SZ
239 break;\r
240 }\r
c411b485 241\r
112e584b
SZ
242 TmpDevPath = NextDevicePathNode (TmpDevPath);\r
243 }\r
244\r
245 //\r
246 // Get device info.\r
247 //\r
c411b485
MK
248 BusNum = 0;\r
249 TmpDevPath = DevicePath;\r
112e584b
SZ
250 TmpDevPath2 = NextDevicePathNode (DevicePath);\r
251 while (!IsDevicePathEnd (TmpDevPath2)) {\r
c411b485
MK
252 if ((TmpDevPath->Type == HARDWARE_DEVICE_PATH) && (TmpDevPath->SubType == HW_PCI_DP)) {\r
253 PciDevPath = (PCI_DEVICE_PATH *)TmpDevPath;\r
a3efbc29 254 if ((TmpDevPath2->Type == MESSAGING_DEVICE_PATH) &&\r
c411b485
MK
255 ((TmpDevPath2->SubType == MSG_SATA_DP) || (TmpDevPath2->SubType == MSG_NVME_NAMESPACE_DP)))\r
256 {\r
112e584b 257 if (DevInfo != NULL) {\r
c411b485
MK
258 PciDevice = &DevInfo->Device;\r
259 PciDevice->Segment = 0;\r
260 PciDevice->Bus = BusNum;\r
261 PciDevice->Device = PciDevPath->Device;\r
112e584b
SZ
262 PciDevice->Function = PciDevPath->Function;\r
263 }\r
264 } else {\r
c411b485 265 if ((TmpDevPath2->Type == HARDWARE_DEVICE_PATH) && (TmpDevPath2->SubType == HW_PCI_DP)) {\r
112e584b
SZ
266 BusNum = PciRead8 (PCI_LIB_ADDRESS (BusNum, PciDevPath->Device, PciDevPath->Function, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));\r
267 }\r
268 }\r
269 }\r
270\r
271 TmpDevPath = NextDevicePathNode (TmpDevPath);\r
272 TmpDevPath2 = NextDevicePathNode (TmpDevPath2);\r
273 }\r
274\r
275 ASSERT (DeviceType != OPAL_DEVICE_TYPE_UNKNOWN);\r
a3efbc29 276 return;\r
112e584b
SZ
277}\r
278\r
279/**\r
a3efbc29 280 Build OPAL device info and save them to LockBox.\r
112e584b
SZ
281\r
282 **/\r
283VOID\r
a3efbc29
HW
284BuildOpalDeviceInfo (\r
285 VOID\r
112e584b
SZ
286 )\r
287{\r
c411b485
MK
288 EFI_STATUS Status;\r
289 OPAL_DEVICE_LOCKBOX_DATA *DevInfo;\r
290 OPAL_DEVICE_LOCKBOX_DATA *TempDevInfo;\r
291 UINTN TotalDevInfoLength;\r
292 UINT32 DevInfoLength;\r
293 OPAL_DRIVER_DEVICE *TmpDev;\r
294 UINT8 DummyData;\r
295 BOOLEAN S3InitDevicesExist;\r
296 UINTN S3InitDevicesLength;\r
297 EFI_DEVICE_PATH_PROTOCOL *S3InitDevices;\r
298 EFI_DEVICE_PATH_PROTOCOL *S3InitDevicesBak;\r
112e584b
SZ
299\r
300 //\r
a3efbc29 301 // Build OPAL device info and save them to LockBox.\r
112e584b 302 //\r
a3efbc29 303 TotalDevInfoLength = 0;\r
c411b485 304 TmpDev = mOpalDriver.DeviceList;\r
112e584b 305 while (TmpDev != NULL) {\r
a3efbc29
HW
306 ExtractDeviceInfoFromDevicePath (\r
307 TmpDev->OpalDisk.OpalDevicePath,\r
308 &DevInfoLength,\r
309 NULL\r
310 );\r
311 TotalDevInfoLength += DevInfoLength;\r
c411b485 312 TmpDev = TmpDev->Next;\r
112e584b
SZ
313 }\r
314\r
a3efbc29 315 if (TotalDevInfoLength == 0) {\r
112e584b
SZ
316 return;\r
317 }\r
318\r
a3efbc29 319 S3InitDevicesLength = sizeof (DummyData);\r
c411b485
MK
320 Status = RestoreLockBox (\r
321 &gS3StorageDeviceInitListGuid,\r
322 &DummyData,\r
323 &S3InitDevicesLength\r
324 );\r
a3efbc29
HW
325 ASSERT ((Status == EFI_NOT_FOUND) || (Status == EFI_BUFFER_TOO_SMALL));\r
326 if (Status == EFI_NOT_FOUND) {\r
327 S3InitDevices = NULL;\r
328 S3InitDevicesExist = FALSE;\r
329 } else if (Status == EFI_BUFFER_TOO_SMALL) {\r
330 S3InitDevices = AllocatePool (S3InitDevicesLength);\r
331 ASSERT (S3InitDevices != NULL);\r
332 if (S3InitDevices == NULL) {\r
333 return;\r
112e584b
SZ
334 }\r
335\r
a3efbc29
HW
336 Status = RestoreLockBox (\r
337 &gS3StorageDeviceInitListGuid,\r
338 S3InitDevices,\r
339 &S3InitDevicesLength\r
340 );\r
341 ASSERT_EFI_ERROR (Status);\r
342 S3InitDevicesExist = TRUE;\r
343 } else {\r
112e584b
SZ
344 return;\r
345 }\r
346\r
a3efbc29
HW
347 DevInfo = AllocateZeroPool (TotalDevInfoLength);\r
348 ASSERT (DevInfo != NULL);\r
349 if (DevInfo == NULL) {\r
d72d8561
ED
350 return;\r
351 }\r
112e584b 352\r
a3efbc29
HW
353 TempDevInfo = DevInfo;\r
354 TmpDev = mOpalDriver.DeviceList;\r
112e584b 355 while (TmpDev != NULL) {\r
a3efbc29
HW
356 ExtractDeviceInfoFromDevicePath (\r
357 TmpDev->OpalDisk.OpalDevicePath,\r
358 &DevInfoLength,\r
359 TempDevInfo\r
360 );\r
c411b485 361 TempDevInfo->Length = DevInfoLength;\r
a3efbc29
HW
362 TempDevInfo->OpalBaseComId = TmpDev->OpalDisk.OpalBaseComId;\r
363 CopyMem (\r
364 TempDevInfo->Password,\r
365 TmpDev->OpalDisk.Password,\r
366 TmpDev->OpalDisk.PasswordLength\r
367 );\r
368 TempDevInfo->PasswordLength = TmpDev->OpalDisk.PasswordLength;\r
369\r
370 S3InitDevicesBak = S3InitDevices;\r
371 S3InitDevices = AppendDevicePathInstance (\r
372 S3InitDevicesBak,\r
373 TmpDev->OpalDisk.OpalDevicePath\r
374 );\r
375 if (S3InitDevicesBak != NULL) {\r
376 FreePool (S3InitDevicesBak);\r
377 }\r
c411b485 378\r
a3efbc29
HW
379 ASSERT (S3InitDevices != NULL);\r
380 if (S3InitDevices == NULL) {\r
381 return;\r
112e584b
SZ
382 }\r
383\r
c411b485
MK
384 TempDevInfo = (OPAL_DEVICE_LOCKBOX_DATA *)((UINTN)TempDevInfo + DevInfoLength);\r
385 TmpDev = TmpDev->Next;\r
112e584b
SZ
386 }\r
387\r
388 Status = SaveLockBox (\r
a3efbc29
HW
389 &mOpalDeviceLockBoxGuid,\r
390 DevInfo,\r
391 TotalDevInfoLength\r
112e584b
SZ
392 );\r
393 ASSERT_EFI_ERROR (Status);\r
394\r
395 Status = SetLockBoxAttributes (\r
a3efbc29 396 &mOpalDeviceLockBoxGuid,\r
112e584b
SZ
397 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\r
398 );\r
399 ASSERT_EFI_ERROR (Status);\r
400\r
a3efbc29
HW
401 S3InitDevicesLength = GetDevicePathSize (S3InitDevices);\r
402 if (S3InitDevicesExist) {\r
403 Status = UpdateLockBox (\r
404 &gS3StorageDeviceInitListGuid,\r
405 0,\r
406 S3InitDevices,\r
407 S3InitDevicesLength\r
408 );\r
409 ASSERT_EFI_ERROR (Status);\r
410 } else {\r
411 Status = SaveLockBox (\r
412 &gS3StorageDeviceInitListGuid,\r
413 S3InitDevices,\r
414 S3InitDevicesLength\r
415 );\r
416 ASSERT_EFI_ERROR (Status);\r
417\r
418 Status = SetLockBoxAttributes (\r
419 &gS3StorageDeviceInitListGuid,\r
420 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\r
421 );\r
422 ASSERT_EFI_ERROR (Status);\r
423 }\r
424\r
425 ZeroMem (DevInfo, TotalDevInfoLength);\r
426 FreePool (DevInfo);\r
427 FreePool (S3InitDevices);\r
112e584b
SZ
428}\r
429\r
539a6c93
ED
430/**\r
431\r
432 Send BlockSid command if needed.\r
433\r
434**/\r
435VOID\r
436SendBlockSidCommand (\r
437 VOID\r
438 )\r
439{\r
c411b485
MK
440 OPAL_DRIVER_DEVICE *Itr;\r
441 TCG_RESULT Result;\r
442 OPAL_SESSION Session;\r
443 UINT32 PpStorageFlag;\r
539a6c93
ED
444\r
445 PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags ();\r
446 if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) {\r
447 //\r
448 // Send BlockSID command to each Opal disk\r
449 //\r
450 Itr = mOpalDriver.DeviceList;\r
451 while (Itr != NULL) {\r
452 if (Itr->OpalDisk.SupportedAttributes.BlockSid) {\r
c411b485
MK
453 ZeroMem (&Session, sizeof (Session));\r
454 Session.Sscp = Itr->OpalDisk.Sscp;\r
455 Session.MediaId = Itr->OpalDisk.MediaId;\r
539a6c93
ED
456 Session.OpalBaseComId = Itr->OpalDisk.OpalBaseComId;\r
457\r
458 DEBUG ((DEBUG_INFO, "OpalPassword: EndOfDxe point, send BlockSid command to device!\n"));\r
459 Result = OpalBlockSid (&Session, TRUE); // HardwareReset must always be TRUE\r
460 if (Result != TcgResultSuccess) {\r
461 DEBUG ((DEBUG_ERROR, "OpalBlockSid fail\n"));\r
462 break;\r
463 }\r
46e69608
ED
464\r
465 //\r
466 // Record BlockSID command has been sent.\r
467 //\r
468 Itr->OpalDisk.SentBlockSID = TRUE;\r
539a6c93
ED
469 }\r
470\r
471 Itr = Itr->Next;\r
472 }\r
473 }\r
474}\r
475\r
112e584b
SZ
476/**\r
477 Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.\r
478\r
479 This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.\r
480\r
481 @param Event Event whose notification function is being invoked.\r
482 @param Context Pointer to the notification function's context.\r
483\r
484**/\r
485VOID\r
486EFIAPI\r
487OpalEndOfDxeEventNotify (\r
c411b485
MK
488 EFI_EVENT Event,\r
489 VOID *Context\r
112e584b
SZ
490 )\r
491{\r
c411b485 492 OPAL_DRIVER_DEVICE *TmpDev;\r
112e584b
SZ
493\r
494 DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__));\r
495\r
496 mOpalEndOfDxe = TRUE;\r
497\r
498 if (mOpalRequestVariable != NULL) {\r
499 //\r
500 // Free the OPAL request variable buffer here\r
501 // as the OPAL requests should have been processed.\r
502 //\r
503 FreePool (mOpalRequestVariable);\r
c411b485 504 mOpalRequestVariable = NULL;\r
112e584b
SZ
505 mOpalRequestVariableSize = 0;\r
506 }\r
507\r
fbe1328a
SZ
508 //\r
509 // If no any device, return directly.\r
510 //\r
511 if (mOpalDriver.DeviceList == NULL) {\r
512 gBS->CloseEvent (Event);\r
513 return;\r
514 }\r
515\r
a3efbc29 516 BuildOpalDeviceInfo ();\r
112e584b
SZ
517\r
518 //\r
519 // Zero passsword.\r
520 //\r
521 TmpDev = mOpalDriver.DeviceList;\r
522 while (TmpDev != NULL) {\r
523 ZeroMem (TmpDev->OpalDisk.Password, TmpDev->OpalDisk.PasswordLength);\r
524 TmpDev = TmpDev->Next;\r
525 }\r
526\r
539a6c93
ED
527 //\r
528 // Send BlockSid command if needed.\r
529 //\r
530 SendBlockSidCommand ();\r
531\r
112e584b
SZ
532 DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__));\r
533\r
534 gBS->CloseEvent (Event);\r
535}\r
536\r
537/**\r
538 Get Psid input from the popup window.\r
539\r
540 @param[in] Dev The device which need Psid to process Psid Revert\r
541 OPAL request.\r
542 @param[in] PopUpString Pop up string.\r
40d32e79 543 @param[in] PopUpString2 Pop up string in line 2.\r
f5245a1d 544 @param[in] PopUpString3 Pop up string in line 3.\r
40d32e79 545\r
112e584b
SZ
546 @param[out] PressEsc Whether user escape function through Press ESC.\r
547\r
aa085730 548 @retval Psid string if success. NULL if failed.\r
112e584b
SZ
549\r
550**/\r
551CHAR8 *\r
552OpalDriverPopUpPsidInput (\r
c411b485
MK
553 IN OPAL_DRIVER_DEVICE *Dev,\r
554 IN CHAR16 *PopUpString,\r
555 IN CHAR16 *PopUpString2,\r
556 IN CHAR16 *PopUpString3,\r
557 OUT BOOLEAN *PressEsc\r
112e584b
SZ
558 )\r
559{\r
c411b485
MK
560 EFI_INPUT_KEY InputKey;\r
561 UINTN InputLength;\r
562 CHAR16 Mask[PSID_CHARACTER_LENGTH + 1];\r
563 CHAR16 Unicode[PSID_CHARACTER_LENGTH + 1];\r
564 CHAR8 *Ascii;\r
112e584b 565\r
c411b485
MK
566 ZeroMem (Unicode, sizeof (Unicode));\r
567 ZeroMem (Mask, sizeof (Mask));\r
112e584b
SZ
568\r
569 *PressEsc = FALSE;\r
570\r
c411b485 571 gST->ConOut->ClearScreen (gST->ConOut);\r
112e584b
SZ
572\r
573 InputLength = 0;\r
574 while (TRUE) {\r
575 Mask[InputLength] = L'_';\r
63c76537
ED
576 if (PopUpString2 == NULL) {\r
577 CreatePopUp (\r
578 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
579 &InputKey,\r
580 PopUpString,\r
581 L"---------------------",\r
582 Mask,\r
583 NULL\r
c411b485 584 );\r
63c76537 585 } else {\r
f5245a1d
CM
586 if (PopUpString3 == NULL) {\r
587 CreatePopUp (\r
588 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
589 &InputKey,\r
590 PopUpString,\r
591 PopUpString2,\r
592 L"---------------------",\r
593 Mask,\r
594 NULL\r
c411b485 595 );\r
f5245a1d
CM
596 } else {\r
597 CreatePopUp (\r
598 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
599 &InputKey,\r
600 PopUpString,\r
601 PopUpString2,\r
602 PopUpString3,\r
603 L"---------------------",\r
604 Mask,\r
605 NULL\r
c411b485 606 );\r
f5245a1d 607 }\r
63c76537 608 }\r
112e584b
SZ
609\r
610 //\r
611 // Check key.\r
612 //\r
613 if (InputKey.ScanCode == SCAN_NULL) {\r
614 //\r
615 // password finished\r
616 //\r
617 if (InputKey.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
618 //\r
619 // Add the null terminator.\r
620 //\r
621 Unicode[InputLength] = 0;\r
c411b485 622 Mask[InputLength] = 0;\r
112e584b
SZ
623 break;\r
624 } else if ((InputKey.UnicodeChar == CHAR_NULL) ||\r
625 (InputKey.UnicodeChar == CHAR_TAB) ||\r
626 (InputKey.UnicodeChar == CHAR_LINEFEED)\r
c411b485
MK
627 )\r
628 {\r
112e584b
SZ
629 continue;\r
630 } else {\r
631 //\r
632 // delete last key entered\r
633 //\r
634 if (InputKey.UnicodeChar == CHAR_BACKSPACE) {\r
635 if (InputLength > 0) {\r
636 Unicode[InputLength] = 0;\r
c411b485 637 Mask[InputLength] = 0;\r
112e584b
SZ
638 InputLength--;\r
639 }\r
640 } else {\r
641 //\r
642 // add Next key entry\r
643 //\r
644 Unicode[InputLength] = InputKey.UnicodeChar;\r
c411b485 645 Mask[InputLength] = InputKey.UnicodeChar;\r
112e584b
SZ
646 InputLength++;\r
647 if (InputLength == PSID_CHARACTER_LENGTH) {\r
648 //\r
649 // Add the null terminator.\r
650 //\r
651 Unicode[InputLength] = 0;\r
c411b485 652 Mask[InputLength] = 0;\r
112e584b
SZ
653 break;\r
654 }\r
655 }\r
656 }\r
657 }\r
658\r
659 //\r
660 // exit on ESC\r
661 //\r
662 if (InputKey.ScanCode == SCAN_ESC) {\r
663 *PressEsc = TRUE;\r
664 break;\r
665 }\r
666 }\r
667\r
c411b485 668 gST->ConOut->ClearScreen (gST->ConOut);\r
112e584b 669\r
c411b485 670 if ((InputLength == 0) || (InputKey.ScanCode == SCAN_ESC)) {\r
112e584b
SZ
671 ZeroMem (Unicode, sizeof (Unicode));\r
672 ZeroMem (Mask, sizeof (Mask));\r
673 return NULL;\r
674 }\r
675\r
676 Ascii = AllocateZeroPool (PSID_CHARACTER_LENGTH + 1);\r
677 if (Ascii == NULL) {\r
678 ZeroMem (Unicode, sizeof (Unicode));\r
679 ZeroMem (Mask, sizeof (Mask));\r
680 return NULL;\r
681 }\r
682\r
683 UnicodeStrToAsciiStrS (Unicode, Ascii, PSID_CHARACTER_LENGTH + 1);\r
684 ZeroMem (Unicode, sizeof (Unicode));\r
685 ZeroMem (Mask, sizeof (Mask));\r
686\r
687 return Ascii;\r
688}\r
689\r
112e584b
SZ
690/**\r
691 Get password input from the popup window.\r
692\r
693 @param[in] Dev The device which need password to unlock or\r
694 process OPAL request.\r
695 @param[in] PopUpString1 Pop up string 1.\r
696 @param[in] PopUpString2 Pop up string 2.\r
f5245a1d 697 @param[in] PopUpString3 Pop up string 3.\r
112e584b
SZ
698 @param[out] PressEsc Whether user escape function through Press ESC.\r
699\r
700 @retval Password string if success. NULL if failed.\r
701\r
702**/\r
703CHAR8 *\r
704OpalDriverPopUpPasswordInput (\r
c411b485
MK
705 IN OPAL_DRIVER_DEVICE *Dev,\r
706 IN CHAR16 *PopUpString1,\r
707 IN CHAR16 *PopUpString2,\r
708 IN CHAR16 *PopUpString3,\r
709 OUT BOOLEAN *PressEsc\r
112e584b
SZ
710 )\r
711{\r
c411b485
MK
712 EFI_INPUT_KEY InputKey;\r
713 UINTN InputLength;\r
714 CHAR16 Mask[OPAL_MAX_PASSWORD_SIZE + 1];\r
715 CHAR16 Unicode[OPAL_MAX_PASSWORD_SIZE + 1];\r
716 CHAR8 *Ascii;\r
112e584b 717\r
c411b485
MK
718 ZeroMem (Unicode, sizeof (Unicode));\r
719 ZeroMem (Mask, sizeof (Mask));\r
112e584b
SZ
720\r
721 *PressEsc = FALSE;\r
722\r
c411b485 723 gST->ConOut->ClearScreen (gST->ConOut);\r
112e584b
SZ
724\r
725 InputLength = 0;\r
726 while (TRUE) {\r
727 Mask[InputLength] = L'_';\r
728 if (PopUpString2 == NULL) {\r
729 CreatePopUp (\r
730 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
731 &InputKey,\r
732 PopUpString1,\r
733 L"---------------------",\r
734 Mask,\r
735 NULL\r
c411b485 736 );\r
112e584b 737 } else {\r
f5245a1d
CM
738 if (PopUpString3 == NULL) {\r
739 CreatePopUp (\r
740 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
741 &InputKey,\r
742 PopUpString1,\r
743 PopUpString2,\r
744 L"---------------------",\r
745 Mask,\r
746 NULL\r
c411b485 747 );\r
f5245a1d
CM
748 } else {\r
749 CreatePopUp (\r
750 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
751 &InputKey,\r
752 PopUpString1,\r
753 PopUpString2,\r
754 PopUpString3,\r
755 L"---------------------",\r
756 Mask,\r
757 NULL\r
c411b485 758 );\r
f5245a1d 759 }\r
112e584b
SZ
760 }\r
761\r
762 //\r
763 // Check key.\r
764 //\r
765 if (InputKey.ScanCode == SCAN_NULL) {\r
766 //\r
767 // password finished\r
768 //\r
769 if (InputKey.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
770 //\r
771 // Add the null terminator.\r
772 //\r
773 Unicode[InputLength] = 0;\r
c411b485 774 Mask[InputLength] = 0;\r
112e584b
SZ
775 break;\r
776 } else if ((InputKey.UnicodeChar == CHAR_NULL) ||\r
777 (InputKey.UnicodeChar == CHAR_TAB) ||\r
778 (InputKey.UnicodeChar == CHAR_LINEFEED)\r
c411b485
MK
779 )\r
780 {\r
112e584b
SZ
781 continue;\r
782 } else {\r
783 //\r
784 // delete last key entered\r
785 //\r
786 if (InputKey.UnicodeChar == CHAR_BACKSPACE) {\r
787 if (InputLength > 0) {\r
788 Unicode[InputLength] = 0;\r
c411b485 789 Mask[InputLength] = 0;\r
112e584b
SZ
790 InputLength--;\r
791 }\r
792 } else {\r
793 //\r
794 // add Next key entry\r
795 //\r
796 Unicode[InputLength] = InputKey.UnicodeChar;\r
c411b485 797 Mask[InputLength] = L'*';\r
112e584b
SZ
798 InputLength++;\r
799 if (InputLength == OPAL_MAX_PASSWORD_SIZE) {\r
800 //\r
801 // Add the null terminator.\r
802 //\r
803 Unicode[InputLength] = 0;\r
c411b485 804 Mask[InputLength] = 0;\r
112e584b
SZ
805 break;\r
806 }\r
807 }\r
808 }\r
809 }\r
810\r
811 //\r
812 // exit on ESC\r
813 //\r
814 if (InputKey.ScanCode == SCAN_ESC) {\r
815 *PressEsc = TRUE;\r
816 break;\r
817 }\r
818 }\r
819\r
c411b485 820 gST->ConOut->ClearScreen (gST->ConOut);\r
112e584b 821\r
c411b485 822 if ((InputLength == 0) || (InputKey.ScanCode == SCAN_ESC)) {\r
112e584b
SZ
823 ZeroMem (Unicode, sizeof (Unicode));\r
824 return NULL;\r
825 }\r
826\r
827 Ascii = AllocateZeroPool (OPAL_MAX_PASSWORD_SIZE + 1);\r
828 if (Ascii == NULL) {\r
829 ZeroMem (Unicode, sizeof (Unicode));\r
830 return NULL;\r
831 }\r
832\r
833 UnicodeStrToAsciiStrS (Unicode, Ascii, OPAL_MAX_PASSWORD_SIZE + 1);\r
834 ZeroMem (Unicode, sizeof (Unicode));\r
835\r
836 return Ascii;\r
837}\r
838\r
839/**\r
aa085730 840 Get pop up string.\r
112e584b 841\r
aa085730 842 @param[in] Dev The OPAL device.\r
112e584b
SZ
843 @param[in] RequestString Request string.\r
844\r
aa085730
SZ
845 @return Pop up string.\r
846\r
112e584b
SZ
847**/\r
848CHAR16 *\r
849OpalGetPopUpString (\r
c411b485
MK
850 IN OPAL_DRIVER_DEVICE *Dev,\r
851 IN CHAR16 *RequestString\r
112e584b
SZ
852 )\r
853{\r
112e584b 854 if (Dev->Name16 == NULL) {\r
aa085730 855 UnicodeSPrint (mPopUpString, sizeof (mPopUpString), L"%s Disk", RequestString);\r
112e584b 856 } else {\r
aa085730 857 UnicodeSPrint (mPopUpString, sizeof (mPopUpString), L"%s %s", RequestString, Dev->Name16);\r
112e584b
SZ
858 }\r
859\r
860 return mPopUpString;\r
861}\r
862\r
863/**\r
864 Check if disk is locked, show popup window and ask for password if it is.\r
865\r
866 @param[in] Dev The device which need to be unlocked.\r
867 @param[in] RequestString Request string.\r
868\r
869**/\r
870VOID\r
871OpalDriverRequestPassword (\r
c411b485
MK
872 IN OPAL_DRIVER_DEVICE *Dev,\r
873 IN CHAR16 *RequestString\r
112e584b
SZ
874 )\r
875{\r
c411b485
MK
876 UINT8 Count;\r
877 BOOLEAN IsEnabled;\r
878 BOOLEAN IsLocked;\r
879 CHAR8 *Password;\r
880 UINT32 PasswordLen;\r
881 OPAL_SESSION Session;\r
882 BOOLEAN PressEsc;\r
883 EFI_INPUT_KEY Key;\r
884 TCG_RESULT Ret;\r
885 CHAR16 *PopUpString;\r
112e584b
SZ
886\r
887 if (Dev == NULL) {\r
888 return;\r
889 }\r
890\r
891 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
892\r
893 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
894\r
895 Count = 0;\r
896\r
897 IsEnabled = OpalFeatureEnabled (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature);\r
898 if (IsEnabled) {\r
c411b485
MK
899 ZeroMem (&Session, sizeof (Session));\r
900 Session.Sscp = Dev->OpalDisk.Sscp;\r
901 Session.MediaId = Dev->OpalDisk.MediaId;\r
112e584b
SZ
902 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
903\r
904 IsLocked = OpalDeviceLocked (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature);\r
905\r
6cbed0e3
CM
906 //\r
907 // Add PcdSkipOpalPasswordPrompt to determin whether to skip password prompt.\r
908 // Due to board design, device may not power off during system warm boot, which result in\r
909 // security status remain unlocked status, hence we add device security status check here.\r
910 //\r
911 // If device is in the locked status, device keeps locked and system continues booting.\r
912 // If device is in the unlocked status, system is forced shutdown to support security requirement.\r
913 //\r
914 if (PcdGetBool (PcdSkipOpalPasswordPrompt)) {\r
915 if (IsLocked) {\r
916 return;\r
917 } else {\r
918 gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);\r
919 }\r
8a9301cd
CM
920 }\r
921\r
112e584b 922 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 923 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, NULL, &PressEsc);\r
112e584b
SZ
924 if (PressEsc) {\r
925 if (IsLocked) {\r
926 //\r
927 // Current device in the lock status and\r
928 // User not input password and press ESC,\r
929 // keep device in lock status and continue boot.\r
930 //\r
931 do {\r
932 CreatePopUp (\r
933 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
934 &Key,\r
935 L"Press ENTER to skip the request and continue boot,",\r
936 L"Press ESC to input password again",\r
937 NULL\r
938 );\r
939 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
940\r
941 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
c411b485 942 gST->ConOut->ClearScreen (gST->ConOut);\r
112e584b
SZ
943 //\r
944 // Keep lock and continue boot.\r
945 //\r
946 return;\r
947 } else {\r
948 //\r
949 // Let user input password again.\r
950 //\r
951 continue;\r
952 }\r
953 } else {\r
954 //\r
955 // Current device in the unlock status and\r
956 // User not input password and press ESC,\r
957 // Shutdown the device.\r
958 //\r
959 do {\r
960 CreatePopUp (\r
961 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
962 &Key,\r
963 L"Press ENTER to shutdown, Press ESC to input password again",\r
964 NULL\r
965 );\r
966 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
967\r
968 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
969 gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);\r
970 } else {\r
971 //\r
972 // Let user input password again.\r
973 //\r
974 continue;\r
975 }\r
976 }\r
977 }\r
978\r
979 if (Password == NULL) {\r
c411b485 980 Count++;\r
112e584b
SZ
981 continue;\r
982 }\r
c411b485
MK
983\r
984 PasswordLen = (UINT32)AsciiStrLen (Password);\r
112e584b
SZ
985\r
986 if (IsLocked) {\r
c411b485 987 Ret = OpalUtilUpdateGlobalLockingRange (&Session, Password, PasswordLen, FALSE, FALSE);\r
112e584b 988 } else {\r
c411b485 989 Ret = OpalUtilUpdateGlobalLockingRange (&Session, Password, PasswordLen, TRUE, TRUE);\r
112e584b 990 if (Ret == TcgResultSuccess) {\r
c411b485 991 Ret = OpalUtilUpdateGlobalLockingRange (&Session, Password, PasswordLen, FALSE, FALSE);\r
112e584b
SZ
992 }\r
993 }\r
994\r
995 if (Ret == TcgResultSuccess) {\r
996 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
997 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
998 } else {\r
999 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1000 }\r
1001\r
1002 if (Password != NULL) {\r
1003 ZeroMem (Password, PasswordLen);\r
1004 FreePool (Password);\r
1005 }\r
1006\r
1007 if (Ret == TcgResultSuccess) {\r
1008 break;\r
1009 }\r
1010\r
e4e314b1
ED
1011 //\r
1012 // Check whether opal device's Tries value has reach the TryLimit value, if yes, force a shutdown\r
1013 // before accept new password.\r
1014 //\r
1015 if (Ret == TcgResultFailureInvalidType) {\r
1016 Count = MAX_PASSWORD_TRY_COUNT;\r
1017 break;\r
1018 }\r
1019\r
112e584b
SZ
1020 Count++;\r
1021\r
1022 do {\r
1023 CreatePopUp (\r
1024 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1025 &Key,\r
1026 L"Invalid password.",\r
1027 L"Press ENTER to retry",\r
1028 NULL\r
1029 );\r
1030 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1031 }\r
1032\r
1033 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1034 do {\r
1035 CreatePopUp (\r
1036 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1037 &Key,\r
1038 L"Opal password retry count exceeds the limit. Must shutdown!",\r
1039 L"Press ENTER to shutdown",\r
1040 NULL\r
1041 );\r
1042 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1043\r
1044 gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);\r
1045 }\r
1046 }\r
1047}\r
1048\r
1049/**\r
1050 Process Enable Feature OPAL request.\r
1051\r
1052 @param[in] Dev The device which has Enable Feature OPAL request.\r
1053 @param[in] RequestString Request string.\r
1054\r
1055**/\r
1056VOID\r
1057ProcessOpalRequestEnableFeature (\r
c411b485
MK
1058 IN OPAL_DRIVER_DEVICE *Dev,\r
1059 IN CHAR16 *RequestString\r
112e584b
SZ
1060 )\r
1061{\r
c411b485
MK
1062 UINT8 Count;\r
1063 CHAR8 *Password;\r
1064 UINT32 PasswordLen;\r
1065 CHAR8 *PasswordConfirm;\r
1066 UINT32 PasswordLenConfirm;\r
1067 OPAL_SESSION Session;\r
1068 BOOLEAN PressEsc;\r
1069 EFI_INPUT_KEY Key;\r
1070 TCG_RESULT Ret;\r
1071 CHAR16 *PopUpString;\r
112e584b
SZ
1072\r
1073 if (Dev == NULL) {\r
1074 return;\r
1075 }\r
1076\r
1077 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1078\r
1079 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1080\r
1081 Count = 0;\r
1082\r
c411b485
MK
1083 ZeroMem (&Session, sizeof (Session));\r
1084 Session.Sscp = Dev->OpalDisk.Sscp;\r
1085 Session.MediaId = Dev->OpalDisk.MediaId;\r
112e584b
SZ
1086 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1087\r
1088 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 1089 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);\r
112e584b 1090 if (PressEsc) {\r
c411b485
MK
1091 do {\r
1092 CreatePopUp (\r
1093 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1094 &Key,\r
1095 L"Press ENTER to skip the request and continue boot,",\r
1096 L"Press ESC to input password again",\r
1097 NULL\r
1098 );\r
1099 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
112e584b 1100\r
c411b485
MK
1101 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1102 gST->ConOut->ClearScreen (gST->ConOut);\r
1103 return;\r
1104 } else {\r
1105 //\r
1106 // Let user input password again.\r
1107 //\r
1108 continue;\r
1109 }\r
112e584b
SZ
1110 }\r
1111\r
1112 if (Password == NULL) {\r
c411b485 1113 Count++;\r
112e584b
SZ
1114 continue;\r
1115 }\r
c411b485
MK
1116\r
1117 PasswordLen = (UINT32)AsciiStrLen (Password);\r
112e584b 1118\r
f5245a1d 1119 PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);\r
112e584b
SZ
1120 if (PasswordConfirm == NULL) {\r
1121 ZeroMem (Password, PasswordLen);\r
1122 FreePool (Password);\r
c411b485 1123 Count++;\r
112e584b
SZ
1124 continue;\r
1125 }\r
c411b485
MK
1126\r
1127 PasswordLenConfirm = (UINT32)AsciiStrLen (PasswordConfirm);\r
112e584b 1128 if ((PasswordLen != PasswordLenConfirm) ||\r
c411b485
MK
1129 (CompareMem (Password, PasswordConfirm, PasswordLen) != 0))\r
1130 {\r
112e584b
SZ
1131 ZeroMem (Password, PasswordLen);\r
1132 FreePool (Password);\r
1133 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
1134 FreePool (PasswordConfirm);\r
1135 do {\r
1136 CreatePopUp (\r
1137 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1138 &Key,\r
1139 L"Passwords are not the same.",\r
1140 L"Press ENTER to retry",\r
1141 NULL\r
1142 );\r
1143 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
c411b485
MK
1144\r
1145 Count++;\r
112e584b
SZ
1146 continue;\r
1147 }\r
1148\r
1149 if (PasswordConfirm != NULL) {\r
1150 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
1151 FreePool (PasswordConfirm);\r
1152 }\r
1153\r
c411b485 1154 Ret = OpalSupportEnableOpalFeature (&Session, Dev->OpalDisk.Msid, Dev->OpalDisk.MsidLength, Password, PasswordLen);\r
112e584b
SZ
1155 if (Ret == TcgResultSuccess) {\r
1156 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
1157 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1158 } else {\r
1159 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1160 }\r
1161\r
1162 if (Password != NULL) {\r
1163 ZeroMem (Password, PasswordLen);\r
1164 FreePool (Password);\r
1165 }\r
1166\r
1167 if (Ret == TcgResultSuccess) {\r
1168 break;\r
1169 }\r
1170\r
1171 Count++;\r
1172\r
1173 do {\r
1174 CreatePopUp (\r
1175 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1176 &Key,\r
1177 L"Request failed.",\r
1178 L"Press ENTER to retry",\r
1179 NULL\r
1180 );\r
1181 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1182 }\r
1183\r
1184 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1185 do {\r
1186 CreatePopUp (\r
1187 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1188 &Key,\r
1189 L"Opal password retry count exceeds the limit.",\r
1190 L"Press ENTER to skip the request and continue boot",\r
1191 NULL\r
1192 );\r
1193 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
c411b485
MK
1194\r
1195 gST->ConOut->ClearScreen (gST->ConOut);\r
112e584b
SZ
1196 }\r
1197}\r
1198\r
1199/**\r
1200 Process Disable User OPAL request.\r
1201\r
1202 @param[in] Dev The device which has Disable User OPAL request.\r
1203 @param[in] RequestString Request string.\r
1204\r
1205**/\r
1206VOID\r
1207ProcessOpalRequestDisableUser (\r
c411b485
MK
1208 IN OPAL_DRIVER_DEVICE *Dev,\r
1209 IN CHAR16 *RequestString\r
112e584b
SZ
1210 )\r
1211{\r
c411b485
MK
1212 UINT8 Count;\r
1213 CHAR8 *Password;\r
1214 UINT32 PasswordLen;\r
1215 OPAL_SESSION Session;\r
1216 BOOLEAN PressEsc;\r
1217 EFI_INPUT_KEY Key;\r
1218 TCG_RESULT Ret;\r
1219 BOOLEAN PasswordFailed;\r
1220 CHAR16 *PopUpString;\r
112e584b
SZ
1221\r
1222 if (Dev == NULL) {\r
1223 return;\r
1224 }\r
1225\r
1226 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1227\r
1228 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1229\r
1230 Count = 0;\r
1231\r
c411b485
MK
1232 ZeroMem (&Session, sizeof (Session));\r
1233 Session.Sscp = Dev->OpalDisk.Sscp;\r
1234 Session.MediaId = Dev->OpalDisk.MediaId;\r
112e584b
SZ
1235 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1236\r
1237 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 1238 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, NULL, &PressEsc);\r
112e584b 1239 if (PressEsc) {\r
c411b485
MK
1240 do {\r
1241 CreatePopUp (\r
1242 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1243 &Key,\r
1244 L"Press ENTER to skip the request and continue boot,",\r
1245 L"Press ESC to input password again",\r
1246 NULL\r
1247 );\r
1248 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
112e584b 1249\r
c411b485
MK
1250 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1251 gST->ConOut->ClearScreen (gST->ConOut);\r
1252 return;\r
1253 } else {\r
1254 //\r
1255 // Let user input password again.\r
1256 //\r
1257 continue;\r
1258 }\r
112e584b
SZ
1259 }\r
1260\r
1261 if (Password == NULL) {\r
c411b485 1262 Count++;\r
112e584b
SZ
1263 continue;\r
1264 }\r
112e584b 1265\r
c411b485
MK
1266 PasswordLen = (UINT32)AsciiStrLen (Password);\r
1267\r
1268 Ret = OpalUtilDisableUser (&Session, Password, PasswordLen, &PasswordFailed);\r
112e584b
SZ
1269 if (Ret == TcgResultSuccess) {\r
1270 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
1271 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1272 } else {\r
1273 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1274 }\r
1275\r
1276 if (Password != NULL) {\r
1277 ZeroMem (Password, PasswordLen);\r
1278 FreePool (Password);\r
1279 }\r
1280\r
1281 if (Ret == TcgResultSuccess) {\r
1282 break;\r
1283 }\r
1284\r
1285 Count++;\r
1286\r
1287 do {\r
1288 CreatePopUp (\r
1289 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1290 &Key,\r
1291 L"Invalid password, request failed.",\r
1292 L"Press ENTER to retry",\r
1293 NULL\r
1294 );\r
1295 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1296 }\r
1297\r
1298 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1299 do {\r
1300 CreatePopUp (\r
1301 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1302 &Key,\r
1303 L"Opal password retry count exceeds the limit.",\r
1304 L"Press ENTER to skip the request and continue boot",\r
1305 NULL\r
1306 );\r
1307 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
c411b485
MK
1308\r
1309 gST->ConOut->ClearScreen (gST->ConOut);\r
112e584b
SZ
1310 }\r
1311}\r
1312\r
1313/**\r
1314 Process Psid Revert OPAL request.\r
1315\r
1316 @param[in] Dev The device which has Psid Revert OPAL request.\r
1317 @param[in] RequestString Request string.\r
1318\r
1319**/\r
1320VOID\r
1321ProcessOpalRequestPsidRevert (\r
c411b485
MK
1322 IN OPAL_DRIVER_DEVICE *Dev,\r
1323 IN CHAR16 *RequestString\r
112e584b
SZ
1324 )\r
1325{\r
c411b485
MK
1326 UINT8 Count;\r
1327 CHAR8 *Psid;\r
1328 UINT32 PsidLen;\r
1329 OPAL_SESSION Session;\r
1330 BOOLEAN PressEsc;\r
1331 EFI_INPUT_KEY Key;\r
1332 TCG_RESULT Ret;\r
1333 CHAR16 *PopUpString;\r
1334 CHAR16 *PopUpString2;\r
1335 CHAR16 *PopUpString3;\r
1336 UINTN BufferSize;\r
112e584b
SZ
1337\r
1338 if (Dev == NULL) {\r
1339 return;\r
1340 }\r
1341\r
1342 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1343\r
1344 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1345\r
40d32e79 1346 if (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME) {\r
c411b485 1347 BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds");\r
40d32e79
ED
1348 PopUpString2 = AllocateZeroPool (BufferSize);\r
1349 ASSERT (PopUpString2 != NULL);\r
1350 UnicodeSPrint (\r
c411b485
MK
1351 PopUpString2,\r
1352 BufferSize,\r
1353 L"WARNING: Revert action will take about %d seconds",\r
1354 Dev->OpalDisk.EstimateTimeCost\r
40d32e79 1355 );\r
f5245a1d 1356 PopUpString3 = L"DO NOT power off system during the revert action!";\r
40d32e79
ED
1357 } else {\r
1358 PopUpString2 = NULL;\r
f5245a1d 1359 PopUpString3 = NULL;\r
40d32e79
ED
1360 }\r
1361\r
112e584b
SZ
1362 Count = 0;\r
1363\r
c411b485
MK
1364 ZeroMem (&Session, sizeof (Session));\r
1365 Session.Sscp = Dev->OpalDisk.Sscp;\r
1366 Session.MediaId = Dev->OpalDisk.MediaId;\r
112e584b
SZ
1367 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1368\r
1369 while (Count < MAX_PSID_TRY_COUNT) {\r
f5245a1d 1370 Psid = OpalDriverPopUpPsidInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);\r
112e584b 1371 if (PressEsc) {\r
c411b485
MK
1372 do {\r
1373 CreatePopUp (\r
1374 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1375 &Key,\r
1376 L"Press ENTER to skip the request and continue boot,",\r
1377 L"Press ESC to input Psid again",\r
1378 NULL\r
1379 );\r
1380 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
112e584b 1381\r
c411b485
MK
1382 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1383 gST->ConOut->ClearScreen (gST->ConOut);\r
1384 goto Done;\r
1385 } else {\r
1386 //\r
1387 // Let user input Psid again.\r
1388 //\r
1389 continue;\r
1390 }\r
112e584b
SZ
1391 }\r
1392\r
1393 if (Psid == NULL) {\r
c411b485 1394 Count++;\r
112e584b
SZ
1395 continue;\r
1396 }\r
112e584b 1397\r
c411b485
MK
1398 PsidLen = (UINT32)AsciiStrLen (Psid);\r
1399\r
1400 Ret = OpalUtilPsidRevert (&Session, Psid, PsidLen);\r
112e584b
SZ
1401 if (Ret == TcgResultSuccess) {\r
1402 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1403 } else {\r
1404 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1405 }\r
1406\r
1407 if (Psid != NULL) {\r
1408 ZeroMem (Psid, PsidLen);\r
1409 FreePool (Psid);\r
1410 }\r
1411\r
1412 if (Ret == TcgResultSuccess) {\r
1413 break;\r
1414 }\r
1415\r
1416 Count++;\r
1417\r
1418 do {\r
1419 CreatePopUp (\r
1420 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1421 &Key,\r
1422 L"Invalid Psid, request failed.",\r
1423 L"Press ENTER to retry",\r
1424 NULL\r
1425 );\r
1426 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1427 }\r
1428\r
1429 if (Count >= MAX_PSID_TRY_COUNT) {\r
1430 do {\r
1431 CreatePopUp (\r
1432 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1433 &Key,\r
1434 L"Opal Psid retry count exceeds the limit.",\r
1435 L"Press ENTER to skip the request and continue boot",\r
1436 NULL\r
1437 );\r
1438 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
c411b485
MK
1439\r
1440 gST->ConOut->ClearScreen (gST->ConOut);\r
112e584b 1441 }\r
40d32e79
ED
1442\r
1443Done:\r
1444 if (PopUpString2 != NULL) {\r
1445 FreePool (PopUpString2);\r
1446 }\r
112e584b
SZ
1447}\r
1448\r
1449/**\r
1450 Process Admin Revert OPAL request.\r
1451\r
1452 @param[in] Dev The device which has Revert OPAL request.\r
1453 @param[in] KeepUserData Whether to keep user data or not.\r
1454 @param[in] RequestString Request string.\r
1455\r
1456**/\r
1457VOID\r
1458ProcessOpalRequestRevert (\r
c411b485
MK
1459 IN OPAL_DRIVER_DEVICE *Dev,\r
1460 IN BOOLEAN KeepUserData,\r
1461 IN CHAR16 *RequestString\r
112e584b
SZ
1462 )\r
1463{\r
c411b485
MK
1464 UINT8 Count;\r
1465 CHAR8 *Password;\r
1466 UINT32 PasswordLen;\r
1467 OPAL_SESSION Session;\r
1468 BOOLEAN PressEsc;\r
1469 EFI_INPUT_KEY Key;\r
1470 TCG_RESULT Ret;\r
1471 BOOLEAN PasswordFailed;\r
1472 CHAR16 *PopUpString;\r
1473 CHAR16 *PopUpString2;\r
1474 CHAR16 *PopUpString3;\r
1475 UINTN BufferSize;\r
112e584b
SZ
1476\r
1477 if (Dev == NULL) {\r
1478 return;\r
1479 }\r
1480\r
1481 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1482\r
1483 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1484\r
4ec00f82 1485 if ((!KeepUserData) &&\r
c411b485
MK
1486 (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME))\r
1487 {\r
1488 BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds");\r
40d32e79
ED
1489 PopUpString2 = AllocateZeroPool (BufferSize);\r
1490 ASSERT (PopUpString2 != NULL);\r
1491 UnicodeSPrint (\r
c411b485
MK
1492 PopUpString2,\r
1493 BufferSize,\r
1494 L"WARNING: Revert action will take about %d seconds",\r
1495 Dev->OpalDisk.EstimateTimeCost\r
40d32e79 1496 );\r
f5245a1d 1497 PopUpString3 = L"DO NOT power off system during the revert action!";\r
40d32e79
ED
1498 } else {\r
1499 PopUpString2 = NULL;\r
f5245a1d 1500 PopUpString3 = NULL;\r
40d32e79
ED
1501 }\r
1502\r
112e584b
SZ
1503 Count = 0;\r
1504\r
c411b485
MK
1505 ZeroMem (&Session, sizeof (Session));\r
1506 Session.Sscp = Dev->OpalDisk.Sscp;\r
1507 Session.MediaId = Dev->OpalDisk.MediaId;\r
112e584b
SZ
1508 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1509\r
1510 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 1511 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);\r
112e584b 1512 if (PressEsc) {\r
c411b485
MK
1513 do {\r
1514 CreatePopUp (\r
1515 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1516 &Key,\r
1517 L"Press ENTER to skip the request and continue boot,",\r
1518 L"Press ESC to input password again",\r
1519 NULL\r
1520 );\r
1521 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
112e584b 1522\r
c411b485
MK
1523 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1524 gST->ConOut->ClearScreen (gST->ConOut);\r
1525 goto Done;\r
1526 } else {\r
1527 //\r
1528 // Let user input password again.\r
1529 //\r
1530 continue;\r
1531 }\r
112e584b
SZ
1532 }\r
1533\r
1534 if (Password == NULL) {\r
c411b485 1535 Count++;\r
112e584b
SZ
1536 continue;\r
1537 }\r
c411b485
MK
1538\r
1539 PasswordLen = (UINT32)AsciiStrLen (Password);\r
112e584b
SZ
1540\r
1541 if ((Dev->OpalDisk.SupportedAttributes.PyriteSsc == 1) &&\r
c411b485
MK
1542 (Dev->OpalDisk.LockingFeature.MediaEncryption == 0))\r
1543 {\r
112e584b
SZ
1544 //\r
1545 // For pyrite type device which does not support media encryption,\r
1546 // it does not accept "Keep User Data" parameter.\r
1547 // So here hardcode a FALSE for this case.\r
1548 //\r
c411b485 1549 Ret = OpalUtilRevert (\r
112e584b
SZ
1550 &Session,\r
1551 FALSE,\r
1552 Password,\r
1553 PasswordLen,\r
1554 &PasswordFailed,\r
1555 Dev->OpalDisk.Msid,\r
1556 Dev->OpalDisk.MsidLength\r
1557 );\r
1558 } else {\r
c411b485 1559 Ret = OpalUtilRevert (\r
112e584b
SZ
1560 &Session,\r
1561 KeepUserData,\r
1562 Password,\r
1563 PasswordLen,\r
1564 &PasswordFailed,\r
1565 Dev->OpalDisk.Msid,\r
1566 Dev->OpalDisk.MsidLength\r
1567 );\r
1568 }\r
c411b485 1569\r
112e584b
SZ
1570 if (Ret == TcgResultSuccess) {\r
1571 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
1572 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1573 } else {\r
1574 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1575 }\r
1576\r
1577 if (Password != NULL) {\r
1578 ZeroMem (Password, PasswordLen);\r
1579 FreePool (Password);\r
1580 }\r
1581\r
1582 if (Ret == TcgResultSuccess) {\r
1583 break;\r
1584 }\r
1585\r
1586 Count++;\r
1587\r
1588 do {\r
1589 CreatePopUp (\r
1590 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1591 &Key,\r
1592 L"Invalid password, request failed.",\r
1593 L"Press ENTER to retry",\r
1594 NULL\r
1595 );\r
1596 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1597 }\r
1598\r
1599 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1600 do {\r
1601 CreatePopUp (\r
1602 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1603 &Key,\r
1604 L"Opal password retry count exceeds the limit.",\r
1605 L"Press ENTER to skip the request and continue boot",\r
1606 NULL\r
1607 );\r
1608 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
c411b485
MK
1609\r
1610 gST->ConOut->ClearScreen (gST->ConOut);\r
112e584b 1611 }\r
40d32e79
ED
1612\r
1613Done:\r
1614 if (PopUpString2 != NULL) {\r
1615 FreePool (PopUpString2);\r
1616 }\r
112e584b
SZ
1617}\r
1618\r
1619/**\r
1620 Process Secure Erase OPAL request.\r
1621\r
1622 @param[in] Dev The device which has Secure Erase OPAL request.\r
1623 @param[in] RequestString Request string.\r
1624\r
1625**/\r
1626VOID\r
1627ProcessOpalRequestSecureErase (\r
c411b485
MK
1628 IN OPAL_DRIVER_DEVICE *Dev,\r
1629 IN CHAR16 *RequestString\r
112e584b
SZ
1630 )\r
1631{\r
c411b485
MK
1632 UINT8 Count;\r
1633 CHAR8 *Password;\r
1634 UINT32 PasswordLen;\r
1635 OPAL_SESSION Session;\r
1636 BOOLEAN PressEsc;\r
1637 EFI_INPUT_KEY Key;\r
1638 TCG_RESULT Ret;\r
1639 BOOLEAN PasswordFailed;\r
1640 CHAR16 *PopUpString;\r
1641 CHAR16 *PopUpString2;\r
1642 CHAR16 *PopUpString3;\r
1643 UINTN BufferSize;\r
112e584b
SZ
1644\r
1645 if (Dev == NULL) {\r
1646 return;\r
1647 }\r
1648\r
1649 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1650\r
1651 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1652\r
f5245a1d 1653 if (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME) {\r
c411b485 1654 BufferSize = StrSize (L"Warning: Secure erase action will take about ####### seconds");\r
f5245a1d
CM
1655 PopUpString2 = AllocateZeroPool (BufferSize);\r
1656 ASSERT (PopUpString2 != NULL);\r
1657 UnicodeSPrint (\r
c411b485
MK
1658 PopUpString2,\r
1659 BufferSize,\r
1660 L"WARNING: Secure erase action will take about %d seconds",\r
1661 Dev->OpalDisk.EstimateTimeCost\r
f5245a1d
CM
1662 );\r
1663 PopUpString3 = L"DO NOT power off system during the action!";\r
1664 } else {\r
1665 PopUpString2 = NULL;\r
1666 PopUpString3 = NULL;\r
1667 }\r
c411b485 1668\r
112e584b
SZ
1669 Count = 0;\r
1670\r
c411b485
MK
1671 ZeroMem (&Session, sizeof (Session));\r
1672 Session.Sscp = Dev->OpalDisk.Sscp;\r
1673 Session.MediaId = Dev->OpalDisk.MediaId;\r
112e584b
SZ
1674 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1675\r
1676 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 1677 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);\r
112e584b 1678 if (PressEsc) {\r
c411b485
MK
1679 do {\r
1680 CreatePopUp (\r
1681 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1682 &Key,\r
1683 L"Press ENTER to skip the request and continue boot,",\r
1684 L"Press ESC to input password again",\r
1685 NULL\r
1686 );\r
1687 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
112e584b 1688\r
c411b485
MK
1689 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1690 gST->ConOut->ClearScreen (gST->ConOut);\r
1691 goto Done;\r
1692 } else {\r
1693 //\r
1694 // Let user input password again.\r
1695 //\r
1696 continue;\r
1697 }\r
112e584b
SZ
1698 }\r
1699\r
1700 if (Password == NULL) {\r
c411b485 1701 Count++;\r
112e584b
SZ
1702 continue;\r
1703 }\r
112e584b 1704\r
c411b485
MK
1705 PasswordLen = (UINT32)AsciiStrLen (Password);\r
1706\r
1707 Ret = OpalUtilSecureErase (&Session, Password, PasswordLen, &PasswordFailed);\r
112e584b
SZ
1708 if (Ret == TcgResultSuccess) {\r
1709 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
1710 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1711 } else {\r
1712 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1713 }\r
1714\r
1715 if (Password != NULL) {\r
1716 ZeroMem (Password, PasswordLen);\r
1717 FreePool (Password);\r
1718 }\r
1719\r
1720 if (Ret == TcgResultSuccess) {\r
1721 break;\r
1722 }\r
1723\r
1724 Count++;\r
1725\r
1726 do {\r
1727 CreatePopUp (\r
1728 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1729 &Key,\r
1730 L"Invalid password, request failed.",\r
1731 L"Press ENTER to retry",\r
1732 NULL\r
1733 );\r
1734 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1735 }\r
1736\r
1737 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1738 do {\r
1739 CreatePopUp (\r
1740 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1741 &Key,\r
1742 L"Opal password retry count exceeds the limit.",\r
1743 L"Press ENTER to skip the request and continue boot",\r
1744 NULL\r
1745 );\r
1746 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
c411b485
MK
1747\r
1748 gST->ConOut->ClearScreen (gST->ConOut);\r
112e584b 1749 }\r
f5245a1d
CM
1750\r
1751Done:\r
1752 if (PopUpString2 != NULL) {\r
1753 FreePool (PopUpString2);\r
1754 }\r
112e584b
SZ
1755}\r
1756\r
1757/**\r
1758 Process Set Admin Pwd OPAL request.\r
1759\r
1760 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.\r
1761 @param[in] RequestString Request string.\r
1762\r
1763**/\r
1764VOID\r
1765ProcessOpalRequestSetUserPwd (\r
c411b485
MK
1766 IN OPAL_DRIVER_DEVICE *Dev,\r
1767 IN CHAR16 *RequestString\r
112e584b
SZ
1768 )\r
1769{\r
c411b485
MK
1770 UINT8 Count;\r
1771 CHAR8 *OldPassword;\r
1772 UINT32 OldPasswordLen;\r
1773 CHAR8 *Password;\r
1774 UINT32 PasswordLen;\r
1775 CHAR8 *PasswordConfirm;\r
1776 UINT32 PasswordLenConfirm;\r
1777 OPAL_SESSION Session;\r
1778 BOOLEAN PressEsc;\r
1779 EFI_INPUT_KEY Key;\r
1780 TCG_RESULT Ret;\r
1781 CHAR16 *PopUpString;\r
112e584b
SZ
1782\r
1783 if (Dev == NULL) {\r
1784 return;\r
1785 }\r
1786\r
1787 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1788\r
1789 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1790\r
1791 Count = 0;\r
1792\r
1793 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 1794 OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", NULL, &PressEsc);\r
112e584b 1795 if (PressEsc) {\r
c411b485
MK
1796 do {\r
1797 CreatePopUp (\r
1798 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1799 &Key,\r
1800 L"Press ENTER to skip the request and continue boot,",\r
1801 L"Press ESC to input password again",\r
1802 NULL\r
1803 );\r
1804 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
112e584b 1805\r
c411b485
MK
1806 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1807 gST->ConOut->ClearScreen (gST->ConOut);\r
1808 return;\r
1809 } else {\r
1810 //\r
1811 // Let user input password again.\r
1812 //\r
1813 continue;\r
1814 }\r
112e584b
SZ
1815 }\r
1816\r
1817 if (OldPassword == NULL) {\r
c411b485 1818 Count++;\r
112e584b
SZ
1819 continue;\r
1820 }\r
112e584b 1821\r
c411b485
MK
1822 OldPasswordLen = (UINT32)AsciiStrLen (OldPassword);\r
1823\r
1824 ZeroMem (&Session, sizeof (Session));\r
1825 Session.Sscp = Dev->OpalDisk.Sscp;\r
1826 Session.MediaId = Dev->OpalDisk.MediaId;\r
112e584b 1827 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
c411b485 1828 Ret = OpalUtilVerifyPassword (&Session, OldPassword, OldPasswordLen, OPAL_LOCKING_SP_USER1_AUTHORITY);\r
112e584b
SZ
1829 if (Ret == TcgResultSuccess) {\r
1830 DEBUG ((DEBUG_INFO, "Verify with USER1 authority : Success\n"));\r
1831 } else {\r
1832 Ret = OpalUtilVerifyPassword (&Session, OldPassword, OldPasswordLen, OPAL_LOCKING_SP_ADMIN1_AUTHORITY);\r
1833 if (Ret == TcgResultSuccess) {\r
1834 DEBUG ((DEBUG_INFO, "Verify with ADMIN1 authority: Success\n"));\r
1835 } else {\r
1836 ZeroMem (OldPassword, OldPasswordLen);\r
1837 FreePool (OldPassword);\r
1838 DEBUG ((DEBUG_INFO, "Verify: Failure\n"));\r
1839 do {\r
1840 CreatePopUp (\r
1841 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1842 &Key,\r
1843 L"Incorrect password.",\r
1844 L"Press ENTER to retry",\r
1845 NULL\r
1846 );\r
1847 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
c411b485
MK
1848\r
1849 Count++;\r
112e584b
SZ
1850 continue;\r
1851 }\r
1852 }\r
1853\r
f5245a1d 1854 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);\r
112e584b
SZ
1855 if (Password == NULL) {\r
1856 ZeroMem (OldPassword, OldPasswordLen);\r
1857 FreePool (OldPassword);\r
c411b485 1858 Count++;\r
112e584b
SZ
1859 continue;\r
1860 }\r
c411b485
MK
1861\r
1862 PasswordLen = (UINT32)AsciiStrLen (Password);\r
112e584b 1863\r
f5245a1d 1864 PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);\r
112e584b
SZ
1865 if (PasswordConfirm == NULL) {\r
1866 ZeroMem (OldPassword, OldPasswordLen);\r
1867 FreePool (OldPassword);\r
1868 ZeroMem (Password, PasswordLen);\r
1869 FreePool (Password);\r
c411b485 1870 Count++;\r
112e584b
SZ
1871 continue;\r
1872 }\r
c411b485
MK
1873\r
1874 PasswordLenConfirm = (UINT32)AsciiStrLen (PasswordConfirm);\r
112e584b 1875 if ((PasswordLen != PasswordLenConfirm) ||\r
c411b485
MK
1876 (CompareMem (Password, PasswordConfirm, PasswordLen) != 0))\r
1877 {\r
112e584b
SZ
1878 ZeroMem (OldPassword, OldPasswordLen);\r
1879 FreePool (OldPassword);\r
1880 ZeroMem (Password, PasswordLen);\r
1881 FreePool (Password);\r
1882 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
1883 FreePool (PasswordConfirm);\r
1884 do {\r
1885 CreatePopUp (\r
1886 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1887 &Key,\r
1888 L"Passwords are not the same.",\r
1889 L"Press ENTER to retry",\r
1890 NULL\r
1891 );\r
1892 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
c411b485
MK
1893\r
1894 Count++;\r
112e584b
SZ
1895 continue;\r
1896 }\r
1897\r
1898 if (PasswordConfirm != NULL) {\r
1899 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
1900 FreePool (PasswordConfirm);\r
1901 }\r
1902\r
c411b485
MK
1903 ZeroMem (&Session, sizeof (Session));\r
1904 Session.Sscp = Dev->OpalDisk.Sscp;\r
1905 Session.MediaId = Dev->OpalDisk.MediaId;\r
112e584b 1906 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
c411b485
MK
1907 Ret = OpalUtilSetUserPassword (\r
1908 &Session,\r
1909 OldPassword,\r
1910 OldPasswordLen,\r
1911 Password,\r
1912 PasswordLen\r
1913 );\r
112e584b
SZ
1914 if (Ret == TcgResultSuccess) {\r
1915 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
1916 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1917 } else {\r
1918 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1919 }\r
1920\r
1921 if (OldPassword != NULL) {\r
1922 ZeroMem (OldPassword, OldPasswordLen);\r
1923 FreePool (OldPassword);\r
1924 }\r
1925\r
1926 if (Password != NULL) {\r
1927 ZeroMem (Password, PasswordLen);\r
1928 FreePool (Password);\r
1929 }\r
1930\r
1931 if (Ret == TcgResultSuccess) {\r
1932 break;\r
1933 }\r
1934\r
1935 Count++;\r
1936\r
1937 do {\r
1938 CreatePopUp (\r
1939 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1940 &Key,\r
1941 L"Request failed.",\r
1942 L"Press ENTER to retry",\r
1943 NULL\r
1944 );\r
1945 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1946 }\r
1947\r
1948 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1949 do {\r
1950 CreatePopUp (\r
1951 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1952 &Key,\r
1953 L"Opal password retry count exceeds the limit.",\r
1954 L"Press ENTER to skip the request and continue boot",\r
1955 NULL\r
1956 );\r
1957 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
c411b485
MK
1958\r
1959 gST->ConOut->ClearScreen (gST->ConOut);\r
112e584b
SZ
1960 }\r
1961}\r
1962\r
1963/**\r
1964 Process Set Admin Pwd OPAL request.\r
1965\r
1966 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.\r
1967 @param[in] RequestString Request string.\r
1968\r
1969**/\r
1970VOID\r
1971ProcessOpalRequestSetAdminPwd (\r
c411b485
MK
1972 IN OPAL_DRIVER_DEVICE *Dev,\r
1973 IN CHAR16 *RequestString\r
112e584b
SZ
1974 )\r
1975{\r
c411b485
MK
1976 UINT8 Count;\r
1977 CHAR8 *OldPassword;\r
1978 UINT32 OldPasswordLen;\r
1979 CHAR8 *Password;\r
1980 UINT32 PasswordLen;\r
1981 CHAR8 *PasswordConfirm;\r
1982 UINT32 PasswordLenConfirm;\r
1983 OPAL_SESSION Session;\r
1984 BOOLEAN PressEsc;\r
1985 EFI_INPUT_KEY Key;\r
1986 TCG_RESULT Ret;\r
1987 CHAR16 *PopUpString;\r
112e584b
SZ
1988\r
1989 if (Dev == NULL) {\r
1990 return;\r
1991 }\r
1992\r
1993 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1994\r
1995 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1996\r
1997 Count = 0;\r
1998\r
1999 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 2000 OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", NULL, &PressEsc);\r
112e584b 2001 if (PressEsc) {\r
c411b485
MK
2002 do {\r
2003 CreatePopUp (\r
2004 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
2005 &Key,\r
2006 L"Press ENTER to skip the request and continue boot,",\r
2007 L"Press ESC to input password again",\r
2008 NULL\r
2009 );\r
2010 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
112e584b 2011\r
c411b485
MK
2012 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
2013 gST->ConOut->ClearScreen (gST->ConOut);\r
2014 return;\r
2015 } else {\r
2016 //\r
2017 // Let user input password again.\r
2018 //\r
2019 continue;\r
2020 }\r
112e584b
SZ
2021 }\r
2022\r
2023 if (OldPassword == NULL) {\r
c411b485 2024 Count++;\r
112e584b
SZ
2025 continue;\r
2026 }\r
112e584b 2027\r
c411b485
MK
2028 OldPasswordLen = (UINT32)AsciiStrLen (OldPassword);\r
2029\r
2030 ZeroMem (&Session, sizeof (Session));\r
2031 Session.Sscp = Dev->OpalDisk.Sscp;\r
2032 Session.MediaId = Dev->OpalDisk.MediaId;\r
112e584b 2033 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
c411b485 2034 Ret = OpalUtilVerifyPassword (&Session, OldPassword, OldPasswordLen, OPAL_LOCKING_SP_ADMIN1_AUTHORITY);\r
112e584b
SZ
2035 if (Ret == TcgResultSuccess) {\r
2036 DEBUG ((DEBUG_INFO, "Verify: Success\n"));\r
2037 } else {\r
2038 ZeroMem (OldPassword, OldPasswordLen);\r
2039 FreePool (OldPassword);\r
2040 DEBUG ((DEBUG_INFO, "Verify: Failure\n"));\r
2041 do {\r
2042 CreatePopUp (\r
2043 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
2044 &Key,\r
2045 L"Incorrect password.",\r
2046 L"Press ENTER to retry",\r
2047 NULL\r
2048 );\r
2049 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
c411b485
MK
2050\r
2051 Count++;\r
112e584b
SZ
2052 continue;\r
2053 }\r
2054\r
f5245a1d 2055 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);\r
112e584b
SZ
2056 if (Password == NULL) {\r
2057 ZeroMem (OldPassword, OldPasswordLen);\r
2058 FreePool (OldPassword);\r
c411b485 2059 Count++;\r
112e584b
SZ
2060 continue;\r
2061 }\r
c411b485
MK
2062\r
2063 PasswordLen = (UINT32)AsciiStrLen (Password);\r
112e584b 2064\r
f5245a1d 2065 PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);\r
112e584b
SZ
2066 if (PasswordConfirm == NULL) {\r
2067 ZeroMem (OldPassword, OldPasswordLen);\r
2068 FreePool (OldPassword);\r
2069 ZeroMem (Password, PasswordLen);\r
2070 FreePool (Password);\r
c411b485 2071 Count++;\r
112e584b
SZ
2072 continue;\r
2073 }\r
c411b485
MK
2074\r
2075 PasswordLenConfirm = (UINT32)AsciiStrLen (PasswordConfirm);\r
112e584b 2076 if ((PasswordLen != PasswordLenConfirm) ||\r
c411b485
MK
2077 (CompareMem (Password, PasswordConfirm, PasswordLen) != 0))\r
2078 {\r
112e584b
SZ
2079 ZeroMem (OldPassword, OldPasswordLen);\r
2080 FreePool (OldPassword);\r
2081 ZeroMem (Password, PasswordLen);\r
2082 FreePool (Password);\r
2083 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
2084 FreePool (PasswordConfirm);\r
2085 do {\r
2086 CreatePopUp (\r
2087 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
2088 &Key,\r
2089 L"Passwords are not the same.",\r
2090 L"Press ENTER to retry",\r
2091 NULL\r
2092 );\r
2093 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
c411b485
MK
2094\r
2095 Count++;\r
112e584b
SZ
2096 continue;\r
2097 }\r
2098\r
2099 if (PasswordConfirm != NULL) {\r
2100 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
2101 FreePool (PasswordConfirm);\r
2102 }\r
2103\r
c411b485
MK
2104 ZeroMem (&Session, sizeof (Session));\r
2105 Session.Sscp = Dev->OpalDisk.Sscp;\r
2106 Session.MediaId = Dev->OpalDisk.MediaId;\r
112e584b 2107 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
c411b485
MK
2108 Ret = OpalUtilSetAdminPassword (\r
2109 &Session,\r
2110 OldPassword,\r
2111 OldPasswordLen,\r
2112 Password,\r
2113 PasswordLen\r
2114 );\r
112e584b
SZ
2115 if (Ret == TcgResultSuccess) {\r
2116 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
2117 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
2118 } else {\r
2119 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
2120 }\r
2121\r
2122 if (OldPassword != NULL) {\r
2123 ZeroMem (OldPassword, OldPasswordLen);\r
2124 FreePool (OldPassword);\r
2125 }\r
2126\r
2127 if (Password != NULL) {\r
2128 ZeroMem (Password, PasswordLen);\r
2129 FreePool (Password);\r
2130 }\r
2131\r
2132 if (Ret == TcgResultSuccess) {\r
2133 break;\r
2134 }\r
2135\r
2136 Count++;\r
2137\r
2138 do {\r
2139 CreatePopUp (\r
2140 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
2141 &Key,\r
2142 L"Request failed.",\r
2143 L"Press ENTER to retry",\r
2144 NULL\r
2145 );\r
2146 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
2147 }\r
2148\r
2149 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
2150 do {\r
2151 CreatePopUp (\r
2152 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
2153 &Key,\r
2154 L"Opal password retry count exceeds the limit.",\r
2155 L"Press ENTER to skip the request and continue boot",\r
2156 NULL\r
2157 );\r
2158 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
c411b485
MK
2159\r
2160 gST->ConOut->ClearScreen (gST->ConOut);\r
112e584b
SZ
2161 }\r
2162}\r
2163\r
2164/**\r
2165 Process OPAL request.\r
2166\r
2167 @param[in] Dev The device which has OPAL request.\r
2168\r
2169**/\r
2170VOID\r
2171ProcessOpalRequest (\r
c411b485 2172 IN OPAL_DRIVER_DEVICE *Dev\r
112e584b
SZ
2173 )\r
2174{\r
2175 EFI_STATUS Status;\r
2176 OPAL_REQUEST_VARIABLE *TempVariable;\r
2177 OPAL_REQUEST_VARIABLE *Variable;\r
2178 UINTN VariableSize;\r
2179 EFI_DEVICE_PATH_PROTOCOL *DevicePathInVariable;\r
2180 UINTN DevicePathSizeInVariable;\r
2181 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
2182 UINTN DevicePathSize;\r
2183 BOOLEAN KeepUserData;\r
2184\r
2185 DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__));\r
2186\r
2187 if (mOpalRequestVariable == NULL) {\r
2188 Status = GetVariable2 (\r
2189 OPAL_REQUEST_VARIABLE_NAME,\r
2190 &gHiiSetupVariableGuid,\r
c411b485 2191 (VOID **)&Variable,\r
112e584b
SZ
2192 &VariableSize\r
2193 );\r
2194 if (EFI_ERROR (Status) || (Variable == NULL)) {\r
2195 return;\r
2196 }\r
c411b485
MK
2197\r
2198 mOpalRequestVariable = Variable;\r
112e584b
SZ
2199 mOpalRequestVariableSize = VariableSize;\r
2200\r
2201 //\r
2202 // Delete the OPAL request variable.\r
2203 //\r
2204 Status = gRT->SetVariable (\r
2205 OPAL_REQUEST_VARIABLE_NAME,\r
c411b485 2206 (EFI_GUID *)&gHiiSetupVariableGuid,\r
112e584b
SZ
2207 0,\r
2208 0,\r
2209 NULL\r
2210 );\r
2211 ASSERT_EFI_ERROR (Status);\r
2212 } else {\r
c411b485 2213 Variable = mOpalRequestVariable;\r
112e584b
SZ
2214 VariableSize = mOpalRequestVariableSize;\r
2215 }\r
2216\r
2217 //\r
2218 // Process the OPAL requests.\r
2219 //\r
2220 TempVariable = Variable;\r
2221 while ((VariableSize > sizeof (OPAL_REQUEST_VARIABLE)) &&\r
2222 (VariableSize >= TempVariable->Length) &&\r
c411b485
MK
2223 (TempVariable->Length > sizeof (OPAL_REQUEST_VARIABLE)))\r
2224 {\r
2225 DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *)((UINTN)TempVariable + sizeof (OPAL_REQUEST_VARIABLE));\r
112e584b 2226 DevicePathSizeInVariable = GetDevicePathSize (DevicePathInVariable);\r
c411b485
MK
2227 DevicePath = Dev->OpalDisk.OpalDevicePath;\r
2228 DevicePathSize = GetDevicePathSize (DevicePath);\r
112e584b 2229 if ((DevicePathSize == DevicePathSizeInVariable) &&\r
c411b485
MK
2230 (CompareMem (DevicePath, DevicePathInVariable, DevicePathSize) == 0))\r
2231 {\r
112e584b
SZ
2232 //\r
2233 // Found the node for the OPAL device.\r
2234 //\r
2235 if (TempVariable->OpalRequest.SetAdminPwd != 0) {\r
2236 ProcessOpalRequestSetAdminPwd (Dev, L"Update Admin Pwd:");\r
2237 }\r
c411b485 2238\r
112e584b
SZ
2239 if (TempVariable->OpalRequest.SetUserPwd != 0) {\r
2240 ProcessOpalRequestSetUserPwd (Dev, L"Set User Pwd:");\r
2241 }\r
c411b485
MK
2242\r
2243 if (TempVariable->OpalRequest.SecureErase != 0) {\r
112e584b
SZ
2244 ProcessOpalRequestSecureErase (Dev, L"Secure Erase:");\r
2245 }\r
c411b485 2246\r
112e584b 2247 if (TempVariable->OpalRequest.Revert != 0) {\r
c411b485 2248 KeepUserData = (BOOLEAN)TempVariable->OpalRequest.KeepUserData;\r
112e584b
SZ
2249 ProcessOpalRequestRevert (\r
2250 Dev,\r
2251 KeepUserData,\r
2252 KeepUserData ? L"Admin Revert(keep):" : L"Admin Revert:"\r
2253 );\r
2254 }\r
c411b485 2255\r
112e584b
SZ
2256 if (TempVariable->OpalRequest.PsidRevert != 0) {\r
2257 ProcessOpalRequestPsidRevert (Dev, L"Psid Revert:");\r
2258 }\r
c411b485 2259\r
112e584b
SZ
2260 if (TempVariable->OpalRequest.DisableUser != 0) {\r
2261 ProcessOpalRequestDisableUser (Dev, L"Disable User:");\r
2262 }\r
c411b485 2263\r
112e584b
SZ
2264 if (TempVariable->OpalRequest.EnableFeature != 0) {\r
2265 ProcessOpalRequestEnableFeature (Dev, L"Enable Feature:");\r
2266 }\r
2267\r
46e69608
ED
2268 //\r
2269 // Update Device ownership.\r
2270 // Later BlockSID command may block the update.\r
2271 //\r
2272 OpalDiskUpdateOwnerShip (&Dev->OpalDisk);\r
2273\r
112e584b
SZ
2274 break;\r
2275 }\r
2276\r
2277 VariableSize -= TempVariable->Length;\r
c411b485 2278 TempVariable = (OPAL_REQUEST_VARIABLE *)((UINTN)TempVariable + TempVariable->Length);\r
112e584b
SZ
2279 }\r
2280\r
2281 DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__));\r
2282}\r
2283\r
2284/**\r
2285 Add new device to the global device list.\r
2286\r
2287 @param Dev New create device.\r
2288\r
2289**/\r
2290VOID\r
c411b485
MK
2291AddDeviceToTail (\r
2292 IN OPAL_DRIVER_DEVICE *Dev\r
112e584b
SZ
2293 )\r
2294{\r
c411b485 2295 OPAL_DRIVER_DEVICE *TmpDev;\r
112e584b
SZ
2296\r
2297 if (mOpalDriver.DeviceList == NULL) {\r
2298 mOpalDriver.DeviceList = Dev;\r
2299 } else {\r
2300 TmpDev = mOpalDriver.DeviceList;\r
2301 while (TmpDev->Next != NULL) {\r
2302 TmpDev = TmpDev->Next;\r
2303 }\r
2304\r
2305 TmpDev->Next = Dev;\r
2306 }\r
2307}\r
2308\r
2309/**\r
2310 Remove one device in the global device list.\r
2311\r
2312 @param Dev The device need to be removed.\r
2313\r
2314**/\r
2315VOID\r
2316RemoveDevice (\r
c411b485 2317 IN OPAL_DRIVER_DEVICE *Dev\r
112e584b
SZ
2318 )\r
2319{\r
c411b485 2320 OPAL_DRIVER_DEVICE *TmpDev;\r
112e584b
SZ
2321\r
2322 if (mOpalDriver.DeviceList == NULL) {\r
2323 return;\r
2324 }\r
2325\r
2326 if (mOpalDriver.DeviceList == Dev) {\r
2327 mOpalDriver.DeviceList = NULL;\r
2328 return;\r
2329 }\r
2330\r
2331 TmpDev = mOpalDriver.DeviceList;\r
2332 while (TmpDev->Next != NULL) {\r
2333 if (TmpDev->Next == Dev) {\r
2334 TmpDev->Next = Dev->Next;\r
2335 break;\r
2336 }\r
2337 }\r
2338}\r
2339\r
2340/**\r
2341 Get current device count.\r
2342\r
2343 @retval return the current created device count.\r
2344\r
2345**/\r
2346UINT8\r
2347GetDeviceCount (\r
2348 VOID\r
2349 )\r
2350{\r
c411b485
MK
2351 UINT8 Count;\r
2352 OPAL_DRIVER_DEVICE *TmpDev;\r
112e584b 2353\r
c411b485 2354 Count = 0;\r
112e584b
SZ
2355 TmpDev = mOpalDriver.DeviceList;\r
2356\r
2357 while (TmpDev != NULL) {\r
2358 Count++;\r
2359 TmpDev = TmpDev->Next;\r
2360 }\r
2361\r
2362 return Count;\r
2363}\r
2364\r
2365/**\r
2366 Get devcie list info.\r
2367\r
2368 @retval return the device list pointer.\r
2369**/\r
c411b485
MK
2370OPAL_DRIVER_DEVICE *\r
2371OpalDriverGetDeviceList (\r
112e584b
SZ
2372 VOID\r
2373 )\r
2374{\r
2375 return mOpalDriver.DeviceList;\r
2376}\r
2377\r
112e584b
SZ
2378/**\r
2379 Stop this Controller.\r
2380\r
2381 @param Dev The device need to be stopped.\r
2382\r
2383**/\r
2384VOID\r
2385OpalDriverStopDevice (\r
c411b485 2386 OPAL_DRIVER_DEVICE *Dev\r
112e584b
SZ
2387 )\r
2388{\r
2389 //\r
2390 // free each name\r
2391 //\r
c411b485 2392 FreePool (Dev->Name16);\r
112e584b
SZ
2393\r
2394 //\r
2395 // remove OPAL_DRIVER_DEVICE from the list\r
2396 // it updates the controllerList pointer\r
2397 //\r
c411b485 2398 RemoveDevice (Dev);\r
112e584b
SZ
2399\r
2400 //\r
2401 // close protocols that were opened\r
2402 //\r
c411b485
MK
2403 gBS->CloseProtocol (\r
2404 Dev->Handle,\r
2405 &gEfiStorageSecurityCommandProtocolGuid,\r
2406 gOpalDriverBinding.DriverBindingHandle,\r
2407 Dev->Handle\r
2408 );\r
2409\r
2410 gBS->CloseProtocol (\r
2411 Dev->Handle,\r
2412 &gEfiBlockIoProtocolGuid,\r
2413 gOpalDriverBinding.DriverBindingHandle,\r
2414 Dev->Handle\r
2415 );\r
2416\r
2417 FreePool (Dev);\r
112e584b
SZ
2418}\r
2419\r
2420/**\r
2421 Get devcie name through the component name protocol.\r
2422\r
2423 @param[in] AllHandlesBuffer The handle buffer for current system.\r
2424 @param[in] NumAllHandles The number of handles for the handle buffer.\r
2425 @param[in] Dev The device which need to get name.\r
2426 @param[in] UseComp1 Whether use component name or name2 protocol.\r
2427\r
2428 @retval TRUE Find the name for this device.\r
2429 @retval FALSE Not found the name for this device.\r
2430**/\r
2431BOOLEAN\r
c411b485
MK
2432OpalDriverGetDeviceNameByProtocol (\r
2433 EFI_HANDLE *AllHandlesBuffer,\r
2434 UINTN NumAllHandles,\r
2435 OPAL_DRIVER_DEVICE *Dev,\r
2436 BOOLEAN UseComp1\r
112e584b
SZ
2437 )\r
2438{\r
c411b485 2439 EFI_HANDLE *ProtocolHandlesBuffer;\r
112e584b
SZ
2440 UINTN NumProtocolHandles;\r
2441 EFI_STATUS Status;\r
c411b485 2442 EFI_COMPONENT_NAME2_PROTOCOL *Cnp1_2; // efi component name and componentName2 have same layout\r
112e584b
SZ
2443 EFI_GUID Protocol;\r
2444 UINTN StrLength;\r
c411b485 2445 EFI_DEVICE_PATH_PROTOCOL *TmpDevPath;\r
112e584b
SZ
2446 UINTN Index1;\r
2447 UINTN Index2;\r
2448 EFI_HANDLE TmpHandle;\r
2449 CHAR16 *DevName;\r
2450\r
c411b485 2451 if ((Dev == NULL) || (AllHandlesBuffer == NULL) || (NumAllHandles == 0)) {\r
112e584b
SZ
2452 return FALSE;\r
2453 }\r
2454\r
2455 Protocol = UseComp1 ? gEfiComponentNameProtocolGuid : gEfiComponentName2ProtocolGuid;\r
2456\r
2457 //\r
2458 // Find all EFI_HANDLES with protocol\r
2459 //\r
c411b485
MK
2460 Status = gBS->LocateHandleBuffer (\r
2461 ByProtocol,\r
2462 &Protocol,\r
2463 NULL,\r
2464 &NumProtocolHandles,\r
2465 &ProtocolHandlesBuffer\r
2466 );\r
2467 if (EFI_ERROR (Status)) {\r
112e584b
SZ
2468 return FALSE;\r
2469 }\r
2470\r
112e584b
SZ
2471 //\r
2472 // Exit early if no supported devices\r
2473 //\r
2474 if (NumProtocolHandles == 0) {\r
2475 return FALSE;\r
2476 }\r
2477\r
2478 //\r
2479 // Get printable name by iterating through all protocols\r
2480 // using the handle as the child, and iterate through all handles for the controller\r
2481 // exit loop early once found, if not found, then delete device\r
2482 // storage security protocol instances already exist, add them to internal list\r
2483 //\r
2484 Status = EFI_DEVICE_ERROR;\r
2485 for (Index1 = 0; Index1 < NumProtocolHandles; Index1++) {\r
2486 DevName = NULL;\r
2487\r
2488 if (Dev->Name16 != NULL) {\r
2489 return TRUE;\r
2490 }\r
2491\r
2492 TmpHandle = ProtocolHandlesBuffer[Index1];\r
2493\r
c411b485
MK
2494 Status = gBS->OpenProtocol (\r
2495 TmpHandle,\r
2496 &Protocol,\r
2497 (VOID **)&Cnp1_2,\r
2498 gImageHandle,\r
2499 NULL,\r
2500 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
2501 );\r
2502 if (EFI_ERROR (Status) || (Cnp1_2 == NULL)) {\r
112e584b
SZ
2503 continue;\r
2504 }\r
2505\r
2506 //\r
2507 // Use all handles array as controller handle\r
2508 //\r
2509 for (Index2 = 0; Index2 < NumAllHandles; Index2++) {\r
c411b485
MK
2510 Status = Cnp1_2->GetControllerName (\r
2511 Cnp1_2,\r
2512 AllHandlesBuffer[Index2],\r
2513 Dev->Handle,\r
2514 LANGUAGE_ISO_639_2_ENGLISH,\r
2515 &DevName\r
2516 );\r
2517 if (EFI_ERROR (Status)) {\r
2518 Status = Cnp1_2->GetControllerName (\r
2519 Cnp1_2,\r
2520 AllHandlesBuffer[Index2],\r
2521 Dev->Handle,\r
2522 LANGUAGE_RFC_3066_ENGLISH,\r
2523 &DevName\r
2524 );\r
112e584b 2525 }\r
c411b485
MK
2526\r
2527 if (!EFI_ERROR (Status) && (DevName != NULL)) {\r
2528 StrLength = StrLen (DevName) + 1; // Add one for NULL terminator\r
2529 Dev->Name16 = AllocateZeroPool (StrLength * sizeof (CHAR16));\r
112e584b
SZ
2530 ASSERT (Dev->Name16 != NULL);\r
2531 StrCpyS (Dev->Name16, StrLength, DevName);\r
c411b485 2532 Dev->NameZ = (CHAR8 *)AllocateZeroPool (StrLength);\r
112e584b
SZ
2533 UnicodeStrToAsciiStrS (DevName, Dev->NameZ, StrLength);\r
2534\r
2535 //\r
2536 // Retrieve bridge BDF info and port number or namespace depending on type\r
2537 //\r
2538 TmpDevPath = NULL;\r
c411b485
MK
2539 Status = gBS->OpenProtocol (\r
2540 Dev->Handle,\r
2541 &gEfiDevicePathProtocolGuid,\r
2542 (VOID **)&TmpDevPath,\r
2543 gImageHandle,\r
2544 NULL,\r
2545 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
2546 );\r
2547 if (!EFI_ERROR (Status)) {\r
112e584b
SZ
2548 Dev->OpalDevicePath = DuplicateDevicePath (TmpDevPath);\r
2549 return TRUE;\r
2550 }\r
2551\r
2552 if (Dev->Name16 != NULL) {\r
c411b485 2553 FreePool (Dev->Name16);\r
112e584b
SZ
2554 Dev->Name16 = NULL;\r
2555 }\r
c411b485 2556\r
112e584b 2557 if (Dev->NameZ != NULL) {\r
c411b485 2558 FreePool (Dev->NameZ);\r
112e584b
SZ
2559 Dev->NameZ = NULL;\r
2560 }\r
2561 }\r
2562 }\r
2563 }\r
2564\r
2565 return FALSE;\r
2566}\r
2567\r
2568/**\r
2569 Get devcie name through the component name protocol.\r
2570\r
2571 @param[in] Dev The device which need to get name.\r
2572\r
2573 @retval TRUE Find the name for this device.\r
2574 @retval FALSE Not found the name for this device.\r
2575**/\r
2576BOOLEAN\r
c411b485
MK
2577OpalDriverGetDriverDeviceName (\r
2578 OPAL_DRIVER_DEVICE *Dev\r
112e584b
SZ
2579 )\r
2580{\r
c411b485
MK
2581 EFI_HANDLE *AllHandlesBuffer;\r
2582 UINTN NumAllHandles;\r
2583 EFI_STATUS Status;\r
112e584b
SZ
2584\r
2585 if (Dev == NULL) {\r
c411b485 2586 DEBUG ((DEBUG_ERROR | DEBUG_INIT, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));\r
112e584b
SZ
2587 return FALSE;\r
2588 }\r
2589\r
2590 //\r
2591 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName\r
2592 //\r
2593 if (Dev->Name16 == NULL) {\r
c411b485 2594 DEBUG ((DEBUG_ERROR | DEBUG_INIT, "Name is null, update it\n"));\r
112e584b
SZ
2595 //\r
2596 // Find all EFI_HANDLES\r
2597 //\r
c411b485
MK
2598 Status = gBS->LocateHandleBuffer (\r
2599 AllHandles,\r
2600 NULL,\r
2601 NULL,\r
2602 &NumAllHandles,\r
2603 &AllHandlesBuffer\r
2604 );\r
2605 if (EFI_ERROR (Status)) {\r
2606 DEBUG ((DEBUG_INFO, "LocateHandleBuffer for AllHandles failed %r\n", Status));\r
112e584b
SZ
2607 return FALSE;\r
2608 }\r
2609\r
2610 //\r
2611 // Try component Name2\r
2612 //\r
c411b485
MK
2613 if (!OpalDriverGetDeviceNameByProtocol (AllHandlesBuffer, NumAllHandles, Dev, FALSE)) {\r
2614 DEBUG ((DEBUG_ERROR | DEBUG_INIT, "ComponentName2 failed to get device name, try ComponentName\n"));\r
2615 if (!OpalDriverGetDeviceNameByProtocol (AllHandlesBuffer, NumAllHandles, Dev, TRUE)) {\r
2616 DEBUG ((DEBUG_ERROR | DEBUG_INIT, "ComponentName failed to get device name, skip device\n"));\r
112e584b
SZ
2617 return FALSE;\r
2618 }\r
2619 }\r
2620 }\r
2621\r
2622 return TRUE;\r
2623}\r
2624\r
2625/**\r
2626 Main entry for this driver.\r
2627\r
2628 @param ImageHandle Image Handle this driver.\r
2629 @param SystemTable Pointer to SystemTable.\r
2630\r
dd40a1f8 2631 @retval EFI_SUCCESS This function always complete successfully.\r
112e584b
SZ
2632**/\r
2633EFI_STATUS\r
2634EFIAPI\r
c411b485
MK
2635EfiDriverEntryPoint (\r
2636 IN EFI_HANDLE ImageHandle,\r
2637 IN EFI_SYSTEM_TABLE *SystemTable\r
112e584b
SZ
2638 )\r
2639{\r
c411b485
MK
2640 EFI_STATUS Status;\r
2641 EFI_EVENT EndOfDxeEvent;\r
112e584b
SZ
2642\r
2643 Status = EfiLibInstallDriverBindingComponentName2 (\r
2644 ImageHandle,\r
2645 SystemTable,\r
2646 &gOpalDriverBinding,\r
2647 ImageHandle,\r
2648 &gOpalComponentName,\r
2649 &gOpalComponentName2\r
2650 );\r
2651\r
c411b485
MK
2652 if (EFI_ERROR (Status)) {\r
2653 DEBUG ((DEBUG_ERROR, "Install protocols to Opal driver Handle failed\n"));\r
2654 return Status;\r
112e584b
SZ
2655 }\r
2656\r
2657 //\r
2658 // Initialize Driver object\r
2659 //\r
c411b485 2660 ZeroMem (&mOpalDriver, sizeof (mOpalDriver));\r
112e584b
SZ
2661 mOpalDriver.Handle = ImageHandle;\r
2662\r
2663 Status = gBS->CreateEventEx (\r
2664 EVT_NOTIFY_SIGNAL,\r
2665 TPL_CALLBACK,\r
2666 OpalEndOfDxeEventNotify,\r
2667 NULL,\r
2668 &gEfiEndOfDxeEventGroupGuid,\r
2669 &EndOfDxeEvent\r
2670 );\r
2671 ASSERT_EFI_ERROR (Status);\r
2672\r
112e584b
SZ
2673 //\r
2674 // Install Hii packages.\r
2675 //\r
c411b485 2676 HiiInstall ();\r
112e584b
SZ
2677\r
2678 return Status;\r
2679}\r
2680\r
2681/**\r
2682 Tests to see if this driver supports a given controller.\r
2683\r
2684 This function checks to see if the controller contains an instance of the\r
d6b926e7 2685 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCOL\r
112e584b
SZ
2686 and returns EFI_SUCCESS if it does.\r
2687\r
2688 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
2689 @param[in] ControllerHandle The Handle of the controller to test. This Handle\r
2690 must support a protocol interface that supplies\r
2691 an I/O abstraction to the driver.\r
2692 @param[in] RemainingDevicePath This parameter is ignored.\r
2693\r
2694 @retval EFI_SUCCESS The device contains required protocols\r
2695 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and\r
2696 RemainingDevicePath is already being managed by the driver\r
2697 specified by This.\r
2698 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and\r
2699 RemainingDevicePath is already being managed by a different\r
2700 driver or an application that requires exclusive access.\r
2701 Currently not implemented.\r
2702 @retval EFI_UNSUPPORTED The device does not contain requires protocols\r
2703\r
2704**/\r
2705EFI_STATUS\r
2706EFIAPI\r
c411b485
MK
2707OpalEfiDriverBindingSupported (\r
2708 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
112e584b 2709 IN EFI_HANDLE Controller,\r
c411b485 2710 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
112e584b
SZ
2711 )\r
2712{\r
c411b485
MK
2713 EFI_STATUS Status;\r
2714 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *SecurityCommand;\r
112e584b
SZ
2715\r
2716 if (mOpalEndOfDxe) {\r
2717 return EFI_UNSUPPORTED;\r
2718 }\r
2719\r
2720 //\r
2721 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.\r
2722 //\r
c411b485
MK
2723 Status = gBS->OpenProtocol (\r
2724 Controller,\r
2725 &gEfiStorageSecurityCommandProtocolGuid,\r
2726 (VOID **)&SecurityCommand,\r
2727 This->DriverBindingHandle,\r
2728 Controller,\r
2729 EFI_OPEN_PROTOCOL_BY_DRIVER\r
2730 );\r
112e584b
SZ
2731\r
2732 if (Status == EFI_ALREADY_STARTED) {\r
2733 return EFI_SUCCESS;\r
2734 }\r
2735\r
c411b485 2736 if (EFI_ERROR (Status)) {\r
112e584b
SZ
2737 return Status;\r
2738 }\r
2739\r
2740 //\r
2741 // Close protocol and reopen in Start call\r
2742 //\r
c411b485
MK
2743 gBS->CloseProtocol (\r
2744 Controller,\r
2745 &gEfiStorageSecurityCommandProtocolGuid,\r
2746 This->DriverBindingHandle,\r
2747 Controller\r
2748 );\r
112e584b
SZ
2749\r
2750 return EFI_SUCCESS;\r
2751}\r
2752\r
2753/**\r
2754 Enables Opal Management on a supported device if available.\r
2755\r
2756 The start function is designed to be called after the Opal UEFI Driver has confirmed the\r
2757 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.\r
2758 This function will complete the other necessary checks, such as verifying the device supports\r
2759 the correct version of Opal. Upon verification, it will add the device to the\r
d6b926e7 2760 Opal HII list in order to expose Opal management options.\r
112e584b
SZ
2761\r
2762 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
2763 @param[in] ControllerHandle The Handle of the controller to start. This Handle\r
2764 must support a protocol interface that supplies\r
2765 an I/O abstraction to the driver.\r
2766 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r
2767 parameter is ignored by device drivers, and is optional for bus\r
2768 drivers. For a bus driver, if this parameter is NULL, then handles\r
2769 for all the children of Controller are created by this driver.\r
2770 If this parameter is not NULL and the first Device Path Node is\r
2771 not the End of Device Path Node, then only the Handle for the\r
2772 child device specified by the first Device Path Node of\r
2773 RemainingDevicePath is created by this driver.\r
2774 If the first Device Path Node of RemainingDevicePath is\r
2775 the End of Device Path Node, no child Handle is created by this\r
2776 driver.\r
2777\r
2778 @retval EFI_SUCCESS Opal management was enabled.\r
2779 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.\r
2780 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
2781 @retval Others The driver failed to start the device.\r
2782\r
2783**/\r
2784EFI_STATUS\r
2785EFIAPI\r
c411b485
MK
2786OpalEfiDriverBindingStart (\r
2787 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
112e584b 2788 IN EFI_HANDLE Controller,\r
c411b485 2789 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
112e584b
SZ
2790 )\r
2791{\r
c411b485
MK
2792 EFI_STATUS Status;\r
2793 EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
2794 OPAL_DRIVER_DEVICE *Dev;\r
2795 OPAL_DRIVER_DEVICE *Itr;\r
2796 BOOLEAN Result;\r
112e584b
SZ
2797\r
2798 Itr = mOpalDriver.DeviceList;\r
2799 while (Itr != NULL) {\r
2800 if (Controller == Itr->Handle) {\r
2801 return EFI_SUCCESS;\r
2802 }\r
c411b485 2803\r
112e584b
SZ
2804 Itr = Itr->Next;\r
2805 }\r
2806\r
2807 //\r
2808 // Create internal device for tracking. This allows all disks to be tracked\r
2809 // by same HII form\r
2810 //\r
c411b485 2811 Dev = (OPAL_DRIVER_DEVICE *)AllocateZeroPool (sizeof (OPAL_DRIVER_DEVICE));\r
112e584b
SZ
2812 if (Dev == NULL) {\r
2813 return EFI_OUT_OF_RESOURCES;\r
2814 }\r
c411b485 2815\r
112e584b
SZ
2816 Dev->Handle = Controller;\r
2817\r
2818 //\r
2819 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks\r
2820 //\r
c411b485
MK
2821 Status = gBS->OpenProtocol (\r
2822 Controller,\r
2823 &gEfiStorageSecurityCommandProtocolGuid,\r
2824 (VOID **)&Dev->Sscp,\r
2825 This->DriverBindingHandle,\r
2826 Controller,\r
2827 EFI_OPEN_PROTOCOL_BY_DRIVER\r
2828 );\r
2829 if (EFI_ERROR (Status)) {\r
2830 FreePool (Dev);\r
112e584b
SZ
2831 return Status;\r
2832 }\r
2833\r
2834 //\r
2835 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL\r
2836 // function APIs\r
2837 //\r
c411b485
MK
2838 Status = gBS->OpenProtocol (\r
2839 Controller,\r
2840 &gEfiBlockIoProtocolGuid,\r
2841 (VOID **)&BlkIo,\r
2842 This->DriverBindingHandle,\r
2843 Controller,\r
2844 EFI_OPEN_PROTOCOL_BY_DRIVER\r
2845 );\r
2846 if (EFI_ERROR (Status)) {\r
112e584b 2847 //\r
1a049513 2848 // Block_IO not supported on handle\r
112e584b 2849 //\r
c411b485 2850 if (Status == EFI_UNSUPPORTED) {\r
1a049513
CM
2851 BlkIo = NULL;\r
2852 } else {\r
2853 //\r
2854 // Close storage security that was opened\r
2855 //\r
c411b485
MK
2856 gBS->CloseProtocol (\r
2857 Controller,\r
2858 &gEfiStorageSecurityCommandProtocolGuid,\r
2859 This->DriverBindingHandle,\r
2860 Controller\r
2861 );\r
112e584b 2862\r
c411b485 2863 FreePool (Dev);\r
1a049513
CM
2864 return Status;\r
2865 }\r
112e584b
SZ
2866 }\r
2867\r
2868 //\r
2869 // Save mediaId\r
2870 //\r
c411b485 2871 if (BlkIo == NULL) {\r
1a049513
CM
2872 // If no Block IO present, use defined MediaId value.\r
2873 Dev->MediaId = 0x0;\r
2874 } else {\r
2875 Dev->MediaId = BlkIo->Media->MediaId;\r
112e584b 2876\r
c411b485
MK
2877 gBS->CloseProtocol (\r
2878 Controller,\r
2879 &gEfiBlockIoProtocolGuid,\r
2880 This->DriverBindingHandle,\r
2881 Controller\r
2882 );\r
1a049513 2883 }\r
112e584b
SZ
2884\r
2885 //\r
2886 // Acquire Ascii printable name of child, if not found, then ignore device\r
2887 //\r
2888 Result = OpalDriverGetDriverDeviceName (Dev);\r
2889 if (!Result) {\r
2890 goto Done;\r
2891 }\r
2892\r
2893 Status = OpalDiskInitialize (Dev);\r
2894 if (EFI_ERROR (Status)) {\r
2895 goto Done;\r
2896 }\r
2897\r
c411b485 2898 AddDeviceToTail (Dev);\r
112e584b
SZ
2899\r
2900 //\r
2901 // Check if device is locked and prompt for password.\r
2902 //\r
2903 OpalDriverRequestPassword (Dev, L"Unlock:");\r
2904\r
2905 //\r
2906 // Process OPAL request from last boot.\r
2907 //\r
2908 ProcessOpalRequest (Dev);\r
2909\r
2910 return EFI_SUCCESS;\r
2911\r
2912Done:\r
2913 //\r
2914 // free device, close protocols and exit\r
2915 //\r
c411b485
MK
2916 gBS->CloseProtocol (\r
2917 Controller,\r
2918 &gEfiStorageSecurityCommandProtocolGuid,\r
2919 This->DriverBindingHandle,\r
2920 Controller\r
2921 );\r
112e584b 2922\r
c411b485 2923 FreePool (Dev);\r
112e584b
SZ
2924\r
2925 return EFI_DEVICE_ERROR;\r
2926}\r
2927\r
2928/**\r
2929 Stop this driver on Controller.\r
2930\r
2931 @param This Protocol instance pointer.\r
2932 @param Controller Handle of device to stop driver on\r
2933 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
2934 children is zero stop the entire bus driver.\r
2935 @param ChildHandleBuffer List of Child Handles to Stop.\r
2936\r
2937 @retval EFI_SUCCESS This driver is removed Controller.\r
2938 @retval other This driver could not be removed from this device.\r
2939\r
2940**/\r
2941EFI_STATUS\r
2942EFIAPI\r
c411b485
MK
2943OpalEfiDriverBindingStop (\r
2944 EFI_DRIVER_BINDING_PROTOCOL *This,\r
2945 EFI_HANDLE Controller,\r
2946 UINTN NumberOfChildren,\r
2947 EFI_HANDLE *ChildHandleBuffer\r
112e584b
SZ
2948 )\r
2949{\r
c411b485 2950 OPAL_DRIVER_DEVICE *Itr;\r
112e584b
SZ
2951\r
2952 Itr = mOpalDriver.DeviceList;\r
2953\r
2954 //\r
2955 // does Controller match any of the devices we are managing for Opal\r
2956 //\r
2957 while (Itr != NULL) {\r
2958 if (Itr->Handle == Controller) {\r
2959 OpalDriverStopDevice (Itr);\r
2960 return EFI_SUCCESS;\r
2961 }\r
2962\r
2963 Itr = Itr->Next;\r
2964 }\r
2965\r
2966 return EFI_NOT_FOUND;\r
2967}\r
2968\r
112e584b
SZ
2969/**\r
2970 Unloads UEFI Driver. Very useful for debugging and testing.\r
2971\r
2972 @param ImageHandle Image Handle this driver.\r
2973\r
2974 @retval EFI_SUCCESS This function always complete successfully.\r
2975 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.\r
2976**/\r
2977EFI_STATUS\r
2978EFIAPI\r
2979OpalEfiDriverUnload (\r
c411b485 2980 IN EFI_HANDLE ImageHandle\r
112e584b
SZ
2981 )\r
2982{\r
c411b485
MK
2983 EFI_STATUS Status;\r
2984 OPAL_DRIVER_DEVICE *Itr;\r
112e584b
SZ
2985\r
2986 Status = EFI_SUCCESS;\r
2987\r
2988 if (ImageHandle != gImageHandle) {\r
2989 return (EFI_INVALID_PARAMETER);\r
2990 }\r
2991\r
2992 //\r
2993 // Uninstall any interface added to each device by us\r
2994 //\r
2995 while (mOpalDriver.DeviceList) {\r
2996 Itr = mOpalDriver.DeviceList;\r
2997 //\r
2998 // Remove OPAL_DRIVER_DEVICE from the list\r
2999 // it updates the controllerList pointer\r
3000 //\r
c411b485 3001 OpalDriverStopDevice (Itr);\r
112e584b
SZ
3002 }\r
3003\r
3004 //\r
3005 // Uninstall the HII capability\r
3006 //\r
c411b485 3007 Status = HiiUninstall ();\r
112e584b
SZ
3008\r
3009 return Status;\r
3010}\r