[RK3288][Android6.0] USB Mass Storage流程小结
来源:互联网 发布:知乎问题 提问者 编辑:程序博客网 时间:2024/05/19 01:59
Platform: ROCKCHIP
OS: Android 6.0
Kernel: 3.10.92
USB Mass Storage遵循Bulk-Only协议,参见:
http://www.usb.org/developers/docs/devclass_docs/usbmassbulk_10.pdf
传输过程大概如下:
1. 插上设备之后USB Host读取描述符信息,判断是Bulk-Only的Mass Storage之后设置地址进入Bulk-Only传输模式.
2. 一开始使用控制端点,后面传输数据使用Bulk-In和Bulk-Out端点.数据传输协议如下,摘自协议文档.
core/usb.c:
usb_init -> bus_register
struct bus_type usb_bus_type = {
.name = "usb",
.match = usb_device_match,
.uevent = usb_uevent,
};
Mass Storage驱动:
假设已经枚举成功, 然后会调用相应驱动的probe函数.
module_usb_driver ->
storage_probe ->
unusual_dev = (id - usb_storage_usb_ids) + us_unusual_dev_list; //减法获得当前设备在表中的偏移,加法获取对应表中的usb设备.
usb_stor_probe1 ->
scsi_host_alloc //分配一个scsi host, 上层通过scsi模块下发命令到usb模块,概念上可以理解为usb controller类似的东西,不过这里的scsi host是虚拟的.
associate_dev //初始化us data里相关变量,包括control/setup buffer, dma buffer.
INIT_DELAYED_WORK(&us->scan_dwork, usb_stor_scan_dwork); //接下来usb_stor_probe2()马上会用到.
get_device_info //获取usb device info.
get_transport //获取transport, 这里是"Bulk"
get_protocol //获取protrocol, 这里是"Transparent SCSI"
usb_stor_probe2 ->
get_pipes //获取pipe和endpoint
usb_stor_acquire_resources ->
usb_alloc_urb //分配urb
kthread_run(usb_stor_control_thread, us, "usb-storage"); //创建线程
usb_stor_control_thread -> //负责处理urb事务.
wait_for_completion_interruptible(&us->cmnd_ready) //休眠等待urb请求
scsi_add_host //mass storage通过scsi协议和上层通信
queue_delayed_work(system_freezable_wq, &us->scan_dwork...) ->
usb_stor_scan_dwork ->
usb_stor_Bulk_max_lun ////获取最大logic number,一个设备可能有多个lun,比如多功能读卡器.
scsi_scan_host
1. scsi发命令过来
2. 设备被拔出.
关注第一种情况:
scsi_dispatch_cmd -> scsi.c
host->hostt->queuecommand -> //usb_stor_probe1()中赋值usb_stor_host_template
queuecommand -> scsiglue.c 宏定义DEF_SCSI_QCMD(scsi_host.h中)会生成queuecommand()函数,内部调用queuecommand_lck()
queuecommand_lck ->
complete(&us->cmnd_ready) ->
usb_stor_control_thread -> usb.c
wait_for_completion_interruptible(&us->cmnd_ready) //被唤醒
us->proto_handler -> //初始化是get_protocol()中有赋值. 经过前面一系列判断之后开始处理command.
usb_stor_transparent_scsi_command ->
usb_stor_invoke_transport -> transport.c //命令发送到transport layer
us->transport -> 初始化时在get_transport()中赋值
usb_stor_Bulk_transport ->
usb_stor_bulk_transfer_buf -> //通过ctrl pipe发送command, 根据协议规定,需要发送CBW(command block wrapper.)
usb_fill_bulk_urb //填充
usb_stor_msg_common //提交
usb_stor_bulk_srb -> //真正传输数据的地方
usb_stor_bulk_transfer_sglist -> //用sglist可以提高传输效率,可以让不连续的buffers通过一次DMA操作完成传输.
usb_sg_init
usb_sg_wait //提交并等待
usb_submit_urb -> //大同小异.
wait_for_completion
usb_stor_bulk_transfer_buf //根据协议规定,需要读取CSW(command status wrapper.)
OS: Android 6.0
Kernel: 3.10.92
USB Mass Storage遵循Bulk-Only协议,参见:
http://www.usb.org/developers/docs/devclass_docs/usbmassbulk_10.pdf
传输过程大概如下:
1. 插上设备之后USB Host读取描述符信息,判断是Bulk-Only的Mass Storage之后设置地址进入Bulk-Only传输模式.
2. 一开始使用控制端点,后面传输数据使用Bulk-In和Bulk-Out端点.数据传输协议如下,摘自协议文档.
传输流程图如下:
core/usb.c:
usb_init -> bus_register
struct bus_type usb_bus_type = {
.name = "usb",
.match = usb_device_match,
.uevent = usb_uevent,
};
Mass Storage驱动:
假设已经枚举成功, 然后会调用相应驱动的probe函数.
module_usb_driver ->
storage_probe ->
unusual_dev = (id - usb_storage_usb_ids) + us_unusual_dev_list; //减法获得当前设备在表中的偏移,加法获取对应表中的usb设备.
usb_stor_probe1 ->
scsi_host_alloc //分配一个scsi host, 上层通过scsi模块下发命令到usb模块,概念上可以理解为usb controller类似的东西,不过这里的scsi host是虚拟的.
associate_dev //初始化us data里相关变量,包括control/setup buffer, dma buffer.
INIT_DELAYED_WORK(&us->scan_dwork, usb_stor_scan_dwork); //接下来usb_stor_probe2()马上会用到.
get_device_info //获取usb device info.
get_transport //获取transport, 这里是"Bulk"
get_protocol //获取protrocol, 这里是"Transparent SCSI"
usb_stor_probe2 ->
get_pipes //获取pipe和endpoint
usb_stor_acquire_resources ->
usb_alloc_urb //分配urb
kthread_run(usb_stor_control_thread, us, "usb-storage"); //创建线程
usb_stor_control_thread -> //负责处理urb事务.
wait_for_completion_interruptible(&us->cmnd_ready) //休眠等待urb请求
scsi_add_host //mass storage通过scsi协议和上层通信
queue_delayed_work(system_freezable_wq, &us->scan_dwork...) ->
usb_stor_scan_dwork ->
usb_stor_Bulk_max_lun ////获取最大logic number,一个设备可能有多个lun,比如多功能读卡器.
scsi_scan_host
URB的工作流程如下图:
1. scsi发命令过来
2. 设备被拔出.
关注第一种情况:
scsi_dispatch_cmd -> scsi.c
host->hostt->queuecommand -> //usb_stor_probe1()中赋值usb_stor_host_template
queuecommand -> scsiglue.c 宏定义DEF_SCSI_QCMD(scsi_host.h中)会生成queuecommand()函数,内部调用queuecommand_lck()
queuecommand_lck ->
complete(&us->cmnd_ready) ->
usb_stor_control_thread -> usb.c
wait_for_completion_interruptible(&us->cmnd_ready) //被唤醒
us->proto_handler -> //初始化是get_protocol()中有赋值. 经过前面一系列判断之后开始处理command.
usb_stor_transparent_scsi_command ->
usb_stor_invoke_transport -> transport.c //命令发送到transport layer
us->transport -> 初始化时在get_transport()中赋值
usb_stor_Bulk_transport ->
usb_stor_bulk_transfer_buf -> //通过ctrl pipe发送command, 根据协议规定,需要发送CBW(command block wrapper.)
usb_fill_bulk_urb //填充
usb_stor_msg_common //提交
usb_stor_bulk_srb -> //真正传输数据的地方
usb_stor_bulk_transfer_sglist -> //用sglist可以提高传输效率,可以让不连续的buffers通过一次DMA操作完成传输.
usb_sg_init
usb_sg_wait //提交并等待
usb_submit_urb -> //大同小异.
wait_for_completion
usb_stor_bulk_transfer_buf //根据协议规定,需要读取CSW(command status wrapper.)
参考:
<<Linux那些事儿之我是U盘>>
http://www.csksoft.net/blog/post/linux_storage_mod.html
http://www.crifan.com/files/doc/docbook/usb_disk_driver/release/html/usb_disk_driver.html
http://www.doc88.com/p-7774041096629.html
http://blog.csdn.net/sharecode/article/details/9166077
1 0
- [RK3288][Android6.0] USB Mass Storage流程小结
- [RK3288][Android6.0] USB hub初始化流程小结
- [RK3288][Android6.0] USB WiFi驱动流程小结
- [RK3288][Android6.0] USB 枚举过程小结
- [RK3288][Android6.0] USB UVC 驱动小结
- [RK3288][Android6.0] USB 枚举过程小结
- [RK3288][Android6.0] USB ECHI 驱动小结
- [RK3288][Android6.0] Camera HAL流程小结
- [RK3288][Android6.0] StageFright解码流程小结
- [RK3288][Android6.0] 串口驱动流程小结
- [RK3288][Android6.0] ION 驱动流程小结
- [RK3288][Android6.0] Camera HAL流程小结
- android6.0.1 usb mass storage 配置
- [RK3288][Android6.0] PWM backlight 驱动流程小结
- [RK3288][Android6.0] DDR Frequency控制流程小结
- [RK3288][Android6.0] U-boot 启动流程小结
- [RK3288][Android6.0] Display驱动初始化流程小结
- [RK3288][Android6.0] U-boot显示模块部分流程小结
- poj2411 Mondriaan's Dream--状压dp
- Java Web开发系列博文介绍
- 第四周:选择结构的程序设计的习题(北理)
- 向前走
- log4j配置
- [RK3288][Android6.0] USB Mass Storage流程小结
- mysql-5.7.16-winx64安装版配置、使用
- android探索之MVP
- 学习spring-boot第一节demo运行与web启动
- JS实现精确加减乘除
- bzoj1069 凸包+旋转卡壳
- uploadAction文件上传
- Android 窗口管理:Z-Order管理
- 面向对象的六大原则