您的位置:首页 > 理论基础 > 数据结构算法

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

2017-02-21 11:29 836 查看
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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: