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
);
39 Removes Protocol from the protocol list (but not the handle list).
41 @param Handle The handle to remove protocol on.
42 @param Protocol GUID of the protocol to be moved
43 @param Interface The interface of the protocol
45 @return Protocol Entry
49 CoreRemoveInterfaceFromProtocol (
51 IN EFI_GUID
*Protocol
,
55 PROTOCOL_INTERFACE
*Prot
;
56 PROTOCOL_NOTIFY
*ProtNotify
;
57 PROTOCOL_ENTRY
*ProtEntry
;
60 ASSERT_LOCKED (&gProtocolDatabaseLock
);
62 Prot
= CoreFindProtocolInterface (Handle
, Protocol
, Interface
);
65 ProtEntry
= Prot
->Protocol
;
68 // If there's a protocol notify location pointing to this entry, back it up one
70 for(Link
= ProtEntry
->Notify
.ForwardLink
; Link
!= &ProtEntry
->Notify
; Link
=Link
->ForwardLink
) {
71 ProtNotify
= CR(Link
, PROTOCOL_NOTIFY
, Link
, PROTOCOL_NOTIFY_SIGNATURE
);
73 if (ProtNotify
->Position
== &Prot
->ByProtocol
) {
74 ProtNotify
->Position
= Prot
->ByProtocol
.BackLink
;
79 // Remove the protocol interface entry
81 RemoveEntryList (&Prot
->ByProtocol
);
89 Add a new protocol notification record for the request protocol.
91 @param Protocol The requested protocol to add the notify
93 @param Event The event to signal
94 @param Registration Returns the registration record
96 @retval EFI_INVALID_PARAMETER Invalid parameter
97 @retval EFI_SUCCESS Successfully returned the registration record
103 CoreRegisterProtocolNotify (
104 IN EFI_GUID
*Protocol
,
106 OUT VOID
**Registration
109 PROTOCOL_ENTRY
*ProtEntry
;
110 PROTOCOL_NOTIFY
*ProtNotify
;
113 if ((Protocol
== NULL
) || (Event
== NULL
) || (Registration
== NULL
)) {
114 return EFI_INVALID_PARAMETER
;
117 CoreAcquireProtocolLock ();
122 // Get the protocol entry to add the notification too
125 ProtEntry
= CoreFindProtocolEntry (Protocol
, TRUE
);
126 if (ProtEntry
!= NULL
) {
129 // Allocate a new notification record
131 ProtNotify
= AllocatePool (sizeof(PROTOCOL_NOTIFY
));
132 if (ProtNotify
!= NULL
) {
133 ((IEVENT
*)Event
)->ExFlag
|= EVT_EXFLAG_EVENT_PROTOCOL_NOTIFICATION
;
134 ProtNotify
->Signature
= PROTOCOL_NOTIFY_SIGNATURE
;
135 ProtNotify
->Protocol
= ProtEntry
;
136 ProtNotify
->Event
= Event
;
138 // start at the begining
140 ProtNotify
->Position
= &ProtEntry
->Protocols
;
142 InsertTailList (&ProtEntry
->Notify
, &ProtNotify
->Link
);
146 CoreReleaseProtocolLock ();
149 // Done. If we have a protocol notify entry, then return it.
150 // Otherwise, we must have run out of resources trying to add one
153 Status
= EFI_OUT_OF_RESOURCES
;
154 if (ProtNotify
!= NULL
) {
155 *Registration
= ProtNotify
;
156 Status
= EFI_SUCCESS
;
164 Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.
166 @param UserHandle Handle on which the interface is to be
168 @param Protocol The numeric ID of the interface
169 @param OldInterface A pointer to the old interface
170 @param NewInterface A pointer to the new interface
172 @retval EFI_SUCCESS The protocol interface was installed
173 @retval EFI_NOT_FOUND The OldInterface on the handle was not found
174 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
179 CoreReinstallProtocolInterface (
180 IN EFI_HANDLE UserHandle
,
181 IN EFI_GUID
*Protocol
,
182 IN VOID
*OldInterface
,
183 IN VOID
*NewInterface
188 PROTOCOL_INTERFACE
*Prot
;
189 PROTOCOL_ENTRY
*ProtEntry
;
191 Status
= CoreValidateHandle (UserHandle
);
192 if (EFI_ERROR (Status
)) {
196 if (Protocol
== NULL
) {
197 return EFI_INVALID_PARAMETER
;
200 Handle
= (IHANDLE
*) UserHandle
;
203 // Lock the protocol database
205 CoreAcquireProtocolLock ();
208 // Check that Protocol exists on UserHandle, and Interface matches the interface in the database
210 Prot
= CoreFindProtocolInterface (UserHandle
, Protocol
, OldInterface
);
212 Status
= EFI_NOT_FOUND
;
217 // Attempt to disconnect all drivers that are using the protocol interface that is about to be reinstalled
219 Status
= CoreDisconnectControllersUsingProtocolInterface (
223 if (EFI_ERROR (Status
)) {
225 // One or more drivers refused to release, so return the error
231 // Remove the protocol interface from the protocol
233 Prot
= CoreRemoveInterfaceFromProtocol (Handle
, Protocol
, OldInterface
);
236 Status
= EFI_NOT_FOUND
;
240 ProtEntry
= Prot
->Protocol
;
243 // Update the interface on the protocol
245 Prot
->Interface
= NewInterface
;
248 // Add this protocol interface to the tail of the
251 InsertTailList (&ProtEntry
->Protocols
, &Prot
->ByProtocol
);
254 // Update the Key to show that the handle has been created/modified
256 gHandleDatabaseKey
++;
257 Handle
->Key
= gHandleDatabaseKey
;
260 // Release the lock and connect all drivers to UserHandle
262 CoreReleaseProtocolLock ();
264 // Return code is ignored on purpose.
266 CoreConnectController (
272 CoreAcquireProtocolLock ();
275 // Notify the notification list for this protocol
277 CoreNotifyProtocolEntry (ProtEntry
);
279 Status
= EFI_SUCCESS
;
282 CoreReleaseProtocolLock ();