arpdriver.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 797 行 · 第 1/2 页

C
797
字号
  ArpCleanService (ArpService);
  NetFreePool (ArpService);

  return Status;
}

EFI_STATUS
EFIAPI
ArpDriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN UINTN                        NumberOfChildren,
  IN EFI_HANDLE                   *ChildHandleBuffer
  )
/*++

Routine Description:

  Stop this driver on ControllerHandle.

Arguments:

  This              - Protocol instance pointer.
  ControllerHandle  - Handle of device to stop driver on 
  NumberOfChildren  - Number of Handles in ChildHandleBuffer. If number of 
                      children is zero stop the entire bus driver.
  ChildHandleBuffer - List of Child Handles to Stop.

Returns:

  EFI_SUCCES - This driver is removed ControllerHandle
  other      - This driver was not removed from this device

--*/
{
  EFI_STATUS                    Status;
  EFI_HANDLE                    NicHandle;
  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
  ARP_SERVICE_DATA              *ArpService;
  ARP_INSTANCE_DATA             *Instance;

  //
  // Get the NicHandle which the arp servicebinding is installed on.
  //
  NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
  if (NicHandle == NULL) {
    return EFI_SUCCESS;
  }

  //
  // Try to get the arp servicebinding protocol on the NicHandle.
  //
  Status = gBS->OpenProtocol (
                  NicHandle,
                  &gEfiArpServiceBindingProtocolGuid,
                  (VOID **)&ServiceBinding,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    ARP_DEBUG_ERROR (("ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status));
    return Status;
  }

  ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding);

  while (!NetListIsEmpty (&ArpService->ChildrenList)) {
    //
    // Iterate all the instances.
    //
    Instance = NET_LIST_HEAD (&ArpService->ChildrenList, ARP_INSTANCE_DATA, List);

    //
    // Destroy this arp child.
    //
    ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
  }

  ASSERT (NetListIsEmpty (&ArpService->PendingRequestTable));
  ASSERT (NetListIsEmpty (&ArpService->DeniedCacheTable));
  ASSERT (NetListIsEmpty (&ArpService->ResolvedCacheTable));

  //
  // Uninstall the ARP ServiceBinding protocol.
  //
  Status = gBS->UninstallMultipleProtocolInterfaces (
                  NicHandle,
                  &gEfiArpServiceBindingProtocolGuid,
                  &ArpService->ServiceBinding,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    ARP_DEBUG_ERROR (("ArpDriverBindingStop: Failed to uninstall ArpSb, %r.\n", Status));
    return Status;
  }

  //
  // Clean the arp servicebinding context data and free the memory allocated.
  //
  ArpCleanService (ArpService);
  NetFreePool (ArpService);

  return Status;
}

EFI_STATUS
EFIAPI
ArpServiceBindingCreateChild (
  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                    *ChildHandle
  )
/*++

Routine Description:

  Creates a child handle with a set of I/O services.

Arguments:

  This         - Protocol instance pointer.
  ChildHandle  - Pointer to the handle of the child to create. If it is NULL, then a
                 new handle is created. If it is not NULL, then the I/O services are 
                 added to the existing child handle.

Returns:

  EFI_SUCCES           - The child handle was created with the I/O services.
  EFI_OUT_OF_RESOURCES - There are not enough resources availabe to create the child.
  other                - The child handle was not created.

--*/
{
  EFI_STATUS         Status;
  ARP_SERVICE_DATA   *ArpService;
  ARP_INSTANCE_DATA  *Instance;
  VOID               *Mnp;

  if ((This == NULL) || (ChildHandle == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  ArpService = ARP_SERVICE_DATA_FROM_THIS (This);

  //
  // Allocate memory for the instance context data.
  //
  Instance = NetAllocateZeroPool (sizeof(ARP_INSTANCE_DATA));
  if (Instance == NULL) {
    ARP_DEBUG_ERROR (("ArpSBCreateChild: Failed to allocate memory for Instance.\n"));

    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Init the instance context data.
  //
  ArpInitInstance (ArpService, Instance);

  //
  // Install the ARP protocol onto the ChildHandle.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  ChildHandle,
                  &gEfiArpProtocolGuid,
                  (VOID *)&Instance->ArpProto,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    ARP_DEBUG_ERROR (("ArpSBCreateChild: faild to install ARP protocol, %r.\n", Status));

    NetFreePool (Instance);
    return Status;
  }

  //
  // Save the ChildHandle.
  //
  Instance->Handle = *ChildHandle;

  //
  // Open the Managed Network protocol BY_CHILD.
  //
  Status = gBS->OpenProtocol (
                  ArpService->MnpChildHandle,
                  &gEfiManagedNetworkProtocolGuid,
                  (VOID **) &Mnp,
                  gArpDriverBinding.DriverBindingHandle,
                  Instance->Handle,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                  );
  if (EFI_ERROR (Status)) {
    goto ERROR;
  }

  if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {

    Status = EFI_ACCESS_DENIED;
    goto ERROR;
  }

  //
  // Insert the instance into children list managed by the arp service context data.
  //
  NetListInsertTail (&ArpService->ChildrenList, &Instance->List);
  ArpService->ChildrenNumber++;

  NET_UNLOCK (&ArpService->Lock);

ERROR:

  if (EFI_ERROR (Status)) {

    gBS->CloseProtocol (
           ArpService->MnpChildHandle,
           &gEfiManagedNetworkProtocolGuid,
           gArpDriverBinding.DriverBindingHandle,
           Instance->Handle
           );

    gBS->UninstallMultipleProtocolInterfaces (
           Instance->Handle,
           &gEfiArpProtocolGuid,
           &Instance->ArpProto,
           NULL
           );

    //
    // Free the allocated memory.
    //
    NetFreePool (Instance);
  }

  return Status;
}

EFI_STATUS
EFIAPI
ArpServiceBindingDestroyChild (
  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                    ChildHandle
  )
/*++

Routine Description:

  Destroys a child handle with a set of I/O services.

Arguments:

  This         - Protocol instance pointer.
  ChildHandle  - Handle of the child to destroy.

Returns:

  EFI_SUCCES            - The I/O services were removed from the child handle.
  EFI_UNSUPPORTED       - The child handle does not support the I/O services 
                          that are being removed.
  EFI_INVALID_PARAMETER - Child handle is not a valid EFI Handle.
  EFI_ACCESS_DENIED     - The child handle could not be destroyed because its 
                          I/O services are being used.
  other                 - The child handle was not destroyed.

--*/
{
  EFI_STATUS         Status;
  ARP_SERVICE_DATA   *ArpService;
  ARP_INSTANCE_DATA  *Instance;
  EFI_ARP_PROTOCOL   *Arp;

  if ((This == NULL) || (ChildHandle == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  ArpService = ARP_SERVICE_DATA_FROM_THIS (This);

  //
  // Get the arp protocol.
  //
  Status = gBS->OpenProtocol (
                  ChildHandle,
                  &gEfiArpProtocolGuid,
                  (VOID **)&Arp,
                  ArpService->ImageHandle,
                  ChildHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  Instance = ARP_INSTANCE_DATA_FROM_THIS (Arp);

  if (Instance->Destroyed) {
    return EFI_SUCCESS;
  }

  //
  // Use the Destroyed as a flag to avoid re-entrance.
  //
  Instance->Destroyed = TRUE;

  //
  // Close the Managed Network protocol.
  //
  gBS->CloseProtocol (
         ArpService->MnpChildHandle,
         &gEfiManagedNetworkProtocolGuid,
         gArpDriverBinding.DriverBindingHandle,
         ChildHandle
         );

  //
  // Uninstall the ARP protocol.
  //
  Status = gBS->UninstallMultipleProtocolInterfaces (
                  ChildHandle,
                  &gEfiArpProtocolGuid,
                  &Instance->ArpProto,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    ARP_DEBUG_ERROR (("ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",
      Status));

    Instance->Destroyed = FALSE;
    return Status;
  }

  if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {
    Instance->Destroyed = FALSE;
    return EFI_ACCESS_DENIED;
  }

  if (Instance->Configured) {
    //
    // Delete the related cache entry.
    //
    ArpDeleteCacheEntry (Instance, FALSE, NULL, TRUE);

    //
    // Reset the instance configuration.
    //
    ArpConfigureInstance (Instance, NULL);
  }

  //
  // Remove this instance from the ChildrenList.
  //
  NetListRemoveEntry (&Instance->List);
  ArpService->ChildrenNumber--;

  NET_UNLOCK (&ArpService->Lock);

  NetFreePool (Instance);

  return Status;
}

EFI_DRIVER_ENTRY_POINT (ArpDriverEntryPoint)

EFI_STATUS
EFIAPI
ArpDriverEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
/*++

Routine Description:

  The entry point for Arp driver which installs the driver binding and component name
  protocol on its ImageHandle.

Arguments:

  ImageHandle - The image handle of the driver.
  SystemTable - The system table.

Returns:

  EFI_SUCCESS - if the driver binding and component name protocols are successfully
                installed, otherwise if failed.

--*/
{
  return NetLibInstallAllDriverProtocols (
           ImageHandle,
           SystemTable,
           &gArpDriverBinding,
           ImageHandle,
           &gArpComponentName,
           NULL,
           NULL
           );
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?