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