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