⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linux设备驱动之usb主机控制器驱动分析-(4)_linux技术文章_linux_操作系统4.htm

📁 linux设备驱动之USB主机控制器驱动分析
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0072)http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940_4.html -->
<HTML><HEAD><TITLE>linux设备驱动之USB主机控制器驱动分析-(4)_Linux技术文章_Linux_操作系统</TITLE>
<META http-equiv=Content-Type content=text/html;charset=gb2312>
<META content=www.diybl.com,DIY部落版权所有 name=Copyright>
<META content=linux设备驱动之USB主机控制器驱动分析_Linux技术文章_Linux_操作系统 name=keywords>
<META 
content="linux设备驱动之USB主机控制器驱动分析_Linux技术文章_ port1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev->dev..." 
name=description>
<META content=index,follow name=robots>
<META content=INDEX,FOLLOW name=GOOGLEBOT><LINK href="article2.css" 
type=text/css rel=stylesheet><LINK 
href="linux设备驱动之USB主机控制器驱动分析-(4)_Linux技术文章_Linux_操作系统4.files/article2.css" 
type=text/css rel=stylesheet>
<SCRIPT src="linux设备驱动之USB主机控制器驱动分析-(4)_Linux技术文章_Linux_操作系统4.files/article.js" 
type=text/javascript></SCRIPT>

<SCRIPT src="linux设备驱动之USB主机控制器驱动分析-(4)_Linux技术文章_Linux_操作系统4.files/1060103.js" 
type=text/javascript></SCRIPT>

<META content="MSHTML 6.00.2900.3395" name=GENERATOR></HEAD>
<BODY><INPUT type=hidden value=144940 name=passage_id><INPUT type=hidden 
value=1060103 name=catalog_id> 
<DIV id=wrap>
<DIV class=top_bar align=center>
<TABLE cellSpacing=0 width=935>
  <TBODY>
  <TR>
    <TD><A href="http://www.diybl.com/">网站首页</A></TD>
    <TD class=top_bar_sline></TD>
    <TD><A href="http://news.diybl.com/" target=_blank>新闻首页</A></TD>
    <TD class=top_bar_sline></TD>
    <TD><A href="http://www.diybl.com/course/1_web/">网页设计</A></TD>
    <TD class=top_bar_sline></TD>
    <TD><A href="http://www.diybl.com/course/2_picdesign/">图形动画</A></TD>
    <TD class=top_bar_sline></TD>
    <TD><A href="http://www.diybl.com/course/3_program/">软件编程</A></TD>
    <TD class=top_bar_sline></TD>
    <TD><A href="http://www.diybl.com/course/4_webprogram/">网站开发</A></TD>
    <TD class=top_bar_sline></TD>
    <TD><A href="http://www.diybl.com/course/5_office/">办公软件</A></TD>
    <TD class=top_bar_sline></TD>
    <TD><A href="http://www.diybl.com/course/6_system/">操作系统</A></TD>
    <TD class=top_bar_sline></TD>
    <TD><A href="http://www.diybl.com/course/7_databases/">数据库</A></TD>
    <TD class=top_bar_sline></TD>
    <TD><A href="http://www.diybl.com/course/webjsh/">网络技术</A></TD>
    <TD class=top_bar_sline></TD>
    <TD><A href="http://www.diybl.com/course/comshiti/">认证考试</A></TD>
    <TD class=top_bar_sline></TD>
    <TD><A href="http://www.diybl.com/course/fwzl/">范文资料</A></TD>
    <TD class=top_bar_sline></TD>
    <TD><A href="http://www.diybl.com/course/hack/">黑客攻防</A></TD>
    <TD class=top_bar_sline></TD>
    <TD><A href="http://www.diybl.com/chm/" target=_blank><FONT 
      color=red>书籍教程</FONT></A></TD>
    <TD class=top_bar_sline></TD>
    <TD><A href="http://bbs.diybl.com/" 
