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

📄 usbbus.c

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

Copyright (c)  1999 - 2002 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:

    UsbBus.c

  Abstract:

    USB Bus Driver

  Revision History

--*/

//
// USB Bus Controller Driver
//
#include "Efi.h"
#include "EfiDriverLib.h"

//
// Driver Consumed Protocol Prototypes
//
#include EFI_PROTOCOL_DEFINITION(DriverBinding)
#include EFI_PROTOCOL_DEFINITION(UsbIo)
#include EFI_PROTOCOL_DEFINITION(DevicePath)

#include "usb.h"
#include EFI_PROTOCOL_DEFINITION(UsbHostController)
#include "usbbus.h"
#include "usblib.h"
#include "usbutil.h"
#include "hub.h"

//
// USB bus entry point
//
EFI_STATUS
UsbBusDriverEntryPoint(
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  );

//
// EFI_DRIVER_BINDING_PROTOCOL Protocol Interface
//
EFI_STATUS
UsbBusControllerDriverSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  );

EFI_STATUS
UsbBusControllerDriverStart (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  );

EFI_STATUS
UsbBusControllerDriverStop (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN UINTN                          NumberOfChildren,
  IN EFI_HANDLE                     *ChildHandleBuffer
  );


//
// Supported function
//
VOID
InitializeUsbIoInstance (
  IN USB_IO_CONTROLLER_DEVICE     *UsbIoController
  );


STATIC
USB_IO_CONTROLLER_DEVICE *
CreateUsbIoControllerDevice (
  VOID
);

STATIC
EFI_STATUS
InitUsbIoController (
  IN USB_IO_CONTROLLER_DEVICE     *UsbIoController
  );

//
// USB Device Configuration / Deconfiguration
//
STATIC
EFI_STATUS
UsbDeviceConfiguration(
  IN  USB_IO_CONTROLLER_DEVICE    *ParentHubController,
  IN  EFI_HANDLE                  HostController,
  IN  UINT8                       ParentPort,
  IN  USB_IO_DEVICE               *UsbIoDevice
  );

STATIC
EFI_STATUS
UsbDeviceDeConfiguration(
  IN  USB_IO_DEVICE  *UsbIoDevice
  );

//
// Usb Bus enumeration function
//
STATIC
VOID
UsbEnumeration (
  IN EFI_EVENT    Event,
  IN VOID         *Context
  );

EFI_DRIVER_ENTRY_POINT(UsbBusDriverEntryPoint)


EFI_DRIVER_BINDING_PROTOCOL gUsbBusDriverBinding = {
  UsbBusControllerDriverSupported,
  UsbBusControllerDriverStart,
  UsbBusControllerDriverStop,
  0x10,
  NULL,
  NULL
};

VOID
ResetRootPort(
  IN UINT8                  PortNum,
  IN EFI_USB_HC_PROTOCOL    *UsbHCInterface
  );

VOID
ClearRootPortConnectionChangeStatus (
  IN UINT8                  PortNum,
  IN EFI_USB_HC_PROTOCOL    *UsbHCInterface
);

STATIC
EFI_STATUS
ParentPortReset (
  IN USB_IO_CONTROLLER_DEVICE    *UsbIoController,
  IN BOOLEAN                     ReConfigure
  );

//
// Following are address allocate and free functions
//
STATIC
UINT8 UsbAllocateAddress(
  IN UINT8    *AddressPool
)
{
  UINT8 ByteIndex;
  UINT8 BitIndex;

  for (ByteIndex = 0; ByteIndex < 16 ; ByteIndex ++) {
    for (BitIndex = 0; BitIndex < 8 ; BitIndex ++) {
      if ((AddressPool[ByteIndex] & (1 << BitIndex)) == 0) {
         //
         // Found one, covert to address, and mark it use
         //
         AddressPool[ByteIndex] |= (1 << BitIndex);
         return (UINT8)(ByteIndex * 8 + BitIndex);
      }
    }
  }

  return 0;

}

STATIC
VOID UsbFreeAddress(
  IN UINT8    DevAddress,
  IN UINT8    *AddressPool
)
{
  UINT8 WhichByte;
  UINT8 WhichBit;

  //
  // Locate the position
  // 
  WhichByte = (UINT8)(DevAddress / 8);
  WhichBit = (UINT8)(DevAddress % 8);

  AddressPool[WhichByte] &= (~(1 << WhichBit));
}

#define MICROSECOND     10000
#define ONESECOND       (1000 * MICROSECOND)

