2009年4月7日 星期二

EHCI r1.0: 4.10 Managing Control/Bulk/Interrupt Transfers via Quque Heads

EHCI r1.0

3.5 Queue Element Transfer Descriptor (qTD)


3.6 Queue Head


Transfer Overlay
a transaction working space, an execution cache for the transfer.

4.10 Managing Control/BulkInterrupt Transfers via Quque Heads

Host Controller Queue Head Traversal State Machine

  • One QH for one endpoint
  • Each qTD represents on or more bus transactions
  • Software simply link qTDs to the QH and activate them
    • Host controller will always find them if/when they are reachable

Fetch QH
QH can be referenced by ASYNCLISTADDR, or Next Link Pointer field of an iTD, siTD, FSTN, or another QH.
  1. empty schedule detection
    • The QH is not an interrupt QH
    • QH.[H] is a one
    • USBSTS.[Reclamation] is a zero
  2. Nak Counter reloads
Advance Queue
  1. find next qTD
    • if [Bytes to Transfer] is not zero and [Alternate Next qTD Pointer].[T] is set to zero, => use [Alternate Next qTD Pointer]
    • else if [Next qTD Pointer].[T] is set to zero => use [Next qTD Pointer]
    • else exit this state and follow [QH Horizontal Pointer]
  2. adjust pointers
    • if the qTD.[Status].[Active] is a one => move the pointer to [Current qTD Pointer]
    • else exit this state and follow [QH Horizontal Pointer]
  3. perform the overlay
    • QH.[dt] = (QH.[dtc]) ? (new qTD.[dtc]) : (QH.[dt])
    • if QH.[EPS] indicate high-speed(10b) => QH.[Status].[Ping] preserved
    • QH.[C-prog-mask] is set to zero
    • QH.[Frame Tag] is set to zero
    • QH.[NakCnt] = QH.[RL]
    • All other areas of the overlay are set by the incoming qTD
  4. write back the result to QH
Execute Transaction

Write Back qTD (aka qTD Retirement)
write (transfer results area) of the (QH overlay area) to qTD pointed by QH.[Current qTD Pointer]

Follow QH Horizontal Pointer

4.10.6 Buffer Pointer List Use fro Data Streaming with qTD


virtually contiguous
The buffer is actually a continuous buffer, maximum 20KB(only when the buffer start on 4K boundary), but there are 5 buffer pointer to assign.
  • the 1st buffer pointer could begin with a offset in a page
  • the rest buffer pointers should be the next 4K boundary following the 1st buffer pointer


我的理解
一個endpoint一個QH,QH裡有一個Overlay,基本上就是個cache,是一個目前正在處理的qTD的複製(又不完全是, ref Advance Queue step3 perform the overlay),會把外部的qTD抓進來,處理完後再寫回去

一個in/out/setup一個qTD。host controller會視情況把data分作好幾個transaction。每個qTD只能帶一個連續的buffer(pointer+size),最大到20K(only if 這個buffer是4KB-aligned)


QH處理流程
  • Fetch QH
  • 只要遇到任何Halted qTD,這個QH就會被跳過,換下一個QH
  • (只在Periodic Schedule與EPS是full/low-speed才成立) 如果[Current qTD]不是[Active]而且[QH].[I]是1 ==> 跳過這個QH
  • 如果[Current qTD]不是[Active] ==> Advance Queue
    • 如果[Current qTD]還沒傳完 則優先用 [Alternate Next qTD Pointer] 其次 [Next qTD Pointer]當作[Current qTD]
    • 如果[Current qTD]傳完了 ==> 用 [Next qTD Pointer]當作[Current qTD]
    • 到這裡如果[Current qTD]的qTD還是沒Active,就跳下一個QH
  • Execute qTD (到這裡[Current qTD]一定是[Active])
    • 每個QH最多只執行一個qTD,不管有沒有執行完,就換下一個QH
    • 如果執行完,則把Overlay的status寫回[Current qTD],然後跳下一個QH
    • 如果沒執行完,則直接跳下一個QH

沒有留言: