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

📄 uhchlp.c

📁 Next BIOS Source code : Extensible Firmware Interface
💻 C
📖 第 1 页 / 共 5 页
字号:
    return EFI_OUT_OF_RESOURCES;
  }

  SetTDLinkPtr(ptrTDStruct,NULL) ;

  // Depth first fashion
  SetTDLinkPtrDepthorBreadth(ptrTDStruct, TRUE);

  //SetTDLinkPtrQHorTDSelect(pTDStruct,FALSE) ;

  //
  // 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
)
{
  //
  // 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
)
{
  //
  // 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
)
{
  //
  // 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
)
{
  //
  // 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
)
{
  //
  // 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
)
{
  //
  // 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
)
{
  //
  // TRUE means enable short packet detection mechanism.
  //
  ptrTDStruct->TDData.TDStatusSPD = (bEnable ? 1 : 0);
}

VOID
SetTDControlErrorCounter(
  IN  TD_STRUCT *ptrTDStruct,
  IN  UINT8   nMaxErrors
)
{
  //
  // 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.
  //
  ptrTDStruct->TDData.TDBufferPtr = (UINT32)((UINTN)(ptrTDStruct->pTDBuffer));
}

BOOLEAN
IsTDStatusActive(
  IN  TD_STRUCT *ptrTDStruct
)
{
  UINT8 TDStatus;
  
  //
  // Detect whether the TD is active.
  //
  TDStatus = (UINT8)(ptrTDStruct->TDData.TDStatus);
  return (BOOLEAN)(TDStatus & 0x80);
}

BOOLEAN
IsTDStatusStalled(
  IN  TD_STRUCT *ptrTDStruct
)
{
  UINT8 TDStatus;
  
  //
  // Detect whether the device/endpoint addressed by this TD is stalled.
  //
  TDStatus = (UINT8)(ptrTDStruct->TDData.TDStatus);
  return (BOOLEAN)(TDStatus & 0x40);
}

BOOLEAN
IsTDStatusBufferError(
  IN  TD_STRUCT *ptrTDStruct
)
{
  UINT8 TDStatus;
  
  //
  // Detect whether Data Buffer Error is happened.
  //
  TDStatus = (UINT8)(ptrTDStruct->TDData.TDStatus);
  return (BOOLEAN)(TDStatus & 0x20);
}


BOOLEAN 
IsTDStatusBabbleError(
  IN  TD_STRUCT *ptrTDStruct
)
{
  UINT8 TDStatus;
  
  //
  // Detect whether Babble Error is happened.
  //
  TDStatus = (UINT8)(ptrTDStruct->TDData.TDStatus);
  return (BOOLEAN)(TDStatus & 0x10);
}

BOOLEAN
IsTDStatusNAKReceived(
  IN  TD_STRUCT *ptrTDStruct
)
{
  UINT8 TDStatus;
  
  //
  // Detect whether NAK is received.
  //
  TDStatus = (UINT8)(ptrTDStruct->TDData.TDStatus);
  return (BOOLEAN)(TDStatus & 0x08);
}

BOOLEAN 
IsTDStatusCRCTimeOutError(
  IN  TD_STRUCT *ptrTDStruct
)
{
  UINT8 TDStatus;
  
  //
  // Detect whether CRC/Time Out Error is encountered.
  //
  TDStatus = (UINT8)(ptrTDStruct->TDData.TDStatus);
  return (BOOLEAN)(TDStatus & 0x04);
}

BOOLEAN 
IsTDStatusBitStuffError(
  IN  TD_STRUCT *ptrTDStruct
)
{
  UINT8 TDStatus;
  
  //
  // Detect whether Bitstuff Error is received.
  //
  TDStatus = (UINT8)(ptrTDStruct->TDData.TDStatus);
  return (BOOLEAN)(TDStatus & 0x02);
}

UINT16
GetTDStatusActualLength(
  IN  TD_STRUCT *ptrTDStruct
)
{
  //
  // Retrieve the actual number of bytes that were tansferred.
  // the value is encoded as n-1. so return the decoded value.
  //
  return (UINT16)((ptrTDStruct->TDData.TDStatusActualLength) + 1);
}

