1d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu/** @file
2d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Driver Binding functions implementation for UEFI HTTP boot.
3d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
4d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuCopyright (c) 2015, Intel Corporation. All rights reserved.<BR>
5d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuThis program and the accompanying materials are licensed and made available under
6d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wuthe terms and conditions of the BSD License that accompanies this distribution.
7d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuThe full text of the license may be found at
8d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wuhttp://opensource.org/licenses/bsd-license.php.
9d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
10d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
13d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu**/
14d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
15d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu#include "HttpBootDxe.h"
16d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
17d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu///
18d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu/// Driver Binding Protocol instance
19d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu///
20d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuEFI_DRIVER_BINDING_PROTOCOL gHttpBootIp4DxeDriverBinding = {
21d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  HttpBootIp4DxeDriverBindingSupported,
22d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  HttpBootIp4DxeDriverBindingStart,
23d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  HttpBootIp4DxeDriverBindingStop,
24d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  HTTP_BOOT_DXE_VERSION,
25d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  NULL,
26d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  NULL
27d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu};
28d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
29b659408b933f40765960e877de3e1f8ceaab52cbZhang LuboEFI_DRIVER_BINDING_PROTOCOL gHttpBootIp6DxeDriverBinding = {
30b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  HttpBootIp6DxeDriverBindingSupported,
31b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  HttpBootIp6DxeDriverBindingStart,
32b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  HttpBootIp6DxeDriverBindingStop,
33b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  HTTP_BOOT_DXE_VERSION,
34b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  NULL,
35b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  NULL
36b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo};
37b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
38d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu/**
39d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Destroy the HTTP child based on IPv4 stack.
40d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
41d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @param[in]  This              Pointer to the EFI_DRIVER_BINDING_PROTOCOL.
42d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @param[in]  Private           Pointer to HTTP_BOOT_PRIVATE_DATA.
43d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
44d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu**/
45d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuVOID
46d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuHttpBootDestroyIp4Children (
47d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
48d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  IN HTTP_BOOT_PRIVATE_DATA       *Private
49d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  )
50d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu{
51d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  ASSERT (This != NULL);
52d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  ASSERT (Private != NULL);
53d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
54d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  if (Private->Dhcp4Child != NULL) {
55d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    gBS->CloseProtocol (
56b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           Private->Dhcp4Child,
57b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &gEfiDhcp4ProtocolGuid,
58b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           This->DriverBindingHandle,
59b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           Private->Controller
60b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           );
61d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
62d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    NetLibDestroyServiceChild (
63d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu      Private->Controller,
64d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu      This->DriverBindingHandle,
65d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu      &gEfiDhcp4ServiceBindingProtocolGuid,
66d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu      Private->Dhcp4Child
67d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu      );
68d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  }
69d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
70d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  if (Private->HttpCreated) {
71d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    HttpIoDestroyIo (&Private->HttpIo);
72d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    Private->HttpCreated = FALSE;
73d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  }
74d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
75b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (Private->Ip4Nic != NULL) {
76b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
77b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    gBS->CloseProtocol (
78b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           Private->Controller,
79b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &gEfiCallerIdGuid,
80b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           This->DriverBindingHandle,
81b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           Private->Ip4Nic->Controller
82b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           );
83b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
84b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    gBS->UninstallMultipleProtocolInterfaces (
85b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           Private->Ip4Nic->Controller,
86b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &gEfiLoadFileProtocolGuid,
87b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &Private->Ip4Nic->LoadFile,
88b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &gEfiDevicePathProtocolGuid,
89b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           Private->Ip4Nic->DevicePath,
90b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           NULL
91b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           );
92b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    FreePool (Private->Ip4Nic);
93b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Private->Ip4Nic = NULL;
94b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
95b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
96b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo}
97b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
98b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo/**
99b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Destroy the HTTP child based on IPv6 stack.
100b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
101b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @param[in]  This              Pointer to the EFI_DRIVER_BINDING_PROTOCOL.
102b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @param[in]  Private           Pointer to HTTP_BOOT_PRIVATE_DATA.
103b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
104b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo**/
105b659408b933f40765960e877de3e1f8ceaab52cbZhang LuboVOID
106b659408b933f40765960e877de3e1f8ceaab52cbZhang LuboHttpBootDestroyIp6Children (
107b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
108b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  IN HTTP_BOOT_PRIVATE_DATA       *Private
109b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  )
110b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo{
111b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  ASSERT (This != NULL);
112b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  ASSERT (Private != NULL);
113b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
114b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (Private->Ip6Child != NULL) {
115b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    gBS->CloseProtocol (
116b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           Private->Ip6Child,
117b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &gEfiIp6ProtocolGuid,
118b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           This->DriverBindingHandle,
119b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           Private->Controller
120b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           );
121b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
122b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    NetLibDestroyServiceChild (
123b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      Private->Controller,
124b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      This->DriverBindingHandle,
125b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      &gEfiIp6ServiceBindingProtocolGuid,
126b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      Private->Ip6Child
127b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      );
128b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
129b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
130b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (Private->Dhcp6Child != NULL) {
131b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    gBS->CloseProtocol (
132b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           Private->Dhcp6Child,
133b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &gEfiDhcp6ProtocolGuid,
134b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           This->DriverBindingHandle,
135b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           Private->Controller
136b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           );
137d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
138b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    NetLibDestroyServiceChild (
139b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      Private->Controller,
140b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      This->DriverBindingHandle,
141b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      &gEfiDhcp6ServiceBindingProtocolGuid,
142b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      Private->Dhcp6Child
143b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      );
144b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
145d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
146b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (Private->HttpCreated) {
147b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    HttpIoDestroyIo(&Private->HttpIo);
148b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Private->HttpCreated = FALSE;
149b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
150b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
151b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (Private->Ip6Nic != NULL) {
152b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
153b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    gBS->CloseProtocol (
154b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           Private->Controller,
155b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &gEfiCallerIdGuid,
156b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           This->DriverBindingHandle,
157b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           Private->Ip6Nic->Controller
158b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           );
159b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
160b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    gBS->UninstallMultipleProtocolInterfaces (
161b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           Private->Ip6Nic->Controller,
162b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &gEfiLoadFileProtocolGuid,
163b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &Private->Ip6Nic->LoadFile,
164b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &gEfiDevicePathProtocolGuid,
165b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           Private->Ip6Nic->DevicePath,
166b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           NULL
167b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           );
168b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    FreePool (Private->Ip6Nic);
169b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Private->Ip6Nic = NULL;
170d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  }
171d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu}
172d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
173d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu/**
174d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Tests to see if this driver supports a given controller. If a child device is provided,
175d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  it further tests to see if this driver supports creating a handle for the specified child device.
176d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
177d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  This function checks to see if the driver specified by This supports the device specified by
178d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  ControllerHandle. Drivers will typically use the device path attached to
179d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  ControllerHandle and/or the services from the bus I/O abstraction attached to
180d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  ControllerHandle to determine if the driver supports ControllerHandle. This function
181d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  may be called many times during platform initialization. In order to reduce boot times, the tests
182d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  performed by this function must be very small, and take as little time as possible to execute. This
183d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  function must not change the state of any hardware devices, and this function must be aware that the
184d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  device specified by ControllerHandle may already be managed by the same driver or a
185d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  different driver. This function must match its calls to AllocatePages() with FreePages(),
186d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
187d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Because ControllerHandle may have been previously started by the same driver, if a protocol is
188d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  already in the opened state, then it must not be closed with CloseProtocol(). This is required
189d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  to guarantee the state of ControllerHandle is not modified by this function.
190d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
191d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
192d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @param[in]  ControllerHandle     The handle of the controller to test. This handle
193d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   must support a protocol interface that supplies
194d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   an I/O abstraction to the driver.
195d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
196d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   parameter is ignored by device drivers, and is optional for bus
197d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   drivers. For bus drivers, if this parameter is not NULL, then
198d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   the bus driver must determine if the bus controller specified
199d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   by ControllerHandle and the child controller specified
200d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   by RemainingDevicePath are both supported by this
201d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   bus driver.
202d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
203d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @retval EFI_SUCCESS              The device specified by ControllerHandle and
204d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   RemainingDevicePath is supported by the driver specified by This.
205d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
206d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   RemainingDevicePath is already being managed by the driver
207d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   specified by This.
208d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
209d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   RemainingDevicePath is already being managed by a different
210d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   driver or an application that requires exclusive access.
211d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   Currently not implemented.
212d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
213d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   RemainingDevicePath is not supported by the driver specified by This.
214d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu**/
215d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuEFI_STATUS
216d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuEFIAPI
217d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuHttpBootIp4DxeDriverBindingSupported (
218d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
219d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  IN EFI_HANDLE                   ControllerHandle,
220d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
221d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  )
222d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu{
223d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  EFI_STATUS                    Status;
224d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
225d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
226d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  // Try to open the DHCP4, HTTP4 and Device Path protocol.
227d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
228d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Status = gBS->OpenProtocol (
229b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
230b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &gEfiDhcp4ServiceBindingProtocolGuid,
231b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  NULL,
232b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  This->DriverBindingHandle,
233b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
234b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
235b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  );
236d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  if (EFI_ERROR (Status)) {
237d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    return Status;
238d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  }
239d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
240d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Status = gBS->OpenProtocol (
241b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
242b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &gEfiHttpServiceBindingProtocolGuid,
243b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  NULL,
244b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  This->DriverBindingHandle,
245b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
246b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
247b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  );
248d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  if (EFI_ERROR (Status)) {
249d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    return Status;
250d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  }
251d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
252d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Status = gBS->OpenProtocol (
253b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
254b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &gEfiDevicePathProtocolGuid,
255b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  NULL,
256b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  This->DriverBindingHandle,
257b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
258b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
259b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  );
260d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
261d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  return Status;
262d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu}
263d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
264d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
265d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu/**
266d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Starts a device controller or a bus controller.
267d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
268d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  The Start() function is designed to be invoked from the EFI boot service ConnectController().
269d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  As a result, much of the error checking on the parameters to Start() has been moved into this
270d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  common boot service. It is legal to call Start() from other locations,
271d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  but the following calling restrictions must be followed, or the system behavior will not be deterministic.
272d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  1. ControllerHandle must be a valid EFI_HANDLE.
273d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
274d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu     EFI_DEVICE_PATH_PROTOCOL.
275d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  3. Prior to calling Start(), the Supported() function for the driver specified by This must
276d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
277d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
278d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
279d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @param[in]  ControllerHandle     The handle of the controller to start. This handle
280d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   must support a protocol interface that supplies
281d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   an I/O abstraction to the driver.
282d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
283d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   parameter is ignored by device drivers, and is optional for bus
284d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   drivers. For a bus driver, if this parameter is NULL, then handles
285d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   for all the children of Controller are created by this driver.
286d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   If this parameter is not NULL and the first Device Path Node is
287d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   not the End of Device Path Node, then only the handle for the
288d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   child device specified by the first Device Path Node of
289d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   RemainingDevicePath is created by this driver.
290d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   If the first Device Path Node of RemainingDevicePath is
291d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   the End of Device Path Node, no child handle is created by this
292d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                   driver.
293d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
294d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @retval EFI_SUCCESS              The device was started.
295d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
296d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
297d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @retval Others                   The driver failded to start the device.
298d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
299d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu**/
300d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuEFI_STATUS
301d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuEFIAPI
302d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuHttpBootIp4DxeDriverBindingStart (
303d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
304d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  IN EFI_HANDLE                   ControllerHandle,
305d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
306d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  )
307d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu{
308d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  EFI_STATUS                 Status;
309d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  HTTP_BOOT_PRIVATE_DATA     *Private;
310d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  EFI_DEV_PATH               *Node;
311d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  EFI_DEVICE_PATH_PROTOCOL   *DevicePath;
312d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  UINT32                     *Id;
313d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
314d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Status = gBS->OpenProtocol (
315d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  ControllerHandle,
316d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  &gEfiCallerIdGuid,
317d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  (VOID **) &Id,
318d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  This->DriverBindingHandle,
319d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  ControllerHandle,
320d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
321d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  );
322b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
323d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  if (!EFI_ERROR (Status)) {
324b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      Private = HTTP_BOOT_PRIVATE_DATA_FROM_ID(Id);
325b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  } else {
326b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
327b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    // Initialize the private data structure.
328b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
329b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Private = AllocateZeroPool (sizeof (HTTP_BOOT_PRIVATE_DATA));
330b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    if (Private == NULL) {
331b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      return EFI_OUT_OF_RESOURCES;
332b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    }
333b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Private->Signature = HTTP_BOOT_PRIVATE_DATA_SIGNATURE;
334b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Private->Controller = ControllerHandle;
335b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Private->Image = This->ImageHandle;
336b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    InitializeListHead (&Private->CacheList);
337b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
338b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    // Get the NII interface if it exists, it's not required.
339b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
340b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Status = gBS->OpenProtocol (
341b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    ControllerHandle,
342b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
343b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    (VOID **) &Private->Nii,
344b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    This->DriverBindingHandle,
345b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    ControllerHandle,
346b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
347b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    );
348b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    if (EFI_ERROR (Status)) {
349b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      Private->Nii = NULL;
350b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    }
351d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
352b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
353b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    // Open Device Path Protocol to prepare for appending IP and URI node.
354b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
355b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Status = gBS->OpenProtocol (
356b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    ControllerHandle,
357b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    &gEfiDevicePathProtocolGuid,
358b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    (VOID **) &Private->ParentDevicePath,
359b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    This->DriverBindingHandle,
360b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    ControllerHandle,
361b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
362b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    );
363b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    if (EFI_ERROR (Status)) {
364b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      goto ON_ERROR;
365b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    }
366b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
367b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
368b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    // Install a protocol with Caller Id Guid to the NIC, this is just to build the relationship between
369b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    // NIC handle and the private data.
370b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
371b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Status = gBS->InstallProtocolInterface (
372b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    &ControllerHandle,
373b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    &gEfiCallerIdGuid,
374b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    EFI_NATIVE_INTERFACE,
375b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    &Private->Id
376b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    );
377b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    if (EFI_ERROR (Status)) {
378b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      goto ON_ERROR;
379b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    }
380b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
381b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
382b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
383b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (Private->Ip4Nic != NULL) {
384b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
385b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    // Already created before
386b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
387b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    return EFI_SUCCESS;
388b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
389b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
390b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Private->Ip4Nic = AllocateZeroPool (sizeof (HTTP_BOOT_VIRTUAL_NIC));
391b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (Private->Ip4Nic == NULL) {
392d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    return EFI_OUT_OF_RESOURCES;
393d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  }
394b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Private->Ip4Nic->Private   = Private;
395b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Private->Ip4Nic->Signature = HTTP_BOOT_VIRTUAL_NIC_SIGNATURE;
396b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
397d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
398b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  // Create DHCP4 child instance.
399d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
400d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Status = NetLibCreateServiceChild (
401d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu             ControllerHandle,
402d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu             This->DriverBindingHandle,
403d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu             &gEfiDhcp4ServiceBindingProtocolGuid,
404d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu             &Private->Dhcp4Child
405d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu             );
406d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  if (EFI_ERROR (Status)) {
407d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    goto ON_ERROR;
408d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  }
409b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
410d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Status = gBS->OpenProtocol (
411d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  Private->Dhcp4Child,
412d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  &gEfiDhcp4ProtocolGuid,
413d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  (VOID **) &Private->Dhcp4,
414d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  This->DriverBindingHandle,
415d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  ControllerHandle,
416d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  EFI_OPEN_PROTOCOL_BY_DRIVER
417d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  );
418d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  if (EFI_ERROR (Status)) {
419d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    goto ON_ERROR;
420d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  }
421b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
422d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
423d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  // Get the Ip4Config2 protocol, it's required to configure the default gateway address.
424d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
425d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Status = gBS->OpenProtocol (
426d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  ControllerHandle,
427d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  &gEfiIp4Config2ProtocolGuid,
428d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  (VOID **) &Private->Ip4Config2,
429d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  This->DriverBindingHandle,
430d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  ControllerHandle,
431d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
432d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  );
433d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  if (EFI_ERROR (Status)) {
434d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    goto ON_ERROR;
435d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  }
436b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
437d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
438d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  // Append IPv4 device path node.
439d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
440d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Node = AllocateZeroPool (sizeof (IPv4_DEVICE_PATH));
441d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  if (Node == NULL) {
442d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    Status = EFI_OUT_OF_RESOURCES;
443d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    goto ON_ERROR;
444d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  }
445d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Node->Ipv4.Header.Type = MESSAGING_DEVICE_PATH;
446d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Node->Ipv4.Header.SubType = MSG_IPv4_DP;
447d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH));
448d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Node->Ipv4.StaticIpAddress = FALSE;
449d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  DevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
450d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  FreePool (Node);
451d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  if (DevicePath == NULL) {
452d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    Status = EFI_OUT_OF_RESOURCES;
453d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    goto ON_ERROR;
454d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  }
455b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
456d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
457d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  // Append URI device path node.
458d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
459d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Node = AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL));
460d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  if (Node == NULL) {
461d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    Status = EFI_OUT_OF_RESOURCES;
462d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    goto ON_ERROR;
463d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  }
464d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Node->DevPath.Type = MESSAGING_DEVICE_PATH;
465d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Node->DevPath.SubType = MSG_URI_DP;
466d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  SetDevicePathNodeLength (Node, sizeof (EFI_DEVICE_PATH_PROTOCOL));
467b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Private->Ip4Nic->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
468d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  FreePool (Node);
469d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  FreePool (DevicePath);
470b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (Private->Ip4Nic->DevicePath == NULL) {
471d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    Status = EFI_OUT_OF_RESOURCES;
472d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    goto ON_ERROR;
473d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  }
474b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
475d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
476d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  // Create a child handle for the HTTP boot and install DevPath and Load file protocol on it.
477d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
478b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  CopyMem (&Private->Ip4Nic->LoadFile, &gHttpBootDxeLoadFile, sizeof (EFI_LOAD_FILE_PROTOCOL));
479d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Status = gBS->InstallMultipleProtocolInterfaces (
480b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &Private->Ip4Nic->Controller,
481d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  &gEfiLoadFileProtocolGuid,
482b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &Private->Ip4Nic->LoadFile,
483d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  &gEfiDevicePathProtocolGuid,
484b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  Private->Ip4Nic->DevicePath,
485d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  NULL
486d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  );
487d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  if (EFI_ERROR (Status)) {
488d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    goto ON_ERROR;
489d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  }
490b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
491d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
492d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  // Open the Caller Id child to setup a parent-child relationship between
493b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  // real NIC handle and the HTTP boot Ipv4 NIC handle.
494d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
495d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Status = gBS->OpenProtocol (
496d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  ControllerHandle,
497d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  &gEfiCallerIdGuid,
498d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  (VOID **) &Id,
499d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  This->DriverBindingHandle,
500b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  Private->Ip4Nic->Controller,
501d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
502d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  );
503d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  if (EFI_ERROR (Status)) {
504d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    goto ON_ERROR;
505d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  }
506b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
507d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  return EFI_SUCCESS;
508d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
509b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
510d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuON_ERROR:
511d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
512d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  HttpBootDestroyIp4Children (This, Private);
513d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  FreePool (Private);
514d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
515d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  return Status;
516d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu}
517d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
518b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
519d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu/**
520d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Stops a device controller or a bus controller.
521d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
522d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
523d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  As a result, much of the error checking on the parameters to Stop() has been moved
524d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  into this common boot service. It is legal to call Stop() from other locations,
525d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  but the following calling restrictions must be followed, or the system behavior will not be deterministic.
526d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
527d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu     same driver's Start() function.
528d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
529d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu     EFI_HANDLE. In addition, all of these handles must have been created in this driver's
530d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu     Start() function, and the Start() function must have called OpenProtocol() on
531d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu     ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
532d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
533d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
534d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
535d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                support a bus specific I/O protocol for the driver
536d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                to use to stop the device.
537d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
538d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
539d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                                if NumberOfChildren is 0.
540d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
541d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @retval EFI_SUCCESS           The device was stopped.
542d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
543d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
544d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu**/
545d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuEFI_STATUS
546d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuEFIAPI
547d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuHttpBootIp4DxeDriverBindingStop (
548d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
549d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  IN EFI_HANDLE                   ControllerHandle,
550d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  IN UINTN                        NumberOfChildren,
551d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
552d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  )
553d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu{
554d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  EFI_STATUS                      Status;
555d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  EFI_LOAD_FILE_PROTOCOL          *LoadFile;
556d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  HTTP_BOOT_PRIVATE_DATA          *Private;
557d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  EFI_HANDLE                      NicHandle;
558d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  UINT32                          *Id;
559d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
560d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
561d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  // Try to get the Load File Protocol from the controller handle.
562d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
563d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Status = gBS->OpenProtocol (
564d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  ControllerHandle,
565d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  &gEfiLoadFileProtocolGuid,
566d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  (VOID **) &LoadFile,
567d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  This->DriverBindingHandle,
568d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  ControllerHandle,
569d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
570d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                  );
571d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  if (EFI_ERROR (Status)) {
572d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    //
573d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    // If failed, try to find the NIC handle for this controller.
574d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    //
575d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    NicHandle = HttpBootGetNicByIp4Children (ControllerHandle);
576d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    if (NicHandle == NULL) {
577d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu      return EFI_SUCCESS;
578d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    }
579d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
580d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    //
581d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    // Try to retrieve the private data by the Caller Id Guid.
582d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    //
583d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    Status = gBS->OpenProtocol (
584d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                    NicHandle,
585d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                    &gEfiCallerIdGuid,
586d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                    (VOID **) &Id,
587d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                    This->DriverBindingHandle,
588d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                    ControllerHandle,
589d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
590d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu                    );
591d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    if (EFI_ERROR (Status)) {
592d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu      return Status;
593d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    }
594d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    Private = HTTP_BOOT_PRIVATE_DATA_FROM_ID (Id);
595d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  } else {
596d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    Private = HTTP_BOOT_PRIVATE_DATA_FROM_LOADFILE (LoadFile);
597d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    NicHandle = Private->Controller;
598d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  }
599d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
600d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
601d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  // Disable the HTTP boot function.
602d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
603d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  Status = HttpBootStop (Private);
604d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  if (Status != EFI_SUCCESS && Status != EFI_NOT_STARTED) {
605d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu    return Status;
606d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  }
607d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
608d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
609d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  // Destory all child instance and uninstall protocol interface.
610d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
611d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  HttpBootDestroyIp4Children (This, Private);
612b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
613b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (Private->Ip4Nic == NULL && Private->Ip6Nic == NULL) {
614b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
615b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    // Release the cached data.
616b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
617b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    HttpBootFreeCacheList (Private);
618b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
619b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    gBS->UninstallProtocolInterface (
620b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           NicHandle,
621b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &gEfiCallerIdGuid,
622b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &Private->Id
623b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           );
624b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    FreePool (Private);
625d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
626b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
627d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
628d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  return EFI_SUCCESS;
629d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu}
630d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
631d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu/**
632b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Tests to see if this driver supports a given controller. If a child device is provided,
633b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  it further tests to see if this driver supports creating a handle for the specified child device.
634d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
635b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  This function checks to see if the driver specified by This supports the device specified by
636b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  ControllerHandle. Drivers will typically use the device path attached to
637b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  ControllerHandle and/or the services from the bus I/O abstraction attached to
638b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  ControllerHandle to determine if the driver supports ControllerHandle. This function
639b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  may be called many times during platform initialization. In order to reduce boot times, the tests
640b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  performed by this function must be very small, and take as little time as possible to execute. This
641b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  function must not change the state of any hardware devices, and this function must be aware that the
642b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  device specified by ControllerHandle may already be managed by the same driver or a
643b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  different driver. This function must match its calls to AllocatePages() with FreePages(),
644b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
645b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Because ControllerHandle may have been previously started by the same driver, if a protocol is
646b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  already in the opened state, then it must not be closed with CloseProtocol(). This is required
647b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  to guarantee the state of ControllerHandle is not modified by this function.
648d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
649b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
650b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @param[in]  ControllerHandle     The handle of the controller to test. This handle
651b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   must support a protocol interface that supplies
652b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   an I/O abstraction to the driver.
653b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
654b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   parameter is ignored by device drivers, and is optional for bus
655b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   drivers. For bus drivers, if this parameter is not NULL, then
656b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   the bus driver must determine if the bus controller specified
657b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   by ControllerHandle and the child controller specified
658b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   by RemainingDevicePath are both supported by this
659b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   bus driver.
660d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
661b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @retval EFI_SUCCESS              The device specified by ControllerHandle and
662b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   RemainingDevicePath is supported by the driver specified by This.
663b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
664b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   RemainingDevicePath is already being managed by the driver
665b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   specified by This.
666b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
667b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   RemainingDevicePath is already being managed by a different
668b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   driver or an application that requires exclusive access.
669b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   Currently not implemented.
670b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
671b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   RemainingDevicePath is not supported by the driver specified by This.
672d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu**/
673d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuEFI_STATUS
674d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin WuEFIAPI
675b659408b933f40765960e877de3e1f8ceaab52cbZhang LuboHttpBootIp6DxeDriverBindingSupported (
676b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
677b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  IN EFI_HANDLE                   ControllerHandle,
678b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
679d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  )
680d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu{
681b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  EFI_STATUS                    Status;
682b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
683d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
684b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  // Try to open the DHCP6, HTTP and Device Path protocol.
685d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu  //
686b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Status = gBS->OpenProtocol (
687b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
688b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &gEfiDhcp6ServiceBindingProtocolGuid,
689b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  NULL,
690b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  This->DriverBindingHandle,
691b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
692b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
693b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  );
694b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (EFI_ERROR (Status)) {
695b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    return Status;
696b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
697b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
698b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Status = gBS->OpenProtocol (
699b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
700b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &gEfiHttpServiceBindingProtocolGuid,
701b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  NULL,
702b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  This->DriverBindingHandle,
703b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
704b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
705b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  );
706b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (EFI_ERROR (Status)) {
707b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    return Status;
708b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
709b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
710b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Status = gBS->OpenProtocol (
711b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
712b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &gEfiDevicePathProtocolGuid,
713b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  NULL,
714b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  This->DriverBindingHandle,
715b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
716b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
717b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  );
718b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
719b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  return Status;
720b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
721b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo}
722b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
723b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo/**
724b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Starts a device controller or a bus controller.
725b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
726b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  The Start() function is designed to be invoked from the EFI boot service ConnectController().
727b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  As a result, much of the error checking on the parameters to Start() has been moved into this
728b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  common boot service. It is legal to call Start() from other locations,
729b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  but the following calling restrictions must be followed, or the system behavior will not be deterministic.
730b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  1. ControllerHandle must be a valid EFI_HANDLE.
731b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
732b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo     EFI_DEVICE_PATH_PROTOCOL.
733b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  3. Prior to calling Start(), the Supported() function for the driver specified by This must
734b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
735b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
736b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
737b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @param[in]  ControllerHandle     The handle of the controller to start. This handle
738b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   must support a protocol interface that supplies
739b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   an I/O abstraction to the driver.
740b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
741b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   parameter is ignored by device drivers, and is optional for bus
742b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   drivers. For a bus driver, if this parameter is NULL, then handles
743b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   for all the children of Controller are created by this driver.
744b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   If this parameter is not NULL and the first Device Path Node is
745b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   not the End of Device Path Node, then only the handle for the
746b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   child device specified by the first Device Path Node of
747b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   RemainingDevicePath is created by this driver.
748b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   If the first Device Path Node of RemainingDevicePath is
749b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   the End of Device Path Node, no child handle is created by this
750b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                   driver.
751b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
752b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @retval EFI_SUCCESS              The device was started.
753b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
754b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
755b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @retval Others                   The driver failded to start the device.
756b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
757b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo**/
758b659408b933f40765960e877de3e1f8ceaab52cbZhang LuboEFI_STATUS
759b659408b933f40765960e877de3e1f8ceaab52cbZhang LuboEFIAPI
760b659408b933f40765960e877de3e1f8ceaab52cbZhang LuboHttpBootIp6DxeDriverBindingStart (
761b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
762b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  IN EFI_HANDLE                   ControllerHandle,
763b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
764b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  )
765b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo{
766b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  EFI_STATUS                 Status;
767b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  HTTP_BOOT_PRIVATE_DATA     *Private;
768b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  EFI_DEV_PATH               *Node;
769b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  EFI_DEVICE_PATH_PROTOCOL   *DevicePath;
770b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  UINT32                     *Id;
771b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
772b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Status = gBS->OpenProtocol (
773b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
774b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &gEfiCallerIdGuid,
775b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  (VOID **) &Id,
776b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  This->DriverBindingHandle,
777b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
778b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
779b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  );
780b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
781b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (!EFI_ERROR (Status)) {
782b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      Private = HTTP_BOOT_PRIVATE_DATA_FROM_ID(Id);
783b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  } else {
784b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
785b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    // Initialize the private data structure.
786b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
787b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Private = AllocateZeroPool (sizeof (HTTP_BOOT_PRIVATE_DATA));
788b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    if (Private == NULL) {
789b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      return EFI_OUT_OF_RESOURCES;
790b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    }
791b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Private->Signature = HTTP_BOOT_PRIVATE_DATA_SIGNATURE;
792b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Private->Controller = ControllerHandle;
793b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Private->Image = This->ImageHandle;
794b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    InitializeListHead (&Private->CacheList);
795b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
796b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    // Get the NII interface if it exists, it's not required.
797b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
798b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Status = gBS->OpenProtocol (
799b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    ControllerHandle,
800b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
801b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    (VOID **) &Private->Nii,
802b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    This->DriverBindingHandle,
803b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    ControllerHandle,
804b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
805b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    );
806b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    if (EFI_ERROR (Status)) {
807b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      Private->Nii = NULL;
808b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    }
809b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
810b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
811b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    // Open Device Path Protocol to prepare for appending IP and URI node.
812b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
813b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Status = gBS->OpenProtocol (
814b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    ControllerHandle,
815b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    &gEfiDevicePathProtocolGuid,
816b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    (VOID **) &Private->ParentDevicePath,
817b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    This->DriverBindingHandle,
818b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    ControllerHandle,
819b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
820b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    );
821b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    if (EFI_ERROR (Status)) {
822b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      goto ON_ERROR;
823b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    }
824b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
825b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
826b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    // Install a protocol with Caller Id Guid to the NIC, this is just to build the relationship between
827b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    // NIC handle and the private data.
828b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
829b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Status = gBS->InstallProtocolInterface (
830b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    &ControllerHandle,
831b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    &gEfiCallerIdGuid,
832b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    EFI_NATIVE_INTERFACE,
833b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    &Private->Id
834b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    );
835b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    if (EFI_ERROR (Status)) {
836b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      goto ON_ERROR;
837b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    }
838b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
839b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
840b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
841b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (Private->Ip6Nic != NULL) {
842b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
843b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    // Already created before
844b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
845b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    return EFI_SUCCESS;
846b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
847b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
848b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Private->Ip6Nic = AllocateZeroPool (sizeof (HTTP_BOOT_VIRTUAL_NIC));
849b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (Private->Ip6Nic == NULL) {
850b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    return EFI_OUT_OF_RESOURCES;
851b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
852b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Private->Ip6Nic->Private   = Private;
853b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Private->Ip6Nic->Signature = HTTP_BOOT_VIRTUAL_NIC_SIGNATURE;
854b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
855b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
856b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  // Create Dhcp6 child and open Dhcp6 protocol
857b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Status = NetLibCreateServiceChild (
858b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             ControllerHandle,
859b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             This->DriverBindingHandle,
860b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             &gEfiDhcp6ServiceBindingProtocolGuid,
861b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             &Private->Dhcp6Child
862b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             );
863b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (EFI_ERROR (Status)) {
864b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    goto ON_ERROR;
865b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
866b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
867b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Status = gBS->OpenProtocol (
868b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  Private->Dhcp6Child,
869b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &gEfiDhcp6ProtocolGuid,
870b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  (VOID **) &Private->Dhcp6,
871b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  This->DriverBindingHandle,
872b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
873b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  EFI_OPEN_PROTOCOL_BY_DRIVER
874b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  );
875b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (EFI_ERROR (Status)) {
876b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    goto ON_ERROR;
877b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
878b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
879b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
880b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  // Create Ip6 child and open Ip6 protocol for background ICMP packets.
881b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
882b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Status = NetLibCreateServiceChild (
883b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo              ControllerHandle,
884b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo              This->DriverBindingHandle,
885b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo              &gEfiIp6ServiceBindingProtocolGuid,
886b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo              &Private->Ip6Child
887b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo              );
888b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (EFI_ERROR (Status)) {
889b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    goto ON_ERROR;
890b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
891b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
892b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Status = gBS->OpenProtocol (
893b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  Private->Ip6Child,
894b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &gEfiIp6ProtocolGuid,
895b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  (VOID **) &Private->Ip6,
896b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  This->DriverBindingHandle,
897b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
898b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  EFI_OPEN_PROTOCOL_BY_DRIVER
899b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  );
900b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (EFI_ERROR (Status)) {
901b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    goto ON_ERROR;
902b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
903b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
904b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
905b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  // Locate Ip6Config protocol, it's required to configure the default gateway address.
906b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
907b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Status = gBS->OpenProtocol (
908b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
909b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &gEfiIp6ConfigProtocolGuid,
910b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  (VOID **) &Private->Ip6Config,
911b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  This->DriverBindingHandle,
912b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
913b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
914b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  );
915b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (EFI_ERROR (Status)) {
916b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    goto ON_ERROR;
917b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
918b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
919b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
920b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  // Append IPv6 device path node.
921b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
922b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH));
923b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (Node == NULL) {
924b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Status = EFI_OUT_OF_RESOURCES;
925b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    goto ON_ERROR;
926b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
927b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Node->Ipv6.Header.Type = MESSAGING_DEVICE_PATH;
928b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Node->Ipv6.Header.SubType = MSG_IPv6_DP;
929b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Node->Ipv6.PrefixLength = IP6_PREFIX_LENGTH;
930b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  SetDevicePathNodeLength (Node, sizeof (IPv6_DEVICE_PATH));
931b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  DevicePath = AppendDevicePathNode(Private->ParentDevicePath, (EFI_DEVICE_PATH*) Node);
932b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  FreePool(Node);
933b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (DevicePath == NULL) {
934b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Status = EFI_OUT_OF_RESOURCES;
935b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    goto ON_ERROR;
936b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
937b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
938b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
939b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  // Append URI device path node.
940b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
941b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Node = AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL));
942b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (Node == NULL) {
943b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Status = EFI_OUT_OF_RESOURCES;
944b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    goto ON_ERROR;
945b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
946b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Node->DevPath.Type = MESSAGING_DEVICE_PATH;
947b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Node->DevPath.SubType = MSG_URI_DP;
948b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  SetDevicePathNodeLength (Node, sizeof (EFI_DEVICE_PATH_PROTOCOL));
949b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Private->Ip6Nic->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
950b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  FreePool (Node);
951b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  FreePool (DevicePath);
952b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (Private->Ip6Nic->DevicePath == NULL) {
953b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Status = EFI_OUT_OF_RESOURCES;
954b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    goto ON_ERROR;
955b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
956b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
957b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
958b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  // Create a child handle for the HTTP boot and install DevPath and Load file protocol on it.
959b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
960b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  CopyMem (&Private->Ip6Nic->LoadFile, &gHttpBootDxeLoadFile, sizeof (Private->LoadFile));
961b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Status = gBS->InstallMultipleProtocolInterfaces (
962b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &Private->Ip6Nic->Controller,
963b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &gEfiLoadFileProtocolGuid,
964b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &Private->Ip6Nic->LoadFile,
965b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &gEfiDevicePathProtocolGuid,
966b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  Private->Ip6Nic->DevicePath,
967b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  NULL
968b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  );
969b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (EFI_ERROR (Status)) {
970b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    goto ON_ERROR;
971b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
972b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
973b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
974b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  // Open the Caller Id child to setup a parent-child relationship between
975b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  // real NIC handle and the HTTP boot child handle.
976b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
977b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Status = gBS->OpenProtocol (
978b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
979b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &gEfiCallerIdGuid,
980b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  (VOID **) &Id,
981b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  This->DriverBindingHandle,
982b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  Private->Ip6Nic->Controller,
983b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
984b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  );
985b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (EFI_ERROR (Status)) {
986b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    goto ON_ERROR;
987b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
988b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
989b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  return EFI_SUCCESS;
990b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
991b659408b933f40765960e877de3e1f8ceaab52cbZhang LuboON_ERROR:
992b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
993b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HttpBootDestroyIp6Children(This, Private);
994b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo FreePool (Private);
995b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
996b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo return Status;
997b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
998b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo}
999b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
1000b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo/**
1001b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Stops a device controller or a bus controller.
1002b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
1003b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
1004b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  As a result, much of the error checking on the parameters to Stop() has been moved
1005b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  into this common boot service. It is legal to call Stop() from other locations,
1006b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  but the following calling restrictions must be followed, or the system behavior will not be deterministic.
1007b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
1008b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo     same driver's Start() function.
1009b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
1010b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo     EFI_HANDLE. In addition, all of these handles must have been created in this driver's
1011b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo     Start() function, and the Start() function must have called OpenProtocol() on
1012b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo     ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
1013b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
1014b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
1015b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
1016b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                support a bus specific I/O protocol for the driver
1017b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                to use to stop the device.
1018b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
1019b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
1020b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                                if NumberOfChildren is 0.
1021b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
1022b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @retval EFI_SUCCESS           The device was stopped.
1023b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
1024b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
1025b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo**/
1026b659408b933f40765960e877de3e1f8ceaab52cbZhang LuboEFI_STATUS
1027b659408b933f40765960e877de3e1f8ceaab52cbZhang LuboEFIAPI
1028b659408b933f40765960e877de3e1f8ceaab52cbZhang LuboHttpBootIp6DxeDriverBindingStop (
1029b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
1030b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  IN EFI_HANDLE                   ControllerHandle,
1031b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  IN UINTN                        NumberOfChildren,
1032b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
1033b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  )
1034b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo{
1035b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  EFI_STATUS                      Status;
1036b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  EFI_LOAD_FILE_PROTOCOL          *LoadFile;
1037b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  HTTP_BOOT_PRIVATE_DATA          *Private;
1038b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  EFI_HANDLE                      NicHandle;
1039b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  UINT32                          *Id;
1040b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
1041b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
1042b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  // Try to get the Load File Protocol from the controller handle.
1043b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
1044b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Status = gBS->OpenProtocol (
1045b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
1046b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  &gEfiLoadFileProtocolGuid,
1047b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  (VOID **) &LoadFile,
1048b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  This->DriverBindingHandle,
1049b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  ControllerHandle,
1050b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
1051b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                  );
1052b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (EFI_ERROR (Status)) {
1053b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
1054b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    // If failed, try to find the NIC handle for this controller.
1055b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
1056b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    NicHandle = HttpBootGetNicByIp6Children (ControllerHandle);
1057b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    if (NicHandle == NULL) {
1058b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      return EFI_SUCCESS;
1059b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    }
1060b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
1061b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
1062b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    // Try to retrieve the private data by the Caller Id Guid.
1063b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
1064b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Status = gBS->OpenProtocol (
1065b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    NicHandle,
1066b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    &gEfiCallerIdGuid,
1067b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    (VOID **) &Id,
1068b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    This->DriverBindingHandle,
1069b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    ControllerHandle,
1070b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
1071b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo                    );
1072b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    if (EFI_ERROR (Status)) {
1073b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo      return Status;
1074b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    }
1075b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Private = HTTP_BOOT_PRIVATE_DATA_FROM_ID (Id);
1076b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  } else {
1077b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    Private = HTTP_BOOT_PRIVATE_DATA_FROM_LOADFILE (LoadFile);
1078b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    NicHandle = Private->Controller;
1079b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
1080b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
1081b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
1082b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  // Disable the HTTP boot function.
1083b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
1084b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Status = HttpBootStop (Private);
1085b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (Status != EFI_SUCCESS && Status != EFI_NOT_STARTED) {
1086b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    return Status;
1087b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
1088b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
1089b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
1090b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  // Destory all child instance and uninstall protocol interface.
1091b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
1092b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  HttpBootDestroyIp6Children (This, Private);
1093b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
1094b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (Private->Ip4Nic == NULL && Private->Ip6Nic == NULL) {
1095b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
1096b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    // Release the cached data.
1097b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    //
1098b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    HttpBootFreeCacheList (Private);
1099b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
1100b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    gBS->UninstallProtocolInterface (
1101b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           NicHandle,
1102b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &gEfiCallerIdGuid,
1103b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &Private->Id
1104b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           );
1105b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    FreePool (Private);
1106b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
1107b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
1108b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
1109b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  return EFI_SUCCESS;
1110b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo}
1111b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo/**
1112b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  This is the declaration of an EFI image entry point. This entry point is
1113b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
1114b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  both device drivers and bus drivers.
1115b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
1116b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
1117b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @param[in]  SystemTable       A pointer to the EFI System Table.
1118b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
1119b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @retval EFI_SUCCESS           The operation completed successfully.
1120b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  @retval Others                An unexpected error occurred.
1121b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
1122b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo**/
1123b659408b933f40765960e877de3e1f8ceaab52cbZhang LuboEFI_STATUS
1124b659408b933f40765960e877de3e1f8ceaab52cbZhang LuboEFIAPI
1125b659408b933f40765960e877de3e1f8ceaab52cbZhang LuboHttpBootDxeDriverEntryPoint (
1126b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  IN EFI_HANDLE        ImageHandle,
1127b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  IN EFI_SYSTEM_TABLE  *SystemTable
1128b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  )
1129b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo{
1130b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  EFI_STATUS   Status;
1131b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
1132b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  // Install UEFI Driver Model protocol(s).
1133b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  //
1134b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Status = EfiLibInstallDriverBindingComponentName2 (
1135b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             ImageHandle,
1136b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             SystemTable,
1137b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             &gHttpBootIp4DxeDriverBinding,
1138b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             ImageHandle,
1139b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             &gHttpBootDxeComponentName,
1140b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             &gHttpBootDxeComponentName2
1141b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             );
1142b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (EFI_ERROR (Status)) {
1143b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    return Status;
1144b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
1145b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo
1146b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  Status = EfiLibInstallDriverBindingComponentName2 (
1147b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             ImageHandle,
1148b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             SystemTable,
1149b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             &gHttpBootIp6DxeDriverBinding,
1150b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             NULL,
1151b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             &gHttpBootDxeComponentName,
1152b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             &gHttpBootDxeComponentName2
1153b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo             );
1154b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  if (EFI_ERROR (Status)) {
1155b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo    gBS->UninstallMultipleProtocolInterfaces(
1156b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           ImageHandle,
1157b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &gEfiDriverBindingProtocolGuid,
1158b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &gHttpBootIp4DxeDriverBinding,
1159b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &gEfiComponentName2ProtocolGuid,
1160b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &gHttpBootDxeComponentName2,
1161b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &gEfiComponentNameProtocolGuid,
1162b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           &gHttpBootDxeComponentName,
1163b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           NULL
1164b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo           );
1165b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  }
1166b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo  return Status;
1167d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu}
1168d933e70a9761bf47941ac3d973cc5e7ee44da930Jiaxin Wu
1169