]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c
1. Sync the latest network stack. Add NetLibCreateIPv4DPathNode () in netlib library.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Dhcp4Dxe / Dhcp4Driver.c
CommitLineData
772db4bb 1/** @file\r
2\r
3Copyright (c) 2006 - 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
12\r
13Module Name:\r
14\r
15 Dhcp4Driver.c\r
16\r
17Abstract:\r
18\r
19\r
20**/\r
21\r
22#include "Dhcp4Impl.h"\r
23#include "Dhcp4Driver.h"\r
24\r
25EFI_DRIVER_BINDING_PROTOCOL gDhcp4DriverBinding = {\r
26 Dhcp4DriverBindingSupported,\r
27 Dhcp4DriverBindingStart,\r
28 Dhcp4DriverBindingStop,\r
29 0xa,\r
30 NULL,\r
31 NULL\r
32};\r
33\r
34EFI_SERVICE_BINDING_PROTOCOL mDhcp4ServiceBindingTemplete = {\r
35 Dhcp4ServiceBindingCreateChild,\r
36 Dhcp4ServiceBindingDestroyChild\r
37};\r
38\r
772db4bb 39\r
40EFI_STATUS\r
41EFIAPI\r
42Dhcp4DriverEntryPoint (\r
43 IN EFI_HANDLE ImageHandle,\r
44 IN EFI_SYSTEM_TABLE *SystemTable\r
45 )\r
46/*++\r
47\r
48Routine Description:\r
49\r
50 Entry point of the DHCP driver to install various protocols.\r
51\r
52Arguments:\r
53\r
54 ImageHandle - The driver's image handle\r
55 SystemTable - The system table\r
56\r
57Returns:\r
58\r
59 EFI_SUCCESS - All the related protocols are installed.\r
60 Others - Failed to install the protocols.\r
61\r
62--*/\r
63{\r
64 return NetLibInstallAllDriverProtocols (\r
65 ImageHandle,\r
66 SystemTable,\r
67 &gDhcp4DriverBinding,\r
68 ImageHandle,\r
69 &gDhcp4ComponentName,\r
70 NULL,\r
71 NULL\r
72 );\r
73}\r
74\r
75\r
76/**\r
77 Test to see if DHCP driver supports the ControllerHandle.\r
78\r
79 @param This Protocol instance pointer.\r
80 @param ControllerHandle Handle of device to test\r
81 @param RemainingDevicePath Optional parameter use to pick a specific child\r
82 device to start.\r
83\r
84 @retval EFI_SUCCES This driver supports this device\r
85 @retval other This driver does not support this device\r
86\r
87**/\r
88EFI_STATUS\r
89EFIAPI\r
90Dhcp4DriverBindingSupported (\r
91 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
92 IN EFI_HANDLE ControllerHandle,\r
93 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
94 )\r
95{\r
96 EFI_STATUS Status;\r
97\r
98 Status = gBS->OpenProtocol (\r
99 ControllerHandle,\r
100 &gEfiUdp4ServiceBindingProtocolGuid,\r
101 NULL,\r
102 This->DriverBindingHandle,\r
103 ControllerHandle,\r
104 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
105 );\r
106\r
107 return Status;\r
108}\r
109\r
110\r
111\r
112/**\r
113 Configure the default UDP child to receive all the DHCP traffics\r
114 on this network interface.\r
115\r
116 @param UdpIo The UDP IO port to configure\r
117 @param Context The context to the function\r
118\r
119 @retval EFI_SUCCESS The UDP IO port is successfully configured.\r
120 @retval Others Failed to configure the UDP child.\r
121\r
122**/\r
123EFI_STATUS\r
124DhcpConfigUdpIo (\r
125 IN UDP_IO_PORT *UdpIo,\r
126 IN VOID *Context\r
127 )\r
128{\r
129 EFI_UDP4_CONFIG_DATA UdpConfigData;\r
130\r
131 UdpConfigData.AcceptBroadcast = TRUE;\r
132 UdpConfigData.AcceptPromiscuous = FALSE;\r
133 UdpConfigData.AcceptAnyPort = FALSE;\r
134 UdpConfigData.AllowDuplicatePort = TRUE;\r
135 UdpConfigData.TypeOfService = 0;\r
136 UdpConfigData.TimeToLive = 64;\r
137 UdpConfigData.DoNotFragment = FALSE;\r
138 UdpConfigData.ReceiveTimeout = 0;\r
139 UdpConfigData.TransmitTimeout = 0;\r
140\r
141 UdpConfigData.UseDefaultAddress = FALSE;\r
142 UdpConfigData.StationPort = DHCP_CLIENT_PORT;\r
143 UdpConfigData.RemotePort = DHCP_SERVER_PORT;\r
144\r
145 NetZeroMem (&UdpConfigData.StationAddress, sizeof (EFI_IPv4_ADDRESS));\r
146 NetZeroMem (&UdpConfigData.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
147 NetZeroMem (&UdpConfigData.RemoteAddress, sizeof (EFI_IPv4_ADDRESS));\r
148\r
149 return UdpIo->Udp->Configure (UdpIo->Udp, &UdpConfigData);;\r
150}\r
151\r
152\r
153\r
154/**\r
155 Destory the DHCP service. The Dhcp4 service may be partly initialized,\r
156 or partly destoried. If a resource is destoried, it is marked as so in\r
157 case the destory failed and being called again later.\r
158\r
159 @param DhcpSb The DHCP service instance to destory.\r
160\r
161 @retval EFI_SUCCESS The DHCP service is successfully closed.\r
162\r
163**/\r
164EFI_STATUS\r
165Dhcp4CloseService (\r
166 IN DHCP_SERVICE *DhcpSb\r
167 )\r
168{\r
169 DhcpCleanLease (DhcpSb);\r
170\r
171 if (DhcpSb->UdpIo != NULL) {\r
172 UdpIoFreePort (DhcpSb->UdpIo);\r
173 DhcpSb->UdpIo = NULL;\r
174 }\r
175\r
176 if (DhcpSb->Timer != NULL) {\r
177 gBS->SetTimer (DhcpSb->Timer, TimerCancel, 0);\r
178 gBS->CloseEvent (DhcpSb->Timer);\r
179\r
180 DhcpSb->Timer = NULL;\r
181 }\r
182\r
183 return EFI_SUCCESS;\r
184}\r
185\r
186\r
187\r
188/**\r
189 Create a new DHCP service binding instance for the controller.\r
190\r
191 @param Controller The controller to install DHCP service binding\r
192 protocol onto\r
193 @param ImageHandle The driver's image handle\r
194 @param Service The variable to receive the created DHCP service\r
195 instance.\r
196\r
197 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource .\r
198 @retval EFI_SUCCESS The DHCP service instance is created.\r
199\r
200**/\r
201EFI_STATUS\r
202Dhcp4CreateService (\r
203 IN EFI_HANDLE Controller,\r
204 IN EFI_HANDLE ImageHandle,\r
205 OUT DHCP_SERVICE **Service\r
206 )\r
207{\r
208 DHCP_SERVICE *DhcpSb;\r
209 EFI_STATUS Status;\r
210\r
211 *Service = NULL;\r
212 DhcpSb = NetAllocateZeroPool (sizeof (DHCP_SERVICE));\r
213\r
214 if (DhcpSb == NULL) {\r
215 return EFI_OUT_OF_RESOURCES;\r
216 }\r
217\r
218 DhcpSb->Signature = DHCP_SERVICE_SIGNATURE;\r
219 DhcpSb->ServiceBinding = mDhcp4ServiceBindingTemplete;\r
220 DhcpSb->ServiceState = DHCP_UNCONFIGED;\r
221 DhcpSb->InDestory = FALSE;\r
222 DhcpSb->Controller = Controller;\r
223 DhcpSb->Image = ImageHandle;\r
224 NetListInit (&DhcpSb->Children);\r
225 DhcpSb->DhcpState = Dhcp4Stopped;\r
226 DhcpSb->Xid = NET_RANDOM (NetRandomInitSeed ());\r
227\r
228 //\r
229 // Create various resources, UdpIo, Timer, and get Mac address\r
230 //\r
231 Status = gBS->CreateEvent (\r
232 EVT_NOTIFY_SIGNAL | EVT_TIMER,\r
233 TPL_CALLBACK,\r
234 DhcpOnTimerTick,\r
235 DhcpSb,\r
236 &DhcpSb->Timer\r
237 );\r
238\r
239 if (EFI_ERROR (Status)) {\r
240 goto ON_ERROR;\r
241 }\r
242\r
243 DhcpSb->UdpIo = UdpIoCreatePort (Controller, ImageHandle, DhcpConfigUdpIo, NULL);\r
244\r
245 if (DhcpSb->UdpIo == NULL) {\r
246 Status = EFI_OUT_OF_RESOURCES;\r
247 goto ON_ERROR;\r
248 }\r
249\r
250 DhcpSb->HwLen = (UINT8) DhcpSb->UdpIo->SnpMode.HwAddressSize;\r
251 DhcpSb->HwType = DhcpSb->UdpIo->SnpMode.IfType;\r
687a2e5f 252 CopyMem (&DhcpSb->Mac, &DhcpSb->UdpIo->SnpMode.CurrentAddress, sizeof (DhcpSb->Mac));\r
772db4bb 253\r
254 *Service = DhcpSb;\r
255 return EFI_SUCCESS;\r
256\r
257ON_ERROR:\r
258 Dhcp4CloseService (DhcpSb);\r
259 NetFreePool (DhcpSb);\r
260\r
261 return Status;\r
262}\r
263\r
264\r
265/**\r
266 Start this driver on ControllerHandle.\r
267\r
268 @param This Protocol instance pointer.\r
269 @param ControllerHandle Handle of device to bind driver to\r
270 @param RemainingDevicePath Optional parameter use to pick a specific child\r
271 device to start.\r
272\r
273 @retval EFI_SUCCES This driver is added to ControllerHandle\r
274 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle\r
275 @retval other This driver does not support this device\r
276\r
277**/\r
278EFI_STATUS\r
279EFIAPI\r
280Dhcp4DriverBindingStart (\r
281 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
282 IN EFI_HANDLE ControllerHandle,\r
283 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
284 )\r
285{\r
286 DHCP_SERVICE *DhcpSb;\r
287 EFI_STATUS Status;\r
288\r
289 //\r
290 // First: test for the DHCP4 Protocol\r
291 //\r
292 Status = gBS->OpenProtocol (\r
293 ControllerHandle,\r
294 &gEfiDhcp4ServiceBindingProtocolGuid,\r
295 NULL,\r
296 This->DriverBindingHandle,\r
297 ControllerHandle,\r
298 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
299 );\r
300\r
301 if (Status == EFI_SUCCESS) {\r
302 return EFI_ALREADY_STARTED;\r
303 }\r
304\r
305 Status = Dhcp4CreateService (ControllerHandle, This->DriverBindingHandle, &DhcpSb);\r
306\r
307 if (EFI_ERROR (Status)) {\r
308 return Status;\r
309 }\r
310\r
311 Status = gBS->SetTimer (DhcpSb->Timer, TimerPeriodic, TICKS_PER_SECOND);\r
312\r
313 if (EFI_ERROR (Status)) {\r
314 goto ON_ERROR;\r
315 }\r
316\r
317 //\r
318 // Install the Dhcp4ServiceBinding Protocol onto ControlerHandle\r
319 //\r
320 Status = gBS->InstallMultipleProtocolInterfaces (\r
321 &ControllerHandle,\r
322 &gEfiDhcp4ServiceBindingProtocolGuid,\r
323 &DhcpSb->ServiceBinding,\r
324 NULL\r
325 );\r
326\r
327 if (EFI_ERROR (Status)) {\r
328 goto ON_ERROR;\r
329 }\r
330\r
331 return Status;\r
332\r
333ON_ERROR:\r
334 Dhcp4CloseService (DhcpSb);\r
335 NetFreePool (DhcpSb);\r
336 return Status;\r
337}\r
338\r
339\r
340/**\r
341 Stop this driver on ControllerHandle.\r
342\r
343 @param This Protocol instance pointer.\r
344 @param ControllerHandle Handle of device to stop driver on\r
345 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number\r
346 of children is zero stop the entire bus driver.\r
347 @param ChildHandleBuffer List of Child Handles to Stop.\r
348\r
349 @retval EFI_SUCCES This driver is removed ControllerHandle\r
350 @retval other This driver was not removed from this device\r
351\r
352**/\r
353EFI_STATUS\r
354EFIAPI\r
355Dhcp4DriverBindingStop (\r
356 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
357 IN EFI_HANDLE ControllerHandle,\r
358 IN UINTN NumberOfChildren,\r
359 IN EFI_HANDLE *ChildHandleBuffer\r
360 )\r
361{\r
362 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
363 DHCP_SERVICE *DhcpSb;\r
364 DHCP_PROTOCOL *Instance;\r
365 EFI_HANDLE NicHandle;\r
366 EFI_STATUS Status;\r
367 EFI_TPL OldTpl;\r
368\r
369 //\r
370 // DHCP driver opens UDP child, So, the ControllerHandle is the\r
371 // UDP child handle. locate the Nic handle first.\r
372 //\r
373 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid);\r
374\r
375 if (NicHandle == NULL) {\r
376 return EFI_SUCCESS;\r
377 }\r
378\r
379 Status = gBS->OpenProtocol (\r
380 NicHandle,\r
381 &gEfiDhcp4ServiceBindingProtocolGuid,\r
382 (VOID **) &ServiceBinding,\r
383 This->DriverBindingHandle,\r
384 NicHandle,\r
385 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
386 );\r
387\r
388 if (EFI_ERROR (Status)) {\r
389 return EFI_DEVICE_ERROR;\r
390 }\r
391\r
392 DhcpSb = DHCP_SERVICE_FROM_THIS (ServiceBinding);\r
393\r
394 if (DhcpSb->InDestory) {\r
395 return EFI_SUCCESS;\r
396 }\r
397\r
398 OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);\r
399 DhcpSb->InDestory = TRUE;\r
400\r
401 //\r
402 // Don't use NET_LIST_FOR_EACH_SAFE here, Dhcp4ServiceBindingDestoryChild\r
403 // may cause other child to be deleted.\r
404 //\r
405 while (!NetListIsEmpty (&DhcpSb->Children)) {\r
406 Instance = NET_LIST_HEAD (&DhcpSb->Children, DHCP_PROTOCOL, Link);\r
407 Dhcp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);\r
408 }\r
409\r
410 if (DhcpSb->NumChildren != 0) {\r
411 Status = EFI_DEVICE_ERROR;\r
412 goto ON_ERROR;\r
413 }\r
414\r
415 DhcpSb->ServiceState = DHCP_DESTORY;\r
416\r
417 Status = gBS->UninstallProtocolInterface (\r
418 NicHandle,\r
419 &gEfiDhcp4ServiceBindingProtocolGuid,\r
420 ServiceBinding\r
421 );\r
422\r
423 if (EFI_ERROR (Status)) {\r
424 goto ON_ERROR;\r
425 }\r
426\r
427 Dhcp4CloseService (DhcpSb);\r
428 NET_RESTORE_TPL (OldTpl);\r
429\r
430 NetFreePool (DhcpSb);\r
431 return EFI_SUCCESS;\r
432\r
433ON_ERROR:\r
434 DhcpSb->InDestory = FALSE;\r
435 NET_RESTORE_TPL (OldTpl);\r
436 return Status;\r
437}\r
438\r
439\r
440/**\r
441 Initialize a new DHCP child\r
442\r
443 @param DhcpSb The dhcp service instance\r
444 @param Instance The dhcp instance to initialize\r
445\r
446 @return None\r
447\r
448**/\r
449VOID\r
450DhcpInitProtocol (\r
451 IN DHCP_SERVICE *DhcpSb,\r
452 IN DHCP_PROTOCOL *Instance\r
453 )\r
454{\r
455 Instance->Signature = DHCP_PROTOCOL_SIGNATURE;\r
687a2e5f 456 CopyMem (&Instance->Dhcp4Protocol, &mDhcp4ProtocolTemplate, sizeof (Instance->Dhcp4Protocol));\r
772db4bb 457 NetListInit (&Instance->Link);\r
458 Instance->Handle = NULL;\r
459 Instance->Service = DhcpSb;\r
460 Instance->InDestory = FALSE;\r
461 Instance->CompletionEvent = NULL;\r
462 Instance->RenewRebindEvent = NULL;\r
463 Instance->Token = NULL;\r
464}\r
465\r
466\r
467/**\r
468 Creates a child handle with a set of DHCP4 services.\r
469\r
470 @param This Protocol instance pointer.\r
471 @param ChildHandle Pointer to the handle of the child to create. If\r
472 it is NULL, then a new handle is created. If it\r
473 is not NULL, then the DHCP4 services are added to\r
474 the existing child handle.\r
475\r
476 @retval EFI_SUCCES The child handle was created with the DHCP4\r
477 services\r
478 @retval EFI_OUT_OF_RESOURCES There are not enough resources to create the child\r
479 @retval other The child handle was not created\r
480\r
481**/\r
482EFI_STATUS\r
483EFIAPI\r
484Dhcp4ServiceBindingCreateChild (\r
485 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
486 IN EFI_HANDLE *ChildHandle\r
487 )\r
488{\r
489 DHCP_SERVICE *DhcpSb;\r
490 DHCP_PROTOCOL *Instance;\r
491 EFI_STATUS Status;\r
492 EFI_TPL OldTpl;\r
493 VOID *Udp4;\r
494\r
495 if ((This == NULL) || (ChildHandle == NULL)) {\r
496 return EFI_INVALID_PARAMETER;\r
497 }\r
498\r
499 Instance = NetAllocatePool (sizeof (*Instance));\r
500\r
501 if (Instance == NULL) {\r
502 return EFI_OUT_OF_RESOURCES;\r
503 }\r
504\r
505 DhcpSb = DHCP_SERVICE_FROM_THIS (This);\r
506 DhcpInitProtocol (DhcpSb, Instance);\r
507\r
508 //\r
509 // Install DHCP4 onto ChildHandle\r
510 //\r
511 Status = gBS->InstallMultipleProtocolInterfaces (\r
512 ChildHandle,\r
513 &gEfiDhcp4ProtocolGuid,\r
514 &Instance->Dhcp4Protocol,\r
515 NULL\r
516 );\r
517\r
518 if (EFI_ERROR (Status)) {\r
519 NetFreePool (Instance);\r
520 return Status;\r
521 }\r
522\r
523 Instance->Handle = *ChildHandle;\r
524\r
525 //\r
526 // Open the Udp4 protocol BY_CHILD.\r
527 //\r
528 Status = gBS->OpenProtocol (\r
529 DhcpSb->UdpIo->UdpHandle,\r
530 &gEfiUdp4ProtocolGuid,\r
531 (VOID **) &Udp4,\r
532 gDhcp4DriverBinding.DriverBindingHandle,\r
533 Instance->Handle,\r
534 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
535 );\r
536 if (EFI_ERROR (Status)) {\r
537 gBS->UninstallMultipleProtocolInterfaces (\r
538 Instance->Handle,\r
539 &gEfiDhcp4ProtocolGuid,\r
540 &Instance->Dhcp4Protocol,\r
541 NULL\r
542 );\r
543\r
544 NetFreePool (Instance);\r
545 return Status;\r
546 }\r
547\r
548 OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);\r
549\r
550 NetListInsertTail (&DhcpSb->Children, &Instance->Link);\r
551 DhcpSb->NumChildren++;\r
552\r
553 NET_RESTORE_TPL (OldTpl);\r
554\r
555 return EFI_SUCCESS;\r
556}\r
557\r
558\r
559/**\r
560 Destroys a child handle with a set of DHCP4 services.\r
561\r
562 @param This Protocol instance pointer.\r
563 @param ChildHandle Handle of the child to destroy\r
564\r
565 @retval EFI_SUCCES The DHCP4 service is removed from the child handle\r
566 @retval EFI_UNSUPPORTED The child handle does not support the DHCP4\r
567 service\r
568 @retval EFI_INVALID_PARAMETER Child handle is not a valid EFI Handle.\r
569 @retval EFI_ACCESS_DENIED The child handle could not be destroyed because\r
570 its DHCP4 services are being used.\r
571 @retval other The child handle was not destroyed\r
572\r
573**/\r
574EFI_STATUS\r
575EFIAPI\r
576Dhcp4ServiceBindingDestroyChild (\r
577 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
578 IN EFI_HANDLE ChildHandle\r
579 )\r
580{\r
581 DHCP_SERVICE *DhcpSb;\r
582 DHCP_PROTOCOL *Instance;\r
583 EFI_DHCP4_PROTOCOL *Dhcp;\r
584 EFI_TPL OldTpl;\r
585 EFI_STATUS Status;\r
586\r
587 if ((This == NULL) || (ChildHandle == NULL)) {\r
588 return EFI_INVALID_PARAMETER;\r
589 }\r
590\r
591 //\r
592 // Retrieve the private context data structures\r
593 //\r
594 Status = gBS->OpenProtocol (\r
595 ChildHandle,\r
596 &gEfiDhcp4ProtocolGuid,\r
597 (VOID **) &Dhcp,\r
598 gDhcp4DriverBinding.DriverBindingHandle,\r
599 ChildHandle,\r
600 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
601 );\r
602\r
603 if (EFI_ERROR (Status)) {\r
604 return EFI_UNSUPPORTED;\r
605 }\r
606\r
607 Instance = DHCP_INSTANCE_FROM_THIS (Dhcp);\r
608 DhcpSb = DHCP_SERVICE_FROM_THIS (This);\r
609\r
610 if (Instance->Service != DhcpSb) {\r
611 return EFI_INVALID_PARAMETER;\r
612 }\r
613\r
614 //\r
615 // A child can be destoried more than once. For example,\r
616 // Dhcp4DriverBindingStop will destory all of its children.\r
617 // when caller driver is being stopped, it will destory the\r
618 // dhcp child it opens.\r
619 //\r
620 if (Instance->InDestory) {\r
621 return EFI_SUCCESS;\r
622 }\r
623\r
624 OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);\r
625 Instance->InDestory = TRUE;\r
626\r
627 //\r
628 // Close the Udp4 protocol.\r
629 //\r
630 gBS->CloseProtocol (\r
631 DhcpSb->UdpIo->UdpHandle,\r
632 &gEfiUdp4ProtocolGuid,\r
633 gDhcp4DriverBinding.DriverBindingHandle,\r
634 ChildHandle\r
635 );\r
636\r
637 //\r
638 // Uninstall the DHCP4 protocol first to enable a top down destruction.\r
639 //\r
640 Status = gBS->UninstallProtocolInterface (\r
641 ChildHandle,\r
642 &gEfiDhcp4ProtocolGuid,\r
643 Dhcp\r
644 );\r
645\r
646 if (EFI_ERROR (Status)) {\r
647 Instance->InDestory = FALSE;\r
648\r
649 NET_RESTORE_TPL (OldTpl);\r
650 return Status;\r
651 }\r
652\r
653 if (DhcpSb->ActiveChild == Instance) {\r
654 DhcpYieldControl (DhcpSb);\r
655 }\r
656\r
657 NetListRemoveEntry (&Instance->Link);\r
658 DhcpSb->NumChildren--;\r
659\r
660 NET_RESTORE_TPL (OldTpl);\r
661\r
662 NetFreePool (Instance);\r
663 return EFI_SUCCESS;\r
664}\r