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