2 The driver binding and service binding protocol for DnsDxe driver.
4 Copyright (c) 2015, 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 if (DnsSb
->IpVersion
== IP_VERSION_4
) {
283 Status
= gBS
->CreateEvent (
288 &DnsSb
->TimerToGetMap
290 if (EFI_ERROR (Status
)) {
297 // Create the timer to retransmit packets.
299 Status
= gBS
->CreateEvent (
300 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
302 DnsOnTimerRetransmit
,
306 if (EFI_ERROR (Status
)) {
307 if (DnsSb
->TimerToGetMap
!= NULL
) {
308 gBS
->CloseEvent (DnsSb
->TimerToGetMap
);
314 DnsSb
->ConnectUdp
= NULL
;
315 DnsSb
->ConnectUdp
= UdpIoCreateIo (
322 if (DnsSb
->ConnectUdp
== NULL
) {
323 if (DnsSb
->TimerToGetMap
!= NULL
) {
324 gBS
->CloseEvent (DnsSb
->TimerToGetMap
);
326 gBS
->CloseEvent (DnsSb
->Timer
);
328 return EFI_DEVICE_ERROR
;
338 @param ImageHandle Handle that identifies the image to be unloaded.
340 @retval EFI_SUCCESS The image has been unloaded.
341 @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
347 IN EFI_HANDLE ImageHandle
353 DNS4_CACHE
*ItemCache4
;
354 DNS4_SERVER_IP
*ItemServerIp4
;
355 DNS6_CACHE
*ItemCache6
;
356 DNS6_SERVER_IP
*ItemServerIp6
;
359 ItemServerIp4
= NULL
;
361 ItemServerIp6
= NULL
;
364 // Disconnect the driver specified by ImageHandle
366 Status
= NetLibDefaultUnload(ImageHandle
);
367 if (EFI_ERROR (Status
)) {
374 if (mDriverData
!= NULL
) {
375 if (mDriverData
->Timer
!= NULL
) {
376 gBS
->CloseEvent (mDriverData
->Timer
);
379 while (!IsListEmpty (&mDriverData
->Dns4CacheList
)) {
380 Entry
= NetListRemoveHead (&mDriverData
->Dns4CacheList
);
381 ItemCache4
= NET_LIST_USER_STRUCT (Entry
, DNS4_CACHE
, AllCacheLink
);
382 if (ItemCache4
->DnsCache
.HostName
!= NULL
) {
383 FreePool (ItemCache4
->DnsCache
.HostName
);
385 if (ItemCache4
->DnsCache
.IpAddress
!= NULL
) {
386 FreePool (ItemCache4
->DnsCache
.IpAddress
);
388 FreePool (ItemCache4
);
391 while (!IsListEmpty (&mDriverData
->Dns4ServerList
)) {
392 Entry
= NetListRemoveHead (&mDriverData
->Dns4ServerList
);
393 ItemServerIp4
= NET_LIST_USER_STRUCT (Entry
, DNS4_SERVER_IP
, AllServerLink
);
394 FreePool (ItemServerIp4
);
397 while (!IsListEmpty (&mDriverData
->Dns6CacheList
)) {
398 Entry
= NetListRemoveHead (&mDriverData
->Dns6CacheList
);
399 ItemCache6
= NET_LIST_USER_STRUCT (Entry
, DNS6_CACHE
, AllCacheLink
);
400 if (ItemCache6
->DnsCache
.HostName
!= NULL
) {
401 FreePool (ItemCache6
->DnsCache
.HostName
);
403 if (ItemCache6
->DnsCache
.IpAddress
!= NULL
) {
404 FreePool (ItemCache6
->DnsCache
.IpAddress
);
406 FreePool (ItemCache6
);
409 while (!IsListEmpty (&mDriverData
->Dns6ServerList
)) {
410 Entry
= NetListRemoveHead (&mDriverData
->Dns6ServerList
);
411 ItemServerIp6
= NET_LIST_USER_STRUCT (Entry
, DNS6_SERVER_IP
, AllServerLink
);
412 FreePool (ItemServerIp6
);
415 FreePool (mDriverData
);
422 This is the declaration of an EFI image entry point. This entry point is
423 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
424 both device drivers and bus drivers.
426 @param ImageHandle The firmware allocated handle for the UEFI image.
427 @param SystemTable A pointer to the EFI System Table.
429 @retval EFI_SUCCESS The operation completed successfully.
430 @retval Others An unexpected error occurred.
434 DnsDriverEntryPoint (
435 IN EFI_HANDLE ImageHandle
,
436 IN EFI_SYSTEM_TABLE
*SystemTable
441 Status
= EFI_SUCCESS
;
444 // Install the Dns4 Driver Binding Protocol.
446 Status
= EfiLibInstallDriverBindingComponentName2 (
454 if (EFI_ERROR (Status
)) {
459 // Install the Dns6 Driver Binding Protocol.
461 Status
= EfiLibInstallDriverBindingComponentName2 (
469 if (EFI_ERROR (Status
)) {
474 // Create the driver data structures.
476 mDriverData
= AllocateZeroPool (sizeof (DNS_DRIVER_DATA
));
477 if (mDriverData
== NULL
) {
478 Status
= EFI_OUT_OF_RESOURCES
;
483 // Create the timer event to update DNS cache list.
485 Status
= gBS
->CreateEvent (
486 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
492 if (EFI_ERROR (Status
)) {
496 Status
= gBS
->SetTimer (mDriverData
->Timer
, TimerPeriodic
, TICKS_PER_SECOND
);
497 if (EFI_ERROR (Status
)) {
501 InitializeListHead (&mDriverData
->Dns4CacheList
);
502 InitializeListHead (&mDriverData
->Dns4ServerList
);
503 InitializeListHead (&mDriverData
->Dns6CacheList
);
504 InitializeListHead (&mDriverData
->Dns6ServerList
);
509 gBS
->CloseEvent (mDriverData
->Timer
);
512 FreePool (mDriverData
);
515 gBS
->UninstallMultipleProtocolInterfaces (
516 gDns6DriverBinding
.DriverBindingHandle
,
517 &gEfiDriverBindingProtocolGuid
,
519 &gEfiComponentName2ProtocolGuid
,
521 &gEfiComponentNameProtocolGuid
,
527 gBS
->UninstallMultipleProtocolInterfaces (
529 &gEfiDriverBindingProtocolGuid
,
531 &gEfiComponentName2ProtocolGuid
,
533 &gEfiComponentNameProtocolGuid
,
542 Tests to see if this driver supports a given controller. If a child device is provided,
543 it further tests to see if this driver supports creating a handle for the specified child device.
545 This function checks to see if the driver specified by This supports the device specified by
546 ControllerHandle. Drivers will typically use the device path attached to
547 ControllerHandle and/or the services from the bus I/O abstraction attached to
548 ControllerHandle to determine if the driver supports ControllerHandle. This function
549 may be called many times during platform initialization. In order to reduce boot times, the tests
550 performed by this function must be very small, and take as little time as possible to execute. This
551 function must not change the state of any hardware devices, and this function must be aware that the
552 device specified by ControllerHandle may already be managed by the same driver or a
553 different driver. This function must match its calls to AllocatePages() with FreePages(),
554 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
555 Because ControllerHandle may have been previously started by the same driver, if a protocol is
556 already in the opened state, then it must not be closed with CloseProtocol(). This is required
557 to guarantee the state of ControllerHandle is not modified by this function.
559 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
560 @param[in] ControllerHandle The handle of the controller to test. This handle
561 must support a protocol interface that supplies
562 an I/O abstraction to the driver.
563 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
564 parameter is ignored by device drivers, and is optional for bus
565 drivers. For bus drivers, if this parameter is not NULL, then
566 the bus driver must determine if the bus controller specified
567 by ControllerHandle and the child controller specified
568 by RemainingDevicePath are both supported by this
571 @retval EFI_SUCCESS The device specified by ControllerHandle and
572 RemainingDevicePath is supported by the driver specified by This.
573 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
574 RemainingDevicePath is already being managed by the driver
576 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
577 RemainingDevicePath is already being managed by a different
578 driver or an application that requires exclusive access.
579 Currently not implemented.
580 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
581 RemainingDevicePath is not supported by the driver specified by This.
585 Dns4DriverBindingSupported (
586 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
587 IN EFI_HANDLE ControllerHandle
,
588 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
594 // Test for the Dns4ServiceBinding Protocol.
596 Status
= gBS
->OpenProtocol (
598 &gEfiDns4ServiceBindingProtocolGuid
,
600 This
->DriverBindingHandle
,
602 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
604 if (!EFI_ERROR (Status
)) {
605 return EFI_ALREADY_STARTED
;
609 // Test for the Udp4ServiceBinding Protocol.
611 Status
= gBS
->OpenProtocol (
613 &gEfiUdp4ServiceBindingProtocolGuid
,
615 This
->DriverBindingHandle
,
617 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
624 Starts a device controller or a bus controller.
626 The Start() function is designed to be invoked from the EFI boot service ConnectController().
627 As a result, much of the error checking on the parameters to Start() has been moved into this
628 common boot service. It is legal to call Start() from other locations,
629 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
630 1. ControllerHandle must be a valid EFI_HANDLE.
631 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
632 EFI_DEVICE_PATH_PROTOCOL.
633 3. Prior to calling Start(), the Supported() function for the driver specified by This must
634 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
636 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
637 @param[in] ControllerHandle The handle of the controller to start. This handle
638 must support a protocol interface that supplies
639 an I/O abstraction to the driver.
640 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
641 parameter is ignored by device drivers, and is optional for bus
642 drivers. For a bus driver, if this parameter is NULL, then handles
643 for all the children of Controller are created by this driver.
644 If this parameter is not NULL and the first Device Path Node is
645 not the End of Device Path Node, then only the handle for the
646 child device specified by the first Device Path Node of
647 RemainingDevicePath is created by this driver.
648 If the first Device Path Node of RemainingDevicePath is
649 the End of Device Path Node, no child handle is created by this
652 @retval EFI_SUCCESS The device was started.
653 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
654 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
655 @retval Others The driver failded to start the device.
660 Dns4DriverBindingStart (
661 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
662 IN EFI_HANDLE ControllerHandle
,
663 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
669 Status
= DnsCreateService (ControllerHandle
, This
->DriverBindingHandle
, IP_VERSION_4
, &DnsSb
);
670 if (EFI_ERROR (Status
)) {
674 ASSERT (DnsSb
!= NULL
);
676 Status
= gBS
->SetTimer (DnsSb
->Timer
, TimerPeriodic
, TICKS_PER_SECOND
);
677 if (EFI_ERROR (Status
)) {
682 // Install the Dns4ServiceBinding Protocol onto ControllerHandle.
684 Status
= gBS
->InstallMultipleProtocolInterfaces (
686 &gEfiDns4ServiceBindingProtocolGuid
,
687 &DnsSb
->ServiceBinding
,
690 if (EFI_ERROR (Status
)) {
697 DnsDestroyService (DnsSb
);
703 Stops a device controller or a bus controller.
705 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
706 As a result, much of the error checking on the parameters to Stop() has been moved
707 into this common boot service. It is legal to call Stop() from other locations,
708 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
709 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
710 same driver's Start() function.
711 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
712 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
713 Start() function, and the Start() function must have called OpenProtocol() on
714 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
716 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
717 @param[in] ControllerHandle A handle to the device being stopped. The handle must
718 support a bus specific I/O protocol for the driver
719 to use to stop the device.
720 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
721 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
722 if NumberOfChildren is 0.
724 @retval EFI_SUCCESS The device was stopped.
725 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
730 Dns4DriverBindingStop (
731 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
732 IN EFI_HANDLE ControllerHandle
,
733 IN UINTN NumberOfChildren
,
734 IN EFI_HANDLE
*ChildHandleBuffer OPTIONAL
737 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
739 EFI_HANDLE NicHandle
;
742 DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context
;
745 // DNS driver opens UDP child, So, Controller is a UDP
746 // child handle. Locate the Nic handle first. Then get the
747 // DNS private data back.
749 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiUdp4ProtocolGuid
);
751 if (NicHandle
== NULL
) {
755 Status
= gBS
->OpenProtocol (
757 &gEfiDns4ServiceBindingProtocolGuid
,
758 (VOID
**) &ServiceBinding
,
759 This
->DriverBindingHandle
,
761 EFI_OPEN_PROTOCOL_GET_PROTOCOL
763 if (EFI_ERROR (Status
)) {
764 return EFI_DEVICE_ERROR
;
767 DnsSb
= DNS_SERVICE_FROM_THIS (ServiceBinding
);
769 if (!IsListEmpty (&DnsSb
->Dns4ChildrenList
)) {
771 // Destroy the Dns child instance in ChildHandleBuffer.
773 List
= &DnsSb
->Dns4ChildrenList
;
774 Context
.ServiceBinding
= ServiceBinding
;
775 Context
.NumberOfChildren
= NumberOfChildren
;
776 Context
.ChildHandleBuffer
= ChildHandleBuffer
;
777 Status
= NetDestroyLinkList (
779 DnsDestroyChildEntryInHandleBuffer
,
785 if (NumberOfChildren
== 0 && IsListEmpty (&DnsSb
->Dns4ChildrenList
)) {
786 gBS
->UninstallProtocolInterface (
788 &gEfiDns4ServiceBindingProtocolGuid
,
792 DnsDestroyService (DnsSb
);
794 if (gDnsControllerNameTable
!= NULL
) {
795 FreeUnicodeStringTable (gDnsControllerNameTable
);
796 gDnsControllerNameTable
= NULL
;
799 Status
= EFI_SUCCESS
;
806 Tests to see if this driver supports a given controller. If a child device is provided,
807 it further tests to see if this driver supports creating a handle for the specified child device.
809 This function checks to see if the driver specified by This supports the device specified by
810 ControllerHandle. Drivers will typically use the device path attached to
811 ControllerHandle and/or the services from the bus I/O abstraction attached to
812 ControllerHandle to determine if the driver supports ControllerHandle. This function
813 may be called many times during platform initialization. In order to reduce boot times, the tests
814 performed by this function must be very small, and take as little time as possible to execute. This
815 function must not change the state of any hardware devices, and this function must be aware that the
816 device specified by ControllerHandle may already be managed by the same driver or a
817 different driver. This function must match its calls to AllocatePages() with FreePages(),
818 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
819 Because ControllerHandle may have been previously started by the same driver, if a protocol is
820 already in the opened state, then it must not be closed with CloseProtocol(). This is required
821 to guarantee the state of ControllerHandle is not modified by this function.
823 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
824 @param[in] ControllerHandle The handle of the controller to test. This handle
825 must support a protocol interface that supplies
826 an I/O abstraction to the driver.
827 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
828 parameter is ignored by device drivers, and is optional for bus
829 drivers. For bus drivers, if this parameter is not NULL, then
830 the bus driver must determine if the bus controller specified
831 by ControllerHandle and the child controller specified
832 by RemainingDevicePath are both supported by this
835 @retval EFI_SUCCESS The device specified by ControllerHandle and
836 RemainingDevicePath is supported by the driver specified by This.
837 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
838 RemainingDevicePath is already being managed by the driver
840 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
841 RemainingDevicePath is already being managed by a different
842 driver or an application that requires exclusive access.
843 Currently not implemented.
844 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
845 RemainingDevicePath is not supported by the driver specified by This.
849 Dns6DriverBindingSupported (
850 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
851 IN EFI_HANDLE ControllerHandle
,
852 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
858 // Test for the Dns6ServiceBinding Protocol
860 Status
= gBS
->OpenProtocol (
862 &gEfiDns6ServiceBindingProtocolGuid
,
864 This
->DriverBindingHandle
,
866 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
868 if (!EFI_ERROR (Status
)) {
869 return EFI_ALREADY_STARTED
;
873 // Test for the Udp6ServiceBinding Protocol
875 Status
= gBS
->OpenProtocol (
877 &gEfiUdp6ServiceBindingProtocolGuid
,
879 This
->DriverBindingHandle
,
881 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
888 Starts a device controller or a bus controller.
890 The Start() function is designed to be invoked from the EFI boot service ConnectController().
891 As a result, much of the error checking on the parameters to Start() has been moved into this
892 common boot service. It is legal to call Start() from other locations,
893 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
894 1. ControllerHandle must be a valid EFI_HANDLE.
895 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
896 EFI_DEVICE_PATH_PROTOCOL.
897 3. Prior to calling Start(), the Supported() function for the driver specified by This must
898 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
900 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
901 @param[in] ControllerHandle The handle of the controller to start. This handle
902 must support a protocol interface that supplies
903 an I/O abstraction to the driver.
904 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
905 parameter is ignored by device drivers, and is optional for bus
906 drivers. For a bus driver, if this parameter is NULL, then handles
907 for all the children of Controller are created by this driver.
908 If this parameter is not NULL and the first Device Path Node is
909 not the End of Device Path Node, then only the handle for the
910 child device specified by the first Device Path Node of
911 RemainingDevicePath is created by this driver.
912 If the first Device Path Node of RemainingDevicePath is
913 the End of Device Path Node, no child handle is created by this
916 @retval EFI_SUCCESS The device was started.
917 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
918 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
919 @retval Others The driver failded to start the device.
924 Dns6DriverBindingStart (
925 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
926 IN EFI_HANDLE ControllerHandle
,
927 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
933 Status
= DnsCreateService (ControllerHandle
, This
->DriverBindingHandle
, IP_VERSION_6
, &DnsSb
);
934 if (EFI_ERROR (Status
)) {
938 ASSERT (DnsSb
!= NULL
);
940 Status
= gBS
->SetTimer (DnsSb
->Timer
, TimerPeriodic
, TICKS_PER_SECOND
);
941 if (EFI_ERROR (Status
)) {
946 // Install the Dns6ServiceBinding Protocol onto ControllerHandle
948 Status
= gBS
->InstallMultipleProtocolInterfaces (
950 &gEfiDns6ServiceBindingProtocolGuid
,
951 &DnsSb
->ServiceBinding
,
955 if (EFI_ERROR (Status
)) {
962 DnsDestroyService (DnsSb
);
968 Stops a device controller or a bus controller.
970 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
971 As a result, much of the error checking on the parameters to Stop() has been moved
972 into this common boot service. It is legal to call Stop() from other locations,
973 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
974 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
975 same driver's Start() function.
976 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
977 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
978 Start() function, and the Start() function must have called OpenProtocol() on
979 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
981 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
982 @param[in] ControllerHandle A handle to the device being stopped. The handle must
983 support a bus specific I/O protocol for the driver
984 to use to stop the device.
985 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
986 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
987 if NumberOfChildren is 0.
989 @retval EFI_SUCCESS The device was stopped.
990 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
995 Dns6DriverBindingStop (
996 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
997 IN EFI_HANDLE ControllerHandle
,
998 IN UINTN NumberOfChildren
,
999 IN EFI_HANDLE
*ChildHandleBuffer OPTIONAL
1002 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
1004 EFI_HANDLE NicHandle
;
1007 DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context
;
1010 // DNS driver opens UDP child, So, Controller is a UDP
1011 // child handle. Locate the Nic handle first. Then get the
1012 // DNS private data back.
1014 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiUdp6ProtocolGuid
);
1016 if (NicHandle
== NULL
) {
1020 Status
= gBS
->OpenProtocol (
1022 &gEfiDns6ServiceBindingProtocolGuid
,
1023 (VOID
**) &ServiceBinding
,
1024 This
->DriverBindingHandle
,
1026 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1028 if (EFI_ERROR (Status
)) {
1029 return EFI_DEVICE_ERROR
;
1032 DnsSb
= DNS_SERVICE_FROM_THIS (ServiceBinding
);
1034 if (!IsListEmpty (&DnsSb
->Dns6ChildrenList
)) {
1036 // Destroy the Dns child instance in ChildHandleBuffer.
1038 List
= &DnsSb
->Dns6ChildrenList
;
1039 Context
.ServiceBinding
= ServiceBinding
;
1040 Context
.NumberOfChildren
= NumberOfChildren
;
1041 Context
.ChildHandleBuffer
= ChildHandleBuffer
;
1042 Status
= NetDestroyLinkList (
1044 DnsDestroyChildEntryInHandleBuffer
,
1050 if (NumberOfChildren
== 0 && IsListEmpty (&DnsSb
->Dns6ChildrenList
)) {
1051 gBS
->UninstallProtocolInterface (
1053 &gEfiDns6ServiceBindingProtocolGuid
,
1057 DnsDestroyService (DnsSb
);
1059 if (gDnsControllerNameTable
!= NULL
) {
1060 FreeUnicodeStringTable (gDnsControllerNameTable
);
1061 gDnsControllerNameTable
= NULL
;
1064 Status
= EFI_SUCCESS
;
1071 Creates a child handle and installs a protocol.
1073 The CreateChild() function installs a protocol on ChildHandle.
1074 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
1075 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
1077 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
1078 @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
1079 then a new handle is created. If it is a pointer to an existing UEFI handle,
1080 then the protocol is added to the existing UEFI handle.
1082 @retval EFI_SUCCES The protocol was added to ChildHandle.
1083 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
1084 @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create
1086 @retval other The child handle was not created
1091 Dns4ServiceBindingCreateChild (
1092 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
1093 IN EFI_HANDLE
*ChildHandle
1097 DNS_INSTANCE
*Instance
;
1102 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
1103 return EFI_INVALID_PARAMETER
;
1106 DnsSb
= DNS_SERVICE_FROM_THIS (This
);
1108 Status
= DnsCreateInstance (DnsSb
, &Instance
);
1109 if (EFI_ERROR (Status
)) {
1112 ASSERT (Instance
!= NULL
);
1115 // Install the DNS protocol onto ChildHandle
1117 Status
= gBS
->InstallMultipleProtocolInterfaces (
1119 &gEfiDns4ProtocolGuid
,
1123 if (EFI_ERROR (Status
)) {
1127 Instance
->ChildHandle
= *ChildHandle
;
1130 // Open the Udp4 protocol BY_CHILD.
1132 Status
= gBS
->OpenProtocol (
1133 DnsSb
->ConnectUdp
->UdpHandle
,
1134 &gEfiUdp4ProtocolGuid
,
1136 gDns4DriverBinding
.DriverBindingHandle
,
1137 Instance
->ChildHandle
,
1138 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1140 if (EFI_ERROR (Status
)) {
1141 gBS
->UninstallMultipleProtocolInterfaces (
1142 Instance
->ChildHandle
,
1143 &gEfiDns4ProtocolGuid
,
1152 // Open the Udp4 protocol by child.
1154 Status
= gBS
->OpenProtocol (
1155 Instance
->UdpIo
->UdpHandle
,
1156 &gEfiUdp4ProtocolGuid
,
1158 gDns4DriverBinding
.DriverBindingHandle
,
1159 Instance
->ChildHandle
,
1160 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1162 if (EFI_ERROR (Status
)) {
1164 // Close the Udp4 protocol.
1166 gBS
->CloseProtocol (
1167 DnsSb
->ConnectUdp
->UdpHandle
,
1168 &gEfiUdp4ProtocolGuid
,
1169 gDns4DriverBinding
.DriverBindingHandle
,
1173 gBS
->UninstallMultipleProtocolInterfaces (
1174 Instance
->ChildHandle
,
1175 &gEfiDns4ProtocolGuid
,
1184 // Add it to the parent's child list.
1186 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1188 InsertTailList (&DnsSb
->Dns4ChildrenList
, &Instance
->Link
);
1189 DnsSb
->Dns4ChildrenNum
++;
1191 gBS
->RestoreTPL (OldTpl
);
1197 DnsDestroyInstance (Instance
);
1202 Destroys a child handle with a protocol installed on it.
1204 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
1205 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
1206 last protocol on ChildHandle, then ChildHandle is destroyed.
1208 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
1209 @param[in] ChildHandle Handle of the child to destroy
1211 @retval EFI_SUCCES The protocol was removed from ChildHandle.
1212 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
1213 @retval EFI_INVALID_PARAMETER Child handle is NULL.
1214 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
1215 because its services are being used.
1216 @retval other The child handle was not destroyed
1221 Dns4ServiceBindingDestroyChild (
1222 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
1223 IN EFI_HANDLE ChildHandle
1227 DNS_INSTANCE
*Instance
;
1229 EFI_DNS4_PROTOCOL
*Dns4
;
1233 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
1234 return EFI_INVALID_PARAMETER
;
1238 // Retrieve the private context data structures
1240 Status
= gBS
->OpenProtocol (
1242 &gEfiDns4ProtocolGuid
,
1244 gDns4DriverBinding
.DriverBindingHandle
,
1246 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1249 if (EFI_ERROR (Status
)) {
1250 return EFI_UNSUPPORTED
;
1253 Instance
= DNS_INSTANCE_FROM_THIS_PROTOCOL4 (Dns4
);
1254 DnsSb
= DNS_SERVICE_FROM_THIS (This
);
1256 if (Instance
->Service
!= DnsSb
) {
1257 return EFI_INVALID_PARAMETER
;
1260 if (Instance
->InDestroy
) {
1264 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1266 Instance
->InDestroy
= TRUE
;
1269 // Close the Udp4 protocol.
1271 gBS
->CloseProtocol (
1272 DnsSb
->ConnectUdp
->UdpHandle
,
1273 &gEfiUdp4ProtocolGuid
,
1274 gDns4DriverBinding
.DriverBindingHandle
,
1278 gBS
->CloseProtocol (
1279 Instance
->UdpIo
->UdpHandle
,
1280 &gEfiUdp4ProtocolGuid
,
1281 gDns4DriverBinding
.DriverBindingHandle
,
1285 gBS
->RestoreTPL (OldTpl
);
1288 // Uninstall the DNS protocol first to enable a top down destruction.
1290 Status
= gBS
->UninstallProtocolInterface (
1292 &gEfiDns4ProtocolGuid
,
1296 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1298 if (EFI_ERROR (Status
)) {
1299 Instance
->InDestroy
= FALSE
;
1300 gBS
->RestoreTPL (OldTpl
);
1304 RemoveEntryList (&Instance
->Link
);
1305 DnsSb
->Dns4ChildrenNum
--;
1307 gBS
->RestoreTPL (OldTpl
);
1309 DnsDestroyInstance (Instance
);
1314 Creates a child handle and installs a protocol.
1316 The CreateChild() function installs a protocol on ChildHandle.
1317 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
1318 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
1320 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
1321 @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
1322 then a new handle is created. If it is a pointer to an existing UEFI handle,
1323 then the protocol is added to the existing UEFI handle.
1325 @retval EFI_SUCCES The protocol was added to ChildHandle.
1326 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
1327 @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create
1329 @retval other The child handle was not created
1334 Dns6ServiceBindingCreateChild (
1335 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
1336 IN EFI_HANDLE
*ChildHandle
1340 DNS_INSTANCE
*Instance
;
1345 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
1346 return EFI_INVALID_PARAMETER
;
1349 DnsSb
= DNS_SERVICE_FROM_THIS (This
);
1351 Status
= DnsCreateInstance (DnsSb
, &Instance
);
1352 if (EFI_ERROR (Status
)) {
1355 ASSERT (Instance
!= NULL
);
1358 // Install the DNS protocol onto ChildHandle
1360 Status
= gBS
->InstallMultipleProtocolInterfaces (
1362 &gEfiDns6ProtocolGuid
,
1366 if (EFI_ERROR (Status
)) {
1370 Instance
->ChildHandle
= *ChildHandle
;
1373 // Open the Udp6 protocol BY_CHILD.
1375 Status
= gBS
->OpenProtocol (
1376 DnsSb
->ConnectUdp
->UdpHandle
,
1377 &gEfiUdp6ProtocolGuid
,
1379 gDns6DriverBinding
.DriverBindingHandle
,
1380 Instance
->ChildHandle
,
1381 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1383 if (EFI_ERROR (Status
)) {
1384 gBS
->UninstallMultipleProtocolInterfaces (
1385 Instance
->ChildHandle
,
1386 &gEfiDns6ProtocolGuid
,
1395 // Open the Udp6 protocol by child.
1397 Status
= gBS
->OpenProtocol (
1398 Instance
->UdpIo
->UdpHandle
,
1399 &gEfiUdp6ProtocolGuid
,
1401 gDns6DriverBinding
.DriverBindingHandle
,
1402 Instance
->ChildHandle
,
1403 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1405 if (EFI_ERROR (Status
)) {
1407 // Close the Udp6 protocol.
1409 gBS
->CloseProtocol (
1410 DnsSb
->ConnectUdp
->UdpHandle
,
1411 &gEfiUdp6ProtocolGuid
,
1412 gDns6DriverBinding
.DriverBindingHandle
,
1416 gBS
->UninstallMultipleProtocolInterfaces (
1417 Instance
->ChildHandle
,
1418 &gEfiDns6ProtocolGuid
,
1427 // Add it to the parent's child list.
1429 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1431 InsertTailList (&DnsSb
->Dns6ChildrenList
, &Instance
->Link
);
1432 DnsSb
->Dns6ChildrenNum
++;
1434 gBS
->RestoreTPL (OldTpl
);
1440 DnsDestroyInstance (Instance
);
1445 Destroys a child handle with a protocol installed on it.
1447 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
1448 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
1449 last protocol on ChildHandle, then ChildHandle is destroyed.
1451 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
1452 @param[in] ChildHandle Handle of the child to destroy
1454 @retval EFI_SUCCES The protocol was removed from ChildHandle.
1455 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
1456 @retval EFI_INVALID_PARAMETER Child handle is NULL.
1457 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
1458 because its services are being used.
1459 @retval other The child handle was not destroyed
1464 Dns6ServiceBindingDestroyChild (
1465 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
1466 IN EFI_HANDLE ChildHandle
1470 DNS_INSTANCE
*Instance
;
1472 EFI_DNS6_PROTOCOL
*Dns6
;
1476 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
1477 return EFI_INVALID_PARAMETER
;
1481 // Retrieve the private context data structures
1483 Status
= gBS
->OpenProtocol (
1485 &gEfiDns6ProtocolGuid
,
1487 gDns6DriverBinding
.DriverBindingHandle
,
1489 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1492 if (EFI_ERROR (Status
)) {
1493 return EFI_UNSUPPORTED
;
1496 Instance
= DNS_INSTANCE_FROM_THIS_PROTOCOL6 (Dns6
);
1497 DnsSb
= DNS_SERVICE_FROM_THIS (This
);
1499 if (Instance
->Service
!= DnsSb
) {
1500 return EFI_INVALID_PARAMETER
;
1503 if (Instance
->InDestroy
) {
1507 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1509 Instance
->InDestroy
= TRUE
;
1512 // Close the Udp6 protocol.
1514 gBS
->CloseProtocol (
1515 DnsSb
->ConnectUdp
->UdpHandle
,
1516 &gEfiUdp6ProtocolGuid
,
1517 gDns6DriverBinding
.DriverBindingHandle
,
1521 gBS
->CloseProtocol (
1522 Instance
->UdpIo
->UdpHandle
,
1523 &gEfiUdp6ProtocolGuid
,
1524 gDns6DriverBinding
.DriverBindingHandle
,
1528 gBS
->RestoreTPL (OldTpl
);
1531 // Uninstall the DNS protocol first to enable a top down destruction.
1533 Status
= gBS
->UninstallProtocolInterface (
1535 &gEfiDns6ProtocolGuid
,
1539 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1541 if (EFI_ERROR (Status
)) {
1542 Instance
->InDestroy
= FALSE
;
1543 gBS
->RestoreTPL (OldTpl
);
1547 RemoveEntryList (&Instance
->Link
);
1548 DnsSb
->Dns6ChildrenNum
--;
1550 gBS
->RestoreTPL (OldTpl
);
1552 DnsDestroyInstance (Instance
);