传输描述符(TD
)
传输描述符(
TD
)是系统内存的数据结构,被
HC
用于定义从端点收发数据的缓冲区。
TD
分为
2
个类型:通用
TD
和同步
TD
。通用
TD
用于中断、控制和批量端点,同步
TD
用于同步传输。使用两种不同的
TD
类型是因为缓冲区类型的不同。对于
U
盘主机控制器来说,不使用同步传输。
若干个传输描述符组成队列链接到
ED
上。
ED
提供传输
TD
数据所需要的端点地址。
HCD
把
TD
增加到队列中,而
HC
把
TD
从队列中删除。
HC
把
TD
从队列删除后,将其链接到已完成队列,这个过程叫做“释放”。
TD
的释放原因包括正常释放和错误释放。当
TD
释放后,释放情况代码被写到
TD
中,以便
HCD
确定释放原因。
TD
是按照顺序进行处理的。它们被链接到
ED
上。
TD
队列的第一个
TD
指针放在
ED
的
NextTransferDescriptor
字段,
HC
从该
TD
开始处理队列。当
TD
被释放,就会从队列中删除,该
TD
的
NextTransferDescriptor
字段所指向的下一个
TD
被转移到队列头。当
HC
处理
ED
的时候,只会产生一个事务。
HC
只有在当前
ED
的所有
TD
都处理完毕后才会产生下一个事务。
在每一个事务完成以后就会更新通用
TD
。有
4
个字段会被更新:
CompletionCode
、
DataToggleControl
、
CurrentBufferPointer
、
ErrorCount
。
DataToggleControl
字段反映了下一次传输所需要的数据分组
PID
。如果当前包成功传输,
HC
就会设置
DataToggleControl
字段最高位,并切换最低位以反映下一次传输所需要的新的数据分组
PID
。如果当前包没有收到
ACK
或
NAK
,则该字段不会被修改。
CurrentBufferPointer
表示当前包传输后是否收到
ACK
或者是否有错误。如果
HC
收到
ACK
或带有不正确切换标记的
NAK
,
CurrentBufferPointer
字段就不会更新,因为
HC
需要重试当前包。如果
CurrentBufferPointer
字段需要更新,包内传输的字节数将会加到当前的
CurrentBufferPointer
字段。如果当前包跨越了页边界,则
CurrentBufferPointer
字段的高
20
比特位将会更新为
BufferEnd
字段的高
20
比特位,以反映页基地址的变化。
CurrentBufferPointer
的低
12
位将会滚动到正确的值以代表新的包地址。
如果包传输发生错误,
ErrorCount
字段会加
1
。如果
ErrorCount
的值为
2
,同时有其它的错误发生,
TD
就会被释放,并且在
CompletionCode
字段设置错误代码。
CompletionCode
字段表示通用
TD
是否传输成功。如果事务成功,则该字段被设置为“无错误”,否则设置为相应的错误代码。对于通用
TD
,
ConditionCode
字段的值只有在
TD
在已完成队列中的时候才有意义。对于
CRC
、位填充错和设备没响应错误,
TD
在错误发生
3
次以后才会被释放到已完成队列。对于拖延、数据溢出、数据不足等错误,
TD
在第一次发生错误的时候就会被释放到已完成队列。通用
TD
没有用到缓冲区溢出和缓冲区不足的错误。
当通用
TD
带着错误被转移到已完成队列时,
ED
的
Halted
字段被设置为
1
,以暂停处理
TD
队列,直到软件清除了错误状态。