自己做的小网站乐清 做网站 多少钱
- 作者: 五速梦信息网
- 时间: 2026年03月21日 04:59
当前位置: 首页 > news >正文
自己做的小网站,乐清 做网站 多少钱,企业名称登记管理规定,wordpress 谷歌分析xhci 数据结构
xhci 数据结构主要在手册上有详细的定义#xff0c;本文根据手册进行归纳总结#xff1a; 重点关注的包括#xff1a;
device contexttrb ringtrb device context设备上下文 设备上下文数据结构由xHC管理#xff0c;用于向系统软件报告设备配置和状态信息。…xhci 数据结构
xhci 数据结构主要在手册上有详细的定义本文根据手册进行归纳总结 重点关注的包括
device contexttrb ringtrb device context设备上下文 设备上下文数据结构由xHC管理用于向系统软件报告设备配置和状态信息。设备上下文数据结构由32个数据结构的数组组成。第一个上下文数据结构索引“0”是Slot Context数据结构。其余上下文数据结构是“端点上下文”数据结构
在枚举USB设备的过程中系统软件会在主机内存中为该设备分配设备上下文数据结构并将其初始化为“0”。然后使用地址设备命令将数据结构的所有权传递给xHC。xHC保留对设备上下文的所有权直到使用“禁用插槽命令”禁用了设备插槽为止。设备上下文数据结构由xHC拥有时应被系统软件视为只读
其中主要分为slot 上下文 和 endpoint 上下文在host xhci 中有定义 616 struct xhci_slot_ctx {617 __le32 dev_info;618 __le32 dev_info2;619 __le32 tt_info;620 __le32 dev_state;621 /* offset 0x10 to 0x1f reserved for HC internal use /622 __le32 reserved[4];623 }; 700 struct xhci_ep_ctx {701 __le32 ep_info;702 __le32 ep_info2;703 __le64 deq;704 __le32 tx_info;705 / offset 0x14 - 0x1f reserved for HC internal use /706 __le32 reserved[3];707 };
slot 上下文 Slot主要是有关 包含与整个设备有关的信息或影响USB设备的所有端点的信息。Slot Context提供的信息包括 控制状态寻址和电源管理。
作为设备上下文成员xHC使用插槽上下文数据结构将设备参数的当前值报告给系统软件。 xHC报告的插槽状态标识设备的当前状态并与USB规范中描述的USB设备状态紧密对应。 设备上下文的Slot Context数据结构也称为“Output Slot Context”。 作为输入上下文成员系统软件使用Slot Context数据结构将命令参数传递给主机控制器。 输入上下文的Slot Context数据结构也称为“Input Slot Context”。 如果针对设备插槽的命令成功执行则xHC将在生成Command Completion Event 之前更新输出插槽上下文以反映其正在主动使用的参数值来管理设备。 插槽上下文的xHCI保留区域可用作xHC实现定义的暂存器。 插槽上下文中的所有保留字段仅供xHC使用除非插槽处于“禁用”状态否则不得由系统软件修改。
endpoint 上下文 重点参数
针对iso通信 在xhci.c 中进行了初始化
1418 / Set up an endpoint with one ring segment. Do not allocate stream rings.
1419 * Drivers will have to call usb_alloc_streams() to do that.
1420 */
1421 int xhci_endpoint_init(struct xhci_hcd *xhci,
1422 struct xhci_virt_device *virt_dev,
1423 struct usb_device *udev,
1424 struct usb_host_endpoint ep,
1425 gfp_t mem_flags)
1426 {
…1494 / Set up the endpoint ring /
1495 virt_dev-eps[ep_index].new_ring
1496 xhci_ring_alloc(xhci, 2, 1, ring_type, max_packet, mem_flags);
1497 if (!virt_dev-eps[ep_index].new_ring)
1498 return -ENOMEM;
…
1503 / Fill the endpoint context */
1504 ep_ctx-ep_info cpu_to_le32(EP_MAX_ESIT_PAYLOAD_HI(max_esit_payload) |
1505 EP_INTERVAL(interval) |
1506 EP_MULT(mult));
1507 ep_ctx-ep_info2 cpu_to_le32(EP_TYPE(endpoint_type) |
1508 MAX_PACKET(max_packet) |
1509 MAX_BURST(max_burst) |
1510 ERROR_COUNT(err_count));
1511 ep_ctx-deq cpu_to_le64(ep_ring-first_seg-dma |
1512 ep_ring-cycle_state);
1513
1514 ep_ctx-tx_info cpu_to_le32(EP_MAX_ESIT_PAYLOAD_LO(max_esit_payload) |
1515 EP_AVG_TRB_LENGTH(avg_trb_len));…
ring
Ring是一个循环队列xHC使用三种类型的Ring
Command Ring每个XHC一个软件使用Command Ring将命令发送给xHC。使系统软件能够发出命令以枚举USB设备配置xHC以支持这些设备以及协调虚拟化功能。Event Ring每个中断一个每个中断器的一种循环队列为xHC提供了一种向系统软件报告的方式数据传输和命令完成状态根集线器端口状态更改以及其他与xHC相关的事件。或者说xHC使用事件环返回状态和命令结果并将其传输到系统软件。Transfer Ring每个Endpoint或Stream一个Transfer Ring被用来在内存和设备Endpoint之间传输数据。
备注每个设备插入的过程中会根据设备反馈的设备描述符注册相应的多个endpoint后面我单独写一篇usb设备插入注册解析设备描述符的过程。
1589 struct xhci_ring {
1590 struct xhci_segment *first_seg;
1591 struct xhci_segment *last_seg;
1592 union xhci_trb *enqueue;
1593 struct xhci_segment *enq_seg;
1594 union xhci_trb *dequeue;
1595 struct xhci_segment deq_seg;
1596 struct list_head td_list;
1597 /
1598 * Write the cycle state into the TRB cycle field to give ownership of
1599 * the TRB to the host controller (if we are the producer), or to check
1600 * if we own the TRB (if we are the consumer). See section 4.9.1.
1601 */
1602 u32 cycle_state;
1603 unsigned int stream_id;
1604 unsigned int num_segs;
1605 unsigned int num_trbs_free;
1606 unsigned int num_trbs_free_temp;
1607 unsigned int bounce_buf_len;
1608 enum xhci_ring_type type;
1609 bool last_td_was_short;
1610 struct radix_tree_root *trb_address_map;
1611 };Transfer Ring
重点介绍每个endpoint 上的Transfer Ring 将需要硬件完成的USB传输通过TRB的形式将信息提交给硬件放入RING当中放入的位置为当前ENQUEUE PTR的位置每放一个ENQUEUE PTR向前跨一步遇到LINK TRB则跳转到LINK TRB指向的位置 而硬件则按DEQUEUE PTR指向的位置取出TRB到CACHE当中执行该TRB同样每执行一个则ADVANCE 该 DEQUEUE PTR遇LINK TRB跳转。 TD表示一个USB TRANSFER不同于USB TRANSACTION 在TRB当中有一个CH BIT如果一处TD由多个TRB构成则软件需要将除最后一个TRB的所有CH BIT置位。 trb 的结构 xhci 发送数据分析
概述 从xhci_urb_enqueue 开始看
1433 static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
1434 {
···
1519 case USB_ENDPOINT_XFER_CONTROL:
1520 ret xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb,
1521 slot_id, ep_index);
···3211 int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
3212 struct urb *urb, int slot_id, unsigned int ep_index)
3213 {
···
246 ret prepare_transfer(xhci, xhci-devs[slot_id],
3247 ep_index, urb-stream_id,
3248 num_trbs, urb, 0, mem_flags);
····3323 queue_trb(xhci, ring, more_trbs_coming | need_zero_pkt,
3324 lower_32_bits(send_addr),
3325 upper_32_bits(send_addr),
3326 length_field,
3327 field);
···2828 static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring,
2829 bool more_trbs_coming,
2830 u32 field1, u32 field2, u32 field3, u32 field4)
2831 {
2832 struct xhci_generic_trb trb;
2833
2834 trb ring-enqueue-generic;
2835 trb-field[0] cpu_to_le32(field1);
2836 trb-field[1] cpu_to_le32(field2);
2837 trb-field[2] cpu_to_le32(field3);
2838 / make sure TRB is fully written before giving it to the controller */
2839 wmb();
2840 trb-field[3] cpu_to_le32(field4);
2841
2842 trace_xhci_queue_trb(ring, trb);
2843
2844 inc_enq(xhci, ring, more_trbs_coming);
2845 }
2846
通过inc_enq 向xhci ring 中写数据更新指针enqueue。 204 static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring,205 bool more_trbs_coming)206 {207 u32 chain;208 union xhci_trb next;209 210 chain le32_to_cpu(ring-enqueue-generic.field[3]) TRB_CHAIN;211 / If this is not event ring, there is one less usable TRB */212 if (!trb_is_link(ring-enqueue))213 ring-num_trbs_free–;214 next (ring-enqueue);
xhci 接收数据分析
xhci 的中断处理函数xhci_irq 调用函数 xhci_handle_event
2625 static int xhci_handle_event(struct xhci_hcd *xhci)
2626 {
2651 switch (le32_to_cpu(event-event_cmd.flags) TRB_TYPE_BITMASK) {
2652 case TRB_TYPE(TRB_COMPLETION):
2653 handle_cmd_completion(xhci, event-event_cmd);
2654 break;
2655 case TRB_TYPE(TRB_PORT_STATUS):
2656 handle_port_status(xhci, event);
2657 update_ptrs 0;
2658 break;
2659 case TRB_TYPE(TRB_TRANSFER):
2660 ret handle_tx_event(xhci, event-trans_event);
2661 if (ret 0)
2662 update_ptrs 0;
2663 break;
2664 case TRB_TYPE(TRB_DEV_NOTE):
2665 handle_device_notification(xhci, event);
2666 break;
2667 default:
2668 if ((le32_to_cpu(event-event_cmd.flags) TRB_TYPE_BITMASK)
2669 TRB_TYPE(48))
2670 handle_vendor_event(xhci, event);
2671 else
2672 xhci_warn(xhci, ERROR unknown event type %d\n,
2673 TRB_FIELD_TO_TYPE(
2674 le32_to_cpu(event-event_cmd.flags)));
2675 }其中判断trb 的类型
#define TRB_TYPE(p) ((p) 10)如果类型是#define TRB_COMPLETION 33 则表示传输完成,调用handle_cmd_completion 则会调用函数handle_cmd_completion - xhci_handle_cmd_set_deq - update_ring_for_set_deq_completion
在函数update_ring_for_set_deq_completion中更新指针dequeue 975 static void update_ring_for_set_deq_completion(struct xhci_hcd *xhci,976 struct xhci_virt_device *dev,977 struct xhci_ring *ep_ring,978 unsigned int ep_index)979 {980 union xhci_trb dequeue_temp;981 int num_trbs_free_temp;982 bool revert false;983 984 num_trbs_free_temp ep_ring-num_trbs_free;985 dequeue_temp ep_ring-dequeue;986 987 / If we get two back-to-back stalls, and the first stalled transfer988 * ends just before a link TRB, the dequeue pointer will be left on989 * the link TRB by the code in the while loop. So we have to update990 * the dequeue pointer one segment further, or well jump off991 * the segment into la-la-land.992 /993 if (trb_is_link(ep_ring-dequeue)) {994 ep_ring-deq_seg ep_ring-deq_seg-next;995 ep_ring-dequeue ep_ring-deq_seg-trbs;996 }997 998 while (ep_ring-dequeue ! dev-eps[ep_index].queued_deq_ptr) {999 / We have more usable TRBs */
1000 ep_ring-num_trbs_free;
1001 ep_ring-dequeue;
1002 if (trb_is_link(ep_ring-dequeue)) {
1003 if (ep_ring-dequeue
1004 dev-eps[ep_index].queued_deq_ptr)
1005 break;
1006 ep_ring-deq_seg ep_ring-deq_seg-next;
1007 ep_ring-dequeue ep_ring-deq_seg-trbs;
1008 }
1009 if (ep_ring-dequeue dequeue_temp) {
1010 revert true;
1011 break;
1012 }
1013 }
1014
1015 if (revert) {
1016 xhci_dbg(xhci, Unable to find new dequeue pointer\n);
1017 ep_ring-num_trbs_free num_trbs_free_temp;
1018 }
1019 }
- 上一篇: 自己做的网站找不到了武威市市建设局网站建筑业管理
- 下一篇: 自己做电商网站工作简历模板电子版
相关文章
-
自己做的网站找不到了武威市市建设局网站建筑业管理
自己做的网站找不到了武威市市建设局网站建筑业管理
- 技术栈
- 2026年03月21日
-
自己做的网站怎么取sql数据百度统计搜索词为什么有与网站不相关的词
自己做的网站怎么取sql数据百度统计搜索词为什么有与网站不相关的词
- 技术栈
- 2026年03月21日
-
自己做的网站怎么挂网上柳州网站建设找哪家好
自己做的网站怎么挂网上柳州网站建设找哪家好
- 技术栈
- 2026年03月21日
-
自己做电商网站工作简历模板电子版
自己做电商网站工作简历模板电子版
- 技术栈
- 2026年03月21日
-
自己做电影网站怎么赚钱试客类网站开发
自己做电影网站怎么赚钱试客类网站开发
- 技术栈
- 2026年03月21日
-
自己做店铺网站电子工程建设
自己做店铺网站电子工程建设
- 技术栈
- 2026年03月21日
