]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/PiSmmCore/Notify.c
MdeModulePkg/S3SmmInitDone.h: Fix copyright coding style error.
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / Notify.c
CommitLineData
e42e9404 1/** @file\r
2 Support functions for UEFI protocol notification infrastructure.\r
3\r
d1102dba
LG
4 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials are licensed and made available\r
6 under the terms and conditions of the BSD License which accompanies this\r
7 distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
e42e9404 9\r
d1102dba
LG
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
e42e9404 12\r
13**/\r
14\r
15#include "PiSmmCore.h"\r
16\r
17/**\r
18 Signal event for every protocol in protocol entry.\r
19\r
20 @param Prot Protocol interface\r
21\r
22**/\r
23VOID\r
24SmmNotifyProtocol (\r
25 IN PROTOCOL_INTERFACE *Prot\r
26 )\r
27{\r
28 PROTOCOL_ENTRY *ProtEntry;\r
29 PROTOCOL_NOTIFY *ProtNotify;\r
30 LIST_ENTRY *Link;\r
31\r
32 ProtEntry = Prot->Protocol;\r
33 for (Link=ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {\r
34 ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
35 ProtNotify->Function (&ProtEntry->ProtocolID, Prot->Interface, Prot->Handle);\r
36 }\r
37}\r
38\r
39/**\r
40 Removes Protocol from the protocol list (but not the handle list).\r
41\r
42 @param Handle The handle to remove protocol on.\r
43 @param Protocol GUID of the protocol to be moved\r
44 @param Interface The interface of the protocol\r
45\r
46 @return Protocol Entry\r
47\r
48**/\r
49PROTOCOL_INTERFACE *\r
50SmmRemoveInterfaceFromProtocol (\r
51 IN IHANDLE *Handle,\r
52 IN EFI_GUID *Protocol,\r
53 IN VOID *Interface\r
54 )\r
55{\r
56 PROTOCOL_INTERFACE *Prot;\r
57 PROTOCOL_NOTIFY *ProtNotify;\r
58 PROTOCOL_ENTRY *ProtEntry;\r
59 LIST_ENTRY *Link;\r
60\r
61 Prot = SmmFindProtocolInterface (Handle, Protocol, Interface);\r
62 if (Prot != NULL) {\r
63\r
64 ProtEntry = Prot->Protocol;\r
65\r
66 //\r
67 // If there's a protocol notify location pointing to this entry, back it up one\r
68 //\r
69 for(Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {\r
70 ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
71\r
72 if (ProtNotify->Position == &Prot->ByProtocol) {\r
73 ProtNotify->Position = Prot->ByProtocol.BackLink;\r
74 }\r
75 }\r
76\r
77 //\r
78 // Remove the protocol interface entry\r
79 //\r
80 RemoveEntryList (&Prot->ByProtocol);\r
81 }\r
82\r
83 return Prot;\r
84}\r
85\r
86/**\r
87 Add a new protocol notification record for the request protocol.\r
88\r
89 @param Protocol The requested protocol to add the notify\r
90 registration\r
91 @param Function Points to the notification function\r
92 @param Registration Returns the registration record\r
93\r
e42e9404 94 @retval EFI_SUCCESS Successfully returned the registration record\r
aeb4c944
JF
95 that has been added or unhooked\r
96 @retval EFI_INVALID_PARAMETER Protocol is NULL or Registration is NULL\r
50903aa5
JF
97 @retval EFI_OUT_OF_RESOURCES Not enough memory resource to finish the request\r
98 @retval EFI_NOT_FOUND If the registration is not found when Function == NULL\r
e42e9404 99\r
100**/\r
101EFI_STATUS\r
102EFIAPI\r
103SmmRegisterProtocolNotify (\r
104 IN CONST EFI_GUID *Protocol,\r
105 IN EFI_SMM_NOTIFY_FN Function,\r
106 OUT VOID **Registration\r
107 )\r
108{\r
109 PROTOCOL_ENTRY *ProtEntry;\r
110 PROTOCOL_NOTIFY *ProtNotify;\r
111 LIST_ENTRY *Link;\r
112 EFI_STATUS Status;\r
113\r
50903aa5 114 if (Protocol == NULL || Registration == NULL) {\r
e42e9404 115 return EFI_INVALID_PARAMETER;\r
116 }\r
117\r
50903aa5 118 if (Function == NULL) {\r
d1102dba 119 //\r
50903aa5
JF
120 // Get the protocol entry per Protocol\r
121 //\r
122 ProtEntry = SmmFindProtocolEntry ((EFI_GUID *) Protocol, FALSE);\r
123 if (ProtEntry != NULL) {\r
124 ProtNotify = (PROTOCOL_NOTIFY * )*Registration;\r
125 for (Link = ProtEntry->Notify.ForwardLink;\r
126 Link != &ProtEntry->Notify;\r
127 Link = Link->ForwardLink) {\r
128 //\r
d1102dba 129 // Compare the notification record\r
50903aa5
JF
130 //\r
131 if (ProtNotify == (CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE))){\r
132 //\r
133 // If Registration is an existing registration, then unhook it\r
134 //\r
135 ProtNotify->Signature = 0;\r
136 RemoveEntryList (&ProtNotify->Link);\r
137 FreePool (ProtNotify);\r
138 return EFI_SUCCESS;\r
139 }\r
140 }\r
141 }\r
142 //\r
143 // If the registration is not found\r
144 //\r
145 return EFI_NOT_FOUND;\r
d1102dba 146 }\r
50903aa5 147\r
e42e9404 148 ProtNotify = NULL;\r
149\r
150 //\r
151 // Get the protocol entry to add the notification too\r
152 //\r
153 ProtEntry = SmmFindProtocolEntry ((EFI_GUID *) Protocol, TRUE);\r
154 if (ProtEntry != NULL) {\r
155 //\r
156 // Find whether notification already exist\r
157 //\r
158 for (Link = ProtEntry->Notify.ForwardLink;\r
159 Link != &ProtEntry->Notify;\r
160 Link = Link->ForwardLink) {\r
161\r
162 ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
163 if (CompareGuid (&ProtNotify->Protocol->ProtocolID, Protocol) &&\r
164 (ProtNotify->Function == Function)) {\r
165\r
166 //\r
167 // Notification already exist\r
168 //\r
169 *Registration = ProtNotify;\r
170\r
171 return EFI_SUCCESS;\r
172 }\r
173 }\r
174\r
175 //\r
176 // Allocate a new notification record\r
177 //\r
178 ProtNotify = AllocatePool (sizeof(PROTOCOL_NOTIFY));\r
179 if (ProtNotify != NULL) {\r
180 ProtNotify->Signature = PROTOCOL_NOTIFY_SIGNATURE;\r
181 ProtNotify->Protocol = ProtEntry;\r
182 ProtNotify->Function = Function;\r
183 //\r
184 // Start at the ending\r
185 //\r
186 ProtNotify->Position = ProtEntry->Protocols.BackLink;\r
187\r
188 InsertTailList (&ProtEntry->Notify, &ProtNotify->Link);\r
189 }\r
190 }\r
191\r
192 //\r
193 // Done. If we have a protocol notify entry, then return it.\r
194 // Otherwise, we must have run out of resources trying to add one\r
195 //\r
196 Status = EFI_OUT_OF_RESOURCES;\r
197 if (ProtNotify != NULL) {\r
198 *Registration = ProtNotify;\r
199 Status = EFI_SUCCESS;\r
200 }\r
201 return Status;\r
202}\r