uhchlp.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 3,348 行 · 第 1/5 页
C
3,348 行
Status = CreateTD (HcDev, &pTDStruct);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
SetTDLinkPtr (pTDStruct, NULL);
//
// Depth first fashion
//
SetTDLinkPtrDepthorBreadth (pTDStruct, TRUE);
//
// initialize as the last TD in the QH context,
// this field will be updated in the TD linkage process.
//
SetTDLinkPtrValidorInvalid (pTDStruct, FALSE);
//
// Disable Short Packet Detection by default
//
EnableorDisableTDShortPacket (pTDStruct, FALSE);
//
// Max error counter is 3, retry 3 times when error encountered.
//
SetTDControlErrorCounter (pTDStruct, 3);
//
// set device speed attribute
// (TRUE - Slow Device; FALSE - Full Speed Device)
//
SetTDLoworFullSpeedDevice (pTDStruct, bSlow);
//
// Non isochronous transfer TD
//
SetTDControlIsochronousorNot (pTDStruct, FALSE);
//
// Interrupt On Complete bit be set to zero,
// Disable IOC interrupt.
//
SetorClearTDControlIOC (pTDStruct, FALSE);
//
// Set TD Active bit
//
SetTDStatusActiveorInactive (pTDStruct, TRUE);
SetTDTokenMaxLength (pTDStruct, RequestLen);
SetTDTokenDataToggle0 (pTDStruct);
SetTDTokenEndPoint (pTDStruct, Endpoint);
SetTDTokenDeviceAddress (pTDStruct, DevAddr);
SetTDTokenPacketID (pTDStruct, SETUP_PACKET_ID);
pTDStruct->pTDBuffer = (UINT8 *) pDevReq;
pTDStruct->TDBufferLength = RequestLen;
SetTDDataBuffer (pTDStruct);
*ppTD = pTDStruct;
return EFI_SUCCESS;
}
EFI_STATUS
GenDataTD (
IN USB_HC_DEV *HcDev,
IN UINT8 DevAddr,
IN UINT8 Endpoint,
IN UINT8 *pData,
IN UINT8 Len,
IN UINT8 PktID,
IN UINT8 Toggle,
IN BOOLEAN bSlow,
OUT TD_STRUCT **ppTD
)
/*++
Routine Description:
Generate Data Stage TD
Arguments:
HcDev - USB_HC_DEV
DevAddr - Device address
Endpoint - Endpoint number
pData - Data buffer
Len - Data length
PktID - Packet ID
Toggle - Data toggle value
bSlow - Full speed or low speed
ppTD - TD_STRUCT to return
Returns:
EFI_OUT_OF_RESOURCES - Can't allocate memory
EFI_SUCCESS - Success
--*/
{
TD_STRUCT *pTDStruct;
EFI_STATUS Status;
Status = CreateTD (HcDev, &pTDStruct);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
SetTDLinkPtr (pTDStruct, NULL);
//
// Depth first fashion
//
SetTDLinkPtrDepthorBreadth (pTDStruct, TRUE);
//
// Link pointer pointing to TD struct
//
SetTDLinkPtrQHorTDSelect (pTDStruct, FALSE);
//
// initialize as the last TD in the QH context,
// this field will be updated in the TD linkage process.
//
SetTDLinkPtrValidorInvalid (pTDStruct, FALSE);
//
// Disable short packet detect
//
EnableorDisableTDShortPacket (pTDStruct, FALSE);
//
// Max error counter is 3
//
SetTDControlErrorCounter (pTDStruct, 3);
//
// set device speed attribute
// (TRUE - Slow Device; FALSE - Full Speed Device)
//
SetTDLoworFullSpeedDevice (pTDStruct, bSlow);
//
// Non isochronous transfer TD
//
SetTDControlIsochronousorNot (pTDStruct, FALSE);
//
// Disable Interrupt On Complete
// Disable IOC interrupt.
//
SetorClearTDControlIOC (pTDStruct, FALSE);
//
// Set Active bit
//
SetTDStatusActiveorInactive (pTDStruct, TRUE);
SetTDTokenMaxLength (pTDStruct, Len);
if (Toggle) {
SetTDTokenDataToggle1 (pTDStruct);
} else {
SetTDTokenDataToggle0 (pTDStruct);
}
SetTDTokenEndPoint (pTDStruct, Endpoint);
SetTDTokenDeviceAddress (pTDStruct, DevAddr);
SetTDTokenPacketID (pTDStruct, PktID);
pTDStruct->pTDBuffer = (UINT8 *) pData;
pTDStruct->TDBufferLength = Len;
SetTDDataBuffer (pTDStruct);
*ppTD = pTDStruct;
return EFI_SUCCESS;
}
EFI_STATUS
CreateStatusTD (
IN USB_HC_DEV *HcDev,
IN UINT8 DevAddr,
IN UINT8 Endpoint,
IN UINT8 PktID,
IN BOOLEAN bSlow,
OUT TD_STRUCT **ppTD
)
/*++
Routine Description:
Generate Status Stage TD
Arguments:
HcDev - USB_HC_DEV
DevAddr - Device address
Endpoint - Endpoint number
PktID - Packet ID
bSlow - Full speed or low speed
ppTD - TD_STRUCT to return
Returns:
EFI_OUT_OF_RESOURCES - Can't allocate memory
EFI_SUCCESS - Success
--*/
{
TD_STRUCT *ptrTDStruct;
EFI_STATUS Status;
Status = CreateTD (HcDev, &ptrTDStruct);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
SetTDLinkPtr (ptrTDStruct, NULL);
//
// Depth first fashion
//
SetTDLinkPtrDepthorBreadth (ptrTDStruct, TRUE);
//
// initialize as the last TD in the QH context,
// this field will be updated in the TD linkage process.
//
SetTDLinkPtrValidorInvalid (ptrTDStruct, FALSE);
//
// Disable short packet detect
//
EnableorDisableTDShortPacket (ptrTDStruct, FALSE);
//
// Max error counter is 3
//
SetTDControlErrorCounter (ptrTDStruct, 3);
//
// set device speed attribute
// (TRUE - Slow Device; FALSE - Full Speed Device)
//
SetTDLoworFullSpeedDevice (ptrTDStruct, bSlow);
//
// Non isochronous transfer TD
//
SetTDControlIsochronousorNot (ptrTDStruct, FALSE);
//
// Disable Interrupt On Complete
// Disable IOC interrupt.
//
SetorClearTDControlIOC (ptrTDStruct, FALSE);
//
// Set TD Active bit
//
SetTDStatusActiveorInactive (ptrTDStruct, TRUE);
SetTDTokenMaxLength (ptrTDStruct, 0);
SetTDTokenDataToggle1 (ptrTDStruct);
SetTDTokenEndPoint (ptrTDStruct, Endpoint);
SetTDTokenDeviceAddress (ptrTDStruct, DevAddr);
SetTDTokenPacketID (ptrTDStruct, PktID);
ptrTDStruct->pTDBuffer = NULL;
ptrTDStruct->TDBufferLength = 0;
SetTDDataBuffer (ptrTDStruct);
*ppTD = ptrTDStruct;
return EFI_SUCCESS;
}
VOID
SetTDLinkPtrValidorInvalid (
IN TD_STRUCT *ptrTDStruct,
IN BOOLEAN bValid
)
/*++
Routine Description:
Set TD Link Pointer Valid or Invalid
Arguments:
ptrTDStruct - TD_STRUCT
bValid - TRUE is valid FALSE is invalid
Returns:
VOID
--*/
{
//
// Valid means the link pointer is valid,
// else, it's invalid.
//
ptrTDStruct->TDData.TDLinkPtrTerminate = (bValid ? 0 : 1);
}
VOID
SetTDLinkPtrQHorTDSelect (
IN TD_STRUCT *ptrTDStruct,
IN BOOLEAN bQH
)
/*++
Routine Description:
Set TD Link Pointer QH or TD Select
Arguments:
ptrTDStruct - TD_STRUCT
bQH - TRUE is QH FALSE is TD
Returns:
VOID
--*/
{
//
// Indicate whether the Link Pointer pointing to a QH or TD
//
ptrTDStruct->TDData.TDLinkPtrQSelect = (bQH ? 1 : 0);
}
VOID
SetTDLinkPtrDepthorBreadth (
IN TD_STRUCT *ptrTDStruct,
IN BOOLEAN bDepth
)
/*++
Routine Description:
Set TD Link Pointer depth or bread priority
Arguments:
ptrTDStruct - TD_STRUCT
bDepth - TRUE is Depth FALSE is Breadth
Returns:
VOID
--*/
{
//
// If TRUE, indicating the host controller should process in depth first
// fashion,
// else, the host controller should process in breadth first fashion
//
ptrTDStruct->TDData.TDLinkPtrDepthSelect = (bDepth ? 1 : 0);
}
VOID
SetTDLinkPtr (
IN TD_STRUCT *ptrTDStruct,
IN VOID *ptrNext
)
/*++
Routine Description:
Set TD Link Pointer
Arguments:
ptrTDStruct - TD_STRUCT
ptrNext - Pointer to set
Returns:
VOID
--*/
{
//
// Set TD Link Pointer. Since QH,TD align on 16-byte boundaries,
// only the highest 28 bits are valid. (if take 32bit address as an example)
//
ptrTDStruct->TDData.TDLinkPtr = (UINT32) ((UINTN) ptrNext >> 4);
}
VOID *
GetTDLinkPtr (
IN TD_STRUCT *ptrTDStruct
)
/*++
Routine Description:
Get TD Link Pointer
Arguments:
ptrTDStruct - TD_STRUCT
Returns:
Pointer to get
--*/
{
//
// Get TD Link Pointer. Restore it back to 32bit
// (if take 32bit address as an example)
//
return (VOID *) ((UINTN) (ptrTDStruct->TDData.TDLinkPtr << 4));
}
BOOLEAN
IsTDLinkPtrQHOrTD (
IN TD_STRUCT *ptrTDStruct
)
/*++
Routine Description:
Is TD Link Pointer is QH Or TD
Arguments:
ptrTDStruct - TODO: add argument description
Returns:
TRUE - QH
FALSE - TD
--*/
{
//
// Get the information about whether the Link Pointer field pointing to
// a QH or a TD.
//
return (BOOLEAN) (ptrTDStruct->TDData.TDLinkPtrQSelect);
}
VOID
EnableorDisableTDShortPacket (
IN TD_STRUCT *ptrTDStruct,
IN BOOLEAN bEnable
)
/*++
Routine Description:
Enable or Disable TD ShortPacket
Arguments:
ptrTDStruct - TD_STRUCT
bEnable - TRUE is Enanble FALSE is Disable
Returns:
VOID
--*/
{
//
// TRUE means enable short packet detection mechanism.
//
ptrTDStruct->TDData.TDStatusSPD = (bEnable ? 1 : 0);
}
VOID
SetTDControlErrorCounter (
IN TD_STRUCT *ptrTDStruct,
IN UINT8 nMaxErrors
)
/*++
Routine Description:
Set TD Control ErrorCounter
Arguments:
ptrTDStruct - TD_STRUCT
nMaxErrors - Error counter number
Returns:
VOID
--*/
{
//
// valid value of nMaxErrors is 0,1,2,3
//
if (nMaxErrors > 3) {
nMaxErrors = 3;
}
ptrTDStruct->TDData.TDStatusErr = nMaxErrors;
}
VOID
SetTDLoworFullSpeedDevice (
IN TD_STRUCT *ptrTDStruct,
IN BOOLEAN bLowSpeedDevice
)
{
//
// TRUE means the TD is targeting at a Low-speed device
//
ptrTDStruct->TDData.TDStatusLS = (bLowSpeedDevice ? 1 : 0);
}
VOID
SetTDControlIsochronousorNot (
IN TD_STRUCT *ptrTDStruct,
IN BOOLEAN IsIsochronous
)
{
//
// TRUE means the TD belongs to Isochronous transfer type.
//
ptrTDStruct->TDData.TDStatusIOS = (IsIsochronous ? 1 : 0);
}
VOID
SetorClearTDControlIOC (
IN TD_STRUCT *ptrTDStruct,
IN BOOLEAN IsSet
)
{
//
// If this bit is set, it indicates that the host controller should issue
// an interrupt on completion of the frame in which this TD is executed.
//
ptrTDStruct->TDData.TDStatusIOC = IsSet ? 1 : 0;
}
VOID
SetTDStatusActiveorInactive (
IN TD_STRUCT *ptrTDStruct,
IN BOOLEAN IsActive
)
{
//
// If this bit is set, it indicates that the TD is active and can be
// executed.
//
if (IsActive) {
ptrTDStruct->TDData.TDStatus |= 0x80;
} else {
ptrTDStruct->TDData.TDStatus &= 0x7F;
}
}
UINT16
SetTDTokenMaxLength (
IN TD_STRUCT *ptrTDStruct,
IN UINT16 MaximumLength
)
{
//
// Specifies the maximum number of data bytes allowed for the transfer.
// the legal value extent is 0 ~ 0x500.
//
if (MaximumLength > 0x500) {
MaximumLength = 0x500;
}
ptrTDStruct->TDData.TDTokenMaxLen = MaximumLength - 1;
return MaximumLength;
}
VOID
SetTDTokenDataToggle1 (
IN TD_STRUCT *ptrTDStruct
)
{
//
// Set the data toggle bit to DATA1
//
ptrTDStruct->TDData.TDTokenDataToggle = 1;
}
VOID
SetTDTokenDataToggle0 (
IN TD_STRUCT *ptrTDStruct
)
{
//
// Set the data toggle bit to DATA0
//
ptrTDStruct->TDData.TDTokenDataToggle = 0;
}
UINT8
GetTDTokenDataToggle (
IN TD_STRUCT *ptrTDStruct
)
{
//
// Get the data toggle value.
//
return (UINT8) (ptrTDStruct->TDData.TDTokenDataToggle);
}
VOID
SetTDTokenEndPoint (
IN TD_STRUCT *ptrTDStruct,
IN UINTN EndPoint
)
{
//
// Set EndPoint Number the TD is targeting at.
//
ptrTDStruct->TDData.TDTokenEndPt = (UINT8) EndPoint;
}
VOID
SetTDTokenDeviceAddress (
IN TD_STRUCT *ptrTDStruct,
IN UINTN DeviceAddress
)
{
//
// Set Device Address the TD is targeting at.
//
ptrTDStruct->TDData.TDTokenDevAddr = (UINT8) DeviceAddress;
}
VOID
SetTDTokenPacketID (
IN TD_STRUCT *ptrTDStruct,
IN UINT8 PID
)
{
//
// Set the Packet Identification to be used for this transaction.
//
ptrTDStruct->TDData.TDTokenPID = PID;
}
VOID
SetTDDataBuffer (
IN TD_STRUCT *ptrTDStruct
)
{
//
// Set the beginning address of the data buffer that will be used
// during the transaction.
//
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?