LINUX下USB1.1设备学习小记(4)_uhci(3)
时间:2009-03-14 来源:superfight
static void check_and_reset_hc(struct uhci_hcd *uhci) |
uhci_check_and_reset_hc在/drivers/usb/host/pci-quirks.c中
int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base) |
hcd->driver->start为uhci_start,这个函数负责初始化uhci的帧列表
uhci_start在/drivers/usb/host/uhci-hcd.c中
static int uhci_start(struct usb_hcd *hcd) |
现在不得不谈一下qh了~ qh是queue head的缩写,我们已经知道帧和td的用途了,呢qh是干嘛的呢?
简单来说qh是td的一个集合,先看看qh的数据结构,如下图
下图描述了使用qh结构的队列 500)this.width=500;" border=0> 左边qh的link指向右边的link,element指向下面的td
右边的qh的link为无效,element指向下面的td
执行顺序为从上到下先执行左边qh的td,再执行右边qh的td 呢什么是龙骨qh呢?~ 在中断传输中,有一个时间片的概念,有些设备要求主机每间隔5ms提取一次数据,有些设备要求10ms,为了满足这样的时间间隔,就诞生了龙骨qh,uhci有1024个帧,每个帧的执行时间为1ms,呢么历遍一次所有的帧就是1024ms,在中断传输中分为,1ms,2ms,4ms,8ms,16ms,32ms,64ms,128ms,我们按照fudan_abc的命名方法,称为int1,int2,.....
怎么满足这样的间隔要求呢?聪明的朋友应该猜到了吧,就是把所有的1024帧连接到同一个qh,不就是1ms访问一次了么,或者把其中一半的帧按间隔分开,512帧连接到同一个qh,不就是2ms了么 对的,龙骨qh干的就是这事情,请看下图 500)this.width=500;" border=0> 可以看到2号龙骨有8帧,呢么就是1024/8=int512,3号龙骨有16帧,呢么就是1024/16=int256,以此类推,
最后一个有点特别,看以看见,2号到8号龙骨qh的link都连接到了9号龙骨,呢么9号龙骨间接使用了这些帧,所以9号龙骨有所有的1024帧,呢么就是int1 负责分配连接这些帧的函数为uhci_frame_skel_link
uhci_frame_skel_link在drivers/usb/host/uhci-hcd.c中
static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame) |
这个函数很简单,是一个模运算,具体怎么模,参考fudan_abc的文章吧,哈哈~
UHCI_PTR_TERM为设置link或者element字段为无效 0号龙骨为无连接qh,1号龙骨为等时qh,2到9号龙骨为中断龙骨,10号龙骨为终结龙骨,一共11个龙骨 如何真正使用这些龙骨在后面介绍 uhci_alloc_td在td_pool中分配一个td结构所需要的内存大小uhci_alloc_td在drivers/usb/host/uhci-q.c中
static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci) |
configure_hc在drivers/usb/host/uhci-hcd.c中
static void configure_hc(struct uhci_hcd *uhci) |
start_rh负责启动根集线器
start_rh在/drivers/usb/host/uhci-hcd.c中
static void start_rh(struct uhci_hcd *uhci) |