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 + -
显示快捷键?