⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driversupport.c

📁 Next BIOS Source code : Extensible Firmware Interface
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c)  1999 - 2003 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.

Module Name:

    DriverSupport.c
    
Abstract:

    EFI Driver Support Protocol

Revision History

--*/

#include "Efi.h"
#include "hand.h"

#include EFI_PROTOCOL_DEFINITION (DevicePath)
#include EFI_PROTOCOL_DEFINITION (DriverBinding)
#include EFI_PROTOCOL_DEFINITION (PlatformDriverOverride)
#include EFI_PROTOCOL_DEFINITION (BusSpecificDriverOverride)

//
// Driver Support Function Prototypes
//
EFI_STATUS 
EFIAPI
ConnectController (
  IN  EFI_HANDLE                ControllerHandle,
  IN  EFI_HANDLE                *DriverImageHandle    OPTIONAL,
  IN  EFI_DEVICE_PATH           *RemainingDevicePath  OPTIONAL,
  IN  BOOLEAN                   Recursive
  );

EFI_STATUS 
ConnectSingleController (
  IN  EFI_HANDLE                ControllerHandle,
  IN  EFI_HANDLE                *DriverImageHandle    OPTIONAL,
  IN  EFI_DEVICE_PATH           *RemainingDevicePath  OPTIONAL
  );

EFI_STATUS 
EFIAPI
DisconnectController (
  IN EFI_HANDLE  ControllerHandle,
  IN EFI_HANDLE  DriverImageHandle,
  IN EFI_HANDLE  ChildHandle        OPTIONAL
  );

//
// Driver Support Functions
//

EFI_STATUS 
EFIAPI
ConnectController (
  IN  EFI_HANDLE                ControllerHandle,
  IN  EFI_HANDLE                *DriverImageHandle    OPTIONAL,
  IN  EFI_DEVICE_PATH           *RemainingDevicePath  OPTIONAL,
  IN  BOOLEAN                   Recursive
  )

{
  EFI_STATUS                           Status;
  EFI_STATUS                           ReturnStatus;
  IHANDLE                              *Handle;
  UINTN                                Index;
  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *OpenInfoBuffer;
  UINTN                                EntryCount;
  PROTOCOL_ENTRY                       *ProtEntry;
  PROTOCOL_INTERFACE                   *Prot;
  LIST_ENTRY                           *Link;
  EFI_DEVICE_PATH                      *AlignedRemainingDevicePath;

  //
  // Make sure ControllerHandle is valid
  //
  Handle = ControllerHandle;
  if (Handle == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  if (Handle->Signature != EFI_HANDLE_SIGNATURE) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Connect all drivers to ControllerHandle 
  //
  AlignedRemainingDevicePath = NULL;
  if (RemainingDevicePath != NULL) {
    AlignedRemainingDevicePath = DuplicateDevicePath (RemainingDevicePath);
  }
  ReturnStatus = ConnectSingleController (
                   ControllerHandle,
                   DriverImageHandle,
                   AlignedRemainingDevicePath
                   );
  if (AlignedRemainingDevicePath != NULL) {
    BS->FreePool (AlignedRemainingDevicePath);
  }

  //
  // If not recursive, then just return after connecting drivers to ControllerHandle
  //
  if (!Recursive) {
    return ReturnStatus;
  }

  //
  // If recursive, then connect all drivers to all of ControllerHandle's children
  //
  for (Link = Handle->Protocols.Flink; Link != &Handle->Protocols; Link = Link->Flink) {
    Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
    ProtEntry = Prot->Protocol;
    Status = OpenProtocolInformation (
               ControllerHandle,
               &ProtEntry->ProtocolID,
               &OpenInfoBuffer,
               &EntryCount
               );
    if (!EFI_ERROR (Status) && OpenInfoBuffer != NULL) {
      for (Index = 0; Index < EntryCount; Index++) {
        if (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
          Status = ConnectController (
                     OpenInfoBuffer[Index].ControllerHandle,
                     NULL,
                     NULL,
                     TRUE
                     );
        }
      }
      BS->FreePool (OpenInfoBuffer);
    }
  }

  return ReturnStatus;
}

VOID
AddSortedDriverBindingProtocol (
  EFI_HANDLE                   DriverBindingHandle,
  UINTN                        *NumberOfSortedDriverBindingProtocols, 
  EFI_DRIVER_BINDING_PROTOCOL  **SortedDriverBindingProtocols,
  UINTN                        DriverBindingHandleCount,
  EFI_HANDLE                   *DriverBindingHandleBuffer
  )

{
  EFI_STATUS                   Status;
  EFI_DRIVER_BINDING_PROTOCOL  *DriverBinding;
  UINTN                        Index;

  //
  // Make sure the DriverBindingHandle is valid
  //
  if (DriverBindingHandle == NULL) {
    return;
  }

  //
  // Retrieve the Driver Binding Protocol from DriverBindingHandle
  //
  Status = BS->HandleProtocol(
                 DriverBindingHandle,
                 &gEfiDriverBindingProtocolGuid,
                 &DriverBinding
                 );
  //
  // If DriverBindingHandle does not support the Driver Binding Protocol then return
  //
  if (EFI_ERROR (Status) || DriverBinding == NULL) {
    return;
  }

  //
  // See if DriverBinding is already in the sorted list
  //
  for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols; Index++) {
    if (DriverBinding == SortedDriverBindingProtocols[Index]) {
      return;
    }
  }

  //
  // Add DriverBinding to the end of the list
  //
  SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding;
  *NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1;

  //
  // Mark the cooresponding handle in DriverBindingHandleBuffer as used
  //
  for (Index = 0; Index < DriverBindingHandleCount; Index++) {
    if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) {
      DriverBindingHandleBuffer[Index] = NULL;
    }
  }
}

