]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c
MdeModulePkg: Clean up source files
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Tcp4Dxe / Tcp4Driver.c
CommitLineData
8a67d61d 1/** @file\r
dab714aa 2 Tcp driver function.\r
8a67d61d 3\r
d1102dba 4Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
e5eed7d3 5This program and the accompanying materials\r
8a67d61d 6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
dfc1f033 8http://opensource.org/licenses/bsd-license.php<BR>\r
8a67d61d 9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
8a67d61d 13**/\r
14\r
15#include "Tcp4Main.h"\r
16\r
17\r
120db52c 18UINT16 mTcp4RandomPort;\r
83cbd279 19extern EFI_COMPONENT_NAME_PROTOCOL gTcp4ComponentName;\r
20extern EFI_COMPONENT_NAME2_PROTOCOL gTcp4ComponentName2;\r
216f7970 21extern EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable;\r
8a67d61d 22\r
23TCP4_HEARTBEAT_TIMER mTcp4Timer = {\r
24 NULL,\r
25 0\r
26};\r
27\r
28EFI_TCP4_PROTOCOL mTcp4ProtocolTemplate = {\r
29 Tcp4GetModeData,\r
30 Tcp4Configure,\r
31 Tcp4Routes,\r
32 Tcp4Connect,\r
33 Tcp4Accept,\r
34 Tcp4Transmit,\r
35 Tcp4Receive,\r
36 Tcp4Close,\r
37 Tcp4Cancel,\r
38 Tcp4Poll\r
39};\r
40\r
41SOCK_INIT_DATA mTcp4DefaultSockData = {\r
f6b7393c 42 SockStream,\r
43 0,\r
8a67d61d 44 NULL,\r
45 TCP_BACKLOG,\r
46 TCP_SND_BUF_SIZE,\r
47 TCP_RCV_BUF_SIZE,\r
48 &mTcp4ProtocolTemplate,\r
4f6e31e4 49 Tcp4CreateSocketCallback,\r
50 Tcp4DestroySocketCallback,\r
51 NULL,\r
52 NULL,\r
53 0,\r
8a67d61d 54 Tcp4Dispatcher,\r
55 NULL,\r
56};\r
57\r
58EFI_DRIVER_BINDING_PROTOCOL mTcp4DriverBinding = {\r
59 Tcp4DriverBindingSupported,\r
60 Tcp4DriverBindingStart,\r
61 Tcp4DriverBindingStop,\r
62 0xa,\r
63 NULL,\r
64 NULL\r
65};\r
66\r
67EFI_SERVICE_BINDING_PROTOCOL mTcp4ServiceBinding = {\r
68 Tcp4ServiceBindingCreateChild,\r
69 Tcp4ServiceBindingDestroyChild\r
70};\r
71\r
72\r
73/**\r
74 Create and start the heartbeat timer for TCP driver.\r
75\r
8a67d61d 76 @retval EFI_SUCCESS The timer is successfully created and started.\r
77 @retval other The timer is not created.\r
78\r
79**/\r
8a67d61d 80EFI_STATUS\r
81Tcp4CreateTimer (\r
82 VOID\r
83 )\r
84{\r
85 EFI_STATUS Status;\r
86\r
87 Status = EFI_SUCCESS;\r
88\r
89 if (mTcp4Timer.RefCnt == 0) {\r
90\r
91 Status = gBS->CreateEvent (\r
92 EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
e48e37fc 93 TPL_NOTIFY,\r
8a67d61d 94 TcpTicking,\r
95 NULL,\r
96 &mTcp4Timer.TimerEvent\r
97 );\r
98 if (!EFI_ERROR (Status)) {\r
99\r
100 Status = gBS->SetTimer (\r
101 mTcp4Timer.TimerEvent,\r
102 TimerPeriodic,\r
103 (UINT64) (TICKS_PER_SECOND / TCP_TICK_HZ)\r
104 );\r
105 }\r
106 }\r
107\r
108 if (!EFI_ERROR (Status)) {\r
109\r
110 mTcp4Timer.RefCnt++;\r
111 }\r
112\r
113 return Status;\r
114}\r
115\r
116\r
117/**\r
118 Stop and destroy the heartbeat timer for TCP driver.\r
d1102dba 119\r
8a67d61d 120**/\r
8a67d61d 121VOID\r
120db52c 122Tcp4DestroyTimer (\r
123 VOID\r
124 )\r
8a67d61d 125{\r
126 ASSERT (mTcp4Timer.RefCnt > 0);\r
127\r
128 mTcp4Timer.RefCnt--;\r
129\r
130 if (mTcp4Timer.RefCnt > 0) {\r
131 return;\r
132 }\r
133\r
134 gBS->SetTimer (mTcp4Timer.TimerEvent, TimerCancel, 0);\r
135 gBS->CloseEvent (mTcp4Timer.TimerEvent);\r
136 mTcp4Timer.TimerEvent = NULL;\r
137}\r
138\r
216f7970 139/**\r
140 Callback function which provided by user to remove one node in NetDestroyLinkList process.\r
d1102dba 141\r
216f7970 142 @param[in] Entry The entry to be removed.\r
143 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.\r
144\r
145 @retval EFI_SUCCESS The entry has been removed successfully.\r
146 @retval Others Fail to remove the entry.\r
147\r
148**/\r
149EFI_STATUS\r
1f7eb561 150EFIAPI\r
216f7970 151Tcp4DestroyChildEntryInHandleBuffer (\r
152 IN LIST_ENTRY *Entry,\r
153 IN VOID *Context\r
1f7eb561 154 )\r
216f7970 155{\r
156 SOCKET *Sock;\r
157 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
158 UINTN NumberOfChildren;\r
159 EFI_HANDLE *ChildHandleBuffer;\r
160\r
161 if (Entry == NULL || Context == NULL) {\r
162 return EFI_INVALID_PARAMETER;\r
163 }\r
164\r
165 Sock = NET_LIST_USER_STRUCT_S (Entry, SOCKET, Link, SOCK_SIGNATURE);\r
166 ServiceBinding = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;\r
167 NumberOfChildren = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;\r
168 ChildHandleBuffer = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;\r
169\r
170 if (!NetIsInHandleBuffer (Sock->SockHandle, NumberOfChildren, ChildHandleBuffer)) {\r
171 return EFI_SUCCESS;\r
172 }\r
173\r
174 return ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);\r
175}\r
176\r
85511ddf 177/**\r
120db52c 178 The entry point for Tcp4 driver, used to install Tcp4 driver on the ImageHandle.\r
85511ddf 179\r
180 @param ImageHandle The firmware allocated handle for this\r
181 driver image.\r
182 @param SystemTable Pointer to the EFI system table.\r
183\r
184 @retval EFI_SUCCESS Driver loaded.\r
185 @retval other Driver not loaded.\r
8a67d61d 186\r
85511ddf 187**/\r
8a67d61d 188EFI_STATUS\r
189EFIAPI\r
190Tcp4DriverEntryPoint (\r
191 IN EFI_HANDLE ImageHandle,\r
192 IN EFI_SYSTEM_TABLE *SystemTable\r
193 )\r
8a67d61d 194{\r
195 EFI_STATUS Status;\r
196 UINT32 Seed;\r
197\r
198 //\r
199 // Install the TCP4 Driver Binding Protocol\r
200 //\r
83cbd279 201 Status = EfiLibInstallDriverBindingComponentName2 (\r
8a67d61d 202 ImageHandle,\r
203 SystemTable,\r
204 &mTcp4DriverBinding,\r
205 ImageHandle,\r
206 &gTcp4ComponentName,\r
83cbd279 207 &gTcp4ComponentName2\r
8a67d61d 208 );\r
da1d0201 209 ASSERT_EFI_ERROR (Status);\r
8a67d61d 210 //\r
211 // Initialize ISS and random port.\r
212 //\r
213 Seed = NetRandomInitSeed ();\r
214 mTcpGlobalIss = NET_RANDOM (Seed) % mTcpGlobalIss;\r
120db52c 215 mTcp4RandomPort = (UINT16) (TCP4_PORT_KNOWN +\r
4eb65aff 216 (UINT16) (NET_RANDOM(Seed) % TCP4_PORT_KNOWN));\r
8a67d61d 217\r
218 return Status;\r
219}\r
220\r
221\r
222/**\r
dfc1f033 223 Tests to see if this driver supports a given controller.\r
d1102dba
LG
224\r
225 If a child device is provided, it further tests to see if this driver supports\r
dfc1f033 226 creating a handle for the specified child device.\r
227\r
228 @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
d1102dba
LG
229 @param ControllerHandle The handle of the controller to test. This handle\r
230 must support a protocol interface that supplies\r
dfc1f033 231 an I/O abstraction to the driver.\r
d1102dba 232 @param RemainingDevicePath A pointer to the remaining portion of a device path.\r
dfc1f033 233 This parameter is ignored by device drivers, and is optional for bus drivers.\r
234\r
235\r
236 @retval EFI_SUCCESS The device specified by ControllerHandle and\r
d1102dba 237 RemainingDevicePath is supported by the driver\r
dfc1f033 238 specified by This.\r
239 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and\r
d1102dba 240 RemainingDevicePath is already being managed by\r
dfc1f033 241 the driver specified by This.\r
242 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and\r
d1102dba
LG
243 RemainingDevicePath is already being managed by a\r
244 different driver or an application that requires\r
dfc1f033 245 exclusive access.\r
246 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and\r
d1102dba 247 RemainingDevicePath is not supported by the driver\r
dfc1f033 248 specified by This.\r
d1102dba 249\r
8a67d61d 250**/\r
251EFI_STATUS\r
252EFIAPI\r
253Tcp4DriverBindingSupported (\r
120db52c 254 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
8a67d61d 255 IN EFI_HANDLE ControllerHandle,\r
120db52c 256 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
8a67d61d 257 )\r
258{\r
259 EFI_STATUS Status;\r
260\r
261 //\r
262 // Test for the Tcp4ServiceBinding Protocol\r
263 //\r
264 Status = gBS->OpenProtocol (\r
265 ControllerHandle,\r
266 &gEfiTcp4ServiceBindingProtocolGuid,\r
267 NULL,\r
268 This->DriverBindingHandle,\r
269 ControllerHandle,\r
270 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
271 );\r
272 if (!EFI_ERROR (Status)) {\r
273 return EFI_ALREADY_STARTED;\r
274 }\r
275\r
276 //\r
277 // Test for the Ip4 Protocol\r
278 //\r
279 Status = gBS->OpenProtocol (\r
280 ControllerHandle,\r
281 &gEfiIp4ServiceBindingProtocolGuid,\r
282 NULL,\r
283 This->DriverBindingHandle,\r
284 ControllerHandle,\r
285 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
286 );\r
287\r
288 return Status;\r
289}\r
290\r
291\r
292/**\r
d1102dba
LG
293 Start this driver on ControllerHandle.\r
294\r
295 The Start() function is designed to be invoked from the EFI boot service\r
296 ConnectController(). As a result, much of the error checking on the parameters\r
297 to Start() has been moved into this common boot service. It is legal to call\r
298 Start() from other locations, but the following calling restrictions must be\r
dfc1f033 299 followed or the system behavior will not be deterministic.\r
300 1. ControllerHandle must be a valid EFI_HANDLE.\r
d1102dba 301 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally\r
dfc1f033 302 aligned EFI_DEVICE_PATH_PROTOCOL.\r
d1102dba
LG
303 3. Prior to calling Start(), the Supported() function for the driver specified\r
304 by This must have been called with the same calling parameters, and Supported()\r
dfc1f033 305 must have returned EFI_SUCCESS.\r
306\r
307 @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
d1102dba
LG
308 @param ControllerHandle The handle of the controller to start. This handle\r
309 must support a protocol interface that supplies\r
dfc1f033 310 an I/O abstraction to the driver.\r
d1102dba
LG
311 @param RemainingDevicePath A pointer to the remaining portion of a device path.\r
312 This parameter is ignored by device drivers, and is\r
dfc1f033 313 optional for bus drivers.\r
314\r
315 @retval EFI_SUCCESS The device was started.\r
316 @retval EFI_ALREADY_STARTED The device could not be started due to a device error.\r
d1102dba 317 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack\r
dfc1f033 318 of resources.\r
8a67d61d 319\r
320**/\r
321EFI_STATUS\r
322EFIAPI\r
323Tcp4DriverBindingStart (\r
120db52c 324 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
8a67d61d 325 IN EFI_HANDLE ControllerHandle,\r
120db52c 326 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
8a67d61d 327 )\r
328{\r
329 EFI_STATUS Status;\r
330 TCP4_SERVICE_DATA *TcpServiceData;\r
331 IP_IO_OPEN_DATA OpenData;\r
332\r
e48e37fc 333 TcpServiceData = AllocateZeroPool (sizeof (TCP4_SERVICE_DATA));\r
8a67d61d 334\r
335 if (NULL == TcpServiceData) {\r
e48e37fc 336 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Have no enough"\r
dfc1f033 337 " resource to create a Tcp Servcie Data\n"));\r
8a67d61d 338\r
339 return EFI_OUT_OF_RESOURCES;\r
340 }\r
341\r
342 //\r
343 // Create a new IP IO to Consume it\r
344 //\r
fb115c61 345 TcpServiceData->IpIo = IpIoCreate (\r
346 This->DriverBindingHandle,\r
347 ControllerHandle,\r
348 IP_VERSION_4\r
349 );\r
8a67d61d 350 if (NULL == TcpServiceData->IpIo) {\r
351\r
e48e37fc 352 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Have no enough"\r
dfc1f033 353 " resource to create an Ip Io\n"));\r
8a67d61d 354\r
355 Status = EFI_OUT_OF_RESOURCES;\r
c4a62a12 356 goto ON_ERROR;\r
8a67d61d 357 }\r
358\r
359 //\r
360 // Configure and start IpIo.\r
361 //\r
e48e37fc 362 ZeroMem (&OpenData, sizeof (IP_IO_OPEN_DATA));\r
8a67d61d 363\r
fb115c61 364 CopyMem (\r
365 &OpenData.IpConfigData.Ip4CfgData,\r
366 &mIp4IoDefaultIpConfigData,\r
367 sizeof (EFI_IP4_CONFIG_DATA)\r
368 );\r
369\r
370 OpenData.IpConfigData.Ip4CfgData.DefaultProtocol = EFI_IP_PROTO_TCP;\r
8a67d61d 371\r
372 OpenData.PktRcvdNotify = Tcp4RxCallback;\r
373 Status = IpIoOpen (TcpServiceData->IpIo, &OpenData);\r
374\r
375 if (EFI_ERROR (Status)) {\r
c4a62a12 376 goto ON_ERROR;\r
8a67d61d 377 }\r
378\r
379 //\r
380 // Create the timer event used by TCP driver\r
381 //\r
382 Status = Tcp4CreateTimer ();\r
383 if (EFI_ERROR (Status)) {\r
384\r
e48e37fc 385 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Create TcpTimer"\r
8a67d61d 386 " Event failed with %r\n", Status));\r
387\r
c4a62a12 388 goto ON_ERROR;\r
8a67d61d 389 }\r
390\r
391 //\r
392 // Install the Tcp4ServiceBinding Protocol on the\r
393 // controller handle\r
394 //\r
395 TcpServiceData->Tcp4ServiceBinding = mTcp4ServiceBinding;\r
396\r
397 Status = gBS->InstallMultipleProtocolInterfaces (\r
398 &ControllerHandle,\r
399 &gEfiTcp4ServiceBindingProtocolGuid,\r
400 &TcpServiceData->Tcp4ServiceBinding,\r
401 NULL\r
402 );\r
403 if (EFI_ERROR (Status)) {\r
404\r
e48e37fc 405 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Install Tcp4 Service Binding"\r
8a67d61d 406 " Protocol failed for %r\n", Status));\r
407\r
c4a62a12 408 Tcp4DestroyTimer ();\r
409 goto ON_ERROR;\r
8a67d61d 410 }\r
411\r
412 //\r
413 // Initialize member in TcpServiceData\r
414 //\r
415 TcpServiceData->ControllerHandle = ControllerHandle;\r
416 TcpServiceData->Signature = TCP4_DRIVER_SIGNATURE;\r
417 TcpServiceData->DriverBindingHandle = This->DriverBindingHandle;\r
418\r
e48e37fc 419 InitializeListHead (&TcpServiceData->SocketList);\r
c4a62a12 420\r
8a67d61d 421 return EFI_SUCCESS;\r
422\r
c4a62a12 423ON_ERROR:\r
8a67d61d 424\r
c4a62a12 425 if (TcpServiceData->IpIo != NULL) {\r
426 IpIoDestroy (TcpServiceData->IpIo);\r
216f7970 427 TcpServiceData->IpIo = NULL;\r
c4a62a12 428 }\r
8a67d61d 429\r
766c7483 430 FreePool (TcpServiceData);\r
8a67d61d 431\r
432 return Status;\r
433}\r
434\r
435\r
436/**\r
437 Stop this driver on ControllerHandle.\r
d1102dba
LG
438\r
439 The Stop() function is designed to be invoked from the EFI boot service\r
440 DisconnectController(). As a result, much of the error checking on the parameters\r
441 to Stop() has been moved into this common boot service. It is legal to call Stop()\r
442 from other locations, but the following calling restrictions must be followed\r
dfc1f033 443 or the system behavior will not be deterministic.\r
d1102dba 444 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call\r
dfc1f033 445 to this same driver's Start() function.\r
446 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r
d1102dba
LG
447 EFI_HANDLE. In addition, all of these handles must have been created in this\r
448 driver's Start() function, and the Start() function must have called OpenProtocol()\r
dfc1f033 449 on ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
d1102dba 450\r
dfc1f033 451 @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
d1102dba
LG
452 @param ControllerHandle A handle to the device being stopped. The handle must\r
453 support a bus specific I/O protocol for the driver\r
dfc1f033 454 to use to stop the device.\r
455 @param NumberOfChildren The number of child device handles in ChildHandleBuffer.\r
d1102dba 456 @param ChildHandleBuffer An array of child handles to be freed. May be NULL if\r
dfc1f033 457 NumberOfChildren is 0.\r
8a67d61d 458\r
dfc1f033 459 @retval EFI_SUCCESS The device was stopped.\r
460 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
8a67d61d 461\r
462**/\r
463EFI_STATUS\r
464EFIAPI\r
465Tcp4DriverBindingStop (\r
466 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
467 IN EFI_HANDLE ControllerHandle,\r
468 IN UINTN NumberOfChildren,\r
469 IN EFI_HANDLE *ChildHandleBuffer\r
470 )\r
471{\r
216f7970 472 EFI_STATUS Status;\r
473 EFI_HANDLE NicHandle;\r
474 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
475 TCP4_SERVICE_DATA *TcpServiceData;\r
476 LIST_ENTRY *List;\r
477 TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;\r
8a67d61d 478\r
479 // Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.\r
480 //\r
481 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);\r
482 if (NicHandle == NULL) {\r
216f7970 483 return EFI_SUCCESS;\r
8a67d61d 484 }\r
485\r
486 //\r
487 // Retrieve the TCP driver Data Structure\r
488 //\r
489 Status = gBS->OpenProtocol (\r
490 NicHandle,\r
491 &gEfiTcp4ServiceBindingProtocolGuid,\r
c4a62a12 492 (VOID **) &ServiceBinding,\r
8a67d61d 493 This->DriverBindingHandle,\r
494 ControllerHandle,\r
495 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
496 );\r
497 if (EFI_ERROR (Status)) {\r
498\r
e48e37fc 499 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStop: Locate Tcp4 Service "\r
8a67d61d 500 " Binding Protocol failed with %r\n", Status));\r
501\r
c4a62a12 502 return EFI_DEVICE_ERROR;\r
8a67d61d 503 }\r
504\r
c4a62a12 505 TcpServiceData = TCP4_FROM_THIS (ServiceBinding);\r
8a67d61d 506\r
216f7970 507 if (NumberOfChildren != 0) {\r
d1102dba 508 List = &TcpServiceData->SocketList;\r
216f7970 509 Context.ServiceBinding = ServiceBinding;\r
510 Context.NumberOfChildren = NumberOfChildren;\r
511 Context.ChildHandleBuffer = ChildHandleBuffer;\r
512 Status = NetDestroyLinkList (\r
513 List,\r
514 Tcp4DestroyChildEntryInHandleBuffer,\r
515 &Context,\r
516 NULL\r
517 );\r
518 } else if (IsListEmpty (&TcpServiceData->SocketList)) {\r
8a67d61d 519 //\r
c4a62a12 520 // Uninstall TCP servicebinding protocol\r
8a67d61d 521 //\r
c4a62a12 522 gBS->UninstallMultipleProtocolInterfaces (\r
523 NicHandle,\r
524 &gEfiTcp4ServiceBindingProtocolGuid,\r
525 ServiceBinding,\r
526 NULL\r
527 );\r
8a67d61d 528\r
c4a62a12 529 //\r
530 // Destroy the IpIO consumed by TCP driver\r
531 //\r
532 IpIoDestroy (TcpServiceData->IpIo);\r
216f7970 533 TcpServiceData->IpIo = NULL;\r
8a67d61d 534\r
c4a62a12 535 //\r
536 // Destroy the heartbeat timer.\r
537 //\r
538 Tcp4DestroyTimer ();\r
8a67d61d 539\r
216f7970 540 if (gTcpControllerNameTable != NULL) {\r
541 FreeUnicodeStringTable (gTcpControllerNameTable);\r
542 gTcpControllerNameTable = NULL;\r
543 }\r
d1102dba 544\r
8a67d61d 545 //\r
c4a62a12 546 // Release the TCP service data\r
8a67d61d 547 //\r
766c7483 548 FreePool (TcpServiceData);\r
8a67d61d 549\r
216f7970 550 Status = EFI_SUCCESS;\r
8a67d61d 551 }\r
552\r
8a67d61d 553 return Status;\r
554}\r
555\r
120db52c 556/**\r
d1102dba 557 Open Ip4 and device path protocols for a created socket, and insert it in\r
120db52c 558 socket list.\r
d1102dba 559\r
120db52c 560 @param This Pointer to the socket just created\r
561 @param Context Context of the socket\r
d1102dba 562\r
120db52c 563 @retval EFI_SUCCESS This protocol is installed successfully.\r
564 @retval other Some error occured.\r
d1102dba 565\r
120db52c 566**/\r
4f6e31e4 567EFI_STATUS\r
568Tcp4CreateSocketCallback (\r
569 IN SOCKET *This,\r
570 IN VOID *Context\r
571 )\r
572{\r
573 EFI_STATUS Status;\r
574 TCP4_SERVICE_DATA *TcpServiceData;\r
575 EFI_IP4_PROTOCOL *Ip4;\r
576\r
577 TcpServiceData = ((TCP4_PROTO_DATA *) This->ProtoReserved)->TcpService;\r
578\r
579 //\r
580 // Open the default Ip4 protocol of IP_IO BY_DRIVER.\r
581 //\r
582 Status = gBS->OpenProtocol (\r
583 TcpServiceData->IpIo->ChildHandle,\r
584 &gEfiIp4ProtocolGuid,\r
585 (VOID **) &Ip4,\r
586 TcpServiceData->DriverBindingHandle,\r
587 This->SockHandle,\r
588 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
589 );\r
590 if (EFI_ERROR (Status)) {\r
591 return Status;\r
592 }\r
593\r
594 //\r
595 // Open the device path on the handle where service binding resides on.\r
596 //\r
597 Status = gBS->OpenProtocol (\r
598 TcpServiceData->ControllerHandle,\r
599 &gEfiDevicePathProtocolGuid,\r
600 (VOID **) &This->ParentDevicePath,\r
601 TcpServiceData->DriverBindingHandle,\r
602 This->SockHandle,\r
bf1400b9 603 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
4f6e31e4 604 );\r
605 if (EFI_ERROR (Status)) {\r
606 gBS->CloseProtocol (\r
607 TcpServiceData->IpIo->ChildHandle,\r
608 &gEfiIp4ProtocolGuid,\r
609 TcpServiceData->DriverBindingHandle,\r
610 This->SockHandle\r
611 );\r
612 } else {\r
613 //\r
614 // Insert this socket into the SocketList.\r
615 //\r
e48e37fc 616 InsertTailList (&TcpServiceData->SocketList, &This->Link);\r
4f6e31e4 617 }\r
618\r
619 return Status;\r
620}\r
621\r
120db52c 622/**\r
d1102dba
LG
623 Close Ip4 and device path protocols for a socket, and remove it from socket list.\r
624\r
120db52c 625 @param This Pointer to the socket to be removed\r
626 @param Context Context of the socket\r
d1102dba 627\r
120db52c 628**/\r
4f6e31e4 629VOID\r
630Tcp4DestroySocketCallback (\r
631 IN SOCKET *This,\r
632 IN VOID *Context\r
633 )\r
634{\r
635 TCP4_SERVICE_DATA *TcpServiceData;\r
636\r
637 TcpServiceData = ((TCP4_PROTO_DATA *) This->ProtoReserved)->TcpService;\r
638\r
639 //\r
640 // Remove this node from the list.\r
641 //\r
e48e37fc 642 RemoveEntryList (&This->Link);\r
4f6e31e4 643\r
4f6e31e4 644 //\r
645 // Close the Ip4 protocol.\r
646 //\r
647 gBS->CloseProtocol (\r
648 TcpServiceData->IpIo->ChildHandle,\r
649 &gEfiIp4ProtocolGuid,\r
650 TcpServiceData->DriverBindingHandle,\r
651 This->SockHandle\r
652 );\r
653}\r
654\r
8a67d61d 655/**\r
dfc1f033 656 Creates a child handle and installs a protocol.\r
d1102dba
LG
657\r
658 The CreateChild() function installs a protocol on ChildHandle. If ChildHandle\r
659 is a pointer to NULL, then a new handle is created and returned in ChildHandle.\r
660 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing\r
dfc1f033 661 ChildHandle.\r
662\r
663 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
d1102dba
LG
664 @param ChildHandle Pointer to the handle of the child to create. If it is NULL, then\r
665 a new handle is created. If it is a pointer to an existing UEFI\r
dfc1f033 666 handle, then the protocol is added to the existing UEFI handle.\r
667\r
668 @retval EFI_SUCCES The protocol was added to ChildHandle.\r
669 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
2048c585 670 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create\r
dfc1f033 671 the child.\r
672 @retval other The child handle was not created.\r
8a67d61d 673\r
674**/\r
675EFI_STATUS\r
676EFIAPI\r
677Tcp4ServiceBindingCreateChild (\r
276dcc1b 678 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
679 IN OUT EFI_HANDLE *ChildHandle\r
8a67d61d 680 )\r
681{\r
682 SOCKET *Sock;\r
683 TCP4_SERVICE_DATA *TcpServiceData;\r
684 TCP4_PROTO_DATA TcpProto;\r
685 EFI_STATUS Status;\r
8a67d61d 686 EFI_TPL OldTpl;\r
687\r
688 if (NULL == This || NULL == ChildHandle) {\r
689 return EFI_INVALID_PARAMETER;\r
690 }\r
691\r
e48e37fc 692 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
4f6e31e4 693 Status = EFI_SUCCESS;\r
8a67d61d 694 TcpServiceData = TCP4_FROM_THIS (This);\r
695 TcpProto.TcpService = TcpServiceData;\r
696 TcpProto.TcpPcb = NULL;\r
697\r
698 //\r
699 // Create a tcp instance with defualt Tcp default\r
700 // sock init data and TcpProto\r
701 //\r
4f6e31e4 702 mTcp4DefaultSockData.ProtoData = &TcpProto;\r
703 mTcp4DefaultSockData.DataSize = sizeof (TCP4_PROTO_DATA);\r
8a67d61d 704 mTcp4DefaultSockData.DriverBinding = TcpServiceData->DriverBindingHandle;\r
e48e37fc 705\r
4f6e31e4 706 Sock = SockCreateChild (&mTcp4DefaultSockData);\r
8a67d61d 707 if (NULL == Sock) {\r
e48e37fc 708 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingCreateChild: "\r
8a67d61d 709 "No resource to create a Tcp Child\n"));\r
710\r
711 Status = EFI_OUT_OF_RESOURCES;\r
c4a62a12 712 } else {\r
4f6e31e4 713 *ChildHandle = Sock->SockHandle;\r
8a67d61d 714 }\r
715\r
c9325700
ED
716 mTcp4DefaultSockData.ProtoData = NULL;\r
717\r
e48e37fc 718 gBS->RestoreTPL (OldTpl);\r
8a67d61d 719 return Status;\r
720}\r
721\r
722\r
723/**\r
dfc1f033 724 Destroys a child handle with a protocol installed on it.\r
d1102dba
LG
725\r
726 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol\r
727 that was installed by CreateChild() from ChildHandle. If the removed protocol is the\r
dfc1f033 728 last protocol on ChildHandle, then ChildHandle is destroyed.\r
729\r
730 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
731 @param ChildHandle Handle of the child to destroy\r
732\r
733 @retval EFI_SUCCES The protocol was removed from ChildHandle.\r
d1102dba 734 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is\r
dfc1f033 735 being removed.\r
284ee2e8 736 @retval EFI_INVALID_PARAMETER Child handle is NULL.\r
dfc1f033 737 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle\r
738 because its services are being used.\r
739 @retval other The child handle was not destroyed.\r
d1102dba 740\r
8a67d61d 741**/\r
742EFI_STATUS\r
743EFIAPI\r
744Tcp4ServiceBindingDestroyChild (\r
745 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
746 IN EFI_HANDLE ChildHandle\r
747 )\r
748{\r
749 EFI_STATUS Status;\r
750 EFI_TCP4_PROTOCOL *Tcp4;\r
751 SOCKET *Sock;\r
8a67d61d 752\r
753 if (NULL == This || NULL == ChildHandle) {\r
754 return EFI_INVALID_PARAMETER;\r
755 }\r
756\r
8a67d61d 757 //\r
758 // retrieve the Tcp4 protocol from ChildHandle\r
759 //\r
760 Status = gBS->OpenProtocol (\r
761 ChildHandle,\r
762 &gEfiTcp4ProtocolGuid,\r
763 (VOID **) &Tcp4,\r
764 mTcp4DriverBinding.DriverBindingHandle,\r
765 ChildHandle,\r
766 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
767 );\r
768 if (EFI_ERROR (Status)) {\r
769 Status = EFI_UNSUPPORTED;\r
4f6e31e4 770 } else {\r
771 //\r
772 // destroy this sock and related Tcp protocol control\r
773 // block\r
774 //\r
775 Sock = SOCK_FROM_THIS (Tcp4);\r
e5e12de7 776\r
4f6e31e4 777 SockDestroyChild (Sock);\r
778 }\r
8a67d61d 779\r
8a67d61d 780 return Status;\r
781}\r
4f6e31e4 782\r