2 Support functions for UEFI protocol notification infrastructure.
4 Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 Signal event for every protocol in protocol entry.
22 @param ProtEntry Protocol entry
26 CoreNotifyProtocolEntry (
27 IN PROTOCOL_ENTRY
*ProtEntry
30 PROTOCOL_NOTIFY
*ProtNotify
;
33 ASSERT_LOCKED (&gProtocolDatabaseLock
);
35 for (Link
=ProtEntry
->Notify
.ForwardLink
; Link
!= &ProtEntry
->Notify
; Link
=Link
->ForwardLink
) {
36 ProtNotify
= CR(Link
, PROTOCOL_NOTIFY
, Link
, PROTOCOL_NOTIFY_SIGNATURE
);
37 CoreSignalEvent (ProtNotify
->Event
);
44 Removes Protocol from the protocol list (but not the handle list).
46 @param Handle The handle to remove protocol on.
47 @param Protocol GUID of the protocol to be moved
48 @param Interface The interface of the protocol
50 @return Protocol Entry
54 CoreRemoveInterfaceFromProtocol (
56 IN EFI_GUID
*Protocol
,
60 PROTOCOL_INTERFACE
*Prot
;
61 PROTOCOL_NOTIFY
*ProtNotify
;
62 PROTOCOL_ENTRY
*ProtEntry
;
65 ASSERT_LOCKED (&gProtocolDatabaseLock
);
67 Prot
= CoreFindProtocolInterface (Handle
, Protocol
, Interface
);
70 ProtEntry
= Prot
->Protocol
;
73 // If there's a protocol notify location pointing to this entry, back it up one
75 for(Link
= ProtEntry
->Notify
.ForwardLink
; Link
!= &ProtEntry
->Notify
; Link
=Link
->ForwardLink
) {
76 ProtNotify
= CR(Link
, PROTOCOL_NOTIFY
, Link
, PROTOCOL_NOTIFY_SIGNATURE
);
78 if (ProtNotify
->Position
== &Prot
->ByProtocol
) {
79 ProtNotify
->Position
= Prot
->ByProtocol
.BackLink
;
84 // Remove the protocol interface entry
86 RemoveEntryList (&Prot
->ByProtocol
);
94 Add a new protocol notification record for the request protocol.
96 @param Protocol The requested protocol to add the notify
98 @param Event The event to signal
99 @param Registration Returns the registration record
101 @retval EFI_INVALID_PARAMETER Invalid parameter
102 @retval EFI_SUCCESS Successfully returned the registration record
108 CoreRegisterProtocolNotify (
109 IN EFI_GUID
*Protocol
,
111 OUT VOID
**Registration
114 PROTOCOL_ENTRY
*ProtEntry
;
115 PROTOCOL_NOTIFY
*ProtNotify
;
118 if ((Protocol
== NULL
) || (Event
== NULL
) || (Registration
== NULL
)) {
119 return EFI_INVALID_PARAMETER
;
122 CoreAcquireProtocolLock ();
127 // Get the protocol entry to add the notification too
130 ProtEntry
= CoreFindProtocolEntry (Protocol
, TRUE
);
131 if (ProtEntry
!= NULL
) {
134 // Allocate a new notification record
136 ProtNotify
= AllocatePool (sizeof(PROTOCOL_NOTIFY
));
137 if (ProtNotify
!= NULL
) {
139 ProtNotify
->Signature
= PROTOCOL_NOTIFY_SIGNATURE
;
140 ProtNotify
->Protocol
= ProtEntry
;
141 ProtNotify
->Event
= Event
;
143 // start at the begining
145 ProtNotify
->Position
= &ProtEntry
->Protocols
;
147 InsertTailList (&ProtEntry
->Notify
, &ProtNotify
->Link
);
151 CoreReleaseProtocolLock ();
154 // Done. If we have a protocol notify entry, then return it.
155 // Otherwise, we must have run out of resources trying to add one
158 Status
= EFI_OUT_OF_RESOURCES
;
159 if (ProtNotify
!= NULL
) {
160 *Registration
= ProtNotify
;
161 Status
= EFI_SUCCESS
;
169 Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.
171 @param UserHandle Handle on which the interface is to be
173 @param Protocol The numeric ID of the interface
174 @param OldInterface A pointer to the old interface
175 @param NewInterface A pointer to the new interface
177 @retval EFI_SUCCESS The protocol interface was installed
178 @retval EFI_NOT_FOUND The OldInterface on the handle was not found
179 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
184 CoreReinstallProtocolInterface (
185 IN EFI_HANDLE UserHandle
,
186 IN EFI_GUID
*Protocol
,
187 IN VOID
*OldInterface
,
188 IN VOID
*NewInterface
193 PROTOCOL_INTERFACE
*Prot
;
194 PROTOCOL_ENTRY
*ProtEntry
;
196 Status
= CoreValidateHandle (UserHandle
);
197 if (EFI_ERROR (Status
)) {
201 if (Protocol
== NULL
) {
202 return EFI_INVALID_PARAMETER
;
205 Handle
= (IHANDLE
*) UserHandle
;
208 // Lock the protocol database
210 CoreAcquireProtocolLock ();
213 // Check that Protocol exists on UserHandle, and Interface matches the interface in the database
215 Prot
= CoreFindProtocolInterface (UserHandle
, Protocol
, OldInterface
);
217 Status
= EFI_NOT_FOUND
;
222 // Attempt to disconnect all drivers that are using the protocol interface that is about to be reinstalled
224 Status
= CoreDisconnectControllersUsingProtocolInterface (
228 if (EFI_ERROR (Status
)) {
230 // One or more drivers refused to release, so return the error
236 // Remove the protocol interface from the protocol
238 Prot
= CoreRemoveInterfaceFromProtocol (Handle
, Protocol
, OldInterface
);
241 Status
= EFI_NOT_FOUND
;
245 ProtEntry
= Prot
->Protocol
;
248 // Update the interface on the protocol
250 Prot
->Interface
= NewInterface
;
253 // Add this protocol interface to the tail of the
256 InsertTailList (&ProtEntry
->Protocols
, &Prot
->ByProtocol
);
259 // Update the Key to show that the handle has been created/modified
261 gHandleDatabaseKey
++;
262 Handle
->Key
= gHandleDatabaseKey
;
265 // Release the lock and connect all drivers to UserHandle
267 CoreReleaseProtocolLock ();
269 // Return code is ignored on purpose.
271 CoreConnectController (
277 CoreAcquireProtocolLock ();
280 // Notify the notification list for this protocol
282 CoreNotifyProtocolEntry (ProtEntry
);
284 Status
= EFI_SUCCESS
;
287 CoreReleaseProtocolLock ();