]> git.proxmox.com Git - mirror_edk2.git/blob - StdLib/SocketDxe/EntryUnload.c
Update the sockets library code
[mirror_edk2.git] / StdLib / SocketDxe / EntryUnload.c
1 /** @file
2 Implement the entry and unload for the socket driver.
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 The following GUID values are only used by the SocketDxe driver. An
20 alternative set of values exists in EfiSocketLib\UseEfiSocketLib.c
21 which an application uses when it links against EfiSocketLib. These
22 two sets of values allow the SocketDxe driver to coexist with socket
23 applications.
24
25 Tag GUID - IPv4 in use by SocketDxe
26 **/
27 CONST EFI_GUID mEslIp4ServiceGuid = {
28 0x4e3a82e6, 0xe43f, 0x460a, { 0x86, 0x6e, 0x9b, 0x5a, 0xab, 0x80, 0x44, 0x48 }
29 };
30
31
32 /**
33 Tag GUID - TCPv4 in use by SocketDxe
34 **/
35 CONST EFI_GUID mEslTcp4ServiceGuid = {
36 0x4dcaab0a, 0x1990, 0x4352, { 0x8d, 0x2f, 0x2d, 0x8f, 0x13, 0x55, 0x98, 0xa5 }
37 };
38
39
40 /**
41 Tag GUID - UDPv4 in use by SocketDxe
42 **/
43 CONST EFI_GUID mEslUdp4ServiceGuid = {
44 0x43a110ce, 0x9ccd, 0x402b, { 0x8c, 0x29, 0x4a, 0x6d, 0x8a, 0xf7, 0x79, 0x90 }
45 };
46
47
48 /**
49 Socket driver unload routine.
50
51 @param [in] ImageHandle Handle for the image.
52
53 @retval EFI_SUCCESS Image may be unloaded
54
55 **/
56 EFI_STATUS
57 EFIAPI
58 DriverUnload (
59 IN EFI_HANDLE ImageHandle
60 )
61 {
62 UINTN BufferSize;
63 UINTN Index;
64 UINTN Max;
65 EFI_HANDLE * pHandle;
66 EFI_STATUS Status;
67
68 //
69 // Determine which devices are using this driver
70 //
71 BufferSize = 0;
72 pHandle = NULL;
73 Status = gBS->LocateHandle (
74 ByProtocol,
75 &gEfiCallerIdGuid,
76 NULL,
77 &BufferSize,
78 NULL );
79 if ( EFI_BUFFER_TOO_SMALL == Status ) {
80 for ( ; ; ) {
81 //
82 // One or more block IO devices are present
83 //
84 Status = gBS->AllocatePool (
85 EfiRuntimeServicesData,
86 BufferSize,
87 (VOID **) &pHandle
88 );
89 if ( EFI_ERROR ( Status )) {
90 DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
91 "Insufficient memory, failed handle buffer allocation\r\n" ));
92 break;
93 }
94
95 //
96 // Locate the block IO devices
97 //
98 Status = gBS->LocateHandle (
99 ByProtocol,
100 &gEfiCallerIdGuid,
101 NULL,
102 &BufferSize,
103 pHandle );
104 if ( EFI_ERROR ( Status )) {
105 //
106 // Error getting handles
107 //
108 DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
109 "Failure getting Telnet handles\r\n" ));
110 break;
111 }
112
113 //
114 // Remove any use of the driver
115 //
116 Max = BufferSize / sizeof ( pHandle[ 0 ]);
117 for ( Index = 0; Max > Index; Index++ ) {
118 Status = DriverStop ( &mDriverBinding,
119 pHandle[ Index ],
120 0,
121 NULL );
122 if ( EFI_ERROR ( Status )) {
123 DEBUG (( DEBUG_WARN | DEBUG_INIT | DEBUG_INFO,
124 "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle[ Index ]));
125 break;
126 }
127 }
128 break;
129 }
130 }
131 else {
132 if ( EFI_NOT_FOUND == Status ) {
133 //
134 // No devices were found
135 //
136 Status = EFI_SUCCESS;
137 }
138 }
139
140 //
141 // Free the handle array
142 //
143 if ( NULL != pHandle ) {
144 gBS->FreePool ( pHandle );
145 }
146
147 //
148 // Done with the socket layer
149 //
150 if ( !EFI_ERROR ( Status )) {
151 Status = EslDxeUninstall ( ImageHandle );
152 if ( !EFI_ERROR ( Status )) {
153 //
154 // Remove the protocols installed by the EntryPoint routine.
155 //
156 Status = gBS->UninstallMultipleProtocolInterfaces (
157 ImageHandle,
158 &gEfiDriverBindingProtocolGuid,
159 &mDriverBinding,
160 &gEfiComponentNameProtocolGuid,
161 &mComponentName,
162 &gEfiComponentName2ProtocolGuid,
163 &mComponentName2,
164 NULL
165 );
166 if ( !EFI_ERROR ( Status )) {
167 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
168 "Removed: gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
169 ImageHandle ));
170 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
171 "Removed: gEfiComponentNameProtocolGuid from 0x%08x\r\n",
172 ImageHandle ));
173 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
174 "Removed: gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
175 ImageHandle ));
176 }
177 else {
178 DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
179 "ERROR - Failed to remove gEfiDriverBindingProtocolGuid from 0x%08x, Status: %r\r\n",
180 ImageHandle,
181 Status ));
182 }
183 }
184 }
185
186 //
187 // Disconnect the network services
188 //
189 if ( !EFI_ERROR ( Status )) {
190 EslServiceUnload ( );
191 }
192
193 //
194 // Return the unload status
195 //
196 return Status;
197 }
198
199
200 /**
201 Socket driver entry point.
202
203 @param [in] ImageHandle Handle for the image.
204 @param [in] pSystemTable Address of the system table.
205
206 @retval EFI_SUCCESS Image successfully loaded.
207
208 **/
209 EFI_STATUS
210 EFIAPI
211 EntryPoint (
212 IN EFI_HANDLE ImageHandle,
213 IN EFI_SYSTEM_TABLE * pSystemTable
214 )
215 {
216 EFI_LOADED_IMAGE_PROTOCOL * pLoadedImage;
217 EFI_STATUS Status;
218
219 DBG_ENTER ( );
220
221 //
222 // Display the image handle
223 //
224 DEBUG (( DEBUG_INFO,
225 "ImageHandle: 0x%08x\r\n",
226 ImageHandle ));
227
228 //
229 // Enable unload support
230 //
231 Status = gBS->HandleProtocol (
232 gImageHandle,
233 &gEfiLoadedImageProtocolGuid,
234 (VOID **)&pLoadedImage
235 );
236 if (!EFI_ERROR (Status)) {
237 pLoadedImage->Unload = DriverUnload;
238
239 //
240 // Add the driver to the list of drivers
241 //
242 Status = EfiLibInstallDriverBindingComponentName2 (
243 ImageHandle,
244 pSystemTable,
245 &mDriverBinding,
246 ImageHandle,
247 &mComponentName,
248 &mComponentName2
249 );
250 if ( !EFI_ERROR ( Status )) {
251 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
252 "Installed: gEfiDriverBindingProtocolGuid on 0x%08x\r\n",
253 ImageHandle ));
254 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
255 "Installed: gEfiComponentNameProtocolGuid on 0x%08x\r\n",
256 ImageHandle ));
257 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
258 "Installed: gEfiComponentName2ProtocolGuid on 0x%08x\r\n",
259 ImageHandle ));
260
261 //
262 // Initialize the service layer
263 //
264 EslServiceLoad ( ImageHandle );
265
266 //
267 // Make the socket serivces available to other drivers
268 // and applications
269 //
270 Status = EslDxeInstall ( &ImageHandle );
271 if ( EFI_ERROR ( Status )) {
272 //
273 // Disconnect from the network
274 //
275 EslServiceUnload ( );
276
277 //
278 // Remove the driver bindings
279 //
280 gBS->UninstallMultipleProtocolInterfaces (
281 ImageHandle,
282 &gEfiDriverBindingProtocolGuid,
283 &mDriverBinding,
284 &gEfiComponentNameProtocolGuid,
285 &mComponentName,
286 &gEfiComponentName2ProtocolGuid,
287 &mComponentName2,
288 NULL
289 );
290 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
291 "Removed: gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
292 ImageHandle ));
293 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
294 "Removed: gEfiComponentNameProtocolGuid from 0x%08x\r\n",
295 ImageHandle ));
296 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
297 "Removed: gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
298 ImageHandle ));
299 }
300 }
301 else {
302 DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
303 "ERROR - EfiLibInstallDriverBindingComponentName2 failed, Status: %r\r\n",
304 Status ));
305 }
306 }
307 DBG_EXIT_STATUS ( Status );
308 return Status;
309 }
310
311
312 /**
313 Socket layer's service binding protocol delcaration.
314 **/
315 CONST EFI_SERVICE_BINDING_PROTOCOL mEfiServiceBinding = {
316 EslDxeCreateChild,
317 EslDxeDestroyChild
318 };
319
320
321 /**
322 The following entries disable the constructor and destructor
323 for the SocketDxe driver. Note that socket applications linking
324 against EfiSocketLib use different redirection.
325 **/
326 PFN_ESL_xSTRUCTOR mpfnEslConstructor = NULL; ///< No EfiSocketLib constructor needed for SocketDxe
327 PFN_ESL_xSTRUCTOR mpfnEslDestructor = NULL; ///< No EfiSocketLib destructor needed for SocketDxe