TianoCore EDK2 master
Loading...
Searching...
No Matches
Udp4Driver.c
Go to the documentation of this file.
1
9#include "Udp4Impl.h"
10
11EFI_DRIVER_BINDING_PROTOCOL gUdp4DriverBinding = {
15 0xa,
16 NULL,
17 NULL
18};
19
20EFI_SERVICE_BINDING_PROTOCOL mUdp4ServiceBinding = {
23};
24
36EFIAPI
38 IN LIST_ENTRY *Entry,
39 IN VOID *Context
40 )
41{
42 UDP4_INSTANCE_DATA *Instance;
43 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
44 UINTN NumberOfChildren;
45 EFI_HANDLE *ChildHandleBuffer;
46
47 if ((Entry == NULL) || (Context == NULL)) {
48 return EFI_INVALID_PARAMETER;
49 }
50
51 Instance = NET_LIST_USER_STRUCT_S (Entry, UDP4_INSTANCE_DATA, Link, UDP4_INSTANCE_DATA_SIGNATURE);
52 ServiceBinding = ((UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ServiceBinding;
53 NumberOfChildren = ((UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->NumberOfChildren;
54 ChildHandleBuffer = ((UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ChildHandleBuffer;
55
56 if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, ChildHandleBuffer)) {
57 return EFI_SUCCESS;
58 }
59
60 return ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
61}
62
82EFIAPI
85 IN EFI_HANDLE ControllerHandle,
86 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
87 )
88{
89 EFI_STATUS Status;
90
91 //
92 // Test for the Udp4ServiceBinding Protocol
93 //
94 Status = gBS->OpenProtocol (
95 ControllerHandle,
96 &gEfiUdp4ServiceBindingProtocolGuid,
97 NULL,
98 This->DriverBindingHandle,
99 ControllerHandle,
100 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
101 );
102 if (!EFI_ERROR (Status)) {
103 return EFI_ALREADY_STARTED;
104 }
105
106 //
107 // Test for the Ip4 Protocol
108 //
109 Status = gBS->OpenProtocol (
110 ControllerHandle,
111 &gEfiIp4ServiceBindingProtocolGuid,
112 NULL,
113 This->DriverBindingHandle,
114 ControllerHandle,
115 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
116 );
117
118 return Status;
119}
120
140EFIAPI
143 IN EFI_HANDLE ControllerHandle,
144 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
145 )
146{
147 EFI_STATUS Status;
148 UDP4_SERVICE_DATA *Udp4Service;
149
150 //
151 // Allocate Private Context Data Structure.
152 //
153 Udp4Service = AllocatePool (sizeof (UDP4_SERVICE_DATA));
154 if (Udp4Service == NULL) {
155 return EFI_OUT_OF_RESOURCES;
156 }
157
158 Status = Udp4CreateService (Udp4Service, This->DriverBindingHandle, ControllerHandle);
159 if (EFI_ERROR (Status)) {
160 FreePool (Udp4Service);
161 return Status;
162 }
163
164 //
165 // Install the Udp4ServiceBindingProtocol on the ControllerHandle.
166 //
167 Status = gBS->InstallMultipleProtocolInterfaces (
168 &ControllerHandle,
169 &gEfiUdp4ServiceBindingProtocolGuid,
170 &Udp4Service->ServiceBinding,
171 NULL
172 );
173 if (EFI_ERROR (Status)) {
174 Udp4CleanService (Udp4Service);
175 FreePool (Udp4Service);
176 }
177
178 return Status;
179}
180
200EFIAPI
203 IN EFI_HANDLE ControllerHandle,
204 IN UINTN NumberOfChildren,
205 IN EFI_HANDLE *ChildHandleBuffer
206 )
207{
208 EFI_STATUS Status;
209 EFI_HANDLE NicHandle;
210 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
211 UDP4_SERVICE_DATA *Udp4Service;
213 LIST_ENTRY *List;
214
215 //
216 // Find the NicHandle where UDP4 ServiceBinding Protocol is installed.
217 //
218 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
219 if (NicHandle == NULL) {
220 return EFI_SUCCESS;
221 }
222
223 //
224 // Retrieve the UDP4 ServiceBinding Protocol.
225 //
226 Status = gBS->OpenProtocol (
227 NicHandle,
228 &gEfiUdp4ServiceBindingProtocolGuid,
229 (VOID **)&ServiceBinding,
230 This->DriverBindingHandle,
231 NicHandle,
232 EFI_OPEN_PROTOCOL_GET_PROTOCOL
233 );
234 if (EFI_ERROR (Status)) {
235 return EFI_DEVICE_ERROR;
236 }
237
238 Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (ServiceBinding);
239 if (NumberOfChildren != 0) {
240 //
241 // NumberOfChildren is not zero, destroy the children instances in ChildHandleBuffer.
242 //
243 List = &Udp4Service->ChildrenList;
244 Context.ServiceBinding = ServiceBinding;
245 Context.NumberOfChildren = NumberOfChildren;
246 Context.ChildHandleBuffer = ChildHandleBuffer;
247 Status = NetDestroyLinkList (
248 List,
250 &Context,
251 NULL
252 );
253 } else {
254 gBS->UninstallMultipleProtocolInterfaces (
255 NicHandle,
256 &gEfiUdp4ServiceBindingProtocolGuid,
257 &Udp4Service->ServiceBinding,
258 NULL
259 );
260
261 Udp4CleanService (Udp4Service);
262
263 if (gUdpControllerNameTable != NULL) {
264 FreeUnicodeStringTable (gUdpControllerNameTable);
265 gUdpControllerNameTable = NULL;
266 }
267
268 FreePool (Udp4Service);
269 }
270
271 return Status;
272}
273
294EFIAPI
297 IN EFI_HANDLE *ChildHandle
298 )
299{
300 EFI_STATUS Status;
301 UDP4_SERVICE_DATA *Udp4Service;
302 UDP4_INSTANCE_DATA *Instance;
303 EFI_TPL OldTpl;
304 VOID *Ip4;
305
306 if ((This == NULL) || (ChildHandle == NULL)) {
307 return EFI_INVALID_PARAMETER;
308 }
309
310 Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (This);
311
312 //
313 // Allocate the instance private data structure.
314 //
315 Instance = AllocateZeroPool (sizeof (UDP4_INSTANCE_DATA));
316 if (Instance == NULL) {
317 return EFI_OUT_OF_RESOURCES;
318 }
319
320 Udp4InitInstance (Udp4Service, Instance);
321
322 //
323 // Add an IpInfo for this instance.
324 //
325 Instance->IpInfo = IpIoAddIp (Udp4Service->IpIo);
326 if (Instance->IpInfo == NULL) {
327 Status = EFI_OUT_OF_RESOURCES;
328 goto ON_ERROR;
329 }
330
331 //
332 // Install the Udp4Protocol for this instance.
333 //
334 Status = gBS->InstallMultipleProtocolInterfaces (
335 ChildHandle,
336 &gEfiUdp4ProtocolGuid,
337 &Instance->Udp4Proto,
338 NULL
339 );
340 if (EFI_ERROR (Status)) {
341 goto ON_ERROR;
342 }
343
344 Instance->ChildHandle = *ChildHandle;
345
346 //
347 // Open the default Ip4 protocol in the IP_IO BY_CHILD.
348 //
349 Status = gBS->OpenProtocol (
350 Udp4Service->IpIo->ChildHandle,
351 &gEfiIp4ProtocolGuid,
352 (VOID **)&Ip4,
353 gUdp4DriverBinding.DriverBindingHandle,
354 Instance->ChildHandle,
355 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
356 );
357 if (EFI_ERROR (Status)) {
358 goto ON_ERROR;
359 }
360
361 //
362 // Open this instance's Ip4 protocol in the IpInfo BY_CHILD.
363 //
364 Status = gBS->OpenProtocol (
365 Instance->IpInfo->ChildHandle,
366 &gEfiIp4ProtocolGuid,
367 (VOID **)&Ip4,
368 gUdp4DriverBinding.DriverBindingHandle,
369 Instance->ChildHandle,
370 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
371 );
372 if (EFI_ERROR (Status)) {
373 goto ON_ERROR;
374 }
375
376 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
377
378 //
379 // Link this instance into the service context data and increase the ChildrenNumber.
380 //
381 InsertTailList (&Udp4Service->ChildrenList, &Instance->Link);
382 Udp4Service->ChildrenNumber++;
383
384 gBS->RestoreTPL (OldTpl);
385
386 return EFI_SUCCESS;
387
388ON_ERROR:
389
390 if (Instance->ChildHandle != NULL) {
391 gBS->UninstallMultipleProtocolInterfaces (
392 Instance->ChildHandle,
393 &gEfiUdp4ProtocolGuid,
394 &Instance->Udp4Proto,
395 NULL
396 );
397 }
398
399 if (Instance->IpInfo != NULL) {
400 IpIoRemoveIp (Udp4Service->IpIo, Instance->IpInfo);
401 }
402
403 Udp4CleanInstance (Instance);
404
405 FreePool (Instance);
406
407 return Status;
408}
409
429EFIAPI
432 IN EFI_HANDLE ChildHandle
433 )
434{
435 EFI_STATUS Status;
436 UDP4_SERVICE_DATA *Udp4Service;
437 EFI_UDP4_PROTOCOL *Udp4Proto;
438 UDP4_INSTANCE_DATA *Instance;
439 EFI_TPL OldTpl;
440
441 if ((This == NULL) || (ChildHandle == NULL)) {
442 return EFI_INVALID_PARAMETER;
443 }
444
445 Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (This);
446
447 //
448 // Try to get the Udp4 protocol from the ChildHandle.
449 //
450 Status = gBS->OpenProtocol (
451 ChildHandle,
452 &gEfiUdp4ProtocolGuid,
453 (VOID **)&Udp4Proto,
454 gUdp4DriverBinding.DriverBindingHandle,
455 ChildHandle,
456 EFI_OPEN_PROTOCOL_GET_PROTOCOL
457 );
458 if (EFI_ERROR (Status)) {
459 return EFI_UNSUPPORTED;
460 }
461
462 Instance = UDP4_INSTANCE_DATA_FROM_THIS (Udp4Proto);
463
464 if (Instance->InDestroy) {
465 return EFI_SUCCESS;
466 }
467
468 //
469 // Use the Destroyed flag to avoid the re-entering of the following code.
470 //
471 Instance->InDestroy = TRUE;
472
473 //
474 // Close the Ip4 protocol.
475 //
476 gBS->CloseProtocol (
477 Udp4Service->IpIo->ChildHandle,
478 &gEfiIp4ProtocolGuid,
479 gUdp4DriverBinding.DriverBindingHandle,
480 Instance->ChildHandle
481 );
482 //
483 // Close the Ip4 protocol on this instance's IpInfo.
484 //
485 gBS->CloseProtocol (
486 Instance->IpInfo->ChildHandle,
487 &gEfiIp4ProtocolGuid,
488 gUdp4DriverBinding.DriverBindingHandle,
489 Instance->ChildHandle
490 );
491
492 //
493 // Uninstall the Udp4Protocol previously installed on the ChildHandle.
494 //
495 Status = gBS->UninstallMultipleProtocolInterfaces (
496 ChildHandle,
497 &gEfiUdp4ProtocolGuid,
498 (VOID *)&Instance->Udp4Proto,
499 NULL
500 );
501 if (EFI_ERROR (Status)) {
502 Instance->InDestroy = FALSE;
503 return Status;
504 }
505
506 //
507 // Reset the configuration in case the instance's consumer forgets to do this.
508 //
509 Udp4Proto->Configure (Udp4Proto, NULL);
510
511 //
512 // Remove the IpInfo this instance consumes.
513 //
514 IpIoRemoveIp (Udp4Service->IpIo, Instance->IpInfo);
515
516 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
517
518 //
519 // Remove this instance from the service context data's ChildrenList.
520 //
521 RemoveEntryList (&Instance->Link);
522 Udp4Service->ChildrenNumber--;
523
524 //
525 // Clean the instance.
526 //
527 Udp4CleanInstance (Instance);
528
529 gBS->RestoreTPL (OldTpl);
530
531 FreePool (Instance);
532
533 return EFI_SUCCESS;
534}
535
552EFIAPI
554 IN EFI_HANDLE ImageHandle,
555 IN EFI_SYSTEM_TABLE *SystemTable
556 )
557{
558 EFI_STATUS Status;
559 UINT32 Random;
560
561 Status = PseudoRandomU32 (&Random);
562 if (EFI_ERROR (Status)) {
563 DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
564 return Status;
565 }
566
567 //
568 // Install the Udp4DriverBinding and Udp4ComponentName protocols.
569 //
571 ImageHandle,
572 SystemTable,
573 &gUdp4DriverBinding,
574 ImageHandle,
575 &gUdp4ComponentName,
576 &gUdp4ComponentName2
577 );
578 if (!EFI_ERROR (Status)) {
579 //
580 // Initialize the UDP random port.
581 //
582 mUdp4RandomPort = (UINT16)(((UINT16)Random) % UDP4_PORT_KNOWN + UDP4_PORT_KNOWN);
583 }
584
585 return Status;
586}
UINT64 UINTN
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 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
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_STATUS EFIAPI Udp4DriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: Udp4Driver.c:83
EFI_STATUS EFIAPI Udp4DriverEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: Udp4Driver.c:553
EFI_STATUS EFIAPI Udp4ServiceBindingDestroyChild(IN EFI_SERVICE_BINDING_PROTOCOL *This, IN EFI_HANDLE ChildHandle)
Definition: Udp4Driver.c:430
EFI_STATUS EFIAPI Udp4DriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: Udp4Driver.c:201
EFI_STATUS EFIAPI Udp4DriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: Udp4Driver.c:141
EFI_STATUS EFIAPI Udp4ServiceBindingCreateChild(IN EFI_SERVICE_BINDING_PROTOCOL *This, IN EFI_HANDLE *ChildHandle)
Definition: Udp4Driver.c:295
EFI_STATUS EFIAPI Udp4DestroyChildEntryInHandleBuffer(IN LIST_ENTRY *Entry, IN VOID *Context)
Definition: Udp4Driver.c:37
EFI_STATUS Udp4CreateService(IN OUT UDP4_SERVICE_DATA *Udp4Service, IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ControllerHandle)
Definition: Udp4Impl.c:262
VOID Udp4InitInstance(IN UDP4_SERVICE_DATA *Udp4Service, IN OUT UDP4_INSTANCE_DATA *Instance)
Definition: Udp4Impl.c:444
VOID Udp4CleanService(IN UDP4_SERVICE_DATA *Udp4Service)
Definition: Udp4Impl.c:355
VOID Udp4CleanInstance(IN UDP4_INSTANCE_DATA *Instance)
Definition: Udp4Impl.c:486
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)
EFI_STATUS EFIAPI FreeUnicodeStringTable(IN EFI_UNICODE_STRING_TABLE *UnicodeStringTable)
Definition: UefiLib.c:1257