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