]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Dxe/Hand/Notify.c
MdeModulePkg DxeCore: Fix issue to print GUID value %g without pointer
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Hand / Notify.c
CommitLineData
23c98c94 1/** @file\r
6c857d66 2 Support functions for UEFI protocol notification infrastructure.\r
28a00297 3\r
cd5ebaa0 4Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>\r
82f3edf2 5(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
cd5ebaa0 6This program and the accompanying materials\r
23c98c94 7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
28a00297 13\r
504214c4 14**/\r
28a00297 15\r
9c4ac31c 16#include "DxeMain.h"\r
ec90508b 17#include "Handle.h"\r
82f3edf2 18#include "Event.h"\r
28a00297 19\r
162ed594 20/**\r
28a00297 21 Signal event for every protocol in protocol entry.\r
22\r
162ed594 23 @param ProtEntry Protocol entry\r
28a00297 24\r
162ed594 25**/\r
26VOID\r
27CoreNotifyProtocolEntry (\r
28 IN PROTOCOL_ENTRY *ProtEntry\r
29 )\r
28a00297 30{\r
31 PROTOCOL_NOTIFY *ProtNotify;\r
32 LIST_ENTRY *Link;\r
33\r
34 ASSERT_LOCKED (&gProtocolDatabaseLock);\r
35\r
36 for (Link=ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {\r
37 ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
38 CoreSignalEvent (ProtNotify->Event);\r
39 }\r
40}\r
41\r
42\r
162ed594 43\r
44/**\r
45 Removes Protocol from the protocol list (but not the handle list).\r
46\r
022c6d45 47 @param Handle The handle to remove protocol on.\r
48 @param Protocol GUID of the protocol to be moved\r
49 @param Interface The interface of the protocol\r
162ed594 50\r
51 @return Protocol Entry\r
52\r
53**/\r
28a00297 54PROTOCOL_INTERFACE *\r
55CoreRemoveInterfaceFromProtocol (\r
56 IN IHANDLE *Handle,\r
57 IN EFI_GUID *Protocol,\r
58 IN VOID *Interface\r
59 )\r
28a00297 60{\r
61 PROTOCOL_INTERFACE *Prot;\r
62 PROTOCOL_NOTIFY *ProtNotify;\r
63 PROTOCOL_ENTRY *ProtEntry;\r
64 LIST_ENTRY *Link;\r
65\r
66 ASSERT_LOCKED (&gProtocolDatabaseLock);\r
67\r
68 Prot = CoreFindProtocolInterface (Handle, Protocol, Interface);\r
69 if (Prot != NULL) {\r
70\r
71 ProtEntry = Prot->Protocol;\r
72\r
73 //\r
74 // If there's a protocol notify location pointing to this entry, back it up one\r
75 //\r
28a00297 76 for(Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {\r
77 ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
78\r
79 if (ProtNotify->Position == &Prot->ByProtocol) {\r
80 ProtNotify->Position = Prot->ByProtocol.BackLink;\r
81 }\r
82 }\r
83\r
84 //\r
85 // Remove the protocol interface entry\r
86 //\r
28a00297 87 RemoveEntryList (&Prot->ByProtocol);\r
88 }\r
89\r
90 return Prot;\r
91}\r
92\r
93\r
162ed594 94/**\r
95 Add a new protocol notification record for the request protocol.\r
96\r
022c6d45 97 @param Protocol The requested protocol to add the notify\r
98 registration\r
99 @param Event The event to signal\r
100 @param Registration Returns the registration record\r
162ed594 101\r
022c6d45 102 @retval EFI_INVALID_PARAMETER Invalid parameter\r
103 @retval EFI_SUCCESS Successfully returned the registration record\r
162ed594 104 that has been added\r
105\r
106**/\r
28a00297 107EFI_STATUS\r
108EFIAPI\r
109CoreRegisterProtocolNotify (\r
110 IN EFI_GUID *Protocol,\r
111 IN EFI_EVENT Event,\r
e94a9ff7 112 OUT VOID **Registration\r
28a00297 113 )\r
28a00297 114{\r
e94a9ff7 115 PROTOCOL_ENTRY *ProtEntry;\r
116 PROTOCOL_NOTIFY *ProtNotify;\r
28a00297 117 EFI_STATUS Status;\r
022c6d45 118\r
28a00297 119 if ((Protocol == NULL) || (Event == NULL) || (Registration == NULL)) {\r
120 return EFI_INVALID_PARAMETER;\r
121 }\r
122\r
123 CoreAcquireProtocolLock ();\r
124\r
125 ProtNotify = NULL;\r
022c6d45 126\r
28a00297 127 //\r
128 // Get the protocol entry to add the notification too\r
129 //\r
130\r
131 ProtEntry = CoreFindProtocolEntry (Protocol, TRUE);\r
132 if (ProtEntry != NULL) {\r
133\r
134 //\r
135 // Allocate a new notification record\r
136 //\r
9c4ac31c 137 ProtNotify = AllocatePool (sizeof(PROTOCOL_NOTIFY));\r
28a00297 138 if (ProtNotify != NULL) {\r
82f3edf2 139 ((IEVENT *)Event)->ExFlag |= EVT_EXFLAG_EVENT_PROTOCOL_NOTIFICATION;\r
28a00297 140 ProtNotify->Signature = PROTOCOL_NOTIFY_SIGNATURE;\r
141 ProtNotify->Protocol = ProtEntry;\r
142 ProtNotify->Event = Event;\r
143 //\r
144 // start at the begining\r
145 //\r
022c6d45 146 ProtNotify->Position = &ProtEntry->Protocols;\r
28a00297 147\r
148 InsertTailList (&ProtEntry->Notify, &ProtNotify->Link);\r
149 }\r
150 }\r
151\r
152 CoreReleaseProtocolLock ();\r
153\r
154 //\r
155 // Done. If we have a protocol notify entry, then return it.\r
156 // Otherwise, we must have run out of resources trying to add one\r
157 //\r
158\r
159 Status = EFI_OUT_OF_RESOURCES;\r
160 if (ProtNotify != NULL) {\r
161 *Registration = ProtNotify;\r
162 Status = EFI_SUCCESS;\r
163 }\r
164\r
165 return Status;\r
166}\r
167\r
168\r
162ed594 169/**\r
170 Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.\r
171\r
022c6d45 172 @param UserHandle Handle on which the interface is to be\r
173 reinstalled\r
174 @param Protocol The numeric ID of the interface\r
175 @param OldInterface A pointer to the old interface\r
176 @param NewInterface A pointer to the new interface\r
162ed594 177\r
178 @retval EFI_SUCCESS The protocol interface was installed\r
179 @retval EFI_NOT_FOUND The OldInterface on the handle was not found\r
180 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value\r
181\r
182**/\r
28a00297 183EFI_STATUS\r
184EFIAPI\r
185CoreReinstallProtocolInterface (\r
186 IN EFI_HANDLE UserHandle,\r
187 IN EFI_GUID *Protocol,\r
188 IN VOID *OldInterface,\r
189 IN VOID *NewInterface\r
190 )\r
28a00297 191{\r
192 EFI_STATUS Status;\r
193 IHANDLE *Handle;\r
194 PROTOCOL_INTERFACE *Prot;\r
195 PROTOCOL_ENTRY *ProtEntry;\r
196\r
197 Status = CoreValidateHandle (UserHandle);\r
198 if (EFI_ERROR (Status)) {\r
199 return Status;\r
200 }\r
201\r
202 if (Protocol == NULL) {\r
203 return EFI_INVALID_PARAMETER;\r
204 }\r
205\r
206 Handle = (IHANDLE *) UserHandle;\r
207\r
208 //\r
209 // Lock the protocol database\r
210 //\r
211 CoreAcquireProtocolLock ();\r
212\r
213 //\r
214 // Check that Protocol exists on UserHandle, and Interface matches the interface in the database\r
215 //\r
216 Prot = CoreFindProtocolInterface (UserHandle, Protocol, OldInterface);\r
217 if (Prot == NULL) {\r
6c857d66 218 Status = EFI_NOT_FOUND;\r
219 goto Done;\r
28a00297 220 }\r
221\r
222 //\r
223 // Attempt to disconnect all drivers that are using the protocol interface that is about to be reinstalled\r
224 //\r
225 Status = CoreDisconnectControllersUsingProtocolInterface (\r
226 UserHandle,\r
227 Prot\r
228 );\r
229 if (EFI_ERROR (Status)) {\r
230 //\r
231 // One or more drivers refused to release, so return the error\r
232 //\r
6c857d66 233 goto Done;\r
28a00297 234 }\r
235\r
236 //\r
237 // Remove the protocol interface from the protocol\r
238 //\r
239 Prot = CoreRemoveInterfaceFromProtocol (Handle, Protocol, OldInterface);\r
240\r
241 if (Prot == NULL) {\r
6c857d66 242 Status = EFI_NOT_FOUND;\r
243 goto Done;\r
28a00297 244 }\r
245\r
246 ProtEntry = Prot->Protocol;\r
247\r
248 //\r
249 // Update the interface on the protocol\r
250 //\r
251 Prot->Interface = NewInterface;\r
252\r
253 //\r
254 // Add this protocol interface to the tail of the\r
255 // protocol entry\r
256 //\r
257 InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol);\r
258\r
259 //\r
260 // Update the Key to show that the handle has been created/modified\r
261 //\r
262 gHandleDatabaseKey++;\r
263 Handle->Key = gHandleDatabaseKey;\r
264\r
265 //\r
266 // Release the lock and connect all drivers to UserHandle\r
267 //\r
268 CoreReleaseProtocolLock ();\r
6c857d66 269 //\r
270 // Return code is ignored on purpose.\r
271 //\r
272 CoreConnectController (\r
273 UserHandle,\r
274 NULL,\r
275 NULL,\r
276 TRUE\r
277 );\r
28a00297 278 CoreAcquireProtocolLock ();\r
022c6d45 279\r
28a00297 280 //\r
281 // Notify the notification list for this protocol\r
282 //\r
283 CoreNotifyProtocolEntry (ProtEntry);\r
284\r
6c857d66 285 Status = EFI_SUCCESS;\r
286\r
287Done:\r
fa3c419f 288 CoreReleaseProtocolLock ();\r
289\r
6c857d66 290 return Status;\r
28a00297 291}\r