ehcisched.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,975 行 · 第 1/5 页
C
2,975 行
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto exit;
}
//
// Software field
//
(*QhPtrPtr)->Next = (*QhPtrPtr);
(*QhPtrPtr)->Prev = (*QhPtrPtr);
(*QhPtrPtr)->TransferType = CONTROL_TRANSFER;
//
// Hardware field
//
// Control Transfer use DataToggleControl
//
(*QhPtrPtr)->Qh.DataToggleControl = TRUE;
(*QhPtrPtr)->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&((*QhPtrPtr)->Qh)) >> 5);
(*QhPtrPtr)->Qh.SelectType = QH_SELECT_TYPE;
(*QhPtrPtr)->Qh.QhTerminate = FALSE;
if (EFI_USB_SPEED_HIGH != DeviceSpeed) {
(*QhPtrPtr)->Qh.ControlEndpointFlag = TRUE;
}
(*QhPtrPtr)->Qh.NakCountReload = NAK_COUNT_RELOAD;
if (NULL != Translator) {
(*QhPtrPtr)->Qh.PortNum = Translator->TranslatorPortNumber;
(*QhPtrPtr)->Qh.HubAddr = Translator->TranslatorHubAddress;
(*QhPtrPtr)->Qh.Status |= QTD_STATUS_DO_START_SPLIT;
}
exit:
return Status;
}
EFI_STATUS
CreateBulkQh (
IN USB2_HC_DEV *HcDev,
IN UINT8 DeviceAddr,
IN UINT8 EndPointAddr,
IN UINT8 DeviceSpeed,
IN UINT8 DataToggle,
IN UINTN MaxPacketLen,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT EHCI_QH_ENTITY **QhPtrPtr
)
/*++
Routine Description:
Create Qh for Bulk Transfer
Arguments:
HcDev - USB2_HC_DEV
DeviceAddr - Address of Device
EndPointAddr - Address of Endpoint
DeviceSpeed - Device Speed
MaxPacketLen - Max Length of one Packet
Translator - Translator Transaction for SplitX
QhPtrPtr - A pointer of pointer to Qh for return
Returns:
EFI_SUCCESS Success
EFI_OUT_OF_RESOURCES Cannot allocate resources
--*/
{
EFI_STATUS Status;
//
// Create and init Bulk Qh
//
Status = CreateQh (
HcDev,
DeviceAddr,
EndPointAddr,
DeviceSpeed,
MaxPacketLen,
QhPtrPtr
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto exit;
}
//
// Software fields
//
(*QhPtrPtr)->Next = (*QhPtrPtr);
(*QhPtrPtr)->Prev = (*QhPtrPtr);
(*QhPtrPtr)->TransferType = BULK_TRANSFER;
//
// Hardware fields
//
// BulkTransfer don't use DataToggleControl
//
(*QhPtrPtr)->Qh.DataToggleControl = FALSE;
(*QhPtrPtr)->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&((*QhPtrPtr)->Qh)) >> 5);
(*QhPtrPtr)->Qh.SelectType = QH_SELECT_TYPE;
(*QhPtrPtr)->Qh.QhTerminate = FALSE;
(*QhPtrPtr)->Qh.NakCountReload = NAK_COUNT_RELOAD;
(*QhPtrPtr)->Qh.DataToggle = DataToggle;
if (NULL != Translator) {
(*QhPtrPtr)->Qh.PortNum = Translator->TranslatorPortNumber;
(*QhPtrPtr)->Qh.HubAddr = Translator->TranslatorHubAddress;
(*QhPtrPtr)->Qh.Status |= QTD_STATUS_DO_START_SPLIT;
}
exit:
return Status;
}
EFI_STATUS
CreateInterruptQh (
IN USB2_HC_DEV *HcDev,
IN UINT8 DeviceAddr,
IN UINT8 EndPointAddr,
IN UINT8 DeviceSpeed,
IN UINT8 DataToggle,
IN UINTN MaxPacketLen,
IN UINTN Interval,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT EHCI_QH_ENTITY **QhPtrPtr
)
/*++
Routine Description:
Create Qh for Control Transfer
Arguments:
HcDev - USB2_HC_DEV
DeviceAddr - Address of Device
EndPointAddr - Address of Endpoint
DeviceSpeed - Device Speed
MaxPacketLen - Max Length of one Packet
Interval - value of interval
Translator - Translator Transaction for SplitX
QhPtrPtr - A pointer of pointer to Qh for return
Returns:
EFI_SUCCESS Success
EFI_OUT_OF_RESOURCES Cannot allocate resources
--*/
{
EFI_STATUS Status;
//
// Create and init InterruptQh
//
Status = CreateQh (
HcDev,
DeviceAddr,
EndPointAddr,
DeviceSpeed,
MaxPacketLen,
QhPtrPtr
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto exit;
}
//
// Software fields
//
if (Interval == 0) {
(*QhPtrPtr)->TransferType = SYNC_INTERRUPT_TRANSFER;
} else {
(*QhPtrPtr)->TransferType = ASYNC_INTERRUPT_TRANSFER;
}
(*QhPtrPtr)->Interval = GetApproxiOfInterval (Interval);
//
// Hardware fields
//
// InterruptTranfer don't use DataToggleControl
//
(*QhPtrPtr)->Qh.DataToggleControl = FALSE;
(*QhPtrPtr)->Qh.QhHorizontalPointer = 0;
(*QhPtrPtr)->Qh.QhTerminate = TRUE;
(*QhPtrPtr)->Qh.NakCountReload = 0;
(*QhPtrPtr)->Qh.InerruptScheduleMask = MICRO_FRAME_0_CHANNEL;
(*QhPtrPtr)->Qh.SplitComletionMask = (MICRO_FRAME_2_CHANNEL | MICRO_FRAME_3_CHANNEL | MICRO_FRAME_4_CHANNEL);
(*QhPtrPtr)->Qh.DataToggle = DataToggle;
if (NULL != Translator) {
(*QhPtrPtr)->Qh.PortNum = Translator->TranslatorPortNumber;
(*QhPtrPtr)->Qh.HubAddr = Translator->TranslatorHubAddress;
(*QhPtrPtr)->Qh.Status |= QTD_STATUS_DO_START_SPLIT;
}
exit:
return Status;
}
EFI_STATUS
CreateQtd (
IN USB2_HC_DEV *HcDev,
IN UINT8 *DataPtr,
IN UINTN DataLen,
IN UINT8 PktId,
IN UINT8 Toggle,
IN UINT8 QtdStatus,
OUT EHCI_QTD_ENTITY **QtdPtrPtr
)
/*++
Routine Description:
Create Qtd Structure and Pre-Initialize it
Arguments:
HcDev - USB2_HC_DEV
DataPtr - A pointer to user data buffer to transfer
DataLen - Length of user data to transfer
PktId - Packet Identification of this Qtd
Toggle - Data Toggle of this Qtd
QtdStatus - Default value of status of this Qtd
QtdPtrPtr - A pointer of pointer to Qtd for return
Returns:
EFI_SUCCESS Success
EFI_OUT_OF_RESOURCES Cannot allocate resources
--*/
{
EFI_STATUS Status;
EHCI_QTD_HW *QtdHwPtr;
ASSERT (HcDev);
ASSERT (QtdPtrPtr);
//
// Create memory for Qtd structure
//
Status = EhciAllocatePool (
HcDev,
(UINT8 **) QtdPtrPtr,
sizeof (EHCI_QTD_ENTITY)
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto exit;
}
//
// Software field
//
(*QtdPtrPtr)->TotalBytes = (UINT32) DataLen;
(*QtdPtrPtr)->StaticTotalBytes = (UINT32) DataLen;
(*QtdPtrPtr)->Prev = NULL;
(*QtdPtrPtr)->Next = NULL;
//
// Hardware field
//
QtdHwPtr = &((*QtdPtrPtr)->Qtd);
QtdHwPtr->NextQtdPointer = 0;
QtdHwPtr->NextQtdTerminate = TRUE;
QtdHwPtr->AltNextQtdPointer = 0;
QtdHwPtr->AltNextQtdTerminate = TRUE;
QtdHwPtr->DataToggle = Toggle;
QtdHwPtr->TotalBytes = (UINT32) DataLen;
QtdHwPtr->CurrentPage = 0;
QtdHwPtr->ErrorCount = QTD_ERROR_COUNTER;
QtdHwPtr->Status = QtdStatus;
QtdHwPtr->Rsvd1 = 0;
QtdHwPtr->Rsvd2 = 0;
QtdHwPtr->Rsvd3 = 0;
QtdHwPtr->Rsvd4 = 0;
QtdHwPtr->Rsvd5 = 0;
QtdHwPtr->Rsvd6 = 0;
//
// Set PacketID [Setup/Data/Status]
//
switch (PktId) {
case SETUP_PACKET_ID:
QtdHwPtr->PidCode = SETUP_PACKET_PID_CODE;
break;
case INPUT_PACKET_ID:
QtdHwPtr->PidCode = INPUT_PACKET_PID_CODE;
break;
case OUTPUT_PACKET_ID:
QtdHwPtr->PidCode = OUTPUT_PACKET_PID_CODE;
break;
default:
Status = EFI_INVALID_PARAMETER;
goto exit;
}
//
// Set Data Buffer Pointers
//
if (NULL != DataPtr) {
SetQtdBufferPointer (
QtdHwPtr,
DataPtr,
DataLen
);
(*QtdPtrPtr)->StaticCurrentOffset = QtdHwPtr->CurrentOffset;
}
exit:
return Status;
}
EFI_STATUS
CreateSetupQtd (
IN USB2_HC_DEV *HcDev,
IN UINT8 *DevReqPtr,
OUT EHCI_QTD_ENTITY **QtdPtrPtr
)
/*++
Routine Description:
Create Qtd Structure for Setup
Arguments:
HcDev - USB2_HC_DEV
DevReqPtr - A pointer to Device Request Data
QtdPtrPtr - A pointer of pointer to Qtd for return
Returns:
EFI_SUCCESS Success
EFI_OUT_OF_RESOURCES Cannot allocate resources
--*/
{
return CreateQtd (
HcDev,
DevReqPtr,
sizeof (EFI_USB_DEVICE_REQUEST),
SETUP_PACKET_ID,
DATA0,
QTD_STATUS_ACTIVE,
QtdPtrPtr
);
}
EFI_STATUS
CreateDataQtd (
IN USB2_HC_DEV *HcDev,
IN UINT8 *DataPtr,
IN UINTN DataLen,
IN UINT8 PktId,
IN UINT8 Toggle,
OUT EHCI_QTD_ENTITY **QtdPtrPtr
)
/*++
Routine Description:
Create Qtd Structure for data
Arguments:
HcDev - USB2_HC_DEV
DataPtr - A pointer to user data buffer to transfer
DataLen - Length of user data to transfer
PktId - Packet Identification of this Qtd
Toggle - Data Toggle of this Qtd
QtdPtrPtr - A pointer of pointer to Qtd for return
Returns:
EFI_SUCCESS Success
EFI_OUT_OF_RESOURCES Cannot allocate resources
--*/
{
return CreateQtd (
HcDev,
DataPtr,
DataLen,
PktId,
Toggle,
QTD_STATUS_ACTIVE,
QtdPtrPtr
);
}
EFI_STATUS
CreateAltQtd (
IN USB2_HC_DEV *HcDev,
IN UINT8 PktId,
OUT EHCI_QTD_ENTITY **QtdPtrPtr
)
/*++
Routine Description:
Create Qtd Structure for Alternative
Arguments:
HcDev - USB2_HC_DEV
PktId - Packet Identification of this Qtd
QtdPtrPtr - A pointer of pointer to Qtd for return
Returns:
EFI_SUCCESS Success
EFI_OUT_OF_RESOURCES Cannot allocate resources
--*/
{
return CreateQtd (
HcDev,
NULL,
0,
PktId,
0,
QTD_STATUS_ACTIVE,
QtdPtrPtr
);
}
EFI_STATUS
CreateStatusQtd (
IN USB2_HC_DEV *HcDev,
IN UINT8 PktId,
OUT EHCI_QTD_ENTITY **QtdPtrPtr
)
/*++
Routine Description:
Create Qtd Structure for status
Arguments:
HcDev - USB2_HC_DEV
PktId - Packet Identification of this Qtd
QtdPtrPtr - A pointer of pointer to Qtd for return
Returns:
EFI_SUCCESS Success
EFI_OUT_OF_RESOURCES Cannot allocate resources
--*/
{
return CreateQtd (
HcDev,
NULL,
0,
PktId,
DATA1,
QTD_STATUS_ACTIVE,
QtdPtrPtr
);
}
EFI_STATUS
CreateControlQtds (
IN USB2_HC_DEV *HcDev,
IN UINT8 DataPktId,
IN UINT8 *RequestCursor,
IN UINT8 *DataCursor,
IN UINTN DataLen,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT EHCI_QTD_ENTITY **ControlQtdsHead
)
/*++
Routine Description:
Create Qtds list for Control Transfer
Arguments:
HcDev - USB2_HC_DEV
DataPktId - Packet Identification of Data Qtds
RequestCursor - A pointer to request structure buffer to transfer
DataCursor - A pointer to user data buffer to transfer
DataLen - Length of user data to transfer
ControlQtdsHead - A pointer of pointer to first Qtd for control tranfer for return
Returns:
EFI_SUCCESS Success
EFI_OUT_OF_RESOURCES Cannot allocate resources
--*/
{
EFI_STATUS Status;
EHCI_QTD_ENTITY *QtdPtr;
EHCI_QTD_ENTITY *PreQtdPtr;
EHCI_QTD_ENTITY *SetupQtdPtr;
EHCI_QTD_ENTITY *FirstDataQtdPtr;
EHCI_QTD_ENTITY *LastDataQtdPtr;
EHCI_QTD_ENTITY *StatusQtdPtr;
UINT8 DataToggle;
UINT8 StatusPktId;
UINTN CapacityOfQtd;
UINTN SizePerQtd;
UINTN DataCount;
QtdPtr = NULL;
PreQtdPtr = NULL;
SetupQtdPtr = NULL;
FirstDataQtdPtr = NULL;
LastDataQtdPtr = NULL;
StatusQtdPtr = NULL;
CapacityOfQtd = 0;
//
// Setup Stage of Control Transfer
//
Status = CreateSetupQtd (
HcDev,
RequestCursor,
&SetupQtdPtr
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto exit;
}
//
// Data Stage of Control Transfer
//
DataToggle = 1;
DataCount = DataLen;
//
// Create Qtd structure and link together
//
while (DataCount > 0) {
//
// PktSize is the data load size that each Qtd.
//
CapacityOfQtd = GetCapacityOfQtd (DataCursor);
SizePerQtd = DataCount;
if (DataCount > CapacityOfQtd) {
SizePerQtd = CapacityOfQtd;
}
Status = CreateDataQtd (
HcDev,
DataCursor,
SizePerQtd,
DataPktId,
DataToggle,
&QtdPtr
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
if (NULL == FirstDataQtdPtr) {
goto destory_setup_qtd;
} else {
goto destory_qtds;
}
}
if (NULL == FirstDataQtdPtr) {
FirstDataQtdPtr = QtdPtr;
} else {
LinkQtdToQtd (PreQtdPtr, QtdPtr);
}
DataToggle ^= 1;
PreQtdPtr = QtdPtr;
DataCursor += SizePerQtd;
DataCount -= SizePerQtd;
}
LastDataQtdPtr = QtdPtr;
//
// Status Stage of Control Transfer
//
if (OUTPUT_PACKET_ID == DataPktId) {
StatusPktId = INPUT_PACKET_ID;
} else {
StatusPktId = OUTPUT_PACKET_ID;
}
Status = CreateStatusQtd (
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?