]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/PiSmmCore/Notify.c
Clean up DEC files:
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / Notify.c
CommitLineData
e42e9404 1/** @file\r
2 Support functions for UEFI protocol notification infrastructure.\r
3\r
cd5ebaa0 4 Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
e42e9404 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
9\r
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
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
94 @retval EFI_INVALID_PARAMETER Invalid parameter\r
95 @retval EFI_SUCCESS Successfully returned the registration record\r
96 that has been added\r
97\r
98**/\r
99EFI_STATUS\r
100EFIAPI\r
101SmmRegisterProtocolNotify (\r
102 IN CONST EFI_GUID *Protocol,\r
103 IN EFI_SMM_NOTIFY_FN Function,\r
104 OUT VOID **Registration\r
105 )\r
106{\r
107 PROTOCOL_ENTRY *ProtEntry;\r
108 PROTOCOL_NOTIFY *ProtNotify;\r
109 LIST_ENTRY *Link;\r
110 EFI_STATUS Status;\r
111\r
112 if ((Protocol == NULL) || (Function == NULL) || (Registration == NULL)) {\r
113 return EFI_INVALID_PARAMETER;\r
114 }\r
115\r
116 ProtNotify = NULL;\r
117\r
118 //\r
119 // Get the protocol entry to add the notification too\r
120 //\r
121 ProtEntry = SmmFindProtocolEntry ((EFI_GUID *) Protocol, TRUE);\r
122 if (ProtEntry != NULL) {\r
123 //\r
124 // Find whether notification already exist\r
125 //\r
126 for (Link = ProtEntry->Notify.ForwardLink;\r
127 Link != &ProtEntry->Notify;\r
128 Link = Link->ForwardLink) {\r
129\r
130 ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
131 if (CompareGuid (&ProtNotify->Protocol->ProtocolID, Protocol) &&\r
132 (ProtNotify->Function == Function)) {\r
133\r
134 //\r
135 // Notification already exist\r
136 //\r
137 *Registration = ProtNotify;\r
138\r
139 return EFI_SUCCESS;\r
140 }\r
141 }\r
142\r
143 //\r
144 // Allocate a new notification record\r
145 //\r
146 ProtNotify = AllocatePool (sizeof(PROTOCOL_NOTIFY));\r
147 if (ProtNotify != NULL) {\r
148 ProtNotify->Signature = PROTOCOL_NOTIFY_SIGNATURE;\r
149 ProtNotify->Protocol = ProtEntry;\r
150 ProtNotify->Function = Function;\r
151 //\r
152 // Start at the ending\r
153 //\r
154 ProtNotify->Position = ProtEntry->Protocols.BackLink;\r
155\r
156 InsertTailList (&ProtEntry->Notify, &ProtNotify->Link);\r
157 }\r
158 }\r
159\r
160 //\r
161 // Done. If we have a protocol notify entry, then return it.\r
162 // Otherwise, we must have run out of resources trying to add one\r
163 //\r
164 Status = EFI_OUT_OF_RESOURCES;\r
165 if (ProtNotify != NULL) {\r
166 *Registration = ProtNotify;\r
167 Status = EFI_SUCCESS;\r
168 }\r
169 return Status;\r
170}\r