)
传输描述符( 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 队列,直到软件清除了错误状态。
阅读(2759) | 评论(1) | 转发(0) |