EFI_STATUS 
ConnectSingleController (
  IN  EFI_HANDLE                ControllerHandle,
  IN  EFI_HANDLE                *ContextDriverImageHandles OPTIONAL,
  IN  EFI_DEVICE_PATH           *RemainingDevicePath       OPTIONAL     
  )
/*++

Routine Description:

    Connects a controller to a driver

Arguments:

    ControllerHandle    -

    DriverImageHandle   -

    DriverImagePath     -

    RemainingDevicePath - 
    
Returns:

    None

--*/
{
  EFI_STATUS                                 Status;
  UINTN                                      Index;
  EFI_HANDLE                                 DriverImageHandle;
  UINTN                                      PlatformDriverOverrideHandleCount;
  EFI_HANDLE                                 *PlatformDriverOverrideHandleBuffer;
  EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL      *PlatformDriverOverride;
  EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL  *BusSpecificDriverOverride;
  UINTN                                      DriverBindingHandleCount;
  EFI_HANDLE                                 *DriverBindingHandleBuffer;
  EFI_DRIVER_BINDING_PROTOCOL                *DriverBinding;
  UINTN                                      NumberOfSortedDriverBindingProtocols;
  EFI_DRIVER_BINDING_PROTOCOL                **SortedDriverBindingProtocols;
  UINT32                                     HighestVersion;
  UINTN                                      HighestIndex;
  UINTN                                      SortIndex;
  BOOLEAN                                    OneStarted;
  BOOLEAN                                    DriverFound;

  //
  // Initialize local variables
  //
  DriverBindingHandleCount              = 0;
  DriverBindingHandleBuffer             = NULL;
  PlatformDriverOverrideHandleCount     = 0;
  PlatformDriverOverrideHandleBuffer    = NULL;
  NumberOfSortedDriverBindingProtocols  = 0;
  SortedDriverBindingProtocols          = NULL;

  //
  // Get list of all Driver Binding Protocol Instances
  //
  Status = LibLocateHandle (
              ByProtocol,   
              &DriverBindingProtocol,  
              NULL,
              &DriverBindingHandleCount, 
              &DriverBindingHandleBuffer
              );
  if (EFI_ERROR (Status) || DriverBindingHandleCount == 0) {
    return EFI_NOT_FOUND;
  }

  //
  // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
  //
  Status = BS->AllocatePool(
                  EfiBootServicesData,
                  sizeof (VOID *) * DriverBindingHandleCount,
                  (VOID **)&SortedDriverBindingProtocols
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Add Driver Binding Protocols from Context Driver Image Handles first
  //
  if (ContextDriverImageHandles != NULL) {
    for (Index = 0; ContextDriverImageHandles[Index] != NULL; Index++) {
      AddSortedDriverBindingProtocol (
        ContextDriverImageHandles[Index],
        &NumberOfSortedDriverBindingProtocols, 
        SortedDriverBindingProtocols,
        DriverBindingHandleCount,
        DriverBindingHandleBuffer
        );
    }
  }

  //
  // Add the Platform Driver Override Protocol drivers for ControllerHandle next
  //

  Status = BS->LocateProtocol (
             &gEfiPlatformDriverOverrideProtocolGuid, 
             NULL, 
             &PlatformDriverOverride
             );
  if (!EFI_ERROR (Status) && PlatformDriverOverride != NULL) {
    DriverImageHandle = NULL;
    do {
      Status = PlatformDriverOverride->GetDriver (
                                         PlatformDriverOverride,
                                         ControllerHandle,
                                         &DriverImageHandle
                                         );
      if (!EFI_ERROR (Status)) {
        AddSortedDriverBindingProtocol (
          DriverImageHandle,
          &NumberOfSortedDriverBindingProtocols, 
          SortedDriverBindingProtocols,
          DriverBindingHandleCount,
          DriverBindingHandleBuffer
          );
      }
    } while (!EFI_ERROR (Status));
  }

  //
  // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
  //
  Status = BS->HandleProtocol(
                 ControllerHandle,  
                 &gEfiBusSpecificDriverOverrideProtocolGuid, 
                 &BusSpecificDriverOverride
                 );
  if (!EFI_ERROR (Status) && BusSpecificDriverOverride != NULL) {
    DriverImageHandle = NULL;
    do {
      Status = BusSpecificDriverOverride->GetDriver (
                                            BusSpecificDriverOverride,
                                            &DriverImageHandle
                                            );
      if (!EFI_ERROR (Status)) {
        AddSortedDriverBindingProtocol (
          DriverImageHandle,
          &NumberOfSortedDriverBindingProtocols, 
          SortedDriverBindingProtocols,
          DriverBindingHandleCount,
          DriverBindingHandleBuffer
          );
      }
    } while (!EFI_ERROR (Status));
  }

  //
  // Then add all the remaining Driver Binding Protocols
  //
  SortIndex = NumberOfSortedDriverBindingProtocols;
  for (Index = 0; Index < DriverBindingHandleCount; Index++) {
    AddSortedDriverBindingProtocol (
      DriverBindingHandleBuffer[Index],
      &NumberOfSortedDriverBindingProtocols, 
      SortedDriverBindingProtocols,
      DriverBindingHandleCount,
      DriverBindingHandleBuffer
      );
  }

  //
  // Free the Driver Binding Handle Buffer
  //
  BS->FreePool(DriverBindingHandleBuffer);

⌨️ 快捷键说明

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