HccaDoneHead是Host 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 116B3. 数据结构本质
物理地址指针
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 → 06. 中断生成机制
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. 数据传输流程
完整的端到端流程
- OHCI处理:硬件处理USB传输,TD完成
- 队列更新:OHCI将完成的TD添加到HccaDoneHead队列
- 中断触发:满足条件时生成WritebackDoneHead中断
- HCD处理:驱动程序读取并清空HccaDoneHead
- TD处理:按完成顺序处理每个传输描述符
- 资源释放:释放完成的TD内存
总结
HccaDoneHead是OHCI完成队列机制的核心:
- 📍 位置:HCCA结构中的4字节字段(偏移0x84)
- 📋 含义:指向已完成传输描述符队列的头部
- ⚙️ 作用:协调OHCI硬件和HCD软件之间的完成传输传递
- 🔄 方向:OHCI→HCD的单向通信通道
- 🔗 结构:单向链表,最新完成的TD在队列头
- 🚨 触发:满足条件时生成WritebackDoneHead中断
- 🛡️ 安全:原子性操作保证数据一致性
- ⚡ 优化:支持中断合并减少CPU开销
简单来说:HccaDoneHead就像OHCI硬件给HCD驱动程序留下的”已完成工作清单”,硬件完成一项工作就在清单上添加一项,驱动程序定期检查并处理这个清单。
