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