码迷,mamicode.com
首页 > 其他好文 > 详细

USB 3.0 驱动 (3)

时间:2020-07-07 00:41:34      阅读:79      评论:0      收藏:0      [点我收藏+]

标签:==   hci   lazy   orb   消费   str   响应   技术   手册   

有阵子没有更新随笔了。。。

技术图片

 

 

(最近时间不多,有时间了也不想写)

目前控制类的收发数据都已经调试通过了,interrupt和bulk传输还没写。今天就把xhci的中断机制总结一下吧。

XHCI中断机制

在新一代的USB主控制器的设计中, 除了寄存器操作, 对主控制器的操作主要分为三种类型: 命令, 传输和事件.

  a) 命令操作: 可以理解为xhci操作的控制流, 例如, 激活/去激活slot, 配置设备端点等;

  b) 传输操作: xhci的数据流, 例如进行control传输, bulk传输等

  c) 事件: xhci对 (驱动软件提交的) 命令和传输的响应

中断的消息模型

对于命令, 传输, 事件的处理无一例外都是采用了统一的异步消息模型. 具体来说, 生产者将消息写入环形数组, 消费者从环形数组中读取消息.

在xhci中, 这个环形数组叫做ring.

下图出自于手册, 描述了transfer ring的工作原理:

技术图片

 

 

生产者和消费者各自维护了一个状态: CCS和PCS.

初始状态

CCS和PCS都为1.

transfer ring的标志位初始值为~PCS.

生产者行动

当生产者传输数据时, 写入带有当前PCS的消息. 例如, 上图中TRB0 - TRB4都是生产者生成的.

当然, 在写入消息时, 要判断是否写满. 环形数组满的条件为 (TRB.CYCLE == PCS).

消费者行动

消费者读取当前 (TRB.CYCLE == PCS) 的消息, 当 (TRB.C != PCS) 时, 表示为空.

环形数组环回

当生产者或者消费者到达数组的末尾时 (xhci通过link方式实现, 具体参考手册), 需要将自己的PCS/CCS进行翻转.

翻转的原因: 以消费者为例, 当CCS为1, 且数组中的TRB.CYCLE都为1 (生产者全部填满), 当环回时, 如果CCS不翻转, 因为值相等, 消费者会无穷无尽的处理下去, 这显然不符合预期.

  注意: 对于生产者而言, 消费者完成哪些消息是可以得知的

这样做的好处在于, 当消费者处理完消息后, 不必修改消息的内容 (例如, TRB.CYCLE. 消费者对消息只读, 生产者对消息只写). 这减少了内存的访问次数, 提升了性能.

消息的通知方式

当生产者将消息写入环形数组后, 需要通知消费者去读取.

xhci提供了专用的中断通知寄存器doorbell, 这是一个寄存器数组, 数组的长度为设备的最大个数. 驱动程序可以通过写寄存器通知主控制器有新的消息.

事件的通知方式

当xhci通过doorbell得知有消息需要处理后, 便开始处理消息. 消息处理完毕后, 产生中断通知驱动程序.

驱动程序通过读取事件的环形数组判断具体的完成事项. 其格式如下:

技术图片

 

 

对比起来, xhci中断产生后, 通知驱动程序的信息量较ehci (USB 2.0主控制器) 要多,比ohci (USB 1.1主控制器) 要少.

  a) ehci中断产生后, 驱动程序仅仅知道是某ehci产生了中断, 除此之外, 没了 (硬件工作量小). 具体哪些传输完成了, 则需要驱动软件自己来查询才能获取.

  b) ohci中断产生之后, 驱动程序可以通过查询寄存器得到传输完成的链表 (硬件的工作量比较大). 链表结构可以携带额外的软件信息, 而xhci的环形数组项则不能扩展信息. 但可以通过计算在数组的索引来间接获取额外的信息.

 

USB 3.0 驱动 (3)

标签:==   hci   lazy   orb   消费   str   响应   技术   手册   

原文地址:https://www.cnblogs.com/lycmtz/p/13258371.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!