2 The driver binding and service binding protocol for DnsDxe driver.
4 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 EFI_DRIVER_BINDING_PROTOCOL gDns4DriverBinding
= {
18 Dns4DriverBindingSupported
,
19 Dns4DriverBindingStart
,
20 Dns4DriverBindingStop
,
26 EFI_DRIVER_BINDING_PROTOCOL gDns6DriverBinding
= {
27 Dns6DriverBindingSupported
,
28 Dns6DriverBindingStart
,
29 Dns6DriverBindingStop
,
35 EFI_SERVICE_BINDING_PROTOCOL mDns4ServiceBinding
= {
36 Dns4ServiceBindingCreateChild
,
37 Dns4ServiceBindingDestroyChild
40 EFI_SERVICE_BINDING_PROTOCOL mDns6ServiceBinding
= {
41 Dns6ServiceBindingCreateChild
,
42 Dns6ServiceBindingDestroyChild
45 DNS_DRIVER_DATA
*mDriverData
= NULL
;
48 Destroy the DNS instance and recycle the resources.
50 @param[in] Instance The pointer to the DNS instance.
55 IN DNS_INSTANCE
*Instance
58 ZeroMem (&Instance
->Dns4CfgData
, sizeof (EFI_DNS4_CONFIG_DATA
));
60 ZeroMem (&Instance
->Dns6CfgData
, sizeof (EFI_DNS6_CONFIG_DATA
));
62 if (!NetMapIsEmpty (&Instance
->Dns4TxTokens
)) {
63 Dns4InstanceCancelToken (Instance
, NULL
);
66 if (!NetMapIsEmpty (&Instance
->Dns6TxTokens
)) {
67 Dns6InstanceCancelToken (Instance
, NULL
);
70 if (Instance
->UdpIo
!= NULL
) {
71 UdpIoFreeIo (Instance
->UdpIo
);
78 Create the DNS instance and initialize it.
80 @param[in] Service The pointer to the DNS service.
81 @param[out] Instance The pointer to the DNS instance.
83 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
84 @retval EFI_SUCCESS The DNS instance is created.
89 IN DNS_SERVICE
*Service
,
90 OUT DNS_INSTANCE
**Instance
97 DnsIns
= AllocateZeroPool (sizeof (DNS_INSTANCE
));
99 return EFI_OUT_OF_RESOURCES
;
102 DnsIns
->Signature
= DNS_INSTANCE_SIGNATURE
;
103 InitializeListHead (&DnsIns
->Link
);
104 DnsIns
->State
= DNS_STATE_UNCONFIGED
;
105 DnsIns
->InDestroy
= FALSE
;
106 DnsIns
->Service
= Service
;
108 if (Service
->IpVersion
== IP_VERSION_4
) {
109 CopyMem (&DnsIns
->Dns4
, &mDns4Protocol
, sizeof (DnsIns
->Dns4
));
110 NetMapInit (&DnsIns
->Dns4TxTokens
);
112 CopyMem (&DnsIns
->Dns6
, &mDns6Protocol
, sizeof (DnsIns
->Dns6
));
113 NetMapInit (&DnsIns
->Dns6TxTokens
);
116 DnsIns
->UdpIo
= UdpIoCreateIo (
117 Service
->ControllerHandle
, /// NicHandle
118 Service
->ImageHandle
,
123 if (DnsIns
->UdpIo
== NULL
) {
125 return EFI_OUT_OF_RESOURCES
;
134 Callback function which provided by user to remove one node in NetDestroyLinkList process.
136 @param[in] Entry The entry to be removed.
137 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
139 @retval EFI_SUCCESS The entry has been removed successfully.
140 @retval Others Fail to remove the entry.
145 DnsDestroyChildEntryInHandleBuffer (
146 IN LIST_ENTRY
*Entry
,
150 DNS_INSTANCE
*Instance
;
151 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
152 UINTN NumberOfChildren
;
153 EFI_HANDLE
*ChildHandleBuffer
;
155 if (Entry
== NULL
|| Context
== NULL
) {
156 return EFI_INVALID_PARAMETER
;
159 Instance
= NET_LIST_USER_STRUCT_S (Entry
, DNS_INSTANCE
, Link
, DNS_INSTANCE_SIGNATURE
);
160 ServiceBinding
= ((DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->ServiceBinding
;
161 NumberOfChildren
= ((DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->NumberOfChildren
;
162 ChildHandleBuffer
= ((DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT
*) Context
)->ChildHandleBuffer
;
164 if (!NetIsInHandleBuffer (Instance
->ChildHandle
, NumberOfChildren
, ChildHandleBuffer
)) {
168 return ServiceBinding
->DestroyChild (ServiceBinding
, Instance
->ChildHandle
);
172 Config a NULL UDP that is used to keep the connection between UDP and DNS.
174 Just leave the Udp child unconfigured. When UDP is unloaded,
175 DNS will be informed with DriverBinding Stop.
177 @param UdpIo The UDP_IO to configure
178 @param Context The opaque parameter to the callback
180 @retval EFI_SUCCESS It always return EFI_SUCCESS directly.
194 Release all the resource used the DNS service binding instance.
196 @param DnsSb The Dns service binding instance.
201 IN DNS_SERVICE
*DnsSb
204 UdpIoFreeIo (DnsSb
->ConnectUdp
);
206 if (DnsSb
->TimerToGetMap
!= NULL
){
207 gBS
->CloseEvent (DnsSb
->TimerToGetMap
);
210 if (DnsSb
->Timer
!= NULL
){
211 gBS
->CloseEvent (DnsSb
->Timer
);
218 Create then initialize a Dns service binding instance.
220 @param Controller The controller to install the DNS service
222 @param Image The driver binding image of the DNS driver
223 @param IpVersion IpVersion for this service
224 @param Service The variable to receive the created service
227 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the instance.
228 @retval EFI_DEVICE_ERROR Failed to create a NULL UDP port to keep
230 @retval EFI_SUCCESS The service instance is created for the
236 IN EFI_HANDLE Controller
,
239 OUT DNS_SERVICE
**Service
245 Status
= EFI_SUCCESS
;
250 DnsSb
= AllocateZeroPool (sizeof (DNS_SERVICE
));
252 return EFI_OUT_OF_RESOURCES
;
255 DnsSb
->Signature
= DNS_SERVICE_SIGNATURE
;
257 if (IpVersion
== IP_VERSION_4
) {
258 DnsSb
->ServiceBinding
= mDns4ServiceBinding
;
260 DnsSb
->ServiceBinding
= mDns6ServiceBinding
;
263 DnsSb
->Dns4ChildrenNum
= 0;
264 InitializeListHead (&DnsSb
->Dns4ChildrenList
);
266 DnsSb
->Dns6ChildrenNum
= 0;
267 InitializeListHead (&DnsSb
->Dns6ChildrenList
);
269 DnsSb
->ControllerHandle
= Controller
;
270 DnsSb
->ImageHandle
= Image
;
272 DnsSb
->TimerToGetMap
= NULL
;
276 DnsSb
->IpVersion
= IpVersion
;
279 // Create the timer used to time out the procedure which is used to
280 // get the default IP address.
282 Status
= gBS
->CreateEvent (
287 &DnsSb
->TimerToGetMap
289 if (EFI_ERROR (Status
)) {
295 // Create the timer to retransmit packets.
297 Status
= gBS
->CreateEvent (
298 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
300 DnsOnTimerRetransmit
,
304 if (EFI_ERROR (Status
)) {
305 if (DnsSb
->TimerToGetMap
!= NULL
) {
306 gBS
->CloseEvent (DnsSb
->TimerToGetMap
);
312 DnsSb
->ConnectUdp
= NULL
;
313 DnsSb
->ConnectUdp
= UdpIoCreateIo (
320 if (DnsSb
->ConnectUdp
== NULL
) {
321 if (DnsSb
->TimerToGetMap
!= NULL
) {
322 gBS
->CloseEvent (DnsSb
->TimerToGetMap
);
324 gBS
->CloseEvent (DnsSb
->Timer
);
326 return EFI_DEVICE_ERROR
;
336 @param ImageHandle Handle that identifies the image to be unloaded.
338 @retval EFI_SUCCESS The image has been unloaded.
339 @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
345 IN EFI_HANDLE ImageHandle
351 DNS4_CACHE
*ItemCache4
;
352 DNS4_SERVER_IP
*ItemServerIp4
;
353 DNS6_CACHE
*ItemCache6
;
354 DNS6_SERVER_IP
*ItemServerIp6
;
357 ItemServerIp4
= NULL
;
359 ItemServerIp6
= NULL
;
362 // Disconnect the driver specified by ImageHandle
364 Status
= NetLibDefaultUnload(ImageHandle
);
365 if (EFI_ERROR (Status
)) {
372 if (mDriverData
!= NULL
) {
373 if (mDriverData
->Timer
!= NULL
) {
374 gBS
->CloseEvent (mDriverData
->Timer
);
377 while (!IsListEmpty (&mDriverData
->Dns4CacheList
)) {
378 Entry
= NetListRemoveHead (&mDriverData
->Dns4CacheList
);
379 ItemCache4
= NET_LIST_USER_STRUCT (Entry
, DNS4_CACHE
, AllCacheLink
);
380 if (ItemCache4
->DnsCache
.HostName
!= NULL
) {
381 FreePool (ItemCache4
->DnsCache
.HostName
);
383 if (ItemCache4
->DnsCache
.IpAddress
!= NULL
) {
384 FreePool (ItemCache4
->DnsCache
.IpAddress
);
386 FreePool (ItemCache4
);
389 while (!IsListEmpty (&mDriverData
->Dns4ServerList
)) {
390 Entry
= NetListRemoveHead (&mDriverData
->Dns4ServerList
);
391 ItemServerIp4
= NET_LIST_USER_STRUCT (Entry
, DNS4_SERVER_IP
, AllServerLink
);
392 FreePool (ItemServerIp4
);
395 while (!IsListEmpty (&mDriverData
->Dns6CacheList
)) {
396 Entry
= NetListRemoveHead (&mDriverData
->Dns6CacheList
);
397 ItemCache6
= NET_LIST_USER_STRUCT (Entry
, DNS6_CACHE
, AllCacheLink
);
398 if (ItemCache6
->DnsCache
.HostName
!= NULL
) {
399 FreePool (ItemCache6
->DnsCache
.HostName
);
401 if (ItemCache6
->DnsCache
.IpAddress
!= NULL
) {
402 FreePool (ItemCache6
->DnsCache
.IpAddress
);
404 FreePool (ItemCache6
);
407 while (!IsListEmpty (&mDriverData
->Dns6ServerList
)) {
408 Entry
= NetListRemoveHead (&mDriverData
->Dns6ServerList
);
409 ItemServerIp6
= NET_LIST_USER_STRUCT (Entry
, DNS6_SERVER_IP
, AllServerLink
);
410 FreePool (ItemServerIp6
);
413 FreePool (mDriverData
);
420 This is the declaration of an EFI image entry point. This entry point is
421 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
422 both device drivers and bus drivers.
424 @param ImageHandle The firmware allocated handle for the UEFI image.
425 @param SystemTable A pointer to the EFI System Table.
427 @retval EFI_SUCCESS The operation completed successfully.
428 @retval Others An unexpected error occurred.
432 DnsDriverEntryPoint (
433 IN EFI_HANDLE ImageHandle
,
434 IN EFI_SYSTEM_TABLE
*SystemTable
439 Status
= EFI_SUCCESS
;
442 // Install the Dns4 Driver Binding Protocol.
444 Status
= EfiLibInstallDriverBindingComponentName2 (
452 if (EFI_ERROR (Status
)) {
457 // Install the Dns6 Driver Binding Protocol.
459 Status
= EfiLibInstallDriverBindingComponentName2 (
467 if (EFI_ERROR (Status
)) {
472 // Create the driver data structures.
474 mDriverData
= AllocateZeroPool (sizeof (DNS_DRIVER_DATA
));
475 if (mDriverData
== NULL
) {
476 Status
= EFI_OUT_OF_RESOURCES
;
481 // Create the timer event to update DNS cache list.
483 Status
= gBS
->CreateEvent (
484 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
490 if (EFI_ERROR (Status
)) {
494 Status
= gBS
->SetTimer (mDriverData
->Timer
, TimerPeriodic
, TICKS_PER_SECOND
);
495 if (EFI_ERROR (Status
)) {
499 InitializeListHead (&mDriverData
->Dns4CacheList
);
500 InitializeListHead (&mDriverData
->Dns4ServerList
);
501 InitializeListHead (&mDriverData
->Dns6CacheList
);
502 InitializeListHead (&mDriverData
->Dns6ServerList
);
507 gBS
->CloseEvent (mDriverData
->Timer
);
510 FreePool (mDriverData
);
513 EfiLibUninstallDriverBindingComponentName2 (
520 EfiLibUninstallDriverBindingComponentName2 (
530 Tests to see if this driver supports a given controller. If a child device is provided,
531 it further tests to see if this driver supports creating a handle for the specified child device.
533 This function checks to see if the driver specified by This supports the device specified by
534 ControllerHandle. Drivers will typically use the device path attached to
535 ControllerHandle and/or the services from the bus I/O abstraction attached to
536 ControllerHandle to determine if the driver supports ControllerHandle. This function
537 may be called many times during platform initialization. In order to reduce boot times, the tests
538 performed by this function must be very small, and take as little time as possible to execute. This
539 function must not change the state of any hardware devices, and this function must be aware that the
540 device specified by ControllerHandle may already be managed by the same driver or a
541 different driver. This function must match its calls to AllocatePages() with FreePages(),
542 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
543 Because ControllerHandle may have been previously started by the same driver, if a protocol is
544 already in the opened state, then it must not be closed with CloseProtocol(). This is required
545 to guarantee the state of ControllerHandle is not modified by this function.
547 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
548 @param[in] ControllerHandle The handle of the controller to test. This handle
549 must support a protocol interface that supplies
550 an I/O abstraction to the driver.
551 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
552 parameter is ignored by device drivers, and is optional for bus
553 drivers. For bus drivers, if this parameter is not NULL, then
554 the bus driver must determine if the bus controller specified
555 by ControllerHandle and the child controller specified
556 by RemainingDevicePath are both supported by this
559 @retval EFI_SUCCESS The device specified by ControllerHandle and
560 RemainingDevicePath is supported by the driver specified by This.
561 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
562 RemainingDevicePath is already being managed by the driver
564 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
565 RemainingDevicePath is already being managed by a different
566 driver or an application that requires exclusive access.
567 Currently not implemented.
568 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
569 RemainingDevicePath is not supported by the driver specified by This.
573 Dns4DriverBindingSupported (
574 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
575 IN EFI_HANDLE ControllerHandle
,
576 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
582 // Test for the Dns4ServiceBinding Protocol.
584 Status
= gBS
->OpenProtocol (
586 &gEfiDns4ServiceBindingProtocolGuid
,
588 This
->DriverBindingHandle
,
590 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
592 if (!EFI_ERROR (Status
)) {
593 return EFI_ALREADY_STARTED
;
597 // Test for the Udp4ServiceBinding Protocol.
599 Status
= gBS
->OpenProtocol (
601 &gEfiUdp4ServiceBindingProtocolGuid
,
603 This
->DriverBindingHandle
,
605 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
612 Starts a device controller or a bus controller.
614 The Start() function is designed to be invoked from the EFI boot service ConnectController().
615 As a result, much of the error checking on the parameters to Start() has been moved into this
616 common boot service. It is legal to call Start() from other locations,
617 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
618 1. ControllerHandle must be a valid EFI_HANDLE.
619 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
620 EFI_DEVICE_PATH_PROTOCOL.
621 3. Prior to calling Start(), the Supported() function for the driver specified by This must
622 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
624 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
625 @param[in] ControllerHandle The handle of the controller to start. This handle
626 must support a protocol interface that supplies
627 an I/O abstraction to the driver.
628 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
629 parameter is ignored by device drivers, and is optional for bus
630 drivers. For a bus driver, if this parameter is NULL, then handles
631 for all the children of Controller are created by this driver.
632 If this parameter is not NULL and the first Device Path Node is
633 not the End of Device Path Node, then only the handle for the
634 child device specified by the first Device Path Node of
635 RemainingDevicePath is created by this driver.
636 If the first Device Path Node of RemainingDevicePath is
637 the End of Device Path Node, no child handle is created by this
640 @retval EFI_SUCCESS The device was started.
641 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
642 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
643 @retval Others The driver failded to start the device.
648 Dns4DriverBindingStart (
649 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
650 IN EFI_HANDLE ControllerHandle
,
651 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
657 Status
= DnsCreateService (ControllerHandle
, This
->DriverBindingHandle
, IP_VERSION_4
, &DnsSb
);
658 if (EFI_ERROR (Status
)) {
662 ASSERT (DnsSb
!= NULL
);
664 Status
= gBS
->SetTimer (DnsSb
->Timer
, TimerPeriodic
, TICKS_PER_SECOND
);
665 if (EFI_ERROR (Status
)) {
670 // Install the Dns4ServiceBinding Protocol onto ControllerHandle.
672 Status
= gBS
->InstallMultipleProtocolInterfaces (
674 &gEfiDns4ServiceBindingProtocolGuid
,
675 &DnsSb
->ServiceBinding
,
678 if (EFI_ERROR (Status
)) {
685 DnsDestroyService (DnsSb
);
691 Stops a device controller or a bus controller.
693 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
694 As a result, much of the error checking on the parameters to Stop() has been moved
695 into this common boot service. It is legal to call Stop() from other locations,
696 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
697 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
698 same driver's Start() function.
699 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
700 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
701 Start() function, and the Start() function must have called OpenProtocol() on
702 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
704 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
705 @param[in] ControllerHandle A handle to the device being stopped. The handle must
706 support a bus specific I/O protocol for the driver
707 to use to stop the device.
708 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
709 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
710 if NumberOfChildren is 0.
712 @retval EFI_SUCCESS The device was stopped.
713 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
718 Dns4DriverBindingStop (
719 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
720 IN EFI_HANDLE ControllerHandle
,
721 IN UINTN NumberOfChildren
,
722 IN EFI_HANDLE
*ChildHandleBuffer OPTIONAL
725 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
727 EFI_HANDLE NicHandle
;
730 DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context
;
733 // DNS driver opens UDP child, So, Controller is a UDP
734 // child handle. Locate the Nic handle first. Then get the
735 // DNS private data back.
737 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiUdp4ProtocolGuid
);
739 if (NicHandle
== NULL
) {
743 Status
= gBS
->OpenProtocol (
745 &gEfiDns4ServiceBindingProtocolGuid
,
746 (VOID
**) &ServiceBinding
,
747 This
->DriverBindingHandle
,
749 EFI_OPEN_PROTOCOL_GET_PROTOCOL
751 if (EFI_ERROR (Status
)) {
752 return EFI_DEVICE_ERROR
;
755 DnsSb
= DNS_SERVICE_FROM_THIS (ServiceBinding
);
757 if (!IsListEmpty (&DnsSb
->Dns4ChildrenList
)) {
759 // Destroy the Dns child instance in ChildHandleBuffer.
761 List
= &DnsSb
->Dns4ChildrenList
;
762 Context
.ServiceBinding
= ServiceBinding
;
763 Context
.NumberOfChildren
= NumberOfChildren
;
764 Context
.ChildHandleBuffer
= ChildHandleBuffer
;
765 Status
= NetDestroyLinkList (
767 DnsDestroyChildEntryInHandleBuffer
,
773 if (NumberOfChildren
== 0 && IsListEmpty (&DnsSb
->Dns4ChildrenList
)) {
774 gBS
->UninstallProtocolInterface (
776 &gEfiDns4ServiceBindingProtocolGuid
,
780 DnsDestroyService (DnsSb
);
782 if (gDnsControllerNameTable
!= NULL
) {
783 FreeUnicodeStringTable (gDnsControllerNameTable
);
784 gDnsControllerNameTable
= NULL
;
787 Status
= EFI_SUCCESS
;
794 Tests to see if this driver supports a given controller. If a child device is provided,
795 it further tests to see if this driver supports creating a handle for the specified child device.
797 This function checks to see if the driver specified by This supports the device specified by
798 ControllerHandle. Drivers will typically use the device path attached to
799 ControllerHandle and/or the services from the bus I/O abstraction attached to
800 ControllerHandle to determine if the driver supports ControllerHandle. This function
801 may be called many times during platform initialization. In order to reduce boot times, the tests
802 performed by this function must be very small, and take as little time as possible to execute. This
803 function must not change the state of any hardware devices, and this function must be aware that the
804 device specified by ControllerHandle may already be managed by the same driver or a
805 different driver. This function must match its calls to AllocatePages() with FreePages(),
806 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
807 Because ControllerHandle may have been previously started by the same driver, if a protocol is
808 already in the opened state, then it must not be closed with CloseProtocol(). This is required
809 to guarantee the state of ControllerHandle is not modified by this function.
811 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
812 @param[in] ControllerHandle The handle of the controller to test. This handle
813 must support a protocol interface that supplies
814 an I/O abstraction to the driver.
815 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
816 parameter is ignored by device drivers, and is optional for bus
817 drivers. For bus drivers, if this parameter is not NULL, then
818 the bus driver must determine if the bus controller specified
819 by ControllerHandle and the child controller specified
820 by RemainingDevicePath are both supported by this
823 @retval EFI_SUCCESS The device specified by ControllerHandle and
824 RemainingDevicePath is supported by the driver specified by This.
825 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
826 RemainingDevicePath is already being managed by the driver
828 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
829 RemainingDevicePath is already being managed by a different
830 driver or an application that requires exclusive access.
831 Currently not implemented.
832 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
833 RemainingDevicePath is not supported by the driver specified by This.
837 Dns6DriverBindingSupported (
838 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
839 IN EFI_HANDLE ControllerHandle
,
840 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
846 // Test for the Dns6ServiceBinding Protocol
848 Status
= gBS
->OpenProtocol (
850 &gEfiDns6ServiceBindingProtocolGuid
,
852 This
->DriverBindingHandle
,
854 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
856 if (!EFI_ERROR (Status
)) {
857 return EFI_ALREADY_STARTED
;
861 // Test for the Udp6ServiceBinding Protocol
863 Status
= gBS
->OpenProtocol (
865 &gEfiUdp6ServiceBindingProtocolGuid
,
867 This
->DriverBindingHandle
,
869 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
876 Starts a device controller or a bus controller.
878 The Start() function is designed to be invoked from the EFI boot service ConnectController().
879 As a result, much of the error checking on the parameters to Start() has been moved into this
880 common boot service. It is legal to call Start() from other locations,
881 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
882 1. ControllerHandle must be a valid EFI_HANDLE.
883 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
884 EFI_DEVICE_PATH_PROTOCOL.
885 3. Prior to calling Start(), the Supported() function for the driver specified by This must
886 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
888 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
889 @param[in] ControllerHandle The handle of the controller to start. This handle
890 must support a protocol interface that supplies
891 an I/O abstraction to the driver.
892 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
893 parameter is ignored by device drivers, and is optional for bus
894 drivers. For a bus driver, if this parameter is NULL, then handles
895 for all the children of Controller are created by this driver.
896 If this parameter is not NULL and the first Device Path Node is
897 not the End of Device Path Node, then only the handle for the
898 child device specified by the first Device Path Node of
899 RemainingDevicePath is created by this driver.
900 If the first Device Path Node of RemainingDevicePath is
901 the End of Device Path Node, no child handle is created by this
904 @retval EFI_SUCCESS The device was started.
905 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
906 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
907 @retval Others The driver failded to start the device.
912 Dns6DriverBindingStart (
913 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
914 IN EFI_HANDLE ControllerHandle
,
915 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
921 Status
= DnsCreateService (ControllerHandle
, This
->DriverBindingHandle
, IP_VERSION_6
, &DnsSb
);
922 if (EFI_ERROR (Status
)) {
926 ASSERT (DnsSb
!= NULL
);
928 Status
= gBS
->SetTimer (DnsSb
->Timer
, TimerPeriodic
, TICKS_PER_SECOND
);
929 if (EFI_ERROR (Status
)) {
934 // Install the Dns6ServiceBinding Protocol onto ControllerHandle
936 Status
= gBS
->InstallMultipleProtocolInterfaces (
938 &gEfiDns6ServiceBindingProtocolGuid
,
939 &DnsSb
->ServiceBinding
,
943 if (EFI_ERROR (Status
)) {
950 DnsDestroyService (DnsSb
);
956 Stops a device controller or a bus controller.
958 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
959 As a result, much of the error checking on the parameters to Stop() has been moved
960 into this common boot service. It is legal to call Stop() from other locations,
961 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
962 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
963 same driver's Start() function.
964 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
965 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
966 Start() function, and the Start() function must have called OpenProtocol() on
967 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
969 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
970 @param[in] ControllerHandle A handle to the device being stopped. The handle must
971 support a bus specific I/O protocol for the driver
972 to use to stop the device.
973 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
974 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
975 if NumberOfChildren is 0.
977 @retval EFI_SUCCESS The device was stopped.
978 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
983 Dns6DriverBindingStop (
984 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
985 IN EFI_HANDLE ControllerHandle
,
986 IN UINTN NumberOfChildren
,
987 IN EFI_HANDLE
*ChildHandleBuffer OPTIONAL
990 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
992 EFI_HANDLE NicHandle
;
995 DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context
;
998 // DNS driver opens UDP child, So, Controller is a UDP
999 // child handle. Locate the Nic handle first. Then get the
1000 // DNS private data back.
1002 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiUdp6ProtocolGuid
);
1004 if (NicHandle
== NULL
) {
1008 Status
= gBS
->OpenProtocol (
1010 &gEfiDns6ServiceBindingProtocolGuid
,
1011 (VOID
**) &ServiceBinding
,
1012 This
->DriverBindingHandle
,
1014 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1016 if (EFI_ERROR (Status
)) {
1017 return EFI_DEVICE_ERROR
;
1020 DnsSb
= DNS_SERVICE_FROM_THIS (ServiceBinding
);
1022 if (!IsListEmpty (&DnsSb
->Dns6ChildrenList
)) {
1024 // Destroy the Dns child instance in ChildHandleBuffer.
1026 List
= &DnsSb
->Dns6ChildrenList
;
1027 Context
.ServiceBinding
= ServiceBinding
;
1028 Context
.NumberOfChildren
= NumberOfChildren
;
1029 Context
.ChildHandleBuffer
= ChildHandleBuffer
;
1030 Status
= NetDestroyLinkList (
1032 DnsDestroyChildEntryInHandleBuffer
,
1038 if (NumberOfChildren
== 0 && IsListEmpty (&DnsSb
->Dns6ChildrenList
)) {
1039 gBS
->UninstallProtocolInterface (
1041 &gEfiDns6ServiceBindingProtocolGuid
,
1045 DnsDestroyService (DnsSb
);
1047 if (gDnsControllerNameTable
!= NULL
) {
1048 FreeUnicodeStringTable (gDnsControllerNameTable
);
1049 gDnsControllerNameTable
= NULL
;
1052 Status
= EFI_SUCCESS
;
1059 Creates a child handle and installs a protocol.
1061 The CreateChild() function installs a protocol on ChildHandle.
1062 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
1063 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
1065 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
1066 @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
1067 then a new handle is created. If it is a pointer to an existing UEFI handle,
1068 then the protocol is added to the existing UEFI handle.
1070 @retval EFI_SUCCES The protocol was added to ChildHandle.
1071 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
1072 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
1074 @retval other The child handle was not created
1079 Dns4ServiceBindingCreateChild (
1080 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
1081 IN EFI_HANDLE
*ChildHandle
1085 DNS_INSTANCE
*Instance
;
1090 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
1091 return EFI_INVALID_PARAMETER
;
1094 DnsSb
= DNS_SERVICE_FROM_THIS (This
);
1096 Status
= DnsCreateInstance (DnsSb
, &Instance
);
1097 if (EFI_ERROR (Status
)) {
1100 ASSERT (Instance
!= NULL
);
1103 // Install the DNS protocol onto ChildHandle
1105 Status
= gBS
->InstallMultipleProtocolInterfaces (
1107 &gEfiDns4ProtocolGuid
,
1111 if (EFI_ERROR (Status
)) {
1115 Instance
->ChildHandle
= *ChildHandle
;
1118 // Open the Udp4 protocol BY_CHILD.
1120 Status
= gBS
->OpenProtocol (
1121 DnsSb
->ConnectUdp
->UdpHandle
,
1122 &gEfiUdp4ProtocolGuid
,
1124 gDns4DriverBinding
.DriverBindingHandle
,
1125 Instance
->ChildHandle
,
1126 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1128 if (EFI_ERROR (Status
)) {
1129 gBS
->UninstallMultipleProtocolInterfaces (
1130 Instance
->ChildHandle
,
1131 &gEfiDns4ProtocolGuid
,
1140 // Open the Udp4 protocol by child.
1142 Status
= gBS
->OpenProtocol (
1143 Instance
->UdpIo
->UdpHandle
,
1144 &gEfiUdp4ProtocolGuid
,
1146 gDns4DriverBinding
.DriverBindingHandle
,
1147 Instance
->ChildHandle
,
1148 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1150 if (EFI_ERROR (Status
)) {
1152 // Close the Udp4 protocol.
1154 gBS
->CloseProtocol (
1155 DnsSb
->ConnectUdp
->UdpHandle
,
1156 &gEfiUdp4ProtocolGuid
,
1157 gDns4DriverBinding
.DriverBindingHandle
,
1161 gBS
->UninstallMultipleProtocolInterfaces (
1162 Instance
->ChildHandle
,
1163 &gEfiDns4ProtocolGuid
,
1172 // Add it to the parent's child list.
1174 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1176 InsertTailList (&DnsSb
->Dns4ChildrenList
, &Instance
->Link
);
1177 DnsSb
->Dns4ChildrenNum
++;
1179 gBS
->RestoreTPL (OldTpl
);
1185 DnsDestroyInstance (Instance
);
1190 Destroys a child handle with a protocol installed on it.
1192 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
1193 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
1194 last protocol on ChildHandle, then ChildHandle is destroyed.
1196 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
1197 @param[in] ChildHandle Handle of the child to destroy
1199 @retval EFI_SUCCES The protocol was removed from ChildHandle.
1200 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
1201 @retval EFI_INVALID_PARAMETER Child handle is NULL.
1202 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
1203 because its services are being used.
1204 @retval other The child handle was not destroyed
1209 Dns4ServiceBindingDestroyChild (
1210 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
1211 IN EFI_HANDLE ChildHandle
1215 DNS_INSTANCE
*Instance
;
1217 EFI_DNS4_PROTOCOL
*Dns4
;
1221 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
1222 return EFI_INVALID_PARAMETER
;
1226 // Retrieve the private context data structures
1228 Status
= gBS
->OpenProtocol (
1230 &gEfiDns4ProtocolGuid
,
1232 gDns4DriverBinding
.DriverBindingHandle
,
1234 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1237 if (EFI_ERROR (Status
)) {
1238 return EFI_UNSUPPORTED
;
1241 Instance
= DNS_INSTANCE_FROM_THIS_PROTOCOL4 (Dns4
);
1242 DnsSb
= DNS_SERVICE_FROM_THIS (This
);
1244 if (Instance
->Service
!= DnsSb
) {
1245 return EFI_INVALID_PARAMETER
;
1248 if (Instance
->InDestroy
) {
1252 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1254 Instance
->InDestroy
= TRUE
;
1257 // Close the Udp4 protocol.
1259 gBS
->CloseProtocol (
1260 DnsSb
->ConnectUdp
->UdpHandle
,
1261 &gEfiUdp4ProtocolGuid
,
1262 gDns4DriverBinding
.DriverBindingHandle
,
1266 gBS
->CloseProtocol (
1267 Instance
->UdpIo
->UdpHandle
,
1268 &gEfiUdp4ProtocolGuid
,
1269 gDns4DriverBinding
.DriverBindingHandle
,
1273 gBS
->RestoreTPL (OldTpl
);
1276 // Uninstall the DNS protocol first to enable a top down destruction.
1278 Status
= gBS
->UninstallProtocolInterface (
1280 &gEfiDns4ProtocolGuid
,
1284 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1286 if (EFI_ERROR (Status
)) {
1287 Instance
->InDestroy
= FALSE
;
1288 gBS
->RestoreTPL (OldTpl
);
1292 RemoveEntryList (&Instance
->Link
);
1293 DnsSb
->Dns4ChildrenNum
--;
1295 gBS
->RestoreTPL (OldTpl
);
1297 DnsDestroyInstance (Instance
);
1302 Creates a child handle and installs a protocol.
1304 The CreateChild() function installs a protocol on ChildHandle.
1305 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
1306 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
1308 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
1309 @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
1310 then a new handle is created. If it is a pointer to an existing UEFI handle,
1311 then the protocol is added to the existing UEFI handle.
1313 @retval EFI_SUCCES The protocol was added to ChildHandle.
1314 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
1315 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
1317 @retval other The child handle was not created
1322 Dns6ServiceBindingCreateChild (
1323 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
1324 IN EFI_HANDLE
*ChildHandle
1328 DNS_INSTANCE
*Instance
;
1333 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
1334 return EFI_INVALID_PARAMETER
;
1337 DnsSb
= DNS_SERVICE_FROM_THIS (This
);
1339 Status
= DnsCreateInstance (DnsSb
, &Instance
);
1340 if (EFI_ERROR (Status
)) {
1343 ASSERT (Instance
!= NULL
);
1346 // Install the DNS protocol onto ChildHandle
1348 Status
= gBS
->InstallMultipleProtocolInterfaces (
1350 &gEfiDns6ProtocolGuid
,
1354 if (EFI_ERROR (Status
)) {
1358 Instance
->ChildHandle
= *ChildHandle
;
1361 // Open the Udp6 protocol BY_CHILD.
1363 Status
= gBS
->OpenProtocol (
1364 DnsSb
->ConnectUdp
->UdpHandle
,
1365 &gEfiUdp6ProtocolGuid
,
1367 gDns6DriverBinding
.DriverBindingHandle
,
1368 Instance
->ChildHandle
,
1369 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1371 if (EFI_ERROR (Status
)) {
1372 gBS
->UninstallMultipleProtocolInterfaces (
1373 Instance
->ChildHandle
,
1374 &gEfiDns6ProtocolGuid
,
1383 // Open the Udp6 protocol by child.
1385 Status
= gBS
->OpenProtocol (
1386 Instance
->UdpIo
->UdpHandle
,
1387 &gEfiUdp6ProtocolGuid
,
1389 gDns6DriverBinding
.DriverBindingHandle
,
1390 Instance
->ChildHandle
,
1391 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1393 if (EFI_ERROR (Status
)) {
1395 // Close the Udp6 protocol.
1397 gBS
->CloseProtocol (
1398 DnsSb
->ConnectUdp
->UdpHandle
,
1399 &gEfiUdp6ProtocolGuid
,
1400 gDns6DriverBinding
.DriverBindingHandle
,
1404 gBS
->UninstallMultipleProtocolInterfaces (
1405 Instance
->ChildHandle
,
1406 &gEfiDns6ProtocolGuid
,
1415 // Add it to the parent's child list.
1417 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1419 InsertTailList (&DnsSb
->Dns6ChildrenList
, &Instance
->Link
);
1420 DnsSb
->Dns6ChildrenNum
++;
1422 gBS
->RestoreTPL (OldTpl
);
1428 DnsDestroyInstance (Instance
);
1433 Destroys a child handle with a protocol installed on it.
1435 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
1436 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
1437 last protocol on ChildHandle, then ChildHandle is destroyed.
1439 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
1440 @param[in] ChildHandle Handle of the child to destroy
1442 @retval EFI_SUCCES The protocol was removed from ChildHandle.
1443 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
1444 @retval EFI_INVALID_PARAMETER Child handle is NULL.
1445 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
1446 because its services are being used.
1447 @retval other The child handle was not destroyed
1452 Dns6ServiceBindingDestroyChild (
1453 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
1454 IN EFI_HANDLE ChildHandle
1458 DNS_INSTANCE
*Instance
;
1460 EFI_DNS6_PROTOCOL
*Dns6
;
1464 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
1465 return EFI_INVALID_PARAMETER
;
1469 // Retrieve the private context data structures
1471 Status
= gBS
->OpenProtocol (
1473 &gEfiDns6ProtocolGuid
,
1475 gDns6DriverBinding
.DriverBindingHandle
,
1477 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1480 if (EFI_ERROR (Status
)) {
1481 return EFI_UNSUPPORTED
;
1484 Instance
= DNS_INSTANCE_FROM_THIS_PROTOCOL6 (Dns6
);
1485 DnsSb
= DNS_SERVICE_FROM_THIS (This
);
1487 if (Instance
->Service
!= DnsSb
) {
1488 return EFI_INVALID_PARAMETER
;
1491 if (Instance
->InDestroy
) {
1495 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1497 Instance
->InDestroy
= TRUE
;
1500 // Close the Udp6 protocol.
1502 gBS
->CloseProtocol (
1503 DnsSb
->ConnectUdp
->UdpHandle
,
1504 &gEfiUdp6ProtocolGuid
,
1505 gDns6DriverBinding
.DriverBindingHandle
,
1509 gBS
->CloseProtocol (
1510 Instance
->UdpIo
->UdpHandle
,
1511 &gEfiUdp6ProtocolGuid
,
1512 gDns6DriverBinding
.DriverBindingHandle
,
1516 gBS
->RestoreTPL (OldTpl
);
1519 // Uninstall the DNS protocol first to enable a top down destruction.
1521 Status
= gBS
->UninstallProtocolInterface (
1523 &gEfiDns6ProtocolGuid
,
1527 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1529 if (EFI_ERROR (Status
)) {
1530 Instance
->InDestroy
= FALSE
;
1531 gBS
->RestoreTPL (OldTpl
);
1535 RemoveEntryList (&Instance
->Link
);
1536 DnsSb
->Dns6ChildrenNum
--;
1538 gBS
->RestoreTPL (OldTpl
);
1540 DnsDestroyInstance (Instance
);