2 The driver binding and service binding protocol for DnsDxe driver.
4 Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
11 EFI_DRIVER_BINDING_PROTOCOL gDns4DriverBinding
= {
12 Dns4DriverBindingSupported
,
13 Dns4DriverBindingStart
,
14 Dns4DriverBindingStop
,
20 EFI_DRIVER_BINDING_PROTOCOL gDns6DriverBinding
= {
21 Dns6DriverBindingSupported
,
22 Dns6DriverBindingStart
,
23 Dns6DriverBindingStop
,
29 EFI_SERVICE_BINDING_PROTOCOL mDns4ServiceBinding
= {
30 Dns4ServiceBindingCreateChild
,
31 Dns4ServiceBindingDestroyChild
34 EFI_SERVICE_BINDING_PROTOCOL mDns6ServiceBinding
= {
35 Dns6ServiceBindingCreateChild
,
36 Dns6ServiceBindingDestroyChild
39 DNS_DRIVER_DATA
*mDriverData
= NULL
;
42 Destroy the DNS instance and recycle the resources.
44 @param[in] Instance The pointer to the DNS instance.
49 IN DNS_INSTANCE
*Instance
52 ZeroMem (&Instance
->Dns4CfgData
, sizeof (EFI_DNS4_CONFIG_DATA
));
54 ZeroMem (&Instance
->Dns6CfgData
, sizeof (EFI_DNS6_CONFIG_DATA
));
56 if (!NetMapIsEmpty (&Instance
->Dns4TxTokens
)) {
57 Dns4InstanceCancelToken (Instance
, NULL
);
60 if (!NetMapIsEmpty (&Instance
->Dns6TxTokens
)) {
61 Dns6InstanceCancelToken (Instance
, NULL
);
64 if (Instance
->UdpIo
!= NULL
) {
65 UdpIoFreeIo (Instance
->UdpIo
);
72 Create the DNS instance and initialize it.
74 @param[in] Service The pointer to the DNS service.
75 @param[out] Instance The pointer to the DNS instance.
77 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
78 @retval EFI_SUCCESS The DNS instance is created.
83 IN DNS_SERVICE
*Service
,
84 OUT DNS_INSTANCE
**Instance
91 DnsIns
= AllocateZeroPool (sizeof (DNS_INSTANCE
));
93 return EFI_OUT_OF_RESOURCES
;
96 DnsIns
->Signature
= DNS_INSTANCE_SIGNATURE
;
97 InitializeListHead (&DnsIns
->Link
);
98 DnsIns
->State
= DNS_STATE_UNCONFIGED
;
99 DnsIns
->InDestroy
= FALSE
;
100 DnsIns
->Service
= Service
;
102 if (Service
->IpVersion
== IP_VERSION_4
) {
103 CopyMem (&DnsIns
->Dns4
, &mDns4Protocol
, sizeof (DnsIns
->Dns4
));
104 NetMapInit (&DnsIns
->Dns4TxTokens
);
106 CopyMem (&DnsIns
->Dns6
, &mDns6Protocol
, sizeof (DnsIns
->Dns6
));
107 NetMapInit (&DnsIns
->Dns6TxTokens
);
110 DnsIns
->UdpIo
= UdpIoCreateIo (
111 Service
->ControllerHandle
, /// NicHandle
112 Service
->ImageHandle
,
117 if (DnsIns
->UdpIo
== NULL
) {
119 return EFI_OUT_OF_RESOURCES
;
128 Callback function which provided by user to remove one node in NetDestroyLinkList process.
130 @param[in] Entry The entry to be removed.
131 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
133 @retval EFI_SUCCESS The entry has been removed successfully.
134 @retval Others Fail to remove the entry.
139 DnsDestroyChildEntryInHandleBuffer (
140 IN LIST_ENTRY
*Entry
,
144 DNS_INSTANCE
*Instance
;
145 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
146 UINTN NumberOfChildren
;
147 EFI_HANDLE
*ChildHandleBuffer
;
149 if (Entry
== NULL
|| Context
== NULL
) {
150 return EFI_INVALID_PARAMETER
;
153 Instance
= NET_LIST_USER_STRUCT_S (Entry
, DNS_INSTANCE
, Link
, DNS_INSTANCE_SIGNATURE
);
154 ServiceBinding
= ((DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->ServiceBinding
;
155 NumberOfChildren
= ((DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->NumberOfChildren
;
156 ChildHandleBuffer
= ((DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->ChildHandleBuffer
;
158 if (!NetIsInHandleBuffer (Instance
->ChildHandle
, NumberOfChildren
, ChildHandleBuffer
)) {
162 return ServiceBinding
->DestroyChild (ServiceBinding
, Instance
->ChildHandle
);
166 Config a NULL UDP that is used to keep the connection between UDP and DNS.
168 Just leave the Udp child unconfigured. When UDP is unloaded,
169 DNS will be informed with DriverBinding Stop.
171 @param UdpIo The UDP_IO to configure
172 @param Context The opaque parameter to the callback
174 @retval EFI_SUCCESS It always return EFI_SUCCESS directly.
188 Release all the resource used the DNS service binding instance.
190 @param DnsSb The Dns service binding instance.
195 IN DNS_SERVICE
*DnsSb
198 UdpIoFreeIo (DnsSb
->ConnectUdp
);
200 if (DnsSb
->TimerToGetMap
!= NULL
) {
201 gBS
->CloseEvent (DnsSb
->TimerToGetMap
);
204 if (DnsSb
->Timer
!= NULL
) {
205 gBS
->CloseEvent (DnsSb
->Timer
);
212 Create then initialize a Dns service binding instance.
214 @param Controller The controller to install the DNS service
216 @param Image The driver binding image of the DNS driver
217 @param IpVersion IpVersion for this service
218 @param Service The variable to receive the created service
221 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the instance.
222 @retval EFI_DEVICE_ERROR Failed to create a NULL UDP port to keep
224 @retval EFI_SUCCESS The service instance is created for the
230 IN EFI_HANDLE Controller
,
233 OUT DNS_SERVICE
**Service
239 Status
= EFI_SUCCESS
;
244 DnsSb
= AllocateZeroPool (sizeof (DNS_SERVICE
));
246 return EFI_OUT_OF_RESOURCES
;
249 DnsSb
->Signature
= DNS_SERVICE_SIGNATURE
;
251 if (IpVersion
== IP_VERSION_4
) {
252 DnsSb
->ServiceBinding
= mDns4ServiceBinding
;
254 DnsSb
->ServiceBinding
= mDns6ServiceBinding
;
257 DnsSb
->Dns4ChildrenNum
= 0;
258 InitializeListHead (&DnsSb
->Dns4ChildrenList
);
260 DnsSb
->Dns6ChildrenNum
= 0;
261 InitializeListHead (&DnsSb
->Dns6ChildrenList
);
263 DnsSb
->ControllerHandle
= Controller
;
264 DnsSb
->ImageHandle
= Image
;
266 DnsSb
->TimerToGetMap
= NULL
;
270 DnsSb
->IpVersion
= IpVersion
;
273 // Create the timer used to time out the procedure which is used to
274 // get the default IP address.
276 Status
= gBS
->CreateEvent (
281 &DnsSb
->TimerToGetMap
283 if (EFI_ERROR (Status
)) {
289 // Create the timer to retransmit packets.
291 Status
= gBS
->CreateEvent (
292 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
294 DnsOnTimerRetransmit
,
298 if (EFI_ERROR (Status
)) {
299 if (DnsSb
->TimerToGetMap
!= NULL
) {
300 gBS
->CloseEvent (DnsSb
->TimerToGetMap
);
306 DnsSb
->ConnectUdp
= NULL
;
307 DnsSb
->ConnectUdp
= UdpIoCreateIo (
314 if (DnsSb
->ConnectUdp
== NULL
) {
315 if (DnsSb
->TimerToGetMap
!= NULL
) {
316 gBS
->CloseEvent (DnsSb
->TimerToGetMap
);
318 gBS
->CloseEvent (DnsSb
->Timer
);
320 return EFI_DEVICE_ERROR
;
330 @param ImageHandle Handle that identifies the image to be unloaded.
332 @retval EFI_SUCCESS The image has been unloaded.
333 @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
339 IN EFI_HANDLE ImageHandle
345 DNS4_CACHE
*ItemCache4
;
346 DNS4_SERVER_IP
*ItemServerIp4
;
347 DNS6_CACHE
*ItemCache6
;
348 DNS6_SERVER_IP
*ItemServerIp6
;
351 ItemServerIp4
= NULL
;
353 ItemServerIp6
= NULL
;
356 // Disconnect the driver specified by ImageHandle
358 Status
= NetLibDefaultUnload(ImageHandle
);
359 if (EFI_ERROR (Status
)) {
366 if (mDriverData
!= NULL
) {
367 if (mDriverData
->Timer
!= NULL
) {
368 gBS
->CloseEvent (mDriverData
->Timer
);
371 while (!IsListEmpty (&mDriverData
->Dns4CacheList
)) {
372 Entry
= NetListRemoveHead (&mDriverData
->Dns4CacheList
);
373 ASSERT (Entry
!= NULL
);
374 ItemCache4
= NET_LIST_USER_STRUCT (Entry
, DNS4_CACHE
, AllCacheLink
);
375 FreePool (ItemCache4
->DnsCache
.HostName
);
376 FreePool (ItemCache4
->DnsCache
.IpAddress
);
377 FreePool (ItemCache4
);
380 while (!IsListEmpty (&mDriverData
->Dns4ServerList
)) {
381 Entry
= NetListRemoveHead (&mDriverData
->Dns4ServerList
);
382 ASSERT (Entry
!= NULL
);
383 ItemServerIp4
= NET_LIST_USER_STRUCT (Entry
, DNS4_SERVER_IP
, AllServerLink
);
384 FreePool (ItemServerIp4
);
387 while (!IsListEmpty (&mDriverData
->Dns6CacheList
)) {
388 Entry
= NetListRemoveHead (&mDriverData
->Dns6CacheList
);
389 ASSERT (Entry
!= NULL
);
390 ItemCache6
= NET_LIST_USER_STRUCT (Entry
, DNS6_CACHE
, AllCacheLink
);
391 FreePool (ItemCache6
->DnsCache
.HostName
);
392 FreePool (ItemCache6
->DnsCache
.IpAddress
);
393 FreePool (ItemCache6
);
396 while (!IsListEmpty (&mDriverData
->Dns6ServerList
)) {
397 Entry
= NetListRemoveHead (&mDriverData
->Dns6ServerList
);
398 ASSERT (Entry
!= NULL
);
399 ItemServerIp6
= NET_LIST_USER_STRUCT (Entry
, DNS6_SERVER_IP
, AllServerLink
);
400 FreePool (ItemServerIp6
);
403 FreePool (mDriverData
);
410 This is the declaration of an EFI image entry point. This entry point is
411 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
412 both device drivers and bus drivers.
414 @param ImageHandle The firmware allocated handle for the UEFI image.
415 @param SystemTable A pointer to the EFI System Table.
417 @retval EFI_SUCCESS The operation completed successfully.
418 @retval Others An unexpected error occurred.
422 DnsDriverEntryPoint (
423 IN EFI_HANDLE ImageHandle
,
424 IN EFI_SYSTEM_TABLE
*SystemTable
429 Status
= EFI_SUCCESS
;
432 // Install the Dns4 Driver Binding Protocol.
434 Status
= EfiLibInstallDriverBindingComponentName2 (
442 if (EFI_ERROR (Status
)) {
447 // Install the Dns6 Driver Binding Protocol.
449 Status
= EfiLibInstallDriverBindingComponentName2 (
457 if (EFI_ERROR (Status
)) {
462 // Create the driver data structures.
464 mDriverData
= AllocateZeroPool (sizeof (DNS_DRIVER_DATA
));
465 if (mDriverData
== NULL
) {
466 Status
= EFI_OUT_OF_RESOURCES
;
471 // Create the timer event to update DNS cache list.
473 Status
= gBS
->CreateEvent (
474 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
480 if (EFI_ERROR (Status
)) {
484 Status
= gBS
->SetTimer (mDriverData
->Timer
, TimerPeriodic
, TICKS_PER_SECOND
);
485 if (EFI_ERROR (Status
)) {
489 InitializeListHead (&mDriverData
->Dns4CacheList
);
490 InitializeListHead (&mDriverData
->Dns4ServerList
);
491 InitializeListHead (&mDriverData
->Dns6CacheList
);
492 InitializeListHead (&mDriverData
->Dns6ServerList
);
497 gBS
->CloseEvent (mDriverData
->Timer
);
500 FreePool (mDriverData
);
503 EfiLibUninstallDriverBindingComponentName2 (
510 EfiLibUninstallDriverBindingComponentName2 (
520 Tests to see if this driver supports a given controller. If a child device is provided,
521 it further tests to see if this driver supports creating a handle for the specified child device.
523 This function checks to see if the driver specified by This supports the device specified by
524 ControllerHandle. Drivers will typically use the device path attached to
525 ControllerHandle and/or the services from the bus I/O abstraction attached to
526 ControllerHandle to determine if the driver supports ControllerHandle. This function
527 may be called many times during platform initialization. In order to reduce boot times, the tests
528 performed by this function must be very small, and take as little time as possible to execute. This
529 function must not change the state of any hardware devices, and this function must be aware that the
530 device specified by ControllerHandle may already be managed by the same driver or a
531 different driver. This function must match its calls to AllocatePages() with FreePages(),
532 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
533 Because ControllerHandle may have been previously started by the same driver, if a protocol is
534 already in the opened state, then it must not be closed with CloseProtocol(). This is required
535 to guarantee the state of ControllerHandle is not modified by this function.
537 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
538 @param[in] ControllerHandle The handle of the controller to test. This handle
539 must support a protocol interface that supplies
540 an I/O abstraction to the driver.
541 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
542 parameter is ignored by device drivers, and is optional for bus
543 drivers. For bus drivers, if this parameter is not NULL, then
544 the bus driver must determine if the bus controller specified
545 by ControllerHandle and the child controller specified
546 by RemainingDevicePath are both supported by this
549 @retval EFI_SUCCESS The device specified by ControllerHandle and
550 RemainingDevicePath is supported by the driver specified by This.
551 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
552 RemainingDevicePath is already being managed by the driver
554 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
555 RemainingDevicePath is already being managed by a different
556 driver or an application that requires exclusive access.
557 Currently not implemented.
558 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
559 RemainingDevicePath is not supported by the driver specified by This.
563 Dns4DriverBindingSupported (
564 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
565 IN EFI_HANDLE ControllerHandle
,
566 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
572 // Test for the Dns4ServiceBinding Protocol.
574 Status
= gBS
->OpenProtocol (
576 &gEfiDns4ServiceBindingProtocolGuid
,
578 This
->DriverBindingHandle
,
580 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
582 if (!EFI_ERROR (Status
)) {
583 return EFI_ALREADY_STARTED
;
587 // Test for the Udp4ServiceBinding Protocol.
589 Status
= gBS
->OpenProtocol (
591 &gEfiUdp4ServiceBindingProtocolGuid
,
593 This
->DriverBindingHandle
,
595 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
602 Starts a device controller or a bus controller.
604 The Start() function is designed to be invoked from the EFI boot service ConnectController().
605 As a result, much of the error checking on the parameters to Start() has been moved into this
606 common boot service. It is legal to call Start() from other locations,
607 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
608 1. ControllerHandle must be a valid EFI_HANDLE.
609 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
610 EFI_DEVICE_PATH_PROTOCOL.
611 3. Prior to calling Start(), the Supported() function for the driver specified by This must
612 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
614 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
615 @param[in] ControllerHandle The handle of the controller to start. This handle
616 must support a protocol interface that supplies
617 an I/O abstraction to the driver.
618 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
619 parameter is ignored by device drivers, and is optional for bus
620 drivers. For a bus driver, if this parameter is NULL, then handles
621 for all the children of Controller are created by this driver.
622 If this parameter is not NULL and the first Device Path Node is
623 not the End of Device Path Node, then only the handle for the
624 child device specified by the first Device Path Node of
625 RemainingDevicePath is created by this driver.
626 If the first Device Path Node of RemainingDevicePath is
627 the End of Device Path Node, no child handle is created by this
630 @retval EFI_SUCCESS The device was started.
631 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
632 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
633 @retval Others The driver failed to start the device.
638 Dns4DriverBindingStart (
639 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
640 IN EFI_HANDLE ControllerHandle
,
641 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
647 Status
= DnsCreateService (ControllerHandle
, This
->DriverBindingHandle
, IP_VERSION_4
, &DnsSb
);
648 if (EFI_ERROR (Status
)) {
652 ASSERT (DnsSb
!= NULL
);
654 Status
= gBS
->SetTimer (DnsSb
->Timer
, TimerPeriodic
, TICKS_PER_SECOND
);
655 if (EFI_ERROR (Status
)) {
660 // Install the Dns4ServiceBinding Protocol onto ControllerHandle.
662 Status
= gBS
->InstallMultipleProtocolInterfaces (
664 &gEfiDns4ServiceBindingProtocolGuid
,
665 &DnsSb
->ServiceBinding
,
668 if (EFI_ERROR (Status
)) {
675 DnsDestroyService (DnsSb
);
681 Stops a device controller or a bus controller.
683 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
684 As a result, much of the error checking on the parameters to Stop() has been moved
685 into this common boot service. It is legal to call Stop() from other locations,
686 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
687 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
688 same driver's Start() function.
689 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
690 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
691 Start() function, and the Start() function must have called OpenProtocol() on
692 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
694 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
695 @param[in] ControllerHandle A handle to the device being stopped. The handle must
696 support a bus specific I/O protocol for the driver
697 to use to stop the device.
698 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
699 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
700 if NumberOfChildren is 0.
702 @retval EFI_SUCCESS The device was stopped.
703 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
708 Dns4DriverBindingStop (
709 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
710 IN EFI_HANDLE ControllerHandle
,
711 IN UINTN NumberOfChildren
,
712 IN EFI_HANDLE
*ChildHandleBuffer OPTIONAL
715 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
717 EFI_HANDLE NicHandle
;
720 DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context
;
723 // DNS driver opens UDP child, So, Controller is a UDP
724 // child handle. Locate the Nic handle first. Then get the
725 // DNS private data back.
727 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiUdp4ProtocolGuid
);
729 if (NicHandle
== NULL
) {
733 Status
= gBS
->OpenProtocol (
735 &gEfiDns4ServiceBindingProtocolGuid
,
736 (VOID
**) &ServiceBinding
,
737 This
->DriverBindingHandle
,
739 EFI_OPEN_PROTOCOL_GET_PROTOCOL
741 if (EFI_ERROR (Status
)) {
742 return EFI_DEVICE_ERROR
;
745 DnsSb
= DNS_SERVICE_FROM_THIS (ServiceBinding
);
747 if (!IsListEmpty (&DnsSb
->Dns4ChildrenList
)) {
749 // Destroy the Dns child instance in ChildHandleBuffer.
751 List
= &DnsSb
->Dns4ChildrenList
;
752 Context
.ServiceBinding
= ServiceBinding
;
753 Context
.NumberOfChildren
= NumberOfChildren
;
754 Context
.ChildHandleBuffer
= ChildHandleBuffer
;
755 Status
= NetDestroyLinkList (
757 DnsDestroyChildEntryInHandleBuffer
,
763 if (NumberOfChildren
== 0 && IsListEmpty (&DnsSb
->Dns4ChildrenList
)) {
764 gBS
->UninstallProtocolInterface (
766 &gEfiDns4ServiceBindingProtocolGuid
,
770 DnsDestroyService (DnsSb
);
772 if (gDnsControllerNameTable
!= NULL
) {
773 FreeUnicodeStringTable (gDnsControllerNameTable
);
774 gDnsControllerNameTable
= NULL
;
777 Status
= EFI_SUCCESS
;
784 Tests to see if this driver supports a given controller. If a child device is provided,
785 it further tests to see if this driver supports creating a handle for the specified child device.
787 This function checks to see if the driver specified by This supports the device specified by
788 ControllerHandle. Drivers will typically use the device path attached to
789 ControllerHandle and/or the services from the bus I/O abstraction attached to
790 ControllerHandle to determine if the driver supports ControllerHandle. This function
791 may be called many times during platform initialization. In order to reduce boot times, the tests
792 performed by this function must be very small, and take as little time as possible to execute. This
793 function must not change the state of any hardware devices, and this function must be aware that the
794 device specified by ControllerHandle may already be managed by the same driver or a
795 different driver. This function must match its calls to AllocatePages() with FreePages(),
796 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
797 Because ControllerHandle may have been previously started by the same driver, if a protocol is
798 already in the opened state, then it must not be closed with CloseProtocol(). This is required
799 to guarantee the state of ControllerHandle is not modified by this function.
801 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
802 @param[in] ControllerHandle The handle of the controller to test. This handle
803 must support a protocol interface that supplies
804 an I/O abstraction to the driver.
805 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
806 parameter is ignored by device drivers, and is optional for bus
807 drivers. For bus drivers, if this parameter is not NULL, then
808 the bus driver must determine if the bus controller specified
809 by ControllerHandle and the child controller specified
810 by RemainingDevicePath are both supported by this
813 @retval EFI_SUCCESS The device specified by ControllerHandle and
814 RemainingDevicePath is supported by the driver specified by This.
815 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
816 RemainingDevicePath is already being managed by the driver
818 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
819 RemainingDevicePath is already being managed by a different
820 driver or an application that requires exclusive access.
821 Currently not implemented.
822 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
823 RemainingDevicePath is not supported by the driver specified by This.
827 Dns6DriverBindingSupported (
828 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
829 IN EFI_HANDLE ControllerHandle
,
830 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
836 // Test for the Dns6ServiceBinding Protocol
838 Status
= gBS
->OpenProtocol (
840 &gEfiDns6ServiceBindingProtocolGuid
,
842 This
->DriverBindingHandle
,
844 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
846 if (!EFI_ERROR (Status
)) {
847 return EFI_ALREADY_STARTED
;
851 // Test for the Udp6ServiceBinding Protocol
853 Status
= gBS
->OpenProtocol (
855 &gEfiUdp6ServiceBindingProtocolGuid
,
857 This
->DriverBindingHandle
,
859 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
866 Starts a device controller or a bus controller.
868 The Start() function is designed to be invoked from the EFI boot service ConnectController().
869 As a result, much of the error checking on the parameters to Start() has been moved into this
870 common boot service. It is legal to call Start() from other locations,
871 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
872 1. ControllerHandle must be a valid EFI_HANDLE.
873 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
874 EFI_DEVICE_PATH_PROTOCOL.
875 3. Prior to calling Start(), the Supported() function for the driver specified by This must
876 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
878 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
879 @param[in] ControllerHandle The handle of the controller to start. This handle
880 must support a protocol interface that supplies
881 an I/O abstraction to the driver.
882 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
883 parameter is ignored by device drivers, and is optional for bus
884 drivers. For a bus driver, if this parameter is NULL, then handles
885 for all the children of Controller are created by this driver.
886 If this parameter is not NULL and the first Device Path Node is
887 not the End of Device Path Node, then only the handle for the
888 child device specified by the first Device Path Node of
889 RemainingDevicePath is created by this driver.
890 If the first Device Path Node of RemainingDevicePath is
891 the End of Device Path Node, no child handle is created by this
894 @retval EFI_SUCCESS The device was started.
895 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
896 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
897 @retval Others The driver failed to start the device.
902 Dns6DriverBindingStart (
903 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
904 IN EFI_HANDLE ControllerHandle
,
905 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
911 Status
= DnsCreateService (ControllerHandle
, This
->DriverBindingHandle
, IP_VERSION_6
, &DnsSb
);
912 if (EFI_ERROR (Status
)) {
916 ASSERT (DnsSb
!= NULL
);
918 Status
= gBS
->SetTimer (DnsSb
->Timer
, TimerPeriodic
, TICKS_PER_SECOND
);
919 if (EFI_ERROR (Status
)) {
924 // Install the Dns6ServiceBinding Protocol onto ControllerHandle
926 Status
= gBS
->InstallMultipleProtocolInterfaces (
928 &gEfiDns6ServiceBindingProtocolGuid
,
929 &DnsSb
->ServiceBinding
,
933 if (EFI_ERROR (Status
)) {
940 DnsDestroyService (DnsSb
);
946 Stops a device controller or a bus controller.
948 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
949 As a result, much of the error checking on the parameters to Stop() has been moved
950 into this common boot service. It is legal to call Stop() from other locations,
951 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
952 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
953 same driver's Start() function.
954 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
955 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
956 Start() function, and the Start() function must have called OpenProtocol() on
957 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
959 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
960 @param[in] ControllerHandle A handle to the device being stopped. The handle must
961 support a bus specific I/O protocol for the driver
962 to use to stop the device.
963 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
964 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
965 if NumberOfChildren is 0.
967 @retval EFI_SUCCESS The device was stopped.
968 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
973 Dns6DriverBindingStop (
974 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
975 IN EFI_HANDLE ControllerHandle
,
976 IN UINTN NumberOfChildren
,
977 IN EFI_HANDLE
*ChildHandleBuffer OPTIONAL
980 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
982 EFI_HANDLE NicHandle
;
985 DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context
;
988 // DNS driver opens UDP child, So, Controller is a UDP
989 // child handle. Locate the Nic handle first. Then get the
990 // DNS private data back.
992 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiUdp6ProtocolGuid
);
994 if (NicHandle
== NULL
) {
998 Status
= gBS
->OpenProtocol (
1000 &gEfiDns6ServiceBindingProtocolGuid
,
1001 (VOID
**) &ServiceBinding
,
1002 This
->DriverBindingHandle
,
1004 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1006 if (EFI_ERROR (Status
)) {
1007 return EFI_DEVICE_ERROR
;
1010 DnsSb
= DNS_SERVICE_FROM_THIS (ServiceBinding
);
1012 if (!IsListEmpty (&DnsSb
->Dns6ChildrenList
)) {
1014 // Destroy the Dns child instance in ChildHandleBuffer.
1016 List
= &DnsSb
->Dns6ChildrenList
;
1017 Context
.ServiceBinding
= ServiceBinding
;
1018 Context
.NumberOfChildren
= NumberOfChildren
;
1019 Context
.ChildHandleBuffer
= ChildHandleBuffer
;
1020 Status
= NetDestroyLinkList (
1022 DnsDestroyChildEntryInHandleBuffer
,
1028 if (NumberOfChildren
== 0 && IsListEmpty (&DnsSb
->Dns6ChildrenList
)) {
1029 gBS
->UninstallProtocolInterface (
1031 &gEfiDns6ServiceBindingProtocolGuid
,
1035 DnsDestroyService (DnsSb
);
1037 if (gDnsControllerNameTable
!= NULL
) {
1038 FreeUnicodeStringTable (gDnsControllerNameTable
);
1039 gDnsControllerNameTable
= NULL
;
1042 Status
= EFI_SUCCESS
;
1049 Creates a child handle and installs a protocol.
1051 The CreateChild() function installs a protocol on ChildHandle.
1052 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
1053 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
1055 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
1056 @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
1057 then a new handle is created. If it is a pointer to an existing UEFI handle,
1058 then the protocol is added to the existing UEFI handle.
1060 @retval EFI_SUCCESS The protocol was added to ChildHandle.
1061 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
1062 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
1064 @retval other The child handle was not created
1069 Dns4ServiceBindingCreateChild (
1070 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
1071 IN EFI_HANDLE
*ChildHandle
1075 DNS_INSTANCE
*Instance
;
1080 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
1081 return EFI_INVALID_PARAMETER
;
1084 DnsSb
= DNS_SERVICE_FROM_THIS (This
);
1086 Status
= DnsCreateInstance (DnsSb
, &Instance
);
1087 if (EFI_ERROR (Status
)) {
1090 ASSERT (Instance
!= NULL
);
1093 // Install the DNS protocol onto ChildHandle
1095 Status
= gBS
->InstallMultipleProtocolInterfaces (
1097 &gEfiDns4ProtocolGuid
,
1101 if (EFI_ERROR (Status
)) {
1105 Instance
->ChildHandle
= *ChildHandle
;
1108 // Open the Udp4 protocol BY_CHILD.
1110 Status
= gBS
->OpenProtocol (
1111 DnsSb
->ConnectUdp
->UdpHandle
,
1112 &gEfiUdp4ProtocolGuid
,
1114 gDns4DriverBinding
.DriverBindingHandle
,
1115 Instance
->ChildHandle
,
1116 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1118 if (EFI_ERROR (Status
)) {
1119 gBS
->UninstallMultipleProtocolInterfaces (
1120 Instance
->ChildHandle
,
1121 &gEfiDns4ProtocolGuid
,
1130 // Open the Udp4 protocol by child.
1132 Status
= gBS
->OpenProtocol (
1133 Instance
->UdpIo
->UdpHandle
,
1134 &gEfiUdp4ProtocolGuid
,
1136 gDns4DriverBinding
.DriverBindingHandle
,
1137 Instance
->ChildHandle
,
1138 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1140 if (EFI_ERROR (Status
)) {
1142 // Close the Udp4 protocol.
1144 gBS
->CloseProtocol (
1145 DnsSb
->ConnectUdp
->UdpHandle
,
1146 &gEfiUdp4ProtocolGuid
,
1147 gDns4DriverBinding
.DriverBindingHandle
,
1151 gBS
->UninstallMultipleProtocolInterfaces (
1152 Instance
->ChildHandle
,
1153 &gEfiDns4ProtocolGuid
,
1162 // Add it to the parent's child list.
1164 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1166 InsertTailList (&DnsSb
->Dns4ChildrenList
, &Instance
->Link
);
1167 DnsSb
->Dns4ChildrenNum
++;
1169 gBS
->RestoreTPL (OldTpl
);
1175 DnsDestroyInstance (Instance
);
1180 Destroys a child handle with a protocol installed on it.
1182 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
1183 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
1184 last protocol on ChildHandle, then ChildHandle is destroyed.
1186 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
1187 @param[in] ChildHandle Handle of the child to destroy
1189 @retval EFI_SUCCESS The protocol was removed from ChildHandle.
1190 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
1191 @retval EFI_INVALID_PARAMETER Child handle is NULL.
1192 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
1193 because its services are being used.
1194 @retval other The child handle was not destroyed
1199 Dns4ServiceBindingDestroyChild (
1200 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
1201 IN EFI_HANDLE ChildHandle
1205 DNS_INSTANCE
*Instance
;
1207 EFI_DNS4_PROTOCOL
*Dns4
;
1211 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
1212 return EFI_INVALID_PARAMETER
;
1216 // Retrieve the private context data structures
1218 Status
= gBS
->OpenProtocol (
1220 &gEfiDns4ProtocolGuid
,
1222 gDns4DriverBinding
.DriverBindingHandle
,
1224 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1227 if (EFI_ERROR (Status
)) {
1228 return EFI_UNSUPPORTED
;
1231 Instance
= DNS_INSTANCE_FROM_THIS_PROTOCOL4 (Dns4
);
1232 DnsSb
= DNS_SERVICE_FROM_THIS (This
);
1234 if (Instance
->Service
!= DnsSb
) {
1235 return EFI_INVALID_PARAMETER
;
1238 if (Instance
->InDestroy
) {
1242 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1244 Instance
->InDestroy
= TRUE
;
1247 // Close the Udp4 protocol.
1249 gBS
->CloseProtocol (
1250 DnsSb
->ConnectUdp
->UdpHandle
,
1251 &gEfiUdp4ProtocolGuid
,
1252 gDns4DriverBinding
.DriverBindingHandle
,
1256 gBS
->CloseProtocol (
1257 Instance
->UdpIo
->UdpHandle
,
1258 &gEfiUdp4ProtocolGuid
,
1259 gDns4DriverBinding
.DriverBindingHandle
,
1263 gBS
->RestoreTPL (OldTpl
);
1266 // Uninstall the DNS protocol first to enable a top down destruction.
1268 Status
= gBS
->UninstallProtocolInterface (
1270 &gEfiDns4ProtocolGuid
,
1274 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1276 if (EFI_ERROR (Status
)) {
1277 Instance
->InDestroy
= FALSE
;
1278 gBS
->RestoreTPL (OldTpl
);
1282 RemoveEntryList (&Instance
->Link
);
1283 DnsSb
->Dns4ChildrenNum
--;
1285 gBS
->RestoreTPL (OldTpl
);
1287 DnsDestroyInstance (Instance
);
1292 Creates a child handle and installs a protocol.
1294 The CreateChild() function installs a protocol on ChildHandle.
1295 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
1296 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
1298 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
1299 @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
1300 then a new handle is created. If it is a pointer to an existing UEFI handle,
1301 then the protocol is added to the existing UEFI handle.
1303 @retval EFI_SUCCESS The protocol was added to ChildHandle.
1304 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
1305 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
1307 @retval other The child handle was not created
1312 Dns6ServiceBindingCreateChild (
1313 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
1314 IN EFI_HANDLE
*ChildHandle
1318 DNS_INSTANCE
*Instance
;
1323 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
1324 return EFI_INVALID_PARAMETER
;
1327 DnsSb
= DNS_SERVICE_FROM_THIS (This
);
1329 Status
= DnsCreateInstance (DnsSb
, &Instance
);
1330 if (EFI_ERROR (Status
)) {
1333 ASSERT (Instance
!= NULL
);
1336 // Install the DNS protocol onto ChildHandle
1338 Status
= gBS
->InstallMultipleProtocolInterfaces (
1340 &gEfiDns6ProtocolGuid
,
1344 if (EFI_ERROR (Status
)) {
1348 Instance
->ChildHandle
= *ChildHandle
;
1351 // Open the Udp6 protocol BY_CHILD.
1353 Status
= gBS
->OpenProtocol (
1354 DnsSb
->ConnectUdp
->UdpHandle
,
1355 &gEfiUdp6ProtocolGuid
,
1357 gDns6DriverBinding
.DriverBindingHandle
,
1358 Instance
->ChildHandle
,
1359 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1361 if (EFI_ERROR (Status
)) {
1362 gBS
->UninstallMultipleProtocolInterfaces (
1363 Instance
->ChildHandle
,
1364 &gEfiDns6ProtocolGuid
,
1373 // Open the Udp6 protocol by child.
1375 Status
= gBS
->OpenProtocol (
1376 Instance
->UdpIo
->UdpHandle
,
1377 &gEfiUdp6ProtocolGuid
,
1379 gDns6DriverBinding
.DriverBindingHandle
,
1380 Instance
->ChildHandle
,
1381 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1383 if (EFI_ERROR (Status
)) {
1385 // Close the Udp6 protocol.
1387 gBS
->CloseProtocol (
1388 DnsSb
->ConnectUdp
->UdpHandle
,
1389 &gEfiUdp6ProtocolGuid
,
1390 gDns6DriverBinding
.DriverBindingHandle
,
1394 gBS
->UninstallMultipleProtocolInterfaces (
1395 Instance
->ChildHandle
,
1396 &gEfiDns6ProtocolGuid
,
1405 // Add it to the parent's child list.
1407 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1409 InsertTailList (&DnsSb
->Dns6ChildrenList
, &Instance
->Link
);
1410 DnsSb
->Dns6ChildrenNum
++;
1412 gBS
->RestoreTPL (OldTpl
);
1418 DnsDestroyInstance (Instance
);
1423 Destroys a child handle with a protocol installed on it.
1425 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
1426 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
1427 last protocol on ChildHandle, then ChildHandle is destroyed.
1429 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
1430 @param[in] ChildHandle Handle of the child to destroy
1432 @retval EFI_SUCCESS The protocol was removed from ChildHandle.
1433 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
1434 @retval EFI_INVALID_PARAMETER Child handle is NULL.
1435 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
1436 because its services are being used.
1437 @retval other The child handle was not destroyed
1442 Dns6ServiceBindingDestroyChild (
1443 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
1444 IN EFI_HANDLE ChildHandle
1448 DNS_INSTANCE
*Instance
;
1450 EFI_DNS6_PROTOCOL
*Dns6
;
1454 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
1455 return EFI_INVALID_PARAMETER
;
1459 // Retrieve the private context data structures
1461 Status
= gBS
->OpenProtocol (
1463 &gEfiDns6ProtocolGuid
,
1465 gDns6DriverBinding
.DriverBindingHandle
,
1467 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1470 if (EFI_ERROR (Status
)) {
1471 return EFI_UNSUPPORTED
;
1474 Instance
= DNS_INSTANCE_FROM_THIS_PROTOCOL6 (Dns6
);
1475 DnsSb
= DNS_SERVICE_FROM_THIS (This
);
1477 if (Instance
->Service
!= DnsSb
) {
1478 return EFI_INVALID_PARAMETER
;
1481 if (Instance
->InDestroy
) {
1485 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1487 Instance
->InDestroy
= TRUE
;
1490 // Close the Udp6 protocol.
1492 gBS
->CloseProtocol (
1493 DnsSb
->ConnectUdp
->UdpHandle
,
1494 &gEfiUdp6ProtocolGuid
,
1495 gDns6DriverBinding
.DriverBindingHandle
,
1499 gBS
->CloseProtocol (
1500 Instance
->UdpIo
->UdpHandle
,
1501 &gEfiUdp6ProtocolGuid
,
1502 gDns6DriverBinding
.DriverBindingHandle
,
1506 gBS
->RestoreTPL (OldTpl
);
1509 // Uninstall the DNS protocol first to enable a top down destruction.
1511 Status
= gBS
->UninstallProtocolInterface (
1513 &gEfiDns6ProtocolGuid
,
1517 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1519 if (EFI_ERROR (Status
)) {
1520 Instance
->InDestroy
= FALSE
;
1521 gBS
->RestoreTPL (OldTpl
);
1525 RemoveEntryList (&Instance
->Link
);
1526 DnsSb
->Dns6ChildrenNum
--;
1528 gBS
->RestoreTPL (OldTpl
);
1530 DnsDestroyInstance (Instance
);