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);
243 ZeroMem (Unicode
, sizeof (Unicode
));
249 Check if disk is locked, show popup window and ask for password if it is
251 @param[in] Dev The device which need to be unlock.
255 OpalDriverRequestPassword (
256 OPAL_DRIVER_DEVICE
*Dev
265 OPAL_SESSION Session
;
275 IsEnabled
= OpalFeatureEnabled (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
277 ZeroMem(&Session
, sizeof(Session
));
278 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
279 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
280 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
282 Locked
= OpalDeviceLocked (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
284 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
285 Password
= OpalDriverPopUpHddPassword (Dev
, &PressEsc
);
289 // Current device in the lock status and
290 // User not input password and press ESC,
291 // keep device in lock status and continue boot.
295 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
297 L
"Press ENTER to skip password, Press ESC to input password",
300 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
302 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
303 gST
->ConOut
->ClearScreen(gST
->ConOut
);
305 // Keep lock and continue boot.
310 // Let user input password again.
316 // Current device in the unlock status and
317 // User not input password and press ESC,
318 // Shutdown the device.
322 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
324 L
"Press ENTER to shutdown, Press ESC to input password",
327 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
329 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
330 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
333 // Let user input password again.
340 if (Password
== NULL
) {
344 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
347 Ret
= OpalSupportUnlock(&Session
, Password
, PasswordLen
, Dev
->OpalDevicePath
);
349 Ret
= OpalSupportLock(&Session
, Password
, PasswordLen
, Dev
->OpalDevicePath
);
350 if (Ret
== TcgResultSuccess
) {
351 Ret
= OpalSupportUnlock(&Session
, Password
, PasswordLen
, Dev
->OpalDevicePath
);
355 if (Password
!= NULL
) {
356 ZeroMem (Password
, PasswordLen
);
360 if (Ret
== TcgResultSuccess
) {
368 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
370 L
"Invalid password.",
371 L
"Press ENTER to retry",
374 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
377 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
380 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
382 L
"Opal password retry count exceeds the limit. Must shutdown!",
383 L
"Press ENTER to shutdown",
386 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
388 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
394 Get devcie list info.
396 @retval return the device list pointer.
399 OpalDriverGetDeviceList(
403 return mOpalDriver
.DeviceList
;
407 ReadyToBoot callback to send BlockSid command.
409 @param Event Pointer to this event
410 @param Context Event handler private Data
415 ReadyToBootCallback (
421 OPAL_DRIVER_DEVICE
* Itr
;
423 OPAL_EXTRA_INFO_VAR OpalExtraInfo
;
425 OPAL_SESSION Session
;
427 gBS
->CloseEvent (Event
);
429 DataSize
= sizeof (OPAL_EXTRA_INFO_VAR
);
430 Status
= gRT
->GetVariable (
431 OPAL_EXTRA_INFO_VAR_NAME
,
432 &gOpalExtraInfoVariableGuid
,
437 if (EFI_ERROR (Status
)) {
441 if (OpalExtraInfo
.EnableBlockSid
== TRUE
) {
443 // Send BlockSID command to each Opal disk
445 Itr
= mOpalDriver
.DeviceList
;
446 while (Itr
!= NULL
) {
447 if (Itr
->OpalDisk
.SupportedAttributes
.BlockSid
) {
448 ZeroMem(&Session
, sizeof(Session
));
449 Session
.Sscp
= Itr
->OpalDisk
.Sscp
;
450 Session
.MediaId
= Itr
->OpalDisk
.MediaId
;
451 Session
.OpalBaseComId
= Itr
->OpalDisk
.OpalBaseComId
;
453 Result
= OpalBlockSid (&Session
, TRUE
); // HardwareReset must always be TRUE
454 if (Result
!= TcgResultSuccess
) {
455 DEBUG ((DEBUG_ERROR
, "OpalBlockSid fail\n"));
466 Stop this Controller.
468 @param Dev The device need to be stopped.
472 OpalDriverStopDevice (
473 OPAL_DRIVER_DEVICE
*Dev
479 FreePool(Dev
->Name16
);
482 // remove OPAL_DRIVER_DEVICE from the list
483 // it updates the controllerList pointer
488 // close protocols that were opened
492 &gEfiStorageSecurityCommandProtocolGuid
,
493 gOpalDriverBinding
.DriverBindingHandle
,
499 &gEfiBlockIoProtocolGuid
,
500 gOpalDriverBinding
.DriverBindingHandle
,
508 Get devcie name through the component name protocol.
510 @param[in] AllHandlesBuffer The handle buffer for current system.
511 @param[in] NumAllHandles The number of handles for the handle buffer.
512 @param[in] Dev The device which need to get name.
513 @param[in] UseComp1 Whether use component name or name2 protocol.
515 @retval TRUE Find the name for this device.
516 @retval FALSE Not found the name for this device.
519 OpalDriverGetDeviceNameByProtocol(
520 EFI_HANDLE
*AllHandlesBuffer
,
522 OPAL_DRIVER_DEVICE
*Dev
,
526 EFI_HANDLE
* ProtocolHandlesBuffer
;
527 UINTN NumProtocolHandles
;
529 EFI_COMPONENT_NAME2_PROTOCOL
* Cnp1_2
; // efi component name and componentName2 have same layout
532 EFI_DEVICE_PATH_PROTOCOL
* TmpDevPath
;
535 EFI_HANDLE TmpHandle
;
538 if (Dev
== NULL
|| AllHandlesBuffer
== NULL
|| NumAllHandles
== 0) {
542 Protocol
= UseComp1
? gEfiComponentNameProtocolGuid
: gEfiComponentName2ProtocolGuid
;
545 // Find all EFI_HANDLES with protocol
547 Status
= gBS
->LocateHandleBuffer(
552 &ProtocolHandlesBuffer
554 if (EFI_ERROR(Status
)) {
560 // Exit early if no supported devices
562 if (NumProtocolHandles
== 0) {
567 // Get printable name by iterating through all protocols
568 // using the handle as the child, and iterate through all handles for the controller
569 // exit loop early once found, if not found, then delete device
570 // storage security protocol instances already exist, add them to internal list
572 Status
= EFI_DEVICE_ERROR
;
573 for (Index1
= 0; Index1
< NumProtocolHandles
; Index1
++) {
576 if (Dev
->Name16
!= NULL
) {
580 TmpHandle
= ProtocolHandlesBuffer
[Index1
];
582 Status
= gBS
->OpenProtocol(
588 EFI_OPEN_PROTOCOL_GET_PROTOCOL
590 if (EFI_ERROR(Status
) || Cnp1_2
== NULL
) {
595 // Use all handles array as controller handle
597 for (Index2
= 0; Index2
< NumAllHandles
; Index2
++) {
598 Status
= Cnp1_2
->GetControllerName(
600 AllHandlesBuffer
[Index2
],
602 LANGUAGE_ISO_639_2_ENGLISH
,
605 if (EFI_ERROR(Status
)) {
606 Status
= Cnp1_2
->GetControllerName(
608 AllHandlesBuffer
[Index2
],
610 LANGUAGE_RFC_3066_ENGLISH
,
614 if (!EFI_ERROR(Status
) && DevName
!= NULL
) {
615 StrLength
= StrLen(DevName
) + 1; // Add one for NULL terminator
616 Dev
->Name16
= AllocateZeroPool(StrLength
* sizeof (CHAR16
));
617 ASSERT (Dev
->Name16
!= NULL
);
618 StrCpyS (Dev
->Name16
, StrLength
, DevName
);
619 Dev
->NameZ
= (CHAR8
*)AllocateZeroPool(StrLength
);
620 UnicodeStrToAsciiStrS (DevName
, Dev
->NameZ
, StrLength
);
623 // Retrieve bridge BDF info and port number or namespace depending on type
626 Status
= gBS
->OpenProtocol(
628 &gEfiDevicePathProtocolGuid
,
632 EFI_OPEN_PROTOCOL_GET_PROTOCOL
634 if (!EFI_ERROR(Status
)) {
635 Dev
->OpalDevicePath
= DuplicateDevicePath (TmpDevPath
);
639 if (Dev
->Name16
!= NULL
) {
640 FreePool(Dev
->Name16
);
643 if (Dev
->NameZ
!= NULL
) {
644 FreePool(Dev
->NameZ
);
655 Get devcie name through the component name protocol.
657 @param[in] Dev The device which need to get name.
659 @retval TRUE Find the name for this device.
660 @retval FALSE Not found the name for this device.
663 OpalDriverGetDriverDeviceName(
664 OPAL_DRIVER_DEVICE
*Dev
667 EFI_HANDLE
* AllHandlesBuffer
;
672 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
677 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
679 if (Dev
->Name16
== NULL
) {
680 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "Name is null, update it\n"));
682 // Find all EFI_HANDLES
684 Status
= gBS
->LocateHandleBuffer(
691 if (EFI_ERROR(Status
)) {
692 DEBUG ((DEBUG_INFO
, "LocateHandleBuffer for AllHandles failed %r\n", Status
));
697 // Try component Name2
699 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, FALSE
)) {
700 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName2 failed to get device name, try ComponentName\n"));
701 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, TRUE
)) {
702 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName failed to get device name, skip device\n"));
712 Main entry for this driver.
714 @param ImageHandle Image Handle this driver.
715 @param SystemTable Pointer to SystemTable.
717 @retval EFI_SUCESS This function always complete successfully.
722 IN EFI_HANDLE ImageHandle
,
723 IN EFI_SYSTEM_TABLE
* SystemTable
727 EFI_EVENT ReadyToBootEvent
;
729 Status
= EfiLibInstallDriverBindingComponentName2 (
738 if (EFI_ERROR(Status
)) {
739 DEBUG((DEBUG_ERROR
, "Install protocols to Opal driver Handle failed\n"));
744 // Initialize Driver object
746 ZeroMem(&mOpalDriver
, sizeof(mOpalDriver
));
747 mOpalDriver
.Handle
= ImageHandle
;
750 // register a ReadyToBoot event callback for sending BlockSid command
752 Status
= EfiCreateEventReadyToBootEx (
755 (VOID
*) &ImageHandle
,
760 // Install Hii packages.
768 Tests to see if this driver supports a given controller.
770 This function checks to see if the controller contains an instance of the
771 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL
772 and returns EFI_SUCCESS if it does.
774 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
775 @param[in] ControllerHandle The Handle of the controller to test. This Handle
776 must support a protocol interface that supplies
777 an I/O abstraction to the driver.
778 @param[in] RemainingDevicePath This parameter is ignored.
780 @retval EFI_SUCCESS The device contains required protocols
781 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
782 RemainingDevicePath is already being managed by the driver
784 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
785 RemainingDevicePath is already being managed by a different
786 driver or an application that requires exclusive access.
787 Currently not implemented.
788 @retval EFI_UNSUPPORTED The device does not contain requires protocols
793 OpalEfiDriverBindingSupported(
794 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
795 IN EFI_HANDLE Controller
,
796 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
800 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
* SecurityCommand
;
801 EFI_BLOCK_IO_PROTOCOL
* BlkIo
;
804 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
806 Status
= gBS
->OpenProtocol(
808 &gEfiStorageSecurityCommandProtocolGuid
,
809 ( VOID
** )&SecurityCommand
,
810 This
->DriverBindingHandle
,
812 EFI_OPEN_PROTOCOL_BY_DRIVER
815 if (Status
== EFI_ALREADY_STARTED
) {
819 if (EFI_ERROR(Status
)) {
824 // Close protocol and reopen in Start call
828 &gEfiStorageSecurityCommandProtocolGuid
,
829 This
->DriverBindingHandle
,
834 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
837 Status
= gBS
->OpenProtocol(
839 &gEfiBlockIoProtocolGuid
,
841 This
->DriverBindingHandle
,
843 EFI_OPEN_PROTOCOL_BY_DRIVER
846 if (EFI_ERROR(Status
)) {
847 DEBUG((DEBUG_INFO
, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));
852 // Close protocol and reopen in Start call
856 &gEfiBlockIoProtocolGuid
,
857 This
->DriverBindingHandle
,
865 Enables Opal Management on a supported device if available.
867 The start function is designed to be called after the Opal UEFI Driver has confirmed the
868 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
869 This function will complete the other necessary checks, such as verifying the device supports
870 the correct version of Opal. Upon verification, it will add the device to the
871 Opal HII list in order to expose Opal managmeent options.
873 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
874 @param[in] ControllerHandle The Handle of the controller to start. This Handle
875 must support a protocol interface that supplies
876 an I/O abstraction to the driver.
877 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
878 parameter is ignored by device drivers, and is optional for bus
879 drivers. For a bus driver, if this parameter is NULL, then handles
880 for all the children of Controller are created by this driver.
881 If this parameter is not NULL and the first Device Path Node is
882 not the End of Device Path Node, then only the Handle for the
883 child device specified by the first Device Path Node of
884 RemainingDevicePath is created by this driver.
885 If the first Device Path Node of RemainingDevicePath is
886 the End of Device Path Node, no child Handle is created by this
889 @retval EFI_SUCCESS Opal management was enabled.
890 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
891 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
892 @retval Others The driver failed to start the device.
897 OpalEfiDriverBindingStart(
898 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
899 IN EFI_HANDLE Controller
,
900 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
904 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
905 OPAL_DRIVER_DEVICE
*Dev
;
906 OPAL_DRIVER_DEVICE
*Itr
;
909 Itr
= mOpalDriver
.DeviceList
;
910 while (Itr
!= NULL
) {
911 if (Controller
== Itr
->Handle
) {
918 // Create internal device for tracking. This allows all disks to be tracked
921 Dev
= (OPAL_DRIVER_DEVICE
*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE
));
923 return EFI_OUT_OF_RESOURCES
;
925 Dev
->Handle
= Controller
;
928 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
930 Status
= gBS
->OpenProtocol(
932 &gEfiStorageSecurityCommandProtocolGuid
,
934 This
->DriverBindingHandle
,
936 EFI_OPEN_PROTOCOL_BY_DRIVER
938 if (EFI_ERROR(Status
)) {
944 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
947 Status
= gBS
->OpenProtocol(
949 &gEfiBlockIoProtocolGuid
,
951 This
->DriverBindingHandle
,
953 EFI_OPEN_PROTOCOL_BY_DRIVER
955 if (EFI_ERROR(Status
)) {
957 // Close storage security that was opened
961 &gEfiStorageSecurityCommandProtocolGuid
,
962 This
->DriverBindingHandle
,
973 Dev
->MediaId
= BlkIo
->Media
->MediaId
;
977 &gEfiBlockIoProtocolGuid
,
978 This
->DriverBindingHandle
,
983 // Acquire Ascii printable name of child, if not found, then ignore device
985 Result
= OpalDriverGetDriverDeviceName (Dev
);
990 Status
= OpalDiskInitialize (Dev
);
991 if (EFI_ERROR (Status
)) {
995 AddDeviceToTail(Dev
);
998 // check if device is locked and prompt for password
1000 OpalDriverRequestPassword (Dev
);
1006 // free device, close protocols and exit
1010 &gEfiStorageSecurityCommandProtocolGuid
,
1011 This
->DriverBindingHandle
,
1017 return EFI_DEVICE_ERROR
;
1021 Stop this driver on Controller.
1023 @param This Protocol instance pointer.
1024 @param Controller Handle of device to stop driver on
1025 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1026 children is zero stop the entire bus driver.
1027 @param ChildHandleBuffer List of Child Handles to Stop.
1029 @retval EFI_SUCCESS This driver is removed Controller.
1030 @retval other This driver could not be removed from this device.
1035 OpalEfiDriverBindingStop(
1036 EFI_DRIVER_BINDING_PROTOCOL
* This
,
1037 EFI_HANDLE Controller
,
1038 UINTN NumberOfChildren
,
1039 EFI_HANDLE
* ChildHandleBuffer
1042 OPAL_DRIVER_DEVICE
* Itr
;
1044 Itr
= mOpalDriver
.DeviceList
;
1047 // does Controller match any of the devices we are managing for Opal
1049 while (Itr
!= NULL
) {
1050 if (Itr
->Handle
== Controller
) {
1051 OpalDriverStopDevice (Itr
);
1058 return EFI_NOT_FOUND
;
1063 Unloads UEFI Driver. Very useful for debugging and testing.
1065 @param ImageHandle Image Handle this driver.
1067 @retval EFI_SUCCESS This function always complete successfully.
1068 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
1072 OpalEfiDriverUnload (
1073 IN EFI_HANDLE ImageHandle
1077 OPAL_DRIVER_DEVICE
*Itr
;
1079 Status
= EFI_SUCCESS
;
1081 if (ImageHandle
!= gImageHandle
) {
1082 return (EFI_INVALID_PARAMETER
);
1086 // Uninstall any interface added to each device by us
1088 while (mOpalDriver
.DeviceList
) {
1089 Itr
= mOpalDriver
.DeviceList
;
1091 // Remove OPAL_DRIVER_DEVICE from the list
1092 // it updates the controllerList pointer
1094 OpalDriverStopDevice(Itr
);
1098 // Uninstall the HII capability
1100 Status
= HiiUninstall();