]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c
Fix coding style issues for Tcp4Dxe driver.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Tcp4Dxe / Tcp4Driver.c
... / ...
CommitLineData
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
25extern EFI_COMPONENT_NAME_PROTOCOL gTcp4ComponentName;\r
26extern EFI_COMPONENT_NAME2_PROTOCOL gTcp4ComponentName2;\r
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
48 (SOCK_STATE) 0,\r
49 NULL,\r
50 TCP_BACKLOG,\r
51 TCP_SND_BUF_SIZE,\r
52 TCP_RCV_BUF_SIZE,\r
53 &mTcp4ProtocolTemplate,\r
54 Tcp4CreateSocketCallback,\r
55 Tcp4DestroySocketCallback,\r
56 NULL,\r
57 NULL,\r
58 0,\r
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
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
100 TPL_NOTIFY,\r
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 None\r
130\r
131**/\r
132VOID\r
133Tcp4DestroyTimer ()\r
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
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
158\r
159**/\r
160EFI_STATUS\r
161EFIAPI\r
162Tcp4DriverEntryPoint (\r
163 IN EFI_HANDLE ImageHandle,\r
164 IN EFI_SYSTEM_TABLE *SystemTable\r
165 )\r
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
173 Status = EfiLibInstallDriverBindingComponentName2 (\r
174 ImageHandle,\r
175 SystemTable,\r
176 &mTcp4DriverBinding,\r
177 ImageHandle,\r
178 &gTcp4ComponentName,\r
179 &gTcp4ComponentName2\r
180 );\r
181 ASSERT_EFI_ERROR (Status);\r
182 //\r
183 // Initialize ISS and random port.\r
184 //\r
185 Seed = NetRandomInitSeed ();\r
186 mTcpGlobalIss = NET_RANDOM (Seed) % mTcpGlobalIss;\r
187 mTcp4RandomPort = (UINT16) ( TCP4_PORT_KNOWN +\r
188 (UINT16) (NET_RANDOM(Seed) % TCP4_PORT_KNOWN));\r
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
274 TcpServiceData = AllocateZeroPool (sizeof (TCP4_SERVICE_DATA));\r
275\r
276 if (NULL == TcpServiceData) {\r
277 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Have no enough"\r
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
289 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Have no enough"\r
290 " resource to create an Ip Io!\n"));\r
291\r
292 Status = EFI_OUT_OF_RESOURCES;\r
293 goto ON_ERROR;\r
294 }\r
295\r
296 //\r
297 // Configure and start IpIo.\r
298 //\r
299 ZeroMem (&OpenData, sizeof (IP_IO_OPEN_DATA));\r
300\r
301 CopyMem (&OpenData.IpConfigData, &mIpIoDefaultIpConfigData, sizeof (OpenData.IpConfigData));\r
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
308 goto ON_ERROR;\r
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
317 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Create TcpTimer"\r
318 " Event failed with %r\n", Status));\r
319\r
320 goto ON_ERROR;\r
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
337 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Install Tcp4 Service Binding"\r
338 " Protocol failed for %r\n", Status));\r
339\r
340 Tcp4DestroyTimer ();\r
341 goto ON_ERROR;\r
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
351 InitializeListHead (&TcpServiceData->SocketList);\r
352\r
353 TcpSetVariableData (TcpServiceData);\r
354\r
355 return EFI_SUCCESS;\r
356\r
357ON_ERROR:\r
358\r
359 if (TcpServiceData->IpIo != NULL) {\r
360 IpIoDestroy (TcpServiceData->IpIo);\r
361 }\r
362\r
363 gBS->FreePool (TcpServiceData);\r
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
393 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
394 TCP4_SERVICE_DATA *TcpServiceData;\r
395 SOCKET *Sock;\r
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
401 return EFI_DEVICE_ERROR;\r
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
410 (VOID **) &ServiceBinding,\r
411 This->DriverBindingHandle,\r
412 ControllerHandle,\r
413 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
414 );\r
415 if (EFI_ERROR (Status)) {\r
416\r
417 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStop: Locate Tcp4 Service "\r
418 " Binding Protocol failed with %r\n", Status));\r
419\r
420 return EFI_DEVICE_ERROR;\r
421 }\r
422\r
423 TcpServiceData = TCP4_FROM_THIS (ServiceBinding);\r
424\r
425 if (NumberOfChildren == 0) {\r
426 //\r
427 // Uninstall TCP servicebinding protocol\r
428 //\r
429 gBS->UninstallMultipleProtocolInterfaces (\r
430 NicHandle,\r
431 &gEfiTcp4ServiceBindingProtocolGuid,\r
432 ServiceBinding,\r
433 NULL\r
434 );\r
435\r
436 //\r
437 // Destroy the IpIO consumed by TCP driver\r
438 //\r
439 IpIoDestroy (TcpServiceData->IpIo);\r
440\r
441 //\r
442 // Destroy the heartbeat timer.\r
443 //\r
444 Tcp4DestroyTimer ();\r
445\r
446 //\r
447 // Clear the variable.\r
448 //\r
449 TcpClearVariableData (TcpServiceData);\r
450\r
451 //\r
452 // Release the TCP service data\r
453 //\r
454 gBS->FreePool (TcpServiceData);\r
455 } else {\r
456\r
457 while (!IsListEmpty (&TcpServiceData->SocketList)) {\r
458 Sock = NET_LIST_HEAD (&TcpServiceData->SocketList, SOCKET, Link);\r
459\r
460 ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);\r
461 }\r
462 }\r
463\r
464 return Status;\r
465}\r
466\r
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
516 InsertTailList (&TcpServiceData->SocketList, &This->Link);\r
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
535 RemoveEntryList (&This->Link);\r
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
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
584 EFI_TPL OldTpl;\r
585\r
586 if (NULL == This || NULL == ChildHandle) {\r
587 return EFI_INVALID_PARAMETER;\r
588 }\r
589\r
590 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
591 Status = EFI_SUCCESS;\r
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
600 mTcp4DefaultSockData.ProtoData = &TcpProto;\r
601 mTcp4DefaultSockData.DataSize = sizeof (TCP4_PROTO_DATA);\r
602 mTcp4DefaultSockData.DriverBinding = TcpServiceData->DriverBindingHandle;\r
603\r
604 Sock = SockCreateChild (&mTcp4DefaultSockData);\r
605 if (NULL == Sock) {\r
606 DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingCreateChild: "\r
607 "No resource to create a Tcp Child\n"));\r
608\r
609 Status = EFI_OUT_OF_RESOURCES;\r
610 } else {\r
611 *ChildHandle = Sock->SockHandle;\r
612 }\r
613\r
614 gBS->RestoreTPL (OldTpl);\r
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
641 EFI_TPL OldTpl;\r
642\r
643 if (NULL == This || NULL == ChildHandle) {\r
644 return EFI_INVALID_PARAMETER;\r
645 }\r
646\r
647 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
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
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
668\r
669 SockDestroyChild (Sock);\r
670 }\r
671\r
672 gBS->RestoreTPL (OldTpl);\r
673 return Status;\r
674}\r
675\r