]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Core/PiSmmCore/Notify.c
Update the copyright notice format
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / Notify.c
1 /** @file
2 Support functions for UEFI protocol notification infrastructure.
3
4 Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are licensed and made available
6 under the terms and conditions of the BSD License which accompanies this
7 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 "PiSmmCore.h"
16
17 /**
18 Signal event for every protocol in protocol entry.
19
20 @param Prot Protocol interface
21
22 **/
23 VOID
24 SmmNotifyProtocol (
25 IN PROTOCOL_INTERFACE *Prot
26 )
27 {
28 PROTOCOL_ENTRY *ProtEntry;
29 PROTOCOL_NOTIFY *ProtNotify;
30 LIST_ENTRY *Link;
31
32 ProtEntry = Prot->Protocol;
33 for (Link=ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {
34 ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
35 ProtNotify->Function (&ProtEntry->ProtocolID, Prot->Interface, Prot->Handle);
36 }
37 }
38
39 /**
40 Removes Protocol from the protocol list (but not the handle list).
41
42 @param Handle The handle to remove protocol on.
43 @param Protocol GUID of the protocol to be moved
44 @param Interface The interface of the protocol
45
46 @return Protocol Entry
47
48 **/
49 PROTOCOL_INTERFACE *
50 SmmRemoveInterfaceFromProtocol (
51 IN IHANDLE *Handle,
52 IN EFI_GUID *Protocol,
53 IN VOID *Interface
54 )
55 {
56 PROTOCOL_INTERFACE *Prot;
57 PROTOCOL_NOTIFY *ProtNotify;
58 PROTOCOL_ENTRY *ProtEntry;
59 LIST_ENTRY *Link;
60
61 Prot = SmmFindProtocolInterface (Handle, Protocol, Interface);
62 if (Prot != NULL) {
63
64 ProtEntry = Prot->Protocol;
65
66 //
67 // If there's a protocol notify location pointing to this entry, back it up one
68 //
69 for(Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {
70 ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
71
72 if (ProtNotify->Position == &Prot->ByProtocol) {
73 ProtNotify->Position = Prot->ByProtocol.BackLink;
74 }
75 }
76
77 //
78 // Remove the protocol interface entry
79 //
80 RemoveEntryList (&Prot->ByProtocol);
81 }
82
83 return Prot;
84 }
85
86 /**
87 Add a new protocol notification record for the request protocol.
88
89 @param Protocol The requested protocol to add the notify
90 registration
91 @param Function Points to the notification function
92 @param Registration Returns the registration record
93
94 @retval EFI_INVALID_PARAMETER Invalid parameter
95 @retval EFI_SUCCESS Successfully returned the registration record
96 that has been added
97
98 **/
99 EFI_STATUS
100 EFIAPI
101 SmmRegisterProtocolNotify (
102 IN CONST EFI_GUID *Protocol,
103 IN EFI_SMM_NOTIFY_FN Function,
104 OUT VOID **Registration
105 )
106 {
107 PROTOCOL_ENTRY *ProtEntry;
108 PROTOCOL_NOTIFY *ProtNotify;
109 LIST_ENTRY *Link;
110 EFI_STATUS Status;
111
112 if ((Protocol == NULL) || (Function == NULL) || (Registration == NULL)) {
113 return EFI_INVALID_PARAMETER;
114 }
115
116 ProtNotify = NULL;
117
118 //
119 // Get the protocol entry to add the notification too
120 //
121 ProtEntry = SmmFindProtocolEntry ((EFI_GUID *) Protocol, TRUE);
122 if (ProtEntry != NULL) {
123 //
124 // Find whether notification already exist
125 //
126 for (Link = ProtEntry->Notify.ForwardLink;
127 Link != &ProtEntry->Notify;
128 Link = Link->ForwardLink) {
129
130 ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
131 if (CompareGuid (&ProtNotify->Protocol->ProtocolID, Protocol) &&
132 (ProtNotify->Function == Function)) {
133
134 //
135 // Notification already exist
136 //
137 *Registration = ProtNotify;
138
139 return EFI_SUCCESS;
140 }
141 }
142
143 //
144 // Allocate a new notification record
145 //
146 ProtNotify = AllocatePool (sizeof(PROTOCOL_NOTIFY));
147 if (ProtNotify != NULL) {
148 ProtNotify->Signature = PROTOCOL_NOTIFY_SIGNATURE;
149 ProtNotify->Protocol = ProtEntry;
150 ProtNotify->Function = Function;
151 //
152 // Start at the ending
153 //
154 ProtNotify->Position = ProtEntry->Protocols.BackLink;
155
156 InsertTailList (&ProtEntry->Notify, &ProtNotify->Link);
157 }
158 }
159
160 //
161 // Done. If we have a protocol notify entry, then return it.
162 // Otherwise, we must have run out of resources trying to add one
163 //
164 Status = EFI_OUT_OF_RESOURCES;
165 if (ProtNotify != NULL) {
166 *Registration = ProtNotify;
167 Status = EFI_SUCCESS;
168 }
169 return Status;
170 }