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

📄 driversupport.c

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

  //
  // Sort the remaining DriverBinding Protocol based on their Version field from
  // highest to lowest.
  //
  for ( ; SortIndex < DriverBindingHandleCount; SortIndex++) {
    HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version;
    HighestIndex   = SortIndex;
    for (Index = SortIndex + 1; Index < DriverBindingHandleCount; Index++) {
      if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) {
        HighestVersion = SortedDriverBindingProtocols[Index]->Version;
        HighestIndex   = Index;
      }
    }
    if (SortIndex != HighestIndex) {
      DriverBinding = SortedDriverBindingProtocols[SortIndex];
      SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex];
      SortedDriverBindingProtocols[HighestIndex] = DriverBinding;
    }
  }

  //
  // Loop until no more drivers can be started on ControllerHandle
  //
  OneStarted = FALSE;
  do {

    //
    // Loop through the sorted Driver Binding Protocol Instances in order, and see if
    // any of the Driver Binding Protocols support the controller specified by 
    // ControllerHandle.
    //
    DriverBinding = NULL;
    DriverFound = FALSE;
    for (Index = 0; Index < NumberOfSortedDriverBindingProtocols; Index++) {
      if (SortedDriverBindingProtocols[Index] != NULL) {
        DriverBinding = SortedDriverBindingProtocols[Index];
        Status = DriverBinding->Supported(
                                  DriverBinding, 
                                  ControllerHandle,
                                  (EFI_DEVICE_PATH_PROTOCOL *)RemainingDevicePath
                                  );
        if (!EFI_ERROR (Status)) {
          SortedDriverBindingProtocols[Index] = NULL;
          DriverFound = TRUE;

          //
          // A driver was found that supports ControllerHandle, so attempt to start the driver
          // on ControllerHandle.
          //
          Status = DriverBinding->Start (
                                    DriverBinding, 
                                    ControllerHandle,
                                    (EFI_DEVICE_PATH_PROTOCOL *)RemainingDevicePath
                                    );
          if (!EFI_ERROR (Status)) {

            //
            // The driver was successfully started on ControllerHandle, so set a flag
            //
            OneStarted = TRUE;
          }
          break;
        }
      }
    }
  } while (DriverFound);

  //
  // Free any buffer that were allocated with AllocatePool()
  //
  BS->FreePool (SortedDriverBindingProtocols);

  //
  // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
  //
  if (OneStarted) {
    return EFI_SUCCESS;
  } 

  //
  // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
  //
  if (RemainingDevicePath != NULL) {
    if (IsDevicePathEnd (RemainingDevicePath)) {
      return EFI_SUCCESS;
    }
  } 

  //
  // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
  //
  return EFI_NOT_FOUND;
}

EFI_STATUS 
DisconnectController (
  IN  EFI_HANDLE  ControllerHandle,
  IN  EFI_HANDLE  DriverImageHandle, OPTIONAL
  IN  EFI_HANDLE  ChildHandle        OPTIONAL
  )
