cbi0.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,088 行 · 第 1/2 页
C
1,088 行
/*++
Copyright (c) 2004 - 2005, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Cbi0.c
Abstract:
--*/
#include "Tiano.h"
#include "EfiDriverLib.h"
#include "usb.h"
#include "cbi.h"
#include "UsbDxeLib.h"
extern EFI_COMPONENT_NAME_PROTOCOL gUsbCbi0ComponentName;
//
// Function prototypes
//
EFI_STATUS
EFIAPI
UsbCbi0DriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
//
// Bot Driver Binding Protocol
//
STATIC
EFI_STATUS
EFIAPI
Cbi0DriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
STATIC
EFI_STATUS
EFIAPI
Cbi0DriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
STATIC
EFI_STATUS
EFIAPI
Cbi0DriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
VOID
Cbi0ReportStatusCode (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN EFI_STATUS_CODE_TYPE CodeType,
IN EFI_STATUS_CODE_VALUE Value
);
EFI_GUID gEfiUsbCbi0DriverGuid = {
0xe0eeba38, 0xa762, 0x4d50, 0xbc, 0x0, 0x67, 0x18, 0xbe, 0x70, 0x90, 0x87
};
EFI_DRIVER_BINDING_PROTOCOL gUsbCbi0DriverBinding = {
Cbi0DriverBindingSupported,
Cbi0DriverBindingStart,
Cbi0DriverBindingStop,
0x10,
NULL,
NULL
};
STATIC
EFI_STATUS
Cbi0RecoveryReset (
IN USB_CBI_DEVICE *UsbCbiDev
);
STATIC
EFI_STATUS
Cbi0CommandPhase (
IN USB_CBI_DEVICE *UsbCbiDev,
IN VOID *Command,
IN UINT8 CommandSize,
IN UINT16 Timeout
);
STATIC
EFI_STATUS
Cbi0DataPhase (
IN USB_CBI_DEVICE *UsbCbiDev,
IN UINT32 *DataSize,
IN OUT VOID *DataBuffer,
IN EFI_USB_DATA_DIRECTION Direction,
IN UINT16 Timeout
);
STATIC
EFI_STATUS
Cbi0StatusPhase (
IN USB_CBI_DEVICE *UsbCbiDev,
OUT INTERRUPT_DATA_BLOCK *InterruptDataBlock,
IN UINT16 Timeout
);
//
// USB Atapi protocol prototype
//
STATIC
EFI_STATUS
EFIAPI
Cbi0AtapiCommand (
IN EFI_USB_ATAPI_PROTOCOL *This,
IN VOID *Command,
IN UINT8 CommandSize,
IN VOID *DataBuffer,
IN UINT32 BufferLength,
IN EFI_USB_DATA_DIRECTION Direction,
IN UINT16 TimeOutInMilliSeconds
);
STATIC
EFI_STATUS
EFIAPI
Cbi0MassStorageReset (
IN EFI_USB_ATAPI_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
);
STATIC EFI_USB_ATAPI_PROTOCOL Cbi0AtapiProtocol = {
Cbi0AtapiCommand,
Cbi0MassStorageReset,
0
};
EFI_DRIVER_ENTRY_POINT (UsbCbi0DriverEntryPoint)
EFI_STATUS
EFIAPI
UsbCbi0DriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Register Driver Binding protocol for this driver.
Arguments:
ImageHandle - EFI_HANDLE
SystemTable - EFI_SYSTEM_TABLE
Returns:
EFI_SUCCESS - Driver loaded
other - Driver not loaded
--*/
{
return EfiLibInstallAllDriverProtocols (
ImageHandle,
SystemTable,
&gUsbCbi0DriverBinding,
ImageHandle,
&gUsbCbi0ComponentName,
NULL,
NULL
);
}
STATIC
EFI_STATUS
EFIAPI
Cbi0DriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Test to see if this driver supports ControllerHandle. Any ControllerHandle
than contains a BlockIo and DiskIo protocol can 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_ALREADY_STARTED - This driver is already running on this device
other - This driver does not support this device
--*/
{
EFI_STATUS Status;
EFI_USB_IO_PROTOCOL *UsbIo;
EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
//
// Check if the Controller supports USB IO protocol
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiUsbIoProtocolGuid,
&UsbIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get the Default interface descriptor, now we only
// suppose interface 1
//
Status = UsbIo->UsbGetInterfaceDescriptor (
UsbIo,
&InterfaceDescriptor
);
if (EFI_ERROR (Status)) {
gBS->CloseProtocol (
ControllerHandle,
&gEfiUsbIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return Status;
}
//
// Check if it is a Cbi0 Type Mass Storage Device
//
if((InterfaceDescriptor.InterfaceClass != MASS_STORAGE_CLASS) ||
(InterfaceDescriptor.InterfaceProtocol != CBI0_INTERFACE_PROTOCOL)) {
Status = EFI_UNSUPPORTED;
} else {
Status = EFI_SUCCESS;
}
gBS->CloseProtocol (
ControllerHandle,
&gEfiUsbIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return Status;
}
STATIC
EFI_STATUS
EFIAPI
Cbi0DriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Start this driver on ControllerHandle by opening a Block IO and Disk IO
protocol, reading Device Path, and creating a child handle with a
Disk IO and device path protocol.
Arguments:
This - Protocol instance pointer.
ControllerHandle - Handle of device to bind driver to
RemainingDevicePath - Not used
Returns:
EFI_SUCCESS - This driver is added to DeviceHandle
EFI_ALREADY_STARTED - This driver is already running on DeviceHandle
other - This driver does not support this device
EFI_OUT_OF_RESOURCES- Can't allocate memory
EFI_UNSUPPORTED - Endpoint is not as expected
--*/
{
USB_CBI_DEVICE *UsbCbiDev;
UINT8 Index;
EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
EFI_STATUS Status;
EFI_USB_IO_PROTOCOL *UsbIo;
UINT8 EndpointExistMask;
//
// Check if the Controller supports USB IO protocol
//
UsbCbiDev = NULL;
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiUsbIoProtocolGuid,
&UsbIo,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get the controller interface descriptor
//
Status = UsbIo->UsbGetInterfaceDescriptor (
UsbIo,
&InterfaceDescriptor
);
if (EFI_ERROR (Status)) {
gBS->CloseProtocol (
ControllerHandle,
&gEfiUsbIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return Status;
}
Cbi0AtapiProtocol.CommandProtocol = InterfaceDescriptor.InterfaceSubClass;
UsbCbiDev = EfiLibAllocateZeroPool (sizeof (USB_CBI_DEVICE));
if (UsbCbiDev == NULL) {
gBS->CloseProtocol (
ControllerHandle,
&gEfiUsbIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return EFI_OUT_OF_RESOURCES;
}
UsbCbiDev->Signature = USB_CBI_DEVICE_SIGNATURE;
UsbCbiDev->UsbIo = UsbIo;
UsbCbiDev->InterfaceDescriptor = InterfaceDescriptor;
UsbCbiDev->UsbAtapiProtocol = Cbi0AtapiProtocol;
//
// Get the Device Path Protocol on Controller's handle
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
(VOID **) &UsbCbiDev->DevicePath,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
gBS->CloseProtocol (
ControllerHandle,
&gEfiUsbIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
if (UsbCbiDev != NULL) {
gBS->FreePool (UsbCbiDev);
}
return Status;
}
//
// Mask used to see whether all three kinds of endpoints exist,
// Mask value:
// bit0: bulk in endpoint;
// bit1: bulk out endpoint;
// bit2: interrupt in endpoint;
//
EndpointExistMask = 0;
for (Index = 0; Index < InterfaceDescriptor.NumEndpoints; Index++) {
UsbIo->UsbGetEndpointDescriptor (
UsbIo,
Index,
&EndpointDescriptor
);
//
// We parse bulk endpoint
//
if (EndpointDescriptor.Attributes == 0x02) {
if (EndpointDescriptor.EndpointAddress & 0x80) {
UsbCbiDev->BulkInEndpointDescriptor = EndpointDescriptor;
EndpointExistMask |= bit (0);
} else {
UsbCbiDev->BulkOutEndpointDescriptor = EndpointDescriptor;
EndpointExistMask |= bit (1);
}
}
//
// We parse interrupt endpoint
//
if (EndpointDescriptor.Attributes == 0x03) {
UsbCbiDev->InterruptEndpointDescriptor = EndpointDescriptor;
EndpointExistMask |= bit (2);
}
}
//
// Double check we have all endpoints needed
//
if (EndpointExistMask != (bit (0) | bit (1) | bit (2))) {
gBS->CloseProtocol (
ControllerHandle,
&gEfiUsbIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
if (UsbCbiDev != NULL) {
gBS->FreePool (UsbCbiDev);
}
return EFI_UNSUPPORTED;
}
//
// After installing Usb-Atapi protocol onto this handle
// it will be called by upper layer drivers such as Fat
//
Cbi0ReportStatusCode (
UsbCbiDev->DevicePath,
EFI_PROGRESS_CODE,
(EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_ENABLE)
);
Status = gBS->InstallProtocolInterface (
&ControllerHandle,
&gEfiUsbAtapiProtocolGuid,
EFI_NATIVE_INTERFACE,
&UsbCbiDev->UsbAtapiProtocol
);
if (EFI_ERROR (Status)) {
gBS->CloseProtocol (
ControllerHandle,
&gEfiUsbIoProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
if (UsbCbiDev != NULL) {
gBS->FreePool (UsbCbiDev);
}
return Status;
}
UsbCbiDev->ControllerNameTable = NULL;
EfiLibAddUnicodeString (
"eng",
gUsbCbi0ComponentName.SupportedLanguages,
&UsbCbiDev->ControllerNameTable,
L"Usb Cbi0 Mass Storage"
);
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
Cbi0DriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Stop this driver on ControllerHandle. Support stoping any child handles
created by this driver.
Arguments:
This - Protocol instance pointer.
ControllerHandle - Handle of device to stop driver on
NumberOfChildren - Number of Children in the ChildHandleBuffer
ChildHandleBuffer - List of handles for the children we need to stop.
Returns:
EFI_SUCCESS - This driver is removed DeviceHandle
EFI_UNSUPPORTED - This driver was not removed from this device
--*/
{
EFI_STATUS Status;
EFI_USB_ATAPI_PROTOCOL *Cbi0AtapiProtocol;
USB_CBI_DEVICE *UsbCbiDev;
EFI_USB_IO_PROTOCOL *UsbIo;
//
// Get our context back.
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiUsbAtapiProtocolGuid,
&Cbi0AtapiProtocol,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
UsbCbiDev = USB_CBI_DEVICE_FROM_THIS (Cbi0AtapiProtocol);
UsbIo = UsbCbiDev->UsbIo;
Cbi0ReportStatusCode (
UsbCbiDev->DevicePath,
EFI_PROGRESS_CODE,
(EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_DISABLE)
);
//
// Uninstall protocol
//
Status = gBS->UninstallProtocolInterface (
ControllerHandle,
&gEfiUsbAtapiProtocolGuid,
&UsbCbiDev->UsbAtapiProtocol
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->CloseProtocol (
ControllerHandle,
&gEfiUsbIoProtocolGuid,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?