urb传输的代码分析【转】
转自:http://blog.csdn.net/zkami/article/details/2503829
urb传输的代码分析
如需引用,请注明出处blog.csdn.net/zkami 作者ZhengKui
分配一个urb,并初始化之。返回这个urb的指针
usb_alloc_urb(int iso_packets, gfp_t mem_flags) (core/message.c)
->urb = kmalloc(...); 分配一个urb
->usb_init_urb(urb); 初始化这个urb:初始化个字段为0,增加引用计数
根据传输类型,填写urb的一些字段(usb.h)
static inline void usb_fill_control_urb (struct urb *urb,
struct usb_device *dev,
unsigned int pipe,
unsigned char *setup_packet,
void *transfer_buffer,
int buffer_length,
usb_complete_t complete_fn,
void *context)
static inline void usb_fill_int_urb (struct urb *urb,
struct usb_device *dev,
unsigned int pipe,
void *transfer_buffer,
int buffer_length,
usb_complete_t complete_fn,
void *context,
int interval)
static inline void usb_fill_bulk_urb (struct urb *urb,
struct usb_device *dev,
unsigned int pipe,
void *transfer_buffer,
int buffer_length,
usb_complete_t complete_fn,
void *context)
相 同:对于ctl/int/bulk这三种传输类型,在fill urb时都需要填充dev,pipe,transfer_buffer,transfer_buffer_length,complete, context 字段。其中pipe代表当前urb传输的管道,transfer_buffer
代表当前urb传输的数据的起始地址,transfer_buffer_length是当前urb传输的数据长度,complete是当前urb处理完后调用的回调函数。
不同:fill control urb时需要fill setup_packet字段,它指向一个setup包的起始地址
fill int urb时要根据传输速度来fill interval字段
提交urb。发出一个异步的传输请求,完成后将调用回调函数。在调用usb_submit_urb函数前必须正确的初始化urb, 最后urb的控制将返回给发出申请的dev driver。
usb_submit_urb(struct urb *urb, gfp_t mem_flags) (core/urb.c)
->ep = (usb_pipein(urb->pipe) ? dev->ep_in : dev->ep_out)[usb_pipeendpoint(urb->pipe)];
根据pipe得到urb要连接到哪个ep的list中
->xfertype = usb_endpoint_type(&ep->desc);
得到端点类型,并根据不同的类型进行设置,如填充urb的transfer_flags字段。
如果是ISO传输,根据iso packet的数量(urb->number_of_packets),初始化每一个packet。 (urb->iso_frame_desc[n])
如果是iso/int传输,根据端点速度类型设置urb->interval
->usb_hcd_submit_urb(urb, mem_flags) (core/hcd.c)
将提交的urb指派给合适的host controller driver,这里的HC遵守OHCI规范
->rh_urb_enqueue(hcd, urb); 如果是Root Hub,调用该函数
->rh_queue_status (hcd, urb); 如果是中断传输
->usb_hcd_link_urb_to_ep(hcd, urb); 把urb挂到ep上
->mod_timer(); 修改rh_timer polling的时间
->rh_call_control (hcd, urb); 如果是控制传输
->usb_hcd_link_urb_to_ep(hcd, urb); 把urb挂到ep上
然后根据不同的standard request(ch9.h) Setup Packet的request域来确定len
->ohci_hub_control(hcd, typeReq, wValue, wIndex,tbuf, wLength)
通过操作根Hub寄存器来完成上层对根Hub发送的命令
->usb_hcd_unlink_urb_from_ep(hcd, urb); 出错的话把urb从ep上脱链
->usb_hcd_giveback_urb(hcd, urb, status); urb处理完后调用回调函数
->ohci_urb_enqueue(hcd, urb, mem_flags) 如果不是Root Hub,调用该函数
-> ed_get (ohci, urb->ep, urb->dev, pipe, urb->interval))) ohci-q.c
如果ep上挂有ed,直接返回。如果没有,则用参数pipe、interval以及ep.desc加工一个ed,将其挂在ep上并返回
-> ed_alloc (ohci, GFP_ATOMIC); (ohci-mem.c)分配一个struct ed
-> td_alloc (ohci, GFP_ATOMIC); (ohci-mem.c)分配一个struct td
-> ed_free(ohci, ed); 释放struct ed
-> usb_calc_bus_time() 计算传输一个拥有最大字节数的数据包所需要的时间(ms)
然后:设定info的各个域,(info其实就是OHCI Spec中定义的Endpoint Descriptor的Dword 0
详见P16 OHCI spec figure4-1)再将info赋给ed->hwInfo
然后: 根据端点的类型确定size(size决定该端点上挂载的td的数目,除实时端点上的td外,
其它端点上的td能够装载4K的数据)
接着: 给urb_priv_t分配空间,并为其上所挂载的td指针数组分配空间
-> td_alloc (ohci, mem_flags); (ohci-mem.c) 分配ed中的每一个td
-> usb_hcd_link_urb_to_ep(hcd, urb); urb挂到ep的urb_list上
-> ed_schedule (ohci, ed);
根据ed的类型将ed插入到HC相应队列中,并读/写HC的寄存器
-> balance (ohci, ed->interval, ed->load);
-> periodic_link(ohci, ed);
-> usb_hcd_unlink_urb_from_ep(hcd, urb);
-> td_submit_urb (ohci, urb); 将urb需要发送的数据安排到相应ed下的td队列中
-> td_fill(ohci, info, data, 4096, urb, cnt);
message.c
usb_interrupt_msg(...) 事实上调用的是usb_bulk_msg()
->usb_bulk_msg(usb_dev, pipe, data, len, actual_length, timeout)
-> usb_alloc_urb(0, GFP_KERNEL) 分配一个urb
-> usb_fill_int_urb(urb, usb_dev, pipe, data, len,
usb_api_blocking_completion, NULL,
ep->desc.bInterval); 如果是int msg
-> usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
usb_api_blocking_completion, NULL); 如果是bulk msg
-> usb_start_wait_urb(urb, timeout, actual_length);
提交urb并等待完成或超时。将urb提交给usb core后就停在wait_for_completion_timeout()等待
当这个urb完成后,会调用usb_api_blocking_completion()进而调用complete来通知不用再等了。
->usb_submit_urb(urb, GFP_NOIO) 提交urb
->wait_for_completion_timeout(&ctx.done, expire)) 等待。其中expire是等待的时间限
&ctx.done是等到了的话,调用的回调函数
->usb_kill_urb(urb) 如果超时就kill这个urb
usb_control_msg(...)
->struct usb_ctrlrequest *dr = kmalloc(...)
首先创建一个usb_ctrlrequest的数据结构(详见usb2.0 spec ch9),并初始化bRequestType,bRequest,wValue
wIndex,wLength字段
->usb_internal_control_msg(dev, pipe, dr, data, size, timeout);
->usb_alloc_urb(0, GFP_NOIO); 分配一个urb
->usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data,
len, usb_api_blocking_completion, NULL);
填充这个ctl urb, usb_api_blocking_completion是回调函数
->usb_start_wait_urb(urb, timeout, &length);
提交urb并等待完成或超时。将urb提交给usb core后就停在wait_for_completion_timeout()等待
当这个urb完成后,会调用usb_api_blocking_completion()进而调用complete来通知不用再等了。
->usb_submit_urb(urb, GFP_NOIO) 提交urb
->wait_for_completion_timeout(&ctx.done, expire)) 等待。其中expire是等待的时间限
&ctx.done是等到了的话,调用的回调函数
->usb_kill_urb(urb) 如果超时就kill这个urb
如需引用,请注明出处blog.csdn.net/zkami 作者ZhengKui
urb传输的代码分析【转】的更多相关文章
- 完整全面的Java资源库(包括构建、操作、代码分析、编译器、数据库、社区等等)
构建 这里搜集了用来构建应用程序的工具. Apache Maven:Maven使用声明进行构建并进行依赖管理,偏向于使用约定而不是配置进行构建.Maven优于Apache Ant.后者采用了一种过程化 ...
- wifi display代码 分析
转自:http://blog.csdn.net/lilian0118/article/details/23168531 这一章中我们来看Wifi Display连接过程的建立,包含P2P的部分和RTS ...
- Bluez SPP实现代码分析(转)
源:http://blog.csdn.net/walkingman321/article/details/7218705 本文分析蓝牙协议栈中蓝牙转串口(SPP)部分的实现. 1. 基本概念 Blu ...
- 20165223《网络对抗技术》Exp4 恶意代码分析
目录 -- 恶意代码分析 恶意代码分析说明 实验任务目标 实验内容概述 schtasks命令使用 实验内容 系统运行监控 恶意软件分析 静态分析 virscan分析和VirusTotal分析 PEiD ...
- Exp4 恶意代码分析
一.原理与实践说明 1. 实践目标 1.1 监控你自己系统的运行状态,看有没有可疑的程序在运行. 1.2 分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sysin ...
- 2018-2019-2 网络对抗技术 20165232 Exp4 恶意代码分析
2018-2019-2 网络对抗技术 20165232 Exp4 恶意代码分析 1.实践目标 监控你自己系统的运行状态,看有没有可疑的程序在运行. 分析一个恶意软件,就分析Exp2或Exp3中生成后门 ...
- 2018-2019-2 20165234 《网络对抗技术》 Exp4 恶意代码分析
实验四 恶意代码分析 实验目的 1.监控自己系统的运行状态,看有没有可疑的程序在运行. 2.分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sysinternals ...
- 2018-2019-2 20165221『网络对抗技术』Exp4:恶意代码分析
2018-2019-2 20165221『网络对抗技术』Exp4:恶意代码分析 实验要求: 是监控你自己系统的运行状态,看有没有可疑的程序在运行. 是分析一个恶意软件,就分析Exp2或Exp3中生成后 ...
- 2018-2019-2 网络对抗技术 20165206 Exp4 恶意代码分析
- 2018-2019-2 网络对抗技术 20165206 Exp4 恶意代码分析 - 实验任务 1系统运行监控(2分) (1)使用如计划任务,每隔一分钟记录自己的电脑有哪些程序在联网,连接的外部IP ...
随机推荐
- PAT-1001 采花生
题目描述 鲁宾逊先生有一只宠物猴,名叫多多.这天,他们两个正沿着乡间小路散步,突然发现路边的告示牌上贴着一张小小的纸条:“欢迎免费品尝我种的花生!——熊字”. 鲁宾逊先生和多多都很开心,因为花生正是他 ...
- 冲刺Two之站立会议8
今天对软件进行了用户试用,找了一些同学让他们试用软件之后对软件给出了建议,这样我们可以在一定程度上对它进行进一步地优化.
- [软工课程博客] 求解第N个素数
任务 求解第 10,0000.100,0000.1000,0000 ... 个素数(要求精确解). 想法 Sieve of Eratosthenes 学习初等数论的时候曾经学过埃拉托斯特尼筛法(Sie ...
- 作业C#程序分析
阅读下面程序,请回答如下问题: 问题1:这个程序要找的是符合什么条件的数? 问题2:这样的数存在么?符合这一条件的最小的数是什么? 问题3:在电脑上运行这一程序,你估计多长时间才能输出第一个结果?时间 ...
- 『编程题全队』Alpha 阶段冲刺博客Day8
1.每日站立式会议 1.会议照片 2.昨天已完成的工作统计 孙志威: 1.修复了看板任务框拖拽时候位置不够精确的问题 2.向个人界面下添加了工具栏 3.个人界面下添加了任务框测试 孙慧君: 1.个人任 ...
- 一本通1623Sherlock and His Girlfriend
1623:Sherlock and His Girlfriend 时间限制: 1000 ms 内存限制: 524288 KB [题目描述] 原题来自:Codeforces Round ...
- 【bzoj1089】严格n元树
Description 如果一棵树的所有非叶节点都恰好有n个儿子,那么我们称它为严格n元树.如果该树中最底层的节点深度为d(根的深度为0),那么我们称它为一棵深度为d的严格n元树.例如,深度为2的严格 ...
- 【bzoj4009】 HNOI2015—接水果
http://www.lydsy.com/JudgeOnline/problem.php?id=4009 (题目链接) 题意 给出一颗无根树.有一些路径记为$P_i$,这些路径有两个端点和一个权值$W ...
- 转载:C++中两个类中互相包含对方对象的指针问题
原文链接:http://www.cnblogs.com/hanxi/archive/2012/07/25/2608068.html 前几天很不爽,因为C++中两个类中互相包含对方对象的指针编译时提示某 ...
- 【洛谷P1892】团伙
题目大意:维护 N 个人和 M 个关系,对每个人来说符合:我朋友的朋友也是我的朋友,我敌人的敌人也是我的朋友,求最多有多少个朋友构成的联通块. 题目大意:维护关系显然要用到并查集,这里是维护了两种关系 ...