2 Driver Binding functions and Service Binding functions
3 implementation for Mtftp6 Driver.
5 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php.
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "Mtftp6Impl.h"
20 EFI_DRIVER_BINDING_PROTOCOL gMtftp6DriverBinding
= {
21 Mtftp6DriverBindingSupported
,
22 Mtftp6DriverBindingStart
,
23 Mtftp6DriverBindingStop
,
29 EFI_SERVICE_BINDING_PROTOCOL gMtftp6ServiceBindingTemplate
= {
30 Mtftp6ServiceBindingCreateChild
,
31 Mtftp6ServiceBindingDestroyChild
36 Destroy the MTFTP6 service. The MTFTP6 service may be partly initialized,
37 or partly destroyed. If a resource is destroyed, it is marked as such in
38 case the destroy failed and is called again later.
40 @param[in] Service The MTFTP6 service to be destroyed.
44 Mtftp6DestroyService (
45 IN MTFTP6_SERVICE
*Service
49 // Make sure all children instances have been already destroyed.
51 ASSERT (Service
->ChildrenNum
== 0);
53 if (Service
->DummyUdpIo
!= NULL
) {
54 UdpIoFreeIo (Service
->DummyUdpIo
);
57 if (Service
->Timer
!= NULL
) {
58 gBS
->CloseEvent (Service
->Timer
);
66 Create then initialize a MTFTP6 service binding instance.
68 @param[in] Controller The controller to install the MTFTP6 service
70 @param[in] Image The driver binding image of the MTFTP6 driver.
71 @param[out] Service The variable to receive the created service
74 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to create the instance
75 @retval EFI_DEVICE_ERROR Failed to create a NULL UDP port to keep connection with UDP.
76 @retval EFI_SUCCESS The service instance is created for the controller.
81 IN EFI_HANDLE Controller
,
83 OUT MTFTP6_SERVICE
**Service
86 MTFTP6_SERVICE
*Mtftp6Srv
;
89 ASSERT (Service
!= NULL
);
92 Mtftp6Srv
= AllocateZeroPool (sizeof (MTFTP6_SERVICE
));
94 if (Mtftp6Srv
== NULL
) {
95 return EFI_OUT_OF_RESOURCES
;
98 Mtftp6Srv
->Signature
= MTFTP6_SERVICE_SIGNATURE
;
99 Mtftp6Srv
->Controller
= Controller
;
100 Mtftp6Srv
->Image
= Image
;
101 Mtftp6Srv
->ChildrenNum
= 0;
104 &Mtftp6Srv
->ServiceBinding
,
105 &gMtftp6ServiceBindingTemplate
,
106 sizeof (EFI_SERVICE_BINDING_PROTOCOL
)
109 InitializeListHead (&Mtftp6Srv
->Children
);
112 // Create a internal timer for all instances.
114 Status
= gBS
->CreateEvent (
115 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
122 if (EFI_ERROR (Status
)) {
123 FreePool (Mtftp6Srv
);
128 // Create a dummy Udp6Io to build parent-child relationship between Udp6 driver
129 // and Mtftp6 driver.
131 Mtftp6Srv
->DummyUdpIo
= UdpIoCreateIo (
134 Mtftp6ConfigDummyUdpIo
,
139 if (Mtftp6Srv
->DummyUdpIo
== NULL
) {
140 gBS
->CloseEvent (Mtftp6Srv
->Timer
);
141 FreePool (Mtftp6Srv
);
142 return EFI_DEVICE_ERROR
;
145 *Service
= Mtftp6Srv
;
151 Destroy the MTFTP6 instance and recycle the resources.
153 @param[in] Instance The pointer to the MTFTP6 instance.
157 Mtftp6DestroyInstance (
158 IN MTFTP6_INSTANCE
*Instance
163 MTFTP6_BLOCK_RANGE
*Block
;
165 if (Instance
->Config
!= NULL
) {
166 FreePool (Instance
->Config
);
169 if (Instance
->Token
!= NULL
&& Instance
->Token
->Event
!= NULL
) {
170 gBS
->SignalEvent (Instance
->Token
->Event
);
173 if (Instance
->LastPacket
!= NULL
) {
174 NetbufFree (Instance
->LastPacket
);
177 if (Instance
->UdpIo
!= NULL
) {
178 UdpIoFreeIo (Instance
->UdpIo
);
181 if (Instance
->McastUdpIo
!= NULL
) {
182 UdpIoFreeIo (Instance
->McastUdpIo
);
185 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Instance
->BlkList
) {
186 Block
= NET_LIST_USER_STRUCT (Entry
, MTFTP6_BLOCK_RANGE
, Link
);
187 RemoveEntryList (Entry
);
196 Create the MTFTP6 instance and initialize it.
198 @param[in] Service The pointer to the MTFTP6 service.
199 @param[out] Instance The pointer to the MTFTP6 instance.
201 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
202 @retval EFI_SUCCESS The MTFTP6 instance is created.
206 Mtftp6CreateInstance (
207 IN MTFTP6_SERVICE
*Service
,
208 OUT MTFTP6_INSTANCE
**Instance
211 MTFTP6_INSTANCE
*Mtftp6Ins
;
214 Mtftp6Ins
= AllocateZeroPool (sizeof (MTFTP6_INSTANCE
));
216 if (Mtftp6Ins
== NULL
) {
217 return EFI_OUT_OF_RESOURCES
;
220 Mtftp6Ins
->Signature
= MTFTP6_INSTANCE_SIGNATURE
;
221 Mtftp6Ins
->InDestroy
= FALSE
;
222 Mtftp6Ins
->Service
= Service
;
226 &gMtftp6ProtocolTemplate
,
227 sizeof (EFI_MTFTP6_PROTOCOL
)
230 InitializeListHead (&Mtftp6Ins
->Link
);
231 InitializeListHead (&Mtftp6Ins
->BlkList
);
233 *Instance
= Mtftp6Ins
;
240 Callback function which provided by user to remove one node in NetDestroyLinkList process.
242 @param[in] Entry The entry to be removed.
243 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
245 @retval EFI_SUCCESS The entry has been removed successfully.
246 @retval Others Fail to remove the entry.
251 Mtftp6DestroyChildEntryInHandleBuffer (
252 IN LIST_ENTRY
*Entry
,
256 MTFTP6_INSTANCE
*Instance
;
257 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
258 UINTN NumberOfChildren
;
259 EFI_HANDLE
*ChildHandleBuffer
;
261 if (Entry
== NULL
|| Context
== NULL
) {
262 return EFI_INVALID_PARAMETER
;
265 Instance
= NET_LIST_USER_STRUCT_S (Entry
, MTFTP6_INSTANCE
, Link
, MTFTP6_INSTANCE_SIGNATURE
);
266 ServiceBinding
= ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->ServiceBinding
;
267 NumberOfChildren
= ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->NumberOfChildren
;
268 ChildHandleBuffer
= ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->ChildHandleBuffer
;
270 if (!NetIsInHandleBuffer (Instance
->Handle
, NumberOfChildren
, ChildHandleBuffer
)) {
274 return ServiceBinding
->DestroyChild (ServiceBinding
, Instance
->Handle
);
279 This is the declaration of an EFI image entry point. This entry point is
280 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
281 both device drivers and bus drivers.
283 Entry point of the MTFTP6 driver to install various protocols.
285 @param[in] ImageHandle The firmware allocated handle for the UEFI image.
286 @param[in] SystemTable The pointer to the EFI System Table.
288 @retval EFI_SUCCESS The operation completed successfully.
289 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
294 Mtftp6DriverEntryPoint (
295 IN EFI_HANDLE ImageHandle
,
296 IN EFI_SYSTEM_TABLE
*SystemTable
299 return EfiLibInstallDriverBindingComponentName2 (
302 &gMtftp6DriverBinding
,
304 &gMtftp6ComponentName
,
305 &gMtftp6ComponentName2
311 Test to see if this driver supports Controller. This service
312 is called by the EFI boot service ConnectController(). In
313 order to make drivers as small as possible, there are calling
314 restrictions for this service. ConnectController() must
315 follow these calling restrictions. If any other agent wishes to call
316 Supported(), it must also follow these calling restrictions.
318 @param[in] This Protocol instance pointer.
319 @param[in] Controller Handle of device to test
320 @param[in] RemainingDevicePath Optional parameter use to pick a specific child.
323 @retval EFI_SUCCESS This driver supports this device.
324 @retval Others This driver does not support this device.
329 Mtftp6DriverBindingSupported (
330 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
331 IN EFI_HANDLE Controller
,
332 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
335 return gBS
->OpenProtocol (
337 &gEfiUdp6ServiceBindingProtocolGuid
,
339 This
->DriverBindingHandle
,
341 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
347 Start this driver on Controller. This service is called by the
348 EFI boot service ConnectController(). In order to make
349 drivers as small as possible, there are calling restrictions for
350 this service. ConnectController() must follow these
351 calling restrictions. If any other agent wishes to call Start() it
352 must also follow these calling restrictions.
354 @param[in] This Protocol instance pointer.
355 @param[in] Controller Handle of device to bind driver to.
356 @param[in] RemainingDevicePath Optional parameter use to pick a specific child
359 @retval EFI_SUCCESS This driver is added to Controller.
360 @retval EFI_ALREADY_STARTED This driver is already running on Controller.
361 @retval Others This driver does not support this device.
366 Mtftp6DriverBindingStart (
367 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
368 IN EFI_HANDLE Controller
,
369 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
372 MTFTP6_SERVICE
*Service
;
376 // Directly return if driver is already running on this Nic handle.
378 Status
= gBS
->OpenProtocol (
380 &gEfiMtftp6ServiceBindingProtocolGuid
,
382 This
->DriverBindingHandle
,
384 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
387 if (!EFI_ERROR (Status
)) {
388 return EFI_ALREADY_STARTED
;
392 // Create Mtftp6 service for this Nic handle
394 Status
= Mtftp6CreateService (
396 This
->DriverBindingHandle
,
400 if (EFI_ERROR (Status
)) {
404 ASSERT (Service
!= NULL
);
407 // Start the internal timer to track the packet retransmission.
409 Status
= gBS
->SetTimer (
415 if (EFI_ERROR (Status
)) {
420 // Install the Mtftp6 service on the Nic handle.
422 Status
= gBS
->InstallMultipleProtocolInterfaces (
424 &gEfiMtftp6ServiceBindingProtocolGuid
,
425 &Service
->ServiceBinding
,
429 if (EFI_ERROR (Status
)) {
437 Mtftp6DestroyService (Service
);
443 Stop this driver on Controller. This service is called by the
444 EFI boot service DisconnectController(). In order to
445 make drivers as small as possible, there are calling
446 restrictions for this service. DisconnectController()
447 must follow these calling restrictions. If any other agent wishes
448 to call Stop(), it must also follow these calling restrictions.
450 @param[in] This Protocol instance pointer.
451 @param[in] Controller Handle of device to stop driver on
452 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
453 children is zero, stop the entire bus driver.
454 @param[in] ChildHandleBuffer List of Child Handles to Stop.
456 @retval EFI_SUCCESS This driver is removed Controller.
457 @retval EFI_DEVICE_ERROR An unexpected error.
458 @retval Others This driver was not removed from this device.
463 Mtftp6DriverBindingStop (
464 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
465 IN EFI_HANDLE Controller
,
466 IN UINTN NumberOfChildren
,
467 IN EFI_HANDLE
*ChildHandleBuffer
470 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
471 MTFTP6_SERVICE
*Service
;
472 EFI_HANDLE NicHandle
;
475 MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context
;
478 // Locate the Nic handle to retrieve the Mtftp6 private data.
480 NicHandle
= NetLibGetNicHandle (Controller
, &gEfiUdp6ProtocolGuid
);
482 if (NicHandle
== NULL
) {
486 Status
= gBS
->OpenProtocol (
488 &gEfiMtftp6ServiceBindingProtocolGuid
,
489 (VOID
**) &ServiceBinding
,
490 This
->DriverBindingHandle
,
492 EFI_OPEN_PROTOCOL_GET_PROTOCOL
495 if (EFI_ERROR (Status
)) {
496 return EFI_DEVICE_ERROR
;
499 Service
= MTFTP6_SERVICE_FROM_THIS (ServiceBinding
);
501 if (!IsListEmpty (&Service
->Children
)) {
503 // Destroy the Mtftp6 child instance in ChildHandleBuffer.
505 List
= &Service
->Children
;
506 Context
.ServiceBinding
= ServiceBinding
;
507 Context
.NumberOfChildren
= NumberOfChildren
;
508 Context
.ChildHandleBuffer
= ChildHandleBuffer
;
509 Status
= NetDestroyLinkList (
511 Mtftp6DestroyChildEntryInHandleBuffer
,
517 if (NumberOfChildren
== 0 && IsListEmpty (&Service
->Children
)) {
519 // Destroy the Mtftp6 service if there is no Mtftp6 child instance left.
521 gBS
->UninstallProtocolInterface (
523 &gEfiMtftp6ServiceBindingProtocolGuid
,
527 Mtftp6DestroyService (Service
);
528 Status
= EFI_SUCCESS
;
536 Creates a child handle and installs a protocol.
538 The CreateChild() function installs a protocol on ChildHandle.
539 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
540 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
542 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
543 @param[in, out] ChildHandle Pointer to the handle of the child to create. If it is NULL,
544 then a new handle is created. If it is a pointer to an existing
545 UEFI handle, then the protocol is added to the existing UEFI handle.
547 @retval EFI_SUCCES The protocol was added to ChildHandle.
548 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
549 @retval Others The child handle was not created.
554 Mtftp6ServiceBindingCreateChild (
555 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
556 IN OUT EFI_HANDLE
*ChildHandle
559 MTFTP6_SERVICE
*Service
;
560 MTFTP6_INSTANCE
*Instance
;
565 if (This
== NULL
|| ChildHandle
== NULL
) {
566 return EFI_INVALID_PARAMETER
;
569 Service
= MTFTP6_SERVICE_FROM_THIS (This
);
571 Status
= Mtftp6CreateInstance (Service
, &Instance
);
573 if (EFI_ERROR (Status
)) {
577 ASSERT (Instance
!= NULL
);
580 // Install the Mtftp6 protocol on the new child handle.
582 Status
= gBS
->InstallMultipleProtocolInterfaces (
584 &gEfiMtftp6ProtocolGuid
,
589 if (EFI_ERROR (Status
)) {
593 Instance
->Handle
= *ChildHandle
;
596 // Open the Udp6 protocol by child.
598 Status
= gBS
->OpenProtocol (
599 Service
->DummyUdpIo
->UdpHandle
,
600 &gEfiUdp6ProtocolGuid
,
602 gMtftp6DriverBinding
.DriverBindingHandle
,
604 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
607 if (EFI_ERROR (Status
)) {
608 gBS
->UninstallMultipleProtocolInterfaces (
610 &gEfiMtftp6ProtocolGuid
,
619 // Add the new Mtftp6 instance into the children list of Mtftp6 service.
621 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
623 InsertTailList (&Service
->Children
, &Instance
->Link
);
624 Service
->ChildrenNum
++;
626 gBS
->RestoreTPL (OldTpl
);
631 Mtftp6DestroyInstance (Instance
);
637 Destroys a child handle with a protocol installed on it.
639 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
640 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
641 last protocol on ChildHandle, then ChildHandle is destroyed.
643 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
644 @param[in] ChildHandle Handle of the child to destroy.
646 @retval EFI_SUCCES The protocol was removed from ChildHandle.
647 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
648 @retval EFI_INVALID_PARAMETER Child handle is NULL.
649 @retval Others The child handle was not destroyed
654 Mtftp6ServiceBindingDestroyChild (
655 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
656 IN EFI_HANDLE ChildHandle
659 MTFTP6_SERVICE
*Service
;
660 MTFTP6_INSTANCE
*Instance
;
661 EFI_MTFTP6_PROTOCOL
*Mtftp6
;
665 if (This
== NULL
|| ChildHandle
== NULL
) {
666 return EFI_INVALID_PARAMETER
;
670 // Locate the Nic handle to retrieve the Mtftp6 private data.
672 Status
= gBS
->OpenProtocol (
674 &gEfiMtftp6ProtocolGuid
,
676 gMtftp6DriverBinding
.DriverBindingHandle
,
678 EFI_OPEN_PROTOCOL_GET_PROTOCOL
681 if (EFI_ERROR (Status
)) {
682 return EFI_UNSUPPORTED
;
685 Instance
= MTFTP6_INSTANCE_FROM_THIS (Mtftp6
);
686 Service
= MTFTP6_SERVICE_FROM_THIS (This
);
688 if (Instance
->Service
!= Service
) {
689 return EFI_INVALID_PARAMETER
;
693 // Check whether the instance already in Destroy state.
695 if (Instance
->InDestroy
) {
699 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
701 Instance
->InDestroy
= TRUE
;
704 Service
->DummyUdpIo
->UdpHandle
,
705 &gEfiUdp6ProtocolGuid
,
706 gMtftp6DriverBinding
.DriverBindingHandle
,
710 if (Instance
->UdpIo
!= NULL
) {
712 Instance
->UdpIo
->UdpHandle
,
713 &gEfiUdp6ProtocolGuid
,
714 gMtftp6DriverBinding
.DriverBindingHandle
,
719 if (Instance
->McastUdpIo
!= NULL
) {
721 Instance
->McastUdpIo
->UdpHandle
,
722 &gEfiUdp6ProtocolGuid
,
723 gMtftp6DriverBinding
.DriverBindingHandle
,
729 // Uninstall the MTFTP6 protocol first to enable a top down destruction.
731 gBS
->RestoreTPL (OldTpl
);
732 Status
= gBS
->UninstallProtocolInterface (
734 &gEfiMtftp6ProtocolGuid
,
737 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
738 if (EFI_ERROR (Status
)) {
739 Instance
->InDestroy
= FALSE
;
740 gBS
->RestoreTPL (OldTpl
);
745 // Remove the Mtftp6 instance from the children list of Mtftp6 service.
747 RemoveEntryList (&Instance
->Link
);
748 Service
->ChildrenNum
--;
750 gBS
->RestoreTPL (OldTpl
);
752 Mtftp6DestroyInstance (Instance
);