//
// USB Bus Driver Entry point
//
EFI_STATUS
UsbBusDriverEntryPoint(
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
/*++

  Routine Description:
    Entry point for EFI drivers.

  Arguments:
    (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

  Returns:
    EFI_SUCCESS
    others

--*/

{
  EFI_STATUS  Status;

  //
  // Install driver binding protocol
  //
  Status = EfiLibInstallAllDriverProtocols (
            ImageHandle, 
            SystemTable, 
            &gUsbBusDriverBinding, 
            ImageHandle,
            &gUsbBusComponentName,
            NULL,
            NULL
           );

  return Status;

}


EFI_STATUS
UsbBusControllerDriverSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
/*++

  Routine Description:
    Test to see if this driver supports ControllerHandle. Any ControllerHandle
    that has UsbHcProtocol installed will be supported.

  Arguments:
    This                - Protocol instance pointer.
    ControllerHandle    - Handle of device to test
    RemainingDevicePath - Not used

  Returns:
    EFI_SUCCESS         - This driver supports this device.
    EFI_UNSUPPORTED     - This driver does not support this device.

--*/
{
  EFI_STATUS                 OpenStatus;

  //
  // Check whether USB Host Controller Protocol is already
  // installed on this handle. If it is installed, we can start
  // USB Bus Driver now.
  //
  OpenStatus = gBS->OpenProtocol (
                      Controller,
                      &gEfiUsbHcProtocolGuid,
                      NULL,
                      This->DriverBindingHandle,
                      Controller,
                      EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                 );

  if (EFI_ERROR (OpenStatus) && (OpenStatus != EFI_ALREADY_STARTED)) {
    return EFI_UNSUPPORTED;
  } 

  return OpenStatus;
}

//
// The UsbBusProtocol is just used to locate USB_BUS_CONTROLLER
// structure in the UsbBusDriverControllerDriverStop(). Then we can
// Close all opened protocols and release this structure.
//
STATIC EFI_GUID mUsbBusProtocolGuid = EFI_USB_BUS_PROTOCOL_GUID;

EFI_STATUS
UsbBusControllerDriverStart (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
/*++

  Routine Description:
    Starting the Usb Bus Driver

  Arguments:
    This                - Protocol instance pointer.
    ControllerHandle    - Handle of device to test
    RemainingDevicePath - Not used

  Returns:
    EFI_SUCCESS         - This driver supports this device.
    EFI_UNSUPPORTED     - This driver does not support this device.
    EFI_DEVICE_ERROR    - This driver cannot be started due to device
                          Error
    EFI_OUT_OF_RESOURCES

--*/
{
  EFI_STATUS                     Status;
  EFI_STATUS                     OpenStatus;
  USB_BUS_CONTROLLER_DEVICE      *UsbBusDev;
  USB_IO_DEVICE                  *RootHub;
  USB_IO_CONTROLLER_DEVICE       *RootHubController;
  EFI_USB_HC_PROTOCOL            *UsbHCInterface;
  EFI_TPL                        OldTPL;

  OldTPL = gBS->RaiseTPL(EFI_TPL_CALLBACK);

  //
  // Allocate USB_BUS_CONTROLLER_DEVICE structure
  //
  UsbBusDev = NULL;
  Status = gBS->AllocatePool(
                  EfiBootServicesData,
                  sizeof(USB_BUS_CONTROLLER_DEVICE),
                  (VOID **)&UsbBusDev
                );

  if (EFI_ERROR(Status)) {
    gBS->RestoreTPL(OldTPL);
    return EFI_OUT_OF_RESOURCES;
  }

  EfiZeroMem(UsbBusDev, sizeof(USB_BUS_CONTROLLER_DEVICE));

  UsbBusDev->Signature = USB_BUS_DEVICE_SIGNATURE;
  UsbBusDev->AddressPool[0] = 1;

  //
  // Get the Device Path Protocol on Controller's handle
  //
  OpenStatus = gBS->OpenProtocol(
                      Controller,
                      &gEfiDevicePathProtocolGuid,
                      (VOID **)&UsbBusDev->BusControllerDevicePath,
                      This->DriverBindingHandle,
                      Controller,
                      EFI_OPEN_PROTOCOL_BY_DRIVER
                    );

  if (EFI_ERROR(OpenStatus)) {
    gBS->FreePool(UsbBusDev);
    gBS->RestoreTPL(OldTPL);
    return EFI_UNSUPPORTED;
  }

  //
  // Locate the Host Controller Interface
  //
  OpenStatus = gBS->OpenProtocol (
                      Controller,
                      &gEfiUsbHcProtocolGuid,
                      (VOID **)&UsbHCInterface,
                      This->DriverBindingHandle,
                      Controller,
                      EFI_OPEN_PROTOCOL_BY_DRIVER
                   );

  if (EFI_ERROR(OpenStatus) && (OpenStatus != EFI_ALREADY_STARTED)) {
    gBS->CloseProtocol(
            Controller,
            &gEfiDevicePathProtocolGuid,
            This->DriverBindingHandle,
            Controller
         );
    gBS->FreePool(UsbBusDev);
    gBS->RestoreTPL(OldTPL);
    return EFI_UNSUPPORTED;
  } 
  
  if (OpenStatus == EFI_ALREADY_STARTED) {
    gBS->CloseProtocol(
            Controller,
            &gEfiDevicePathProtocolGuid,
            This->DriverBindingHandle,
            Controller
         );
    gBS->FreePool(UsbBusDev);
    gBS->RestoreTPL(OldTPL);
    return EFI_ALREADY_STARTED;
  }

  UsbBusDev->UsbHCInterface = UsbHCInterface;

  //
  // Attach EFI_USB_BUS_PROTOCOL to controller handle,
  // for locate UsbBusDev later
  //
  Status = gBS->InstallProtocolInterface(
                  &Controller,
                  &mUsbBusProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &UsbBusDev->BusIdentify
                );

  if (EFI_ERROR(Status)) {
    gBS->CloseProtocol(
            Controller,
            &gEfiDevicePathProtocolGuid,
            This->DriverBindingHandle,
            Controller
         );
    gBS->CloseProtocol(
            Controller,
            &gEfiUsbHcProtocolGuid,
            This->DriverBindingHandle,
            Controller
         );
    gBS->FreePool(UsbBusDev);
    gBS->RestoreTPL(OldTPL);
    return Status;
  }

  //
  // Add root hub to the tree
  //
  RootHub = NULL;
  Status = gBS->AllocatePool(
                 EfiBootServicesData,
                 sizeof (USB_IO_DEVICE),
                 (VOID **)&RootHub
                );

  if (EFI_ERROR(Status)) {
     gBS->UninstallProtocolInterface(
            Controller,
            &mUsbBusProtocolGuid,
            &UsbBusDev->BusIdentify
          );
    gBS->CloseProtocol(
            Controller,
            &gEfiDevicePathProtocolGuid,
            This->DriverBindingHandle,
            Controller
         );
    gBS->CloseProtocol(
            Controller,
            &gEfiUsbHcProtocolGuid,
            This->DriverBindingHandle,
            Controller
         );
    gBS->FreePool(UsbBusDev);
    gBS->RestoreTPL(OldTPL);
    return EFI_OUT_OF_RESOURCES;
  }

  EfiZeroMem(RootHub, sizeof(USB_IO_DEVICE));

  RootHub->BusController  = UsbBusDev;
  RootHub->DeviceAddress  = UsbAllocateAddress(UsbBusDev->AddressPool);

  UsbBusDev->Root = RootHub;

  //
  // Allocate Root Hub Controller
  //
  RootHubController = CreateUsbIoControllerDevice();
  if(RootHubController == NULL) {
     gBS->UninstallProtocolInterface(
            Controller,
            &mUsbBusProtocolGuid,
            &UsbBusDev->BusIdentify
          );
    gBS->CloseProtocol(
            Controller,
            &gEfiDevicePathProtocolGuid,
            This->DriverBindingHandle,
            Controller
         );
    gBS->CloseProtocol(
            Controller,
            &gEfiUsbHcProtocolGuid,
            This->DriverBindingHandle,
            Controller
         );
    gBS->FreePool(UsbBusDev);
    gBS->FreePool(RootHub);
    gBS->RestoreTPL(OldTPL);
    return EFI_OUT_OF_RESOURCES;
  }

  UsbHCInterface->GetRootHubPortNumber (
                    UsbHCInterface,
                    &RootHubController->DownstreamPorts
                  );
  RootHubController->UsbDevice      = RootHub;
  RootHubController->IsUsbHub       = TRUE;
  RootHubController->DevicePath     = UsbBusDev->BusControllerDevicePath;
  RootHubController->HostController = Controller;

  RootHub->NumOfControllers = 1;
  RootHub->UsbController[0] = RootHubController;

  //
  // Create a timer to query root ports periodically
  //
  Status = gBS->CreateEvent(
                  EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
                  EFI_TPL_CALLBACK,
                  UsbEnumeration,
                  RootHubController,
                  &RootHubController->HubNotify
                );
  if (EFI_ERROR(Status)) {
    gBS->UninstallProtocolInterface(
           Controller,
           &mUsbBusProtocolGuid,
           &UsbBusDev->BusIdentify
         );

    gBS->CloseProtocol(
           Controller,
           &gEfiDevicePathProtocolGuid,
           This->DriverBindingHandle,
           Controller
         );

    gBS->CloseProtocol(
           Controller,
           &gEfiUsbHcProtocolGuid,
           This->DriverBindingHandle,
           Controller
         );

⌨️ 快捷键说明

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