2 Driver Binding functions implementation for UEFI HTTP boot.
4 Copyright (c) 2015 - 2016, 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
);
54 if (Private
->Dhcp4Child
!= NULL
) {
57 &gEfiDhcp4ProtocolGuid
,
58 This
->DriverBindingHandle
,
62 NetLibDestroyServiceChild (
64 This
->DriverBindingHandle
,
65 &gEfiDhcp4ServiceBindingProtocolGuid
,
70 if (Private
->HttpCreated
) {
71 HttpIoDestroyIo (&Private
->HttpIo
);
72 Private
->HttpCreated
= FALSE
;
75 if (Private
->Ip4Nic
!= NULL
) {
80 This
->DriverBindingHandle
,
81 Private
->Ip4Nic
->Controller
84 gBS
->UninstallMultipleProtocolInterfaces (
85 Private
->Ip4Nic
->Controller
,
86 &gEfiLoadFileProtocolGuid
,
87 &Private
->Ip4Nic
->LoadFile
,
88 &gEfiDevicePathProtocolGuid
,
89 Private
->Ip4Nic
->DevicePath
,
92 FreePool (Private
->Ip4Nic
);
93 Private
->Ip4Nic
= NULL
;
99 Destroy the HTTP child based on IPv6 stack.
101 @param[in] This Pointer to the EFI_DRIVER_BINDING_PROTOCOL.
102 @param[in] Private Pointer to HTTP_BOOT_PRIVATE_DATA.
106 HttpBootDestroyIp6Children (
107 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
108 IN HTTP_BOOT_PRIVATE_DATA
*Private
111 ASSERT (This
!= NULL
);
112 ASSERT (Private
!= NULL
);
114 if (Private
->Ip6Child
!= NULL
) {
117 &gEfiIp6ProtocolGuid
,
118 This
->DriverBindingHandle
,
122 NetLibDestroyServiceChild (
124 This
->DriverBindingHandle
,
125 &gEfiIp6ServiceBindingProtocolGuid
,
130 if (Private
->Dhcp6Child
!= NULL
) {
133 &gEfiDhcp6ProtocolGuid
,
134 This
->DriverBindingHandle
,
138 NetLibDestroyServiceChild (
140 This
->DriverBindingHandle
,
141 &gEfiDhcp6ServiceBindingProtocolGuid
,
146 if (Private
->HttpCreated
) {
147 HttpIoDestroyIo(&Private
->HttpIo
);
148 Private
->HttpCreated
= FALSE
;
151 if (Private
->Ip6Nic
!= NULL
) {
156 This
->DriverBindingHandle
,
157 Private
->Ip6Nic
->Controller
160 gBS
->UninstallMultipleProtocolInterfaces (
161 Private
->Ip6Nic
->Controller
,
162 &gEfiLoadFileProtocolGuid
,
163 &Private
->Ip6Nic
->LoadFile
,
164 &gEfiDevicePathProtocolGuid
,
165 Private
->Ip6Nic
->DevicePath
,
168 FreePool (Private
->Ip6Nic
);
169 Private
->Ip6Nic
= NULL
;
174 Tests to see if this driver supports a given controller. If a child device is provided,
175 it further tests to see if this driver supports creating a handle for the specified child device.
177 This function checks to see if the driver specified by This supports the device specified by
178 ControllerHandle. Drivers will typically use the device path attached to
179 ControllerHandle and/or the services from the bus I/O abstraction attached to
180 ControllerHandle to determine if the driver supports ControllerHandle. This function
181 may be called many times during platform initialization. In order to reduce boot times, the tests
182 performed by this function must be very small, and take as little time as possible to execute. This
183 function must not change the state of any hardware devices, and this function must be aware that the
184 device specified by ControllerHandle may already be managed by the same driver or a
185 different driver. This function must match its calls to AllocatePages() with FreePages(),
186 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
187 Because ControllerHandle may have been previously started by the same driver, if a protocol is
188 already in the opened state, then it must not be closed with CloseProtocol(). This is required
189 to guarantee the state of ControllerHandle is not modified by this function.
191 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
192 @param[in] ControllerHandle The handle of the controller to test. This handle
193 must support a protocol interface that supplies
194 an I/O abstraction to the driver.
195 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
196 parameter is ignored by device drivers, and is optional for bus
197 drivers. For bus drivers, if this parameter is not NULL, then
198 the bus driver must determine if the bus controller specified
199 by ControllerHandle and the child controller specified
200 by RemainingDevicePath are both supported by this
203 @retval EFI_SUCCESS The device specified by ControllerHandle and
204 RemainingDevicePath is supported by the driver specified by This.
205 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
206 RemainingDevicePath is already being managed by the driver
208 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
209 RemainingDevicePath is already being managed by a different
210 driver or an application that requires exclusive access.
211 Currently not implemented.
212 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
213 RemainingDevicePath is not supported by the driver specified by This.
217 HttpBootIp4DxeDriverBindingSupported (
218 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
219 IN EFI_HANDLE ControllerHandle
,
220 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
226 // Try to open the DHCP4, HTTP4 and Device Path protocol.
228 Status
= gBS
->OpenProtocol (
230 &gEfiDhcp4ServiceBindingProtocolGuid
,
232 This
->DriverBindingHandle
,
234 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
236 if (EFI_ERROR (Status
)) {
240 Status
= gBS
->OpenProtocol (
242 &gEfiHttpServiceBindingProtocolGuid
,
244 This
->DriverBindingHandle
,
246 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
248 if (EFI_ERROR (Status
)) {
252 Status
= gBS
->OpenProtocol (
254 &gEfiDevicePathProtocolGuid
,
256 This
->DriverBindingHandle
,
258 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
266 Starts a device controller or a bus controller.
268 The Start() function is designed to be invoked from the EFI boot service ConnectController().
269 As a result, much of the error checking on the parameters to Start() has been moved into this
270 common boot service. It is legal to call Start() from other locations,
271 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
272 1. ControllerHandle must be a valid EFI_HANDLE.
273 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
274 EFI_DEVICE_PATH_PROTOCOL.
275 3. Prior to calling Start(), the Supported() function for the driver specified by This must
276 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
278 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
279 @param[in] ControllerHandle The handle of the controller to start. This handle
280 must support a protocol interface that supplies
281 an I/O abstraction to the driver.
282 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
283 parameter is ignored by device drivers, and is optional for bus
284 drivers. For a bus driver, if this parameter is NULL, then handles
285 for all the children of Controller are created by this driver.
286 If this parameter is not NULL and the first Device Path Node is
287 not the End of Device Path Node, then only the handle for the
288 child device specified by the first Device Path Node of
289 RemainingDevicePath is created by this driver.
290 If the first Device Path Node of RemainingDevicePath is
291 the End of Device Path Node, no child handle is created by this
294 @retval EFI_SUCCESS The device was started.
295 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
296 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
297 @retval Others The driver failded to start the device.
302 HttpBootIp4DxeDriverBindingStart (
303 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
304 IN EFI_HANDLE ControllerHandle
,
305 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
309 HTTP_BOOT_PRIVATE_DATA
*Private
;
311 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
314 Status
= gBS
->OpenProtocol (
318 This
->DriverBindingHandle
,
320 EFI_OPEN_PROTOCOL_GET_PROTOCOL
323 if (!EFI_ERROR (Status
)) {
324 Private
= HTTP_BOOT_PRIVATE_DATA_FROM_ID(Id
);
327 // Initialize the private data structure.
329 Private
= AllocateZeroPool (sizeof (HTTP_BOOT_PRIVATE_DATA
));
330 if (Private
== NULL
) {
331 return EFI_OUT_OF_RESOURCES
;
333 Private
->Signature
= HTTP_BOOT_PRIVATE_DATA_SIGNATURE
;
334 Private
->Controller
= ControllerHandle
;
335 InitializeListHead (&Private
->CacheList
);
337 // Get the NII interface if it exists, it's not required.
339 Status
= gBS
->OpenProtocol (
341 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
342 (VOID
**) &Private
->Nii
,
343 This
->DriverBindingHandle
,
345 EFI_OPEN_PROTOCOL_GET_PROTOCOL
347 if (EFI_ERROR (Status
)) {
352 // Open Device Path Protocol to prepare for appending IP and URI node.
354 Status
= gBS
->OpenProtocol (
356 &gEfiDevicePathProtocolGuid
,
357 (VOID
**) &Private
->ParentDevicePath
,
358 This
->DriverBindingHandle
,
360 EFI_OPEN_PROTOCOL_GET_PROTOCOL
362 if (EFI_ERROR (Status
)) {
367 // Initialize the HII configuration form.
369 Status
= HttpBootConfigFormInit (Private
);
370 if (EFI_ERROR (Status
)) {
375 // Install a protocol with Caller Id Guid to the NIC, this is just to build the relationship between
376 // NIC handle and the private data.
378 Status
= gBS
->InstallProtocolInterface (
381 EFI_NATIVE_INTERFACE
,
384 if (EFI_ERROR (Status
)) {
390 if (Private
->Ip4Nic
!= NULL
) {
392 // Already created before
397 Private
->Ip4Nic
= AllocateZeroPool (sizeof (HTTP_BOOT_VIRTUAL_NIC
));
398 if (Private
->Ip4Nic
== NULL
) {
399 return EFI_OUT_OF_RESOURCES
;
401 Private
->Ip4Nic
->Private
= Private
;
402 Private
->Ip4Nic
->ImageHandle
= This
->DriverBindingHandle
;
403 Private
->Ip4Nic
->Signature
= HTTP_BOOT_VIRTUAL_NIC_SIGNATURE
;
406 // Create DHCP4 child instance.
408 Status
= NetLibCreateServiceChild (
410 This
->DriverBindingHandle
,
411 &gEfiDhcp4ServiceBindingProtocolGuid
,
414 if (EFI_ERROR (Status
)) {
418 Status
= gBS
->OpenProtocol (
420 &gEfiDhcp4ProtocolGuid
,
421 (VOID
**) &Private
->Dhcp4
,
422 This
->DriverBindingHandle
,
424 EFI_OPEN_PROTOCOL_BY_DRIVER
426 if (EFI_ERROR (Status
)) {
431 // Get the Ip4Config2 protocol, it's required to configure the default gateway address.
433 Status
= gBS
->OpenProtocol (
435 &gEfiIp4Config2ProtocolGuid
,
436 (VOID
**) &Private
->Ip4Config2
,
437 This
->DriverBindingHandle
,
439 EFI_OPEN_PROTOCOL_GET_PROTOCOL
441 if (EFI_ERROR (Status
)) {
446 // Append IPv4 device path node.
448 Node
= AllocateZeroPool (sizeof (IPv4_DEVICE_PATH
));
450 Status
= EFI_OUT_OF_RESOURCES
;
453 Node
->Ipv4
.Header
.Type
= MESSAGING_DEVICE_PATH
;
454 Node
->Ipv4
.Header
.SubType
= MSG_IPv4_DP
;
455 SetDevicePathNodeLength (Node
, sizeof (IPv4_DEVICE_PATH
));
456 Node
->Ipv4
.StaticIpAddress
= FALSE
;
457 DevicePath
= AppendDevicePathNode (Private
->ParentDevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*) Node
);
459 if (DevicePath
== NULL
) {
460 Status
= EFI_OUT_OF_RESOURCES
;
465 // Append URI device path node.
467 Node
= AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL
));
469 Status
= EFI_OUT_OF_RESOURCES
;
472 Node
->DevPath
.Type
= MESSAGING_DEVICE_PATH
;
473 Node
->DevPath
.SubType
= MSG_URI_DP
;
474 SetDevicePathNodeLength (Node
, sizeof (EFI_DEVICE_PATH_PROTOCOL
));
475 Private
->Ip4Nic
->DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*) Node
);
477 FreePool (DevicePath
);
478 if (Private
->Ip4Nic
->DevicePath
== NULL
) {
479 Status
= EFI_OUT_OF_RESOURCES
;
484 // Create a child handle for the HTTP boot and install DevPath and Load file protocol on it.
486 CopyMem (&Private
->Ip4Nic
->LoadFile
, &gHttpBootDxeLoadFile
, sizeof (EFI_LOAD_FILE_PROTOCOL
));
487 Status
= gBS
->InstallMultipleProtocolInterfaces (
488 &Private
->Ip4Nic
->Controller
,
489 &gEfiLoadFileProtocolGuid
,
490 &Private
->Ip4Nic
->LoadFile
,
491 &gEfiDevicePathProtocolGuid
,
492 Private
->Ip4Nic
->DevicePath
,
495 if (EFI_ERROR (Status
)) {
500 // Open the Caller Id child to setup a parent-child relationship between
501 // real NIC handle and the HTTP boot Ipv4 NIC handle.
503 Status
= gBS
->OpenProtocol (
507 This
->DriverBindingHandle
,
508 Private
->Ip4Nic
->Controller
,
509 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
511 if (EFI_ERROR (Status
)) {
520 HttpBootDestroyIp4Children (This
, Private
);
521 HttpBootConfigFormUnload (Private
);
529 Stops a device controller or a bus controller.
531 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
532 As a result, much of the error checking on the parameters to Stop() has been moved
533 into this common boot service. It is legal to call Stop() from other locations,
534 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
535 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
536 same driver's Start() function.
537 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
538 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
539 Start() function, and the Start() function must have called OpenProtocol() on
540 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
542 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
543 @param[in] ControllerHandle A handle to the device being stopped. The handle must
544 support a bus specific I/O protocol for the driver
545 to use to stop the device.
546 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
547 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
548 if NumberOfChildren is 0.
550 @retval EFI_SUCCESS The device was stopped.
551 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
556 HttpBootIp4DxeDriverBindingStop (
557 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
558 IN EFI_HANDLE ControllerHandle
,
559 IN UINTN NumberOfChildren
,
560 IN EFI_HANDLE
*ChildHandleBuffer OPTIONAL
564 EFI_LOAD_FILE_PROTOCOL
*LoadFile
;
565 HTTP_BOOT_PRIVATE_DATA
*Private
;
566 EFI_HANDLE NicHandle
;
570 // Try to get the Load File Protocol from the controller handle.
572 Status
= gBS
->OpenProtocol (
574 &gEfiLoadFileProtocolGuid
,
576 This
->DriverBindingHandle
,
578 EFI_OPEN_PROTOCOL_GET_PROTOCOL
580 if (EFI_ERROR (Status
)) {
582 // If failed, try to find the NIC handle for this controller.
584 NicHandle
= HttpBootGetNicByIp4Children (ControllerHandle
);
585 if (NicHandle
== NULL
) {
590 // Try to retrieve the private data by the Caller Id Guid.
592 Status
= gBS
->OpenProtocol (
596 This
->DriverBindingHandle
,
598 EFI_OPEN_PROTOCOL_GET_PROTOCOL
600 if (EFI_ERROR (Status
)) {
603 Private
= HTTP_BOOT_PRIVATE_DATA_FROM_ID (Id
);
605 Private
= HTTP_BOOT_PRIVATE_DATA_FROM_LOADFILE (LoadFile
);
606 NicHandle
= Private
->Controller
;
610 // Disable the HTTP boot function.
612 Status
= HttpBootStop (Private
);
613 if (Status
!= EFI_SUCCESS
&& Status
!= EFI_NOT_STARTED
) {
618 // Destory all child instance and uninstall protocol interface.
620 HttpBootDestroyIp4Children (This
, Private
);
622 if (Private
->Ip4Nic
== NULL
&& Private
->Ip6Nic
== NULL
) {
624 // Release the cached data.
626 HttpBootFreeCacheList (Private
);
629 // Unload the config form.
631 HttpBootConfigFormUnload (Private
);
633 gBS
->UninstallProtocolInterface (
646 Tests to see if this driver supports a given controller. If a child device is provided,
647 it further tests to see if this driver supports creating a handle for the specified child device.
649 This function checks to see if the driver specified by This supports the device specified by
650 ControllerHandle. Drivers will typically use the device path attached to
651 ControllerHandle and/or the services from the bus I/O abstraction attached to
652 ControllerHandle to determine if the driver supports ControllerHandle. This function
653 may be called many times during platform initialization. In order to reduce boot times, the tests
654 performed by this function must be very small, and take as little time as possible to execute. This
655 function must not change the state of any hardware devices, and this function must be aware that the
656 device specified by ControllerHandle may already be managed by the same driver or a
657 different driver. This function must match its calls to AllocatePages() with FreePages(),
658 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
659 Because ControllerHandle may have been previously started by the same driver, if a protocol is
660 already in the opened state, then it must not be closed with CloseProtocol(). This is required
661 to guarantee the state of ControllerHandle is not modified by this function.
663 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
664 @param[in] ControllerHandle The handle of the controller to test. This handle
665 must support a protocol interface that supplies
666 an I/O abstraction to the driver.
667 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
668 parameter is ignored by device drivers, and is optional for bus
669 drivers. For bus drivers, if this parameter is not NULL, then
670 the bus driver must determine if the bus controller specified
671 by ControllerHandle and the child controller specified
672 by RemainingDevicePath are both supported by this
675 @retval EFI_SUCCESS The device specified by ControllerHandle and
676 RemainingDevicePath is supported by the driver specified by This.
677 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
678 RemainingDevicePath is already being managed by the driver
680 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
681 RemainingDevicePath is already being managed by a different
682 driver or an application that requires exclusive access.
683 Currently not implemented.
684 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
685 RemainingDevicePath is not supported by the driver specified by This.
689 HttpBootIp6DxeDriverBindingSupported (
690 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
691 IN EFI_HANDLE ControllerHandle
,
692 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
698 // Try to open the DHCP6, HTTP and Device Path protocol.
700 Status
= gBS
->OpenProtocol (
702 &gEfiDhcp6ServiceBindingProtocolGuid
,
704 This
->DriverBindingHandle
,
706 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
708 if (EFI_ERROR (Status
)) {
712 Status
= gBS
->OpenProtocol (
714 &gEfiHttpServiceBindingProtocolGuid
,
716 This
->DriverBindingHandle
,
718 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
720 if (EFI_ERROR (Status
)) {
724 Status
= gBS
->OpenProtocol (
726 &gEfiDevicePathProtocolGuid
,
728 This
->DriverBindingHandle
,
730 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
738 Starts a device controller or a bus controller.
740 The Start() function is designed to be invoked from the EFI boot service ConnectController().
741 As a result, much of the error checking on the parameters to Start() has been moved into this
742 common boot service. It is legal to call Start() from other locations,
743 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
744 1. ControllerHandle must be a valid EFI_HANDLE.
745 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
746 EFI_DEVICE_PATH_PROTOCOL.
747 3. Prior to calling Start(), the Supported() function for the driver specified by This must
748 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
750 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
751 @param[in] ControllerHandle The handle of the controller to start. This handle
752 must support a protocol interface that supplies
753 an I/O abstraction to the driver.
754 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
755 parameter is ignored by device drivers, and is optional for bus
756 drivers. For a bus driver, if this parameter is NULL, then handles
757 for all the children of Controller are created by this driver.
758 If this parameter is not NULL and the first Device Path Node is
759 not the End of Device Path Node, then only the handle for the
760 child device specified by the first Device Path Node of
761 RemainingDevicePath is created by this driver.
762 If the first Device Path Node of RemainingDevicePath is
763 the End of Device Path Node, no child handle is created by this
766 @retval EFI_SUCCESS The device was started.
767 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
768 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
769 @retval Others The driver failded to start the device.
774 HttpBootIp6DxeDriverBindingStart (
775 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
776 IN EFI_HANDLE ControllerHandle
,
777 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
781 HTTP_BOOT_PRIVATE_DATA
*Private
;
783 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
786 Status
= gBS
->OpenProtocol (
790 This
->DriverBindingHandle
,
792 EFI_OPEN_PROTOCOL_GET_PROTOCOL
795 if (!EFI_ERROR (Status
)) {
796 Private
= HTTP_BOOT_PRIVATE_DATA_FROM_ID(Id
);
799 // Initialize the private data structure.
801 Private
= AllocateZeroPool (sizeof (HTTP_BOOT_PRIVATE_DATA
));
802 if (Private
== NULL
) {
803 return EFI_OUT_OF_RESOURCES
;
805 Private
->Signature
= HTTP_BOOT_PRIVATE_DATA_SIGNATURE
;
806 Private
->Controller
= ControllerHandle
;
807 InitializeListHead (&Private
->CacheList
);
809 // Get the NII interface if it exists, it's not required.
811 Status
= gBS
->OpenProtocol (
813 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
814 (VOID
**) &Private
->Nii
,
815 This
->DriverBindingHandle
,
817 EFI_OPEN_PROTOCOL_GET_PROTOCOL
819 if (EFI_ERROR (Status
)) {
824 // Open Device Path Protocol to prepare for appending IP and URI node.
826 Status
= gBS
->OpenProtocol (
828 &gEfiDevicePathProtocolGuid
,
829 (VOID
**) &Private
->ParentDevicePath
,
830 This
->DriverBindingHandle
,
832 EFI_OPEN_PROTOCOL_GET_PROTOCOL
834 if (EFI_ERROR (Status
)) {
839 // Initialize the HII configuration form.
841 Status
= HttpBootConfigFormInit (Private
);
842 if (EFI_ERROR (Status
)) {
847 // Install a protocol with Caller Id Guid to the NIC, this is just to build the relationship between
848 // NIC handle and the private data.
850 Status
= gBS
->InstallProtocolInterface (
853 EFI_NATIVE_INTERFACE
,
856 if (EFI_ERROR (Status
)) {
862 if (Private
->Ip6Nic
!= NULL
) {
864 // Already created before
869 Private
->Ip6Nic
= AllocateZeroPool (sizeof (HTTP_BOOT_VIRTUAL_NIC
));
870 if (Private
->Ip6Nic
== NULL
) {
871 return EFI_OUT_OF_RESOURCES
;
873 Private
->Ip6Nic
->Private
= Private
;
874 Private
->Ip6Nic
->ImageHandle
= This
->DriverBindingHandle
;
875 Private
->Ip6Nic
->Signature
= HTTP_BOOT_VIRTUAL_NIC_SIGNATURE
;
878 // Create Dhcp6 child and open Dhcp6 protocol
879 Status
= NetLibCreateServiceChild (
881 This
->DriverBindingHandle
,
882 &gEfiDhcp6ServiceBindingProtocolGuid
,
885 if (EFI_ERROR (Status
)) {
889 Status
= gBS
->OpenProtocol (
891 &gEfiDhcp6ProtocolGuid
,
892 (VOID
**) &Private
->Dhcp6
,
893 This
->DriverBindingHandle
,
895 EFI_OPEN_PROTOCOL_BY_DRIVER
897 if (EFI_ERROR (Status
)) {
902 // Create Ip6 child and open Ip6 protocol for background ICMP packets.
904 Status
= NetLibCreateServiceChild (
906 This
->DriverBindingHandle
,
907 &gEfiIp6ServiceBindingProtocolGuid
,
910 if (EFI_ERROR (Status
)) {
914 Status
= gBS
->OpenProtocol (
916 &gEfiIp6ProtocolGuid
,
917 (VOID
**) &Private
->Ip6
,
918 This
->DriverBindingHandle
,
920 EFI_OPEN_PROTOCOL_BY_DRIVER
922 if (EFI_ERROR (Status
)) {
927 // Locate Ip6Config protocol, it's required to configure the default gateway address.
929 Status
= gBS
->OpenProtocol (
931 &gEfiIp6ConfigProtocolGuid
,
932 (VOID
**) &Private
->Ip6Config
,
933 This
->DriverBindingHandle
,
935 EFI_OPEN_PROTOCOL_GET_PROTOCOL
937 if (EFI_ERROR (Status
)) {
942 // Append IPv6 device path node.
944 Node
= AllocateZeroPool (sizeof (IPv6_DEVICE_PATH
));
946 Status
= EFI_OUT_OF_RESOURCES
;
949 Node
->Ipv6
.Header
.Type
= MESSAGING_DEVICE_PATH
;
950 Node
->Ipv6
.Header
.SubType
= MSG_IPv6_DP
;
951 Node
->Ipv6
.PrefixLength
= IP6_PREFIX_LENGTH
;
952 SetDevicePathNodeLength (Node
, sizeof (IPv6_DEVICE_PATH
));
953 DevicePath
= AppendDevicePathNode(Private
->ParentDevicePath
, (EFI_DEVICE_PATH
*) Node
);
955 if (DevicePath
== NULL
) {
956 Status
= EFI_OUT_OF_RESOURCES
;
961 // Append URI device path node.
963 Node
= AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL
));
965 Status
= EFI_OUT_OF_RESOURCES
;
968 Node
->DevPath
.Type
= MESSAGING_DEVICE_PATH
;
969 Node
->DevPath
.SubType
= MSG_URI_DP
;
970 SetDevicePathNodeLength (Node
, sizeof (EFI_DEVICE_PATH_PROTOCOL
));
971 Private
->Ip6Nic
->DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*) Node
);
973 FreePool (DevicePath
);
974 if (Private
->Ip6Nic
->DevicePath
== NULL
) {
975 Status
= EFI_OUT_OF_RESOURCES
;
980 // Create a child handle for the HTTP boot and install DevPath and Load file protocol on it.
982 CopyMem (&Private
->Ip6Nic
->LoadFile
, &gHttpBootDxeLoadFile
, sizeof (Private
->LoadFile
));
983 Status
= gBS
->InstallMultipleProtocolInterfaces (
984 &Private
->Ip6Nic
->Controller
,
985 &gEfiLoadFileProtocolGuid
,
986 &Private
->Ip6Nic
->LoadFile
,
987 &gEfiDevicePathProtocolGuid
,
988 Private
->Ip6Nic
->DevicePath
,
991 if (EFI_ERROR (Status
)) {
996 // Open the Caller Id child to setup a parent-child relationship between
997 // real NIC handle and the HTTP boot child handle.
999 Status
= gBS
->OpenProtocol (
1003 This
->DriverBindingHandle
,
1004 Private
->Ip6Nic
->Controller
,
1005 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1007 if (EFI_ERROR (Status
)) {
1015 HttpBootDestroyIp6Children(This
, Private
);
1016 HttpBootConfigFormUnload (Private
);
1023 Stops a device controller or a bus controller.
1025 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
1026 As a result, much of the error checking on the parameters to Stop() has been moved
1027 into this common boot service. It is legal to call Stop() from other locations,
1028 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
1029 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
1030 same driver's Start() function.
1031 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
1032 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
1033 Start() function, and the Start() function must have called OpenProtocol() on
1034 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
1036 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
1037 @param[in] ControllerHandle A handle to the device being stopped. The handle must
1038 support a bus specific I/O protocol for the driver
1039 to use to stop the device.
1040 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
1041 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
1042 if NumberOfChildren is 0.
1044 @retval EFI_SUCCESS The device was stopped.
1045 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
1050 HttpBootIp6DxeDriverBindingStop (
1051 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1052 IN EFI_HANDLE ControllerHandle
,
1053 IN UINTN NumberOfChildren
,
1054 IN EFI_HANDLE
*ChildHandleBuffer OPTIONAL
1058 EFI_LOAD_FILE_PROTOCOL
*LoadFile
;
1059 HTTP_BOOT_PRIVATE_DATA
*Private
;
1060 EFI_HANDLE NicHandle
;
1064 // Try to get the Load File Protocol from the controller handle.
1066 Status
= gBS
->OpenProtocol (
1068 &gEfiLoadFileProtocolGuid
,
1069 (VOID
**) &LoadFile
,
1070 This
->DriverBindingHandle
,
1072 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1074 if (EFI_ERROR (Status
)) {
1076 // If failed, try to find the NIC handle for this controller.
1078 NicHandle
= HttpBootGetNicByIp6Children (ControllerHandle
);
1079 if (NicHandle
== NULL
) {
1084 // Try to retrieve the private data by the Caller Id Guid.
1086 Status
= gBS
->OpenProtocol (
1090 This
->DriverBindingHandle
,
1092 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1094 if (EFI_ERROR (Status
)) {
1097 Private
= HTTP_BOOT_PRIVATE_DATA_FROM_ID (Id
);
1099 Private
= HTTP_BOOT_PRIVATE_DATA_FROM_LOADFILE (LoadFile
);
1100 NicHandle
= Private
->Controller
;
1104 // Disable the HTTP boot function.
1106 Status
= HttpBootStop (Private
);
1107 if (Status
!= EFI_SUCCESS
&& Status
!= EFI_NOT_STARTED
) {
1112 // Destory all child instance and uninstall protocol interface.
1114 HttpBootDestroyIp6Children (This
, Private
);
1116 if (Private
->Ip4Nic
== NULL
&& Private
->Ip6Nic
== NULL
) {
1118 // Release the cached data.
1120 HttpBootFreeCacheList (Private
);
1123 // Unload the config form.
1125 HttpBootConfigFormUnload (Private
);
1127 gBS
->UninstallProtocolInterface (
1139 This is the declaration of an EFI image entry point. This entry point is
1140 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
1141 both device drivers and bus drivers.
1143 @param[in] ImageHandle The firmware allocated handle for the UEFI image.
1144 @param[in] SystemTable A pointer to the EFI System Table.
1146 @retval EFI_SUCCESS The operation completed successfully.
1147 @retval Others An unexpected error occurred.
1152 HttpBootDxeDriverEntryPoint (
1153 IN EFI_HANDLE ImageHandle
,
1154 IN EFI_SYSTEM_TABLE
*SystemTable
1160 // Install UEFI Driver Model protocol(s).
1162 Status
= EfiLibInstallDriverBindingComponentName2 (
1165 &gHttpBootIp4DxeDriverBinding
,
1167 &gHttpBootDxeComponentName
,
1168 &gHttpBootDxeComponentName2
1170 if (EFI_ERROR (Status
)) {
1174 Status
= EfiLibInstallDriverBindingComponentName2 (
1177 &gHttpBootIp6DxeDriverBinding
,
1179 &gHttpBootDxeComponentName
,
1180 &gHttpBootDxeComponentName2
1182 if (EFI_ERROR (Status
)) {
1183 gBS
->UninstallMultipleProtocolInterfaces(
1185 &gEfiDriverBindingProtocolGuid
,
1186 &gHttpBootIp4DxeDriverBinding
,
1187 &gEfiComponentName2ProtocolGuid
,
1188 &gHttpBootDxeComponentName2
,
1189 &gEfiComponentNameProtocolGuid
,
1190 &gHttpBootDxeComponentName
,