/*++

Routine Description:

    Disonnects a controller from a driver

Arguments:

    ControllerHandle    -

    GuidList            - 

Returns:

    None

--*/
{
  EFI_STATUS                          Status;
  EFI_DRIVER_BINDING_PROTOCOL         *DriverBinding;
  IHANDLE                             *Handle;
  PROTOCOL_ENTRY                      *ProtEntry;
  PROTOCOL_INTERFACE                  *Prot;
  LIST_ENTRY                          *Link;
  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
  UINTN                               EntryCount;
  UINTN                               ChildBufferCount;
  EFI_HANDLE                          *ChildBuffer;
  UINTN                               Index;
  UINTN                               j;
  UINTN                               k;
  BOOLEAN                             Duplicate;
  BOOLEAN                             ChildHandleValid;
  BOOLEAN                             DriverImageHandleValid;
  UINTN                               ChildrenToStop;
  EFI_HANDLE                          *DriverImageHandleBuffer;
  UINTN                               DriverImageHandleCount;
  UINTN                               StopCount;

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

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

  Handle = ControllerHandle;

  //
  // Get list of drivers that are currently managing ControllerHandle
  //
  DriverImageHandleBuffer = NULL;
  DriverImageHandleCount  = 1;
  if (DriverImageHandle == NULL) {
    //
    // Look at each protocol interface for a match
    //
    DriverImageHandleCount = 0;
    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_DRIVER) {
            DriverImageHandleCount++;
          }
        }
        BS->FreePool (OpenInfoBuffer);
      }
    }

    //
    // If there are no drivers managing this controller, then return EFI_SUCCESS
    //
    if (DriverImageHandleCount == 0) {
      return EFI_SUCCESS;
    }

    Status = BS->AllocatePool (
                    EfiBootServicesData,
                    sizeof (EFI_HANDLE) * DriverImageHandleCount,
                    (VOID **)&DriverImageHandleBuffer
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    DriverImageHandleCount = 0;
    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_DRIVER) {
            Duplicate = FALSE;
            for (j = 0; j< DriverImageHandleCount; j++) {
              if (DriverImageHandleBuffer[j] == OpenInfoBuffer[Index].AgentHandle) {
                Duplicate = TRUE;
              }
            }
            if (Duplicate == FALSE) {
              DriverImageHandleBuffer[DriverImageHandleCount] = OpenInfoBuffer[Index].AgentHandle;
              DriverImageHandleCount++;
            }
          }
        }
        BS->FreePool (OpenInfoBuffer);
      }
    }
  }

  StopCount = 0;
  for (j = 0; j < DriverImageHandleCount; j++) {

    if (DriverImageHandleBuffer != NULL) {
      DriverImageHandle = DriverImageHandleBuffer[j];
    }

    //
    // Get the Driver Binding Protocol of the driver that is managing this controller
    //
    Status = BS->OpenProtocol (
                    DriverImageHandle,  
                    &DriverBindingProtocol,   
                    &DriverBinding,
                    NULL, //gMyImageHandle,     
                    NULL,   
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR(Status)) {
      return Status;
    }

    //
    // Look at each protocol interface for a match
    //
    DriverImageHandleValid = FALSE;
    ChildBufferCount = 0;
    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].AgentHandle == DriverImageHandle &&
              (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER)) {
            ChildBufferCount++;
          }
          if (OpenInfoBuffer[Index].AgentHandle == DriverImageHandle &&
              (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER)) {
            DriverImageHandleValid = TRUE;
          }
        }
        BS->FreePool (OpenInfoBuffer);
      }
    }

    if (DriverImageHandleValid) {
      ChildHandleValid = FALSE;
      ChildBuffer = NULL;
      if (ChildBufferCount != 0) {

        Status = BS->AllocatePool (
                        EfiBootServicesData,
                        sizeof (EFI_HANDLE) * ChildBufferCount,
                        (VOID **)&ChildBuffer
                        );
        if (EFI_ERROR (Status)) {
          if (DriverImageHandleBuffer != NULL) {
            BS->FreePool (DriverImageHandleBuffer);
          }
          return Status;
        }

        ChildBufferCount = 0;
        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].AgentHandle == DriverImageHandle &&
                  (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER)) {
                Duplicate = FALSE;
                for (k = 0; k < ChildBufferCount; k++) {
                  if (ChildBuffer[k] == OpenInfoBuffer[Index].ControllerHandle) {
                    Duplicate = TRUE;
                    break;
                  }
                }
                if (Duplicate == FALSE) {
                  ChildBuffer[ChildBufferCount] = OpenInfoBuffer[Index].ControllerHandle;
                  if (ChildHandle == ChildBuffer[ChildBufferCount]) {
                    ChildHandleValid = TRUE;
                  }
                  ChildBufferCount++;
                }
              }
            }
            BS->FreePool (OpenInfoBuffer);
          }
        }
      }

      if (ChildHandle == NULL || ChildHandleValid) {
        ChildrenToStop = 0;
        Status = EFI_SUCCESS;
        if (ChildBufferCount > 0) {
          if (ChildHandle != NULL) {
            ChildrenToStop = 1;
            Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle);
          } else {
            ChildrenToStop = ChildBufferCount;
            Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer);
          }
        }
        if (!EFI_ERROR (Status) && ChildHandle == NULL && ChildBufferCount == ChildrenToStop) {
          Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL);
        }
        if (!EFI_ERROR(Status)) {
          StopCount++;
        }
      }

      if (ChildBuffer != NULL) {
        BS->FreePool (ChildBuffer);
      }

    }
  }

  if (DriverImageHandleBuffer != NULL) {
    BS->FreePool (DriverImageHandleBuffer);
  }

  if (StopCount > 0) {
    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}

⌨️ 快捷键说明

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