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

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

📁 linux设备驱动之USB主机控制器驱动分析
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0070)http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940.html -->
<HTML><HEAD><TITLE>linux设备驱动之USB主机控制器驱动分析_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 style="BORDER-COLLAPSE: collapse" 
content="linux设备驱动之USB主机控制器驱动分析_Linux技术文章_<span class=" name=description 
Apple-style-span?>
<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主机控制器驱动分析_Linux技术文章_Linux_操作系统1.files/article2.css" 
type=text/css rel=stylesheet>
<SCRIPT src="linux设备驱动之USB主机控制器驱动分析_Linux技术文章_Linux_操作系统1.files/article.js" 
type=text/javascript></SCRIPT>

<SCRIPT src="linux设备驱动之USB主机控制器驱动分析_Linux技术文章_Linux_操作系统1.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主机控制器驱动分析_Linux技术文章_Linux_操作系统1.files/logo.gif" 
      width=200></A></DIV>
      <DIV class=ad_f1 id=ad_f1>
      <SCRIPT 
      src="linux设备驱动之USB主机控制器驱动分析_Linux技术文章_Linux_操作系统1.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/161efsddstk.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主机控制器驱动分析_Linux技术文章_Linux_操作系统1.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/161efsddstk.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主机控制器驱动分析_Linux技术文章_Linux_操作系统1.files/p_count.htm" 
lanuage="javascript"></SCRIPT>
 </SPAN> <A 
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940.html#comment">[ 
评论 ]</A></DIV>
<DIV class=artibody>
<DIV class=ad_f2 id=ad_f2>
<SCRIPT 
src="linux设备驱动之USB主机控制器驱动分析_Linux技术文章_Linux_操作系统1.files/ad_f2.js"></SCRIPT>
</DIV>
<DIV class=ad_f3 id=ad_f3>
<SCRIPT 
src="linux设备驱动之USB主机控制器驱动分析_Linux技术文章_Linux_操作系统1.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主机控制器驱动分析_Linux技术文章_Linux_操作系统1.files/art_top.js"></SCRIPT>
 
