musb 0619
2016-06-19 23:33
555 查看
06.18
. usb_core.c和usb20.c(对应两个驱动,一个是specific musb controller驱动,一个是musb core驱动)的关系
usb20/musb_core.c中的musb_init初始化musb core驱动。usb20目录下的文件应该是musb core的文件。这个目录下的mtk目录是mt6735 specific musb controller
驱动的文件。在mt6735目录下的usb20.c中的mt_usb_probe函数中,musb_hdrc_platform_data类型的结构中的指针成员
platform_ops指向musb_platform_ops类型的mt_usb_ops结构,之后通过platform_device_add_data函数将platform device结构中的device结构中的指针platform_data
成员指向musb_hdrc_platform_data类型的结构。
在musb core驱动的musb_probe中根据platform_device结构(就是usb20.c中的mt musb controller),获得这个结构中的device类型结构给musb_init_controller,在这个函数中,根据参数device类型的结构
中的platform_data指针得到一个musb_hdrc_platform_data类型的结构,这个结构中有一个musb_hdrc_config类型的成员,根据这个成员和musb controller寄存器起始
地址,通过allocate_instance创建一个musb结构。创建这个musb结构时,设置musb中的mregs成员为参数中的musb controller寄存器base address。然后在musb_init_controller
函数中,将分配得到的musb结构中的musb_platform_ops类型的成员ops设置为musb_hdrc_platform_data中的platform_ops指针。然后根据musb执行musb_platform_init。
在这个函数中,执行musb中的musb_platform_ops类型的成员ops中的init函数。
. fifo_cfg_host和fifo_cfg的关系
fifo_cfg_host:应该是musb controller作为host时的hw endpoint配置;而fifo_cfg应该是musb controller作为slave时的配置,同一个时刻musb controller
应该只能担当一种角色。
. 看下面的log,mt6735 musb controller应该还支持high bandwidth isoc rx&tx:
[ 5.415233]<3>.(3)[1:swapper/0][zhongcai] musb_core: musb-hdrc: ConfigData=0x1f (UTMI-16, dyn FIFOs, HB-ISO Rx, HB-ISO Tx, SoftConn)
. 在提交urb之后,musb控制器向usb camera请求数据的过程中调用了函数musb_ep_program,如果hw ep的rx dma_channel是null,调用dma_controller的channel alloc
函数分配一个dma_channel给它。所以当musb controller收到urb packet时,在musb_host_rx函数中,dma_channel类型的dma指针不是null。
. dma_controller中的channel_program函数所做的事情应该是从fifo读取数据到RAM上的buffer。
musb_host_r函数结构
当musb controller收到urb的packet时,会调用musb_host_rx(在中断context),在这个函数中:
1. 这时urb的status是INPROGRESS,并且RXCSR中的DMAENA标志没有被设置,dma指针不为null。这时,设置RXCSR寄存器中的DMAENA标志,清除REQPKT标志。
根据当前urb packet的序号确定urb中当前的空的packet buffer,调用channel_program函数执行从rx fifo中卸载usb(urb) packet到
urb的packet buffer中。如果这个函数执行失败,清除RXCSR中DMAENA标志,取消dma channel,设置dma指针为null,如果这个指针为null,执行紧接着的if(!dma)部分。
2. 上面的卸载工作完成之后,再次调用musb_host_rx,此时dma_channel类型的指针仍然还非null,并且RXCSR中的DMAENA标志为1,这时,
清除RXCSR中的DMAENA标志,根据step1中dma传输的数据大小,设置当前urb packet的实际大小,并增加urb packet的计数。然后设置RXCSR
中的REQPKT标志从新向usb camera请求usb(urb) packet。然后在musb_host_rx的最下面将urb的实际大小和musb_qh中offset成员增加本次
step1中dma传输的大小。
如果urb packet的计数达到了urb中packet的最大值,会调用urb的complete函数。
注意:
1. 在step1中xfer_len为0,所以urb的实际大小、musb_qh中offset成员的大小会维持。
2. 在step2中,读RXCOUNT寄存器,读到的结果是0.因为rx fifo中的数据已经被读取了。而在step1中,读取RXCOUNT,读到的结果不是0,它和在这一step中dma读取大小是
相等的。
musb
. Operates as a function controller for a USB peripheral or as the host in communications with another USB function
usb设备控制器称为usb function controller
. RXCSRH中的incompRX标志:
If the indicated number of packets has not been received by the end of a microframe, the IncompRx bit in the RxCSR register will
be set to indicate that the data in the FIFO is incomplete.
usb
*******************************************************************
. URB_SHORT_NOT_OK,如果有这个标志,说明认为urb short packet是error的。
. stream on时,执行ioctl(STREAMON)根据要求的bandwidth(max video frame size)在每个setting中找到一个目标endpoint,判断这个endpoint
的最大包大小是否满足bandwidth,如果大于,则满足,成为best endpoint candidate,它的max packet size成为best size candidate。然后继续
对余下的setting执行同样的操作,知道最后一个setting判断完,这时的best endpoint candidate和best packet size candidate成为best endpoint
和best packet size。
注意:在上面的循环中,还会确定best setting。
根据log,这个循环选出的best setting index是6,best endpoint的最大包大小是1024,因为是high bandwidth isoc endpoint,multi等于2,加1之后
就是3,所以一个usb isoc transfer macroframe的大小是3072(这仍然是一个usb packet大小):
<7>[ 1387.902910]<0> (2)[2970:ra.simplewebcam]uvcvideo: Selecting alternate setting 6 (3072 B/frame bandwidth).
所以接下来分配的urb中所有packet都是3072.
. 一个urb中最大的packet数量是transfer_buf_length,32.
. usb_submit_urb提交一个urb(in类型的urb),当usb host controller收到usb device的数据包后,开始装填urb中的packet,当这个urb中的所有packet
装填完毕时,调用这个urb的complete函数,这个usb_submit_urb函数返回。
. usb_core.c和usb20.c(对应两个驱动,一个是specific musb controller驱动,一个是musb core驱动)的关系
usb20/musb_core.c中的musb_init初始化musb core驱动。usb20目录下的文件应该是musb core的文件。这个目录下的mtk目录是mt6735 specific musb controller
驱动的文件。在mt6735目录下的usb20.c中的mt_usb_probe函数中,musb_hdrc_platform_data类型的结构中的指针成员
platform_ops指向musb_platform_ops类型的mt_usb_ops结构,之后通过platform_device_add_data函数将platform device结构中的device结构中的指针platform_data
成员指向musb_hdrc_platform_data类型的结构。
在musb core驱动的musb_probe中根据platform_device结构(就是usb20.c中的mt musb controller),获得这个结构中的device类型结构给musb_init_controller,在这个函数中,根据参数device类型的结构
中的platform_data指针得到一个musb_hdrc_platform_data类型的结构,这个结构中有一个musb_hdrc_config类型的成员,根据这个成员和musb controller寄存器起始
地址,通过allocate_instance创建一个musb结构。创建这个musb结构时,设置musb中的mregs成员为参数中的musb controller寄存器base address。然后在musb_init_controller
函数中,将分配得到的musb结构中的musb_platform_ops类型的成员ops设置为musb_hdrc_platform_data中的platform_ops指针。然后根据musb执行musb_platform_init。
在这个函数中,执行musb中的musb_platform_ops类型的成员ops中的init函数。
. fifo_cfg_host和fifo_cfg的关系
fifo_cfg_host:应该是musb controller作为host时的hw endpoint配置;而fifo_cfg应该是musb controller作为slave时的配置,同一个时刻musb controller
应该只能担当一种角色。
. 看下面的log,mt6735 musb controller应该还支持high bandwidth isoc rx&tx:
[ 5.415233]<3>.(3)[1:swapper/0][zhongcai] musb_core: musb-hdrc: ConfigData=0x1f (UTMI-16, dyn FIFOs, HB-ISO Rx, HB-ISO Tx, SoftConn)
. 在提交urb之后,musb控制器向usb camera请求数据的过程中调用了函数musb_ep_program,如果hw ep的rx dma_channel是null,调用dma_controller的channel alloc
函数分配一个dma_channel给它。所以当musb controller收到urb packet时,在musb_host_rx函数中,dma_channel类型的dma指针不是null。
. dma_controller中的channel_program函数所做的事情应该是从fifo读取数据到RAM上的buffer。
musb_host_r函数结构
当musb controller收到urb的packet时,会调用musb_host_rx(在中断context),在这个函数中:
1. 这时urb的status是INPROGRESS,并且RXCSR中的DMAENA标志没有被设置,dma指针不为null。这时,设置RXCSR寄存器中的DMAENA标志,清除REQPKT标志。
根据当前urb packet的序号确定urb中当前的空的packet buffer,调用channel_program函数执行从rx fifo中卸载usb(urb) packet到
urb的packet buffer中。如果这个函数执行失败,清除RXCSR中DMAENA标志,取消dma channel,设置dma指针为null,如果这个指针为null,执行紧接着的if(!dma)部分。
2. 上面的卸载工作完成之后,再次调用musb_host_rx,此时dma_channel类型的指针仍然还非null,并且RXCSR中的DMAENA标志为1,这时,
清除RXCSR中的DMAENA标志,根据step1中dma传输的数据大小,设置当前urb packet的实际大小,并增加urb packet的计数。然后设置RXCSR
中的REQPKT标志从新向usb camera请求usb(urb) packet。然后在musb_host_rx的最下面将urb的实际大小和musb_qh中offset成员增加本次
step1中dma传输的大小。
如果urb packet的计数达到了urb中packet的最大值,会调用urb的complete函数。
注意:
1. 在step1中xfer_len为0,所以urb的实际大小、musb_qh中offset成员的大小会维持。
2. 在step2中,读RXCOUNT寄存器,读到的结果是0.因为rx fifo中的数据已经被读取了。而在step1中,读取RXCOUNT,读到的结果不是0,它和在这一step中dma读取大小是
相等的。
musb
. Operates as a function controller for a USB peripheral or as the host in communications with another USB function
usb设备控制器称为usb function controller
. RXCSRH中的incompRX标志:
If the indicated number of packets has not been received by the end of a microframe, the IncompRx bit in the RxCSR register will
be set to indicate that the data in the FIFO is incomplete.
usb
*******************************************************************
. URB_SHORT_NOT_OK,如果有这个标志,说明认为urb short packet是error的。
. stream on时,执行ioctl(STREAMON)根据要求的bandwidth(max video frame size)在每个setting中找到一个目标endpoint,判断这个endpoint
的最大包大小是否满足bandwidth,如果大于,则满足,成为best endpoint candidate,它的max packet size成为best size candidate。然后继续
对余下的setting执行同样的操作,知道最后一个setting判断完,这时的best endpoint candidate和best packet size candidate成为best endpoint
和best packet size。
注意:在上面的循环中,还会确定best setting。
根据log,这个循环选出的best setting index是6,best endpoint的最大包大小是1024,因为是high bandwidth isoc endpoint,multi等于2,加1之后
就是3,所以一个usb isoc transfer macroframe的大小是3072(这仍然是一个usb packet大小):
<7>[ 1387.902910]<0> (2)[2970:ra.simplewebcam]uvcvideo: Selecting alternate setting 6 (3072 B/frame bandwidth).
所以接下来分配的urb中所有packet都是3072.
. 一个urb中最大的packet数量是transfer_buf_length,32.
. usb_submit_urb提交一个urb(in类型的urb),当usb host controller收到usb device的数据包后,开始装填urb中的packet,当这个urb中的所有packet
装填完毕时,调用这个urb的complete函数,这个usb_submit_urb函数返回。
相关文章推荐
- 20145321 《Java程序设计》课程总结
- 选择排序与冒泡排序
- 20145316 《Java程序设计》 课程总结
- 十五周进度条
- mysql 统计每个门店 每天 每月 每年 的订单 消费总额
- 推举一个在线matlab(octave)
- HDU 1874 畅通工程续
- 简单实现一个ArrayList
- 即将迈入大学未来想做网站运营,如何避免走弯路?
- 即将迈入大学未来想做网站运营,如何避免走弯路?
- Java TreeMap工作原理及实现
- 日志服务器:
- 14.1 && 14.2节练习
- LeetCode-235 Lowest Common Ancestor of a Binary Search Tree
- Spring mvc框架tutorial
- Struts2(五):ActionSupport
- js闭包
- TCP通信的三次握手和四次撒手的详细流程
- Java 多维数组遍历
- Hibernate(一) 之 延迟加载