TianoCore EDK2 master
Loading...
Searching...
No Matches
Udp6Driver.c
Go to the documentation of this file.
1
10#include "Udp6Impl.h"
11
12EFI_DRIVER_BINDING_PROTOCOL gUdp6DriverBinding = {
16 0xa,
17 NULL,
18 NULL
19};
20
21EFI_SERVICE_BINDING_PROTOCOL mUdp6ServiceBinding = {
24};
25
69EFIAPI
72 IN EFI_HANDLE ControllerHandle,
73 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
74 )
75{
76 EFI_STATUS Status;
77
78 //
79 // Test for the Udp6ServiceBinding Protocol
80 //
81 Status = gBS->OpenProtocol (
82 ControllerHandle,
83 &gEfiUdp6ServiceBindingProtocolGuid,
84 NULL,
85 This->DriverBindingHandle,
86 ControllerHandle,
87 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
88 );
89 if (!EFI_ERROR (Status)) {
90 return EFI_ALREADY_STARTED;
91 }
92
93 //
94 // Test for the Ip6ServiceBinding Protocol
95 //
96 Status = gBS->OpenProtocol (
97 ControllerHandle,
98 &gEfiIp6ServiceBindingProtocolGuid,
99 NULL,
100 This->DriverBindingHandle,
101 ControllerHandle,
102 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
103 );
104
105 return Status;
106}
107
128EFIAPI
131 IN EFI_HANDLE ControllerHandle,
132 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
133 )
134{
135 EFI_STATUS Status;
136 UDP6_SERVICE_DATA *Udp6Service;
137
138 //
139 // Allocate Private Context Data Structure.
140 //
141 Udp6Service = AllocateZeroPool (sizeof (UDP6_SERVICE_DATA));
142 if (Udp6Service == NULL) {
143 Status = EFI_OUT_OF_RESOURCES;
144 goto EXIT;
145 }
146
147 Status = Udp6CreateService (Udp6Service, This->DriverBindingHandle, ControllerHandle);
148 if (EFI_ERROR (Status)) {
149 goto EXIT;
150 }
151
152 //
153 // Install the Udp6ServiceBindingProtocol on the ControllerHandle.
154 //
155 Status = gBS->InstallMultipleProtocolInterfaces (
156 &ControllerHandle,
157 &gEfiUdp6ServiceBindingProtocolGuid,
158 &Udp6Service->ServiceBinding,
159 NULL
160 );
161 if (EFI_ERROR (Status)) {
162 Udp6CleanService (Udp6Service);
163 }
164
165EXIT:
166 if (EFI_ERROR (Status)) {
167 if (Udp6Service != NULL) {
168 FreePool (Udp6Service);
169 }
170 }
171
172 return Status;
173}
174
187EFIAPI
189 IN LIST_ENTRY *Entry,
190 IN VOID *Context
191 )
192{
193 UDP6_INSTANCE_DATA *Instance;
194 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
195 UINTN NumberOfChildren;
196 EFI_HANDLE *ChildHandleBuffer;
197
198 if ((Entry == NULL) || (Context == NULL)) {
199 return EFI_INVALID_PARAMETER;
200 }
201
202 Instance = NET_LIST_USER_STRUCT_S (Entry, UDP6_INSTANCE_DATA, Link, UDP6_INSTANCE_DATA_SIGNATURE);
203 ServiceBinding = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ServiceBinding;
204 NumberOfChildren = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->NumberOfChildren;
205 ChildHandleBuffer = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ChildHandleBuffer;
206
207 if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, ChildHandleBuffer)) {
208 return EFI_SUCCESS;
209 }
210
211 return ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
212}
213
235EFIAPI
238 IN EFI_HANDLE ControllerHandle,
239 IN UINTN NumberOfChildren,
240 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
241 )
242{
243 EFI_STATUS Status;
244 EFI_HANDLE NicHandle;
245 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
246 UDP6_SERVICE_DATA *Udp6Service;
247 LIST_ENTRY *List;
249
250 //
251 // Find the NicHandle where UDP6 ServiceBinding Protocol is installed.
252 //
253 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp6ProtocolGuid);
254 if (NicHandle == NULL) {
255 return EFI_SUCCESS;
256 }
257
258 //
259 // Retrieve the UDP6 ServiceBinding Protocol.
260 //
261 Status = gBS->OpenProtocol (
262 NicHandle,
263 &gEfiUdp6ServiceBindingProtocolGuid,
264 (VOID **)&ServiceBinding,
265 This->DriverBindingHandle,
266 NicHandle,
267 EFI_OPEN_PROTOCOL_GET_PROTOCOL
268 );
269 if (EFI_ERROR (Status)) {
270 return EFI_DEVICE_ERROR;
271 }
272
273 Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (ServiceBinding);
274
275 if (NumberOfChildren != 0) {
276 //
277 // NumberOfChildren is not zero, destroy the children instances in ChildHandleBuffer.
278 //
279 List = &Udp6Service->ChildrenList;
280 Context.ServiceBinding = ServiceBinding;
281 Context.NumberOfChildren = NumberOfChildren;
282 Context.ChildHandleBuffer = ChildHandleBuffer;
283 Status = NetDestroyLinkList (
284 List,
286 &Context,
287 NULL
288 );
289 } else if (IsListEmpty (&Udp6Service->ChildrenList)) {
290 Status = gBS->UninstallMultipleProtocolInterfaces (
291 NicHandle,
292 &gEfiUdp6ServiceBindingProtocolGuid,
293 &Udp6Service->ServiceBinding,
294 NULL
295 );
296
297 Udp6CleanService (Udp6Service);
298 FreePool (Udp6Service);
299 }
300
301 return Status;
302}
303
324EFIAPI
327 IN OUT EFI_HANDLE *ChildHandle
328 )
329{
330 EFI_STATUS Status;
331 UDP6_SERVICE_DATA *Udp6Service;
332 UDP6_INSTANCE_DATA *Instance;
333 EFI_TPL OldTpl;
334 VOID *Ip6;
335
336 if ((This == NULL) || (ChildHandle == NULL)) {
337 return EFI_INVALID_PARAMETER;
338 }
339
340 Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (This);
341
342 //
343 // Allocate the instance private data structure.
344 //
345 Instance = AllocateZeroPool (sizeof (UDP6_INSTANCE_DATA));
346 if (Instance == NULL) {
347 return EFI_OUT_OF_RESOURCES;
348 }
349
350 Udp6InitInstance (Udp6Service, Instance);
351
352 //
353 // Add an IpInfo for this instance.
354 //
355 Instance->IpInfo = IpIoAddIp (Udp6Service->IpIo);
356 if (Instance->IpInfo == NULL) {
357 Status = EFI_OUT_OF_RESOURCES;
358 goto ON_ERROR;
359 }
360
361 //
362 // Install the Udp6Protocol for this instance.
363 //
364 Status = gBS->InstallMultipleProtocolInterfaces (
365 ChildHandle,
366 &gEfiUdp6ProtocolGuid,
367 &Instance->Udp6Proto,
368 NULL
369 );
370 if (EFI_ERROR (Status)) {
371 goto ON_ERROR;
372 }
373
374 Instance->ChildHandle = *ChildHandle;
375
376 //
377 // Open the default Ip6 protocol in the IP_IO BY_CHILD.
378 //
379 Status = gBS->OpenProtocol (
380 Udp6Service->IpIo->ChildHandle,
381 &gEfiIp6ProtocolGuid,
382 (VOID **)&Ip6,
383 gUdp6DriverBinding.DriverBindingHandle,
384 Instance->ChildHandle,
385 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
386 );
387 if (EFI_ERROR (Status)) {
388 goto ON_ERROR;
389 }
390
391 //
392 // Open this instance's Ip6 protocol in the IpInfo BY_CHILD.
393 //
394 Status = gBS->OpenProtocol (
395 Instance->IpInfo->ChildHandle,
396 &gEfiIp6ProtocolGuid,
397 (VOID **)&Ip6,
398 gUdp6DriverBinding.DriverBindingHandle,
399 Instance->ChildHandle,
400 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
401 );
402 if (EFI_ERROR (Status)) {
403 goto ON_ERROR;
404 }
405
406 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
407
408 //
409 // Link this instance into the service context data and increase the ChildrenNumber.
410 //
411 InsertTailList (&Udp6Service->ChildrenList, &Instance->Link);
412 Udp6Service->ChildrenNumber++;
413
414 gBS->RestoreTPL (OldTpl);
415
416 return EFI_SUCCESS;
417
418ON_ERROR:
419
420 if (Instance->ChildHandle != NULL) {
421 gBS->UninstallMultipleProtocolInterfaces (
422 Instance->ChildHandle,
423 &gEfiUdp6ProtocolGuid,
424 &Instance->Udp6Proto,
425 NULL
426 );
427 }
428
429 if (Instance->IpInfo != NULL) {
430 IpIoRemoveIp (Udp6Service->IpIo, Instance->IpInfo);
431 }
432
433 Udp6CleanInstance (Instance);
434
435 FreePool (Instance);
436
437 return Status;
438}
439
460EFIAPI
463 IN EFI_HANDLE ChildHandle
464 )
465{
466 EFI_STATUS Status;
467 UDP6_SERVICE_DATA *Udp6Service;
468 EFI_UDP6_PROTOCOL *Udp6Proto;
469 UDP6_INSTANCE_DATA *Instance;
470 EFI_TPL OldTpl;
471
472 if ((This == NULL) || (ChildHandle == NULL)) {
473 return EFI_INVALID_PARAMETER;
474 }
475
476 Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (This);
477
478 //
479 // Try to get the Udp6 protocol from the ChildHandle.
480 //
481 Status = gBS->OpenProtocol (
482 ChildHandle,
483 &gEfiUdp6ProtocolGuid,
484 (VOID **)&Udp6Proto,
485 gUdp6DriverBinding.DriverBindingHandle,
486 ChildHandle,
487 EFI_OPEN_PROTOCOL_GET_PROTOCOL
488 );
489 if (EFI_ERROR (Status)) {
490 return EFI_UNSUPPORTED;
491 }
492
493 Instance = UDP6_INSTANCE_DATA_FROM_THIS (Udp6Proto);
494
495 if (Instance->InDestroy) {
496 return EFI_SUCCESS;
497 }
498
499 //
500 // Use the Destroyed flag to avoid the re-entering of the following code.
501 //
502 Instance->InDestroy = TRUE;
503
504 //
505 // Close the Ip6 protocol on the default IpIo.
506 //
507 Status = gBS->CloseProtocol (
508 Udp6Service->IpIo->ChildHandle,
509 &gEfiIp6ProtocolGuid,
510 gUdp6DriverBinding.DriverBindingHandle,
511 Instance->ChildHandle
512 );
513 if (EFI_ERROR (Status)) {
514 Instance->InDestroy = FALSE;
515 return Status;
516 }
517
518 //
519 // Close the Ip6 protocol on this instance's IpInfo.
520 //
521 Status = gBS->CloseProtocol (
522 Instance->IpInfo->ChildHandle,
523 &gEfiIp6ProtocolGuid,
524 gUdp6DriverBinding.DriverBindingHandle,
525 Instance->ChildHandle
526 );
527 if (EFI_ERROR (Status)) {
528 Instance->InDestroy = FALSE;
529 return Status;
530 }
531
532 //
533 // Uninstall the Udp6Protocol previously installed on the ChildHandle.
534 //
535 Status = gBS->UninstallMultipleProtocolInterfaces (
536 ChildHandle,
537 &gEfiUdp6ProtocolGuid,
538 (VOID *)&Instance->Udp6Proto,
539 NULL
540 );
541 if (EFI_ERROR (Status)) {
542 Instance->InDestroy = FALSE;
543 return Status;
544 }
545
546 //
547 // Reset the configuration in case the instance's consumer forgets to do this.
548 //
549 Udp6Proto->Configure (Udp6Proto, NULL);
550
551 //
552 // Remove the IpInfo this instance consumes.
553 //
554 IpIoRemoveIp (Udp6Service->IpIo, Instance->IpInfo);
555
556 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
557
558 //
559 // Remove this instance from the service context data's ChildrenList.
560 //
561 RemoveEntryList (&Instance->Link);
562 Udp6Service->ChildrenNumber--;
563
564 //
565 // Clean the instance.
566 //
567 Udp6CleanInstance (Instance);
568
569 gBS->RestoreTPL (OldTpl);
570
571 FreePool (Instance);
572
573 return EFI_SUCCESS;
574}
575
592EFIAPI
594 IN EFI_HANDLE ImageHandle,
595 IN EFI_SYSTEM_TABLE *SystemTable
596 )
597{
598 EFI_STATUS Status;
599 UINT32 Random;
600
601 Status = PseudoRandomU32 (&Random);
602 if (EFI_ERROR (Status)) {
603 DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
604 return Status;
605 }
606
607 //
608 // Install the Udp6DriverBinding and Udp6ComponentName protocols.
609 //
610
612 ImageHandle,
613 SystemTable,
614 &gUdp6DriverBinding,
615 ImageHandle,
616 &gUdp6ComponentName,
617 &gUdp6ComponentName2
618 );
619 if (!EFI_ERROR (Status)) {
620 //
621 // Initialize the UDP random port.
622 //
623 mUdp6RandomPort = (UINT16)(
624 ((UINT16)Random) %
625 UDP6_PORT_KNOWN +
626 UDP6_PORT_KNOWN
627 );
628 }
629
630 return Status;
631}
UINT64 UINTN
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID EFIAPI IpIoRemoveIp(IN IP_IO *IpIo, IN IP_IO_IP_INFO *IpInfo)
Definition: DxeIpIoLib.c:1968
IP_IO_IP_INFO *EFIAPI IpIoAddIp(IN OUT IP_IO *IpIo)
Definition: DxeIpIoLib.c:1700
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
BOOLEAN EFIAPI NetIsInHandleBuffer(IN EFI_HANDLE Handle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer OPTIONAL)
Definition: DxeNetLib.c:1306
EFI_STATUS EFIAPI PseudoRandomU32(OUT UINT32 *Output)
Definition: DxeNetLib.c:1011
EFI_HANDLE EFIAPI NetLibGetNicHandle(IN EFI_HANDLE Controller, IN EFI_GUID *ProtocolGuid)
Definition: DxeNetLib.c:3019
EFI_STATUS EFIAPI NetDestroyLinkList(IN LIST_ENTRY *List, IN NET_DESTROY_LINK_LIST_CALLBACK CallBack, IN VOID *Context OPTIONAL, OUT UINTN *ListLength OPTIONAL)
Definition: DxeNetLib.c:1236
EFI_STATUS EFIAPI Udp6ServiceBindingCreateChild(IN EFI_SERVICE_BINDING_PROTOCOL *This, IN OUT EFI_HANDLE *ChildHandle)
Definition: Udp6Driver.c:325
EFI_STATUS EFIAPI Udp6DriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: Udp6Driver.c:70
EFI_STATUS EFIAPI Udp6ServiceBindingDestroyChild(IN EFI_SERVICE_BINDING_PROTOCOL *This, IN EFI_HANDLE ChildHandle)
Definition: Udp6Driver.c:461
EFI_STATUS EFIAPI Udp6DriverEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: Udp6Driver.c:593
EFI_STATUS EFIAPI Udp6DriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: Udp6Driver.c:129
EFI_STATUS EFIAPI Udp6DestroyChildEntryInHandleBuffer(IN LIST_ENTRY *Entry, IN VOID *Context)
Definition: Udp6Driver.c:188
EFI_STATUS EFIAPI Udp6DriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer OPTIONAL)
Definition: Udp6Driver.c:236
EFI_STATUS Udp6CreateService(IN UDP6_SERVICE_DATA *Udp6Service, IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ControllerHandle)
Definition: Udp6Impl.c:285
VOID Udp6CleanInstance(IN OUT UDP6_INSTANCE_DATA *Instance)
Definition: Udp6Impl.c:507
VOID Udp6InitInstance(IN UDP6_SERVICE_DATA *Udp6Service, IN OUT UDP6_INSTANCE_DATA *Instance)
Definition: Udp6Impl.c:465
VOID Udp6CleanService(IN OUT UDP6_SERVICE_DATA *Udp6Service)
Definition: Udp6Impl.c:380
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
UINTN EFI_TPL
Definition: UefiBaseType.h:41
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)