📄 usbbus.c
字号:
/*++
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 + -