]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c
Fix coding style issues for Tcp4Dxe driver.
[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
85511ddf 126 \r
127 None\r
128 \r
129 None\r
8a67d61d 130\r
131**/\r
8a67d61d 132VOID\r
85511ddf 133Tcp4DestroyTimer ()\r
8a67d61d 134{\r
135 ASSERT (mTcp4Timer.RefCnt > 0);\r
136\r
137 mTcp4Timer.RefCnt--;\r
138\r
139 if (mTcp4Timer.RefCnt > 0) {\r
140 return;\r
141 }\r
142\r
143 gBS->SetTimer (mTcp4Timer.TimerEvent, TimerCancel, 0);\r
144 gBS->CloseEvent (mTcp4Timer.TimerEvent);\r
145 mTcp4Timer.TimerEvent = NULL;\r
146}\r
147\r
85511ddf 148/**\r
149 The entry point for Tcp4 driver. \r
150 Used to install Tcp4 driver on the ImageHandle.\r
151\r
152 @param ImageHandle The firmware allocated handle for this\r
153 driver image.\r
154 @param SystemTable Pointer to the EFI system table.\r
155\r
156 @retval EFI_SUCCESS Driver loaded.\r
157 @retval other Driver not loaded.\r
8a67d61d 158\r
85511ddf 159**/\r
8a67d61d 160EFI_STATUS\r
161EFIAPI\r
162Tcp4DriverEntryPoint (\r
163 IN EFI_HANDLE ImageHandle,\r
164 IN EFI_SYSTEM_TABLE *SystemTable\r
165 )\r
8a67d61d 166{\r
167 EFI_STATUS Status;\r
168 UINT32 Seed;\r
169\r
170 //\r
171 // Install the TCP4 Driver Binding Protocol\r
172 //\r
83cbd279 173 Status = EfiLibInstallDriverBindingComponentName2 (\r
8a67d61d 174 ImageHandle,\r
175 SystemTable,\r
176 &mTcp4DriverBinding,\r
177 ImageHandle,\r
178 &gTcp4ComponentName,\r
83cbd279 179 &gTcp4ComponentName2\r
8a67d61d 180 );\r
da1d0201 181 ASSERT_EFI_ERROR (Status);\r
8a67d61d 182 //\r
183 // Initialize ISS and random port.\r
184 //\r
185 Seed = NetRandomInitSeed ();\r
186 mTcpGlobalIss = NET_RANDOM (Seed) % mTcpGlobalIss;\r
4eb65aff 187 mTcp4RandomPort = (UINT16) ( TCP4_PORT_KNOWN +\r
188 (UINT16) (NET_RANDOM(Seed) % TCP4_PORT_KNOWN));\r
8a67d61d 189\r
190 return Status;\r
191}\r
192\r
193\r
194/**\r
195 Test to see if this driver supports ControllerHandle.\r
196\r
197 @param This Protocol instance pointer.\r
198 @param ControllerHandle Handle of device to test.\r
199 @param RemainingDevicePath Optional parameter use to pick a specific child\r
200 device to start.\r
201\r
202 @retval EFI_SUCCESS This driver supports this device.\r
203 @retval EFI_ALREADY_STARTED This driver is already running on this device.\r
204 @retval other This driver does not support this device.\r
205\r
206**/\r
207EFI_STATUS\r
208EFIAPI\r
209Tcp4DriverBindingSupported (\r
210 IN EFI_DRIVER_BINDING_PROTOCOL * This,\r
211 IN EFI_HANDLE ControllerHandle,\r
212 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL\r
213 )\r
214{\r
215 EFI_STATUS Status;\r
216\r
217 //\r
218 // Test for the Tcp4ServiceBinding Protocol\r
219 //\r
220 Status = gBS->OpenProtocol (\r
221 ControllerHandle,\r
222 &gEfiTcp4ServiceBindingProtocolGuid,\r
223 NULL,\r
224 This->DriverBindingHandle,\r
225 ControllerHandle,\r
226 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
227 );\r
228 if (!EFI_ERROR (Status)) {\r
229 return EFI_ALREADY_STARTED;\r
230 }\r
231\r
232 //\r
233 // Test for the Ip4 Protocol\r
234 //\r
235 Status = gBS->OpenProtocol (\r
236 ControllerHandle,\r
237 &gEfiIp4ServiceBindingProtocolGuid,\r
238 NULL,\r
239 This->DriverBindingHandle,\r
240 ControllerHandle,\r
241 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
242 );\r
243\r
244 return Status;\r
245}\r
246\r
247\r
248/**\r
249 Start this driver on ControllerHandle.\r
250\r
251 @param This Protocol instance pointer.\r
252 @param ControllerHandle Handle of device to bind driver to.\r
253 @param RemainingDevicePath Optional parameter use to pick a specific child\r
254 device to start.\r
255\r
256 @retval EFI_SUCCESS The driver is added to ControllerHandle.\r
257 @retval EFI_OUT_OF_RESOURCES There are not enough resources to start the\r
258 driver.\r
259 @retval other The driver cannot be added to ControllerHandle.\r
260\r
261**/\r
262EFI_STATUS\r
263EFIAPI\r
264Tcp4DriverBindingStart (\r
265 IN EFI_DRIVER_BINDING_PROTOCOL * This,\r
266 IN EFI_HANDLE ControllerHandle,\r
267 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL\r
268 )\r
269{\r
270 EFI_STATUS Status;\r
271 TCP4_SERVICE_DATA *TcpServiceData;\r
272 IP_IO_OPEN_DATA OpenData;\r
273\r
e48e37fc 274 TcpServiceData = AllocateZeroPool (sizeof (TCP4_SERVICE_DATA));\r
8a67d61d 275\r
276 if (NULL == TcpServiceData) {\r
e48e37fc 277 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Have no enough"\r
8a67d61d 278 " resource to create a Tcp Servcie Data!\n"));\r
279\r
280 return EFI_OUT_OF_RESOURCES;\r
281 }\r
282\r
283 //\r
284 // Create a new IP IO to Consume it\r
285 //\r
286 TcpServiceData->IpIo = IpIoCreate (This->DriverBindingHandle, ControllerHandle);\r
287 if (NULL == TcpServiceData->IpIo) {\r
288\r
e48e37fc 289 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Have no enough"\r
8a67d61d 290 " resource to create an Ip Io!\n"));\r
291\r
292 Status = EFI_OUT_OF_RESOURCES;\r
c4a62a12 293 goto ON_ERROR;\r
8a67d61d 294 }\r
295\r
296 //\r
297 // Configure and start IpIo.\r
298 //\r
e48e37fc 299 ZeroMem (&OpenData, sizeof (IP_IO_OPEN_DATA));\r
8a67d61d 300\r
687a2e5f 301 CopyMem (&OpenData.IpConfigData, &mIpIoDefaultIpConfigData, sizeof (OpenData.IpConfigData));\r
8a67d61d 302 OpenData.IpConfigData.DefaultProtocol = EFI_IP_PROTO_TCP;\r
303\r
304 OpenData.PktRcvdNotify = Tcp4RxCallback;\r
305 Status = IpIoOpen (TcpServiceData->IpIo, &OpenData);\r
306\r
307 if (EFI_ERROR (Status)) {\r
c4a62a12 308 goto ON_ERROR;\r
8a67d61d 309 }\r
310\r
311 //\r
312 // Create the timer event used by TCP driver\r
313 //\r
314 Status = Tcp4CreateTimer ();\r
315 if (EFI_ERROR (Status)) {\r
316\r
e48e37fc 317 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Create TcpTimer"\r
8a67d61d 318 " Event failed with %r\n", Status));\r
319\r
c4a62a12 320 goto ON_ERROR;\r
8a67d61d 321 }\r
322\r
323 //\r
324 // Install the Tcp4ServiceBinding Protocol on the\r
325 // controller handle\r
326 //\r
327 TcpServiceData->Tcp4ServiceBinding = mTcp4ServiceBinding;\r
328\r
329 Status = gBS->InstallMultipleProtocolInterfaces (\r
330 &ControllerHandle,\r
331 &gEfiTcp4ServiceBindingProtocolGuid,\r
332 &TcpServiceData->Tcp4ServiceBinding,\r
333 NULL\r
334 );\r
335 if (EFI_ERROR (Status)) {\r
336\r
e48e37fc 337 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Install Tcp4 Service Binding"\r
8a67d61d 338 " Protocol failed for %r\n", Status));\r
339\r
c4a62a12 340 Tcp4DestroyTimer ();\r
341 goto ON_ERROR;\r
8a67d61d 342 }\r
343\r
344 //\r
345 // Initialize member in TcpServiceData\r
346 //\r
347 TcpServiceData->ControllerHandle = ControllerHandle;\r
348 TcpServiceData->Signature = TCP4_DRIVER_SIGNATURE;\r
349 TcpServiceData->DriverBindingHandle = This->DriverBindingHandle;\r
350\r
e48e37fc 351 InitializeListHead (&TcpServiceData->SocketList);\r
c4a62a12 352\r
8a67d61d 353 TcpSetVariableData (TcpServiceData);\r
354\r
355 return EFI_SUCCESS;\r
356\r
c4a62a12 357ON_ERROR:\r
8a67d61d 358\r
c4a62a12 359 if (TcpServiceData->IpIo != NULL) {\r
360 IpIoDestroy (TcpServiceData->IpIo);\r
361 }\r
8a67d61d 362\r
e48e37fc 363 gBS->FreePool (TcpServiceData);\r
8a67d61d 364\r
365 return Status;\r
366}\r
367\r
368\r
369/**\r
370 Stop this driver on ControllerHandle.\r
371\r
372 @param This Protocol instance pointer.\r
373 @param ControllerHandle Handle of device to stop driver on.\r
374 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number\r
375 of children is zero stop the entire bus driver.\r
376 @param ChildHandleBuffer List of Child Handles to Stop.\r
377\r
378 @retval EFI_SUCCESS This driver is removed from ControllerHandle.\r
379 @retval other This driver is not removed from ControllerHandle.\r
380\r
381**/\r
382EFI_STATUS\r
383EFIAPI\r
384Tcp4DriverBindingStop (\r
385 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
386 IN EFI_HANDLE ControllerHandle,\r
387 IN UINTN NumberOfChildren,\r
388 IN EFI_HANDLE *ChildHandleBuffer\r
389 )\r
390{\r
391 EFI_STATUS Status;\r
392 EFI_HANDLE NicHandle;\r
c4a62a12 393 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
8a67d61d 394 TCP4_SERVICE_DATA *TcpServiceData;\r
8a67d61d 395 SOCKET *Sock;\r
8a67d61d 396\r
397 // Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.\r
398 //\r
399 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);\r
400 if (NicHandle == NULL) {\r
c4a62a12 401 return EFI_DEVICE_ERROR;\r
8a67d61d 402 }\r
403\r
404 //\r
405 // Retrieve the TCP driver Data Structure\r
406 //\r
407 Status = gBS->OpenProtocol (\r
408 NicHandle,\r
409 &gEfiTcp4ServiceBindingProtocolGuid,\r
c4a62a12 410 (VOID **) &ServiceBinding,\r
8a67d61d 411 This->DriverBindingHandle,\r
412 ControllerHandle,\r
413 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
414 );\r
415 if (EFI_ERROR (Status)) {\r
416\r
e48e37fc 417 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStop: Locate Tcp4 Service "\r
8a67d61d 418 " Binding Protocol failed with %r\n", Status));\r
419\r
c4a62a12 420 return EFI_DEVICE_ERROR;\r
8a67d61d 421 }\r
422\r
c4a62a12 423 TcpServiceData = TCP4_FROM_THIS (ServiceBinding);\r
8a67d61d 424\r
c4a62a12 425 if (NumberOfChildren == 0) {\r
8a67d61d 426 //\r
c4a62a12 427 // Uninstall TCP servicebinding protocol\r
8a67d61d 428 //\r
c4a62a12 429 gBS->UninstallMultipleProtocolInterfaces (\r
430 NicHandle,\r
431 &gEfiTcp4ServiceBindingProtocolGuid,\r
432 ServiceBinding,\r
433 NULL\r
434 );\r
8a67d61d 435\r
c4a62a12 436 //\r
437 // Destroy the IpIO consumed by TCP driver\r
438 //\r
439 IpIoDestroy (TcpServiceData->IpIo);\r
8a67d61d 440\r
c4a62a12 441 //\r
442 // Destroy the heartbeat timer.\r
443 //\r
444 Tcp4DestroyTimer ();\r
8a67d61d 445\r
c4a62a12 446 //\r
447 // Clear the variable.\r
448 //\r
449 TcpClearVariableData (TcpServiceData);\r
8a67d61d 450\r
451 //\r
c4a62a12 452 // Release the TCP service data\r
8a67d61d 453 //\r
e48e37fc 454 gBS->FreePool (TcpServiceData);\r
c4a62a12 455 } else {\r
8a67d61d 456\r
e48e37fc 457 while (!IsListEmpty (&TcpServiceData->SocketList)) {\r
c4a62a12 458 Sock = NET_LIST_HEAD (&TcpServiceData->SocketList, SOCKET, Link);\r
8a67d61d 459\r
c4a62a12 460 ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);\r
8a67d61d 461 }\r
462 }\r
463\r
8a67d61d 464 return Status;\r
465}\r
466\r
4f6e31e4 467EFI_STATUS\r
468Tcp4CreateSocketCallback (\r
469 IN SOCKET *This,\r
470 IN VOID *Context\r
471 )\r
472{\r
473 EFI_STATUS Status;\r
474 TCP4_SERVICE_DATA *TcpServiceData;\r
475 EFI_IP4_PROTOCOL *Ip4;\r
476\r
477 TcpServiceData = ((TCP4_PROTO_DATA *) This->ProtoReserved)->TcpService;\r
478\r
479 //\r
480 // Open the default Ip4 protocol of IP_IO BY_DRIVER.\r
481 //\r
482 Status = gBS->OpenProtocol (\r
483 TcpServiceData->IpIo->ChildHandle,\r
484 &gEfiIp4ProtocolGuid,\r
485 (VOID **) &Ip4,\r
486 TcpServiceData->DriverBindingHandle,\r
487 This->SockHandle,\r
488 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
489 );\r
490 if (EFI_ERROR (Status)) {\r
491 return Status;\r
492 }\r
493\r
494 //\r
495 // Open the device path on the handle where service binding resides on.\r
496 //\r
497 Status = gBS->OpenProtocol (\r
498 TcpServiceData->ControllerHandle,\r
499 &gEfiDevicePathProtocolGuid,\r
500 (VOID **) &This->ParentDevicePath,\r
501 TcpServiceData->DriverBindingHandle,\r
502 This->SockHandle,\r
503 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
504 );\r
505 if (EFI_ERROR (Status)) {\r
506 gBS->CloseProtocol (\r
507 TcpServiceData->IpIo->ChildHandle,\r
508 &gEfiIp4ProtocolGuid,\r
509 TcpServiceData->DriverBindingHandle,\r
510 This->SockHandle\r
511 );\r
512 } else {\r
513 //\r
514 // Insert this socket into the SocketList.\r
515 //\r
e48e37fc 516 InsertTailList (&TcpServiceData->SocketList, &This->Link);\r
4f6e31e4 517 }\r
518\r
519 return Status;\r
520}\r
521\r
522VOID\r
523Tcp4DestroySocketCallback (\r
524 IN SOCKET *This,\r
525 IN VOID *Context\r
526 )\r
527{\r
528 TCP4_SERVICE_DATA *TcpServiceData;\r
529\r
530 TcpServiceData = ((TCP4_PROTO_DATA *) This->ProtoReserved)->TcpService;\r
531\r
532 //\r
533 // Remove this node from the list.\r
534 //\r
e48e37fc 535 RemoveEntryList (&This->Link);\r
4f6e31e4 536\r
537 //\r
538 // Close the device path protocol\r
539 //\r
540 gBS->CloseProtocol (\r
541 TcpServiceData->ControllerHandle,\r
542 &gEfiDevicePathProtocolGuid,\r
543 TcpServiceData->DriverBindingHandle,\r
544 This->SockHandle\r
545 );\r
546\r
547 //\r
548 // Close the Ip4 protocol.\r
549 //\r
550 gBS->CloseProtocol (\r
551 TcpServiceData->IpIo->ChildHandle,\r
552 &gEfiIp4ProtocolGuid,\r
553 TcpServiceData->DriverBindingHandle,\r
554 This->SockHandle\r
555 );\r
556}\r
557\r
8a67d61d 558/**\r
559 Creates a child handle with a set of TCP4 services.\r
560\r
561 @param This Protocol instance pointer.\r
562 @param ChildHandle Pointer to the handle of the child to create. If\r
563 it is NULL, then a new handle is created. If it is\r
564 not NULL, then the I/O services are added to the\r
565 existing child handle.\r
566\r
567 @retval EFI_SUCCESS The child handle is created.\r
568 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
569 @retval EFI_OUT_OF_RESOURCES There are not enough resources to create the\r
570 child.\r
571\r
572**/\r
573EFI_STATUS\r
574EFIAPI\r
575Tcp4ServiceBindingCreateChild (\r
576 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
577 IN EFI_HANDLE *ChildHandle\r
578 )\r
579{\r
580 SOCKET *Sock;\r
581 TCP4_SERVICE_DATA *TcpServiceData;\r
582 TCP4_PROTO_DATA TcpProto;\r
583 EFI_STATUS Status;\r
8a67d61d 584 EFI_TPL OldTpl;\r
585\r
586 if (NULL == This || NULL == ChildHandle) {\r
587 return EFI_INVALID_PARAMETER;\r
588 }\r
589\r
e48e37fc 590 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
4f6e31e4 591 Status = EFI_SUCCESS;\r
8a67d61d 592 TcpServiceData = TCP4_FROM_THIS (This);\r
593 TcpProto.TcpService = TcpServiceData;\r
594 TcpProto.TcpPcb = NULL;\r
595\r
596 //\r
597 // Create a tcp instance with defualt Tcp default\r
598 // sock init data and TcpProto\r
599 //\r
4f6e31e4 600 mTcp4DefaultSockData.ProtoData = &TcpProto;\r
601 mTcp4DefaultSockData.DataSize = sizeof (TCP4_PROTO_DATA);\r
8a67d61d 602 mTcp4DefaultSockData.DriverBinding = TcpServiceData->DriverBindingHandle;\r
e48e37fc 603\r
4f6e31e4 604 Sock = SockCreateChild (&mTcp4DefaultSockData);\r
8a67d61d 605 if (NULL == Sock) {\r
e48e37fc 606 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingCreateChild: "\r
8a67d61d 607 "No resource to create a Tcp Child\n"));\r
608\r
609 Status = EFI_OUT_OF_RESOURCES;\r
c4a62a12 610 } else {\r
4f6e31e4 611 *ChildHandle = Sock->SockHandle;\r
8a67d61d 612 }\r
613\r
e48e37fc 614 gBS->RestoreTPL (OldTpl);\r
8a67d61d 615 return Status;\r
616}\r
617\r
618\r
619/**\r
620 Destroys a child handle with a set of UDP4 services.\r
621\r
622 @param This Protocol instance pointer.\r
623 @param ChildHandle Handle of the child to be destroyed.\r
624\r
625 @retval EFI_SUCCESS The TCP4 services are removed from the child\r
626 handle.\r
627 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
628 @retval other The child handle is not destroyed.\r
629\r
630**/\r
631EFI_STATUS\r
632EFIAPI\r
633Tcp4ServiceBindingDestroyChild (\r
634 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
635 IN EFI_HANDLE ChildHandle\r
636 )\r
637{\r
638 EFI_STATUS Status;\r
639 EFI_TCP4_PROTOCOL *Tcp4;\r
640 SOCKET *Sock;\r
8a67d61d 641 EFI_TPL OldTpl;\r
642\r
643 if (NULL == This || NULL == ChildHandle) {\r
644 return EFI_INVALID_PARAMETER;\r
645 }\r
646\r
e48e37fc 647 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
8a67d61d 648\r
649 //\r
650 // retrieve the Tcp4 protocol from ChildHandle\r
651 //\r
652 Status = gBS->OpenProtocol (\r
653 ChildHandle,\r
654 &gEfiTcp4ProtocolGuid,\r
655 (VOID **) &Tcp4,\r
656 mTcp4DriverBinding.DriverBindingHandle,\r
657 ChildHandle,\r
658 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
659 );\r
660 if (EFI_ERROR (Status)) {\r
661 Status = EFI_UNSUPPORTED;\r
4f6e31e4 662 } else {\r
663 //\r
664 // destroy this sock and related Tcp protocol control\r
665 // block\r
666 //\r
667 Sock = SOCK_FROM_THIS (Tcp4);\r
e5e12de7 668\r
4f6e31e4 669 SockDestroyChild (Sock);\r
670 }\r
8a67d61d 671\r
e48e37fc 672 gBS->RestoreTPL (OldTpl);\r
8a67d61d 673 return Status;\r
674}\r
4f6e31e4 675\r