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