]> git.proxmox.com Git - mirror_edk2.git/blame - StdLib/EfiSocketLib/Service.c
Add Socket Libraries.
[mirror_edk2.git] / StdLib / EfiSocketLib / Service.c
CommitLineData
d7ce7006 1/** @file\r
2 Connect to and disconnect from the various network layers\r
3\r
4 Copyright (c) 2011, Intel Corporation\r
5 All rights reserved. This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "Socket.h"\r
16\r
17EFI_TCP4_PROTOCOL * mpEfiTcpClose4 [ 1024 ];\r
18\r
19\r
20/**\r
21 Connect to the network service bindings\r
22\r
23 Walk the network service protocols on the controller handle and\r
24 locate any that are not in use. Create service structures to\r
25 manage the service binding for the socket driver.\r
26\r
27 @param [in] BindingHandle Handle for protocol binding.\r
28 @param [in] Controller Handle of device to work with.\r
29\r
30 @retval EFI_SUCCESS This driver is added to Controller.\r
31 @retval other This driver does not support this device.\r
32\r
33**/\r
34EFI_STATUS\r
35EFIAPI\r
36EslServiceConnect (\r
37 IN EFI_HANDLE BindingHandle,\r
38 IN EFI_HANDLE Controller\r
39 )\r
40{\r
41 BOOLEAN bInUse;\r
42 UINTN LengthInBytes;\r
43 CONST DT_SOCKET_BINDING * pEnd;\r
44 VOID * pJunk;\r
45 VOID * pInterface;\r
46 DT_SERVICE * pService;\r
47 CONST DT_SOCKET_BINDING * pSocketBinding;\r
48 EFI_STATUS Status;\r
49 EFI_TPL TplPrevious;\r
50\r
51 DBG_ENTER ( );\r
52\r
53 //\r
54 // Assume the list is empty\r
55 //\r
56 Status = EFI_UNSUPPORTED;\r
57 bInUse = FALSE;\r
58\r
59 //\r
60 // Walk the list of network connection points\r
61 //\r
62 pSocketBinding = &cEslSocketBinding[0];\r
63 pEnd = &pSocketBinding[ cEslSocketBindingEntries ];\r
64 while ( pEnd > pSocketBinding ) {\r
65 //\r
66 // Determine if the controller supports the network protocol\r
67 //\r
68 Status = gBS->OpenProtocol (\r
69 Controller,\r
70 pSocketBinding->pNetworkBinding,\r
71 &pInterface,\r
72 BindingHandle,\r
73 Controller,\r
74 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
75 );\r
76 if ( !EFI_ERROR ( Status )) {\r
77 //\r
78 // Determine if the socket layer is already connected\r
79 //\r
80 Status = gBS->OpenProtocol (\r
81 Controller,\r
82 (EFI_GUID *)pSocketBinding->pTagGuid,\r
83 &pJunk,\r
84 BindingHandle,\r
85 Controller,\r
86 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
87 );\r
88 if ( EFI_UNSUPPORTED == Status ) {\r
89 //\r
90 // Allocate a service structure since the tag is not present\r
91 //\r
92 LengthInBytes = sizeof ( *pService );\r
93 Status = gBS->AllocatePool (\r
94 EfiRuntimeServicesData,\r
95 LengthInBytes,\r
96 (VOID **) &pService\r
97 );\r
98 if ( !EFI_ERROR ( Status )) {\r
99 DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
100 "0x%08x: Allocate pService, %d bytes\r\n",\r
101 pService,\r
102 LengthInBytes ));\r
103\r
104 //\r
105 // Set the structure signature and service binding\r
106 //\r
107 ZeroMem ( pService, LengthInBytes );\r
108 pService->Signature = SERVICE_SIGNATURE;\r
109 pService->pSocketBinding = pSocketBinding;\r
110 pService->Controller = Controller;\r
111 pService->pInterface = pInterface;\r
112\r
113 //\r
114 // Mark the controller in use\r
115 //\r
116 if ( !bInUse ) {\r
117 Status = gBS->InstallMultipleProtocolInterfaces (\r
118 &Controller,\r
119 &gEfiCallerIdGuid,\r
120 NULL,\r
121 NULL\r
122 );\r
123 if ( !EFI_ERROR ( Status )) {\r
124 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
125 "Installed: gEfiCallerIdGuid on 0x%08x\r\n",\r
126 Controller ));\r
127 bInUse = TRUE;\r
128 }\r
129 else {\r
130 if ( EFI_INVALID_PARAMETER == Status ) {\r
131 Status = EFI_SUCCESS;\r
132 }\r
133 }\r
134 }\r
135 if ( !EFI_ERROR ( Status )) {\r
136 //\r
137 // Mark the network service protocol in use\r
138 //\r
139 Status = gBS->InstallMultipleProtocolInterfaces (\r
140 &Controller,\r
141 pSocketBinding->pTagGuid,\r
142 pService,\r
143 NULL\r
144 );\r
145 if ( !EFI_ERROR ( Status )) {\r
146 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
147 "Installed: %s TagGuid on 0x%08x\r\n",\r
148 pSocketBinding->pName,\r
149 Controller ));\r
150\r
151 //\r
152 // Synchronize with the socket layer\r
153 //\r
154 RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
155\r
156 //\r
157 // Initialize the service\r
158 //\r
159 Status = pSocketBinding->pfnInitialize ( pService );\r
160\r
161 //\r
162 // Release the socket layer synchronization\r
163 //\r
164 RESTORE_TPL ( TplPrevious );\r
165\r
166 //\r
167 // Determine if the initialization was successful\r
168 //\r
169 if ( EFI_ERROR ( Status )) {\r
170 DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
171 "ERROR - Failed to initialize service %s on 0x%08x, Status: %r\r\n",\r
172 pSocketBinding->pName,\r
173 Controller,\r
174 Status ));\r
175\r
176 //\r
177 // Free the network service binding if necessary\r
178 //\r
179 gBS->UninstallMultipleProtocolInterfaces (\r
180 Controller,\r
181 pSocketBinding->pTagGuid,\r
182 pService,\r
183 NULL );\r
184 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
185 "Removed: %s TagGuid from 0x%08x\r\n",\r
186 pSocketBinding->pName,\r
187 Controller ));\r
188 }\r
189 }\r
190 else {\r
191 DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
192 "ERROR - Failed to install %s TagGuid on 0x%08x, Status: %r\r\n",\r
193 pSocketBinding->pName,\r
194 Controller,\r
195 Status ));\r
196 }\r
197\r
198 if ( EFI_ERROR ( Status )) {\r
199 //\r
200 // The controller is no longer in use\r
201 //\r
202 if ( bInUse ) {\r
203 gBS->UninstallMultipleProtocolInterfaces (\r
204 Controller,\r
205 &gEfiCallerIdGuid,\r
206 NULL,\r
207 NULL );\r
208 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
209 "Removed: gEfiCallerIdGuid from 0x%08x\r\n",\r
210 Controller ));\r
211 }\r
212 }\r
213 }\r
214 else {\r
215 DEBUG (( DEBUG_ERROR | DEBUG_INIT,\r
216 "ERROR - Failed to install gEfiCallerIdGuid on 0x%08x, Status: %r\r\n",\r
217 Controller,\r
218 Status ));\r
219 }\r
220\r
221 //\r
222 // Release the service if necessary\r
223 //\r
224 if ( EFI_ERROR ( Status )) {\r
225 gBS->FreePool ( pService );\r
226 DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
227 "0x%08x: Free pService, %d bytes\r\n",\r
228 pService,\r
229 sizeof ( *pService )));\r
230 pService = NULL;\r
231 }\r
232 }\r
233 else {\r
234 DEBUG (( DEBUG_ERROR | DEBUG_INIT,\r
235 "ERROR - Failed service allocation, Status: %r\r\n",\r
236 Status ));\r
237 }\r
238 }\r
239 }\r
240 \r
241 //\r
242 // Set the next network protocol\r
243 //\r
244 pSocketBinding += 1;\r
245 }\r
246 \r
247 //\r
248 // Display the driver start status\r
249 //\r
250 DBG_EXIT_STATUS ( Status );\r
251 return Status;\r
252}\r
253\r
254\r
255/**\r
256 Shutdown the network connections to this controller by removing\r
257 NetworkInterfaceIdentifier protocol and closing the DevicePath\r
258 and PciIo protocols on Controller.\r
259\r
260 @param [in] BindingHandle Handle for protocol binding.\r
261 @param [in] Controller Handle of device to stop driver on.\r
262\r
263 @retval EFI_SUCCESS This driver is removed Controller.\r
264 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
265 @retval other This driver was not removed from this device.\r
266\r
267**/\r
268EFI_STATUS\r
269EFIAPI\r
270EslServiceDisconnect (\r
271 IN EFI_HANDLE BindingHandle,\r
272 IN EFI_HANDLE Controller\r
273 )\r
274{\r
275 CONST DT_SOCKET_BINDING * pEnd;\r
276 DT_SERVICE * pService;\r
277 CONST DT_SOCKET_BINDING * pSocketBinding;\r
278 EFI_STATUS Status;\r
279 EFI_TPL TplPrevious;\r
280 \r
281 DBG_ENTER ( );\r
282\r
283 //\r
284 // Walk the list of network connection points in reverse order\r
285 //\r
286 pEnd = &cEslSocketBinding[0];\r
287 pSocketBinding = &pEnd[ cEslSocketBindingEntries ];\r
288 while ( pEnd < pSocketBinding ) {\r
289 //\r
290 // Set the next network protocol\r
291 //\r
292 pSocketBinding -= 1;\r
293\r
294 //\r
295 // Determine if the driver connected\r
296 //\r
297 Status = gBS->OpenProtocol (\r
298 Controller,\r
299 (EFI_GUID *)pSocketBinding->pTagGuid,\r
300 (VOID **)&pService,\r
301 BindingHandle,\r
302 Controller,\r
303 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
304 );\r
305 if ( !EFI_ERROR ( Status )) {\r
306\r
307 //\r
308 // Synchronize with the socket layer\r
309 //\r
310 RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
311\r
312 //\r
313 // Shutdown the service\r
314 //\r
315 pSocketBinding->pfnShutdown ( pService );\r
316\r
317 //\r
318 // Release the socket layer synchronization\r
319 //\r
320 RESTORE_TPL ( TplPrevious );\r
321\r
322 //\r
323 // Break the driver connection\r
324 //\r
325 Status = gBS->UninstallMultipleProtocolInterfaces (\r
326 Controller,\r
327 pSocketBinding->pTagGuid,\r
328 pService,\r
329 NULL );\r
330 if ( !EFI_ERROR ( Status )) {\r
331 DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
332 "Removed: %s TagGuid from 0x%08x\r\n",\r
333 pSocketBinding->pName,\r
334 Controller ));\r
335 }\r
336 else {\r
337 DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
338 "ERROR - Failed to removed %s TagGuid from 0x%08x, Status: %r\r\n",\r
339 pSocketBinding->pName,\r
340 Controller,\r
341 Status ));\r
342 }\r
343\r
344 //\r
345 // Free the service structure\r
346 //\r
347 Status = gBS->FreePool ( pService );\r
348 if ( !EFI_ERROR ( Status )) {\r
349 DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
350 "0x%08x: Free pService, %d bytes\r\n",\r
351 pService,\r
352 sizeof ( *pService )));\r
353 }\r
354 else {\r
355 DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
356 "ERROR - Failed to free pService 0x%08x, Status: %r\r\n",\r
357 pService,\r
358 Status ));\r
359 }\r
360 pService = NULL;\r
361 }\r
362 }\r
363\r
364 //\r
365 // The controller is no longer in use\r
366 //\r
367 gBS->UninstallMultipleProtocolInterfaces (\r
368 Controller,\r
369 &gEfiCallerIdGuid,\r
370 NULL,\r
371 NULL );\r
372 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
373 "Removed: gEfiCallerIdGuid from 0x%08x\r\n",\r
374 Controller ));\r
375\r
376 //\r
377 // The driver is disconnected from the network controller\r
378 //\r
379 Status = EFI_SUCCESS;\r
380\r
381 //\r
382 // Display the driver start status\r
383 //\r
384 DBG_EXIT_STATUS ( Status );\r
385 return Status;\r
386}\r
387\r
388\r
389\r
390/**\r
391Install the socket service\r
392\r
393@param [in] pImageHandle Address of the image handle\r
394\r
395@retval EFI_SUCCESS Service installed successfully\r
396**/\r
397EFI_STATUS\r
398EFIAPI\r
399EslServiceInstall (\r
400 IN EFI_HANDLE * pImageHandle\r
401 )\r
402{\r
403 EFI_STATUS Status;\r
404\r
405 //\r
406 // Install the socket service binding protocol\r
407 //\r
408 Status = gBS->InstallMultipleProtocolInterfaces (\r
409 pImageHandle,\r
410 &gEfiSocketServiceBindingProtocolGuid,\r
411 &mEslLayer.ServiceBinding,\r
412 NULL\r
413 );\r
414 if ( !EFI_ERROR ( Status )) {\r
415 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
416 "Installed: gEfiSocketServiceBindingProtocolGuid on 0x%08x\r\n",\r
417 *pImageHandle ));\r
418 }\r
419 else {\r
420 DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
421 "ERROR - InstallMultipleProtocolInterfaces failed, Status: %r\r\n",\r
422 Status ));\r
423 }\r
424\r
425 //\r
426 // Return the operation status\r
427 //\r
428 return Status;\r
429}\r
430\r
431\r
432/**\r
433Initialize the service layer\r
434\r
435@param [in] ImageHandle Handle for the image.\r
436\r
437**/\r
438VOID\r
439EFIAPI\r
440EslServiceLoad (\r
441 IN EFI_HANDLE ImageHandle\r
442 )\r
443{\r
444 DT_LAYER * pLayer;\r
445\r
446 //\r
447 // Save the image handle\r
448 //\r
449 pLayer = &mEslLayer;\r
450 pLayer->Signature = LAYER_SIGNATURE;\r
451 pLayer->ImageHandle = ImageHandle;\r
452\r
453 //\r
454 // Initialize the TCP4 close\r
455 //\r
456 pLayer->TcpCloseMax4 = DIM ( mpEfiTcpClose4 );\r
457 pLayer->ppTcpClose4 = mpEfiTcpClose4;\r
458\r
459 //\r
460 // Connect the service binding protocol to the image handle\r
461 //\r
462 pLayer->ServiceBinding.CreateChild = EslSocketCreateChild;\r
463 pLayer->ServiceBinding.DestroyChild = EslSocketDestroyChild;\r
464}\r
465\r
466\r
467/**\r
468Uninstall the socket service\r
469\r
470@param [in] ImageHandle Handle for the image.\r
471\r
472@retval EFI_SUCCESS Service installed successfully\r
473**/\r
474EFI_STATUS\r
475EFIAPI\r
476EslServiceUninstall (\r
477 IN EFI_HANDLE ImageHandle\r
478 )\r
479{\r
480 EFI_STATUS Status;\r
481\r
482 //\r
483 // Install the socket service binding protocol\r
484 //\r
485 Status = gBS->UninstallMultipleProtocolInterfaces (\r
486 ImageHandle,\r
487 &gEfiSocketServiceBindingProtocolGuid,\r
488 &mEslLayer.ServiceBinding,\r
489 NULL\r
490 );\r
491 if ( !EFI_ERROR ( Status )) {\r
492 DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
493 "Removed: gEfiSocketServiceBindingProtocolGuid from 0x%08x\r\n",\r
494 ImageHandle ));\r
495 }\r
496 else {\r
497 DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
498 "ERROR - Failed to remove gEfiSocketServiceBindingProtocolGuid from 0x%08x, Status: %r\r\n",\r
499 ImageHandle,\r
500 Status ));\r
501 }\r
502\r
503 //\r
504 // Return the operation status\r
505 //\r
506 return Status;\r
507}\r
508\r
509\r
510/**\r
511 Shutdown the service layer\r
512\r
513**/\r
514VOID\r
515EFIAPI\r
516EslServiceUnload (\r
517 VOID\r
518 )\r
519{\r
520 DT_LAYER * pLayer;\r
521\r
522 //\r
523 // Undo the work by ServiceLoad\r
524 //\r
525 pLayer = &mEslLayer;\r
526 pLayer->ImageHandle = NULL;\r
527 pLayer->ServiceBinding.CreateChild = NULL;\r
528 pLayer->ServiceBinding.DestroyChild = NULL;\r
529}\r