2 Entrypoint of Opal UEFI Driver and contains all the logic to
3 register for new Opal device instances.
5 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 // This UEFI driver consumes EFI_STORAGE_SECURITY_PROTOCOL instances and installs an
17 // HII GUI to manage Opal features if the device is Opal capable
18 // If the Opal device is being managed by the UEFI Driver, it shall provide a popup
19 // window during boot requesting a user password
21 #include "OpalDriver.h"
22 #include "OpalDriverPrivate.h"
25 OPAL_DRIVER mOpalDriver
;
27 #define MAX_PASSWORD_SIZE 32
28 #define MAX_PASSWORD_TRY_COUNT 5
33 EFI_DRIVER_BINDING_PROTOCOL gOpalDriverBinding
= {
34 OpalEfiDriverBindingSupported
,
35 OpalEfiDriverBindingStart
,
36 OpalEfiDriverBindingStop
,
44 Add new device to the global device list.
46 @param Dev New create device.
51 IN OPAL_DRIVER_DEVICE
*Dev
54 OPAL_DRIVER_DEVICE
*TmpDev
;
56 if (mOpalDriver
.DeviceList
== NULL
) {
57 mOpalDriver
.DeviceList
= Dev
;
59 TmpDev
= mOpalDriver
.DeviceList
;
60 while (TmpDev
->Next
!= NULL
) {
61 TmpDev
= TmpDev
->Next
;
69 Remove one device in the global device list.
71 @param Dev The device need to be removed.
76 IN OPAL_DRIVER_DEVICE
*Dev
79 OPAL_DRIVER_DEVICE
*TmpDev
;
81 if (mOpalDriver
.DeviceList
== NULL
) {
85 if (mOpalDriver
.DeviceList
== Dev
) {
86 mOpalDriver
.DeviceList
= NULL
;
90 TmpDev
= mOpalDriver
.DeviceList
;
91 while (TmpDev
->Next
!= NULL
) {
92 if (TmpDev
->Next
== Dev
) {
93 TmpDev
->Next
= Dev
->Next
;
100 Get current device count.
102 @retval return the current created device count.
111 OPAL_DRIVER_DEVICE
*TmpDev
;
114 TmpDev
= mOpalDriver
.DeviceList
;
116 while (TmpDev
!= NULL
) {
118 TmpDev
= TmpDev
->Next
;
125 Get password input from the popup windows, and unlock the device.
127 @param[in] Dev The device which need to be unlock.
128 @param[out] PressEsc Whether user escape function through Press ESC.
130 @retval Password string if success. NULL if failed.
134 OpalDriverPopUpHddPassword (
135 IN OPAL_DRIVER_DEVICE
*Dev
,
136 OUT BOOLEAN
*PressEsc
139 EFI_INPUT_KEY InputKey
;
141 CHAR16 Mask
[MAX_PASSWORD_SIZE
+ 1];
142 CHAR16 Unicode
[MAX_PASSWORD_SIZE
+ 1];
147 ZeroMem(Unicode
, sizeof(Unicode
));
148 ZeroMem(Mask
, sizeof(Mask
));
150 StrLength
= StrLen(Dev
->Name16
);
151 PopUpString
= (CHAR16
*) AllocateZeroPool ((8 + StrLength
) * 2);
154 if (Dev
->Name16
== NULL
) {
155 UnicodeSPrint(PopUpString
, StrLen(L
"Unlock Disk") + 1, L
"Unlock Disk");
157 UnicodeSPrint(PopUpString
, StrLen(L
"Unlock ") + StrLength
+ 1, L
"Unlock %s", Dev
->Name16
);
160 gST
->ConOut
->ClearScreen(gST
->ConOut
);
164 Mask
[InputLength
] = L
'_';
166 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
169 L
"---------------------",
177 if (InputKey
.ScanCode
== SCAN_NULL
) {
181 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
183 // Add the null terminator.
185 Unicode
[InputLength
] = 0;
188 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
189 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
190 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
195 // delete last key entered
197 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
198 if (InputLength
> 0) {
199 Unicode
[InputLength
] = 0;
200 Mask
[InputLength
] = 0;
205 // add Next key entry
207 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
208 Mask
[InputLength
] = L
'*';
210 if (InputLength
== MAX_PASSWORD_SIZE
) {
212 // Add the null terminator.
214 Unicode
[InputLength
] = 0;
215 Mask
[InputLength
] = 0;
225 if (InputKey
.ScanCode
== SCAN_ESC
) {
231 gST
->ConOut
->ClearScreen(gST
->ConOut
);
233 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
237 Ascii
= AllocateZeroPool (MAX_PASSWORD_SIZE
+ 1);
242 UnicodeStrToAsciiStr(Unicode
, Ascii
);
248 Check if disk is locked, show popup window and ask for password if it is
250 @param[in] Dev The device which need to be unlock.
254 OpalDriverRequestPassword (
255 OPAL_DRIVER_DEVICE
*Dev
264 OPAL_SESSION Session
;
273 IsEnabled
= OpalFeatureEnabled (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
275 ZeroMem(&Session
, sizeof(Session
));
276 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
277 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
278 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
280 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
281 Password
= OpalDriverPopUpHddPassword (Dev
, &PressEsc
);
284 // User not input password and press ESC, keep device in lock status and continue boot.
288 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
290 L
"Confirm: Not unlock device and continue boot?.",
291 L
"Press ENTER to confirm, Press Esc to input password",
294 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
296 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
297 gST
->ConOut
->ClearScreen(gST
->ConOut
);
299 // Keep lock and continue boot.
304 // Let user input password again.
310 if (Password
== NULL
) {
314 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
316 if (OpalDeviceLocked (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
)) {
317 Ret
= OpalSupportUnlock(&Session
, Password
, PasswordLen
, Dev
->OpalDevicePath
);
319 Ret
= OpalSupportLock(&Session
, Password
, PasswordLen
, Dev
->OpalDevicePath
);
320 if (Ret
== TcgResultSuccess
) {
321 Ret
= OpalSupportUnlock(&Session
, Password
, PasswordLen
, Dev
->OpalDevicePath
);
325 if (Password
!= NULL
) {
326 ZeroMem (Password
, PasswordLen
);
330 if (Ret
== TcgResultSuccess
) {
338 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
340 L
"Invalid password.",
341 L
"Press ENTER to retry",
344 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
347 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
350 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
352 L
"Opal password retry count is expired. Keep lock and continue boot.",
353 L
"Press ENTER to continue",
356 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
357 gST
->ConOut
->ClearScreen(gST
->ConOut
);
363 Get devcie list info.
365 @retval return the device list pointer.
368 OpalDriverGetDeviceList(
372 return mOpalDriver
.DeviceList
;
376 ReadyToBoot callback to send BlockSid command.
378 @param Event Pointer to this event
379 @param Context Event hanlder private Data
384 ReadyToBootCallback (
390 OPAL_DRIVER_DEVICE
* Itr
;
392 OPAL_EXTRA_INFO_VAR OpalExtraInfo
;
394 OPAL_SESSION Session
;
396 gBS
->CloseEvent (Event
);
398 DataSize
= sizeof (OPAL_EXTRA_INFO_VAR
);
399 Status
= gRT
->GetVariable (
400 OPAL_EXTRA_INFO_VAR_NAME
,
401 &gOpalExtraInfoVariableGuid
,
406 if (EFI_ERROR (Status
)) {
410 if (OpalExtraInfo
.EnableBlockSid
== TRUE
) {
412 // Send BlockSID command to each Opal disk
414 Itr
= mOpalDriver
.DeviceList
;
415 while (Itr
!= NULL
) {
416 if (Itr
->OpalDisk
.SupportedAttributes
.BlockSid
) {
417 ZeroMem(&Session
, sizeof(Session
));
418 Session
.Sscp
= Itr
->OpalDisk
.Sscp
;
419 Session
.MediaId
= Itr
->OpalDisk
.MediaId
;
420 Session
.OpalBaseComId
= Itr
->OpalDisk
.OpalBaseComId
;
422 Result
= OpalBlockSid (&Session
, TRUE
); // HardwareReset must always be TRUE
423 if (Result
!= TcgResultSuccess
) {
424 DEBUG ((DEBUG_ERROR
, "OpalBlockSid fail\n"));
435 Stop this Controller.
437 @param Dev The device need to be stopped.
441 OpalDriverStopDevice (
442 OPAL_DRIVER_DEVICE
*Dev
448 FreePool(Dev
->Name16
);
451 // remove OPAL_DRIVER_DEVICE from the list
452 // it updates the controllerList pointer
457 // close protocols that were opened
461 &gEfiStorageSecurityCommandProtocolGuid
,
462 gOpalDriverBinding
.DriverBindingHandle
,
468 &gEfiBlockIoProtocolGuid
,
469 gOpalDriverBinding
.DriverBindingHandle
,
477 Get devcie name through the component name protocol.
479 @param[in] AllHandlesBuffer The handle buffer for current system.
480 @param[in] NumAllHandles The number of handles for the handle buffer.
481 @param[in] Dev The device which need to get name.
482 @param[in] UseComp1 Whether use component name or name2 protocol.
484 @retval TRUE Find the name for this device.
485 @retval FALSE Not found the name for this device.
488 OpalDriverGetDeviceNameByProtocol(
489 EFI_HANDLE
*AllHandlesBuffer
,
491 OPAL_DRIVER_DEVICE
*Dev
,
495 EFI_HANDLE
* ProtocolHandlesBuffer
;
496 UINTN NumProtocolHandles
;
498 EFI_COMPONENT_NAME2_PROTOCOL
* Cnp1_2
; // efi component name and componentName2 have same layout
501 EFI_DEVICE_PATH_PROTOCOL
* TmpDevPath
;
504 EFI_HANDLE TmpHandle
;
507 if (Dev
== NULL
|| AllHandlesBuffer
== NULL
|| NumAllHandles
== 0) {
511 Protocol
= UseComp1
? gEfiComponentNameProtocolGuid
: gEfiComponentName2ProtocolGuid
;
514 // Find all EFI_HANDLES with protocol
516 Status
= gBS
->LocateHandleBuffer(
521 &ProtocolHandlesBuffer
523 if (EFI_ERROR(Status
)) {
529 // Exit early if no supported devices
531 if (NumProtocolHandles
== 0) {
536 // Get printable name by iterating through all protocols
537 // using the handle as the child, and iterate through all handles for the controller
538 // exit loop early once found, if not found, then delete device
539 // storage security protocol instances already exist, add them to internal list
541 Status
= EFI_DEVICE_ERROR
;
542 for (Index1
= 0; Index1
< NumProtocolHandles
; Index1
++) {
545 if (Dev
->Name16
!= NULL
) {
549 TmpHandle
= ProtocolHandlesBuffer
[Index1
];
551 Status
= gBS
->OpenProtocol(
557 EFI_OPEN_PROTOCOL_GET_PROTOCOL
559 if (EFI_ERROR(Status
) || Cnp1_2
== NULL
) {
564 // Use all handles array as controller handle
566 for (Index2
= 0; Index2
< NumAllHandles
; Index2
++) {
567 Status
= Cnp1_2
->GetControllerName(
569 AllHandlesBuffer
[Index2
],
571 LANGUAGE_ISO_639_2_ENGLISH
,
574 if (EFI_ERROR(Status
)) {
575 Status
= Cnp1_2
->GetControllerName(
577 AllHandlesBuffer
[Index2
],
579 LANGUAGE_RFC_3066_ENGLISH
,
583 if (!EFI_ERROR(Status
) && DevName
!= NULL
) {
584 StrLength
= StrLen(DevName
) + 1; // Add one for NULL terminator
585 Dev
->Name16
= AllocateZeroPool(StrLength
* sizeof (CHAR16
));
586 ASSERT (Dev
->Name16
!= NULL
);
587 StrCpyS (Dev
->Name16
, StrLength
, DevName
);
588 Dev
->NameZ
= (CHAR8
*)AllocateZeroPool(StrLength
);
589 UnicodeStrToAsciiStr(DevName
, Dev
->NameZ
);
592 // Retrieve bridge BDF info and port number or namespace depending on type
595 Status
= gBS
->OpenProtocol(
597 &gEfiDevicePathProtocolGuid
,
601 EFI_OPEN_PROTOCOL_GET_PROTOCOL
603 if (!EFI_ERROR(Status
)) {
604 Dev
->OpalDevicePath
= DuplicateDevicePath (TmpDevPath
);
608 if (Dev
->Name16
!= NULL
) {
609 FreePool(Dev
->Name16
);
612 if (Dev
->NameZ
!= NULL
) {
613 FreePool(Dev
->NameZ
);
624 Get devcie name through the component name protocol.
626 @param[in] Dev The device which need to get name.
628 @retval TRUE Find the name for this device.
629 @retval FALSE Not found the name for this device.
632 OpalDriverGetDriverDeviceName(
633 OPAL_DRIVER_DEVICE
*Dev
636 EFI_HANDLE
* AllHandlesBuffer
;
641 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
646 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
648 if (Dev
->Name16
== NULL
) {
649 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "Name is null, update it\n"));
651 // Find all EFI_HANDLES
653 Status
= gBS
->LocateHandleBuffer(
660 if (EFI_ERROR(Status
)) {
661 DEBUG ((DEBUG_INFO
, "LocateHandleBuffer for AllHandles failed %r\n", Status
));
666 // Try component Name2
668 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, FALSE
)) {
669 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName2 failed to get device name, try ComponentName\n"));
670 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, TRUE
)) {
671 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName failed to get device name, skip device\n"));
681 Main entry for this driver.
683 @param ImageHandle Image Handle this driver.
684 @param SystemTable Pointer to SystemTable.
686 @retval EFI_SUCESS This function always complete successfully.
691 IN EFI_HANDLE ImageHandle
,
692 IN EFI_SYSTEM_TABLE
* SystemTable
696 EFI_EVENT ReadyToBootEvent
;
698 Status
= EfiLibInstallDriverBindingComponentName2 (
707 if (EFI_ERROR(Status
)) {
708 DEBUG((DEBUG_ERROR
, "Install protocols to Opal driver Handle failed\n"));
713 // Initialize Driver object
715 ZeroMem(&mOpalDriver
, sizeof(mOpalDriver
));
716 mOpalDriver
.Handle
= ImageHandle
;
719 // register a ReadyToBoot event callback for sending BlockSid command
721 Status
= EfiCreateEventReadyToBootEx (
724 (VOID
*) &ImageHandle
,
729 // Install Hii packages.
737 Tests to see if this driver supports a given controller.
739 This function checks to see if the controller contains an instance of the
740 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL
741 and returns EFI_SUCCESS if it does.
743 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
744 @param[in] ControllerHandle The Handle of the controller to test. This Handle
745 must support a protocol interface that supplies
746 an I/O abstraction to the driver.
747 @param[in] RemainingDevicePath This parameter is ignored.
749 @retval EFI_SUCCESS The device contains required protocols
750 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
751 RemainingDevicePath is already being managed by the driver
753 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
754 RemainingDevicePath is already being managed by a different
755 driver or an application that requires exclusive access.
756 Currently not implemented.
757 @retval EFI_UNSUPPORTED The device does not contain requires protocols
762 OpalEfiDriverBindingSupported(
763 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
764 IN EFI_HANDLE Controller
,
765 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
769 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
* SecurityCommand
;
770 EFI_BLOCK_IO_PROTOCOL
* BlkIo
;
773 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
775 Status
= gBS
->OpenProtocol(
777 &gEfiStorageSecurityCommandProtocolGuid
,
778 ( VOID
** )&SecurityCommand
,
779 This
->DriverBindingHandle
,
781 EFI_OPEN_PROTOCOL_BY_DRIVER
784 if (Status
== EFI_ALREADY_STARTED
) {
788 if (EFI_ERROR(Status
)) {
793 // Close protocol and reopen in Start call
797 &gEfiStorageSecurityCommandProtocolGuid
,
798 This
->DriverBindingHandle
,
803 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
806 Status
= gBS
->OpenProtocol(
808 &gEfiBlockIoProtocolGuid
,
810 This
->DriverBindingHandle
,
812 EFI_OPEN_PROTOCOL_BY_DRIVER
815 if (EFI_ERROR(Status
)) {
816 DEBUG((DEBUG_INFO
, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));
821 // Close protocol and reopen in Start call
825 &gEfiBlockIoProtocolGuid
,
826 This
->DriverBindingHandle
,
834 Enables Opal Management on a supported device if available.
836 The start function is designed to be called after the Opal UEFI Driver has confirmed the
837 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
838 This function will complete the other necessary checks, such as verifying the device supports
839 the correct version of Opal. Upon verification, it will add the device to the
840 Opal HII list in order to expose Opal managmeent options.
842 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
843 @param[in] ControllerHandle The Handle of the controller to start. This Handle
844 must support a protocol interface that supplies
845 an I/O abstraction to the driver.
846 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
847 parameter is ignored by device drivers, and is optional for bus
848 drivers. For a bus driver, if this parameter is NULL, then handles
849 for all the children of Controller are created by this driver.
850 If this parameter is not NULL and the first Device Path Node is
851 not the End of Device Path Node, then only the Handle for the
852 child device specified by the first Device Path Node of
853 RemainingDevicePath is created by this driver.
854 If the first Device Path Node of RemainingDevicePath is
855 the End of Device Path Node, no child Handle is created by this
858 @retval EFI_SUCCESS Opal management was enabled.
859 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
860 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
861 @retval Others The driver failed to start the device.
866 OpalEfiDriverBindingStart(
867 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
868 IN EFI_HANDLE Controller
,
869 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
873 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
874 OPAL_DRIVER_DEVICE
*Dev
;
875 OPAL_DRIVER_DEVICE
*Itr
;
878 Itr
= mOpalDriver
.DeviceList
;
879 while (Itr
!= NULL
) {
880 if (Controller
== Itr
->Handle
) {
887 // Create internal device for tracking. This allows all disks to be tracked
890 Dev
= (OPAL_DRIVER_DEVICE
*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE
));
892 return EFI_OUT_OF_RESOURCES
;
894 Dev
->Handle
= Controller
;
897 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
899 Status
= gBS
->OpenProtocol(
901 &gEfiStorageSecurityCommandProtocolGuid
,
903 This
->DriverBindingHandle
,
905 EFI_OPEN_PROTOCOL_BY_DRIVER
907 if (EFI_ERROR(Status
)) {
913 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
916 Status
= gBS
->OpenProtocol(
918 &gEfiBlockIoProtocolGuid
,
920 This
->DriverBindingHandle
,
922 EFI_OPEN_PROTOCOL_BY_DRIVER
924 if (EFI_ERROR(Status
)) {
926 // Close storage security that was opened
930 &gEfiStorageSecurityCommandProtocolGuid
,
931 This
->DriverBindingHandle
,
942 Dev
->MediaId
= BlkIo
->Media
->MediaId
;
946 &gEfiBlockIoProtocolGuid
,
947 This
->DriverBindingHandle
,
952 // Acquire Ascii printable name of child, if not found, then ignore device
954 Result
= OpalDriverGetDriverDeviceName (Dev
);
959 Status
= OpalDiskInitialize (Dev
);
960 if (EFI_ERROR (Status
)) {
964 AddDeviceToTail(Dev
);
967 // check if device is locked and prompt for password
969 OpalDriverRequestPassword (Dev
);
975 // free device, close protocols and exit
979 &gEfiStorageSecurityCommandProtocolGuid
,
980 This
->DriverBindingHandle
,
986 return EFI_DEVICE_ERROR
;
990 Stop this driver on Controller.
992 @param This Protocol instance pointer.
993 @param Controller Handle of device to stop driver on
994 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
995 children is zero stop the entire bus driver.
996 @param ChildHandleBuffer List of Child Handles to Stop.
998 @retval EFI_SUCCESS This driver is removed Controller.
999 @retval other This driver could not be removed from this device.
1004 OpalEfiDriverBindingStop(
1005 EFI_DRIVER_BINDING_PROTOCOL
* This
,
1006 EFI_HANDLE Controller
,
1007 UINTN NumberOfChildren
,
1008 EFI_HANDLE
* ChildHandleBuffer
1011 OPAL_DRIVER_DEVICE
* Itr
;
1013 Itr
= mOpalDriver
.DeviceList
;
1016 // does Controller match any of the devices we are managing for Opal
1018 while (Itr
!= NULL
) {
1019 if (Itr
->Handle
== Controller
) {
1020 OpalDriverStopDevice (Itr
);
1027 return EFI_NOT_FOUND
;
1032 Unloads UEFI Driver. Very useful for debugging and testing.
1034 @param ImageHandle Image Handle this driver.
1036 @retval EFI_SUCCESS This function always complete successfully.
1037 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
1041 OpalEfiDriverUnload (
1042 IN EFI_HANDLE ImageHandle
1046 OPAL_DRIVER_DEVICE
*Itr
;
1048 Status
= EFI_SUCCESS
;
1050 if (ImageHandle
!= gImageHandle
) {
1051 return (EFI_INVALID_PARAMETER
);
1055 // Uninstall any interface added to each device by us
1057 while (mOpalDriver
.DeviceList
) {
1058 Itr
= mOpalDriver
.DeviceList
;
1060 // Remove OPAL_DRIVER_DEVICE from the list
1061 // it updates the controllerList pointer
1063 OpalDriverStopDevice(Itr
);
1067 // Uninstall the HII capability
1069 Status
= HiiUninstall();