]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - 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
1/** @file\r
2 Support functions for UEFI protocol notification infrastructure.\r
3\r
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
12\r
13**/\r
14\r
15#include "DxeMain.h"\r
16#include "Handle.h"\r
17\r
18\r
19/**\r
20 Signal event for every protocol in protocol entry.\r
21\r
22 @param ProtEntry Protocol entry\r
23\r
24**/\r
25VOID\r
26CoreNotifyProtocolEntry (\r
27 IN PROTOCOL_ENTRY *ProtEntry\r
28 )\r
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
42\r
43/**\r
44 Removes Protocol from the protocol list (but not the handle list).\r
45\r
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
49\r
50 @return Protocol Entry\r
51\r
52**/\r
53PROTOCOL_INTERFACE *\r
54CoreRemoveInterfaceFromProtocol (\r
55 IN IHANDLE *Handle,\r
56 IN EFI_GUID *Protocol,\r
57 IN VOID *Interface\r
58 )\r
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
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
86 RemoveEntryList (&Prot->ByProtocol);\r
87 }\r
88\r
89 return Prot;\r
90}\r
91\r
92\r
93/**\r
94 Add a new protocol notification record for the request protocol.\r
95\r
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
100\r
101 @retval EFI_INVALID_PARAMETER Invalid parameter\r
102 @retval EFI_SUCCESS Successfully returned the registration record\r
103 that has been added\r
104\r
105**/\r
106EFI_STATUS\r
107EFIAPI\r
108CoreRegisterProtocolNotify (\r
109 IN EFI_GUID *Protocol,\r
110 IN EFI_EVENT Event,\r
111 OUT VOID **Registration\r
112 )\r
113{\r
114 PROTOCOL_ENTRY *ProtEntry;\r
115 PROTOCOL_NOTIFY *ProtNotify;\r
116 EFI_STATUS Status;\r
117\r
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
125\r
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
136 ProtNotify = AllocatePool (sizeof(PROTOCOL_NOTIFY));\r
137 if (ProtNotify != NULL) {\r
138\r
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
145 ProtNotify->Position = &ProtEntry->Protocols;\r
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
168/**\r
169 Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.\r
170\r
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
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
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
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
217 Status = EFI_NOT_FOUND;\r
218 goto Done;\r
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
232 goto Done;\r
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
241 Status = EFI_NOT_FOUND;\r
242 goto Done;\r
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
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
277 CoreAcquireProtocolLock ();\r
278\r
279 //\r
280 // Notify the notification list for this protocol\r
281 //\r
282 CoreNotifyProtocolEntry (ProtEntry);\r
283\r
284 Status = EFI_SUCCESS;\r
285\r
286Done:\r
287 CoreReleaseProtocolLock ();\r
288\r
289 return Status;\r
290}\r