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 UnicodeStrToAsciiStrS (Unicode
, Ascii
, MAX_PASSWORD_SIZE
+ 1);
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
;
274 IsEnabled
= OpalFeatureEnabled (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
276 ZeroMem(&Session
, sizeof(Session
));
277 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
278 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
279 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
281 Locked
= OpalDeviceLocked (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
283 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
284 Password
= OpalDriverPopUpHddPassword (Dev
, &PressEsc
);
288 // Current device in the lock status and
289 // User not input password and press ESC,
290 // keep device in lock status and continue boot.
294 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
296 L
"Press ENTER to skip password, Press ESC to input password",
299 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
301 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
302 gST
->ConOut
->ClearScreen(gST
->ConOut
);
304 // Keep lock and continue boot.
309 // Let user input password again.
315 // Current device in the unlock status and
316 // User not input password and press ESC,
317 // Shutdown the device.
321 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
323 L
"Press ENTER to shutdown, Press ESC to input password",
326 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
328 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
329 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
332 // Let user input password again.
339 if (Password
== NULL
) {
343 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
346 Ret
= OpalSupportUnlock(&Session
, Password
, PasswordLen
, Dev
->OpalDevicePath
);
348 Ret
= OpalSupportLock(&Session
, Password
, PasswordLen
, Dev
->OpalDevicePath
);
349 if (Ret
== TcgResultSuccess
) {
350 Ret
= OpalSupportUnlock(&Session
, Password
, PasswordLen
, Dev
->OpalDevicePath
);
354 if (Password
!= NULL
) {
355 ZeroMem (Password
, PasswordLen
);
359 if (Ret
== TcgResultSuccess
) {
367 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
369 L
"Invalid password.",
370 L
"Press ENTER to retry",
373 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
376 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
379 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
381 L
"Opal password retry count exceeds the limit. Must shutdown!",
382 L
"Press ENTER to shutdown",
385 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
387 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
393 Get devcie list info.
395 @retval return the device list pointer.
398 OpalDriverGetDeviceList(
402 return mOpalDriver
.DeviceList
;
406 ReadyToBoot callback to send BlockSid command.
408 @param Event Pointer to this event
409 @param Context Event handler private Data
414 ReadyToBootCallback (
419 OPAL_DRIVER_DEVICE
*Itr
;
421 OPAL_SESSION Session
;
422 UINT32 PpStorageFlag
;
424 gBS
->CloseEvent (Event
);
426 PpStorageFlag
= TcgPhysicalPresenceStorageLibReturnStorageFlags();
427 if ((PpStorageFlag
& TCG_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID
) != 0) {
429 // Send BlockSID command to each Opal disk
431 Itr
= mOpalDriver
.DeviceList
;
432 while (Itr
!= NULL
) {
433 if (Itr
->OpalDisk
.SupportedAttributes
.BlockSid
) {
434 ZeroMem(&Session
, sizeof(Session
));
435 Session
.Sscp
= Itr
->OpalDisk
.Sscp
;
436 Session
.MediaId
= Itr
->OpalDisk
.MediaId
;
437 Session
.OpalBaseComId
= Itr
->OpalDisk
.OpalBaseComId
;
439 Result
= OpalBlockSid (&Session
, TRUE
); // HardwareReset must always be TRUE
440 if (Result
!= TcgResultSuccess
) {
441 DEBUG ((DEBUG_ERROR
, "OpalBlockSid fail\n"));
452 Stop this Controller.
454 @param Dev The device need to be stopped.
458 OpalDriverStopDevice (
459 OPAL_DRIVER_DEVICE
*Dev
465 FreePool(Dev
->Name16
);
468 // remove OPAL_DRIVER_DEVICE from the list
469 // it updates the controllerList pointer
474 // close protocols that were opened
478 &gEfiStorageSecurityCommandProtocolGuid
,
479 gOpalDriverBinding
.DriverBindingHandle
,
485 &gEfiBlockIoProtocolGuid
,
486 gOpalDriverBinding
.DriverBindingHandle
,
494 Get devcie name through the component name protocol.
496 @param[in] AllHandlesBuffer The handle buffer for current system.
497 @param[in] NumAllHandles The number of handles for the handle buffer.
498 @param[in] Dev The device which need to get name.
499 @param[in] UseComp1 Whether use component name or name2 protocol.
501 @retval TRUE Find the name for this device.
502 @retval FALSE Not found the name for this device.
505 OpalDriverGetDeviceNameByProtocol(
506 EFI_HANDLE
*AllHandlesBuffer
,
508 OPAL_DRIVER_DEVICE
*Dev
,
512 EFI_HANDLE
* ProtocolHandlesBuffer
;
513 UINTN NumProtocolHandles
;
515 EFI_COMPONENT_NAME2_PROTOCOL
* Cnp1_2
; // efi component name and componentName2 have same layout
518 EFI_DEVICE_PATH_PROTOCOL
* TmpDevPath
;
521 EFI_HANDLE TmpHandle
;
524 if (Dev
== NULL
|| AllHandlesBuffer
== NULL
|| NumAllHandles
== 0) {
528 Protocol
= UseComp1
? gEfiComponentNameProtocolGuid
: gEfiComponentName2ProtocolGuid
;
531 // Find all EFI_HANDLES with protocol
533 Status
= gBS
->LocateHandleBuffer(
538 &ProtocolHandlesBuffer
540 if (EFI_ERROR(Status
)) {
546 // Exit early if no supported devices
548 if (NumProtocolHandles
== 0) {
553 // Get printable name by iterating through all protocols
554 // using the handle as the child, and iterate through all handles for the controller
555 // exit loop early once found, if not found, then delete device
556 // storage security protocol instances already exist, add them to internal list
558 Status
= EFI_DEVICE_ERROR
;
559 for (Index1
= 0; Index1
< NumProtocolHandles
; Index1
++) {
562 if (Dev
->Name16
!= NULL
) {
566 TmpHandle
= ProtocolHandlesBuffer
[Index1
];
568 Status
= gBS
->OpenProtocol(
574 EFI_OPEN_PROTOCOL_GET_PROTOCOL
576 if (EFI_ERROR(Status
) || Cnp1_2
== NULL
) {
581 // Use all handles array as controller handle
583 for (Index2
= 0; Index2
< NumAllHandles
; Index2
++) {
584 Status
= Cnp1_2
->GetControllerName(
586 AllHandlesBuffer
[Index2
],
588 LANGUAGE_ISO_639_2_ENGLISH
,
591 if (EFI_ERROR(Status
)) {
592 Status
= Cnp1_2
->GetControllerName(
594 AllHandlesBuffer
[Index2
],
596 LANGUAGE_RFC_3066_ENGLISH
,
600 if (!EFI_ERROR(Status
) && DevName
!= NULL
) {
601 StrLength
= StrLen(DevName
) + 1; // Add one for NULL terminator
602 Dev
->Name16
= AllocateZeroPool(StrLength
* sizeof (CHAR16
));
603 ASSERT (Dev
->Name16
!= NULL
);
604 StrCpyS (Dev
->Name16
, StrLength
, DevName
);
605 Dev
->NameZ
= (CHAR8
*)AllocateZeroPool(StrLength
);
606 UnicodeStrToAsciiStrS (DevName
, Dev
->NameZ
, StrLength
);
609 // Retrieve bridge BDF info and port number or namespace depending on type
612 Status
= gBS
->OpenProtocol(
614 &gEfiDevicePathProtocolGuid
,
618 EFI_OPEN_PROTOCOL_GET_PROTOCOL
620 if (!EFI_ERROR(Status
)) {
621 Dev
->OpalDevicePath
= DuplicateDevicePath (TmpDevPath
);
625 if (Dev
->Name16
!= NULL
) {
626 FreePool(Dev
->Name16
);
629 if (Dev
->NameZ
!= NULL
) {
630 FreePool(Dev
->NameZ
);
641 Get devcie name through the component name protocol.
643 @param[in] Dev The device which need to get name.
645 @retval TRUE Find the name for this device.
646 @retval FALSE Not found the name for this device.
649 OpalDriverGetDriverDeviceName(
650 OPAL_DRIVER_DEVICE
*Dev
653 EFI_HANDLE
* AllHandlesBuffer
;
658 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
663 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
665 if (Dev
->Name16
== NULL
) {
666 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "Name is null, update it\n"));
668 // Find all EFI_HANDLES
670 Status
= gBS
->LocateHandleBuffer(
677 if (EFI_ERROR(Status
)) {
678 DEBUG ((DEBUG_INFO
, "LocateHandleBuffer for AllHandles failed %r\n", Status
));
683 // Try component Name2
685 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, FALSE
)) {
686 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName2 failed to get device name, try ComponentName\n"));
687 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, TRUE
)) {
688 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName failed to get device name, skip device\n"));
698 Main entry for this driver.
700 @param ImageHandle Image Handle this driver.
701 @param SystemTable Pointer to SystemTable.
703 @retval EFI_SUCESS This function always complete successfully.
708 IN EFI_HANDLE ImageHandle
,
709 IN EFI_SYSTEM_TABLE
* SystemTable
713 EFI_EVENT ReadyToBootEvent
;
715 Status
= EfiLibInstallDriverBindingComponentName2 (
724 if (EFI_ERROR(Status
)) {
725 DEBUG((DEBUG_ERROR
, "Install protocols to Opal driver Handle failed\n"));
730 // Initialize Driver object
732 ZeroMem(&mOpalDriver
, sizeof(mOpalDriver
));
733 mOpalDriver
.Handle
= ImageHandle
;
736 // register a ReadyToBoot event callback for sending BlockSid command
738 Status
= EfiCreateEventReadyToBootEx (
741 (VOID
*) &ImageHandle
,
746 // Install Hii packages.
754 Tests to see if this driver supports a given controller.
756 This function checks to see if the controller contains an instance of the
757 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL
758 and returns EFI_SUCCESS if it does.
760 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
761 @param[in] ControllerHandle The Handle of the controller to test. This Handle
762 must support a protocol interface that supplies
763 an I/O abstraction to the driver.
764 @param[in] RemainingDevicePath This parameter is ignored.
766 @retval EFI_SUCCESS The device contains required protocols
767 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
768 RemainingDevicePath is already being managed by the driver
770 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
771 RemainingDevicePath is already being managed by a different
772 driver or an application that requires exclusive access.
773 Currently not implemented.
774 @retval EFI_UNSUPPORTED The device does not contain requires protocols
779 OpalEfiDriverBindingSupported(
780 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
781 IN EFI_HANDLE Controller
,
782 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
786 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
* SecurityCommand
;
787 EFI_BLOCK_IO_PROTOCOL
* BlkIo
;
790 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
792 Status
= gBS
->OpenProtocol(
794 &gEfiStorageSecurityCommandProtocolGuid
,
795 ( VOID
** )&SecurityCommand
,
796 This
->DriverBindingHandle
,
798 EFI_OPEN_PROTOCOL_BY_DRIVER
801 if (Status
== EFI_ALREADY_STARTED
) {
805 if (EFI_ERROR(Status
)) {
810 // Close protocol and reopen in Start call
814 &gEfiStorageSecurityCommandProtocolGuid
,
815 This
->DriverBindingHandle
,
820 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
823 Status
= gBS
->OpenProtocol(
825 &gEfiBlockIoProtocolGuid
,
827 This
->DriverBindingHandle
,
829 EFI_OPEN_PROTOCOL_BY_DRIVER
832 if (EFI_ERROR(Status
)) {
833 DEBUG((DEBUG_INFO
, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));
838 // Close protocol and reopen in Start call
842 &gEfiBlockIoProtocolGuid
,
843 This
->DriverBindingHandle
,
851 Enables Opal Management on a supported device if available.
853 The start function is designed to be called after the Opal UEFI Driver has confirmed the
854 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
855 This function will complete the other necessary checks, such as verifying the device supports
856 the correct version of Opal. Upon verification, it will add the device to the
857 Opal HII list in order to expose Opal managmeent options.
859 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
860 @param[in] ControllerHandle The Handle of the controller to start. This Handle
861 must support a protocol interface that supplies
862 an I/O abstraction to the driver.
863 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
864 parameter is ignored by device drivers, and is optional for bus
865 drivers. For a bus driver, if this parameter is NULL, then handles
866 for all the children of Controller are created by this driver.
867 If this parameter is not NULL and the first Device Path Node is
868 not the End of Device Path Node, then only the Handle for the
869 child device specified by the first Device Path Node of
870 RemainingDevicePath is created by this driver.
871 If the first Device Path Node of RemainingDevicePath is
872 the End of Device Path Node, no child Handle is created by this
875 @retval EFI_SUCCESS Opal management was enabled.
876 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
877 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
878 @retval Others The driver failed to start the device.
883 OpalEfiDriverBindingStart(
884 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
885 IN EFI_HANDLE Controller
,
886 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
890 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
891 OPAL_DRIVER_DEVICE
*Dev
;
892 OPAL_DRIVER_DEVICE
*Itr
;
895 Itr
= mOpalDriver
.DeviceList
;
896 while (Itr
!= NULL
) {
897 if (Controller
== Itr
->Handle
) {
904 // Create internal device for tracking. This allows all disks to be tracked
907 Dev
= (OPAL_DRIVER_DEVICE
*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE
));
909 return EFI_OUT_OF_RESOURCES
;
911 Dev
->Handle
= Controller
;
914 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
916 Status
= gBS
->OpenProtocol(
918 &gEfiStorageSecurityCommandProtocolGuid
,
920 This
->DriverBindingHandle
,
922 EFI_OPEN_PROTOCOL_BY_DRIVER
924 if (EFI_ERROR(Status
)) {
930 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
933 Status
= gBS
->OpenProtocol(
935 &gEfiBlockIoProtocolGuid
,
937 This
->DriverBindingHandle
,
939 EFI_OPEN_PROTOCOL_BY_DRIVER
941 if (EFI_ERROR(Status
)) {
943 // Close storage security that was opened
947 &gEfiStorageSecurityCommandProtocolGuid
,
948 This
->DriverBindingHandle
,
959 Dev
->MediaId
= BlkIo
->Media
->MediaId
;
963 &gEfiBlockIoProtocolGuid
,
964 This
->DriverBindingHandle
,
969 // Acquire Ascii printable name of child, if not found, then ignore device
971 Result
= OpalDriverGetDriverDeviceName (Dev
);
976 Status
= OpalDiskInitialize (Dev
);
977 if (EFI_ERROR (Status
)) {
981 AddDeviceToTail(Dev
);
984 // check if device is locked and prompt for password
986 OpalDriverRequestPassword (Dev
);
992 // free device, close protocols and exit
996 &gEfiStorageSecurityCommandProtocolGuid
,
997 This
->DriverBindingHandle
,
1003 return EFI_DEVICE_ERROR
;
1007 Stop this driver on Controller.
1009 @param This Protocol instance pointer.
1010 @param Controller Handle of device to stop driver on
1011 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1012 children is zero stop the entire bus driver.
1013 @param ChildHandleBuffer List of Child Handles to Stop.
1015 @retval EFI_SUCCESS This driver is removed Controller.
1016 @retval other This driver could not be removed from this device.
1021 OpalEfiDriverBindingStop(
1022 EFI_DRIVER_BINDING_PROTOCOL
* This
,
1023 EFI_HANDLE Controller
,
1024 UINTN NumberOfChildren
,
1025 EFI_HANDLE
* ChildHandleBuffer
1028 OPAL_DRIVER_DEVICE
* Itr
;
1030 Itr
= mOpalDriver
.DeviceList
;
1033 // does Controller match any of the devices we are managing for Opal
1035 while (Itr
!= NULL
) {
1036 if (Itr
->Handle
== Controller
) {
1037 OpalDriverStopDevice (Itr
);
1044 return EFI_NOT_FOUND
;
1049 Unloads UEFI Driver. Very useful for debugging and testing.
1051 @param ImageHandle Image Handle this driver.
1053 @retval EFI_SUCCESS This function always complete successfully.
1054 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
1058 OpalEfiDriverUnload (
1059 IN EFI_HANDLE ImageHandle
1063 OPAL_DRIVER_DEVICE
*Itr
;
1065 Status
= EFI_SUCCESS
;
1067 if (ImageHandle
!= gImageHandle
) {
1068 return (EFI_INVALID_PARAMETER
);
1072 // Uninstall any interface added to each device by us
1074 while (mOpalDriver
.DeviceList
) {
1075 Itr
= mOpalDriver
.DeviceList
;
1077 // Remove OPAL_DRIVER_DEVICE from the list
1078 // it updates the controllerList pointer
1080 OpalDriverStopDevice(Itr
);
1084 // Uninstall the HII capability
1086 Status
= HiiUninstall();