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