Exemple #1
0
/**

  Create a ED

  @Param   Ohc                  Device private data

  @retval  ED                   descriptor pointer

**/
ED_DESCRIPTOR *
OhciCreateED (
  USB_OHCI_HC_DEV          *Ohc
  )
{
  ED_DESCRIPTOR   *Ed;
  Ed = UsbHcAllocateMem(Ohc->MemPool, sizeof (ED_DESCRIPTOR));
  if (Ed == NULL) {
    return NULL;
  }
  Ed->Word0.Skip = 1;
  Ed->TdTailPointer = NULL;
  Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 ((UINT32) NULL);
  Ed->NextED = NULL;

  return Ed;
}
Exemple #2
0
/**

  Create a ED

  @Param   Ohc                  Device private data

  @retval  ED                   descriptor pointer

**/
ED_DESCRIPTOR *
OhciCreateED (
  USB_OHCI_HC_DEV          *Ohc
  )
{
  ED_DESCRIPTOR   *Ed;
  Ed = UsbHcAllocateMem(Ohc->MemPool, sizeof (ED_DESCRIPTOR));
  if (Ed == NULL) {
    DEBUG ((EFI_D_INFO, "STV allocate ED fail !\r\n"));
    return NULL;
  }
  Ed->Word0.Skip = 1;
  Ed->TdTailPointer = 0;
  Ed->Word2.TdHeadPointer = 0;
  Ed->NextED = 0;

  return Ed;
}
Exemple #3
0
/**

  Create a TD

  @Param  Ohc                   UHC private data

  @retval                       TD structure pointer

**/
TD_DESCRIPTOR *
OhciCreateTD (
  IN USB_OHCI_HC_DEV      *Ohc
  )
{
  TD_DESCRIPTOR           *Td;

  Td = UsbHcAllocateMem(Ohc->MemPool, sizeof(TD_DESCRIPTOR));
  if (Td == NULL) {
    return NULL;
  }
  Td->CurrBufferPointer = NULL;
  Td->NextTD = NULL;
  Td->BufferEndPointer = NULL;
  Td->NextTDPointer = NULL;

  return Td;
}
Exemple #4
0
/**

  Create a TD

  @Param  Ohc                   UHC private data

  @retval                       TD structure pointer

**/
TD_DESCRIPTOR *
OhciCreateTD (
  IN USB_OHCI_HC_DEV      *Ohc
  )
{
  TD_DESCRIPTOR           *Td;

  Td = UsbHcAllocateMem(Ohc->MemPool, sizeof(TD_DESCRIPTOR));
  if (Td == NULL) {
    DEBUG ((EFI_D_INFO, "STV allocate TD fail !\r\n"));
    return NULL;
  }
  Td->CurrBufferPointer = 0;
  Td->NextTD = 0;
  Td->BufferEndPointer = 0;
  Td->NextTDPointer = 0;

  return Td;
}
Exemple #5
0
/**
  Create and intialize a TD.

  @param  Uhc         The UHCI device.

  @return The newly allocated and initialized TD.

**/
UHCI_TD_SW *
UhciCreateTd (
  IN  USB_HC_DEV          *Uhc
  )
{
  UHCI_TD_SW              *Td;

  Td     = UsbHcAllocateMem (Uhc->MemPool, sizeof (UHCI_TD_SW));
  if (Td == NULL) {
    return NULL;
  }

  Td->TdHw.NextLink = TD_LINK (NULL, FALSE, TRUE);
  Td->NextTd        = NULL;
  Td->Data          = NULL;
  Td->DataLen       = 0;

  return Td;
}
Exemple #6
0
/**
  Create an initialize a new queue head.

  @param  Uhc         The UHCI device.
  @param  Interval    The polling interval for the queue.

  @return The newly created queue header.

**/
UHCI_QH_SW *
UhciCreateQh (
  IN  USB_HC_DEV        *Uhc,
  IN  UINTN             Interval
  )
{
  UHCI_QH_SW            *Qh;

  Qh = UsbHcAllocateMem (Uhc->MemPool, sizeof (UHCI_QH_SW));

  if (Qh == NULL) {
    return NULL;
  }

  Qh->QhHw.HorizonLink  = QH_HLINK (NULL, TRUE);
  Qh->QhHw.VerticalLink = QH_VLINK (NULL, TRUE);
  Qh->Interval          = UhciConvertPollRate(Interval);
  Qh->TDs               = NULL;
  Qh->NextQh            = NULL;

  return Qh;
}
Exemple #7
0
/**
  Delete a single asynchronous interrupt transfer for
  the device and endpoint.
  
  @param  Ehc         The EHCI device.
  @param  Data        Current data not associated with a QTD.
  @param  DataLen     The length of the data.
  @param  PktId       Packet ID to use in the QTD.
  @param  Toggle      Data toggle to use in the QTD.
  @param  MaxPacket   Maximu packet length of the endpoint.

  @retval the pointer to the created QTD or NULL if failed to create one.

**/
PEI_EHC_QTD *
EhcCreateQtd (
  IN PEI_USB2_HC_DEV      *Ehc,
  IN UINT8                *Data,
  IN UINTN                DataLen,
  IN UINT8                PktId,
  IN UINT8                Toggle,
  IN UINTN                MaxPacket
  )
{
  PEI_EHC_QTD             *Qtd;
  QTD_HW                  *QtdHw;
  UINTN                   Index;
  UINTN                   Len;
  UINTN                   ThisBufLen;

  ASSERT (Ehc != NULL);

  Qtd = UsbHcAllocateMem (Ehc, Ehc->MemPool, sizeof (PEI_EHC_QTD));

  if (Qtd == NULL) {
    return NULL;
  }

  Qtd->Signature    = EHC_QTD_SIG;
  Qtd->Data         = Data;
  Qtd->DataLen      = 0;

  InitializeListHead (&Qtd->QtdList);

  QtdHw             = &Qtd->QtdHw;
  QtdHw->NextQtd    = QTD_LINK (NULL, TRUE);
  QtdHw->AltNext    = QTD_LINK (NULL, TRUE);
  QtdHw->Status     = QTD_STAT_ACTIVE;
  QtdHw->Pid        = PktId;
  QtdHw->ErrCnt     = QTD_MAX_ERR;
  QtdHw->Ioc        = 0;
  QtdHw->TotalBytes = 0;
  QtdHw->DataToggle = Toggle;

  //
  // Fill in the buffer points
  //
  if (Data != NULL) {
    Len = 0;

    for (Index = 0; Index <= QTD_MAX_BUFFER; Index++) {
      //
      // Set the buffer point (Check page 41 EHCI Spec 1.0). No need to
      // compute the offset and clear Reserved fields. This is already
      // done in the data point.
      //
      QtdHw->Page[Index]      = EHC_LOW_32BIT (Data);
      QtdHw->PageHigh[Index]  = EHC_HIGH_32BIT (Data);

      ThisBufLen              = QTD_BUF_LEN - (EHC_LOW_32BIT (Data) & QTD_BUF_MASK);

      if (Len + ThisBufLen >= DataLen) {
        Len = DataLen;
        break;
      }

      Len += ThisBufLen;
      Data += ThisBufLen;
    }
    
    //
    // Need to fix the last pointer if the Qtd can't hold all the
    // user's data to make sure that the length is in the unit of
    // max packets. If it can hold all the data, there is no such
    // need.
    //
    if (Len < DataLen) {
      Len = Len - Len % MaxPacket;
    }

    QtdHw->TotalBytes = (UINT32) Len;
    Qtd->DataLen      = Len;
  }

  return Qtd;
}
Exemple #8
0
/**
  Allocate and initialize a EHCI queue head.
  
  @param  Ehci      The EHCI device.
  @param  Ep        The endpoint to create queue head for.

  @retval the pointer to the created queue head or NULL if failed to create one.

**/
PEI_EHC_QH *
EhcCreateQh (
  IN PEI_USB2_HC_DEV      *Ehci,
  IN USB_ENDPOINT         *Ep
  )
{
  PEI_EHC_QH              *Qh;
  QH_HW                   *QhHw;

  Qh = UsbHcAllocateMem (Ehci, Ehci->MemPool, sizeof (PEI_EHC_QH));

  if (Qh == NULL) {
    return NULL;
  }

  Qh->Signature       = EHC_QH_SIG;
  Qh->NextQh          = NULL;
  Qh->Interval        = Ep->PollRate;
  
  InitializeListHead (&Qh->Qtds);

  QhHw                = &Qh->QhHw;
  QhHw->HorizonLink   = QH_LINK (NULL, 0, TRUE);
  QhHw->DeviceAddr    = Ep->DevAddr;
  QhHw->Inactive      = 0;
  QhHw->EpNum         = Ep->EpAddr;
  QhHw->EpSpeed       = Ep->DevSpeed;
  QhHw->DtCtrl        = 0;
  QhHw->ReclaimHead   = 0;
  QhHw->MaxPacketLen  = (UINT32) Ep->MaxPacket;
  QhHw->CtrlEp        = 0;
  QhHw->NakReload     = QH_NAK_RELOAD;
  QhHw->HubAddr       = Ep->HubAddr;
  QhHw->PortNum       = Ep->HubPort;
  QhHw->Multiplier    = 1;
  QhHw->DataToggle    = Ep->Toggle;

  if (Ep->DevSpeed != EFI_USB_SPEED_HIGH) {
    QhHw->Status |= QTD_STAT_DO_SS;
  }

  switch (Ep->Type) {
  case EHC_CTRL_TRANSFER:
    //
    // Special initialization for the control transfer:
    // 1. Control transfer initialize data toggle from each QTD
    // 2. Set the Control Endpoint Flag (C) for low/full speed endpoint.
    //
    QhHw->DtCtrl = 1;

    if (Ep->DevSpeed != EFI_USB_SPEED_HIGH) {
      QhHw->CtrlEp = 1;
    }
    break;

  case EHC_INT_TRANSFER_ASYNC:
  case EHC_INT_TRANSFER_SYNC:
    //
    // Special initialization for the interrupt transfer
    // to set the S-Mask and C-Mask
    //
    QhHw->NakReload = 0;
    EhcInitIntQh (Ep, QhHw);
    break;

  case EHC_BULK_TRANSFER:
    if ((Ep->DevSpeed == EFI_USB_SPEED_HIGH) && (Ep->Direction == EfiUsbDataOut)) {
      QhHw->Status |= QTD_STAT_DO_PING;
    }

    break;
  }

  return Qh;
}