UINT16 
GetTDTokenMaxLength(
  IN  TD_STRUCT *ptrTDStruct
)
{
  //
  // Retrieve the maximum number of data bytes allowed for the trnasfer.
  //
  return (UINT16)((ptrTDStruct->TDData.TDTokenMaxLen) + 1);
}

UINT8 
GetTDTokenEndPoint(
  IN  TD_STRUCT *ptrTDStruct
)
{
  //
  // Retrieve the endpoint number the transaction is targeting at.
  //
  return (UINT8)(ptrTDStruct->TDData.TDTokenEndPt);
}

UINT8 
GetTDTokenDeviceAddress(
  IN  TD_STRUCT *ptrTDStruct
)
{
  //
  // Retrieve the device address the transaction is targeting at.
  //
  return (UINT8)(ptrTDStruct->TDData.TDTokenDevAddr);
}

UINT8 
GetTDTokenPacketID(
  IN  TD_STRUCT *ptrTDStruct
)
{
  //
  // Retrieve the Packet Identification information.
  //
  return (UINT8)(ptrTDStruct->TDData.TDTokenPID);
}

UINT8*
GetTDDataBuffer(
  IN  TD_STRUCT *ptrTDStruct
)
{
  //
  // Retrieve the beginning address of the data buffer 
  // that involved in this transaction.
  //
  return ptrTDStruct->pTDBuffer;
}

BOOLEAN
GetTDLinkPtrValidorInvalid(
  IN  TD_STRUCT *ptrTDStruct
)
{
  //
  // Retrieve the information of whether the Link Pointer field 
  // is valid or not.
  //
  if (ptrTDStruct->TDData.TDLinkPtrTerminate) {
    return FALSE;
  } else {
    return TRUE;
  }

}

UINTN
CountTDsNumber(
  IN  TD_STRUCT *ptrFirstTD
  )
{
  UINTN     Number;
  TD_STRUCT *ptr;
  
  //
  // Count the queued TDs number.
  //
  Number = 0 ;
  ptr = ptrFirstTD ;
  while(ptr) {
    ptr = (TD_STRUCT*)ptr->ptrNextTD ;
    Number ++ ;
  }

  return Number ;
}



VOID
LinkTDToQH(
  IN  QH_STRUCT *ptrQH,
  IN  TD_STRUCT *ptrTD
)
{
  if (ptrQH == NULL || ptrTD == NULL) {
    return;
  }
  //
  //  Validate QH Vertical Ptr field
  //
  SetQHVerticalValidorInvalid(ptrQH, TRUE);

  //
  //  Vertical Ptr pointing to TD structure
  //
  SetQHVerticalQHorTDSelect(ptrQH, FALSE);

  SetQHVerticalLinkPtr(ptrQH, (VOID*)ptrTD);

  ptrQH->ptrDown = (VOID*)ptrTD;
}

VOID
LinkTDToTD(
  IN  TD_STRUCT *ptrPreTD,
  IN  TD_STRUCT *ptrTD
  )
{
  if (ptrPreTD == NULL || ptrTD == NULL) {
    return ;
  }
  //
  // Depth first fashion
  //
  SetTDLinkPtrDepthorBreadth(ptrPreTD, TRUE);

  //
  // Link pointer pointing to TD struct
  //
  SetTDLinkPtrQHorTDSelect(ptrPreTD,FALSE) ;
  
  //
  // Validate the link pointer valid bit
  //
  SetTDLinkPtrValidorInvalid(ptrPreTD, TRUE);

  SetTDLinkPtr(ptrPreTD,ptrTD) ;

  ptrPreTD->ptrNextTD = (VOID*)ptrTD ;  
}


//
// Transfer Schedule related Helper Functions
//
VOID
SetorClearCurFrameListTerminate(
  IN  FRAMELIST_ENTRY   *pCurEntry,
  IN  BOOLEAN           IsSet
  )
{
  //
  // If TRUE, empty the frame. If FALSE, indicate the Pointer field is valid.
  //
  pCurEntry-> FrameListPtrTerminate = (IsSet ? 1 : 0) ;
}

VOID

⌨️ 快捷键说明

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