2 UEFI notify infrastructure
4 Copyright (c) 2006 - 2008, Intel Corporation. <BR>
5 All rights reserved. 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.
19 Signal event for every protocol in protocol entry.
21 @param ProtEntry Protocol entry
25 CoreNotifyProtocolEntry (
26 IN PROTOCOL_ENTRY
*ProtEntry
29 PROTOCOL_NOTIFY
*ProtNotify
;
32 ASSERT_LOCKED (&gProtocolDatabaseLock
);
34 for (Link
=ProtEntry
->Notify
.ForwardLink
; Link
!= &ProtEntry
->Notify
; Link
=Link
->ForwardLink
) {
35 ProtNotify
= CR(Link
, PROTOCOL_NOTIFY
, Link
, PROTOCOL_NOTIFY_SIGNATURE
);
36 CoreSignalEvent (ProtNotify
->Event
);
43 Removes Protocol from the protocol list (but not the handle list).
45 @param Handle The handle to remove protocol on.
46 @param Protocol GUID of the protocol to be moved
47 @param Interface The interface of the protocol
49 @return Protocol Entry
53 CoreRemoveInterfaceFromProtocol (
55 IN EFI_GUID
*Protocol
,
59 PROTOCOL_INTERFACE
*Prot
;
60 PROTOCOL_NOTIFY
*ProtNotify
;
61 PROTOCOL_ENTRY
*ProtEntry
;
64 ASSERT_LOCKED (&gProtocolDatabaseLock
);
66 Prot
= CoreFindProtocolInterface (Handle
, Protocol
, Interface
);
69 ProtEntry
= Prot
->Protocol
;
72 // 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
87 RemoveEntryList (&Prot
->ByProtocol
);
97 Add a new protocol notification record for the request protocol.
99 @param Protocol The requested protocol to add the notify
101 @param Event The event to signal
102 @param Registration Returns the registration record
104 @retval EFI_INVALID_PARAMETER Invalid parameter
105 @retval EFI_SUCCESS Successfully returned the registration record
111 CoreRegisterProtocolNotify (
112 IN EFI_GUID
*Protocol
,
114 OUT VOID
**Registration
117 PROTOCOL_ENTRY
*ProtEntry
;
118 PROTOCOL_NOTIFY
*ProtNotify
;
121 if ((Protocol
== NULL
) || (Event
== NULL
) || (Registration
== NULL
)) {
122 return EFI_INVALID_PARAMETER
;
125 CoreAcquireProtocolLock ();
130 // Get the protocol entry to add the notification too
133 ProtEntry
= CoreFindProtocolEntry (Protocol
, TRUE
);
134 if (ProtEntry
!= NULL
) {
137 // Allocate a new notification record
140 ProtNotify
= CoreAllocateBootServicesPool (sizeof(PROTOCOL_NOTIFY
));
142 if (ProtNotify
!= NULL
) {
144 ProtNotify
->Signature
= PROTOCOL_NOTIFY_SIGNATURE
;
145 ProtNotify
->Protocol
= ProtEntry
;
146 ProtNotify
->Event
= Event
;
148 // start at the begining
150 ProtNotify
->Position
= &ProtEntry
->Protocols
;
152 InsertTailList (&ProtEntry
->Notify
, &ProtNotify
->Link
);
156 CoreReleaseProtocolLock ();
159 // Done. If we have a protocol notify entry, then return it.
160 // Otherwise, we must have run out of resources trying to add one
163 Status
= EFI_OUT_OF_RESOURCES
;
164 if (ProtNotify
!= NULL
) {
165 *Registration
= ProtNotify
;
166 Status
= EFI_SUCCESS
;
176 Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.
178 @param UserHandle Handle on which the interface is to be
180 @param Protocol The numeric ID of the interface
181 @param OldInterface A pointer to the old interface
182 @param NewInterface A pointer to the new interface
184 @retval EFI_SUCCESS The protocol interface was installed
185 @retval EFI_NOT_FOUND The OldInterface on the handle was not found
186 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
191 CoreReinstallProtocolInterface (
192 IN EFI_HANDLE UserHandle
,
193 IN EFI_GUID
*Protocol
,
194 IN VOID
*OldInterface
,
195 IN VOID
*NewInterface
200 PROTOCOL_INTERFACE
*Prot
;
201 PROTOCOL_ENTRY
*ProtEntry
;
203 Status
= CoreValidateHandle (UserHandle
);
204 if (EFI_ERROR (Status
)) {
208 if (Protocol
== NULL
) {
209 return EFI_INVALID_PARAMETER
;
212 Handle
= (IHANDLE
*) UserHandle
;
215 // Lock the protocol database
217 CoreAcquireProtocolLock ();
220 // Check that Protocol exists on UserHandle, and Interface matches the interface in the database
222 Prot
= CoreFindProtocolInterface (UserHandle
, Protocol
, OldInterface
);
224 CoreReleaseProtocolLock ();
225 return EFI_NOT_FOUND
;
229 // Attempt to disconnect all drivers that are using the protocol interface that is about to be reinstalled
231 Status
= CoreDisconnectControllersUsingProtocolInterface (
235 if (EFI_ERROR (Status
)) {
237 // One or more drivers refused to release, so return the error
239 CoreReleaseProtocolLock ();
244 // Remove the protocol interface from the protocol
246 Prot
= CoreRemoveInterfaceFromProtocol (Handle
, Protocol
, OldInterface
);
249 CoreReleaseProtocolLock ();
250 return EFI_NOT_FOUND
;
253 ProtEntry
= Prot
->Protocol
;
256 // Update the interface on the protocol
258 Prot
->Interface
= NewInterface
;
261 // Add this protocol interface to the tail of the
264 InsertTailList (&ProtEntry
->Protocols
, &Prot
->ByProtocol
);
267 // Update the Key to show that the handle has been created/modified
269 gHandleDatabaseKey
++;
270 Handle
->Key
= gHandleDatabaseKey
;
273 // Release the lock and connect all drivers to UserHandle
275 CoreReleaseProtocolLock ();
276 Status
= CoreConnectController (
282 CoreAcquireProtocolLock ();
285 // Notify the notification list for this protocol
287 CoreNotifyProtocolEntry (ProtEntry
);
289 CoreReleaseProtocolLock ();