3 UEFI notify infrastructure
5 Copyright (c) 2006 - 2008, Intel Corporation
6 All rights reserved. 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.
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
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
88 RemoveEntryList (&Prot
->ByProtocol
);
98 Add a new protocol notification record for the request protocol.
100 @param Protocol The requested protocol to add the notify
102 @param Event The event to signal
103 @param Registration Returns the registration record
105 @retval EFI_INVALID_PARAMETER Invalid parameter
106 @retval EFI_SUCCESS Successfully returned the registration record
112 CoreRegisterProtocolNotify (
113 IN EFI_GUID
*Protocol
,
115 OUT VOID
**Registration
118 PROTOCOL_ENTRY
*ProtEntry
;
119 PROTOCOL_NOTIFY
*ProtNotify
;
122 if ((Protocol
== NULL
) || (Event
== NULL
) || (Registration
== NULL
)) {
123 return EFI_INVALID_PARAMETER
;
126 CoreAcquireProtocolLock ();
131 // Get the protocol entry to add the notification too
134 ProtEntry
= CoreFindProtocolEntry (Protocol
, TRUE
);
135 if (ProtEntry
!= NULL
) {
138 // Allocate a new notification record
141 ProtNotify
= CoreAllocateBootServicesPool (sizeof(PROTOCOL_NOTIFY
));
143 if (ProtNotify
!= NULL
) {
145 ProtNotify
->Signature
= PROTOCOL_NOTIFY_SIGNATURE
;
146 ProtNotify
->Protocol
= ProtEntry
;
147 ProtNotify
->Event
= Event
;
149 // start at the begining
151 ProtNotify
->Position
= &ProtEntry
->Protocols
;
153 InsertTailList (&ProtEntry
->Notify
, &ProtNotify
->Link
);
157 CoreReleaseProtocolLock ();
160 // Done. If we have a protocol notify entry, then return it.
161 // Otherwise, we must have run out of resources trying to add one
164 Status
= EFI_OUT_OF_RESOURCES
;
165 if (ProtNotify
!= NULL
) {
166 *Registration
= ProtNotify
;
167 Status
= EFI_SUCCESS
;
177 Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.
179 @param UserHandle Handle on which the interface is to be
181 @param Protocol The numeric ID of the interface
182 @param OldInterface A pointer to the old interface
183 @param NewInterface A pointer to the new interface
185 @retval EFI_SUCCESS The protocol interface was installed
186 @retval EFI_NOT_FOUND The OldInterface on the handle was not found
187 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
192 CoreReinstallProtocolInterface (
193 IN EFI_HANDLE UserHandle
,
194 IN EFI_GUID
*Protocol
,
195 IN VOID
*OldInterface
,
196 IN VOID
*NewInterface
201 PROTOCOL_INTERFACE
*Prot
;
202 PROTOCOL_ENTRY
*ProtEntry
;
204 Status
= CoreValidateHandle (UserHandle
);
205 if (EFI_ERROR (Status
)) {
209 if (Protocol
== NULL
) {
210 return EFI_INVALID_PARAMETER
;
213 Handle
= (IHANDLE
*) UserHandle
;
216 // Lock the protocol database
218 CoreAcquireProtocolLock ();
221 // Check that Protocol exists on UserHandle, and Interface matches the interface in the database
223 Prot
= CoreFindProtocolInterface (UserHandle
, Protocol
, OldInterface
);
225 CoreReleaseProtocolLock ();
226 return EFI_NOT_FOUND
;
230 // Attempt to disconnect all drivers that are using the protocol interface that is about to be reinstalled
232 Status
= CoreDisconnectControllersUsingProtocolInterface (
236 if (EFI_ERROR (Status
)) {
238 // One or more drivers refused to release, so return the error
240 CoreReleaseProtocolLock ();
245 // Remove the protocol interface from the protocol
247 Prot
= CoreRemoveInterfaceFromProtocol (Handle
, Protocol
, OldInterface
);
250 CoreReleaseProtocolLock ();
251 return EFI_NOT_FOUND
;
254 ProtEntry
= Prot
->Protocol
;
257 // Update the interface on the protocol
259 Prot
->Interface
= NewInterface
;
262 // Add this protocol interface to the tail of the
265 InsertTailList (&ProtEntry
->Protocols
, &Prot
->ByProtocol
);
268 // Update the Key to show that the handle has been created/modified
270 gHandleDatabaseKey
++;
271 Handle
->Key
= gHandleDatabaseKey
;
274 // Release the lock and connect all drivers to UserHandle
276 CoreReleaseProtocolLock ();
277 Status
= CoreConnectController (
283 CoreAcquireProtocolLock ();
286 // Notify the notification list for this protocol
288 CoreNotifyProtocolEntry (ProtEntry
);
290 CoreReleaseProtocolLock ();