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 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.
21 Signal event for every protocol in protocol entry.
23 @param ProtEntry Protocol entry
27 CoreNotifyProtocolEntry (
28 IN PROTOCOL_ENTRY
*ProtEntry
31 PROTOCOL_NOTIFY
*ProtNotify
;
34 ASSERT_LOCKED (&gProtocolDatabaseLock
);
36 for (Link
=ProtEntry
->Notify
.ForwardLink
; Link
!= &ProtEntry
->Notify
; Link
=Link
->ForwardLink
) {
37 ProtNotify
= CR(Link
, PROTOCOL_NOTIFY
, Link
, PROTOCOL_NOTIFY_SIGNATURE
);
38 CoreSignalEvent (ProtNotify
->Event
);
45 Removes Protocol from the protocol list (but not the handle list).
47 @param Handle The handle to remove protocol on.
48 @param Protocol GUID of the protocol to be moved
49 @param Interface The interface of the protocol
51 @return Protocol Entry
55 CoreRemoveInterfaceFromProtocol (
57 IN EFI_GUID
*Protocol
,
61 PROTOCOL_INTERFACE
*Prot
;
62 PROTOCOL_NOTIFY
*ProtNotify
;
63 PROTOCOL_ENTRY
*ProtEntry
;
66 ASSERT_LOCKED (&gProtocolDatabaseLock
);
68 Prot
= CoreFindProtocolInterface (Handle
, Protocol
, Interface
);
71 ProtEntry
= Prot
->Protocol
;
74 // If there's a protocol notify location pointing to this entry, back it up one
76 for(Link
= ProtEntry
->Notify
.ForwardLink
; Link
!= &ProtEntry
->Notify
; Link
=Link
->ForwardLink
) {
77 ProtNotify
= CR(Link
, PROTOCOL_NOTIFY
, Link
, PROTOCOL_NOTIFY_SIGNATURE
);
79 if (ProtNotify
->Position
== &Prot
->ByProtocol
) {
80 ProtNotify
->Position
= Prot
->ByProtocol
.BackLink
;
85 // Remove the protocol interface entry
87 RemoveEntryList (&Prot
->ByProtocol
);
95 Add a new protocol notification record for the request protocol.
97 @param Protocol The requested protocol to add the notify
99 @param Event The event to signal
100 @param Registration Returns the registration record
102 @retval EFI_INVALID_PARAMETER Invalid parameter
103 @retval EFI_SUCCESS Successfully returned the registration record
109 CoreRegisterProtocolNotify (
110 IN EFI_GUID
*Protocol
,
112 OUT VOID
**Registration
115 PROTOCOL_ENTRY
*ProtEntry
;
116 PROTOCOL_NOTIFY
*ProtNotify
;
119 if ((Protocol
== NULL
) || (Event
== NULL
) || (Registration
== NULL
)) {
120 return EFI_INVALID_PARAMETER
;
123 CoreAcquireProtocolLock ();
128 // Get the protocol entry to add the notification too
131 ProtEntry
= CoreFindProtocolEntry (Protocol
, TRUE
);
132 if (ProtEntry
!= NULL
) {
135 // Allocate a new notification record
137 ProtNotify
= AllocatePool (sizeof(PROTOCOL_NOTIFY
));
138 if (ProtNotify
!= NULL
) {
139 ((IEVENT
*)Event
)->ExFlag
|= EVT_EXFLAG_EVENT_PROTOCOL_NOTIFICATION
;
140 ProtNotify
->Signature
= PROTOCOL_NOTIFY_SIGNATURE
;
141 ProtNotify
->Protocol
= ProtEntry
;
142 ProtNotify
->Event
= Event
;
144 // start at the begining
146 ProtNotify
->Position
= &ProtEntry
->Protocols
;
148 InsertTailList (&ProtEntry
->Notify
, &ProtNotify
->Link
);
152 CoreReleaseProtocolLock ();
155 // Done. If we have a protocol notify entry, then return it.
156 // Otherwise, we must have run out of resources trying to add one
159 Status
= EFI_OUT_OF_RESOURCES
;
160 if (ProtNotify
!= NULL
) {
161 *Registration
= ProtNotify
;
162 Status
= EFI_SUCCESS
;
170 Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.
172 @param UserHandle Handle on which the interface is to be
174 @param Protocol The numeric ID of the interface
175 @param OldInterface A pointer to the old interface
176 @param NewInterface A pointer to the new interface
178 @retval EFI_SUCCESS The protocol interface was installed
179 @retval EFI_NOT_FOUND The OldInterface on the handle was not found
180 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
185 CoreReinstallProtocolInterface (
186 IN EFI_HANDLE UserHandle
,
187 IN EFI_GUID
*Protocol
,
188 IN VOID
*OldInterface
,
189 IN VOID
*NewInterface
194 PROTOCOL_INTERFACE
*Prot
;
195 PROTOCOL_ENTRY
*ProtEntry
;
197 Status
= CoreValidateHandle (UserHandle
);
198 if (EFI_ERROR (Status
)) {
202 if (Protocol
== NULL
) {
203 return EFI_INVALID_PARAMETER
;
206 Handle
= (IHANDLE
*) UserHandle
;
209 // Lock the protocol database
211 CoreAcquireProtocolLock ();
214 // Check that Protocol exists on UserHandle, and Interface matches the interface in the database
216 Prot
= CoreFindProtocolInterface (UserHandle
, Protocol
, OldInterface
);
218 Status
= EFI_NOT_FOUND
;
223 // Attempt to disconnect all drivers that are using the protocol interface that is about to be reinstalled
225 Status
= CoreDisconnectControllersUsingProtocolInterface (
229 if (EFI_ERROR (Status
)) {
231 // One or more drivers refused to release, so return the error
237 // Remove the protocol interface from the protocol
239 Prot
= CoreRemoveInterfaceFromProtocol (Handle
, Protocol
, OldInterface
);
242 Status
= EFI_NOT_FOUND
;
246 ProtEntry
= Prot
->Protocol
;
249 // Update the interface on the protocol
251 Prot
->Interface
= NewInterface
;
254 // Add this protocol interface to the tail of the
257 InsertTailList (&ProtEntry
->Protocols
, &Prot
->ByProtocol
);
260 // Update the Key to show that the handle has been created/modified
262 gHandleDatabaseKey
++;
263 Handle
->Key
= gHandleDatabaseKey
;
266 // Release the lock and connect all drivers to UserHandle
268 CoreReleaseProtocolLock ();
270 // Return code is ignored on purpose.
272 CoreConnectController (
278 CoreAcquireProtocolLock ();
281 // Notify the notification list for this protocol
283 CoreNotifyProtocolEntry (ProtEntry
);
285 Status
= EFI_SUCCESS
;
288 CoreReleaseProtocolLock ();