]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c
Remove dependency on PCI Root Bridge I/O Protocol. This library should only layer...
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Mtftp4Dxe / Mtftp4Driver.c
CommitLineData
772db4bb 1/** @file\r
dab714aa 2 Implementation of Mtftp drivers.\r
3 \r
b45b45b2 4Copyright (c) 2006 - 2009, 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
b45b45b2 110 @param UdpIo The UDP_IO to configure\r
772db4bb 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
b45b45b2 118 IN UDP_IO *UdpIo,\r
772db4bb 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
766c7483 183 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
766c7483 200 FreePool (MtftpSb);\r
772db4bb 201 return Status;\r
202 }\r
203\r
b45b45b2 204 MtftpSb->ConnectUdp = UdpIoCreateIo (\r
205 Controller,\r
206 Image,\r
207 Mtftp4ConfigNullUdp,\r
208 UDP_IO_UDP4_VERSION,\r
209 NULL\r
210 );\r
772db4bb 211\r
212 if (MtftpSb->ConnectUdp == NULL) {\r
213 gBS->CloseEvent (MtftpSb->TimerToGetMap);\r
214 gBS->CloseEvent (MtftpSb->Timer);\r
766c7483 215 FreePool (MtftpSb);\r
772db4bb 216 return EFI_DEVICE_ERROR;\r
217 }\r
218\r
219 *Service = MtftpSb;\r
220 return EFI_SUCCESS;\r
221}\r
222\r
223\r
224/**\r
225 Release all the resource used the MTFTP service binding instance.\r
226\r
227 @param MtftpSb The MTFTP service binding instance.\r
228\r
772db4bb 229**/\r
230VOID\r
231Mtftp4CleanService (\r
232 IN MTFTP4_SERVICE *MtftpSb\r
233 )\r
234{\r
b45b45b2 235 UdpIoFreeIo (MtftpSb->ConnectUdp);\r
772db4bb 236 gBS->CloseEvent (MtftpSb->TimerToGetMap);\r
237 gBS->CloseEvent (MtftpSb->Timer);\r
238}\r
239\r
240\r
241/**\r
dab714aa 242 Start the MTFTP driver on this controller. \r
243 \r
244 MTFTP driver will install a MTFTP SERVICE BINDING protocol on the supported\r
772db4bb 245 controller, which can be used to create/destroy MTFTP children.\r
246\r
247 @param This The MTFTP driver binding protocol.\r
248 @param Controller The controller to manage.\r
249 @param RemainingDevicePath Remaining device path.\r
250\r
251 @retval EFI_ALREADY_STARTED The MTFTP service binding protocol has been\r
252 started on the controller.\r
253 @retval EFI_SUCCESS The MTFTP service binding is installed on the\r
254 controller.\r
255\r
256**/\r
257EFI_STATUS\r
dab714aa 258EFIAPI\r
772db4bb 259Mtftp4DriverBindingStart (\r
260 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
261 IN EFI_HANDLE Controller,\r
262 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
263 )\r
264{\r
265 MTFTP4_SERVICE *MtftpSb;\r
266 EFI_STATUS Status;\r
267\r
268 //\r
269 // Directly return if driver is already running.\r
270 //\r
271 Status = gBS->OpenProtocol (\r
272 Controller,\r
273 &gEfiMtftp4ServiceBindingProtocolGuid,\r
274 NULL,\r
275 This->DriverBindingHandle,\r
276 Controller,\r
277 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
278 );\r
279\r
280 if (Status == EFI_SUCCESS) {\r
281 return EFI_ALREADY_STARTED;\r
282 }\r
283\r
284 Status = Mtftp4CreateService (Controller, This->DriverBindingHandle, &MtftpSb);\r
285\r
286 if (EFI_ERROR (Status)) {\r
287 return Status;\r
288 }\r
289\r
290 Status = gBS->SetTimer (MtftpSb->Timer, TimerPeriodic, TICKS_PER_SECOND);\r
291\r
292 if (EFI_ERROR (Status)) {\r
293 goto ON_ERROR;\r
294 }\r
295\r
296 //\r
297 // Install the Mtftp4ServiceBinding Protocol onto Controller\r
298 //\r
299 Status = gBS->InstallMultipleProtocolInterfaces (\r
300 &Controller,\r
301 &gEfiMtftp4ServiceBindingProtocolGuid,\r
302 &MtftpSb->ServiceBinding,\r
303 NULL\r
304 );\r
305\r
306 if (EFI_ERROR (Status)) {\r
307 goto ON_ERROR;\r
308 }\r
309\r
310 return EFI_SUCCESS;\r
311\r
312ON_ERROR:\r
313 Mtftp4CleanService (MtftpSb);\r
766c7483 314 FreePool (MtftpSb);\r
772db4bb 315\r
316 return Status;\r
317}\r
318\r
319\r
320/**\r
321 Stop the MTFTP driver on controller. The controller is a UDP\r
322 child handle.\r
323\r
324 @param This The MTFTP driver binding protocol\r
325 @param Controller The controller to stop\r
326 @param NumberOfChildren The number of children\r
327 @param ChildHandleBuffer The array of the child handle.\r
328\r
329 @retval EFI_SUCCESS The driver is stopped on the controller.\r
330 @retval EFI_DEVICE_ERROR Failed to stop the driver on the controller.\r
331\r
332**/\r
333EFI_STATUS\r
dab714aa 334EFIAPI\r
772db4bb 335Mtftp4DriverBindingStop (\r
dab714aa 336 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
337 IN EFI_HANDLE Controller,\r
338 IN UINTN NumberOfChildren,\r
339 IN EFI_HANDLE *ChildHandleBuffer\r
772db4bb 340 )\r
341{\r
342 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
343 MTFTP4_SERVICE *MtftpSb;\r
344 MTFTP4_PROTOCOL *Instance;\r
345 EFI_HANDLE NicHandle;\r
346 EFI_STATUS Status;\r
347 EFI_TPL OldTpl;\r
348\r
349 //\r
350 // MTFTP driver opens UDP child, So, Controller is a UDP\r
351 // child handle. Locate the Nic handle first. Then get the\r
352 // MTFTP private data back.\r
353 //\r
354 NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp4ProtocolGuid);\r
355\r
356 if (NicHandle == NULL) {\r
c4a62a12 357 return EFI_DEVICE_ERROR;\r
772db4bb 358 }\r
359\r
360 Status = gBS->OpenProtocol (\r
361 NicHandle,\r
362 &gEfiMtftp4ServiceBindingProtocolGuid,\r
363 (VOID **) &ServiceBinding,\r
364 This->DriverBindingHandle,\r
365 NicHandle,\r
366 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
367 );\r
368\r
369 if (EFI_ERROR (Status)) {\r
370 return EFI_DEVICE_ERROR;\r
371 }\r
372\r
373 MtftpSb = MTFTP4_SERVICE_FROM_THIS (ServiceBinding);\r
374\r
375 if (MtftpSb->InDestory) {\r
376 return EFI_SUCCESS;\r
377 }\r
378\r
e48e37fc 379 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
772db4bb 380\r
c4a62a12 381 if (NumberOfChildren == 0) {\r
772db4bb 382\r
c4a62a12 383 MtftpSb->InDestory = TRUE;\r
772db4bb 384\r
c4a62a12 385 gBS->UninstallProtocolInterface (\r
386 NicHandle,\r
387 &gEfiMtftp4ServiceBindingProtocolGuid,\r
388 ServiceBinding\r
389 );\r
772db4bb 390\r
c4a62a12 391 Mtftp4CleanService (MtftpSb);\r
772db4bb 392\r
766c7483 393 FreePool (MtftpSb);\r
c4a62a12 394 } else {\r
772db4bb 395\r
e48e37fc 396 while (!IsListEmpty (&MtftpSb->Children)) {\r
c4a62a12 397 Instance = NET_LIST_HEAD (&MtftpSb->Children, MTFTP4_PROTOCOL, Link);\r
398 Mtftp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);\r
399 }\r
772db4bb 400\r
c4a62a12 401 if (MtftpSb->ChildrenNum != 0) {\r
402 Status = EFI_DEVICE_ERROR;\r
403 }\r
404 }\r
772db4bb 405\r
e48e37fc 406 gBS->RestoreTPL (OldTpl);\r
772db4bb 407 return Status;\r
408}\r
409\r
410\r
411/**\r
412 Initialize a MTFTP protocol instance which is the child of MtftpSb.\r
413\r
414 @param MtftpSb The MTFTP service binding protocol.\r
415 @param Instance The MTFTP instance to initialize.\r
416\r
772db4bb 417**/\r
418VOID\r
419Mtftp4InitProtocol (\r
dab714aa 420 IN MTFTP4_SERVICE *MtftpSb,\r
421 OUT MTFTP4_PROTOCOL *Instance\r
772db4bb 422 )\r
423{\r
e48e37fc 424 ZeroMem (Instance, sizeof (MTFTP4_PROTOCOL));\r
772db4bb 425\r
426 Instance->Signature = MTFTP4_PROTOCOL_SIGNATURE;\r
e48e37fc 427 InitializeListHead (&Instance->Link);\r
687a2e5f 428 CopyMem (&Instance->Mtftp4, &gMtftp4ProtocolTemplate, sizeof (Instance->Mtftp4));\r
772db4bb 429 Instance->State = MTFTP4_STATE_UNCONFIGED;\r
dab714aa 430 Instance->InDestory = FALSE;\r
772db4bb 431 Instance->Service = MtftpSb;\r
432\r
e48e37fc 433 InitializeListHead (&Instance->Blocks);\r
772db4bb 434}\r
435\r
436\r
437/**\r
438 Create a MTFTP child for the service binding instance, then\r
439 install the MTFTP protocol to the ChildHandle.\r
440\r
441 @param This The MTFTP service binding instance.\r
442 @param ChildHandle The Child handle to install the MTFTP protocol.\r
443\r
444 @retval EFI_INVALID_PARAMETER The parameter is invalid.\r
445 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource for the new child.\r
446 @retval EFI_SUCCESS The child is successfully create.\r
447\r
448**/\r
449EFI_STATUS\r
dab714aa 450EFIAPI\r
772db4bb 451Mtftp4ServiceBindingCreateChild (\r
452 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
dab714aa 453 IN EFI_HANDLE *ChildHandle\r
772db4bb 454 )\r
455{\r
456 MTFTP4_SERVICE *MtftpSb;\r
457 MTFTP4_PROTOCOL *Instance;\r
458 EFI_STATUS Status;\r
459 EFI_TPL OldTpl;\r
460 VOID *Udp4;\r
461\r
462 if ((This == NULL) || (ChildHandle == NULL)) {\r
463 return EFI_INVALID_PARAMETER;\r
464 }\r
465\r
e48e37fc 466 Instance = AllocatePool (sizeof (*Instance));\r
772db4bb 467\r
468 if (Instance == NULL) {\r
469 return EFI_OUT_OF_RESOURCES;\r
470 }\r
471\r
472 MtftpSb = MTFTP4_SERVICE_FROM_THIS (This);\r
473\r
474 Mtftp4InitProtocol (MtftpSb, Instance);\r
475\r
b45b45b2 476 Instance->UnicastPort = UdpIoCreateIo (\r
772db4bb 477 MtftpSb->Controller,\r
478 MtftpSb->Image,\r
479 Mtftp4ConfigNullUdp,\r
b45b45b2 480 UDP_IO_UDP4_VERSION,\r
772db4bb 481 Instance\r
482 );\r
483\r
484 if (Instance->UnicastPort == NULL) {\r
766c7483 485 FreePool (Instance);\r
772db4bb 486 return EFI_OUT_OF_RESOURCES;\r
487 }\r
488\r
489 //\r
490 // Install the MTFTP protocol onto ChildHandle\r
491 //\r
492 Status = gBS->InstallMultipleProtocolInterfaces (\r
493 ChildHandle,\r
494 &gEfiMtftp4ProtocolGuid,\r
495 &Instance->Mtftp4,\r
496 NULL\r
497 );\r
498\r
499 if (EFI_ERROR (Status)) {\r
500 goto ON_ERROR;\r
501 }\r
502\r
503 Instance->Handle = *ChildHandle;\r
504\r
505 //\r
506 // Open the Udp4 protocol BY_CHILD.\r
507 //\r
508 Status = gBS->OpenProtocol (\r
509 MtftpSb->ConnectUdp->UdpHandle,\r
510 &gEfiUdp4ProtocolGuid,\r
511 (VOID **) &Udp4,\r
512 gMtftp4DriverBinding.DriverBindingHandle,\r
513 Instance->Handle,\r
514 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
515 );\r
516 if (EFI_ERROR (Status)) {\r
517 gBS->UninstallMultipleProtocolInterfaces (\r
518 Instance->Handle,\r
519 &gEfiMtftp4ProtocolGuid,\r
520 &Instance->Mtftp4,\r
521 NULL\r
522 );\r
523\r
524 goto ON_ERROR;\r
525 }\r
526\r
527 //\r
528 // Add it to the parent's child list.\r
529 //\r
e48e37fc 530 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
772db4bb 531\r
e48e37fc 532 InsertTailList (&MtftpSb->Children, &Instance->Link);\r
772db4bb 533 MtftpSb->ChildrenNum++;\r
534\r
e48e37fc 535 gBS->RestoreTPL (OldTpl);\r
772db4bb 536\r
537ON_ERROR:\r
538\r
539 if (EFI_ERROR (Status)) {\r
b45b45b2 540 UdpIoFreeIo (Instance->UnicastPort);\r
766c7483 541 FreePool (Instance);\r
772db4bb 542 }\r
543\r
544 return Status;\r
545}\r
546\r
547\r
548/**\r
549 Destory one of the service binding's child.\r
550\r
551 @param This The service binding instance\r
552 @param ChildHandle The child handle to destory\r
553\r
554 @retval EFI_INVALID_PARAMETER The parameter is invaid.\r
555 @retval EFI_UNSUPPORTED The child may have already been destoried.\r
556 @retval EFI_SUCCESS The child is destoried and removed from the\r
557 parent's child list.\r
558\r
559**/\r
560EFI_STATUS\r
dab714aa 561EFIAPI\r
772db4bb 562Mtftp4ServiceBindingDestroyChild (\r
563 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
564 IN EFI_HANDLE ChildHandle\r
565 )\r
566{\r
567 MTFTP4_SERVICE *MtftpSb;\r
568 MTFTP4_PROTOCOL *Instance;\r
569 EFI_MTFTP4_PROTOCOL *Mtftp4;\r
570 EFI_STATUS Status;\r
571 EFI_TPL OldTpl;\r
572\r
573 if ((This == NULL) || (ChildHandle == NULL)) {\r
574 return EFI_INVALID_PARAMETER;\r
575 }\r
576\r
577 //\r
578 // Retrieve the private context data structures\r
579 //\r
580 Status = gBS->OpenProtocol (\r
581 ChildHandle,\r
582 &gEfiMtftp4ProtocolGuid,\r
583 (VOID **) &Mtftp4,\r
584 gMtftp4DriverBinding.DriverBindingHandle,\r
585 ChildHandle,\r
586 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
587 );\r
588\r
589 if (EFI_ERROR (Status)) {\r
590 return EFI_UNSUPPORTED;\r
591 }\r
592\r
593 Instance = MTFTP4_PROTOCOL_FROM_THIS (Mtftp4);\r
594 MtftpSb = MTFTP4_SERVICE_FROM_THIS (This);\r
595\r
596 if (Instance->Service != MtftpSb) {\r
597 return EFI_INVALID_PARAMETER;\r
598 }\r
599\r
dab714aa 600 if (Instance->InDestory) {\r
772db4bb 601 return EFI_SUCCESS;\r
602 }\r
603\r
dab714aa 604 Instance->InDestory = TRUE;\r
772db4bb 605\r
606 //\r
607 // Close the Udp4 protocol.\r
608 //\r
609 gBS->CloseProtocol (\r
610 MtftpSb->ConnectUdp->UdpHandle,\r
611 &gEfiUdp4ProtocolGuid,\r
612 gMtftp4DriverBinding.DriverBindingHandle,\r
613 ChildHandle\r
614 );\r
615\r
616 //\r
617 // Uninstall the MTFTP4 protocol first to enable a top down destruction.\r
618 //\r
619 Status = gBS->UninstallProtocolInterface (\r
620 ChildHandle,\r
621 &gEfiMtftp4ProtocolGuid,\r
622 Mtftp4\r
623 );\r
624\r
625 if (EFI_ERROR (Status)) {\r
dab714aa 626 Instance->InDestory = FALSE;\r
772db4bb 627 return Status;\r
628 }\r
629\r
e48e37fc 630 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
772db4bb 631\r
632 Mtftp4CleanOperation (Instance, EFI_DEVICE_ERROR);\r
b45b45b2 633 UdpIoFreeIo (Instance->UnicastPort);\r
772db4bb 634\r
e48e37fc 635 RemoveEntryList (&Instance->Link);\r
772db4bb 636 MtftpSb->ChildrenNum--;\r
637\r
e48e37fc 638 gBS->RestoreTPL (OldTpl);\r
772db4bb 639\r
766c7483 640 FreePool (Instance);\r
772db4bb 641 return EFI_SUCCESS;\r
642}\r