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