第四十七篇:Linux中的USB XHCI HOST TRANSFER RING的相关数据结构 (2)

struct xhci_segment {
union xhci_trb *trbs;
/* private to HCD */
struct xhci_segment *next;
dma_addr_t dma;
/* Max packet sized bounce buffer for td-fragmant alignment */
dma_addr_t bounce_dma;
void *bounce_buf;
unsigned int bounce_offs;
unsigned int bounce_len;

};


第一个相关的数据结构,segment

1. union xhci_trb *trbs;

一个segment一般由多个trb构成,由于xhci定义了许多种trb,所以,linux driver定义了一个union

union xhci_trb *trbs; 即指向一段内存,该内存是连续的多个trb数据结构

2. struct xhci_segment *next;

硬件上,多个segment是通过link trb来串起来的

而软件上,则通过定义一个segment类型的指针来串起多个seg

3. dma_addr_t dma;

该段trbs的首总线地址,硬件通过该地址来取trbs

4.  void *bounce_buf;
unsigned int bounce_offs;
unsigned int bounce_len;

这三个成员,是Linux driver最近针对XHCI SPEC 4.11.7.1 TD Fragments 加入的,本人还没有仔细研究,研究完了,再加到评论当中。



struct xhci_td {
struct list_head td_list;
struct list_head cancelled_td_list;
struct urb *urb;
struct xhci_segment *start_seg;
union xhci_trb *first_trb;
union xhci_trb *last_trb;
struct xhci_segment *bounce_seg;
/* actual_length of the URB has already been set */
bool urb_length_set;
};

1. struct list_head td_list;

硬件上,一个TD(transfer descriptor)是由CH bit来实现的,即一个TD中的所有TRB,除了最后一个的CH BIT置1,最后一个为0, 这样,RING当中的TD与TD之间,就分隔开了。

软件上则是通过list_head的形式来管理,TD。

2. struct list_head cancelled_td_list;

取消掉的TD LIST。

3. struct urb *urb;

URB USB REQUEST BLOCK

URB是比较上层的数据结构,最终,是被XHCI DRIVER分解为TRB的.

4. struct xhci_segment *start_seg;

一个TD中,对应的第一个SEGMENT。

5.  union xhci_trb *first_trb;
union xhci_trb *last_trb;

一个起始TRB与一个结束TRB,他们及他们之间的TRB,构成了一个TD。

6. struct xhci_segment *bounce_seg;

没有研究,猜测与XHCI SPEC 4.11.7.1 TD Fragments,最近更新。

7. bool urb_length_set;

一个布尔变量,用来判断,URB中的actual transfer length是否已经被设置过了。




struct xhci_ring {
struct xhci_segment *first_seg;
struct xhci_segment *last_seg;
union  xhci_trb *enqueue;
struct xhci_segment *enq_seg;
unsigned int enq_updates;
union  xhci_trb *dequeue;
struct xhci_segment *deq_seg;
unsigned int deq_updates;
struct list_head td_list;
/*
* Write the cycle state into the TRB cycle field to give ownership of
* the TRB to the host controller (if we are the producer), or to check
* if we own the TRB (if we are the consumer).  See section 4.9.1.
*/
u32 cycle_state;
unsigned int stream_id;
unsigned int num_segs;
unsigned int num_trbs_free;
unsigned int num_trbs_free_temp;
unsigned int bounce_buf_len;
enum xhci_ring_type type;
bool last_td_was_short;
struct radix_tree_root *trb_address_map;
};


RING由SEGMENT构成。

1.  struct xhci_segment *first_seg;
struct xhci_segment *last_seg;

第一个与最后一个SEGMENT

2.  union  xhci_trb *enqueue;
struct xhci_segment *enq_seg;
unsigned int enq_updates;
union  xhci_trb *dequeue;
struct xhci_segment *deq_seg;
unsigned int deq_updates;

针对RING当中的TRB,有生产与消费的关系。

生产者(SW)通过enqueue ptr来指定放入TRB的位置,消费者(HW)通过dequeue ptr来指定取得TRB的位置

3. struct list_head td_list;

一个RING当中,可能会存在多个TD

4. u32 cycle_state;

TRB中有一个CYCLE BIT, 生产者与消费者统一,这样,消费者就可以判断,当前dequeue ptr指向的TRB是有效需要执行的,还是不需要执行的无效TRB。

5. unsigned int stream_id;

与BULK STREAMING相关, 一个STREAM ID对应BULK EP的一个STREAMING。

6.  unsigned int num_segs;
unsigned int num_trbs_free;
unsigned int num_trbs_free_temp;

seg, trb的统计数据

7. unsigned int bounce_buf_len;

可能还是与XHCI SPEC 4.11.7.1 TD Fragments ,最近更新

8. enum xhci_ring_type type;

枚举变量,为CMD, EVENT, TRANSFER中的一种

9. bool last_td_was_short;

布尔变量,表示一个TD是否为短包结束

10. struct radix_tree_root *trb_address_map;

RADIX TREE,方便查找TRB。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值