]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Dxe/Hand/Notify.c
Use TmpStr as a backup, as StrCpy in BaseLib does not handle copy of two strings
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Hand / Notify.c
CommitLineData
23c98c94 1/** @file\r
504214c4 2 UEFI notify infrastructure\r
28a00297 3\r
23c98c94 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
28a00297 12\r
504214c4 13**/\r
28a00297 14\r
15#include <DxeMain.h>\r
16\r
28a00297 17\r
162ed594 18/**\r
28a00297 19 Signal event for every protocol in protocol entry.\r
20\r
162ed594 21 @param ProtEntry Protocol entry\r
28a00297 22\r
162ed594 23**/\r
24VOID\r
25CoreNotifyProtocolEntry (\r
26 IN PROTOCOL_ENTRY *ProtEntry\r
27 )\r
28a00297 28{\r
29 PROTOCOL_NOTIFY *ProtNotify;\r
30 LIST_ENTRY *Link;\r
31\r
32 ASSERT_LOCKED (&gProtocolDatabaseLock);\r
33\r
34 for (Link=ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {\r
35 ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
36 CoreSignalEvent (ProtNotify->Event);\r
37 }\r
38}\r
39\r
40\r
162ed594 41\r
42/**\r
43 Removes Protocol from the protocol list (but not the handle list).\r
44\r
45 @param Handle The handle to remove protocol on. \r
46 @param Protocol GUID of the protocol to be moved \r
47 @param Interface The interface of the protocol \r
48\r
49 @return Protocol Entry\r
50\r
51**/\r
28a00297 52PROTOCOL_INTERFACE *\r
53CoreRemoveInterfaceFromProtocol (\r
54 IN IHANDLE *Handle,\r
55 IN EFI_GUID *Protocol,\r
56 IN VOID *Interface\r
57 )\r
28a00297 58{\r
59 PROTOCOL_INTERFACE *Prot;\r
60 PROTOCOL_NOTIFY *ProtNotify;\r
61 PROTOCOL_ENTRY *ProtEntry;\r
62 LIST_ENTRY *Link;\r
63\r
64 ASSERT_LOCKED (&gProtocolDatabaseLock);\r
65\r
66 Prot = CoreFindProtocolInterface (Handle, Protocol, Interface);\r
67 if (Prot != NULL) {\r
68\r
69 ProtEntry = Prot->Protocol;\r
70\r
71 //\r
72 // If there's a protocol notify location pointing to this entry, back it up one\r
73 //\r
28a00297 74 for(Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {\r
75 ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
76\r
77 if (ProtNotify->Position == &Prot->ByProtocol) {\r
78 ProtNotify->Position = Prot->ByProtocol.BackLink;\r
79 }\r
80 }\r
81\r
82 //\r
83 // Remove the protocol interface entry\r
84 //\r
28a00297 85 RemoveEntryList (&Prot->ByProtocol);\r
86 }\r
87\r
88 return Prot;\r
89}\r
90\r
91\r
162ed594 92/**\r
93 Add a new protocol notification record for the request protocol.\r
94\r
95 @param Protocol The requested protocol to add the notify \r
96 registration \r
97 @param Event The event to signal \r
98 @param Registration Returns the registration record \r
99\r
100 @retval EFI_INVALID_PARAMETER Invalid parameter \r
101 @retval EFI_SUCCESS Successfully returned the registration record \r
102 that has been added\r
103\r
104**/\r
28a00297 105EFI_STATUS\r
106EFIAPI\r
107CoreRegisterProtocolNotify (\r
108 IN EFI_GUID *Protocol,\r
109 IN EFI_EVENT Event,\r
e94a9ff7 110 OUT VOID **Registration\r
28a00297 111 )\r
28a00297 112{\r
e94a9ff7 113 PROTOCOL_ENTRY *ProtEntry;\r
114 PROTOCOL_NOTIFY *ProtNotify;\r
28a00297 115 EFI_STATUS Status;\r
116 \r
117 if ((Protocol == NULL) || (Event == NULL) || (Registration == NULL)) {\r
118 return EFI_INVALID_PARAMETER;\r
119 }\r
120\r
121 CoreAcquireProtocolLock ();\r
122\r
123 ProtNotify = NULL;\r
124 \r
125 //\r
126 // Get the protocol entry to add the notification too\r
127 //\r
128\r
129 ProtEntry = CoreFindProtocolEntry (Protocol, TRUE);\r
130 if (ProtEntry != NULL) {\r
131\r
132 //\r
133 // Allocate a new notification record\r
134 //\r
28a00297 135 ProtNotify = CoreAllocateBootServicesPool (sizeof(PROTOCOL_NOTIFY));\r
28a00297 136 if (ProtNotify != NULL) {\r
137 \r
138 ProtNotify->Signature = PROTOCOL_NOTIFY_SIGNATURE;\r
139 ProtNotify->Protocol = ProtEntry;\r
140 ProtNotify->Event = Event;\r
141 //\r
142 // start at the begining\r
143 //\r
144 ProtNotify->Position = &ProtEntry->Protocols; \r
145\r
146 InsertTailList (&ProtEntry->Notify, &ProtNotify->Link);\r
147 }\r
148 }\r
149\r
150 CoreReleaseProtocolLock ();\r
151\r
152 //\r
153 // Done. If we have a protocol notify entry, then return it.\r
154 // Otherwise, we must have run out of resources trying to add one\r
155 //\r
156\r
157 Status = EFI_OUT_OF_RESOURCES;\r
158 if (ProtNotify != NULL) {\r
159 *Registration = ProtNotify;\r
160 Status = EFI_SUCCESS;\r
161 }\r
162\r
163 return Status;\r
164}\r
165\r
166\r
162ed594 167/**\r
168 Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.\r
169\r
170 @param UserHandle Handle on which the interface is to be \r
171 reinstalled \r
172 @param Protocol The numeric ID of the interface \r
173 @param OldInterface A pointer to the old interface \r
174 @param NewInterface A pointer to the new interface \r
175\r
176 @retval EFI_SUCCESS The protocol interface was installed\r
177 @retval EFI_NOT_FOUND The OldInterface on the handle was not found\r
178 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value\r
179\r
180**/\r
28a00297 181EFI_STATUS\r
182EFIAPI\r
183CoreReinstallProtocolInterface (\r
184 IN EFI_HANDLE UserHandle,\r
185 IN EFI_GUID *Protocol,\r
186 IN VOID *OldInterface,\r
187 IN VOID *NewInterface\r
188 )\r
28a00297 189{\r
190 EFI_STATUS Status;\r
191 IHANDLE *Handle;\r
192 PROTOCOL_INTERFACE *Prot;\r
193 PROTOCOL_ENTRY *ProtEntry;\r
194\r
195 Status = CoreValidateHandle (UserHandle);\r
196 if (EFI_ERROR (Status)) {\r
197 return Status;\r
198 }\r
199\r
200 if (Protocol == NULL) {\r
201 return EFI_INVALID_PARAMETER;\r
202 }\r
203\r
204 Handle = (IHANDLE *) UserHandle;\r
205\r
206 //\r
207 // Lock the protocol database\r
208 //\r
209 CoreAcquireProtocolLock ();\r
210\r
211 //\r
212 // Check that Protocol exists on UserHandle, and Interface matches the interface in the database\r
213 //\r
214 Prot = CoreFindProtocolInterface (UserHandle, Protocol, OldInterface);\r
215 if (Prot == NULL) {\r
216 CoreReleaseProtocolLock ();\r
217 return EFI_NOT_FOUND;\r
218 }\r
219\r
220 //\r
221 // Attempt to disconnect all drivers that are using the protocol interface that is about to be reinstalled\r
222 //\r
223 Status = CoreDisconnectControllersUsingProtocolInterface (\r
224 UserHandle,\r
225 Prot\r
226 );\r
227 if (EFI_ERROR (Status)) {\r
228 //\r
229 // One or more drivers refused to release, so return the error\r
230 //\r
231 CoreReleaseProtocolLock ();\r
232 return Status;\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 CoreReleaseProtocolLock ();\r
242 return EFI_NOT_FOUND;\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 Status = CoreConnectController (\r
e94a9ff7 269 UserHandle, \r
270 NULL, \r
271 NULL, \r
272 TRUE\r
273 );\r
28a00297 274 CoreAcquireProtocolLock ();\r
275 \r
276 //\r
277 // Notify the notification list for this protocol\r
278 //\r
279 CoreNotifyProtocolEntry (ProtEntry);\r
280\r
281 CoreReleaseProtocolLock ();\r
282 \r
283 return EFI_SUCCESS;\r
284}\r