2 Driver Binding functions implementation for UEFI HTTP boot.
4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 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.
15 #include "HttpBootDxe.h"
18 /// Driver Binding Protocol instance
20 EFI_DRIVER_BINDING_PROTOCOL gHttpBootIp4DxeDriverBinding
= {
21 HttpBootIp4DxeDriverBindingSupported
,
22 HttpBootIp4DxeDriverBindingStart
,
23 HttpBootIp4DxeDriverBindingStop
,
24 HTTP_BOOT_DXE_VERSION
,
29 EFI_DRIVER_BINDING_PROTOCOL gHttpBootIp6DxeDriverBinding
= {
30 HttpBootIp6DxeDriverBindingSupported
,
31 HttpBootIp6DxeDriverBindingStart
,
32 HttpBootIp6DxeDriverBindingStop
,
33 HTTP_BOOT_DXE_VERSION
,
39 Destroy the HTTP child based on IPv4 stack.
41 @param[in] This Pointer to the EFI_DRIVER_BINDING_PROTOCOL.
42 @param[in] Private Pointer to HTTP_BOOT_PRIVATE_DATA.
46 HttpBootDestroyIp4Children (
47 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
48 IN HTTP_BOOT_PRIVATE_DATA
*Private
51 ASSERT (This
!= NULL
);
52 ASSERT (Private
!= NULL
);
53 ASSERT (Private
->UsingIpv6
== FALSE
);
55 if (Private
->Dhcp4Child
!= NULL
) {
58 &gEfiDhcp4ProtocolGuid
,
59 This
->DriverBindingHandle
,
63 NetLibDestroyServiceChild (
65 This
->DriverBindingHandle
,
66 &gEfiDhcp4ServiceBindingProtocolGuid
,
71 if (Private
->HttpCreated
) {
72 HttpIoDestroyIo (&Private
->HttpIo
);
73 Private
->HttpCreated
= FALSE
;
76 if (Private
->Ip4Nic
!= NULL
) {
81 This
->DriverBindingHandle
,
82 Private
->Ip4Nic
->Controller
85 gBS
->UninstallMultipleProtocolInterfaces (
86 Private
->Ip4Nic
->Controller
,
87 &gEfiLoadFileProtocolGuid
,
88 &Private
->Ip4Nic
->LoadFile
,
89 &gEfiDevicePathProtocolGuid
,
90 Private
->Ip4Nic
->DevicePath
,
93 FreePool (Private
->Ip4Nic
);
94 Private
->Ip4Nic
= NULL
;
100 Destroy the HTTP child based on IPv6 stack.
102 @param[in] This Pointer to the EFI_DRIVER_BINDING_PROTOCOL.
103 @param[in] Private Pointer to HTTP_BOOT_PRIVATE_DATA.
107 HttpBootDestroyIp6Children (
108 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
109 IN HTTP_BOOT_PRIVATE_DATA
*Private
112 ASSERT (This
!= NULL
);
113 ASSERT (Private
!= NULL
);
114 ASSERT (Private
->UsingIpv6
== TRUE
);
116 if (Private
->Ip6Child
!= NULL
) {
119 &gEfiIp6ProtocolGuid
,
120 This
->DriverBindingHandle
,
124 NetLibDestroyServiceChild (
126 This
->DriverBindingHandle
,
127 &gEfiIp6ServiceBindingProtocolGuid
,
132 if (Private
->Dhcp6Child
!= NULL
) {
135 &gEfiDhcp6ProtocolGuid
,
136 This
->DriverBindingHandle
,
140 NetLibDestroyServiceChild (
142 This
->DriverBindingHandle
,
143 &gEfiDhcp6ServiceBindingProtocolGuid
,
148 if (Private
->HttpCreated
) {
149 HttpIoDestroyIo(&Private
->HttpIo
);
150 Private
->HttpCreated
= FALSE
;
153 if (Private
->Ip6Nic
!= NULL
) {
158 This
->DriverBindingHandle
,
159 Private
->Ip6Nic
->Controller
162 gBS
->UninstallMultipleProtocolInterfaces (
163 Private
->Ip6Nic
->Controller
,
164 &gEfiLoadFileProtocolGuid
,
165 &Private
->Ip6Nic
->LoadFile
,
166 &gEfiDevicePathProtocolGuid
,
167 Private
->Ip6Nic
->DevicePath
,
170 FreePool (Private
->Ip6Nic
);
171 Private
->Ip6Nic
= NULL
;
176 Tests to see if this driver supports a given controller. If a child device is provided,
177 it further tests to see if this driver supports creating a handle for the specified child device.
179 This function checks to see if the driver specified by This supports the device specified by
180 ControllerHandle. Drivers will typically use the device path attached to
181 ControllerHandle and/or the services from the bus I/O abstraction attached to
182 ControllerHandle to determine if the driver supports ControllerHandle. This function
183 may be called many times during platform initialization. In order to reduce boot times, the tests
184 performed by this function must be very small, and take as little time as possible to execute. This
185 function must not change the state of any hardware devices, and this function must be aware that the
186 device specified by ControllerHandle may already be managed by the same driver or a
187 different driver. This function must match its calls to AllocatePages() with FreePages(),
188 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
189 Because ControllerHandle may have been previously started by the same driver, if a protocol is
190 already in the opened state, then it must not be closed with CloseProtocol(). This is required
191 to guarantee the state of ControllerHandle is not modified by this function.
193 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
194 @param[in] ControllerHandle The handle of the controller to test. This handle
195 must support a protocol interface that supplies
196 an I/O abstraction to the driver.
197 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
198 parameter is ignored by device drivers, and is optional for bus
199 drivers. For bus drivers, if this parameter is not NULL, then
200 the bus driver must determine if the bus controller specified
201 by ControllerHandle and the child controller specified
202 by RemainingDevicePath are both supported by this
205 @retval EFI_SUCCESS The device specified by ControllerHandle and
206 RemainingDevicePath is supported by the driver specified by This.
207 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
208 RemainingDevicePath is already being managed by the driver
210 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
211 RemainingDevicePath is already being managed by a different
212 driver or an application that requires exclusive access.
213 Currently not implemented.
214 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
215 RemainingDevicePath is not supported by the driver specified by This.
219 HttpBootIp4DxeDriverBindingSupported (
220 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
221 IN EFI_HANDLE ControllerHandle
,
222 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
228 // Try to open the DHCP4, HTTP4 and Device Path protocol.
230 Status
= gBS
->OpenProtocol (
232 &gEfiDhcp4ServiceBindingProtocolGuid
,
234 This
->DriverBindingHandle
,
236 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
238 if (EFI_ERROR (Status
)) {
242 Status
= gBS
->OpenProtocol (
244 &gEfiHttpServiceBindingProtocolGuid
,
246 This
->DriverBindingHandle
,
248 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
250 if (EFI_ERROR (Status
)) {
254 Status
= gBS
->OpenProtocol (
256 &gEfiDevicePathProtocolGuid
,
258 This
->DriverBindingHandle
,
260 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
268 Starts a device controller or a bus controller.
270 The Start() function is designed to be invoked from the EFI boot service ConnectController().
271 As a result, much of the error checking on the parameters to Start() has been moved into this
272 common boot service. It is legal to call Start() from other locations,
273 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
274 1. ControllerHandle must be a valid EFI_HANDLE.
275 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
276 EFI_DEVICE_PATH_PROTOCOL.
277 3. Prior to calling Start(), the Supported() function for the driver specified by This must
278 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
280 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
281 @param[in] ControllerHandle The handle of the controller to start. This handle
282 must support a protocol interface that supplies
283 an I/O abstraction to the driver.
284 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
285 parameter is ignored by device drivers, and is optional for bus
286 drivers. For a bus driver, if this parameter is NULL, then handles
287 for all the children of Controller are created by this driver.
288 If this parameter is not NULL and the first Device Path Node is
289 not the End of Device Path Node, then only the handle for the
290 child device specified by the first Device Path Node of
291 RemainingDevicePath is created by this driver.
292 If the first Device Path Node of RemainingDevicePath is
293 the End of Device Path Node, no child handle is created by this
296 @retval EFI_SUCCESS The device was started.
297 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
298 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
299 @retval Others The driver failded to start the device.
304 HttpBootIp4DxeDriverBindingStart (
305 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
306 IN EFI_HANDLE ControllerHandle
,
307 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
311 HTTP_BOOT_PRIVATE_DATA
*Private
;
313 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
316 Status
= gBS
->OpenProtocol (
320 This
->DriverBindingHandle
,
322 EFI_OPEN_PROTOCOL_GET_PROTOCOL
325 if (!EFI_ERROR (Status
)) {
326 Private
= HTTP_BOOT_PRIVATE_DATA_FROM_ID(Id
);
329 // Initialize the private data structure.
331 Private
= AllocateZeroPool (sizeof (HTTP_BOOT_PRIVATE_DATA
));
332 if (Private
== NULL
) {
333 return EFI_OUT_OF_RESOURCES
;
335 Private
->Signature
= HTTP_BOOT_PRIVATE_DATA_SIGNATURE
;
336 Private
->Controller
= ControllerHandle
;
337 Private
->Image
= This
->ImageHandle
;
338 InitializeListHead (&Private
->CacheList
);
340 // Get the NII interface if it exists, it's not required.
342 Status
= gBS
->OpenProtocol (
344 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
345 (VOID
**) &Private
->Nii
,
346 This
->DriverBindingHandle
,
348 EFI_OPEN_PROTOCOL_GET_PROTOCOL
350 if (EFI_ERROR (Status
)) {
355 // Open Device Path Protocol to prepare for appending IP and URI node.
357 Status
= gBS
->OpenProtocol (
359 &gEfiDevicePathProtocolGuid
,
360 (VOID
**) &Private
->ParentDevicePath
,
361 This
->DriverBindingHandle
,
363 EFI_OPEN_PROTOCOL_GET_PROTOCOL
365 if (EFI_ERROR (Status
)) {
370 // Install a protocol with Caller Id Guid to the NIC, this is just to build the relationship between
371 // NIC handle and the private data.
373 Status
= gBS
->InstallProtocolInterface (
376 EFI_NATIVE_INTERFACE
,
379 if (EFI_ERROR (Status
)) {
385 if (Private
->Ip4Nic
!= NULL
) {
387 // Already created before
392 Private
->Ip4Nic
= AllocateZeroPool (sizeof (HTTP_BOOT_VIRTUAL_NIC
));
393 if (Private
->Ip4Nic
== NULL
) {
394 return EFI_OUT_OF_RESOURCES
;
396 Private
->Ip4Nic
->Private
= Private
;
397 Private
->Ip4Nic
->Signature
= HTTP_BOOT_VIRTUAL_NIC_SIGNATURE
;
400 // Create DHCP4 child instance.
402 Status
= NetLibCreateServiceChild (
404 This
->DriverBindingHandle
,
405 &gEfiDhcp4ServiceBindingProtocolGuid
,
408 if (EFI_ERROR (Status
)) {
412 Status
= gBS
->OpenProtocol (
414 &gEfiDhcp4ProtocolGuid
,
415 (VOID
**) &Private
->Dhcp4
,
416 This
->DriverBindingHandle
,
418 EFI_OPEN_PROTOCOL_BY_DRIVER
420 if (EFI_ERROR (Status
)) {
425 // Get the Ip4Config2 protocol, it's required to configure the default gateway address.
427 Status
= gBS
->OpenProtocol (
429 &gEfiIp4Config2ProtocolGuid
,
430 (VOID
**) &Private
->Ip4Config2
,
431 This
->DriverBindingHandle
,
433 EFI_OPEN_PROTOCOL_GET_PROTOCOL
435 if (EFI_ERROR (Status
)) {
440 // Append IPv4 device path node.
442 Node
= AllocateZeroPool (sizeof (IPv4_DEVICE_PATH
));
444 Status
= EFI_OUT_OF_RESOURCES
;
447 Node
->Ipv4
.Header
.Type
= MESSAGING_DEVICE_PATH
;
448 Node
->Ipv4
.Header
.SubType
= MSG_IPv4_DP
;
449 SetDevicePathNodeLength (Node
, sizeof (IPv4_DEVICE_PATH
));
450 Node
->Ipv4
.StaticIpAddress
= FALSE
;
451 DevicePath
= AppendDevicePathNode (Private
->ParentDevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*) Node
);
453 if (DevicePath
== NULL
) {
454 Status
= EFI_OUT_OF_RESOURCES
;
459 // Append URI device path node.
461 Node
= AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL
));
463 Status
= EFI_OUT_OF_RESOURCES
;
466 Node
->DevPath
.Type
= MESSAGING_DEVICE_PATH
;
467 Node
->DevPath
.SubType
= MSG_URI_DP
;
468 SetDevicePathNodeLength (Node
, sizeof (EFI_DEVICE_PATH_PROTOCOL
));
469 Private
->Ip4Nic
->DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*) Node
);
471 FreePool (DevicePath
);
472 if (Private
->Ip4Nic
->DevicePath
== NULL
) {
473 Status
= EFI_OUT_OF_RESOURCES
;
478 // Create a child handle for the HTTP boot and install DevPath and Load file protocol on it.
480 CopyMem (&Private
->Ip4Nic
->LoadFile
, &gHttpBootDxeLoadFile
, sizeof (EFI_LOAD_FILE_PROTOCOL
));
481 Status
= gBS
->InstallMultipleProtocolInterfaces (
482 &Private
->Ip4Nic
->Controller
,
483 &gEfiLoadFileProtocolGuid
,
484 &Private
->Ip4Nic
->LoadFile
,
485 &gEfiDevicePathProtocolGuid
,
486 Private
->Ip4Nic
->DevicePath
,
489 if (EFI_ERROR (Status
)) {
494 // Open the Caller Id child to setup a parent-child relationship between
495 // real NIC handle and the HTTP boot Ipv4 NIC handle.
497 Status
= gBS
->OpenProtocol (
501 This
->DriverBindingHandle
,
502 Private
->Ip4Nic
->Controller
,
503 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
505 if (EFI_ERROR (Status
)) {
514 HttpBootDestroyIp4Children (This
, Private
);
522 Stops a device controller or a bus controller.
524 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
525 As a result, much of the error checking on the parameters to Stop() has been moved
526 into this common boot service. It is legal to call Stop() from other locations,
527 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
528 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
529 same driver's Start() function.
530 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
531 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
532 Start() function, and the Start() function must have called OpenProtocol() on
533 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
535 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
536 @param[in] ControllerHandle A handle to the device being stopped. The handle must
537 support a bus specific I/O protocol for the driver
538 to use to stop the device.
539 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
540 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
541 if NumberOfChildren is 0.
543 @retval EFI_SUCCESS The device was stopped.
544 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
549 HttpBootIp4DxeDriverBindingStop (
550 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
551 IN EFI_HANDLE ControllerHandle
,
552 IN UINTN NumberOfChildren
,
553 IN EFI_HANDLE
*ChildHandleBuffer OPTIONAL
557 EFI_LOAD_FILE_PROTOCOL
*LoadFile
;
558 HTTP_BOOT_PRIVATE_DATA
*Private
;
559 EFI_HANDLE NicHandle
;
563 // Try to get the Load File Protocol from the controller handle.
565 Status
= gBS
->OpenProtocol (
567 &gEfiLoadFileProtocolGuid
,
569 This
->DriverBindingHandle
,
571 EFI_OPEN_PROTOCOL_GET_PROTOCOL
573 if (EFI_ERROR (Status
)) {
575 // If failed, try to find the NIC handle for this controller.
577 NicHandle
= HttpBootGetNicByIp4Children (ControllerHandle
);
578 if (NicHandle
== NULL
) {
583 // Try to retrieve the private data by the Caller Id Guid.
585 Status
= gBS
->OpenProtocol (
589 This
->DriverBindingHandle
,
591 EFI_OPEN_PROTOCOL_GET_PROTOCOL
593 if (EFI_ERROR (Status
)) {
596 Private
= HTTP_BOOT_PRIVATE_DATA_FROM_ID (Id
);
598 Private
= HTTP_BOOT_PRIVATE_DATA_FROM_LOADFILE (LoadFile
);
599 NicHandle
= Private
->Controller
;
603 // Disable the HTTP boot function.
605 Status
= HttpBootStop (Private
);
606 if (Status
!= EFI_SUCCESS
&& Status
!= EFI_NOT_STARTED
) {
611 // Destory all child instance and uninstall protocol interface.
613 HttpBootDestroyIp4Children (This
, Private
);
615 if (Private
->Ip4Nic
== NULL
&& Private
->Ip6Nic
== NULL
) {
617 // Release the cached data.
619 HttpBootFreeCacheList (Private
);
621 gBS
->UninstallProtocolInterface (
634 Tests to see if this driver supports a given controller. If a child device is provided,
635 it further tests to see if this driver supports creating a handle for the specified child device.
637 This function checks to see if the driver specified by This supports the device specified by
638 ControllerHandle. Drivers will typically use the device path attached to
639 ControllerHandle and/or the services from the bus I/O abstraction attached to
640 ControllerHandle to determine if the driver supports ControllerHandle. This function
641 may be called many times during platform initialization. In order to reduce boot times, the tests
642 performed by this function must be very small, and take as little time as possible to execute. This
643 function must not change the state of any hardware devices, and this function must be aware that the
644 device specified by ControllerHandle may already be managed by the same driver or a
645 different driver. This function must match its calls to AllocatePages() with FreePages(),
646 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
647 Because ControllerHandle may have been previously started by the same driver, if a protocol is
648 already in the opened state, then it must not be closed with CloseProtocol(). This is required
649 to guarantee the state of ControllerHandle is not modified by this function.
651 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
652 @param[in] ControllerHandle The handle of the controller to test. This handle
653 must support a protocol interface that supplies
654 an I/O abstraction to the driver.
655 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
656 parameter is ignored by device drivers, and is optional for bus
657 drivers. For bus drivers, if this parameter is not NULL, then
658 the bus driver must determine if the bus controller specified
659 by ControllerHandle and the child controller specified
660 by RemainingDevicePath are both supported by this
663 @retval EFI_SUCCESS The device specified by ControllerHandle and
664 RemainingDevicePath is supported by the driver specified by This.
665 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
666 RemainingDevicePath is already being managed by the driver
668 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
669 RemainingDevicePath is already being managed by a different
670 driver or an application that requires exclusive access.
671 Currently not implemented.
672 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
673 RemainingDevicePath is not supported by the driver specified by This.
677 HttpBootIp6DxeDriverBindingSupported (
678 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
679 IN EFI_HANDLE ControllerHandle
,
680 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
686 // Try to open the DHCP6, HTTP and Device Path protocol.
688 Status
= gBS
->OpenProtocol (
690 &gEfiDhcp6ServiceBindingProtocolGuid
,
692 This
->DriverBindingHandle
,
694 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
696 if (EFI_ERROR (Status
)) {
700 Status
= gBS
->OpenProtocol (
702 &gEfiHttpServiceBindingProtocolGuid
,
704 This
->DriverBindingHandle
,
706 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
708 if (EFI_ERROR (Status
)) {
712 Status
= gBS
->OpenProtocol (
714 &gEfiDevicePathProtocolGuid
,
716 This
->DriverBindingHandle
,
718 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
726 Starts a device controller or a bus controller.
728 The Start() function is designed to be invoked from the EFI boot service ConnectController().
729 As a result, much of the error checking on the parameters to Start() has been moved into this
730 common boot service. It is legal to call Start() from other locations,
731 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
732 1. ControllerHandle must be a valid EFI_HANDLE.
733 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
734 EFI_DEVICE_PATH_PROTOCOL.
735 3. Prior to calling Start(), the Supported() function for the driver specified by This must
736 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
738 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
739 @param[in] ControllerHandle The handle of the controller to start. This handle
740 must support a protocol interface that supplies
741 an I/O abstraction to the driver.
742 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
743 parameter is ignored by device drivers, and is optional for bus
744 drivers. For a bus driver, if this parameter is NULL, then handles
745 for all the children of Controller are created by this driver.
746 If this parameter is not NULL and the first Device Path Node is
747 not the End of Device Path Node, then only the handle for the
748 child device specified by the first Device Path Node of
749 RemainingDevicePath is created by this driver.
750 If the first Device Path Node of RemainingDevicePath is
751 the End of Device Path Node, no child handle is created by this
754 @retval EFI_SUCCESS The device was started.
755 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
756 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
757 @retval Others The driver failded to start the device.
762 HttpBootIp6DxeDriverBindingStart (
763 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
764 IN EFI_HANDLE ControllerHandle
,
765 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
769 HTTP_BOOT_PRIVATE_DATA
*Private
;
771 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
774 Status
= gBS
->OpenProtocol (
778 This
->DriverBindingHandle
,
780 EFI_OPEN_PROTOCOL_GET_PROTOCOL
783 if (!EFI_ERROR (Status
)) {
784 Private
= HTTP_BOOT_PRIVATE_DATA_FROM_ID(Id
);
787 // Initialize the private data structure.
789 Private
= AllocateZeroPool (sizeof (HTTP_BOOT_PRIVATE_DATA
));
790 if (Private
== NULL
) {
791 return EFI_OUT_OF_RESOURCES
;
793 Private
->Signature
= HTTP_BOOT_PRIVATE_DATA_SIGNATURE
;
794 Private
->Controller
= ControllerHandle
;
795 Private
->Image
= This
->ImageHandle
;
796 InitializeListHead (&Private
->CacheList
);
798 // Get the NII interface if it exists, it's not required.
800 Status
= gBS
->OpenProtocol (
802 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
803 (VOID
**) &Private
->Nii
,
804 This
->DriverBindingHandle
,
806 EFI_OPEN_PROTOCOL_GET_PROTOCOL
808 if (EFI_ERROR (Status
)) {
813 // Open Device Path Protocol to prepare for appending IP and URI node.
815 Status
= gBS
->OpenProtocol (
817 &gEfiDevicePathProtocolGuid
,
818 (VOID
**) &Private
->ParentDevicePath
,
819 This
->DriverBindingHandle
,
821 EFI_OPEN_PROTOCOL_GET_PROTOCOL
823 if (EFI_ERROR (Status
)) {
828 // Install a protocol with Caller Id Guid to the NIC, this is just to build the relationship between
829 // NIC handle and the private data.
831 Status
= gBS
->InstallProtocolInterface (
834 EFI_NATIVE_INTERFACE
,
837 if (EFI_ERROR (Status
)) {
843 if (Private
->Ip6Nic
!= NULL
) {
845 // Already created before
850 Private
->Ip6Nic
= AllocateZeroPool (sizeof (HTTP_BOOT_VIRTUAL_NIC
));
851 if (Private
->Ip6Nic
== NULL
) {
852 return EFI_OUT_OF_RESOURCES
;
854 Private
->Ip6Nic
->Private
= Private
;
855 Private
->Ip6Nic
->Signature
= HTTP_BOOT_VIRTUAL_NIC_SIGNATURE
;
858 // Create Dhcp6 child and open Dhcp6 protocol
859 Status
= NetLibCreateServiceChild (
861 This
->DriverBindingHandle
,
862 &gEfiDhcp6ServiceBindingProtocolGuid
,
865 if (EFI_ERROR (Status
)) {
869 Status
= gBS
->OpenProtocol (
871 &gEfiDhcp6ProtocolGuid
,
872 (VOID
**) &Private
->Dhcp6
,
873 This
->DriverBindingHandle
,
875 EFI_OPEN_PROTOCOL_BY_DRIVER
877 if (EFI_ERROR (Status
)) {
882 // Create Ip6 child and open Ip6 protocol for background ICMP packets.
884 Status
= NetLibCreateServiceChild (
886 This
->DriverBindingHandle
,
887 &gEfiIp6ServiceBindingProtocolGuid
,
890 if (EFI_ERROR (Status
)) {
894 Status
= gBS
->OpenProtocol (
896 &gEfiIp6ProtocolGuid
,
897 (VOID
**) &Private
->Ip6
,
898 This
->DriverBindingHandle
,
900 EFI_OPEN_PROTOCOL_BY_DRIVER
902 if (EFI_ERROR (Status
)) {
907 // Locate Ip6Config protocol, it's required to configure the default gateway address.
909 Status
= gBS
->OpenProtocol (
911 &gEfiIp6ConfigProtocolGuid
,
912 (VOID
**) &Private
->Ip6Config
,
913 This
->DriverBindingHandle
,
915 EFI_OPEN_PROTOCOL_GET_PROTOCOL
917 if (EFI_ERROR (Status
)) {
922 // Append IPv6 device path node.
924 Node
= AllocateZeroPool (sizeof (IPv6_DEVICE_PATH
));
926 Status
= EFI_OUT_OF_RESOURCES
;
929 Node
->Ipv6
.Header
.Type
= MESSAGING_DEVICE_PATH
;
930 Node
->Ipv6
.Header
.SubType
= MSG_IPv6_DP
;
931 Node
->Ipv6
.PrefixLength
= IP6_PREFIX_LENGTH
;
932 SetDevicePathNodeLength (Node
, sizeof (IPv6_DEVICE_PATH
));
933 DevicePath
= AppendDevicePathNode(Private
->ParentDevicePath
, (EFI_DEVICE_PATH
*) Node
);
935 if (DevicePath
== NULL
) {
936 Status
= EFI_OUT_OF_RESOURCES
;
941 // Append URI device path node.
943 Node
= AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL
));
945 Status
= EFI_OUT_OF_RESOURCES
;
948 Node
->DevPath
.Type
= MESSAGING_DEVICE_PATH
;
949 Node
->DevPath
.SubType
= MSG_URI_DP
;
950 SetDevicePathNodeLength (Node
, sizeof (EFI_DEVICE_PATH_PROTOCOL
));
951 Private
->Ip6Nic
->DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*) Node
);
953 FreePool (DevicePath
);
954 if (Private
->Ip6Nic
->DevicePath
== NULL
) {
955 Status
= EFI_OUT_OF_RESOURCES
;
960 // Create a child handle for the HTTP boot and install DevPath and Load file protocol on it.
962 CopyMem (&Private
->Ip6Nic
->LoadFile
, &gHttpBootDxeLoadFile
, sizeof (Private
->LoadFile
));
963 Status
= gBS
->InstallMultipleProtocolInterfaces (
964 &Private
->Ip6Nic
->Controller
,
965 &gEfiLoadFileProtocolGuid
,
966 &Private
->Ip6Nic
->LoadFile
,
967 &gEfiDevicePathProtocolGuid
,
968 Private
->Ip6Nic
->DevicePath
,
971 if (EFI_ERROR (Status
)) {
976 // Open the Caller Id child to setup a parent-child relationship between
977 // real NIC handle and the HTTP boot child handle.
979 Status
= gBS
->OpenProtocol (
983 This
->DriverBindingHandle
,
984 Private
->Ip6Nic
->Controller
,
985 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
987 if (EFI_ERROR (Status
)) {
995 HttpBootDestroyIp6Children(This
, Private
);
1003 Stops a device controller or a bus controller.
1005 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
1006 As a result, much of the error checking on the parameters to Stop() has been moved
1007 into this common boot service. It is legal to call Stop() from other locations,
1008 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
1009 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
1010 same driver's Start() function.
1011 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
1012 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
1013 Start() function, and the Start() function must have called OpenProtocol() on
1014 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
1016 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
1017 @param[in] ControllerHandle A handle to the device being stopped. The handle must
1018 support a bus specific I/O protocol for the driver
1019 to use to stop the device.
1020 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
1021 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
1022 if NumberOfChildren is 0.
1024 @retval EFI_SUCCESS The device was stopped.
1025 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
1030 HttpBootIp6DxeDriverBindingStop (
1031 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1032 IN EFI_HANDLE ControllerHandle
,
1033 IN UINTN NumberOfChildren
,
1034 IN EFI_HANDLE
*ChildHandleBuffer OPTIONAL
1038 EFI_LOAD_FILE_PROTOCOL
*LoadFile
;
1039 HTTP_BOOT_PRIVATE_DATA
*Private
;
1040 EFI_HANDLE NicHandle
;
1044 // Try to get the Load File Protocol from the controller handle.
1046 Status
= gBS
->OpenProtocol (
1048 &gEfiLoadFileProtocolGuid
,
1049 (VOID
**) &LoadFile
,
1050 This
->DriverBindingHandle
,
1052 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1054 if (EFI_ERROR (Status
)) {
1056 // If failed, try to find the NIC handle for this controller.
1058 NicHandle
= HttpBootGetNicByIp6Children (ControllerHandle
);
1059 if (NicHandle
== NULL
) {
1064 // Try to retrieve the private data by the Caller Id Guid.
1066 Status
= gBS
->OpenProtocol (
1070 This
->DriverBindingHandle
,
1072 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1074 if (EFI_ERROR (Status
)) {
1077 Private
= HTTP_BOOT_PRIVATE_DATA_FROM_ID (Id
);
1079 Private
= HTTP_BOOT_PRIVATE_DATA_FROM_LOADFILE (LoadFile
);
1080 NicHandle
= Private
->Controller
;
1084 // Disable the HTTP boot function.
1086 Status
= HttpBootStop (Private
);
1087 if (Status
!= EFI_SUCCESS
&& Status
!= EFI_NOT_STARTED
) {
1092 // Destory all child instance and uninstall protocol interface.
1094 HttpBootDestroyIp6Children (This
, Private
);
1096 if (Private
->Ip4Nic
== NULL
&& Private
->Ip6Nic
== NULL
) {
1098 // Release the cached data.
1100 HttpBootFreeCacheList (Private
);
1102 gBS
->UninstallProtocolInterface (
1114 This is the declaration of an EFI image entry point. This entry point is
1115 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
1116 both device drivers and bus drivers.
1118 @param[in] ImageHandle The firmware allocated handle for the UEFI image.
1119 @param[in] SystemTable A pointer to the EFI System Table.
1121 @retval EFI_SUCCESS The operation completed successfully.
1122 @retval Others An unexpected error occurred.
1127 HttpBootDxeDriverEntryPoint (
1128 IN EFI_HANDLE ImageHandle
,
1129 IN EFI_SYSTEM_TABLE
*SystemTable
1134 // Install UEFI Driver Model protocol(s).
1136 Status
= EfiLibInstallDriverBindingComponentName2 (
1139 &gHttpBootIp4DxeDriverBinding
,
1141 &gHttpBootDxeComponentName
,
1142 &gHttpBootDxeComponentName2
1144 if (EFI_ERROR (Status
)) {
1148 Status
= EfiLibInstallDriverBindingComponentName2 (
1151 &gHttpBootIp6DxeDriverBinding
,
1153 &gHttpBootDxeComponentName
,
1154 &gHttpBootDxeComponentName2
1156 if (EFI_ERROR (Status
)) {
1157 gBS
->UninstallMultipleProtocolInterfaces(
1159 &gEfiDriverBindingProtocolGuid
,
1160 &gHttpBootIp4DxeDriverBinding
,
1161 &gEfiComponentName2ProtocolGuid
,
1162 &gHttpBootDxeComponentName2
,
1163 &gEfiComponentNameProtocolGuid
,
1164 &gHttpBootDxeComponentName
,