]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Dxe/Hand/Notify.c
Change the file name case to follow coding style: The first character should be capital.
[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
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
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
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
75\r
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
87\r
88 RemoveEntryList (&Prot->ByProtocol);\r
89 }\r
90\r
91 return Prot;\r
92}\r
93\r
94\r
95\r
162ed594 96\r
97/**\r
98 Add a new protocol notification record for the request protocol.\r
99\r
100 @param Protocol The requested protocol to add the notify \r
101 registration \r
102 @param Event The event to signal \r
103 @param Registration Returns the registration record \r
104\r
105 @retval EFI_INVALID_PARAMETER Invalid parameter \r
106 @retval EFI_SUCCESS Successfully returned the registration record \r
107 that has been added\r
108\r
109**/\r
28a00297 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
28a00297 117{\r
118 PROTOCOL_ENTRY *ProtEntry;\r
119 PROTOCOL_NOTIFY *ProtNotify;\r
120 EFI_STATUS Status;\r
121 \r
122 if ((Protocol == NULL) || (Event == NULL) || (Registration == NULL)) {\r
123 return EFI_INVALID_PARAMETER;\r
124 }\r
125\r
126 CoreAcquireProtocolLock ();\r
127\r
128 ProtNotify = NULL;\r
129 \r
130 //\r
131 // Get the protocol entry to add the notification too\r
132 //\r
133\r
134 ProtEntry = CoreFindProtocolEntry (Protocol, TRUE);\r
135 if (ProtEntry != NULL) {\r
136\r
137 //\r
138 // Allocate a new notification record\r
139 //\r
140\r
141 ProtNotify = CoreAllocateBootServicesPool (sizeof(PROTOCOL_NOTIFY));\r
142\r
143 if (ProtNotify != NULL) {\r
144 \r
145 ProtNotify->Signature = PROTOCOL_NOTIFY_SIGNATURE;\r
146 ProtNotify->Protocol = ProtEntry;\r
147 ProtNotify->Event = Event;\r
148 //\r
149 // start at the begining\r
150 //\r
151 ProtNotify->Position = &ProtEntry->Protocols; \r
152\r
153 InsertTailList (&ProtEntry->Notify, &ProtNotify->Link);\r
154 }\r
155 }\r
156\r
157 CoreReleaseProtocolLock ();\r
158\r
159 //\r
160 // Done. If we have a protocol notify entry, then return it.\r
161 // Otherwise, we must have run out of resources trying to add one\r
162 //\r
163\r
164 Status = EFI_OUT_OF_RESOURCES;\r
165 if (ProtNotify != NULL) {\r
166 *Registration = ProtNotify;\r
167 Status = EFI_SUCCESS;\r
168 }\r
169\r
170 return Status;\r
171}\r
172\r
173\r
174\r
162ed594 175\r
176/**\r
177 Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.\r
178\r
179 @param UserHandle Handle on which the interface is to be \r
180 reinstalled \r
181 @param Protocol The numeric ID of the interface \r
182 @param OldInterface A pointer to the old interface \r
183 @param NewInterface A pointer to the new interface \r
184\r
185 @retval EFI_SUCCESS The protocol interface was installed\r
186 @retval EFI_NOT_FOUND The OldInterface on the handle was not found\r
187 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value\r
188\r
189**/\r
28a00297 190EFI_STATUS\r
191EFIAPI\r
192CoreReinstallProtocolInterface (\r
193 IN EFI_HANDLE UserHandle,\r
194 IN EFI_GUID *Protocol,\r
195 IN VOID *OldInterface,\r
196 IN VOID *NewInterface\r
197 )\r
28a00297 198{\r
199 EFI_STATUS Status;\r
200 IHANDLE *Handle;\r
201 PROTOCOL_INTERFACE *Prot;\r
202 PROTOCOL_ENTRY *ProtEntry;\r
203\r
204 Status = CoreValidateHandle (UserHandle);\r
205 if (EFI_ERROR (Status)) {\r
206 return Status;\r
207 }\r
208\r
209 if (Protocol == NULL) {\r
210 return EFI_INVALID_PARAMETER;\r
211 }\r
212\r
213 Handle = (IHANDLE *) UserHandle;\r
214\r
215 //\r
216 // Lock the protocol database\r
217 //\r
218 CoreAcquireProtocolLock ();\r
219\r
220 //\r
221 // Check that Protocol exists on UserHandle, and Interface matches the interface in the database\r
222 //\r
223 Prot = CoreFindProtocolInterface (UserHandle, Protocol, OldInterface);\r
224 if (Prot == NULL) {\r
225 CoreReleaseProtocolLock ();\r
226 return EFI_NOT_FOUND;\r
227 }\r
228\r
229 //\r
230 // Attempt to disconnect all drivers that are using the protocol interface that is about to be reinstalled\r
231 //\r
232 Status = CoreDisconnectControllersUsingProtocolInterface (\r
233 UserHandle,\r
234 Prot\r
235 );\r
236 if (EFI_ERROR (Status)) {\r
237 //\r
238 // One or more drivers refused to release, so return the error\r
239 //\r
240 CoreReleaseProtocolLock ();\r
241 return Status;\r
242 }\r
243\r
244 //\r
245 // Remove the protocol interface from the protocol\r
246 //\r
247 Prot = CoreRemoveInterfaceFromProtocol (Handle, Protocol, OldInterface);\r
248\r
249 if (Prot == NULL) {\r
250 CoreReleaseProtocolLock ();\r
251 return EFI_NOT_FOUND;\r
252 }\r
253\r
254 ProtEntry = Prot->Protocol;\r
255\r
256 //\r
257 // Update the interface on the protocol\r
258 //\r
259 Prot->Interface = NewInterface;\r
260\r
261 //\r
262 // Add this protocol interface to the tail of the\r
263 // protocol entry\r
264 //\r
265 InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol);\r
266\r
267 //\r
268 // Update the Key to show that the handle has been created/modified\r
269 //\r
270 gHandleDatabaseKey++;\r
271 Handle->Key = gHandleDatabaseKey;\r
272\r
273 //\r
274 // Release the lock and connect all drivers to UserHandle\r
275 //\r
276 CoreReleaseProtocolLock ();\r
277 Status = CoreConnectController (\r
278 UserHandle, \r
279 NULL, \r
280 NULL, \r
281 TRUE\r
282 );\r
283 CoreAcquireProtocolLock ();\r
284 \r
285 //\r
286 // Notify the notification list for this protocol\r
287 //\r
288 CoreNotifyProtocolEntry (ProtEntry);\r
289\r
290 CoreReleaseProtocolLock ();\r
291 \r
292 return EFI_SUCCESS;\r
293}\r