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