1/** @file
2  SocketDxe support routines
3
4  Copyright (c) 2011, Intel Corporation
5  All rights reserved. This program and the accompanying materials
6  are licensed and made available under the terms and conditions of the BSD License
7  which accompanies this 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 "Socket.h"
16
17
18/**
19  Creates a child handle and installs gEfiSocketProtocolGuid.
20
21  This routine creates a child handle for the socket driver and
22  installs the ::gEfiSocketProtocolGuid on that handle with a pointer
23  to the ::EFI_SOCKET_PROTOCOL structure address.
24
25  This routine is called by ::EslServiceGetProtocol in UseSocketDxe
26  when the socket application is linked with UseSocketDxe.
27
28  @param [in] pThis        Address of the EFI_SERVICE_BINDING_PROTOCOL structure.
29  @param [in] pChildHandle Pointer to the handle of the child to create. If it is NULL,
30                           then a new handle is created. If it is a pointer to an existing UEFI handle,
31                           then the protocol is added to the existing UEFI handle.
32
33  @retval EFI_SUCCESS           The protocol was added to ChildHandle.
34  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
35  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to create
36                                the child
37  @retval other                 The child handle was not created
38
39**/
40EFI_STATUS
41EFIAPI
42EslDxeCreateChild (
43  IN     EFI_SERVICE_BINDING_PROTOCOL * pThis,
44  IN OUT EFI_HANDLE * pChildHandle
45  )
46{
47  ESL_SOCKET * pSocket;
48  EFI_STATUS Status;
49
50  DBG_ENTER ( );
51
52  //
53  //  Create a socket structure
54  //
55  Status = EslSocketAllocate ( pChildHandle,
56                               DEBUG_SOCKET,
57                               &pSocket );
58
59  //
60  //  Return the operation status
61  //
62  DBG_EXIT_STATUS ( Status );
63  return Status;
64}
65
66
67/**
68  Removes gEfiSocketProtocolGuid and destroys the child handle.
69
70  This routine uninstalls ::gEfiSocketProtocolGuid from the child handle
71  and destroys the child handle if necessary.
72
73  This routine is called from ???.
74
75  @param [in] pThis       Address of the EFI_SERVICE_BINDING_PROTOCOL structure.
76  @param [in] ChildHandle Handle of the child to destroy
77
78  @retval EFI_SUCCESS           The protocol was removed from ChildHandle.
79  @retval EFI_UNSUPPORTED       ChildHandle does not support the protocol that is being removed.
80  @retval EFI_INVALID_PARAMETER Child handle is not a valid UEFI Handle.
81  @retval EFI_ACCESS_DENIED     The protocol could not be removed from the ChildHandle
82                                because its services are being used.
83  @retval other                 The child handle was not destroyed
84
85**/
86EFI_STATUS
87EFIAPI
88EslDxeDestroyChild (
89  IN EFI_SERVICE_BINDING_PROTOCOL * pThis,
90  IN EFI_HANDLE ChildHandle
91  )
92{
93  ESL_LAYER * pLayer;
94  EFI_SOCKET_PROTOCOL * pSocketProtocol;
95  EFI_STATUS Status;
96
97  DBG_ENTER ( );
98
99  //
100  //  Locate the socket control structure
101  //
102  pLayer = &mEslLayer;
103  Status = gBS->OpenProtocol (
104                  ChildHandle,
105                  &gEfiSocketProtocolGuid,
106                  (VOID **)&pSocketProtocol,
107                  pLayer->ImageHandle,
108                  NULL,
109                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
110                  );
111  if ( !EFI_ERROR ( Status )) {
112    //
113    //  Free the socket resources
114    //
115    Status = EslSocketFree ( pSocketProtocol, NULL );
116  }
117  else {
118    DEBUG (( DEBUG_ERROR,
119              "ERROR - Failed to open socket protocol on 0x%08x, Status; %r\r\n",
120              ChildHandle,
121              Status ));
122  }
123
124  //
125  //  Return the operation status
126  //
127  DBG_EXIT_STATUS ( Status );
128  return Status;
129}
130
131
132/**
133Install the socket service
134
135This routine installs the ::gEfiSocketServiceBindingProtocolGuid
136on the SocketDxe image handle to announce the availability
137of the socket layer to the rest of EFI.
138
139SocketDxe's EntryPoint routine calls this routine to
140make the socket layer available.
141
142@param [in] pImageHandle      Address of the image handle
143
144@retval EFI_SUCCESS     Service installed successfully
145**/
146EFI_STATUS
147EFIAPI
148EslDxeInstall (
149  IN EFI_HANDLE * pImageHandle
150  )
151{
152  EFI_STATUS Status;
153
154  //
155  //  Install the socket service binding protocol
156  //
157  Status = gBS->InstallMultipleProtocolInterfaces (
158                  pImageHandle,
159                  &gEfiSocketServiceBindingProtocolGuid,
160                  mEslLayer.pServiceBinding,
161                  NULL
162                  );
163  if ( !EFI_ERROR ( Status )) {
164    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
165              "Installed: gEfiSocketServiceBindingProtocolGuid on   0x%08x\r\n",
166              *pImageHandle ));
167  }
168  else {
169    DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
170              "ERROR - InstallMultipleProtocolInterfaces failed, Status: %r\r\n",
171              Status ));
172  }
173
174  //
175  //  Return the operation status
176  //
177  return Status;
178}
179
180
181/**
182Uninstall the socket service
183
184This routine removes the gEfiSocketServiceBindingProtocolGuid from
185the SocketDxe image handle to notify EFI that the socket layer
186is no longer available.
187
188SocketDxe's DriverUnload routine calls this routine to remove the
189socket layer.
190
191@param [in] ImageHandle       Handle for the image.
192
193@retval EFI_SUCCESS     Service installed successfully
194**/
195EFI_STATUS
196EFIAPI
197EslDxeUninstall (
198  IN EFI_HANDLE ImageHandle
199  )
200{
201  EFI_STATUS Status;
202
203  //
204  //  Install the socket service binding protocol
205  //
206  Status = gBS->UninstallMultipleProtocolInterfaces (
207              ImageHandle,
208              &gEfiSocketServiceBindingProtocolGuid,
209              mEslLayer.pServiceBinding,
210              NULL
211              );
212  if ( !EFI_ERROR ( Status )) {
213    DEBUG (( DEBUG_POOL | DEBUG_INIT,
214                "Removed:   gEfiSocketServiceBindingProtocolGuid from 0x%08x\r\n",
215                ImageHandle ));
216  }
217  else {
218    DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
219                "ERROR - Failed to remove gEfiSocketServiceBindingProtocolGuid from 0x%08x, Status: %r\r\n",
220                ImageHandle,
221                Status ));
222  }
223
224  //
225  //  Return the operation status
226  //
227  return Status;
228}
229