2 Support functions for UEFI protocol notification infrastructure.
4 Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
15 Signal event for every protocol in protocol entry.
17 @param ProtEntry Protocol entry
21 CoreNotifyProtocolEntry (
22 IN PROTOCOL_ENTRY
*ProtEntry
25 PROTOCOL_NOTIFY
*ProtNotify
;
28 ASSERT_LOCKED (&gProtocolDatabaseLock
);
30 for (Link
= ProtEntry
->Notify
.ForwardLink
; Link
!= &ProtEntry
->Notify
; Link
= Link
->ForwardLink
) {
31 ProtNotify
= CR (Link
, PROTOCOL_NOTIFY
, Link
, PROTOCOL_NOTIFY_SIGNATURE
);
32 CoreSignalEvent (ProtNotify
->Event
);
37 Removes Protocol from the protocol list (but not the handle list).
39 @param Handle The handle to remove protocol on.
40 @param Protocol GUID of the protocol to be moved
41 @param Interface The interface of the protocol
43 @return Protocol Entry
47 CoreRemoveInterfaceFromProtocol (
49 IN EFI_GUID
*Protocol
,
53 PROTOCOL_INTERFACE
*Prot
;
54 PROTOCOL_NOTIFY
*ProtNotify
;
55 PROTOCOL_ENTRY
*ProtEntry
;
58 ASSERT_LOCKED (&gProtocolDatabaseLock
);
60 Prot
= CoreFindProtocolInterface (Handle
, Protocol
, Interface
);
62 ProtEntry
= Prot
->Protocol
;
65 // If there's a protocol notify location pointing to this entry, back it up one
67 for (Link
= ProtEntry
->Notify
.ForwardLink
; Link
!= &ProtEntry
->Notify
; Link
= Link
->ForwardLink
) {
68 ProtNotify
= CR (Link
, PROTOCOL_NOTIFY
, Link
, PROTOCOL_NOTIFY_SIGNATURE
);
70 if (ProtNotify
->Position
== &Prot
->ByProtocol
) {
71 ProtNotify
->Position
= Prot
->ByProtocol
.BackLink
;
76 // Remove the protocol interface entry
78 RemoveEntryList (&Prot
->ByProtocol
);
85 Add a new protocol notification record for the request protocol.
87 @param Protocol The requested protocol to add the notify
89 @param Event The event to signal
90 @param Registration Returns the registration record
92 @retval EFI_INVALID_PARAMETER Invalid parameter
93 @retval EFI_SUCCESS Successfully returned the registration record
99 CoreRegisterProtocolNotify (
100 IN EFI_GUID
*Protocol
,
102 OUT VOID
**Registration
105 PROTOCOL_ENTRY
*ProtEntry
;
106 PROTOCOL_NOTIFY
*ProtNotify
;
109 if ((Protocol
== NULL
) || (Event
== NULL
) || (Registration
== NULL
)) {
110 return EFI_INVALID_PARAMETER
;
113 CoreAcquireProtocolLock ();
118 // Get the protocol entry to add the notification too
121 ProtEntry
= CoreFindProtocolEntry (Protocol
, TRUE
);
122 if (ProtEntry
!= NULL
) {
124 // Allocate a new notification record
126 ProtNotify
= AllocatePool (sizeof (PROTOCOL_NOTIFY
));
127 if (ProtNotify
!= NULL
) {
128 ((IEVENT
*)Event
)->ExFlag
|= EVT_EXFLAG_EVENT_PROTOCOL_NOTIFICATION
;
129 ProtNotify
->Signature
= PROTOCOL_NOTIFY_SIGNATURE
;
130 ProtNotify
->Protocol
= ProtEntry
;
131 ProtNotify
->Event
= Event
;
133 // start at the begining
135 ProtNotify
->Position
= &ProtEntry
->Protocols
;
137 InsertTailList (&ProtEntry
->Notify
, &ProtNotify
->Link
);
141 CoreReleaseProtocolLock ();
144 // Done. If we have a protocol notify entry, then return it.
145 // Otherwise, we must have run out of resources trying to add one
148 Status
= EFI_OUT_OF_RESOURCES
;
149 if (ProtNotify
!= NULL
) {
150 *Registration
= ProtNotify
;
151 Status
= EFI_SUCCESS
;
158 Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.
160 @param UserHandle Handle on which the interface is to be
162 @param Protocol The numeric ID of the interface
163 @param OldInterface A pointer to the old interface
164 @param NewInterface A pointer to the new interface
166 @retval EFI_SUCCESS The protocol interface was installed
167 @retval EFI_NOT_FOUND The OldInterface on the handle was not found
168 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
173 CoreReinstallProtocolInterface (
174 IN EFI_HANDLE UserHandle
,
175 IN EFI_GUID
*Protocol
,
176 IN VOID
*OldInterface
,
177 IN VOID
*NewInterface
182 PROTOCOL_INTERFACE
*Prot
;
183 PROTOCOL_ENTRY
*ProtEntry
;
185 if (Protocol
== NULL
) {
186 return EFI_INVALID_PARAMETER
;
190 // Lock the protocol database
192 CoreAcquireProtocolLock ();
194 Status
= CoreValidateHandle (UserHandle
);
195 if (EFI_ERROR (Status
)) {
199 Handle
= (IHANDLE
*)UserHandle
;
201 // Check that Protocol exists on UserHandle, and Interface matches the interface in the database
203 Prot
= CoreFindProtocolInterface (UserHandle
, Protocol
, OldInterface
);
205 Status
= EFI_NOT_FOUND
;
210 // Attempt to disconnect all drivers that are using the protocol interface that is about to be reinstalled
212 Status
= CoreDisconnectControllersUsingProtocolInterface (
216 if (EFI_ERROR (Status
)) {
218 // One or more drivers refused to release, so return the error
224 // Remove the protocol interface from the protocol
226 Prot
= CoreRemoveInterfaceFromProtocol (Handle
, Protocol
, OldInterface
);
229 Status
= EFI_NOT_FOUND
;
233 ProtEntry
= Prot
->Protocol
;
236 // Update the interface on the protocol
238 Prot
->Interface
= NewInterface
;
241 // Add this protocol interface to the tail of the
244 InsertTailList (&ProtEntry
->Protocols
, &Prot
->ByProtocol
);
247 // Update the Key to show that the handle has been created/modified
249 gHandleDatabaseKey
++;
250 Handle
->Key
= gHandleDatabaseKey
;
253 // Release the lock and connect all drivers to UserHandle
255 CoreReleaseProtocolLock ();
257 // Return code is ignored on purpose.
259 CoreConnectController (
265 CoreAcquireProtocolLock ();
268 // Notify the notification list for this protocol
270 CoreNotifyProtocolEntry (ProtEntry
);
272 Status
= EFI_SUCCESS
;
275 CoreReleaseProtocolLock ();