2 Driver Binding functions and Service Binding functions
3 implementation for Mtftp6 Driver.
5 Copyright (c) 2009 - 2012, 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.
250 Mtftp6DestroyChildEntryInHandleBuffer (
251 IN LIST_ENTRY
*Entry
,
255 MTFTP6_INSTANCE
*Instance
;
256 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
257 UINTN NumberOfChildren
;
258 EFI_HANDLE
*ChildHandleBuffer
;
260 if (Entry
== NULL
|| Context
== NULL
) {
261 return EFI_INVALID_PARAMETER
;
264 Instance
= NET_LIST_USER_STRUCT_S (Entry
, MTFTP6_INSTANCE
, Link
, MTFTP6_INSTANCE_SIGNATURE
);
265 ServiceBinding
= ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->ServiceBinding
;
266 NumberOfChildren
= ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->NumberOfChildren
;
267 ChildHandleBuffer
= ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->ChildHandleBuffer
;
269 if (!NetIsInHandleBuffer (Instance
->Handle
, NumberOfChildren
, ChildHandleBuffer
)) {
273 return ServiceBinding
->DestroyChild (ServiceBinding
, Instance
->Handle
);
278 This is the declaration of an EFI image entry point. This entry point is
279 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
280 both device drivers and bus drivers.
282 Entry point of the MTFTP6 driver to install various protocols.
284 @param[in] ImageHandle The firmware allocated handle for the UEFI image.
285 @param[in] SystemTable The pointer to the EFI System Table.
287 @retval EFI_SUCCESS The operation completed successfully.
288 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
293 Mtftp6DriverEntryPoint (
294 IN EFI_HANDLE ImageHandle
,
295 IN EFI_SYSTEM_TABLE
*SystemTable
298 return EfiLibInstallDriverBindingComponentName2 (
301 &gMtftp6DriverBinding
,
303 &gMtftp6ComponentName
,
304 &gMtftp6ComponentName2
310 Test to see if this driver supports Controller. This service
311 is called by the EFI boot service ConnectController(). In
312 order to make drivers as small as possible, there are calling
313 restrictions for this service. ConnectController() must
314 follow these calling restrictions. If any other agent wishes to call
315 Supported(), it must also follow these calling restrictions.
317 @param[in] This Protocol instance pointer.
318 @param[in] Controller Handle of device to test
319 @param[in] RemainingDevicePath Optional parameter use to pick a specific child.
322 @retval EFI_SUCCESS This driver supports this device.
323 @retval Others This driver does not support this device.
328 Mtftp6DriverBindingSupported (
329 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
330 IN EFI_HANDLE Controller
,
331 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
334 return gBS
->OpenProtocol (
336 &gEfiUdp6ServiceBindingProtocolGuid
,
338 This
->DriverBindingHandle
,
340 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
346 Start this driver on Controller. This service is called by the
347 EFI boot service ConnectController(). In order to make
348 drivers as small as possible, there are calling restrictions for
349 this service. ConnectController() must follow these
350 calling restrictions. If any other agent wishes to call Start() it
351 must also follow these calling restrictions.
353 @param[in] This Protocol instance pointer.
354 @param[in] Controller Handle of device to bind driver to.
355 @param[in] RemainingDevicePath Optional parameter use to pick a specific child
358 @retval EFI_SUCCESS This driver is added to Controller.
359 @retval EFI_ALREADY_STARTED This driver is already running on Controller.
360 @retval Others This driver does not support this device.
365 Mtftp6DriverBindingStart (
366 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
367 IN EFI_HANDLE Controller
,
368 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
371 MTFTP6_SERVICE
*Service
;
375 // Directly return if driver is already running on this Nic handle.
377 Status
= gBS
->OpenProtocol (
379 &gEfiMtftp6ServiceBindingProtocolGuid
,
381 This
->DriverBindingHandle
,
383 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
386 if (!EFI_ERROR (Status
)) {
387 return EFI_ALREADY_STARTED
;
391 // Create Mtftp6 service for this Nic handle
393 Status
= Mtftp6CreateService (
395 This
->DriverBindingHandle
,
399 if (EFI_ERROR (Status
)) {
403 ASSERT (Service
!= NULL
);
406 // Start the internal timer to track the packet retransmission.
408 Status
= gBS
->SetTimer (
414 if (EFI_ERROR (Status
)) {
419 // Install the Mtftp6 service on the Nic handle.
421 Status
= gBS
->InstallMultipleProtocolInterfaces (
423 &gEfiMtftp6ServiceBindingProtocolGuid
,
424 &Service
->ServiceBinding
,
428 if (EFI_ERROR (Status
)) {
436 Mtftp6DestroyService (Service
);
442 Stop this driver on Controller. This service is called by the
443 EFI boot service DisconnectController(). In order to
444 make drivers as small as possible, there are calling
445 restrictions for this service. DisconnectController()
446 must follow these calling restrictions. If any other agent wishes
447 to call Stop(), it must also follow these calling restrictions.
449 @param[in] This Protocol instance pointer.
450 @param[in] Controller Handle of device to stop driver on
451 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
452 children is zero, stop the entire bus driver.
453 @param[in] ChildHandleBuffer List of Child Handles to Stop.
455 @retval EFI_SUCCESS This driver is removed Controller.
456 @retval EFI_DEVICE_ERROR An unexpected error.
457 @retval Others This driver was not removed from this device.
462 Mtftp6DriverBindingStop (
463 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
464 IN EFI_HANDLE Controller
,
465 IN UINTN NumberOfChildren
,
466 IN EFI_HANDLE
*ChildHandleBuffer
469 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
470 MTFTP6_SERVICE
*Service
;
471 EFI_HANDLE NicHandle
;
474 MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context
;
477 // Locate the Nic handle to retrieve the Mtftp6 private data.
479 NicHandle
= NetLibGetNicHandle (Controller
, &gEfiUdp6ProtocolGuid
);
481 if (NicHandle
== NULL
) {
485 Status
= gBS
->OpenProtocol (
487 &gEfiMtftp6ServiceBindingProtocolGuid
,
488 (VOID
**) &ServiceBinding
,
489 This
->DriverBindingHandle
,
491 EFI_OPEN_PROTOCOL_GET_PROTOCOL
494 if (EFI_ERROR (Status
)) {
495 return EFI_DEVICE_ERROR
;
498 Service
= MTFTP6_SERVICE_FROM_THIS (ServiceBinding
);
500 if (!IsListEmpty (&Service
->Children
)) {
502 // Destroy the Mtftp6 child instance in ChildHandleBuffer.
504 List
= &Service
->Children
;
505 Context
.ServiceBinding
= ServiceBinding
;
506 Context
.NumberOfChildren
= NumberOfChildren
;
507 Context
.ChildHandleBuffer
= ChildHandleBuffer
;
508 Status
= NetDestroyLinkList (
510 Mtftp6DestroyChildEntryInHandleBuffer
,
516 if (NumberOfChildren
== 0 && IsListEmpty (&Service
->Children
)) {
518 // Destroy the Mtftp6 service if there is no Mtftp6 child instance left.
520 gBS
->UninstallProtocolInterface (
522 &gEfiMtftp6ServiceBindingProtocolGuid
,
526 Mtftp6DestroyService (Service
);
527 Status
= EFI_SUCCESS
;
535 Creates a child handle and installs a protocol.
537 The CreateChild() function installs a protocol on ChildHandle.
538 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
539 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
541 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
542 @param[in, out] ChildHandle Pointer to the handle of the child to create. If it is NULL,
543 then a new handle is created. If it is a pointer to an existing
544 UEFI handle, then the protocol is added to the existing UEFI handle.
546 @retval EFI_SUCCES The protocol was added to ChildHandle.
547 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
548 @retval Others The child handle was not created.
553 Mtftp6ServiceBindingCreateChild (
554 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
555 IN OUT EFI_HANDLE
*ChildHandle
558 MTFTP6_SERVICE
*Service
;
559 MTFTP6_INSTANCE
*Instance
;
564 if (This
== NULL
|| ChildHandle
== NULL
) {
565 return EFI_INVALID_PARAMETER
;
568 Service
= MTFTP6_SERVICE_FROM_THIS (This
);
570 Status
= Mtftp6CreateInstance (Service
, &Instance
);
572 if (EFI_ERROR (Status
)) {
576 ASSERT (Instance
!= NULL
);
579 // Install the Mtftp6 protocol on the new child handle.
581 Status
= gBS
->InstallMultipleProtocolInterfaces (
583 &gEfiMtftp6ProtocolGuid
,
588 if (EFI_ERROR (Status
)) {
592 Instance
->Handle
= *ChildHandle
;
595 // Open the Udp6 protocol by child.
597 Status
= gBS
->OpenProtocol (
598 Service
->DummyUdpIo
->UdpHandle
,
599 &gEfiUdp6ProtocolGuid
,
601 gMtftp6DriverBinding
.DriverBindingHandle
,
603 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
606 if (EFI_ERROR (Status
)) {
607 gBS
->UninstallMultipleProtocolInterfaces (
609 &gEfiMtftp6ProtocolGuid
,
618 // Add the new Mtftp6 instance into the children list of Mtftp6 service.
620 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
622 InsertTailList (&Service
->Children
, &Instance
->Link
);
623 Service
->ChildrenNum
++;
625 gBS
->RestoreTPL (OldTpl
);
630 Mtftp6DestroyInstance (Instance
);
636 Destroys a child handle with a protocol installed on it.
638 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
639 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
640 last protocol on ChildHandle, then ChildHandle is destroyed.
642 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
643 @param[in] ChildHandle Handle of the child to destroy.
645 @retval EFI_SUCCES The protocol was removed from ChildHandle.
646 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
647 @retval EFI_INVALID_PARAMETER Child handle is NULL.
648 @retval Others The child handle was not destroyed
653 Mtftp6ServiceBindingDestroyChild (
654 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
655 IN EFI_HANDLE ChildHandle
658 MTFTP6_SERVICE
*Service
;
659 MTFTP6_INSTANCE
*Instance
;
660 EFI_MTFTP6_PROTOCOL
*Mtftp6
;
664 if (This
== NULL
|| ChildHandle
== NULL
) {
665 return EFI_INVALID_PARAMETER
;
669 // Locate the Nic handle to retrieve the Mtftp6 private data.
671 Status
= gBS
->OpenProtocol (
673 &gEfiMtftp6ProtocolGuid
,
675 gMtftp6DriverBinding
.DriverBindingHandle
,
677 EFI_OPEN_PROTOCOL_GET_PROTOCOL
680 if (EFI_ERROR (Status
)) {
681 return EFI_UNSUPPORTED
;
684 Instance
= MTFTP6_INSTANCE_FROM_THIS (Mtftp6
);
685 Service
= MTFTP6_SERVICE_FROM_THIS (This
);
687 if (Instance
->Service
!= Service
) {
688 return EFI_INVALID_PARAMETER
;
692 // Check whether the instance already in Destroy state.
694 if (Instance
->InDestroy
) {
698 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
700 Instance
->InDestroy
= TRUE
;
703 Service
->DummyUdpIo
->UdpHandle
,
704 &gEfiUdp6ProtocolGuid
,
705 gMtftp6DriverBinding
.DriverBindingHandle
,
709 if (Instance
->UdpIo
!= NULL
) {
711 Instance
->UdpIo
->UdpHandle
,
712 &gEfiUdp6ProtocolGuid
,
713 gMtftp6DriverBinding
.DriverBindingHandle
,
718 if (Instance
->McastUdpIo
!= NULL
) {
720 Instance
->McastUdpIo
->UdpHandle
,
721 &gEfiUdp6ProtocolGuid
,
722 gMtftp6DriverBinding
.DriverBindingHandle
,
728 // Uninstall the MTFTP6 protocol first to enable a top down destruction.
730 gBS
->RestoreTPL (OldTpl
);
731 Status
= gBS
->UninstallProtocolInterface (
733 &gEfiMtftp6ProtocolGuid
,
736 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
737 if (EFI_ERROR (Status
)) {
738 Instance
->InDestroy
= FALSE
;
739 gBS
->RestoreTPL (OldTpl
);
744 // Remove the Mtftp6 instance from the children list of Mtftp6 service.
746 RemoveEntryList (&Instance
->Link
);
747 Service
->ChildrenNum
--;
749 gBS
->RestoreTPL (OldTpl
);
751 Mtftp6DestroyInstance (Instance
);