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