XHCI命令传输(传输完成)


Segmented Event Ring

Transfer Event TRB


struct XhciTrb {
  UINT32      PtrLow;
  UINT32      PtrHigh;
  UINT32      Status;
  UINT32      Control;
}
void
ProcessEvents ()
{
  for (;;) {
    //取得驱动软件维护的出队指针
    UINT32 EvtDequeueIndx = Evts->DequeueIdx;
    //取得CCS,Consumer Cycle State
    UINT32 Cs = Evts->Cs;
    //根据出队指针取出准备处理的Event Ring TRB
    XhciTrb  *EventTrb = Evts->Ring + EvtDequeueIdx;
    //依据CCS判断取得的Event TRB是否有效。也就是CCS要等于PCS。
    UINT32 Control = EventTrb->Control;
    if ((control & TRB_C) != (cs ? 1 : 0)) {
      return;
    }
    //取得Event TRB类型和Completion code
    UINT32 EventType = TRB_TYPE(Control);
    UINT32 CompletionCode = (EventTrb->Status >> 24) & 0xff;
    //依据不同的Event TRB类型,区别处理。
    switch (EventType) {
      case EVENT_TRANSFER:
      case EVENT_COMMAND_COMPLETE:
         //取得产生此Event TRB相应的Command TRB或者Transfer TRB
         struct XhciTrb  *RingTrb = EventTrb->PtrLow;
         //取得Command  TRB或者Transfer TRB对应的Ring struct
        struct XhciRing  *Ring = XHCI_RING(RingTrb);
        //取得命令或者传输Ring出队指针,并更新
        RingDequeueIdx = RingTrb - Ring->Ring + 1;
        Ring->DequeueIdx = RingDequeueIdx;
        //取得输出传输结果
        XhciTrb *RingEvt = &Ring->Evt;
        MemCpy(RingEvt, EventTrb, sizeof(*EventTrb));
        break;
      case EVENT_PORT_STATUS_CHANGE:
        ......
    }
      //更新Event Ring出队指针,因为驱动软件作为consummer已经处理完此Event TRB
     EvtDequeueIndx ++
     if (EvtDequeueIndx == XHCI_RING_ITEMS) {
        EvtDequeueIndx = 0;
        Cs = Cs? 0:1;
        Evts->Cs = Cs;
     }
     Evts->DequeueIdx = EvtDequeueIndx;
     // 写入Event Ring Dequeue Pointer Register,ERDP
      UINT32 Erdp = Evts->Ring + EvtDequeueIndx;
     MmioWrite(ErdpLow,   Erdp);
     MmioWrite(ErdpHigh, 0);
  }
}
展开阅读全文

页面更新:2024-02-06

标签:命令   由此可知   寄存器   指针   也就是说   逻辑   也就是   类型   基地   软件

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top