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