target=_blank>进入论坛</A></TD></TR></TBODY></TABLE></DIV>
<TABLE class=adNone id=PublicRelation cellSpacing=0 cellPadding=0 width=950 
border=0>
  <TBODY>
  <TR>
    <TD vAlign=top width=864>
      <DIV class=logo><A href="http://www.diybl.com/" target=_blank><IMG 
      height=60 
      src="linux设备驱动之USB主机控制器驱动分析-(4)_Linux技术文章_Linux_操作系统4.files/logo.gif" 
      width=200></A></DIV>
      <DIV class=ad_f1 id=ad_f1>
      <SCRIPT 
      src="linux设备驱动之USB主机控制器驱动分析-(4)_Linux技术文章_Linux_操作系统4.files/ad_f1.js"></SCRIPT>
      </DIV><!--<div class="top_bar2">-->
      <UL class=menu>
        <LI><A href="http://www.diybl.com/course/6_system/linux/" 
        target=_blank><SPAN>Linux</SPAN></A>
        <LI><A href="http://www.diybl.com/course/6_system/linux/Linuxxl/" 
        target=_blank><SPAN>Linux系列教程</SPAN></A>
        <LI><A href="http://www.diybl.com/course/6_system/linux/linuxjq/" 
        target=_blank><SPAN>Linux应用技巧</SPAN></A>
        <LI><A 
        href="http://www.diybl.com/course/6_system/linux/Linuxjs/70b7fsdwvtk.html" 
        target=_blank><SPAN>Linux技术文章</SPAN></A></LI></UL><!--</div>--></TD>
    <TD width=6></TD>
    <TD vAlign=top align=middle width=100>
      <DIV class=hotNCout>
      <DIV class=hotNC>
      <UL>
        <LI><A 
        href="javascript:window.external.addFavorite('http://www.diybl.com/','DIY部落');">加入收藏</A> 

        <LI><A href="http://www.diybl.com/map.html" target=_blank>网站地图</A> 
        <LI><A href="http://www.diybl.com/chm/" target=_blank>书籍教程</A> 
        <LI><A href="http://www.diybl.com/user/register.asp" 
        target=_blank>会员注册</A> </LI></UL></DIV></DIV></TD></TR></TBODY></TABLE>
<DIV class=split style="HEIGHT: 3px"></DIV>
<DIV class=ad_ftop id=ad_ftop>
<SCRIPT 
src="linux设备驱动之USB主机控制器驱动分析-(4)_Linux技术文章_Linux_操作系统4.files/ad_ftop.js"></SCRIPT>
</DIV>
<DIV class=subNav>
<DIV style="FLOAT: right"><INPUT name=wd1> <INPUT onclick=tosearch(document.all.wd1); type=button value=" 千寻搜索 "></DIV><SPAN><A 
href="http://www.diybl.com/">DIY部落</A> &gt;&gt; <A 
href="http://www.diybl.com/course/6_system/">操作系统</A> &gt;&gt; <A 
href="http://www.diybl.com/course/6_system/linux/">Linux</A> &gt;&gt; <A 
href="http://www.diybl.com/course/6_system/linux/Linuxjs/70b7fsdwvtk.html">Linux技术文章</A> 
&gt;&gt; 正文</SPAN></DIV>
<DIV class=split></DIV>
<DIV class=main>
<DIV class=lc_blue>
<DIV class=lcBlk>
<H1>linux设备驱动之USB主机控制器驱动分析</H1>
<DIV class=from_info>http://www.diybl.com/ 2008-9-23  网络 点击:<SPAN 
style="FONT-WEIGHT: bold; COLOR: #ff0000">
<SCRIPT src="linux设备驱动之USB主机控制器驱动分析-(4)_Linux技术文章_Linux_操作系统4.files/p_count.htm" 
lanuage="javascript"></SCRIPT>
 </SPAN> <A 
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940_4.html#comment">[ 
评论 ]</A></DIV>
<DIV class=artibody>
<DIV class=ad_f2 id=ad_f2>
<SCRIPT 
src="linux设备驱动之USB主机控制器驱动分析-(4)_Linux技术文章_Linux_操作系统4.files/ad_f2.js"></SCRIPT>
</DIV>
<DIV class=ad_f3 id=ad_f3>
<SCRIPT 
src="linux设备驱动之USB主机控制器驱动分析-(4)_Linux技术文章_Linux_操作系统4.files/ad_f3.js"></SCRIPT>
</DIV>文章搜索: <INPUT maxLength=255 size=30 name=wd2> &nbsp;&nbsp; <INPUT onclick=tosearch(document.all.wd2); type=button value=千寻搜索><A 
class=redlink 
href="javascript:self.location='/user/chm/rar.asp?c_id=48375'">【点击打包该文章】</A>
<SCRIPT 
src="linux设备驱动之USB主机控制器驱动分析-(4)_Linux技术文章_Linux_操作系统4.files/art_top.js"></SCRIPT>
 
