EDK2 doxygen online documents - Firmware Encoding Index 1
EDK2 doxygen online documents - Firmware Encoding Index

NetworkPkg/Udp6Dxe/Udp6Driver.c

Go to the documentation of this file.
00001 
00016 #include "Udp6Impl.h"
00017 
00018 EFI_DRIVER_BINDING_PROTOCOL gUdp6DriverBinding = {
00019   Udp6DriverBindingSupported,
00020   Udp6DriverBindingStart,
00021   Udp6DriverBindingStop,
00022   0xa,
00023   NULL,
00024   NULL
00025 };
00026 
00027 EFI_SERVICE_BINDING_PROTOCOL mUdp6ServiceBinding = {
00028   Udp6ServiceBindingCreateChild,
00029   Udp6ServiceBindingDestroyChild
00030 };
00031 
00074 EFI_STATUS
00075 EFIAPI
00076 Udp6DriverBindingSupported (
00077   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
00078   IN EFI_HANDLE                   ControllerHandle,
00079   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath  OPTIONAL
00080   )
00081 {
00082   EFI_STATUS  Status;
00083   //
00084   // Test for the Udp6ServiceBinding Protocol
00085   //
00086   Status = gBS->OpenProtocol (
00087                   ControllerHandle,
00088                   &gEfiUdp6ServiceBindingProtocolGuid,
00089                   NULL,
00090                   This->DriverBindingHandle,
00091                   ControllerHandle,
00092                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL
00093                   );
00094   if (!EFI_ERROR (Status)) {
00095     return EFI_ALREADY_STARTED;
00096   }
00097   //
00098   // Test for the Ip6ServiceBinding Protocol
00099   //
00100   Status = gBS->OpenProtocol (
00101                   ControllerHandle,
00102                   &gEfiIp6ServiceBindingProtocolGuid,
00103                   NULL,
00104                   This->DriverBindingHandle,
00105                   ControllerHandle,
00106                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL
00107                   );
00108 
00109   return Status;
00110 }
00111 
00131 EFI_STATUS
00132 EFIAPI
00133 Udp6DriverBindingStart (
00134   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
00135   IN EFI_HANDLE                   ControllerHandle,
00136   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath  OPTIONAL
00137   )
00138 {
00139   EFI_STATUS         Status;
00140   UDP6_SERVICE_DATA  *Udp6Service;
00141 
00142   //
00143   // Allocate Private Context Data Structure.
00144   //
00145   Udp6Service = AllocateZeroPool (sizeof (UDP6_SERVICE_DATA));
00146   if (Udp6Service == NULL) {
00147     Status = EFI_OUT_OF_RESOURCES;
00148     goto EXIT;
00149   }
00150 
00151   Status = Udp6CreateService (Udp6Service, This->DriverBindingHandle, ControllerHandle);
00152   if (EFI_ERROR (Status)) {
00153     goto EXIT;
00154   }
00155 
00156   //
00157   // Install the Udp6ServiceBindingProtocol on the ControllerHandle.
00158   //
00159   Status = gBS->InstallMultipleProtocolInterfaces (
00160                   &ControllerHandle,
00161                   &gEfiUdp6ServiceBindingProtocolGuid,
00162                   &Udp6Service->ServiceBinding,
00163                   NULL
00164                   );
00165   if (EFI_ERROR (Status)) {
00166     Udp6CleanService (Udp6Service);
00167     goto EXIT;
00168   } else {
00169     Status = Udp6SetVariableData (Udp6Service);
00170   }
00171 
00172 EXIT:
00173   if (EFI_ERROR (Status)) {
00174     if (Udp6Service != NULL) {
00175       FreePool (Udp6Service);
00176     }
00177   }
00178   return Status;
00179 }
00180 
00201 EFI_STATUS
00202 EFIAPI
00203 Udp6DriverBindingStop (
00204   IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
00205   IN  EFI_HANDLE                   ControllerHandle,
00206   IN  UINTN                        NumberOfChildren,
00207   IN  EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
00208   )
00209 {
00210   EFI_STATUS                    Status;
00211   EFI_HANDLE                    NicHandle;
00212   EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
00213   UDP6_SERVICE_DATA             *Udp6Service;
00214   UDP6_INSTANCE_DATA            *Instance;
00215 
00216   //
00217   // Find the NicHandle where UDP6 ServiceBinding Protocol is installed.
00218   //
00219   NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp6ProtocolGuid);
00220   if (NicHandle == NULL) {
00221     return EFI_DEVICE_ERROR;
00222   }
00223 
00224   //
00225   // Retrieve the UDP6 ServiceBinding Protocol.
00226   //
00227   Status = gBS->OpenProtocol (
00228                   NicHandle,
00229                   &gEfiUdp6ServiceBindingProtocolGuid,
00230                   (VOID **) &ServiceBinding,
00231                   This->DriverBindingHandle,
00232                   NicHandle,
00233                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
00234                   );
00235   if (EFI_ERROR (Status)) {
00236     return EFI_DEVICE_ERROR;
00237   }
00238 
00239   Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (ServiceBinding);
00240 
00241   if (NumberOfChildren == 0) {
00242 
00243     gBS->UninstallMultipleProtocolInterfaces (
00244            NicHandle,
00245            &gEfiUdp6ServiceBindingProtocolGuid,
00246            &Udp6Service->ServiceBinding,
00247            NULL
00248            );
00249 
00250     Udp6ClearVariableData (Udp6Service);
00251 
00252     Udp6CleanService (Udp6Service);
00253 
00254     FreePool (Udp6Service);
00255   } else {
00256 
00257     while (!IsListEmpty (&Udp6Service->ChildrenList)) {
00258       Instance = NET_LIST_HEAD (&Udp6Service->ChildrenList, UDP6_INSTANCE_DATA, Link);
00259 
00260       Status = ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
00261     }
00262   }
00263 
00264   return Status;
00265 }
00266 
00286 EFI_STATUS
00287 EFIAPI
00288 Udp6ServiceBindingCreateChild (
00289   IN EFI_SERVICE_BINDING_PROTOCOL  *This,
00290   IN OUT EFI_HANDLE                *ChildHandle
00291   )
00292 {
00293   EFI_STATUS          Status;
00294   UDP6_SERVICE_DATA   *Udp6Service;
00295   UDP6_INSTANCE_DATA  *Instance;
00296   EFI_TPL             OldTpl;
00297   VOID                *Ip6;
00298 
00299   if ((This == NULL) || (ChildHandle == NULL)) {
00300     return EFI_INVALID_PARAMETER;
00301   }
00302 
00303   Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (This);
00304 
00305   //
00306   // Allocate the instance private data structure.
00307   //
00308   Instance = AllocateZeroPool (sizeof (UDP6_INSTANCE_DATA));
00309   if (Instance == NULL) {
00310     return EFI_OUT_OF_RESOURCES;
00311   }
00312 
00313   Udp6InitInstance (Udp6Service, Instance);
00314 
00315   //
00316   // Add an IpInfo for this instance.
00317   //
00318   Instance->IpInfo = IpIoAddIp (Udp6Service->IpIo);
00319   if (Instance->IpInfo == NULL) {
00320     Status = EFI_OUT_OF_RESOURCES;
00321     goto ON_ERROR;
00322   }
00323 
00324   //
00325   // Install the Udp6Protocol for this instance.
00326   //
00327   Status = gBS->InstallMultipleProtocolInterfaces (
00328                   ChildHandle,
00329                   &gEfiUdp6ProtocolGuid,
00330                   &Instance->Udp6Proto,
00331                   NULL
00332                   );
00333   if (EFI_ERROR (Status)) {
00334     goto ON_ERROR;
00335   }
00336 
00337   Instance->ChildHandle = *ChildHandle;
00338 
00339   //
00340   // Open the default Ip6 protocol in the IP_IO BY_CHILD.
00341   //
00342   Status = gBS->OpenProtocol (
00343                   Udp6Service->IpIo->ChildHandle,
00344                   &gEfiIp6ProtocolGuid,
00345                   (VOID **) &Ip6,
00346                   gUdp6DriverBinding.DriverBindingHandle,
00347                   Instance->ChildHandle,
00348                   EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
00349                   );
00350   if (EFI_ERROR (Status)) {
00351     goto ON_ERROR;
00352   }
00353 
00354   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
00355 
00356   //
00357   // Link this instance into the service context data and increase the ChildrenNumber.
00358   //
00359   InsertTailList (&Udp6Service->ChildrenList, &Instance->Link);
00360   Udp6Service->ChildrenNumber++;
00361 
00362   gBS->RestoreTPL (OldTpl);
00363 
00364   return EFI_SUCCESS;
00365 
00366 ON_ERROR:
00367 
00368   if (Instance->ChildHandle != NULL) {
00369     gBS->UninstallMultipleProtocolInterfaces (
00370            Instance->ChildHandle,
00371            &gEfiUdp6ProtocolGuid,
00372            &Instance->Udp6Proto,
00373            NULL
00374            );
00375   }
00376 
00377   if (Instance->IpInfo != NULL) {
00378     IpIoRemoveIp (Udp6Service->IpIo, Instance->IpInfo);
00379   }
00380 
00381   Udp6CleanInstance (Instance);
00382 
00383   FreePool (Instance);
00384 
00385   return Status;
00386 }
00387 
00407 EFI_STATUS
00408 EFIAPI
00409 Udp6ServiceBindingDestroyChild (
00410   IN EFI_SERVICE_BINDING_PROTOCOL  *This,
00411   IN EFI_HANDLE                    ChildHandle
00412   )
00413 {
00414   EFI_STATUS          Status;
00415   UDP6_SERVICE_DATA   *Udp6Service;
00416   EFI_UDP6_PROTOCOL   *Udp6Proto;
00417   UDP6_INSTANCE_DATA  *Instance;
00418   EFI_TPL             OldTpl;
00419 
00420   if ((This == NULL) || (ChildHandle == NULL)) {
00421     return EFI_INVALID_PARAMETER;
00422   }
00423 
00424   Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (This);
00425 
00426   //
00427   // Try to get the Udp6 protocol from the ChildHandle.
00428   //
00429   Status = gBS->OpenProtocol (
00430                   ChildHandle,
00431                   &gEfiUdp6ProtocolGuid,
00432                   (VOID **) &Udp6Proto,
00433                   gUdp6DriverBinding.DriverBindingHandle,
00434                   ChildHandle,
00435                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
00436                   );
00437   if (EFI_ERROR (Status)) {
00438     return EFI_UNSUPPORTED;
00439   }
00440 
00441   Instance = UDP6_INSTANCE_DATA_FROM_THIS (Udp6Proto);
00442 
00443   if (Instance->Destroyed) {
00444     return EFI_SUCCESS;
00445   }
00446 
00447   //
00448   // Use the Destroyed flag to avoid the re-entering of the following code.
00449   //
00450   Instance->Destroyed = TRUE;
00451 
00452   //
00453   // Close the Ip6 protocol.
00454   //
00455   gBS->CloseProtocol (
00456          Udp6Service->IpIo->ChildHandle,
00457          &gEfiIp6ProtocolGuid,
00458          gUdp6DriverBinding.DriverBindingHandle,
00459          Instance->ChildHandle
00460          );
00461 
00462   //
00463   // Uninstall the Udp6Protocol previously installed on the ChildHandle.
00464   //
00465   Status = gBS->UninstallMultipleProtocolInterfaces (
00466                   ChildHandle,
00467                   &gEfiUdp6ProtocolGuid,
00468                   (VOID *) &Instance->Udp6Proto,
00469                   NULL
00470                   );
00471   if (EFI_ERROR (Status)) {
00472     Instance->Destroyed = FALSE;
00473     return Status;
00474   }
00475 
00476   //
00477   // Reset the configuration in case the instance's consumer forgets to do this.
00478   //
00479   Udp6Proto->Configure (Udp6Proto, NULL);
00480 
00481   //
00482   // Remove the IpInfo this instance consumes.
00483   //
00484   IpIoRemoveIp (Udp6Service->IpIo, Instance->IpInfo);
00485 
00486   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
00487 
00488   //
00489   // Remove this instance from the service context data's ChildrenList.
00490   //
00491   RemoveEntryList (&Instance->Link);
00492   Udp6Service->ChildrenNumber--;
00493 
00494   //
00495   // Clean the instance.
00496   //
00497   Udp6CleanInstance (Instance);
00498 
00499   gBS->RestoreTPL (OldTpl);
00500 
00501   FreePool (Instance);
00502 
00503   return EFI_SUCCESS;
00504 }
00505 
00521 EFI_STATUS
00522 EFIAPI
00523 Udp6DriverEntryPoint (
00524   IN EFI_HANDLE        ImageHandle,
00525   IN EFI_SYSTEM_TABLE  *SystemTable
00526   )
00527 {
00528   EFI_STATUS  Status;
00529 
00530   //
00531   // Install the Udp6DriverBinding and Udp6ComponentName protocols.
00532   //
00533 
00534   Status = EfiLibInstallDriverBindingComponentName2 (
00535              ImageHandle,
00536              SystemTable,
00537              &gUdp6DriverBinding,
00538              ImageHandle,
00539              &gUdp6ComponentName,
00540              &gUdp6ComponentName2
00541              );
00542   if (!EFI_ERROR (Status)) {
00543     //
00544     // Initialize the UDP random port.
00545     //
00546     mUdp6RandomPort = (UINT16)(
00547                         ((UINT16) NetRandomInitSeed ()) %
00548                          UDP6_PORT_KNOWN +
00549                          UDP6_PORT_KNOWN
00550                          );
00551   }
00552 
00553   return Status;
00554 }
00555 
00556 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines