]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/HttpDxe/HttpDriver.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / NetworkPkg / HttpDxe / HttpDriver.c
1 /** @file
2 The driver binding and service binding protocol for HttpDxe driver.
3
4 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #include "HttpDriver.h"
12
13 EFI_HTTP_UTILITIES_PROTOCOL *mHttpUtilities = NULL;
14
15 ///
16 /// Driver Binding Protocol instance
17 ///
18 EFI_DRIVER_BINDING_PROTOCOL gHttpDxeIp4DriverBinding = {
19 HttpDxeIp4DriverBindingSupported,
20 HttpDxeIp4DriverBindingStart,
21 HttpDxeIp4DriverBindingStop,
22 HTTP_DRIVER_VERSION,
23 NULL,
24 NULL
25 };
26
27 EFI_DRIVER_BINDING_PROTOCOL gHttpDxeIp6DriverBinding = {
28 HttpDxeIp6DriverBindingSupported,
29 HttpDxeIp6DriverBindingStart,
30 HttpDxeIp6DriverBindingStop,
31 HTTP_DRIVER_VERSION,
32 NULL,
33 NULL
34 };
35
36 /**
37 Create a HTTP driver service binding private instance.
38
39 @param[in] Controller The controller that has TCP4 service binding
40 installed.
41 @param[out] ServiceData Point to HTTP driver private instance.
42
43 @retval EFI_OUT_OF_RESOURCES Failed to allocate some resources.
44 @retval EFI_SUCCESS A new HTTP driver private instance is created.
45
46 **/
47 EFI_STATUS
48 HttpCreateService (
49 IN EFI_HANDLE Controller,
50 OUT HTTP_SERVICE **ServiceData
51 )
52 {
53 HTTP_SERVICE *HttpService;
54
55 ASSERT (ServiceData != NULL);
56 *ServiceData = NULL;
57
58 HttpService = AllocateZeroPool (sizeof (HTTP_SERVICE));
59 if (HttpService == NULL) {
60 return EFI_OUT_OF_RESOURCES;
61 }
62
63 HttpService->Signature = HTTP_SERVICE_SIGNATURE;
64 HttpService->ServiceBinding.CreateChild = HttpServiceBindingCreateChild;
65 HttpService->ServiceBinding.DestroyChild = HttpServiceBindingDestroyChild;
66 HttpService->ControllerHandle = Controller;
67 HttpService->ChildrenNumber = 0;
68 InitializeListHead (&HttpService->ChildrenList);
69
70 *ServiceData = HttpService;
71 return EFI_SUCCESS;
72 }
73
74 /**
75 Release all the resource used the HTTP service binding instance.
76
77 @param[in] HttpService The HTTP private instance.
78 @param[in] UsingIpv6 Indicate use TCP4 protocol or TCP6 protocol.
79 if TRUE, use Tcp6 protocol.
80 if FALSE, use Tcp4 protocol.
81 **/
82 VOID
83 HttpCleanService (
84 IN HTTP_SERVICE *HttpService,
85 IN BOOLEAN UsingIpv6
86 )
87 {
88 if (HttpService == NULL) {
89 return;
90 }
91
92 if (!UsingIpv6) {
93 if (HttpService->Tcp4ChildHandle != NULL) {
94 gBS->CloseProtocol (
95 HttpService->Tcp4ChildHandle,
96 &gEfiTcp4ProtocolGuid,
97 HttpService->Ip4DriverBindingHandle,
98 HttpService->ControllerHandle
99 );
100
101 NetLibDestroyServiceChild (
102 HttpService->ControllerHandle,
103 HttpService->Ip4DriverBindingHandle,
104 &gEfiTcp4ServiceBindingProtocolGuid,
105 HttpService->Tcp4ChildHandle
106 );
107
108 HttpService->Tcp4ChildHandle = NULL;
109 }
110 } else {
111 if (HttpService->Tcp6ChildHandle != NULL) {
112 gBS->CloseProtocol (
113 HttpService->Tcp6ChildHandle,
114 &gEfiTcp6ProtocolGuid,
115 HttpService->Ip6DriverBindingHandle,
116 HttpService->ControllerHandle
117 );
118
119 NetLibDestroyServiceChild (
120 HttpService->ControllerHandle,
121 HttpService->Ip6DriverBindingHandle,
122 &gEfiTcp6ServiceBindingProtocolGuid,
123 HttpService->Tcp6ChildHandle
124 );
125
126 HttpService->Tcp6ChildHandle = NULL;
127 }
128 }
129 }
130
131 /**
132 The event process routine when the http utilities protocol is installed
133 in the system.
134
135 @param[in] Event Not used.
136 @param[in] Context The pointer to the IP4 config2 instance data or IP6 Config instance data.
137
138 **/
139 VOID
140 EFIAPI
141 HttpUtilitiesInstalledCallback (
142 IN EFI_EVENT Event,
143 IN VOID *Context
144 )
145 {
146 gBS->LocateProtocol (
147 &gEfiHttpUtilitiesProtocolGuid,
148 NULL,
149 (VOID **)&mHttpUtilities
150 );
151
152 //
153 // Close the event if Http utilities protocol is located.
154 //
155 if ((mHttpUtilities != NULL) && (Event != NULL)) {
156 gBS->CloseEvent (Event);
157 }
158 }
159
160 /**
161 This is the declaration of an EFI image entry point. This entry point is
162 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
163 both device drivers and bus drivers.
164
165 @param ImageHandle The firmware allocated handle for the UEFI image.
166 @param SystemTable A pointer to the EFI System Table.
167
168 @retval EFI_SUCCESS The operation completed successfully.
169 @retval Others An unexpected error occurred.
170
171 **/
172 EFI_STATUS
173 EFIAPI
174 HttpDxeDriverEntryPoint (
175 IN EFI_HANDLE ImageHandle,
176 IN EFI_SYSTEM_TABLE *SystemTable
177 )
178 {
179 EFI_STATUS Status;
180 VOID *Registration;
181
182 gBS->LocateProtocol (
183 &gEfiHttpUtilitiesProtocolGuid,
184 NULL,
185 (VOID **)&mHttpUtilities
186 );
187
188 if (mHttpUtilities == NULL) {
189 //
190 // No Http utilities protocol, register a notify.
191 //
192 EfiCreateProtocolNotifyEvent (
193 &gEfiHttpUtilitiesProtocolGuid,
194 TPL_CALLBACK,
195 HttpUtilitiesInstalledCallback,
196 NULL,
197 &Registration
198 );
199 }
200
201 //
202 // Install UEFI Driver Model protocol(s).
203 //
204 Status = EfiLibInstallDriverBindingComponentName2 (
205 ImageHandle,
206 SystemTable,
207 &gHttpDxeIp4DriverBinding,
208 ImageHandle,
209 &gHttpDxeComponentName,
210 &gHttpDxeComponentName2
211 );
212 if (EFI_ERROR (Status)) {
213 return Status;
214 }
215
216 Status = EfiLibInstallDriverBindingComponentName2 (
217 ImageHandle,
218 SystemTable,
219 &gHttpDxeIp6DriverBinding,
220 NULL,
221 &gHttpDxeComponentName,
222 &gHttpDxeComponentName2
223 );
224 if (EFI_ERROR (Status)) {
225 EfiLibUninstallDriverBindingComponentName2 (
226 &gHttpDxeIp4DriverBinding,
227 &gHttpDxeComponentName,
228 &gHttpDxeComponentName2
229 );
230 }
231
232 return Status;
233 }
234
235 /**
236 Callback function which provided by user to remove one node in NetDestroyLinkList process.
237
238 @param[in] Entry The entry to be removed.
239 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
240
241 @retval EFI_INVALID_PARAMETER Any input parameter is NULL.
242 @retval EFI_SUCCESS The entry has been removed successfully.
243 @retval Others Fail to remove the entry.
244
245 **/
246 EFI_STATUS
247 EFIAPI
248 HttpDestroyChildEntryInHandleBuffer (
249 IN LIST_ENTRY *Entry,
250 IN VOID *Context
251 )
252 {
253 HTTP_PROTOCOL *HttpInstance;
254 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
255 UINTN NumberOfChildren;
256 EFI_HANDLE *ChildHandleBuffer;
257
258 if ((Entry == NULL) || (Context == NULL)) {
259 return EFI_INVALID_PARAMETER;
260 }
261
262 HttpInstance = NET_LIST_USER_STRUCT_S (Entry, HTTP_PROTOCOL, Link, HTTP_PROTOCOL_SIGNATURE);
263 ServiceBinding = ((HTTP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ServiceBinding;
264 NumberOfChildren = ((HTTP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->NumberOfChildren;
265 ChildHandleBuffer = ((HTTP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ChildHandleBuffer;
266
267 if (!NetIsInHandleBuffer (HttpInstance->Handle, NumberOfChildren, ChildHandleBuffer)) {
268 return EFI_SUCCESS;
269 }
270
271 return ServiceBinding->DestroyChild (ServiceBinding, HttpInstance->Handle);
272 }
273
274 /**
275 Test to see if this driver supports ControllerHandle. This is the worker function for
276 HttpDxeIp4(6)DriverBindingSupported.
277
278 @param[in] This The pointer to the driver binding protocol.
279 @param[in] ControllerHandle The handle of device to be tested.
280 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
281 device to be started.
282 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
283
284 @retval EFI_SUCCESS This driver supports this device.
285 @retval EFI_UNSUPPORTED This driver does not support this device.
286
287 **/
288 EFI_STATUS
289 EFIAPI
290 HttpDxeSupported (
291 IN EFI_DRIVER_BINDING_PROTOCOL *This,
292 IN EFI_HANDLE ControllerHandle,
293 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
294 IN UINT8 IpVersion
295 )
296 {
297 EFI_STATUS Status;
298 EFI_GUID *TcpServiceBindingProtocolGuid;
299
300 if (IpVersion == IP_VERSION_4) {
301 TcpServiceBindingProtocolGuid = &gEfiTcp4ServiceBindingProtocolGuid;
302 } else {
303 TcpServiceBindingProtocolGuid = &gEfiTcp6ServiceBindingProtocolGuid;
304 }
305
306 Status = gBS->OpenProtocol (
307 ControllerHandle,
308 TcpServiceBindingProtocolGuid,
309 NULL,
310 This->DriverBindingHandle,
311 ControllerHandle,
312 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
313 );
314
315 if (EFI_ERROR (Status)) {
316 return EFI_UNSUPPORTED;
317 }
318
319 return EFI_SUCCESS;
320 }
321
322 /**
323 Start this driver on ControllerHandle. This is the worker function for
324 HttpDxeIp4(6)DriverBindingStart.
325
326 @param[in] This The pointer to the driver binding protocol.
327 @param[in] ControllerHandle The handle of device to be started.
328 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
329 device to be started.
330 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
331
332
333 @retval EFI_SUCCESS This driver is installed to ControllerHandle.
334 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
335 @retval other This driver does not support this device.
336
337 **/
338 EFI_STATUS
339 EFIAPI
340 HttpDxeStart (
341 IN EFI_DRIVER_BINDING_PROTOCOL *This,
342 IN EFI_HANDLE ControllerHandle,
343 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
344 IN UINT8 IpVersion
345 )
346 {
347 EFI_STATUS Status;
348 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
349 HTTP_SERVICE *HttpService;
350 VOID *Interface;
351 BOOLEAN UsingIpv6;
352
353 UsingIpv6 = FALSE;
354
355 //
356 // Test for the Http service binding protocol
357 //
358 Status = gBS->OpenProtocol (
359 ControllerHandle,
360 &gEfiHttpServiceBindingProtocolGuid,
361 (VOID **)&ServiceBinding,
362 This->DriverBindingHandle,
363 ControllerHandle,
364 EFI_OPEN_PROTOCOL_GET_PROTOCOL
365 );
366
367 if (!EFI_ERROR (Status)) {
368 HttpService = HTTP_SERVICE_FROM_PROTOCOL (ServiceBinding);
369 } else {
370 Status = HttpCreateService (ControllerHandle, &HttpService);
371 if (EFI_ERROR (Status)) {
372 return Status;
373 }
374
375 ASSERT (HttpService != NULL);
376
377 //
378 // Install the HttpServiceBinding Protocol onto Controller
379 //
380 Status = gBS->InstallMultipleProtocolInterfaces (
381 &ControllerHandle,
382 &gEfiHttpServiceBindingProtocolGuid,
383 &HttpService->ServiceBinding,
384 NULL
385 );
386
387 if (EFI_ERROR (Status)) {
388 goto ON_ERROR;
389 }
390 }
391
392 if (IpVersion == IP_VERSION_4) {
393 HttpService->Ip4DriverBindingHandle = This->DriverBindingHandle;
394
395 if (HttpService->Tcp4ChildHandle == NULL) {
396 //
397 // Create a TCP4 child instance, but do not configure it. This will establish the parent-child relationship.
398 //
399 Status = NetLibCreateServiceChild (
400 ControllerHandle,
401 This->DriverBindingHandle,
402 &gEfiTcp4ServiceBindingProtocolGuid,
403 &HttpService->Tcp4ChildHandle
404 );
405
406 if (EFI_ERROR (Status)) {
407 goto ON_ERROR;
408 }
409
410 Status = gBS->OpenProtocol (
411 HttpService->Tcp4ChildHandle,
412 &gEfiTcp4ProtocolGuid,
413 &Interface,
414 This->DriverBindingHandle,
415 ControllerHandle,
416 EFI_OPEN_PROTOCOL_BY_DRIVER
417 );
418
419 if (EFI_ERROR (Status)) {
420 goto ON_ERROR;
421 }
422 } else {
423 return EFI_ALREADY_STARTED;
424 }
425 } else {
426 UsingIpv6 = TRUE;
427 HttpService->Ip6DriverBindingHandle = This->DriverBindingHandle;
428
429 if (HttpService->Tcp6ChildHandle == NULL) {
430 //
431 // Create a TCP6 child instance, but do not configure it. This will establish the parent-child relationship.
432 //
433 Status = NetLibCreateServiceChild (
434 ControllerHandle,
435 This->DriverBindingHandle,
436 &gEfiTcp6ServiceBindingProtocolGuid,
437 &HttpService->Tcp6ChildHandle
438 );
439
440 if (EFI_ERROR (Status)) {
441 goto ON_ERROR;
442 }
443
444 Status = gBS->OpenProtocol (
445 HttpService->Tcp6ChildHandle,
446 &gEfiTcp6ProtocolGuid,
447 &Interface,
448 This->DriverBindingHandle,
449 ControllerHandle,
450 EFI_OPEN_PROTOCOL_BY_DRIVER
451 );
452
453 if (EFI_ERROR (Status)) {
454 goto ON_ERROR;
455 }
456 } else {
457 return EFI_ALREADY_STARTED;
458 }
459 }
460
461 return EFI_SUCCESS;
462
463 ON_ERROR:
464
465 if (HttpService != NULL) {
466 HttpCleanService (HttpService, UsingIpv6);
467 if ((HttpService->Tcp4ChildHandle == NULL) && (HttpService->Tcp6ChildHandle == NULL)) {
468 FreePool (HttpService);
469 }
470 }
471
472 return Status;
473 }
474
475 /**
476 Stop this driver on ControllerHandle. This is the worker function for
477 HttpDxeIp4(6)DriverBindingStop.
478
479 @param[in] This Protocol instance pointer.
480 @param[in] ControllerHandle Handle of device to stop driver on.
481 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
482 children is zero stop the entire bus driver.
483 @param[in] ChildHandleBuffer List of Child Handles to Stop.
484 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
485
486 @retval EFI_SUCCESS This driver was removed ControllerHandle.
487 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
488 @retval Others This driver was not removed from this device
489
490 **/
491 EFI_STATUS
492 EFIAPI
493 HttpDxeStop (
494 IN EFI_DRIVER_BINDING_PROTOCOL *This,
495 IN EFI_HANDLE ControllerHandle,
496 IN UINTN NumberOfChildren,
497 IN EFI_HANDLE *ChildHandleBuffer,
498 IN UINT8 IpVersion
499 )
500 {
501 EFI_HANDLE NicHandle;
502 EFI_STATUS Status;
503 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
504 HTTP_SERVICE *HttpService;
505 LIST_ENTRY *List;
506 HTTP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
507 BOOLEAN UsingIpv6;
508
509 //
510 // HTTP driver opens TCP4(6) child, So, Controller is a TCP4(6)
511 // child handle. Locate the Nic handle first. Then get the
512 // HTTP private data back.
513 //
514 if (IpVersion == IP_VERSION_4) {
515 UsingIpv6 = FALSE;
516 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);
517 } else {
518 UsingIpv6 = TRUE;
519 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiTcp6ProtocolGuid);
520 }
521
522 if (NicHandle == NULL) {
523 return EFI_SUCCESS;
524 }
525
526 Status = gBS->OpenProtocol (
527 NicHandle,
528 &gEfiHttpServiceBindingProtocolGuid,
529 (VOID **)&ServiceBinding,
530 This->DriverBindingHandle,
531 NicHandle,
532 EFI_OPEN_PROTOCOL_GET_PROTOCOL
533 );
534
535 if (!EFI_ERROR (Status)) {
536 HttpService = HTTP_SERVICE_FROM_PROTOCOL (ServiceBinding);
537
538 if (NumberOfChildren != 0) {
539 //
540 // Destroy the HTTP child instance in ChildHandleBuffer.
541 //
542 List = &HttpService->ChildrenList;
543 Context.ServiceBinding = ServiceBinding;
544 Context.NumberOfChildren = NumberOfChildren;
545 Context.ChildHandleBuffer = ChildHandleBuffer;
546 Status = NetDestroyLinkList (
547 List,
548 HttpDestroyChildEntryInHandleBuffer,
549 &Context,
550 NULL
551 );
552 } else {
553 HttpCleanService (HttpService, UsingIpv6);
554
555 if ((HttpService->Tcp4ChildHandle == NULL) && (HttpService->Tcp6ChildHandle == NULL)) {
556 gBS->UninstallProtocolInterface (
557 NicHandle,
558 &gEfiHttpServiceBindingProtocolGuid,
559 ServiceBinding
560 );
561 FreePool (HttpService);
562 }
563
564 Status = EFI_SUCCESS;
565 }
566 }
567
568 return Status;
569 }
570
571 /**
572 Tests to see if this driver supports a given controller. If a child device is provided,
573 it further tests to see if this driver supports creating a handle for the specified child device.
574
575 This function checks to see if the driver specified by This supports the device specified by
576 ControllerHandle. Drivers will typically use the device path attached to
577 ControllerHandle and/or the services from the bus I/O abstraction attached to
578 ControllerHandle to determine if the driver supports ControllerHandle. This function
579 may be called many times during platform initialization. In order to reduce boot times, the tests
580 performed by this function must be very small, and take as little time as possible to execute. This
581 function must not change the state of any hardware devices, and this function must be aware that the
582 device specified by ControllerHandle may already be managed by the same driver or a
583 different driver. This function must match its calls to AllocatePages() with FreePages(),
584 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
585 Because ControllerHandle may have been previously started by the same driver, if a protocol is
586 already in the opened state, then it must not be closed with CloseProtocol(). This is required
587 to guarantee the state of ControllerHandle is not modified by this function.
588
589 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
590 @param[in] ControllerHandle The handle of the controller to test. This handle
591 must support a protocol interface that supplies
592 an I/O abstraction to the driver.
593 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
594 parameter is ignored by device drivers, and is optional for bus
595 drivers. For bus drivers, if this parameter is not NULL, then
596 the bus driver must determine if the bus controller specified
597 by ControllerHandle and the child controller specified
598 by RemainingDevicePath are both supported by this
599 bus driver.
600
601 @retval EFI_SUCCESS The device specified by ControllerHandle and
602 RemainingDevicePath is supported by the driver specified by This.
603 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
604 RemainingDevicePath is already being managed by the driver
605 specified by This.
606 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
607 RemainingDevicePath is already being managed by a different
608 driver or an application that requires exclusive access.
609 Currently not implemented.
610 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
611 RemainingDevicePath is not supported by the driver specified by This.
612 **/
613 EFI_STATUS
614 EFIAPI
615 HttpDxeIp4DriverBindingSupported (
616 IN EFI_DRIVER_BINDING_PROTOCOL *This,
617 IN EFI_HANDLE ControllerHandle,
618 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
619 )
620 {
621 return HttpDxeSupported (
622 This,
623 ControllerHandle,
624 RemainingDevicePath,
625 IP_VERSION_4
626 );
627 }
628
629 /**
630 Starts a device controller or a bus controller.
631
632 The Start() function is designed to be invoked from the EFI boot service ConnectController().
633 As a result, much of the error checking on the parameters to Start() has been moved into this
634 common boot service. It is legal to call Start() from other locations,
635 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
636 1. ControllerHandle must be a valid EFI_HANDLE.
637 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
638 EFI_DEVICE_PATH_PROTOCOL.
639 3. Prior to calling Start(), the Supported() function for the driver specified by This must
640 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
641
642 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
643 @param[in] ControllerHandle The handle of the controller to start. This handle
644 must support a protocol interface that supplies
645 an I/O abstraction to the driver.
646 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
647 parameter is ignored by device drivers, and is optional for bus
648 drivers. For a bus driver, if this parameter is NULL, then handles
649 for all the children of Controller are created by this driver.
650 If this parameter is not NULL and the first Device Path Node is
651 not the End of Device Path Node, then only the handle for the
652 child device specified by the first Device Path Node of
653 RemainingDevicePath is created by this driver.
654 If the first Device Path Node of RemainingDevicePath is
655 the End of Device Path Node, no child handle is created by this
656 driver.
657
658 @retval EFI_SUCCESS The device was started.
659 @retval EFI_ALREADY_STARTED This device is already running on ControllerHandle.
660 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
661 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
662 @retval Others The driver failed to start the device.
663
664 **/
665 EFI_STATUS
666 EFIAPI
667 HttpDxeIp4DriverBindingStart (
668 IN EFI_DRIVER_BINDING_PROTOCOL *This,
669 IN EFI_HANDLE ControllerHandle,
670 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
671 )
672 {
673 return HttpDxeStart (
674 This,
675 ControllerHandle,
676 RemainingDevicePath,
677 IP_VERSION_4
678 );
679 }
680
681 /**
682 Stops a device controller or a bus controller.
683
684 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
685 As a result, much of the error checking on the parameters to Stop() has been moved
686 into this common boot service. It is legal to call Stop() from other locations,
687 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
688 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
689 same driver's Start() function.
690 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
691 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
692 Start() function, and the Start() function must have called OpenProtocol() on
693 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
694
695 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
696 @param[in] ControllerHandle A handle to the device being stopped. The handle must
697 support a bus specific I/O protocol for the driver
698 to use to stop the device.
699 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
700 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
701 if NumberOfChildren is 0.
702
703 @retval EFI_SUCCESS The device was stopped.
704 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
705
706 **/
707 EFI_STATUS
708 EFIAPI
709 HttpDxeIp4DriverBindingStop (
710 IN EFI_DRIVER_BINDING_PROTOCOL *This,
711 IN EFI_HANDLE ControllerHandle,
712 IN UINTN NumberOfChildren,
713 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
714 )
715 {
716 return HttpDxeStop (
717 This,
718 ControllerHandle,
719 NumberOfChildren,
720 ChildHandleBuffer,
721 IP_VERSION_4
722 );
723 }
724
725 /**
726 Tests to see if this driver supports a given controller. If a child device is provided,
727 it further tests to see if this driver supports creating a handle for the specified child device.
728
729 This function checks to see if the driver specified by This supports the device specified by
730 ControllerHandle. Drivers will typically use the device path attached to
731 ControllerHandle and/or the services from the bus I/O abstraction attached to
732 ControllerHandle to determine if the driver supports ControllerHandle. This function
733 may be called many times during platform initialization. In order to reduce boot times, the tests
734 performed by this function must be very small, and take as little time as possible to execute. This
735 function must not change the state of any hardware devices, and this function must be aware that the
736 device specified by ControllerHandle may already be managed by the same driver or a
737 different driver. This function must match its calls to AllocatePages() with FreePages(),
738 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
739 Because ControllerHandle may have been previously started by the same driver, if a protocol is
740 already in the opened state, then it must not be closed with CloseProtocol(). This is required
741 to guarantee the state of ControllerHandle is not modified by this function.
742
743 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
744 @param[in] ControllerHandle The handle of the controller to test. This handle
745 must support a protocol interface that supplies
746 an I/O abstraction to the driver.
747 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
748 parameter is ignored by device drivers, and is optional for bus
749 drivers. For bus drivers, if this parameter is not NULL, then
750 the bus driver must determine if the bus controller specified
751 by ControllerHandle and the child controller specified
752 by RemainingDevicePath are both supported by this
753 bus driver.
754
755 @retval EFI_SUCCESS The device specified by ControllerHandle and
756 RemainingDevicePath is supported by the driver specified by This.
757 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
758 RemainingDevicePath is already being managed by the driver
759 specified by This.
760 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
761 RemainingDevicePath is already being managed by a different
762 driver or an application that requires exclusive access.
763 Currently not implemented.
764 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
765 RemainingDevicePath is not supported by the driver specified by This.
766 **/
767 EFI_STATUS
768 EFIAPI
769 HttpDxeIp6DriverBindingSupported (
770 IN EFI_DRIVER_BINDING_PROTOCOL *This,
771 IN EFI_HANDLE ControllerHandle,
772 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
773 )
774 {
775 return HttpDxeSupported (
776 This,
777 ControllerHandle,
778 RemainingDevicePath,
779 IP_VERSION_6
780 );
781 }
782
783 /**
784 Starts a device controller or a bus controller.
785
786 The Start() function is designed to be invoked from the EFI boot service ConnectController().
787 As a result, much of the error checking on the parameters to Start() has been moved into this
788 common boot service. It is legal to call Start() from other locations,
789 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
790 1. ControllerHandle must be a valid EFI_HANDLE.
791 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
792 EFI_DEVICE_PATH_PROTOCOL.
793 3. Prior to calling Start(), the Supported() function for the driver specified by This must
794 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
795
796 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
797 @param[in] ControllerHandle The handle of the controller to start. This handle
798 must support a protocol interface that supplies
799 an I/O abstraction to the driver.
800 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
801 parameter is ignored by device drivers, and is optional for bus
802 drivers. For a bus driver, if this parameter is NULL, then handles
803 for all the children of Controller are created by this driver.
804 If this parameter is not NULL and the first Device Path Node is
805 not the End of Device Path Node, then only the handle for the
806 child device specified by the first Device Path Node of
807 RemainingDevicePath is created by this driver.
808 If the first Device Path Node of RemainingDevicePath is
809 the End of Device Path Node, no child handle is created by this
810 driver.
811
812 @retval EFI_SUCCESS The device was started.
813 @retval EFI_ALREADY_STARTED This device is already running on ControllerHandle.
814 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
815 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
816 @retval Others The driver failed to start the device.
817
818 **/
819 EFI_STATUS
820 EFIAPI
821 HttpDxeIp6DriverBindingStart (
822 IN EFI_DRIVER_BINDING_PROTOCOL *This,
823 IN EFI_HANDLE ControllerHandle,
824 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
825 )
826 {
827 return HttpDxeStart (
828 This,
829 ControllerHandle,
830 RemainingDevicePath,
831 IP_VERSION_6
832 );
833 }
834
835 /**
836 Stops a device controller or a bus controller.
837
838 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
839 As a result, much of the error checking on the parameters to Stop() has been moved
840 into this common boot service. It is legal to call Stop() from other locations,
841 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
842 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
843 same driver's Start() function.
844 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
845 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
846 Start() function, and the Start() function must have called OpenProtocol() on
847 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
848
849 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
850 @param[in] ControllerHandle A handle to the device being stopped. The handle must
851 support a bus specific I/O protocol for the driver
852 to use to stop the device.
853 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
854 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
855 if NumberOfChildren is 0.
856
857 @retval EFI_SUCCESS The device was stopped.
858 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
859
860 **/
861 EFI_STATUS
862 EFIAPI
863 HttpDxeIp6DriverBindingStop (
864 IN EFI_DRIVER_BINDING_PROTOCOL *This,
865 IN EFI_HANDLE ControllerHandle,
866 IN UINTN NumberOfChildren,
867 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
868 )
869 {
870 return HttpDxeStop (
871 This,
872 ControllerHandle,
873 NumberOfChildren,
874 ChildHandleBuffer,
875 IP_VERSION_6
876 );
877 }
878
879 /**
880 Creates a child handle and installs a protocol.
881
882 The CreateChild() function installs a protocol on ChildHandle.
883 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
884 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
885
886 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
887 @param ChildHandle Pointer to the handle of the child to create. If it is NULL,
888 then a new handle is created. If it is a pointer to an existing UEFI handle,
889 then the protocol is added to the existing UEFI handle.
890
891 @retval EFI_SUCCESS The protocol was added to ChildHandle.
892 @retval EFI_INVALID_PARAMETER This is NULL, or ChildHandle is NULL.
893 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
894 the child.
895 @retval other The child handle was not created.
896
897 **/
898 EFI_STATUS
899 EFIAPI
900 HttpServiceBindingCreateChild (
901 IN EFI_SERVICE_BINDING_PROTOCOL *This,
902 IN OUT EFI_HANDLE *ChildHandle
903 )
904 {
905 HTTP_SERVICE *HttpService;
906 HTTP_PROTOCOL *HttpInstance;
907 EFI_STATUS Status;
908 EFI_TPL OldTpl;
909
910 if ((This == NULL) || (ChildHandle == NULL)) {
911 return EFI_INVALID_PARAMETER;
912 }
913
914 HttpService = HTTP_SERVICE_FROM_PROTOCOL (This);
915 HttpInstance = AllocateZeroPool (sizeof (HTTP_PROTOCOL));
916 if (HttpInstance == NULL) {
917 return EFI_OUT_OF_RESOURCES;
918 }
919
920 HttpInstance->Signature = HTTP_PROTOCOL_SIGNATURE;
921 HttpInstance->Service = HttpService;
922 HttpInstance->Method = HttpMethodMax;
923
924 CopyMem (&HttpInstance->Http, &mEfiHttpTemplate, sizeof (HttpInstance->Http));
925 NetMapInit (&HttpInstance->TxTokens);
926 NetMapInit (&HttpInstance->RxTokens);
927
928 //
929 // Install HTTP protocol onto ChildHandle
930 //
931 Status = gBS->InstallMultipleProtocolInterfaces (
932 ChildHandle,
933 &gEfiHttpProtocolGuid,
934 &HttpInstance->Http,
935 NULL
936 );
937
938 if (EFI_ERROR (Status)) {
939 goto ON_ERROR;
940 }
941
942 HttpInstance->Handle = *ChildHandle;
943
944 //
945 // Add it to the HTTP service's child list.
946 //
947 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
948
949 InsertTailList (&HttpService->ChildrenList, &HttpInstance->Link);
950 HttpService->ChildrenNumber++;
951
952 gBS->RestoreTPL (OldTpl);
953
954 return EFI_SUCCESS;
955
956 ON_ERROR:
957
958 NetMapClean (&HttpInstance->TxTokens);
959 NetMapClean (&HttpInstance->RxTokens);
960 FreePool (HttpInstance);
961
962 return Status;
963 }
964
965 /**
966 Destroys a child handle with a protocol installed on it.
967
968 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
969 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
970 last protocol on ChildHandle, then ChildHandle is destroyed.
971
972 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
973 @param ChildHandle Handle of the child to destroy
974
975 @retval EFI_SUCCESS The protocol was removed from ChildHandle.
976 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
977 @retval EFI_INVALID_PARAMETER Child handle is NULL.
978 @retval other The child handle was not destroyed
979
980 **/
981 EFI_STATUS
982 EFIAPI
983 HttpServiceBindingDestroyChild (
984 IN EFI_SERVICE_BINDING_PROTOCOL *This,
985 IN EFI_HANDLE ChildHandle
986 )
987 {
988 HTTP_SERVICE *HttpService;
989 HTTP_PROTOCOL *HttpInstance;
990 EFI_HTTP_PROTOCOL *Http;
991 EFI_STATUS Status;
992 EFI_TPL OldTpl;
993
994 if ((This == NULL) || (ChildHandle == NULL)) {
995 return EFI_INVALID_PARAMETER;
996 }
997
998 HttpService = HTTP_SERVICE_FROM_PROTOCOL (This);
999 Status = gBS->OpenProtocol (
1000 ChildHandle,
1001 &gEfiHttpProtocolGuid,
1002 (VOID **)&Http,
1003 NULL,
1004 NULL,
1005 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1006 );
1007 if (EFI_ERROR (Status)) {
1008 return EFI_UNSUPPORTED;
1009 }
1010
1011 HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (Http);
1012 if (HttpInstance->Service != HttpService) {
1013 return EFI_INVALID_PARAMETER;
1014 }
1015
1016 if (HttpInstance->InDestroy) {
1017 return EFI_SUCCESS;
1018 }
1019
1020 HttpInstance->InDestroy = TRUE;
1021
1022 //
1023 // Uninstall the HTTP protocol.
1024 //
1025 Status = gBS->UninstallProtocolInterface (
1026 ChildHandle,
1027 &gEfiHttpProtocolGuid,
1028 Http
1029 );
1030
1031 if (EFI_ERROR (Status)) {
1032 HttpInstance->InDestroy = FALSE;
1033 return Status;
1034 }
1035
1036 HttpCleanProtocol (HttpInstance);
1037
1038 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1039
1040 RemoveEntryList (&HttpInstance->Link);
1041 HttpService->ChildrenNumber--;
1042
1043 gBS->RestoreTPL (OldTpl);
1044
1045 FreePool (HttpInstance);
1046 return EFI_SUCCESS;
1047 }