<P>port1);<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
dev-&gt;dev.parent = 
&amp;parent-&gt;dev;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
sprintf(&amp;dev-&gt;dev.bus_id[0], 
"%d-%s",<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
bus-&gt;busnum, 
dev-&gt;devpath);<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
/* hub driver sets up TT records */<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
}<BR>//上面的节点名称赋值很有意思: 如果是根集线器,它的名称为"usb"+总线号<BR>//如果是第1条总线上的root 
hub,对应就是usb0<BR>//如果是根集线其下面的设备.它的名称为:总线号+ "-" + portnum 或者:总线号+ "-"&nbsp; + 
上层总线//的devpath<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; dev-&gt;portnum = 
port1;<BR>&nbsp;&nbsp;&nbsp;&nbsp; dev-&gt;bus = 
bus;<BR>&nbsp;&nbsp;&nbsp;&nbsp; dev-&gt;parent = 
parent;<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
INIT_LIST_HEAD(&amp;dev-&gt;filelist);<BR>&nbsp;<BR>#ifdef&nbsp;&nbsp; 
CONFIG_PM<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
mutex_init(&amp;dev-&gt;pm_mutex);<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
INIT_DELAYED_WORK(&amp;dev-&gt;autosuspend, 
usb_autosuspend_work);<BR>&nbsp;&nbsp;&nbsp;&nbsp; dev-&gt;autosuspend_delay = 
usb_autosuspend_delay * HZ;<BR>&nbsp;&nbsp;&nbsp;&nbsp; dev-&gt;connect_time = 
jiffies;<BR>&nbsp;&nbsp;&nbsp;&nbsp; dev-&gt;active_duration = 
-jiffies;<BR>#endif<BR>&nbsp;&nbsp;&nbsp;&nbsp; if (root_hub) /* Root hub always 
ok [and always wired] */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
dev-&gt;authorized = 1;<BR>&nbsp;&nbsp;&nbsp;&nbsp; else 
{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev-&gt;authorized = 
usb_hcd-&gt;authorized_default;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
dev-&gt;wusb = usb_bus_is_wusb(bus)? 1 : 0;<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
}<BR>&nbsp;&nbsp;&nbsp;&nbsp; return 
dev;<BR>}<BR>该函数的参数如下:<BR>Parent:该设备的上层hub.对于root 
hub来说,该参数为NULL.表示它的上层无设备<BR>Bus&nbsp; :该设备所属的bus<BR>port1:该设备所连hub的端口号.对于root 
hub来说,该项为0.<BR>参考添加的注释,这段代码应该很容易理解.注意在代码为usb_driver内嵌的struct 
device的赋值过程.它的bus被设置成了usb_bus_type.它的type被设置成了usb_device_type.这些赋值是我们以后分析usb设备驱动的基础.这里不再啰嗦.为以后的分析打一个伏笔.:-) 
.在这里,注重分析一下对端点0的操作以及设备的命名规则.<BR>1:对于端点0:<BR>USB协议规定每个设备都必须要有一个端点0.USB控制器和这个端点0通信都可以获得整个设备的信息.USB设备可以有多个端口.但是除了端点0外,其它端口的通信都是单向的.如:一些端点只能接收数据.另外的端点只能发送数据.每个端点都对应一个端点号,一个端点号+通信方向就确定了一个端点.也就是说,一个端点号对应二个端点,进来方向的一个,出去方向的一个.<BR>对于端点0.就分析这么多.具体的流程.以后结合代码再来分析.<BR>结合上面的代码:<BR>dev-&gt;ep0.desc.表示ep0(端点0)的端点描述符.desc的定义为struct 
usb_endpoint_descriptor.在usb2.0的规范中,总共有8种描述符.端点描述符的类型定义为5.整个端点描述符的长度为7.<BR>跟进去看一下usb_enable_endpoint():<BR>void 
usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint 
*ep)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp; int epnum = 
usb_endpoint_num(&amp;ep-&gt;desc);<BR>&nbsp;&nbsp;&nbsp;&nbsp; int is_out = 
usb_endpoint_dir_out(&amp;ep-&gt;desc);<BR>&nbsp;&nbsp;&nbsp;&nbsp; int 
is_control = 
usb_endpoint_xfer_control(&amp;ep-&gt;desc);<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
if (is_out || is_control) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
usb_settoggle(dev, epnum, 1, 
0);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev-&gt;ep_out[epnum] = 
ep;<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; if (!is_out || 
is_control) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
usb_settoggle(dev, epnum, 0, 
0);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev-&gt;ep_in[epnum] = 
ep;<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; ep-&gt;enabled = 
1;<BR>}<BR>Usb_endpoint_num()定义如下:<BR>static inline int usb_endpoint_num(const 
struct usb_endpoint_descriptor *epd)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp; return 
epd-&gt;bEndpointAddress &amp; 
USB_ENDPOINT_NUMBER_MASK;<BR>}<BR>即在描述符的bEndpointAddress字段中,取得端点号.<BR>usb_endpoint_dir_out()定义如下:<BR>static 
inline int 
usb_endpoint_dir_out(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
const struct usb_endpoint_descriptor *epd)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
return ((epd-&gt;bEndpointAddress &amp; USB_ENDPOINT_DIR_MASK) == 
USB_DIR_OUT);<BR>}<BR>即判断该端点是否是OUT方向的.OUT方向.就是指从主机发往设备方向.<BR>usb_endpoint_xfer_control()定义如下:<BR>static 
inline int 
usb_endpoint_xfer_control(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
const struct usb_endpoint_descriptor *epd)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
return ((epd-&gt;bmAttributes &amp; USB_ENDPOINT_XFERTYPE_MASK) 
==<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
USB_ENDPOINT_XFER_CONTROL);<BR>}<BR>即检查该端点是否是控制传输端点.<BR>&nbsp;<BR>从上面的流程看,我们并没有对ep0的相关字段赋值,这些函数会全部都返回0.<BR>所以,流程就转到这里:<BR>&nbsp;<BR>if 
(!is_out || is_control) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
usb_settoggle(dev, epnum, 0, 
0);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev-&gt;ep_in[epnum] = 
ep;<BR>}<BR>&nbsp;&nbsp;&nbsp;&nbsp; ep-&gt;enabled = 
1;<BR>&nbsp;<BR>这段代码执行的效果就是:dev-&gt;ep_in[0]=ep. Dev-&gt; 
toggle[0]的0位被置1.<BR>最后将ep-&gt;enabled置为1.表示启用该设备.<BR>其实该段代码主要是改变dev-&gt;ep_in[]和dev-&gt;toggle[].将struct 
usb_device的相关成员列出:<BR>struct usb_device {<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
……<BR>&nbsp;&nbsp;&nbsp;&nbsp; unsigned int toggle[2];&nbsp;&nbsp;&nbsp;&nbsp; 
/* one bit for each endpoint*/<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
……<BR>&nbsp;&nbsp;&nbsp;&nbsp; struct usb_host_endpoint 
*ep_in[16];<BR>&nbsp;&nbsp;&nbsp;&nbsp; struct usb_host_endpoint 
*ep_out[16];<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
……<BR>}<BR>Usb2.0的spec规定.每个设备最多有15个端点号.即最多表示30个端点.另外再加一个端点0.共计31个.<BR>数组ep_in[]表示in方向的端点集合.ep_out[]表示ONT方向的集合.它们在数组中的位置是以端点号做为索引的.<BR><BR>而对于toggle[]数组.他实际上就是一个位图.IN方向的是toggle[0].OUT方向的是toggle[1].其实,这个数组中的每一位表示ep的toggle值.关于toggle,在分析USB的数据传输再来说明,另外,从usb_enable_endpoint()中的代码可以看到,端点的toggle是初始化为0的.<BR>2:对于usb设备的命名规则<BR>注释中解释了一部份,在这里整理一下.相应的代码如下:<BR>if 
(unlikely(!parent)) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
dev-&gt;devpath[0] = 
'0';<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -