]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/Udp6Dxe/Udp6Driver.c
NetworkPkg/Udp6Dxe: Fix various typos
[mirror_edk2.git] / NetworkPkg / Udp6Dxe / Udp6Driver.c
1 /** @file
2 Driver Binding functions and Service Binding functions for the Network driver module.
3
4 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "Udp6Impl.h"
11
12 EFI_DRIVER_BINDING_PROTOCOL gUdp6DriverBinding = {
13 Udp6DriverBindingSupported,
14 Udp6DriverBindingStart,
15 Udp6DriverBindingStop,
16 0xa,
17 NULL,
18 NULL
19 };
20
21 EFI_SERVICE_BINDING_PROTOCOL mUdp6ServiceBinding = {
22 Udp6ServiceBindingCreateChild,
23 Udp6ServiceBindingDestroyChild
24 };
25
26 /**
27 Tests to see if this driver supports a given controller. If a child device is provided,
28 it further tests to see if this driver supports creating a handle for the specified child device.
29
30 This function checks to see if the driver specified by This supports the device specified by
31 ControllerHandle. Drivers will typically use the device path attached to
32 ControllerHandle and/or the services from the bus I/O abstraction attached to
33 ControllerHandle to determine if the driver supports ControllerHandle. This function
34 may be called many times during platform initialization. In order to reduce boot times, the tests
35 performed by this function must be very small, and take as little time as possible to execute. This
36 function must not change the state of any hardware devices, and this function must be aware that the
37 device specified by ControllerHandle may already be managed by the same driver or a
38 different driver. This function must match its calls to AllocatePages() with FreePages(),
39 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
40 Because ControllerHandle may have been previously started by the same driver, if a protocol is
41 already in the opened state, then it must not be closed with CloseProtocol(). This is required
42 to guarantee the state of ControllerHandle is not modified by this function.
43
44 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
45 @param[in] ControllerHandle The handle of the controller to test. This handle
46 must support a protocol interface that supplies
47 an I/O abstraction to the driver.
48 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
49 parameter is ignored by device drivers, and is optional for bus
50 drivers. For bus drivers, if this parameter is not NULL, then
51 the bus driver must determine if the bus controller specified
52 by ControllerHandle and the child controller specified
53 by RemainingDevicePath are both supported by this
54 bus driver.
55
56 @retval EFI_SUCCESS The device specified by ControllerHandle and
57 RemainingDevicePath is supported by the driver specified by This.
58 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
59 RemainingDevicePath is already being managed by the driver
60 specified by This.
61 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
62 RemainingDevicePath is already being managed by a different
63 driver or an application that requires exclusive access.
64 Currently not implemented.
65 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
66 RemainingDevicePath is not supported by the driver specified by This.
67 **/
68 EFI_STATUS
69 EFIAPI
70 Udp6DriverBindingSupported (
71 IN EFI_DRIVER_BINDING_PROTOCOL *This,
72 IN EFI_HANDLE ControllerHandle,
73 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
74 )
75 {
76 EFI_STATUS Status;
77 //
78 // Test for the Udp6ServiceBinding Protocol
79 //
80 Status = gBS->OpenProtocol (
81 ControllerHandle,
82 &gEfiUdp6ServiceBindingProtocolGuid,
83 NULL,
84 This->DriverBindingHandle,
85 ControllerHandle,
86 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
87 );
88 if (!EFI_ERROR (Status)) {
89 return EFI_ALREADY_STARTED;
90 }
91 //
92 // Test for the Ip6ServiceBinding Protocol
93 //
94 Status = gBS->OpenProtocol (
95 ControllerHandle,
96 &gEfiIp6ServiceBindingProtocolGuid,
97 NULL,
98 This->DriverBindingHandle,
99 ControllerHandle,
100 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
101 );
102
103 return Status;
104 }
105
106 /**
107 Start this driver on ControllerHandle.
108
109 This service is called by the EFI boot service ConnectController(). In order to make
110 drivers as small as possible, there are a few calling restrictions for
111 this service. ConnectController() must follow these
112 calling restrictions. If any other agent wishes to call Start() it
113 must also follow these calling restrictions.
114
115 @param[in] This Protocol instance pointer.
116 @param[in] ControllerHandle Handle of device to bind the driver to.
117 @param[in] RemainingDevicePath Optional parameter use to pick a specific child
118 device to start.
119
120 @retval EFI_SUCCESS This driver is added to ControllerHandle.
121 @retval EFI_OUT_OF_RESOURCES The required system resource can't be allocated.
122 @retval other This driver does not support this device.
123
124 **/
125 EFI_STATUS
126 EFIAPI
127 Udp6DriverBindingStart (
128 IN EFI_DRIVER_BINDING_PROTOCOL *This,
129 IN EFI_HANDLE ControllerHandle,
130 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
131 )
132 {
133 EFI_STATUS Status;
134 UDP6_SERVICE_DATA *Udp6Service;
135
136 //
137 // Allocate Private Context Data Structure.
138 //
139 Udp6Service = AllocateZeroPool (sizeof (UDP6_SERVICE_DATA));
140 if (Udp6Service == NULL) {
141 Status = EFI_OUT_OF_RESOURCES;
142 goto EXIT;
143 }
144
145 Status = Udp6CreateService (Udp6Service, This->DriverBindingHandle, ControllerHandle);
146 if (EFI_ERROR (Status)) {
147 goto EXIT;
148 }
149
150 //
151 // Install the Udp6ServiceBindingProtocol on the ControllerHandle.
152 //
153 Status = gBS->InstallMultipleProtocolInterfaces (
154 &ControllerHandle,
155 &gEfiUdp6ServiceBindingProtocolGuid,
156 &Udp6Service->ServiceBinding,
157 NULL
158 );
159 if (EFI_ERROR (Status)) {
160 Udp6CleanService (Udp6Service);
161 }
162
163 EXIT:
164 if (EFI_ERROR (Status)) {
165 if (Udp6Service != NULL) {
166 FreePool (Udp6Service);
167 }
168 }
169 return Status;
170 }
171
172 /**
173 Callback function which provided by user to remove one node in NetDestroyLinkList process.
174
175 @param[in] Entry The entry to be removed.
176 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
177
178 @retval EFI_INVALID_PARAMETER Entry is NULL or Context is NULL.
179 @retval EFI_SUCCESS The entry has been removed successfully.
180 @retval Others Fail to remove the entry.
181
182 **/
183 EFI_STATUS
184 EFIAPI
185 Udp6DestroyChildEntryInHandleBuffer (
186 IN LIST_ENTRY *Entry,
187 IN VOID *Context
188 )
189 {
190 UDP6_INSTANCE_DATA *Instance;
191 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
192 UINTN NumberOfChildren;
193 EFI_HANDLE *ChildHandleBuffer;
194
195 if (Entry == NULL || Context == NULL) {
196 return EFI_INVALID_PARAMETER;
197 }
198
199 Instance = NET_LIST_USER_STRUCT_S (Entry, UDP6_INSTANCE_DATA, Link, UDP6_INSTANCE_DATA_SIGNATURE);
200 ServiceBinding = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
201 NumberOfChildren = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
202 ChildHandleBuffer = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
203
204 if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, ChildHandleBuffer)) {
205 return EFI_SUCCESS;
206 }
207
208 return ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
209 }
210
211 /**
212 Stop this driver on ControllerHandle.
213
214 This service is called by the EFI boot service DisconnectController(). In order to
215 make drivers as small as possible, there are a few calling
216 restrictions for this service. DisconnectController()
217 must follow these calling restrictions. If any other agent wishes
218 to call Stop(), it must also follow these calling restrictions.
219
220 @param[in] This Protocol instance pointer.
221 @param[in] ControllerHandle Handle of device to stop the driver on.
222 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If the number
223 of children is zero stop the entire bus driver.
224 @param[in] ChildHandleBuffer List of Child Handles to Stop. It is optional.
225
226 @retval EFI_SUCCESS This driver is removed ControllerHandle.
227 @retval EFI_DEVICE_ERROR Can't find the NicHandle from the ControllerHandle and specified GUID.
228 @retval other This driver was not removed from this device.
229
230 **/
231 EFI_STATUS
232 EFIAPI
233 Udp6DriverBindingStop (
234 IN EFI_DRIVER_BINDING_PROTOCOL *This,
235 IN EFI_HANDLE ControllerHandle,
236 IN UINTN NumberOfChildren,
237 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
238 )
239 {
240 EFI_STATUS Status;
241 EFI_HANDLE NicHandle;
242 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
243 UDP6_SERVICE_DATA *Udp6Service;
244 LIST_ENTRY *List;
245 UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
246
247 //
248 // Find the NicHandle where UDP6 ServiceBinding Protocol is installed.
249 //
250 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp6ProtocolGuid);
251 if (NicHandle == NULL) {
252 return EFI_SUCCESS;
253 }
254
255 //
256 // Retrieve the UDP6 ServiceBinding Protocol.
257 //
258 Status = gBS->OpenProtocol (
259 NicHandle,
260 &gEfiUdp6ServiceBindingProtocolGuid,
261 (VOID **) &ServiceBinding,
262 This->DriverBindingHandle,
263 NicHandle,
264 EFI_OPEN_PROTOCOL_GET_PROTOCOL
265 );
266 if (EFI_ERROR (Status)) {
267 return EFI_DEVICE_ERROR;
268 }
269
270 Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (ServiceBinding);
271
272 if (NumberOfChildren != 0) {
273 //
274 // NumberOfChildren is not zero, destroy the children instances in ChildHandleBuffer.
275 //
276 List = &Udp6Service->ChildrenList;
277 Context.ServiceBinding = ServiceBinding;
278 Context.NumberOfChildren = NumberOfChildren;
279 Context.ChildHandleBuffer = ChildHandleBuffer;
280 Status = NetDestroyLinkList (
281 List,
282 Udp6DestroyChildEntryInHandleBuffer,
283 &Context,
284 NULL
285 );
286 } else if (IsListEmpty (&Udp6Service->ChildrenList)) {
287 Status = gBS->UninstallMultipleProtocolInterfaces (
288 NicHandle,
289 &gEfiUdp6ServiceBindingProtocolGuid,
290 &Udp6Service->ServiceBinding,
291 NULL
292 );
293
294 Udp6CleanService (Udp6Service);
295 FreePool (Udp6Service);
296 }
297
298 return Status;
299 }
300
301 /**
302 Creates a child handle and installs a protocol.
303
304 The CreateChild() function installs a protocol on ChildHandle.
305 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
306 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
307
308 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
309 @param[in, out] ChildHandle Pointer to the handle of the child to create. If it is NULL,
310 then a new handle is created. If it is a pointer to an existing UEFI handle,
311 then the protocol is added to the existing UEFI handle.
312
313 @retval EFI_SUCCESS The protocol was added to ChildHandle.
314 @retval EFI_INVALID_PARAMETER This is NULL or ChildHandle is NULL.
315 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
316 the child.
317 @retval other The child handle was not created.
318
319 **/
320 EFI_STATUS
321 EFIAPI
322 Udp6ServiceBindingCreateChild (
323 IN EFI_SERVICE_BINDING_PROTOCOL *This,
324 IN OUT EFI_HANDLE *ChildHandle
325 )
326 {
327 EFI_STATUS Status;
328 UDP6_SERVICE_DATA *Udp6Service;
329 UDP6_INSTANCE_DATA *Instance;
330 EFI_TPL OldTpl;
331 VOID *Ip6;
332
333 if ((This == NULL) || (ChildHandle == NULL)) {
334 return EFI_INVALID_PARAMETER;
335 }
336
337 Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (This);
338
339 //
340 // Allocate the instance private data structure.
341 //
342 Instance = AllocateZeroPool (sizeof (UDP6_INSTANCE_DATA));
343 if (Instance == NULL) {
344 return EFI_OUT_OF_RESOURCES;
345 }
346
347 Udp6InitInstance (Udp6Service, Instance);
348
349 //
350 // Add an IpInfo for this instance.
351 //
352 Instance->IpInfo = IpIoAddIp (Udp6Service->IpIo);
353 if (Instance->IpInfo == NULL) {
354 Status = EFI_OUT_OF_RESOURCES;
355 goto ON_ERROR;
356 }
357
358 //
359 // Install the Udp6Protocol for this instance.
360 //
361 Status = gBS->InstallMultipleProtocolInterfaces (
362 ChildHandle,
363 &gEfiUdp6ProtocolGuid,
364 &Instance->Udp6Proto,
365 NULL
366 );
367 if (EFI_ERROR (Status)) {
368 goto ON_ERROR;
369 }
370
371 Instance->ChildHandle = *ChildHandle;
372
373 //
374 // Open the default Ip6 protocol in the IP_IO BY_CHILD.
375 //
376 Status = gBS->OpenProtocol (
377 Udp6Service->IpIo->ChildHandle,
378 &gEfiIp6ProtocolGuid,
379 (VOID **) &Ip6,
380 gUdp6DriverBinding.DriverBindingHandle,
381 Instance->ChildHandle,
382 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
383 );
384 if (EFI_ERROR (Status)) {
385 goto ON_ERROR;
386 }
387
388 //
389 // Open this instance's Ip6 protocol in the IpInfo BY_CHILD.
390 //
391 Status = gBS->OpenProtocol (
392 Instance->IpInfo->ChildHandle,
393 &gEfiIp6ProtocolGuid,
394 (VOID **) &Ip6,
395 gUdp6DriverBinding.DriverBindingHandle,
396 Instance->ChildHandle,
397 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
398 );
399 if (EFI_ERROR (Status)) {
400 goto ON_ERROR;
401 }
402
403 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
404
405 //
406 // Link this instance into the service context data and increase the ChildrenNumber.
407 //
408 InsertTailList (&Udp6Service->ChildrenList, &Instance->Link);
409 Udp6Service->ChildrenNumber++;
410
411 gBS->RestoreTPL (OldTpl);
412
413 return EFI_SUCCESS;
414
415 ON_ERROR:
416
417 if (Instance->ChildHandle != NULL) {
418 gBS->UninstallMultipleProtocolInterfaces (
419 Instance->ChildHandle,
420 &gEfiUdp6ProtocolGuid,
421 &Instance->Udp6Proto,
422 NULL
423 );
424 }
425
426 if (Instance->IpInfo != NULL) {
427 IpIoRemoveIp (Udp6Service->IpIo, Instance->IpInfo);
428 }
429
430 Udp6CleanInstance (Instance);
431
432 FreePool (Instance);
433
434 return Status;
435 }
436
437 /**
438 Destroys a child handle with a set of I/O services.
439 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
440 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
441 last protocol on ChildHandle, then ChildHandle is destroyed.
442
443 @param[in] This Protocol instance pointer.
444 @param[in] ChildHandle Handle of the child to destroy.
445
446 @retval EFI_SUCCESS The I/O services were removed from the child
447 handle.
448 @retval EFI_UNSUPPORTED The child handle does not support the I/O services
449 that are being removed.
450 @retval EFI_INVALID_PARAMETER Child handle is NULL.
451 @retval EFI_ACCESS_DENIED The child handle could not be destroyed because
452 its I/O services are being used.
453 @retval other The child handle was not destroyed.
454
455 **/
456 EFI_STATUS
457 EFIAPI
458 Udp6ServiceBindingDestroyChild (
459 IN EFI_SERVICE_BINDING_PROTOCOL *This,
460 IN EFI_HANDLE ChildHandle
461 )
462 {
463 EFI_STATUS Status;
464 UDP6_SERVICE_DATA *Udp6Service;
465 EFI_UDP6_PROTOCOL *Udp6Proto;
466 UDP6_INSTANCE_DATA *Instance;
467 EFI_TPL OldTpl;
468
469 if ((This == NULL) || (ChildHandle == NULL)) {
470 return EFI_INVALID_PARAMETER;
471 }
472
473 Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (This);
474
475 //
476 // Try to get the Udp6 protocol from the ChildHandle.
477 //
478 Status = gBS->OpenProtocol (
479 ChildHandle,
480 &gEfiUdp6ProtocolGuid,
481 (VOID **) &Udp6Proto,
482 gUdp6DriverBinding.DriverBindingHandle,
483 ChildHandle,
484 EFI_OPEN_PROTOCOL_GET_PROTOCOL
485 );
486 if (EFI_ERROR (Status)) {
487 return EFI_UNSUPPORTED;
488 }
489
490 Instance = UDP6_INSTANCE_DATA_FROM_THIS (Udp6Proto);
491
492 if (Instance->InDestroy) {
493 return EFI_SUCCESS;
494 }
495
496 //
497 // Use the Destroyed flag to avoid the re-entering of the following code.
498 //
499 Instance->InDestroy = TRUE;
500
501 //
502 // Close the Ip6 protocol on the default IpIo.
503 //
504 Status = gBS->CloseProtocol (
505 Udp6Service->IpIo->ChildHandle,
506 &gEfiIp6ProtocolGuid,
507 gUdp6DriverBinding.DriverBindingHandle,
508 Instance->ChildHandle
509 );
510 if (EFI_ERROR (Status)) {
511 Instance->InDestroy = FALSE;
512 return Status;
513 }
514
515 //
516 // Close the Ip6 protocol on this instance's IpInfo.
517 //
518 Status = gBS->CloseProtocol (
519 Instance->IpInfo->ChildHandle,
520 &gEfiIp6ProtocolGuid,
521 gUdp6DriverBinding.DriverBindingHandle,
522 Instance->ChildHandle
523 );
524 if (EFI_ERROR (Status)) {
525 Instance->InDestroy = FALSE;
526 return Status;
527 }
528
529 //
530 // Uninstall the Udp6Protocol previously installed on the ChildHandle.
531 //
532 Status = gBS->UninstallMultipleProtocolInterfaces (
533 ChildHandle,
534 &gEfiUdp6ProtocolGuid,
535 (VOID *) &Instance->Udp6Proto,
536 NULL
537 );
538 if (EFI_ERROR (Status)) {
539 Instance->InDestroy = FALSE;
540 return Status;
541 }
542
543 //
544 // Reset the configuration in case the instance's consumer forgets to do this.
545 //
546 Udp6Proto->Configure (Udp6Proto, NULL);
547
548 //
549 // Remove the IpInfo this instance consumes.
550 //
551 IpIoRemoveIp (Udp6Service->IpIo, Instance->IpInfo);
552
553 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
554
555 //
556 // Remove this instance from the service context data's ChildrenList.
557 //
558 RemoveEntryList (&Instance->Link);
559 Udp6Service->ChildrenNumber--;
560
561 //
562 // Clean the instance.
563 //
564 Udp6CleanInstance (Instance);
565
566 gBS->RestoreTPL (OldTpl);
567
568 FreePool (Instance);
569
570 return EFI_SUCCESS;
571 }
572
573 /**
574 This is the declaration of an EFI image entry point. This entry point is
575 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
576 both device drivers and bus drivers.
577
578 The entry point for Udp6 driver that installs the driver binding
579 and component name protocol on its ImageHandle.
580
581 @param[in] ImageHandle The firmware allocated handle for the UEFI image.
582 @param[in] SystemTable A pointer to the EFI System Table.
583
584 @retval EFI_SUCCESS The operation completed successfully.
585 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
586
587 **/
588 EFI_STATUS
589 EFIAPI
590 Udp6DriverEntryPoint (
591 IN EFI_HANDLE ImageHandle,
592 IN EFI_SYSTEM_TABLE *SystemTable
593 )
594 {
595 EFI_STATUS Status;
596
597 //
598 // Install the Udp6DriverBinding and Udp6ComponentName protocols.
599 //
600
601 Status = EfiLibInstallDriverBindingComponentName2 (
602 ImageHandle,
603 SystemTable,
604 &gUdp6DriverBinding,
605 ImageHandle,
606 &gUdp6ComponentName,
607 &gUdp6ComponentName2
608 );
609 if (!EFI_ERROR (Status)) {
610 //
611 // Initialize the UDP random port.
612 //
613 mUdp6RandomPort = (UINT16)(
614 ((UINT16) NetRandomInitSeed ()) %
615 UDP6_PORT_KNOWN +
616 UDP6_PORT_KNOWN
617 );
618 }
619
620 return Status;
621 }
622
623