HccaDoneHeadHost Controller Communication Area Done Head的缩写,是OHCI规范中最重要的数据结构之一。让我详细解释其含义、作用和工作机制。

HccaDoneHead的完整定义

1. 字面含义解析

HccaDoneHead = HCCA + Done + Head

  • HCCA:Host Controller Communication Area(主机控制器通信区)
  • Done:已完成(的传输描述符)
  • Head:队列头部指针

完整含义主机控制器通信区中的已完成传输队列头指针

2. 在HCCA结构中的位置

HCCA内存布局(第4.4.2节)

typedef struct _HCCA {
    ULONG HccaInterruptTable[32];  // 中断表 - 128字节(偏移0x00-0x7F)
    USHORT HccaFrameNumber;        // 帧号 - 2字节(偏移0x80-0x81)
    USHORT HccaPad1;               // 填充 - 2字节(偏移0x82-0x83)
    ULONG HccaDoneHead;            // 完成队列头 - 4字节(偏移0x84-0x87)
    UCHAR Reserved[116];       // 保留 - 116字节(偏移0x88-0xFB)
} HCCA;

内存映射

偏移地址:  0x00    0x80    0x84    0x88
          [中断表][帧号][填充][DoneHead][保留区域]
大小:     128B    2B     2B     4B      116B

3. 数据结构本质

物理地址指针

HccaDoneHead存储的是一个32位物理地址

// HccaDoneHead的值含义
ULONG HccaDoneHead;  // 指向最新完成的TD的物理地址

// 示例值:
HccaDoneHead = 0x12345000;  // 指向物理地址0x12345000处的TD

链表结构

HccaDoneHead指向一个单向链表

HccaDoneHead
    ↓
TD1 → TD2 → TD3 → ... → TDn → 0(空指针)

待验证:
HccaDoneHead 是指向已完成所有TD的链表的第1个,还是链表中每传输完一个TDn就更新给 HccaDoneHead ?

4. 工作原理:生产者-消费者模型

OHCI硬件作为生产者

// OHCI硬件添加完成的TD(第6.4.4.6节)
void HC_AddCompletedTD(HC_TD* new_td) {
    // 1. 新TD指向当前队列头
    new_td->NextTD = HCCA->DoneHead;

    // 2. 原子性更新队列头
    HCCA->DoneHead = (ULONG)new_td;

    // 3. 更新中断计数器
    UpdateInterruptCounter(new_td);
}

HCD驱动作为消费者

// HCD处理完成队列(第5.3节)
void HCD_ProcessDoneQueue() {
    // 1. 保存当前队列
    ULONG done_queue = HCCA->DoneHead;

    // 2. 清空HCCA队列(允许OHCI继续添加)
    HCCA->DoneHead = 0;

    // 3. 处理所有完成的TD
    ProcessCompletedTDs(done_queue);
}

5. 队列构建示例

TD完成的时间线

时间点     动作                    HccaDoneHead值
----------------------------------------------------
T0:       初始状态                0x00000000(空队列)
T1:       TD1完成                0x12345000(指向TD1)
T2:       TD2完成                0x12346000 → 0x12345000
T3:       TD3完成                0x12347000 → 0x12346000 → 0x12345000

内存中的实际布局

内存地址       内容                 说明
0x12345000: [TD1数据][NextTD=0]    第一个完成的TD
0x12346000: [TD2数据][NextTD=0x12345000] 第二个完成,指向TD1
0x12347000: [TD3数据][NextTD=0x12346000] 第三个完成,指向TD2

HccaDoneHead = 0x12347000(指向最新的TD3)
实际队列:TD3 → TD2 → TD1 → 0

6. 中断生成机制

WritebackDoneHead中断(第6.5.2节)

HccaDoneHead更新触发中断的条件:

// 中断生成逻辑
BOOL ShouldGenerateInterrupt() {
    // 条件1:完成队列非空
    if (HCCA->DoneHead == 0) return FALSE;

    // 条件2:不在写回状态
    if (WritebackDoneHead != 0) return FALSE;

    // 条件3:中断计数器到期或错误发生
    if (DoneQueueInterruptCounter > 0 && 
        !HasErrorCondition()) return FALSE;

    return TRUE;
}

7. 数据传输流程

完整的端到端流程

  1. OHCI处理:硬件处理USB传输,TD完成
  2. 队列更新:OHCI将完成的TD添加到HccaDoneHead队列
  3. 中断触发:满足条件时生成WritebackDoneHead中断
  4. HCD处理:驱动程序读取并清空HccaDoneHead
  5. TD处理:按完成顺序处理每个传输描述符
  6. 资源释放:释放完成的TD内存

总结

HccaDoneHead是OHCI完成队列机制的核心

  1. 📍 位置:HCCA结构中的4字节字段(偏移0x84)
  2. 📋 含义:指向已完成传输描述符队列的头部
  3. ⚙️ 作用:协调OHCI硬件和HCD软件之间的完成传输传递
  4. 🔄 方向:OHCI→HCD的单向通信通道
  5. 🔗 结构:单向链表,最新完成的TD在队列头
  6. 🚨 触发:满足条件时生成WritebackDoneHead中断
  7. 🛡️ 安全:原子性操作保证数据一致性
  8. ⚡ 优化:支持中断合并减少CPU开销

简单来说:HccaDoneHead就像OHCI硬件给HCD驱动程序留下的”已完成工作清单”,硬件完成一项工作就在清单上添加一项,驱动程序定期检查并处理这个清单。