]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c
Patch to remove STATIC modifier. This is on longer recommended by EFI Framework codin...
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Tcp4Dxe / Tcp4Driver.c
CommitLineData
8a67d61d 1/** @file\r
2\r
3Copyright (c) 2005 - 2007, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 Tcp4Driver.c\r
15\r
16Abstract:\r
17\r
18\r
19**/\r
20\r
21#include "Tcp4Main.h"\r
22\r
23\r
24UINT16 mTcp4RandomPort;\r
83cbd279 25extern EFI_COMPONENT_NAME_PROTOCOL gTcp4ComponentName;\r
26extern EFI_COMPONENT_NAME2_PROTOCOL gTcp4ComponentName2;\r
8a67d61d 27\r
28TCP4_HEARTBEAT_TIMER mTcp4Timer = {\r
29 NULL,\r
30 0\r
31};\r
32\r
33EFI_TCP4_PROTOCOL mTcp4ProtocolTemplate = {\r
34 Tcp4GetModeData,\r
35 Tcp4Configure,\r
36 Tcp4Routes,\r
37 Tcp4Connect,\r
38 Tcp4Accept,\r
39 Tcp4Transmit,\r
40 Tcp4Receive,\r
41 Tcp4Close,\r
42 Tcp4Cancel,\r
43 Tcp4Poll\r
44};\r
45\r
46SOCK_INIT_DATA mTcp4DefaultSockData = {\r
47 SOCK_STREAM,\r
4eb65aff 48 (SOCK_STATE) 0,\r
8a67d61d 49 NULL,\r
50 TCP_BACKLOG,\r
51 TCP_SND_BUF_SIZE,\r
52 TCP_RCV_BUF_SIZE,\r
53 &mTcp4ProtocolTemplate,\r
4f6e31e4 54 Tcp4CreateSocketCallback,\r
55 Tcp4DestroySocketCallback,\r
56 NULL,\r
57 NULL,\r
58 0,\r
8a67d61d 59 Tcp4Dispatcher,\r
60 NULL,\r
61};\r
62\r
63EFI_DRIVER_BINDING_PROTOCOL mTcp4DriverBinding = {\r
64 Tcp4DriverBindingSupported,\r
65 Tcp4DriverBindingStart,\r
66 Tcp4DriverBindingStop,\r
67 0xa,\r
68 NULL,\r
69 NULL\r
70};\r
71\r
72EFI_SERVICE_BINDING_PROTOCOL mTcp4ServiceBinding = {\r
73 Tcp4ServiceBindingCreateChild,\r
74 Tcp4ServiceBindingDestroyChild\r
75};\r
76\r
77\r
78/**\r
79 Create and start the heartbeat timer for TCP driver.\r
80\r
81 None.\r
82\r
83 @retval EFI_SUCCESS The timer is successfully created and started.\r
84 @retval other The timer is not created.\r
85\r
86**/\r
8a67d61d 87EFI_STATUS\r
88Tcp4CreateTimer (\r
89 VOID\r
90 )\r
91{\r
92 EFI_STATUS Status;\r
93\r
94 Status = EFI_SUCCESS;\r
95\r
96 if (mTcp4Timer.RefCnt == 0) {\r
97\r
98 Status = gBS->CreateEvent (\r
99 EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
e48e37fc 100 TPL_NOTIFY,\r
8a67d61d 101 TcpTicking,\r
102 NULL,\r
103 &mTcp4Timer.TimerEvent\r
104 );\r
105 if (!EFI_ERROR (Status)) {\r
106\r
107 Status = gBS->SetTimer (\r
108 mTcp4Timer.TimerEvent,\r
109 TimerPeriodic,\r
110 (UINT64) (TICKS_PER_SECOND / TCP_TICK_HZ)\r
111 );\r
112 }\r
113 }\r
114\r
115 if (!EFI_ERROR (Status)) {\r
116\r
117 mTcp4Timer.RefCnt++;\r
118 }\r
119\r
120 return Status;\r
121}\r
122\r
123\r
124/**\r
125 Stop and destroy the heartbeat timer for TCP driver.\r
126\r
127 None.\r
128\r
129 @return None.\r
130\r
131**/\r
8a67d61d 132VOID\r
133Tcp4DestroyTimer (\r
134 VOID\r
135 )\r
136{\r
137 ASSERT (mTcp4Timer.RefCnt > 0);\r
138\r
139 mTcp4Timer.RefCnt--;\r
140\r
141 if (mTcp4Timer.RefCnt > 0) {\r
142 return;\r
143 }\r
144\r
145 gBS->SetTimer (mTcp4Timer.TimerEvent, TimerCancel, 0);\r
146 gBS->CloseEvent (mTcp4Timer.TimerEvent);\r
147 mTcp4Timer.TimerEvent = NULL;\r
148}\r
149\r
8a67d61d 150\r
151EFI_STATUS\r
152EFIAPI\r
153Tcp4DriverEntryPoint (\r
154 IN EFI_HANDLE ImageHandle,\r
155 IN EFI_SYSTEM_TABLE *SystemTable\r
156 )\r
157/*++\r
158\r
159Routine Description:\r
160\r
161 The entry point for Tcp4 driver. used to install\r
162 Tcp4 driver on the ImageHandle.\r
163\r
164Arguments:\r
165\r
166 ImageHandle - The firmware allocated handle for this\r
167 driver image.\r
168 SystemTable - Pointer to the EFI system table.\r
169\r
170Returns:\r
171\r
172 EFI_SUCCESS - Driver loaded.\r
173 other - Driver not loaded.\r
174\r
175--*/\r
176{\r
177 EFI_STATUS Status;\r
178 UINT32 Seed;\r
179\r
180 //\r
181 // Install the TCP4 Driver Binding Protocol\r
182 //\r
83cbd279 183 Status = EfiLibInstallDriverBindingComponentName2 (\r
8a67d61d 184 ImageHandle,\r
185 SystemTable,\r
186 &mTcp4DriverBinding,\r
187 ImageHandle,\r
188 &gTcp4ComponentName,\r
83cbd279 189 &gTcp4ComponentName2\r
8a67d61d 190 );\r
da1d0201 191 ASSERT_EFI_ERROR (Status);\r
8a67d61d 192 //\r
193 // Initialize ISS and random port.\r
194 //\r
195 Seed = NetRandomInitSeed ();\r
196 mTcpGlobalIss = NET_RANDOM (Seed) % mTcpGlobalIss;\r
4eb65aff 197 mTcp4RandomPort = (UINT16) ( TCP4_PORT_KNOWN +\r
198 (UINT16) (NET_RANDOM(Seed) % TCP4_PORT_KNOWN));\r
8a67d61d 199\r
200 return Status;\r
201}\r
202\r
203\r
204/**\r
205 Test to see if this driver supports ControllerHandle.\r
206\r
207 @param This Protocol instance pointer.\r
208 @param ControllerHandle Handle of device to test.\r
209 @param RemainingDevicePath Optional parameter use to pick a specific child\r
210 device to start.\r
211\r
212 @retval EFI_SUCCESS This driver supports this device.\r
213 @retval EFI_ALREADY_STARTED This driver is already running on this device.\r
214 @retval other This driver does not support this device.\r
215\r
216**/\r
217EFI_STATUS\r
218EFIAPI\r
219Tcp4DriverBindingSupported (\r
220 IN EFI_DRIVER_BINDING_PROTOCOL * This,\r
221 IN EFI_HANDLE ControllerHandle,\r
222 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL\r
223 )\r
224{\r
225 EFI_STATUS Status;\r
226\r
227 //\r
228 // Test for the Tcp4ServiceBinding Protocol\r
229 //\r
230 Status = gBS->OpenProtocol (\r
231 ControllerHandle,\r
232 &gEfiTcp4ServiceBindingProtocolGuid,\r
233 NULL,\r
234 This->DriverBindingHandle,\r
235 ControllerHandle,\r
236 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
237 );\r
238 if (!EFI_ERROR (Status)) {\r
239 return EFI_ALREADY_STARTED;\r
240 }\r
241\r
242 //\r
243 // Test for the Ip4 Protocol\r
244 //\r
245 Status = gBS->OpenProtocol (\r
246 ControllerHandle,\r
247 &gEfiIp4ServiceBindingProtocolGuid,\r
248 NULL,\r
249 This->DriverBindingHandle,\r
250 ControllerHandle,\r
251 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
252 );\r
253\r
254 return Status;\r
255}\r
256\r
257\r
258/**\r
259 Start this driver on ControllerHandle.\r
260\r
261 @param This Protocol instance pointer.\r
262 @param ControllerHandle Handle of device to bind driver to.\r
263 @param RemainingDevicePath Optional parameter use to pick a specific child\r
264 device to start.\r
265\r
266 @retval EFI_SUCCESS The driver is added to ControllerHandle.\r
267 @retval EFI_OUT_OF_RESOURCES There are not enough resources to start the\r
268 driver.\r
269 @retval other The driver cannot be added to ControllerHandle.\r
270\r
271**/\r
272EFI_STATUS\r
273EFIAPI\r
274Tcp4DriverBindingStart (\r
275 IN EFI_DRIVER_BINDING_PROTOCOL * This,\r
276 IN EFI_HANDLE ControllerHandle,\r
277 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL\r
278 )\r
279{\r
280 EFI_STATUS Status;\r
281 TCP4_SERVICE_DATA *TcpServiceData;\r
282 IP_IO_OPEN_DATA OpenData;\r
283\r
e48e37fc 284 TcpServiceData = AllocateZeroPool (sizeof (TCP4_SERVICE_DATA));\r
8a67d61d 285\r
286 if (NULL == TcpServiceData) {\r
e48e37fc 287 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Have no enough"\r
8a67d61d 288 " resource to create a Tcp Servcie Data!\n"));\r
289\r
290 return EFI_OUT_OF_RESOURCES;\r
291 }\r
292\r
293 //\r
294 // Create a new IP IO to Consume it\r
295 //\r
296 TcpServiceData->IpIo = IpIoCreate (This->DriverBindingHandle, ControllerHandle);\r
297 if (NULL == TcpServiceData->IpIo) {\r
298\r
e48e37fc 299 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Have no enough"\r
8a67d61d 300 " resource to create an Ip Io!\n"));\r
301\r
302 Status = EFI_OUT_OF_RESOURCES;\r
c4a62a12 303 goto ON_ERROR;\r
8a67d61d 304 }\r
305\r
306 //\r
307 // Configure and start IpIo.\r
308 //\r
e48e37fc 309 ZeroMem (&OpenData, sizeof (IP_IO_OPEN_DATA));\r
8a67d61d 310\r
687a2e5f 311 CopyMem (&OpenData.IpConfigData, &mIpIoDefaultIpConfigData, sizeof (OpenData.IpConfigData));\r
8a67d61d 312 OpenData.IpConfigData.DefaultProtocol = EFI_IP_PROTO_TCP;\r
313\r
314 OpenData.PktRcvdNotify = Tcp4RxCallback;\r
315 Status = IpIoOpen (TcpServiceData->IpIo, &OpenData);\r
316\r
317 if (EFI_ERROR (Status)) {\r
c4a62a12 318 goto ON_ERROR;\r
8a67d61d 319 }\r
320\r
321 //\r
322 // Create the timer event used by TCP driver\r
323 //\r
324 Status = Tcp4CreateTimer ();\r
325 if (EFI_ERROR (Status)) {\r
326\r
e48e37fc 327 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Create TcpTimer"\r
8a67d61d 328 " Event failed with %r\n", Status));\r
329\r
c4a62a12 330 goto ON_ERROR;\r
8a67d61d 331 }\r
332\r
333 //\r
334 // Install the Tcp4ServiceBinding Protocol on the\r
335 // controller handle\r
336 //\r
337 TcpServiceData->Tcp4ServiceBinding = mTcp4ServiceBinding;\r
338\r
339 Status = gBS->InstallMultipleProtocolInterfaces (\r
340 &ControllerHandle,\r
341 &gEfiTcp4ServiceBindingProtocolGuid,\r
342 &TcpServiceData->Tcp4ServiceBinding,\r
343 NULL\r
344 );\r
345 if (EFI_ERROR (Status)) {\r
346\r
e48e37fc 347 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Install Tcp4 Service Binding"\r
8a67d61d 348 " Protocol failed for %r\n", Status));\r
349\r
c4a62a12 350 Tcp4DestroyTimer ();\r
351 goto ON_ERROR;\r
8a67d61d 352 }\r
353\r
354 //\r
355 // Initialize member in TcpServiceData\r
356 //\r
357 TcpServiceData->ControllerHandle = ControllerHandle;\r
358 TcpServiceData->Signature = TCP4_DRIVER_SIGNATURE;\r
359 TcpServiceData->DriverBindingHandle = This->DriverBindingHandle;\r
360\r
e48e37fc 361 InitializeListHead (&TcpServiceData->SocketList);\r
c4a62a12 362\r
8a67d61d 363 TcpSetVariableData (TcpServiceData);\r
364\r
365 return EFI_SUCCESS;\r
366\r
c4a62a12 367ON_ERROR:\r
8a67d61d 368\r
c4a62a12 369 if (TcpServiceData->IpIo != NULL) {\r
370 IpIoDestroy (TcpServiceData->IpIo);\r
371 }\r
8a67d61d 372\r
e48e37fc 373 gBS->FreePool (TcpServiceData);\r
8a67d61d 374\r
375 return Status;\r
376}\r
377\r
378\r
379/**\r
380 Stop this driver on ControllerHandle.\r
381\r
382 @param This Protocol instance pointer.\r
383 @param ControllerHandle Handle of device to stop driver on.\r
384 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number\r
385 of children is zero stop the entire bus driver.\r
386 @param ChildHandleBuffer List of Child Handles to Stop.\r
387\r
388 @retval EFI_SUCCESS This driver is removed from ControllerHandle.\r
389 @retval other This driver is not removed from ControllerHandle.\r
390\r
391**/\r
392EFI_STATUS\r
393EFIAPI\r
394Tcp4DriverBindingStop (\r
395 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
396 IN EFI_HANDLE ControllerHandle,\r
397 IN UINTN NumberOfChildren,\r
398 IN EFI_HANDLE *ChildHandleBuffer\r
399 )\r
400{\r
401 EFI_STATUS Status;\r
402 EFI_HANDLE NicHandle;\r
c4a62a12 403 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
8a67d61d 404 TCP4_SERVICE_DATA *TcpServiceData;\r
8a67d61d 405 SOCKET *Sock;\r
8a67d61d 406\r
407 // Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.\r
408 //\r
409 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);\r
410 if (NicHandle == NULL) {\r
c4a62a12 411 return EFI_DEVICE_ERROR;\r
8a67d61d 412 }\r
413\r
414 //\r
415 // Retrieve the TCP driver Data Structure\r
416 //\r
417 Status = gBS->OpenProtocol (\r
418 NicHandle,\r
419 &gEfiTcp4ServiceBindingProtocolGuid,\r
c4a62a12 420 (VOID **) &ServiceBinding,\r
8a67d61d 421 This->DriverBindingHandle,\r
422 ControllerHandle,\r
423 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
424 );\r
425 if (EFI_ERROR (Status)) {\r
426\r
e48e37fc 427 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStop: Locate Tcp4 Service "\r
8a67d61d 428 " Binding Protocol failed with %r\n", Status));\r
429\r
c4a62a12 430 return EFI_DEVICE_ERROR;\r
8a67d61d 431 }\r
432\r
c4a62a12 433 TcpServiceData = TCP4_FROM_THIS (ServiceBinding);\r
8a67d61d 434\r
c4a62a12 435 if (NumberOfChildren == 0) {\r
8a67d61d 436 //\r
c4a62a12 437 // Uninstall TCP servicebinding protocol\r
8a67d61d 438 //\r
c4a62a12 439 gBS->UninstallMultipleProtocolInterfaces (\r
440 NicHandle,\r
441 &gEfiTcp4ServiceBindingProtocolGuid,\r
442 ServiceBinding,\r
443 NULL\r
444 );\r
8a67d61d 445\r
c4a62a12 446 //\r
447 // Destroy the IpIO consumed by TCP driver\r
448 //\r
449 IpIoDestroy (TcpServiceData->IpIo);\r
8a67d61d 450\r
c4a62a12 451 //\r
452 // Destroy the heartbeat timer.\r
453 //\r
454 Tcp4DestroyTimer ();\r
8a67d61d 455\r
c4a62a12 456 //\r
457 // Clear the variable.\r
458 //\r
459 TcpClearVariableData (TcpServiceData);\r
8a67d61d 460\r
461 //\r
c4a62a12 462 // Release the TCP service data\r
8a67d61d 463 //\r
e48e37fc 464 gBS->FreePool (TcpServiceData);\r
c4a62a12 465 } else {\r
8a67d61d 466\r
e48e37fc 467 while (!IsListEmpty (&TcpServiceData->SocketList)) {\r
c4a62a12 468 Sock = NET_LIST_HEAD (&TcpServiceData->SocketList, SOCKET, Link);\r
8a67d61d 469\r
c4a62a12 470 ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);\r
8a67d61d 471 }\r
472 }\r
473\r
8a67d61d 474 return Status;\r
475}\r
476\r
4f6e31e4 477EFI_STATUS\r
478Tcp4CreateSocketCallback (\r
479 IN SOCKET *This,\r
480 IN VOID *Context\r
481 )\r
482{\r
483 EFI_STATUS Status;\r
484 TCP4_SERVICE_DATA *TcpServiceData;\r
485 EFI_IP4_PROTOCOL *Ip4;\r
486\r
487 TcpServiceData = ((TCP4_PROTO_DATA *) This->ProtoReserved)->TcpService;\r
488\r
489 //\r
490 // Open the default Ip4 protocol of IP_IO BY_DRIVER.\r
491 //\r
492 Status = gBS->OpenProtocol (\r
493 TcpServiceData->IpIo->ChildHandle,\r
494 &gEfiIp4ProtocolGuid,\r
495 (VOID **) &Ip4,\r
496 TcpServiceData->DriverBindingHandle,\r
497 This->SockHandle,\r
498 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
499 );\r
500 if (EFI_ERROR (Status)) {\r
501 return Status;\r
502 }\r
503\r
504 //\r
505 // Open the device path on the handle where service binding resides on.\r
506 //\r
507 Status = gBS->OpenProtocol (\r
508 TcpServiceData->ControllerHandle,\r
509 &gEfiDevicePathProtocolGuid,\r
510 (VOID **) &This->ParentDevicePath,\r
511 TcpServiceData->DriverBindingHandle,\r
512 This->SockHandle,\r
513 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
514 );\r
515 if (EFI_ERROR (Status)) {\r
516 gBS->CloseProtocol (\r
517 TcpServiceData->IpIo->ChildHandle,\r
518 &gEfiIp4ProtocolGuid,\r
519 TcpServiceData->DriverBindingHandle,\r
520 This->SockHandle\r
521 );\r
522 } else {\r
523 //\r
524 // Insert this socket into the SocketList.\r
525 //\r
e48e37fc 526 InsertTailList (&TcpServiceData->SocketList, &This->Link);\r
4f6e31e4 527 }\r
528\r
529 return Status;\r
530}\r
531\r
532VOID\r
533Tcp4DestroySocketCallback (\r
534 IN SOCKET *This,\r
535 IN VOID *Context\r
536 )\r
537{\r
538 TCP4_SERVICE_DATA *TcpServiceData;\r
539\r
540 TcpServiceData = ((TCP4_PROTO_DATA *) This->ProtoReserved)->TcpService;\r
541\r
542 //\r
543 // Remove this node from the list.\r
544 //\r
e48e37fc 545 RemoveEntryList (&This->Link);\r
4f6e31e4 546\r
547 //\r
548 // Close the device path protocol\r
549 //\r
550 gBS->CloseProtocol (\r
551 TcpServiceData->ControllerHandle,\r
552 &gEfiDevicePathProtocolGuid,\r
553 TcpServiceData->DriverBindingHandle,\r
554 This->SockHandle\r
555 );\r
556\r
557 //\r
558 // Close the Ip4 protocol.\r
559 //\r
560 gBS->CloseProtocol (\r
561 TcpServiceData->IpIo->ChildHandle,\r
562 &gEfiIp4ProtocolGuid,\r
563 TcpServiceData->DriverBindingHandle,\r
564 This->SockHandle\r
565 );\r
566}\r
567\r
8a67d61d 568/**\r
569 Creates a child handle with a set of TCP4 services.\r
570\r
571 @param This Protocol instance pointer.\r
572 @param ChildHandle Pointer to the handle of the child to create. If\r
573 it is NULL, then a new handle is created. If it is\r
574 not NULL, then the I/O services are added to the\r
575 existing child handle.\r
576\r
577 @retval EFI_SUCCESS The child handle is created.\r
578 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
579 @retval EFI_OUT_OF_RESOURCES There are not enough resources to create the\r
580 child.\r
581\r
582**/\r
583EFI_STATUS\r
584EFIAPI\r
585Tcp4ServiceBindingCreateChild (\r
586 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
587 IN EFI_HANDLE *ChildHandle\r
588 )\r
589{\r
590 SOCKET *Sock;\r
591 TCP4_SERVICE_DATA *TcpServiceData;\r
592 TCP4_PROTO_DATA TcpProto;\r
593 EFI_STATUS Status;\r
8a67d61d 594 EFI_TPL OldTpl;\r
595\r
596 if (NULL == This || NULL == ChildHandle) {\r
597 return EFI_INVALID_PARAMETER;\r
598 }\r
599\r
e48e37fc 600 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
4f6e31e4 601 Status = EFI_SUCCESS;\r
8a67d61d 602 TcpServiceData = TCP4_FROM_THIS (This);\r
603 TcpProto.TcpService = TcpServiceData;\r
604 TcpProto.TcpPcb = NULL;\r
605\r
606 //\r
607 // Create a tcp instance with defualt Tcp default\r
608 // sock init data and TcpProto\r
609 //\r
4f6e31e4 610 mTcp4DefaultSockData.ProtoData = &TcpProto;\r
611 mTcp4DefaultSockData.DataSize = sizeof (TCP4_PROTO_DATA);\r
8a67d61d 612 mTcp4DefaultSockData.DriverBinding = TcpServiceData->DriverBindingHandle;\r
e48e37fc 613\r
4f6e31e4 614 Sock = SockCreateChild (&mTcp4DefaultSockData);\r
8a67d61d 615 if (NULL == Sock) {\r
e48e37fc 616 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingCreateChild: "\r
8a67d61d 617 "No resource to create a Tcp Child\n"));\r
618\r
619 Status = EFI_OUT_OF_RESOURCES;\r
c4a62a12 620 } else {\r
4f6e31e4 621 *ChildHandle = Sock->SockHandle;\r
8a67d61d 622 }\r
623\r
e48e37fc 624 gBS->RestoreTPL (OldTpl);\r
8a67d61d 625 return Status;\r
626}\r
627\r
628\r
629/**\r
630 Destroys a child handle with a set of UDP4 services.\r
631\r
632 @param This Protocol instance pointer.\r
633 @param ChildHandle Handle of the child to be destroyed.\r
634\r
635 @retval EFI_SUCCESS The TCP4 services are removed from the child\r
636 handle.\r
637 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
638 @retval other The child handle is not destroyed.\r
639\r
640**/\r
641EFI_STATUS\r
642EFIAPI\r
643Tcp4ServiceBindingDestroyChild (\r
644 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
645 IN EFI_HANDLE ChildHandle\r
646 )\r
647{\r
648 EFI_STATUS Status;\r
649 EFI_TCP4_PROTOCOL *Tcp4;\r
650 SOCKET *Sock;\r
8a67d61d 651 EFI_TPL OldTpl;\r
652\r
653 if (NULL == This || NULL == ChildHandle) {\r
654 return EFI_INVALID_PARAMETER;\r
655 }\r
656\r
e48e37fc 657 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
8a67d61d 658\r
659 //\r
660 // retrieve the Tcp4 protocol from ChildHandle\r
661 //\r
662 Status = gBS->OpenProtocol (\r
663 ChildHandle,\r
664 &gEfiTcp4ProtocolGuid,\r
665 (VOID **) &Tcp4,\r
666 mTcp4DriverBinding.DriverBindingHandle,\r
667 ChildHandle,\r
668 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
669 );\r
670 if (EFI_ERROR (Status)) {\r
671 Status = EFI_UNSUPPORTED;\r
4f6e31e4 672 } else {\r
673 //\r
674 // destroy this sock and related Tcp protocol control\r
675 // block\r
676 //\r
677 Sock = SOCK_FROM_THIS (Tcp4);\r
e5e12de7 678\r
4f6e31e4 679 SockDestroyChild (Sock);\r
680 }\r
8a67d61d 681\r
e48e37fc 682 gBS->RestoreTPL (OldTpl);\r
8a67d61d 683 return Status;\r
684}\r
4f6e31e4 685\r