<P><BR><SPAN class=Apple-style-span 
style="FONT-FAMILY: song; BORDER-COLLAPSE: collapse"><BR>一:前言<BR>Usb是一个很复杂的系统.在usb2.0规范中,将其定义成了一个分层模型.linux中的代码也是按照这个分层模型来设计的.具体的分为usb设备,hub和主机控制器三部份.在阅读代码的时候,必须要参考相应的规范.最基本的就是USB2.0的spec.它定义了USB协议.另外的一个是USB控制器的规范.有UHCI,EHCI,OHCI三种.其中UHCI是Intel推出的一种USB控制器标准.它将很多功能交给软件处理.相比之下,它也是最为复杂的.因此,本文档以UHCI为例分析.另外,在分析的过程中参考了情景分析和fudan_abc的&lt;&lt;Linux那些事儿之我是UHCI&gt;&gt;.正是因为踩在许多牛人的肩膀上,才使USB这个复杂的工程在我们面前变得越来越清晰.<BR>本文的代码分析是基于linux 
kernel 
2.6.25.涉及到的代码主要位于linux-2.6.25/drivers/usb目录下.<BR>二:UHCI的初始化<BR>UHCI主机控制器的代码位于linux-2.6.25/drivers/usb/host下面.在配置kernel的时候可以选择将其编译进内核或者编译成模块.模块的入口函数为: 
uhci_hcd_init().代码如下:<BR>static int __init 
uhci_hcd_init(void)<BR>{<BR>&nbsp;&nbsp;&nbsp; int retval = 
-ENOMEM;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_INFO DRIVER_DESC " " 
DRIVER_VERSION 
"%s\n",<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
ignore_oc ? ", overcurrent ignored" : "");<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
if (usb_disabled())<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 
-ENODEV;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; if (DEBUG_CONFIGURED) 
{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; errbuf = 
kmalloc(ERRBUF_LEN, 
GFP_KERNEL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if 
(!errbuf)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
goto errbuf_failed;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
uhci_debugfs_root = debugfs_create_dir("uhci", 
NULL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if 
(!uhci_debugfs_root)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
goto debug_failed;<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
}<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; uhci_up_cachep = 
kmem_cache_create("uhci_urb_priv",<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
sizeof(struct urb_priv), 0, 0, NULL);<BR>&nbsp;&nbsp;&nbsp;&nbsp; if 
(!uhci_up_cachep)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto 
up_failed;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; retval = 
pci_register_driver(&amp;uhci_pci_driver);<BR>&nbsp;&nbsp;&nbsp;&nbsp; if 
(retval)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto 
init_failed;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; return 
0;<BR>&nbsp;<BR>init_failed:<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
kmem_cache_destroy(uhci_up_cachep);<BR>&nbsp;<BR>up_failed:<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
debugfs_remove(uhci_debugfs_root);<BR>&nbsp;<BR>debug_failed:<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
kfree(errbuf);<BR>&nbsp;<BR>errbuf_failed:<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
return 
retval;<BR>}<BR>入口函数比较简单.其中涉及到的接口在之前都已经详细的分析过.<BR>在引导系统的时候,可以为kernel指定参数.如果配置了”nousb”,就明确禁止使用USB.该入口函数首先通过usb_disabled()来检测用户指定了nousb参数.然后为struct 
urb_priv创建了一个cache.然后注册了一个PCI驱动.struct 
usb_priv等以后用到的时候再进行分析.UHCI是一个PCI设备.PCI的驱动架构我们之前已经分析过了,这里不再赘述.<BR>uhci_pci_driver定义如下所示:<BR>static 
struct pci_driver uhci_pci_driver = {<BR>&nbsp;&nbsp;&nbsp;&nbsp; .name 
=&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (char 
*)hcd_name,<BR>&nbsp;&nbsp;&nbsp;&nbsp; .id_table =&nbsp;&nbsp; 
uhci_pci_ids,<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; .probe = 
usb_hcd_pci_probe,<BR>&nbsp;&nbsp;&nbsp;&nbsp; .remove = 
usb_hcd_pci_remove,<BR>&nbsp;&nbsp;&nbsp;&nbsp; .shutdown =&nbsp;&nbsp; 
uhci_shutdown,<BR>&nbsp;<BR>#ifdef&nbsp;&nbsp; 
CONFIG_PM<BR>&nbsp;&nbsp;&nbsp;&nbsp; .suspend =&nbsp;&nbsp;&nbsp; 
usb_hcd_pci_suspend,<BR>&nbsp;&nbsp;&nbsp;&nbsp; .resume = 
usb_hcd_pci_resume,<BR>#endif&nbsp;&nbsp; /* PM 
*/<BR>};<BR>通过之前的对PCI的分析,我们知道对于pci_dev和pci_driver的匹配过程是通过判断pci_driver的id_table项和pci_dev的相关项是否符合来进行的.在这里.id_talbe的定义如下所示:<BR>static 
const struct pci_dev_id uhci_pci_ids[] = { {<BR>&nbsp;&nbsp;&nbsp;&nbsp; /* 
handle any USB UHCI controller */<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
PCI_DEV_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
.driver_data =&nbsp;&nbsp;&nbsp;&nbsp; (unsigned long) 
&amp;uhci_driver,<BR>&nbsp;&nbsp;&nbsp;&nbsp; }, { /* end: all zeroes */ 
}<BR>};<BR>由此,可以看到,只要是属于PCI_CLASS_SERIAL_USB_UHCI类的设备,都能匹配到这个驱动.这个宏的定义如下:<BR>#define 
PCI_CLASS_SERIAL_USB_UHCI&nbsp;&nbsp;&nbsp; 
0x0c0300<BR>其实该类型是由UHCI的spec规定的.<BR>另外,id_talbe的私有项(driver_data)被置为了uhci_driver.这个在以后是会被用到的.<BR>&nbsp;<BR>如果pci_driver成功匹配到设备.就会调用其probe接口.在这里.probe接口被置为了usb_hcd_pci_probe.如下所示:<BR>int 
usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_dev_id 
*id)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp; struct hc_driver&nbsp;&nbsp; 
*driver;<BR>&nbsp;&nbsp;&nbsp;&nbsp; struct 
usb_hcd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
*hcd;<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
retval;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; if 
(usb_disabled())<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 
-ENODEV;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; if 
(!id)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 
-EINVAL;<BR>&nbsp;&nbsp;&nbsp;&nbsp; driver = (struct hc_driver 
*)id-&gt;driver_data;<BR>&nbsp;&nbsp;&nbsp;&nbsp; if 
(!driver)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 
-EINVAL;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; if (pci_enable_device(dev) &lt; 
0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 
-ENODEV;<BR>&nbsp;&nbsp;&nbsp;&nbsp; dev-&gt;current_state = 
PCI_D0;<BR>&nbsp;&nbsp;&nbsp;&nbsp; dev-&gt;dev.power.power_state = 
PMSG_ON;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; if (!dev-&gt;irq) 
{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
dev_err(&amp;dev-&gt;dev,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
"Found HC with no IRQ.&nbsp; Check BIOS/PCI %s 
setup!\n",<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
pci_name(dev));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = 

⌨️ 快捷键说明

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