]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c
Roll back the DEBUG mask change which cause SerialIo read_conf test item failure.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Mtftp4Dxe / Mtftp4Driver.c
CommitLineData
772db4bb 1/** @file\r
dab714aa 2 Implementation of Mtftp drivers.\r
3 \r
4Copyright (c) 2006 - 2007, Intel Corporation<BR>\r
772db4bb 5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
dab714aa 8http://opensource.org/licenses/bsd-license.php<BR>\r
772db4bb 9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
772db4bb 13**/\r
14\r
15#include "Mtftp4Impl.h"\r
16\r
17EFI_DRIVER_BINDING_PROTOCOL gMtftp4DriverBinding = {\r
18 Mtftp4DriverBindingSupported,\r
19 Mtftp4DriverBindingStart,\r
20 Mtftp4DriverBindingStop,\r
21 0xa,\r
22 NULL,\r
23 NULL\r
24};\r
25\r
26EFI_SERVICE_BINDING_PROTOCOL gMtftp4ServiceBindingTemplete = {\r
27 Mtftp4ServiceBindingCreateChild,\r
28 Mtftp4ServiceBindingDestroyChild\r
29};\r
30\r
dab714aa 31\r
32/**\r
33 The driver entry point which installs multiple protocols to the ImageHandle.\r
34\r
35 @param ImageHandle The MTFTP's image handle.\r
36 @param SystemTable The system table.\r
37\r
38 @retval EFI_SUCCESS The handles are successfully installed on the image. \r
39 @retval others some EFI_ERROR occured.\r
40\r
41**/\r
772db4bb 42EFI_STATUS\r
43EFIAPI\r
44Mtftp4DriverEntryPoint (\r
45 IN EFI_HANDLE ImageHandle,\r
46 IN EFI_SYSTEM_TABLE *SystemTable\r
47 )\r
772db4bb 48{\r
83cbd279 49 return EfiLibInstallDriverBindingComponentName2 (\r
772db4bb 50 ImageHandle,\r
51 SystemTable,\r
52 &gMtftp4DriverBinding,\r
53 ImageHandle,\r
54 &gMtftp4ComponentName,\r
83cbd279 55 &gMtftp4ComponentName2\r
772db4bb 56 );\r
57}\r
58\r
59\r
60/**\r
61 Test whether MTFTP driver support this controller.\r
62\r
63 @param This The MTFTP driver binding instance\r
64 @param Controller The controller to test\r
65 @param RemainingDevicePath The remaining device path\r
66\r
67 @retval EFI_SUCCESS The controller has UDP service binding protocol\r
68 installed, MTFTP can support it.\r
69 @retval Others MTFTP can't support the controller.\r
70\r
71**/\r
72EFI_STATUS\r
dab714aa 73EFIAPI\r
772db4bb 74Mtftp4DriverBindingSupported (\r
75 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
76 IN EFI_HANDLE Controller,\r
77 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
78 )\r
79{\r
80 EFI_STATUS Status;\r
81\r
82 Status = gBS->OpenProtocol (\r
83 Controller,\r
84 &gEfiUdp4ServiceBindingProtocolGuid,\r
85 NULL,\r
86 This->DriverBindingHandle,\r
87 Controller,\r
88 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
89 );\r
90\r
91 return Status;\r
92}\r
93\r
94\r
95/**\r
dab714aa 96 Config a NULL UDP that is used to keep the connection between UDP and MTFTP. \r
97 \r
98 Just leave the Udp child unconfigured. When UDP is unloaded, \r
99 MTFTP will be informed with DriverBinding Stop.\r
772db4bb 100\r
101 @param UdpIo The UDP port to configure\r
102 @param Context The opaque parameter to the callback\r
103\r
104 @retval EFI_SUCCESS It always return EFI_SUCCESS directly.\r
105\r
106**/\r
107EFI_STATUS\r
108Mtftp4ConfigNullUdp (\r
109 IN UDP_IO_PORT *UdpIo,\r
110 IN VOID *Context\r
111 )\r
112{\r
113 return EFI_SUCCESS;\r
114}\r
115\r
116\r
117/**\r
118 Create then initialize a MTFTP service binding instance.\r
119\r
120 @param Controller The controller to install the MTFTP service\r
121 binding on\r
122 @param Image The driver binding image of the MTFTP driver\r
123 @param Service The variable to receive the created service\r
124 binding instance.\r
125\r
126 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the instance\r
127 @retval EFI_DEVICE_ERROR Failed to create a NULL UDP port to keep\r
128 connection with UDP.\r
129 @retval EFI_SUCCESS The service instance is created for the\r
130 controller.\r
131\r
132**/\r
133EFI_STATUS\r
134Mtftp4CreateService (\r
dab714aa 135 IN EFI_HANDLE Controller,\r
136 IN EFI_HANDLE Image,\r
137 OUT MTFTP4_SERVICE **Service\r
772db4bb 138 )\r
139{\r
140 MTFTP4_SERVICE *MtftpSb;\r
141 EFI_STATUS Status;\r
142\r
143 *Service = NULL;\r
e48e37fc 144 MtftpSb = AllocatePool (sizeof (MTFTP4_SERVICE));\r
772db4bb 145\r
146 if (MtftpSb == NULL) {\r
147 return EFI_OUT_OF_RESOURCES;\r
148 }\r
149\r
150 MtftpSb->Signature = MTFTP4_SERVICE_SIGNATURE;\r
151 MtftpSb->ServiceBinding = gMtftp4ServiceBindingTemplete;\r
152 MtftpSb->InDestory = FALSE;\r
153 MtftpSb->ChildrenNum = 0;\r
e48e37fc 154 InitializeListHead (&MtftpSb->Children);\r
772db4bb 155\r
156 MtftpSb->Timer = NULL;\r
157 MtftpSb->TimerToGetMap = NULL;\r
158 MtftpSb->Controller = Controller;\r
159 MtftpSb->Image = Image;\r
160 MtftpSb->ConnectUdp = NULL;\r
161\r
162 //\r
163 // Create the timer and a udp to be notified when UDP is uninstalled\r
164 //\r
165 Status = gBS->CreateEvent (\r
166 EVT_NOTIFY_SIGNAL | EVT_TIMER,\r
e48e37fc 167 TPL_CALLBACK,\r
772db4bb 168 Mtftp4OnTimerTick,\r
169 MtftpSb,\r
170 &MtftpSb->Timer\r
171 );\r
172\r
173 if (EFI_ERROR (Status)) {\r
e48e37fc 174 gBS->FreePool (MtftpSb);\r
772db4bb 175 return Status;\r
176 }\r
177\r
178 //\r
179 // Create the timer used to time out the procedure which is used to\r
180 // get the default IP address.\r
181 //\r
182 Status = gBS->CreateEvent (\r
183 EVT_TIMER,\r
e48e37fc 184 TPL_CALLBACK,\r
772db4bb 185 NULL,\r
186 NULL,\r
187 &MtftpSb->TimerToGetMap\r
188 );\r
189 if (EFI_ERROR (Status)) {\r
190 gBS->CloseEvent (MtftpSb->Timer);\r
e48e37fc 191 gBS->FreePool (MtftpSb);\r
772db4bb 192 return Status;\r
193 }\r
194\r
195 MtftpSb->ConnectUdp = UdpIoCreatePort (Controller, Image, Mtftp4ConfigNullUdp, NULL);\r
196\r
197 if (MtftpSb->ConnectUdp == NULL) {\r
198 gBS->CloseEvent (MtftpSb->TimerToGetMap);\r
199 gBS->CloseEvent (MtftpSb->Timer);\r
e48e37fc 200 gBS->FreePool (MtftpSb);\r
772db4bb 201 return EFI_DEVICE_ERROR;\r
202 }\r
203\r
204 *Service = MtftpSb;\r
205 return EFI_SUCCESS;\r
206}\r
207\r
208\r
209/**\r
210 Release all the resource used the MTFTP service binding instance.\r
211\r
212 @param MtftpSb The MTFTP service binding instance.\r
213\r
772db4bb 214**/\r
215VOID\r
216Mtftp4CleanService (\r
217 IN MTFTP4_SERVICE *MtftpSb\r
218 )\r
219{\r
220 UdpIoFreePort (MtftpSb->ConnectUdp);\r
221 gBS->CloseEvent (MtftpSb->TimerToGetMap);\r
222 gBS->CloseEvent (MtftpSb->Timer);\r
223}\r
224\r
225\r
226/**\r
dab714aa 227 Start the MTFTP driver on this controller. \r
228 \r
229 MTFTP driver will install a MTFTP SERVICE BINDING protocol on the supported\r
772db4bb 230 controller, which can be used to create/destroy MTFTP children.\r
231\r
232 @param This The MTFTP driver binding protocol.\r
233 @param Controller The controller to manage.\r
234 @param RemainingDevicePath Remaining device path.\r
235\r
236 @retval EFI_ALREADY_STARTED The MTFTP service binding protocol has been\r
237 started on the controller.\r
238 @retval EFI_SUCCESS The MTFTP service binding is installed on the\r
239 controller.\r
240\r
241**/\r
242EFI_STATUS\r
dab714aa 243EFIAPI\r
772db4bb 244Mtftp4DriverBindingStart (\r
245 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
246 IN EFI_HANDLE Controller,\r
247 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
248 )\r
249{\r
250 MTFTP4_SERVICE *MtftpSb;\r
251 EFI_STATUS Status;\r
252\r
253 //\r
254 // Directly return if driver is already running.\r
255 //\r
256 Status = gBS->OpenProtocol (\r
257 Controller,\r
258 &gEfiMtftp4ServiceBindingProtocolGuid,\r
259 NULL,\r
260 This->DriverBindingHandle,\r
261 Controller,\r
262 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
263 );\r
264\r
265 if (Status == EFI_SUCCESS) {\r
266 return EFI_ALREADY_STARTED;\r
267 }\r
268\r
269 Status = Mtftp4CreateService (Controller, This->DriverBindingHandle, &MtftpSb);\r
270\r
271 if (EFI_ERROR (Status)) {\r
272 return Status;\r
273 }\r
274\r
275 Status = gBS->SetTimer (MtftpSb->Timer, TimerPeriodic, TICKS_PER_SECOND);\r
276\r
277 if (EFI_ERROR (Status)) {\r
278 goto ON_ERROR;\r
279 }\r
280\r
281 //\r
282 // Install the Mtftp4ServiceBinding Protocol onto Controller\r
283 //\r
284 Status = gBS->InstallMultipleProtocolInterfaces (\r
285 &Controller,\r
286 &gEfiMtftp4ServiceBindingProtocolGuid,\r
287 &MtftpSb->ServiceBinding,\r
288 NULL\r
289 );\r
290\r
291 if (EFI_ERROR (Status)) {\r
292 goto ON_ERROR;\r
293 }\r
294\r
295 return EFI_SUCCESS;\r
296\r
297ON_ERROR:\r
298 Mtftp4CleanService (MtftpSb);\r
e48e37fc 299 gBS->FreePool (MtftpSb);\r
772db4bb 300\r
301 return Status;\r
302}\r
303\r
304\r
305/**\r
306 Stop the MTFTP driver on controller. The controller is a UDP\r
307 child handle.\r
308\r
309 @param This The MTFTP driver binding protocol\r
310 @param Controller The controller to stop\r
311 @param NumberOfChildren The number of children\r
312 @param ChildHandleBuffer The array of the child handle.\r
313\r
314 @retval EFI_SUCCESS The driver is stopped on the controller.\r
315 @retval EFI_DEVICE_ERROR Failed to stop the driver on the controller.\r
316\r
317**/\r
318EFI_STATUS\r
dab714aa 319EFIAPI\r
772db4bb 320Mtftp4DriverBindingStop (\r
dab714aa 321 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
322 IN EFI_HANDLE Controller,\r
323 IN UINTN NumberOfChildren,\r
324 IN EFI_HANDLE *ChildHandleBuffer\r
772db4bb 325 )\r
326{\r
327 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
328 MTFTP4_SERVICE *MtftpSb;\r
329 MTFTP4_PROTOCOL *Instance;\r
330 EFI_HANDLE NicHandle;\r
331 EFI_STATUS Status;\r
332 EFI_TPL OldTpl;\r
333\r
334 //\r
335 // MTFTP driver opens UDP child, So, Controller is a UDP\r
336 // child handle. Locate the Nic handle first. Then get the\r
337 // MTFTP private data back.\r
338 //\r
339 NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp4ProtocolGuid);\r
340\r
341 if (NicHandle == NULL) {\r
c4a62a12 342 return EFI_DEVICE_ERROR;\r
772db4bb 343 }\r
344\r
345 Status = gBS->OpenProtocol (\r
346 NicHandle,\r
347 &gEfiMtftp4ServiceBindingProtocolGuid,\r
348 (VOID **) &ServiceBinding,\r
349 This->DriverBindingHandle,\r
350 NicHandle,\r
351 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
352 );\r
353\r
354 if (EFI_ERROR (Status)) {\r
355 return EFI_DEVICE_ERROR;\r
356 }\r
357\r
358 MtftpSb = MTFTP4_SERVICE_FROM_THIS (ServiceBinding);\r
359\r
360 if (MtftpSb->InDestory) {\r
361 return EFI_SUCCESS;\r
362 }\r
363\r
e48e37fc 364 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
772db4bb 365\r
c4a62a12 366 if (NumberOfChildren == 0) {\r
772db4bb 367\r
c4a62a12 368 MtftpSb->InDestory = TRUE;\r
772db4bb 369\r
c4a62a12 370 gBS->UninstallProtocolInterface (\r
371 NicHandle,\r
372 &gEfiMtftp4ServiceBindingProtocolGuid,\r
373 ServiceBinding\r
374 );\r
772db4bb 375\r
c4a62a12 376 Mtftp4CleanService (MtftpSb);\r
772db4bb 377\r
e48e37fc 378 gBS->FreePool (MtftpSb);\r
c4a62a12 379 } else {\r
772db4bb 380\r
e48e37fc 381 while (!IsListEmpty (&MtftpSb->Children)) {\r
c4a62a12 382 Instance = NET_LIST_HEAD (&MtftpSb->Children, MTFTP4_PROTOCOL, Link);\r
383 Mtftp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);\r
384 }\r
772db4bb 385\r
c4a62a12 386 if (MtftpSb->ChildrenNum != 0) {\r
387 Status = EFI_DEVICE_ERROR;\r
388 }\r
389 }\r
772db4bb 390\r
e48e37fc 391 gBS->RestoreTPL (OldTpl);\r
772db4bb 392 return Status;\r
393}\r
394\r
395\r
396/**\r
397 Initialize a MTFTP protocol instance which is the child of MtftpSb.\r
398\r
399 @param MtftpSb The MTFTP service binding protocol.\r
400 @param Instance The MTFTP instance to initialize.\r
401\r
772db4bb 402**/\r
403VOID\r
404Mtftp4InitProtocol (\r
dab714aa 405 IN MTFTP4_SERVICE *MtftpSb,\r
406 OUT MTFTP4_PROTOCOL *Instance\r
772db4bb 407 )\r
408{\r
e48e37fc 409 ZeroMem (Instance, sizeof (MTFTP4_PROTOCOL));\r
772db4bb 410\r
411 Instance->Signature = MTFTP4_PROTOCOL_SIGNATURE;\r
e48e37fc 412 InitializeListHead (&Instance->Link);\r
687a2e5f 413 CopyMem (&Instance->Mtftp4, &gMtftp4ProtocolTemplate, sizeof (Instance->Mtftp4));\r
772db4bb 414 Instance->State = MTFTP4_STATE_UNCONFIGED;\r
dab714aa 415 Instance->InDestory = FALSE;\r
772db4bb 416 Instance->Service = MtftpSb;\r
417\r
e48e37fc 418 InitializeListHead (&Instance->Blocks);\r
772db4bb 419}\r
420\r
421\r
422/**\r
423 Create a MTFTP child for the service binding instance, then\r
424 install the MTFTP protocol to the ChildHandle.\r
425\r
426 @param This The MTFTP service binding instance.\r
427 @param ChildHandle The Child handle to install the MTFTP protocol.\r
428\r
429 @retval EFI_INVALID_PARAMETER The parameter is invalid.\r
430 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource for the new child.\r
431 @retval EFI_SUCCESS The child is successfully create.\r
432\r
433**/\r
434EFI_STATUS\r
dab714aa 435EFIAPI\r
772db4bb 436Mtftp4ServiceBindingCreateChild (\r
437 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
dab714aa 438 IN EFI_HANDLE *ChildHandle\r
772db4bb 439 )\r
440{\r
441 MTFTP4_SERVICE *MtftpSb;\r
442 MTFTP4_PROTOCOL *Instance;\r
443 EFI_STATUS Status;\r
444 EFI_TPL OldTpl;\r
445 VOID *Udp4;\r
446\r
447 if ((This == NULL) || (ChildHandle == NULL)) {\r
448 return EFI_INVALID_PARAMETER;\r
449 }\r
450\r
e48e37fc 451 Instance = AllocatePool (sizeof (*Instance));\r
772db4bb 452\r
453 if (Instance == NULL) {\r
454 return EFI_OUT_OF_RESOURCES;\r
455 }\r
456\r
457 MtftpSb = MTFTP4_SERVICE_FROM_THIS (This);\r
458\r
459 Mtftp4InitProtocol (MtftpSb, Instance);\r
460\r
461 Instance->UnicastPort = UdpIoCreatePort (\r
462 MtftpSb->Controller,\r
463 MtftpSb->Image,\r
464 Mtftp4ConfigNullUdp,\r
465 Instance\r
466 );\r
467\r
468 if (Instance->UnicastPort == NULL) {\r
e48e37fc 469 gBS->FreePool (Instance);\r
772db4bb 470 return EFI_OUT_OF_RESOURCES;\r
471 }\r
472\r
473 //\r
474 // Install the MTFTP protocol onto ChildHandle\r
475 //\r
476 Status = gBS->InstallMultipleProtocolInterfaces (\r
477 ChildHandle,\r
478 &gEfiMtftp4ProtocolGuid,\r
479 &Instance->Mtftp4,\r
480 NULL\r
481 );\r
482\r
483 if (EFI_ERROR (Status)) {\r
484 goto ON_ERROR;\r
485 }\r
486\r
487 Instance->Handle = *ChildHandle;\r
488\r
489 //\r
490 // Open the Udp4 protocol BY_CHILD.\r
491 //\r
492 Status = gBS->OpenProtocol (\r
493 MtftpSb->ConnectUdp->UdpHandle,\r
494 &gEfiUdp4ProtocolGuid,\r
495 (VOID **) &Udp4,\r
496 gMtftp4DriverBinding.DriverBindingHandle,\r
497 Instance->Handle,\r
498 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
499 );\r
500 if (EFI_ERROR (Status)) {\r
501 gBS->UninstallMultipleProtocolInterfaces (\r
502 Instance->Handle,\r
503 &gEfiMtftp4ProtocolGuid,\r
504 &Instance->Mtftp4,\r
505 NULL\r
506 );\r
507\r
508 goto ON_ERROR;\r
509 }\r
510\r
511 //\r
512 // Add it to the parent's child list.\r
513 //\r
e48e37fc 514 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
772db4bb 515\r
e48e37fc 516 InsertTailList (&MtftpSb->Children, &Instance->Link);\r
772db4bb 517 MtftpSb->ChildrenNum++;\r
518\r
e48e37fc 519 gBS->RestoreTPL (OldTpl);\r
772db4bb 520\r
521ON_ERROR:\r
522\r
523 if (EFI_ERROR (Status)) {\r
524 UdpIoFreePort (Instance->UnicastPort);\r
e48e37fc 525 gBS->FreePool (Instance);\r
772db4bb 526 }\r
527\r
528 return Status;\r
529}\r
530\r
531\r
532/**\r
533 Destory one of the service binding's child.\r
534\r
535 @param This The service binding instance\r
536 @param ChildHandle The child handle to destory\r
537\r
538 @retval EFI_INVALID_PARAMETER The parameter is invaid.\r
539 @retval EFI_UNSUPPORTED The child may have already been destoried.\r
540 @retval EFI_SUCCESS The child is destoried and removed from the\r
541 parent's child list.\r
542\r
543**/\r
544EFI_STATUS\r
dab714aa 545EFIAPI\r
772db4bb 546Mtftp4ServiceBindingDestroyChild (\r
547 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
548 IN EFI_HANDLE ChildHandle\r
549 )\r
550{\r
551 MTFTP4_SERVICE *MtftpSb;\r
552 MTFTP4_PROTOCOL *Instance;\r
553 EFI_MTFTP4_PROTOCOL *Mtftp4;\r
554 EFI_STATUS Status;\r
555 EFI_TPL OldTpl;\r
556\r
557 if ((This == NULL) || (ChildHandle == NULL)) {\r
558 return EFI_INVALID_PARAMETER;\r
559 }\r
560\r
561 //\r
562 // Retrieve the private context data structures\r
563 //\r
564 Status = gBS->OpenProtocol (\r
565 ChildHandle,\r
566 &gEfiMtftp4ProtocolGuid,\r
567 (VOID **) &Mtftp4,\r
568 gMtftp4DriverBinding.DriverBindingHandle,\r
569 ChildHandle,\r
570 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
571 );\r
572\r
573 if (EFI_ERROR (Status)) {\r
574 return EFI_UNSUPPORTED;\r
575 }\r
576\r
577 Instance = MTFTP4_PROTOCOL_FROM_THIS (Mtftp4);\r
578 MtftpSb = MTFTP4_SERVICE_FROM_THIS (This);\r
579\r
580 if (Instance->Service != MtftpSb) {\r
581 return EFI_INVALID_PARAMETER;\r
582 }\r
583\r
dab714aa 584 if (Instance->InDestory) {\r
772db4bb 585 return EFI_SUCCESS;\r
586 }\r
587\r
dab714aa 588 Instance->InDestory = TRUE;\r
772db4bb 589\r
590 //\r
591 // Close the Udp4 protocol.\r
592 //\r
593 gBS->CloseProtocol (\r
594 MtftpSb->ConnectUdp->UdpHandle,\r
595 &gEfiUdp4ProtocolGuid,\r
596 gMtftp4DriverBinding.DriverBindingHandle,\r
597 ChildHandle\r
598 );\r
599\r
600 //\r
601 // Uninstall the MTFTP4 protocol first to enable a top down destruction.\r
602 //\r
603 Status = gBS->UninstallProtocolInterface (\r
604 ChildHandle,\r
605 &gEfiMtftp4ProtocolGuid,\r
606 Mtftp4\r
607 );\r
608\r
609 if (EFI_ERROR (Status)) {\r
dab714aa 610 Instance->InDestory = FALSE;\r
772db4bb 611 return Status;\r
612 }\r
613\r
e48e37fc 614 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
772db4bb 615\r
616 Mtftp4CleanOperation (Instance, EFI_DEVICE_ERROR);\r
617 UdpIoFreePort (Instance->UnicastPort);\r
618\r
e48e37fc 619 RemoveEntryList (&Instance->Link);\r
772db4bb 620 MtftpSb->ChildrenNum--;\r
621\r
e48e37fc 622 gBS->RestoreTPL (OldTpl);\r
772db4bb 623\r
e48e37fc 624 gBS->FreePool (Instance);\r
772db4bb 625 return EFI_SUCCESS;\r
626}\r