2 Support functions for UEFI protocol notification 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
74 for(Link
= ProtEntry
->Notify
.ForwardLink
; Link
!= &ProtEntry
->Notify
; Link
=Link
->ForwardLink
) {
75 ProtNotify
= CR(Link
, PROTOCOL_NOTIFY
, Link
, PROTOCOL_NOTIFY_SIGNATURE
);
77 if (ProtNotify
->Position
== &Prot
->ByProtocol
) {
78 ProtNotify
->Position
= Prot
->ByProtocol
.BackLink
;
83 // Remove the protocol interface entry
85 RemoveEntryList (&Prot
->ByProtocol
);
93 Add a new protocol notification record for the request protocol.
95 @param Protocol The requested protocol to add the notify
97 @param Event The event to signal
98 @param Registration Returns the registration record
100 @retval EFI_INVALID_PARAMETER Invalid parameter
101 @retval EFI_SUCCESS Successfully returned the registration record
107 CoreRegisterProtocolNotify (
108 IN EFI_GUID
*Protocol
,
110 OUT VOID
**Registration
113 PROTOCOL_ENTRY
*ProtEntry
;
114 PROTOCOL_NOTIFY
*ProtNotify
;
117 if ((Protocol
== NULL
) || (Event
== NULL
) || (Registration
== NULL
)) {
118 return EFI_INVALID_PARAMETER
;
121 CoreAcquireProtocolLock ();
126 // Get the protocol entry to add the notification too
129 ProtEntry
= CoreFindProtocolEntry (Protocol
, TRUE
);
130 if (ProtEntry
!= NULL
) {
133 // Allocate a new notification record
135 ProtNotify
= AllocatePool (sizeof(PROTOCOL_NOTIFY
));
136 if (ProtNotify
!= NULL
) {
138 ProtNotify
->Signature
= PROTOCOL_NOTIFY_SIGNATURE
;
139 ProtNotify
->Protocol
= ProtEntry
;
140 ProtNotify
->Event
= Event
;
142 // start at the begining
144 ProtNotify
->Position
= &ProtEntry
->Protocols
;
146 InsertTailList (&ProtEntry
->Notify
, &ProtNotify
->Link
);
150 CoreReleaseProtocolLock ();
153 // Done. If we have a protocol notify entry, then return it.
154 // Otherwise, we must have run out of resources trying to add one
157 Status
= EFI_OUT_OF_RESOURCES
;
158 if (ProtNotify
!= NULL
) {
159 *Registration
= ProtNotify
;
160 Status
= EFI_SUCCESS
;
168 Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.
170 @param UserHandle Handle on which the interface is to be
172 @param Protocol The numeric ID of the interface
173 @param OldInterface A pointer to the old interface
174 @param NewInterface A pointer to the new interface
176 @retval EFI_SUCCESS The protocol interface was installed
177 @retval EFI_NOT_FOUND The OldInterface on the handle was not found
178 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
183 CoreReinstallProtocolInterface (
184 IN EFI_HANDLE UserHandle
,
185 IN EFI_GUID
*Protocol
,
186 IN VOID
*OldInterface
,
187 IN VOID
*NewInterface
192 PROTOCOL_INTERFACE
*Prot
;
193 PROTOCOL_ENTRY
*ProtEntry
;
195 Status
= CoreValidateHandle (UserHandle
);
196 if (EFI_ERROR (Status
)) {
200 if (Protocol
== NULL
) {
201 return EFI_INVALID_PARAMETER
;
204 Handle
= (IHANDLE
*) UserHandle
;
207 // Lock the protocol database
209 CoreAcquireProtocolLock ();
212 // Check that Protocol exists on UserHandle, and Interface matches the interface in the database
214 Prot
= CoreFindProtocolInterface (UserHandle
, Protocol
, OldInterface
);
216 Status
= EFI_NOT_FOUND
;
221 // Attempt to disconnect all drivers that are using the protocol interface that is about to be reinstalled
223 Status
= CoreDisconnectControllersUsingProtocolInterface (
227 if (EFI_ERROR (Status
)) {
229 // One or more drivers refused to release, so return the error
235 // Remove the protocol interface from the protocol
237 Prot
= CoreRemoveInterfaceFromProtocol (Handle
, Protocol
, OldInterface
);
240 Status
= EFI_NOT_FOUND
;
244 ProtEntry
= Prot
->Protocol
;
247 // Update the interface on the protocol
249 Prot
->Interface
= NewInterface
;
252 // Add this protocol interface to the tail of the
255 InsertTailList (&ProtEntry
->Protocols
, &Prot
->ByProtocol
);
258 // Update the Key to show that the handle has been created/modified
260 gHandleDatabaseKey
++;
261 Handle
->Key
= gHandleDatabaseKey
;
264 // Release the lock and connect all drivers to UserHandle
266 CoreReleaseProtocolLock ();
268 // Return code is ignored on purpose.
270 CoreConnectController (
276 CoreAcquireProtocolLock ();
279 // Notify the notification list for this protocol
281 CoreNotifyProtocolEntry (ProtEntry
);
283 Status
= EFI_SUCCESS
;
286 CoreReleaseProtocolLock ();