📄 linux设备驱动之usb主机控制器驱动分析-(2)_linux技术文章_linux_操作系统2.htm
字号:
bus_name:OHCI对应的pci_dev的name<BR> <BR>在这里,注意一下hcd内存的分配.如下示:<BR>hcd =
kzalloc(sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL);<BR>我们知道,struct
usb_hcd是一个位于usb_core下的东东,这个东东所有的host control都会用到.那么hcd就有一个私有区结构,用来表示host
control之间不同的数据结构.而其它们相同的结构保存在struct usb_hcd中.这个hcd_priv成员在struct
usb_hcd被定义成了0项数组的形式,而大小则是由hc_driver的hcd_priv_size项来指定的.<BR> <BR>struct
usb_hcd结构很庞大.这里不方便将其全部列出.只来说明一下在这里会用到的成员:<BR>1:self成员: 我们可以这想思考.每条USB总线上只有一个host
control.每个host control都对应着一条总线. 这个self成员就是表示hcd所对应的USB总线.
self.controller表示该总线上的控制器,也就是UHCI对应的pci_dev中封装的struct device. Self.
bus_name表示该总线的名称.也就是OHCI对应的pci_dev的名称.self. uses_dma来表示该总线上的控制器是否使用DMA<BR>2:
rh_timer成员:该成员是一个定时器,用来轮询控制器的根集线器的状态改变,通常用做电源管理.在这里不加详分析.<BR>2:
driver成员:表示该hcd对应驱动.<BR>总而言之,
usb_create_hcd就是对hcd的各项成员赋值.<BR> <BR>相比之下usb_add_hcd()的代码就比较繁杂了.下面以分段的形式分析如下:<BR>int
usb_add_hcd(struct usb_hcd
*hcd,<BR> unsigned int irqnum,
unsigned long irqflags)<BR>{<BR> int
retval;<BR> struct usb_device
*rhdev;<BR> <BR> dev_info(hcd->self.controller,
"%s\n", hcd->product_desc);<BR> <BR>
hcd->authorized_default = hcd->wireless? 0 :
1;<BR> set_bit(HCD_FLAG_HW_ACCESSIBLE,
&hcd->flags);<BR> <BR> /* HC is in reset
state, but accessible. Now do the one-time
init,<BR> * bottom up so that hcds can customize
the root hubs before khubd<BR> * starts talking to
them. (Note, bus id is assigned early too.)<BR>
*/<BR> //创建pool<BR>
if ((retval = hcd_buffer_create(hcd)) != 0)
{<BR>
dev_dbg(hcd->self.controller, "pool alloc
failed\n");<BR> return
retval;<BR> }<BR>在我们分析的流程中,
Hcd->wireless默认为0.相应的hcd->authorized_default也被置为了0.然后将hcd->flags置为HCD_FLAG_HW_ACCESSIBLE.表示该USB控制器是可以访问的.最后在hcd_buffer_create中,因为hc_driver的flags标志被末置HCD_LOCAL_MEM.该函数在这里什么都不做就返回0了.<BR> <BR>
//注册usb_bus<BR> if ((retval =
usb_register_bus(&hcd->self)) <
0)<BR> goto
err_register_bus;<BR> <BR> //分配并初始化root
hub<BR> if ((rhdev = usb_alloc_dev(NULL,
&hcd->self, 0)) == NULL)
{<BR>
dev_err(hcd->self.controller, "unable to allocate root
hub\n");<BR> retval =
-ENOMEM;<BR> goto
err_allocate_root_hub;<BR> }<BR>
//OHCI定义于usb1.1只能支持全速<BR> rhdev->speed =
(hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH
:<BR>
USB_SPEED_FULL;<BR> hcd->self.root_hub =
rhdev;<BR> <BR> /* wakeup flag init defaults to
"everything works" for root hubs,<BR> * but
drivers can override it in reset() if needed, along
with<BR> * recording the overall controller's
system wakeup capability.<BR>
*/<BR> device_init_wakeup(&rhdev->dev,
1);<BR>在前面.我们看到了在hcd的self成员的赋值过程,而所有的总线信息都要保存在一个地方,在其它的地方会用到这些总线信息.所以usb_register_bus()对应的工作就是在全局变量busmap的位图中找到没有被使用的位做为usb_bus的序号(我们暂且称呼它为USB总线号).然后为该总线注册一个属于usb_host_class类的设备.以后在/sys/class/host中就可以看到该bus对应的目录了.最后,将总线链接到usb_bus_list链表中.<BR>然后,每一个USB控制器都有一个根集线器.这里也要为总线下的根集钱器创建相应的结构,
usb_alloc_dev()用来生成并初始化的usb_device结构.这个函数比较重要,在后面给出这个函数的详细分析.<BR>因为OHCI是USB1.1的设备,所以,根集线器的speed会被定义成USB_SPEED_FULL(全速).最后将这个根集线器关联到总线中.<BR>device_init_wakeup(&rhdev->dev,
1)是和总线相关的,忽略它吧 :-)<BR> /* "reset" is misnamed; its role
is now one-time init. the controller<BR> * should
already have been reset (and boot firmware kicked off
etc).<BR> */<BR> if
(hcd->driver->reset && (retval = hcd->driver->reset(hcd))
< 0) {<BR>
dev_err(hcd->self.controller,</P>
<DIV class=ad_f10 id=ad_f10>
<SCRIPT
src="linux设备驱动之USB主机控制器驱动分析-(2)_Linux技术文章_Linux_操作系统2.files/ad_f10.js"></SCRIPT>
</DIV>
<DIV class=ad_f11 id=ad_f11>
<SCRIPT
src="linux设备驱动之USB主机控制器驱动分析-(2)_Linux技术文章_Linux_操作系统2.files/ad_f11.js"></SCRIPT>
</DIV>
<DIV class=kjy><STRONG>文章整理:</STRONG><A href="http://www.diybl.com/"
target=_blank><STRONG><FONT color=#cc0000>DIY部落</FONT></STRONG></A>
<STRONG>http://www.diybl.com</STRONG> (本站) <A class=redlink
href="javascript:self.location='/user/chm/rar.asp?c_id=144940'">【点击打包该文章】</A></DIV>
<DIV class=klkl><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940.html">[1]</A><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/course/6_system/linux/Linuxjs/2008923/144939.html"><SPAN
style="DISPLAY: none">'klkl'</SPAN></A> [2] <A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940_3.html">[3]</A><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940_4.html">
[4]</A><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940_5.html">
[5]</A><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940_6.html">
[6]</A><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940_7.html">
[7]</A><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940_8.html">
[8]</A><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940_9.html">
[9]</A><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940_10.html">
[10]</A><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940_11.html">
[11]</A><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940_12.html">
[12]</A><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940_13.html">
[13]</A></DIV></DIV>
<DIV class=ad_f4 id=ad_f4>
<SCRIPT
src="linux设备驱动之USB主机控制器驱动分析-(2)_Linux技术文章_Linux_操作系统2.files/ad_f4.js"></SCRIPT>
</DIV>
<DIV class=mediacontent>如果图片或页面不能正常显示请<A class=redlink
onmouseover="this.style.cursor='hand';"
onclick="openerror('144940','linux设备驱动之USB主机控制器驱动分析');">点击这里</A> 站内搜索: <INPUT
maxLength=255 size=25 name=wd3> <INPUT onclick=tosearch(document.all.wd3); type=button value=千寻搜索></DIV>
<DIV style="CLEAR: both" align=center></DIV>
<DIV class=toollinks>【<A
href="javascript:window.external.addFavorite(window.location,'linux设备驱动之USB主机控制器驱动分析-DIY部落');">收藏此页</A>】【<A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/6a44sdetjoktk.html"
target=_blank>栏目页面</A>】【<A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940_2.html#comment">发表评论</A>】【<A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940_2.html#">返回顶部</A>】【<A
href="javascript:window.close()">关闭</A>】 </DIV>
<DIV class=p_bottom>上一篇文章:<A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144941.html">
Linux 启动脚本 完全注释2 --- rc脚本注释</A><BR>下一篇文章:<A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144939.html">Rsync命令参数详解</A></DIV></DIV>
<DIV style="CLEAR: both; BACKGROUND: #fff; OVERFLOW: hidden; HEIGHT: 8px"></DIV>
<DIV id=links align=center>
<TABLE class=xgzt cellSpacing=0 cellPadding=0 width=687>
<TBODY>
<TR>
<TD style="PADDING-LEFT: 5px" bgColor=#e1effa>
<H3>推荐文章</H3></TD></TR>
<TR>
<TD bgColor=#fcfeff>
<DIV class="tj_l tj"><NOBR><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008814/135944.html"
target=_blank>桌面Linux系统优化</A><BR><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008821/136822.html"
target=_blank>Vi的基本命令</A><BR><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/20071027/80317.html"
target=_blank>终于搞定了X~</A><BR><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2007930/75354.html"
target=_blank>拨开云雾:Lastlog文件不断变大的原因</A><BR><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2007917/71731.html"
target=_blank>9月15日,我们爬山去</A><BR><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2007126/90911.html"
target=_blank>常用的几个shell脚本_4_更新jsp</A><BR><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008717/133287.html"
target=_blank>rhel5-kvm虚拟机安装oracle rac</A><BR><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144806.html"
target=_blank>NAND闪存工作原理</A></DIV>
<DIV class="tj_r tj"><NOBR><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008617/125862.html"
target=_blank>MySql源文件安装</A><BR><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008617/125890.html"
target=_blank>定制Linux系统内核,发挥Linux潜能</A><BR><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144890.html"
target=_blank>使用VIM开发软件项目 - (10) 程序员的利器: cscope</A><BR><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/200899/141129.html"
target=_blank>ssh系列</A><BR><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2007114/84145.html"
target=_blank>禁止不用的帐户登陆</A><BR><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008812/135754.html"
target=_blank>Linux认证复习题100道(3)</A><BR><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008816/136151.html"
target=_blank>Linux系统NFS服务</A><BR><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/200896/139648.html"
target=_blank>linux内核的移植与遭遇问题的解决</A></DIV></NOBR></TD></TR></TBODY></TABLE></DIV>
<DIV style="CLEAR: both; BACKGROUND: #fff; OVERFLOW: hidden; HEIGHT: 8px"></DIV>
<DIV class=cleanblock2
style="BORDER-RIGHT: #dedfde 1px solid; BORDER-TOP: #dedfde 1px solid; BACKGROUND: #ededed; BORDER-LEFT: #dedfde 1px solid; BORDER-BOTTOM: #dedfde 1px solid">
<H3>文章评论</H3></DIV>
<DIV class=cleanblock3><IFRAME class=comm_index name=pindex
src="linux设备驱动之USB主机控制器驱动分析-(2)_Linux技术文章_Linux_操作系统2.files/CAP2NPPM.htm"
frameBorder=false width="100%" scrolling=no
onload="window.setTimeout('iframe_resize()',1000)" height=0></IFRAME></DIV>
<DIV style="CLEAR: both; BACKGROUND: #fff; OVERFLOW: hidden; HEIGHT: 8px"></DIV>
<FORM style="MARGIN-TOP: 0px"
action=/user/comment.asp?id=144940&url=http://www.diybl.com/course/6_system/linux/Linuxjs/2008923/144940.html
method=post>
<DIV class=comment_1>
<DIV class=cleanblock2><A name=comment></A>
<H3>请您留言</H3></DIV>
<DIV class=cleanblock style="PADDING-RIGHT: 20px; PADDING-LEFT: 20px"><LABEL
for=label>昵称: <INPUT onclick=this.focus();this.select() maxLength=20 size=15
value=DIY部落网友 name=hypocorism> <A
href="http://www.diybl.com/user/register.asp" target=_blank><FONT
color=red>注册会员</FONT></A> <A href="http://www.diybl.com/user/login.asp"
target=_blank>会员登陆</A> <BR><SPAN style="LINE-HEIGHT: 25px"><A
href="http://www.diybl.com/user/chgpage/cata.asp?num=1060103"
target=_blank><FONT color=#990000><STRONG>点击这里</STRONG></FONT></A></SPAN>
自己制作打包的chm电子书教程 <TEXTAREA style="VERTICAL-ALIGN: text-top; WIDTH: 100%; HEIGHT: 7em" onfocus=showchk(); name=content rows=6></TEXTAREA>
<LABEL id=checkCode style="DISPLAY: none">验证: <INPUT maxLength=5 size=8
name=loginnum> <IMG id=codeImg
style="VERTICAL-ALIGN: middle; CURSOR: pointer; HEIGHT: 18px"
onclick="this.src='/user/getcode.asp?t='+Math.random()" alt=验证码,看不清楚?请点击刷新验证码
src=""> </LABEL> <INPUT class=btn_2k3 style="MARGIN-TOP: 8px" type=submit value=发表评论>
</DIV></DIV>
<DIV class=comment_1
style="FLOAT: left; MARGIN-LEFT: 6px; WIDTH: 313px; HEIGHT: 90px">
<DIV class=cleanblock2>
<H3>网友推荐文章</H3></DIV>
<DIV class=cleanblock>
<TABLE cellSpacing=0 cellPadding=0 width="100%">
<TBODY>
<TR>
<TD style="PADDING-RIGHT: 15px">
<UL>
<LI><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008611/124679.html"
target=_blank>转:我理解的逻辑地址、线性地址、物理地址和虚拟地址</A></LI>
<LI><A
href="http://www.diybl.com/course/6_system/linux/Linuxjs/2008624/128094.html"
target=_blank>使用gdbserver远程调试</A></LI>
<LI><A
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -