• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   This is service binding for Hash driver.
3 
4 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 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 "Driver.h"
16 
17 EFI_SERVICE_BINDING_PROTOCOL    mHash2ServiceBindingProtocol = {
18   Hash2ServiceBindingCreateChild,
19   Hash2ServiceBindingDestroyChild
20 };
21 
22 /**
23   Creates a child handle with a set of I/O services.
24 
25   @param[in]       This              Protocol instance pointer.
26   @param[in, out]  ChildHandle       Pointer to the handle of the child to create. If
27                                      it is NULL, then a new handle is created. If
28                                      it is not NULL, then the I/O services are added
29                                      to the existing child handle.
30 
31   @retval EFI_SUCCES                 The protocol was added to ChildHandle.
32   @retval EFI_INVALID_PARAMETER      ChildHandle is NULL.
33   @retval EFI_OUT_OF_RESOURCES       There are not enough resources available to
34                                      create the child.
35   @retval Others                     The child handle was not created.
36 
37 **/
38 EFI_STATUS
39 EFIAPI
Hash2ServiceBindingCreateChild(IN EFI_SERVICE_BINDING_PROTOCOL * This,IN OUT EFI_HANDLE * ChildHandle)40 Hash2ServiceBindingCreateChild (
41   IN     EFI_SERVICE_BINDING_PROTOCOL    *This,
42   IN OUT EFI_HANDLE                      *ChildHandle
43   )
44 {
45   EFI_STATUS          Status;
46   HASH2_SERVICE_DATA  *Hash2ServiceData;
47   HASH2_INSTANCE_DATA *Instance;
48   EFI_TPL             OldTpl;
49 
50   if ((This == NULL) || (ChildHandle == NULL)) {
51     return EFI_INVALID_PARAMETER;
52   }
53 
54   Hash2ServiceData = HASH2_SERVICE_DATA_FROM_THIS (This);
55 
56   //
57   // Allocate buffer for the new instance.
58   //
59   Instance = AllocateZeroPool (sizeof (HASH2_INSTANCE_DATA));
60   if (Instance == NULL) {
61     return EFI_OUT_OF_RESOURCES;
62   }
63 
64   //
65   // Init the instance data.
66   //
67   Instance->Signature = HASH2_INSTANCE_DATA_SIGNATURE;
68   CopyMem (&Instance->Hash2Protocol, &mHash2Protocol, sizeof (Instance->Hash2Protocol));
69   Instance->Hash2ServiceData = Hash2ServiceData;
70 
71   Status = gBS->InstallMultipleProtocolInterfaces (
72                   ChildHandle,
73                   &gEfiHash2ProtocolGuid,
74                   &Instance->Hash2Protocol,
75                   NULL
76                   );
77   if (EFI_ERROR (Status)) {
78     FreePool (Instance);
79     return Status;
80   }
81 
82   Instance->Handle = *ChildHandle;
83 
84   //
85   // Add the child instance into ChildrenList.
86   //
87   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
88 
89   InsertTailList (&Hash2ServiceData->ChildrenList, &Instance->InstEntry);
90 
91   gBS->RestoreTPL (OldTpl);
92 
93   return Status;
94 }
95 
96 
97 /**
98   Destroys a child handle with a set of I/O services.
99 
100   The DestroyChild() function does the opposite of CreateChild(). It removes a
101   protocol that was installed by CreateChild() from ChildHandle. If the removed
102   protocol is the last protocol on ChildHandle, then ChildHandle is destroyed.
103 
104   @param[in]  This               Pointer to the EFI_SERVICE_BINDING_PROTOCOL
105                                  instance.
106   @param[in]  ChildHandle        Handle of the child to destroy.
107 
108   @retval EFI_SUCCES             The protocol was removed from ChildHandle.
109   @retval EFI_UNSUPPORTED        ChildHandle does not support the protocol that
110                                  is being removed.
111   @retval EFI_INVALID_PARAMETER  ChildHandle is NULL.
112   @retval EFI_ACCESS_DENIED      The protocol could not be removed from the
113                                  ChildHandle because its services are being
114                                  used.
115   @retval Others                 The child handle was not destroyed.
116 
117 **/
118 EFI_STATUS
119 EFIAPI
Hash2ServiceBindingDestroyChild(IN EFI_SERVICE_BINDING_PROTOCOL * This,IN EFI_HANDLE ChildHandle)120 Hash2ServiceBindingDestroyChild (
121   IN EFI_SERVICE_BINDING_PROTOCOL    *This,
122   IN EFI_HANDLE                      ChildHandle
123   )
124 {
125   EFI_STATUS                     Status;
126   HASH2_SERVICE_DATA             *Hash2ServiceData;
127   EFI_HASH2_PROTOCOL             *Hash2Protocol;
128   HASH2_INSTANCE_DATA            *Instance;
129   EFI_TPL                        OldTpl;
130   LIST_ENTRY                     *Entry;
131 
132   if ((This == NULL) || (ChildHandle == NULL)) {
133     return EFI_INVALID_PARAMETER;
134   }
135 
136   Hash2ServiceData = HASH2_SERVICE_DATA_FROM_THIS (This);
137 
138   //
139   // Check if this ChildHandle is valid
140   //
141   Instance = NULL;
142   for(Entry = (&Hash2ServiceData->ChildrenList)->ForwardLink; Entry != (&Hash2ServiceData->ChildrenList); Entry = Entry->ForwardLink) {
143     Instance = HASH2_INSTANCE_DATA_FROM_LINK (Entry);
144     if (Instance->Handle == ChildHandle) {
145       break;
146     } else {
147       Instance = NULL;
148     }
149   }
150   if (Instance == NULL) {
151     DEBUG ((EFI_D_ERROR, "Hash2ServiceBindingDestroyChild - Invalid handle\n"));
152     return EFI_UNSUPPORTED;
153   }
154 
155   //
156   // Get HashProtocol
157   //
158   Status = gBS->HandleProtocol (
159                   ChildHandle,
160                   &gEfiHash2ProtocolGuid,
161                   (VOID **)&Hash2Protocol
162                   );
163   if (EFI_ERROR (Status)) {
164     return Status;
165   }
166 
167   ASSERT (Hash2Protocol == &Instance->Hash2Protocol);
168 
169   //
170   // Uninstall the Hash protocol.
171   //
172   Status = gBS->UninstallMultipleProtocolInterfaces (
173                   ChildHandle,
174                   &gEfiHash2ProtocolGuid,
175                   &Instance->Hash2Protocol,
176                   NULL
177                   );
178   if (EFI_ERROR (Status)) {
179     return Status;
180   }
181 
182   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
183 
184   //
185   // Remove this instance from the ChildrenList.
186   //
187   RemoveEntryList (&Instance->InstEntry);
188 
189   gBS->RestoreTPL (OldTpl);
190 
191   FreePool (Instance);
192 
193   return Status;
194 }
195 
196 /**
197   The entry point for Hash driver which installs the service binding protocol.
198 
199   @param[in]  ImageHandle  The image handle of the driver.
200   @param[in]  SystemTable  The system table.
201 
202   @retval EFI_SUCCES       The service binding protocols is successfully installed.
203   @retval Others           Other errors as indicated.
204 
205 **/
206 EFI_STATUS
207 EFIAPI
Hash2DriverEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)208 Hash2DriverEntryPoint (
209   IN EFI_HANDLE          ImageHandle,
210   IN EFI_SYSTEM_TABLE    *SystemTable
211   )
212 {
213   EFI_STATUS         Status;
214   HASH2_SERVICE_DATA *Hash2ServiceData;
215 
216   //
217   // Initialize the Hash Service Data.
218   //
219   Hash2ServiceData = AllocateZeroPool (sizeof (HASH2_SERVICE_DATA));
220   if (Hash2ServiceData == NULL) {
221     return EFI_OUT_OF_RESOURCES;
222   }
223 
224   Hash2ServiceData->Signature     = HASH2_SERVICE_DATA_SIGNATURE;
225   CopyMem (&Hash2ServiceData->ServiceBinding, &mHash2ServiceBindingProtocol, sizeof (EFI_SERVICE_BINDING_PROTOCOL));
226   InitializeListHead (&Hash2ServiceData->ChildrenList);
227 
228   //
229   // Install the HASH Service Binding Protocol
230   //
231   Status = gBS->InstallMultipleProtocolInterfaces (
232                   &Hash2ServiceData->ServiceHandle,
233                   &gEfiHash2ServiceBindingProtocolGuid,
234                   &Hash2ServiceData->ServiceBinding,
235                   NULL
236                   );
237   if (EFI_ERROR (Status)) {
238     FreePool (Hash2ServiceData);
239   }
240 
241   return Status;
242 }