mnpdriver.c

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

C
591
字号
}

EFI_STATUS
EFIAPI
MnpServiceBindingCreateChild (
  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;
  MNP_SERVICE_DATA  *MnpServiceData;
  MNP_INSTANCE_DATA *Instance;
  VOID              *Snp;

  if ((This == NULL) || (ChildHandle == NULL)) {

    return EFI_INVALID_PARAMETER;
  }

  MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (This);

  //
  // Allocate buffer for the new instance.
  //
  Instance = NetAllocateZeroPool (sizeof (MNP_INSTANCE_DATA));
  if (Instance == NULL) {

    MNP_DEBUG_ERROR (("MnpServiceBindingCreateChild: Faild to allocate ""memory for the new instance.\n"));
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Init the instance data.
  //
  MnpInitializeInstanceData (MnpServiceData, Instance);

  Status = gBS->InstallMultipleProtocolInterfaces (
                  ChildHandle,
                  &gEfiManagedNetworkProtocolGuid,
                  &Instance->ManagedNetwork,
                  NULL
                  );
  if (EFI_ERROR (Status)) {

    MNP_DEBUG_ERROR (
      ("MnpServiceBindingCreateChild: Failed to install ""the MNP protocol, %r.\n",
      Status)
      );
    goto ErrorExit;
  }

  //
  // Save the instance's childhandle.
  //
  Instance->Handle = *ChildHandle;

  Status = gBS->OpenProtocol (
                  MnpServiceData->ControllerHandle,
                  &gEfiSimpleNetworkProtocolGuid,
                  (VOID **) &Snp,
                  gMnpDriverBinding.DriverBindingHandle,
                  Instance->Handle,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                  );
  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  //
  // Add the child instance into ChildrenList.
  //
  if (EFI_ERROR (NET_TRYLOCK (&MnpServiceData->ChildrenListLock))) {

    MNP_DEBUG_ERROR (("MnpServiceBindingCreateChild: Faild to acquire ""the childrenlist lock.\n"));
    Status = EFI_ACCESS_DENIED;
    goto ErrorExit;
  }

  NetListInsertTail (&MnpServiceData->ChildrenList, &Instance->InstEntry);
  MnpServiceData->ChildrenNumber++;

  NET_UNLOCK (&MnpServiceData->ChildrenListLock);

ErrorExit:

  if (EFI_ERROR (Status)) {

    if (Instance->Handle != NULL) {

      gBS->UninstallMultipleProtocolInterfaces (
            &gEfiManagedNetworkProtocolGuid,
            &Instance->ManagedNetwork,
            NULL
            );
    }

    NetFreePool (Instance);
  }

  return Status;
}

EFI_STATUS
EFIAPI
MnpServiceBindingDestroyChild (
  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;
  MNP_SERVICE_DATA              *MnpServiceData;
  EFI_MANAGED_NETWORK_PROTOCOL  *ManagedNetwork;
  MNP_INSTANCE_DATA             *Instance;

  if ((This == NULL) || (ChildHandle == NULL)) {

    return EFI_INVALID_PARAMETER;
  }

  MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (This);

  //
  // Try to retrieve ManagedNetwork Protocol from ChildHandle.
  //
  Status = gBS->OpenProtocol (
                  ChildHandle,
                  &gEfiManagedNetworkProtocolGuid,
                  (VOID **) &ManagedNetwork,
                  gMnpDriverBinding.DriverBindingHandle,
                  ChildHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {

    return EFI_UNSUPPORTED;
  }

  Instance = MNP_INSTANCE_DATA_FROM_THIS (ManagedNetwork);

  //
  // MnpServiceBindingDestroyChild may be called twice: first called by
  // MnpServiceBindingStop, second called by uninstalling the MNP protocol
  // in this ChildHandle. Use destroyed to make sure the resource clean code
  // will only excecute once.
  //
  if (Instance->Destroyed) {

    return EFI_SUCCESS;
  }

  Instance->Destroyed = TRUE;

  //
  // Close the Simple Network protocol.
  //
  gBS->CloseProtocol (
         MnpServiceData->ControllerHandle,
         &gEfiSimpleNetworkProtocolGuid,
         gMnpDriverBinding.DriverBindingHandle,
         ChildHandle
         );

  //
  // Uninstall the ManagedNetwork protocol.
  //
  Status = gBS->UninstallMultipleProtocolInterfaces (
                  ChildHandle,
                  &gEfiManagedNetworkProtocolGuid,
                  &Instance->ManagedNetwork,
                  NULL
                  );
  if (EFI_ERROR (Status)) {

    MNP_DEBUG_ERROR (
      ("MnpServiceBindingDestroyChild: Failed to uninstall ""the ManagedNetwork protocol, %r.\n",
      Status)
      );

    Instance->Destroyed = FALSE;
    return Status;
  }

  //
  // Reset the configuration.
  //
  ManagedNetwork->Configure (ManagedNetwork, NULL);

  //
  // Try to flush the RcvdPacketQueue.
  //
  MnpFlushRcvdDataQueue (Instance);

  //
  // Clean the RxTokenMap.
  //
  NetMapClean (&Instance->RxTokenMap);

  if (EFI_ERROR (NET_TRYLOCK (&MnpServiceData->ChildrenListLock))) {

    return EFI_ACCESS_DENIED;
  }

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

  NET_UNLOCK (&MnpServiceData->ChildrenListLock);

  NetFreePool (Instance);

  return Status;
}

EFI_DRIVER_ENTRY_POINT (MnpDriverEntryPoint)

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

Routine Description:

  The entry point for Mnp 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,
          &gMnpDriverBinding,
          ImageHandle,
          &gMnpComponentName,
          NULL,
          NULL
          );
}

⌨️ 快捷键说明

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