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