]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c
Fix a conformance issue in gBS->CreateEvent() & gBS->CreateEventEx():
[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
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
101 NET_TPL_EVENT,\r
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
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
185 Status = EfiLibInstallDriverBindingComponentName2 (\r
186 ImageHandle,\r
187 SystemTable,\r
188 &mTcp4DriverBinding,\r
189 ImageHandle,\r
190 &gTcp4ComponentName,\r
191 &gTcp4ComponentName2\r
192 );\r
193 ASSERT_EFI_ERROR (Status);\r
194 //\r
195 // Initialize ISS and random port.\r
196 //\r
197 Seed = NetRandomInitSeed ();\r
198 mTcpGlobalIss = NET_RANDOM (Seed) % mTcpGlobalIss;\r
199 mTcp4RandomPort = (UINT16) ( TCP4_PORT_KNOWN +\r
200 (UINT16) (NET_RANDOM(Seed) % TCP4_PORT_KNOWN));\r
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
305 goto ON_ERROR;\r
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
313 CopyMem (&OpenData.IpConfigData, &mIpIoDefaultIpConfigData, sizeof (OpenData.IpConfigData));\r
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
320 goto ON_ERROR;\r
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
332 goto ON_ERROR;\r
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
352 Tcp4DestroyTimer ();\r
353 goto ON_ERROR;\r
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
363 NetListInit (&TcpServiceData->SocketList);\r
364\r
365 TcpSetVariableData (TcpServiceData);\r
366\r
367 return EFI_SUCCESS;\r
368\r
369ON_ERROR:\r
370\r
371 if (TcpServiceData->IpIo != NULL) {\r
372 IpIoDestroy (TcpServiceData->IpIo);\r
373 }\r
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
405 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
406 TCP4_SERVICE_DATA *TcpServiceData;\r
407 SOCKET *Sock;\r
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
413 return EFI_DEVICE_ERROR;\r
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
422 (VOID **) &ServiceBinding,\r
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
432 return EFI_DEVICE_ERROR;\r
433 }\r
434\r
435 TcpServiceData = TCP4_FROM_THIS (ServiceBinding);\r
436\r
437 if (NumberOfChildren == 0) {\r
438 //\r
439 // Uninstall TCP servicebinding protocol\r
440 //\r
441 gBS->UninstallMultipleProtocolInterfaces (\r
442 NicHandle,\r
443 &gEfiTcp4ServiceBindingProtocolGuid,\r
444 ServiceBinding,\r
445 NULL\r
446 );\r
447\r
448 //\r
449 // Destroy the IpIO consumed by TCP driver\r
450 //\r
451 IpIoDestroy (TcpServiceData->IpIo);\r
452\r
453 //\r
454 // Destroy the heartbeat timer.\r
455 //\r
456 Tcp4DestroyTimer ();\r
457\r
458 //\r
459 // Clear the variable.\r
460 //\r
461 TcpClearVariableData (TcpServiceData);\r
462\r
463 //\r
464 // Release the TCP service data\r
465 //\r
466 NetFreePool (TcpServiceData);\r
467 } else {\r
468\r
469 while (!NetListIsEmpty (&TcpServiceData->SocketList)) {\r
470 Sock = NET_LIST_HEAD (&TcpServiceData->SocketList, SOCKET, Link);\r
471\r
472 ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);\r
473 }\r
474 }\r
475\r
476 return Status;\r
477}\r
478\r
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
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
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
603 Status = EFI_SUCCESS;\r
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
612 mTcp4DefaultSockData.ProtoData = &TcpProto;\r
613 mTcp4DefaultSockData.DataSize = sizeof (TCP4_PROTO_DATA);\r
614 mTcp4DefaultSockData.DriverBinding = TcpServiceData->DriverBindingHandle;\r
615 \r
616 Sock = SockCreateChild (&mTcp4DefaultSockData);\r
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
622 } else {\r
623 *ChildHandle = Sock->SockHandle;\r
624 }\r
625\r
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
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
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
680\r
681 SockDestroyChild (Sock);\r
682 }\r
683\r
684 NET_RESTORE_TPL (OldTpl);\r
685 return Status;\r
686}\r
687\r