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