RK3588 kernel-6.1 drivers/usb/storage 代码功能与实现原理

RK3588 kernel-6.1 drivers/usb/storage 代码功能与实现原理

1. 定位:两套路径(BOT vs UAS)

模块(Makefile 典型名称 作用
usb-storageCONFIG_USB_STORAGE usb-storage.ko USB Mass Storage Bulk-Only Transport(BOT) 及旧 CB/CBI 等:Bulk 管道搬运 SCSI CDB
uasCONFIG_USB_UAS uas.ko USB Attached SCSI:命令/状态/数据 多管道 + 可选 USB3 Streams,更接近原生 SCSI 异步模型

二者均依赖 SCSI 子系统;常见块设备还需 CONFIG_BLK_DEV_SD(sd 磁盘)。


2. USB Mass Storage 类规范与分层

usb.h 头部注释说明实现依据 USB Mass Storage Class,命令形态贴近 SCSI-II / ATAPI;类规范对 NAK/STALL/ACK 的语义与通用 USB 略有差异,部分设备用 中断端点 上报命令状态(CBI)。

内核内部分层(struct us_data):

层级 文件 职责
协议(Protocol) protocol.c scsi_cmnd 打成设备可接受的 CDB 长度/变体(透明 SCSI、UFI、Pad12 等),再调用传输
传输(Transport) transport.c CB/CBI/Bulk-Only:打包 URB、Bulk 收发、REQUEST_SENSE 自动 sense、复位与错误恢复
SCSI 胶水 scsiglue.c 注册 struct scsi_host_templatequeuecommandslave_configure(队列 max_hw_sectors、DMA bounce)、eh_abort / reset
设备生命周期与线程 usb.c usb_driver probe、根据接口 bInterfaceSubClass / Protocol 绑定 transport + proto_handler控制内核线程

大量 unusual_*.h / usual-tables.cVID/PID + quirks + 可选 init,覆盖不按规范暴露 SubClass/Protocol 的固件。


3. 核心数据结构:us_datausb.h

每个已绑定的 U 盘对应一块 us_data(挂在 Scsi_Host->hostdata):

  • USBpusb_devpusb_intf、缓存的 bulk/control/intr pipe
  • 传输/协议transporttransport_resetproto_handlersubclass/protocol/max_lun
  • 并发模型单命令槽 srb + completion cmnd_ready + usb_stor_control_thread
  • 缓冲iobuf(小 DMA 缓冲)、current_urbusb_sg_request
  • quirksfflags/dflagsuse_last_sector_hacks

4. 命令路径:queuecommand → 内核线程 → invoke_transport

4.1 SCSI 中层下发

scsiglue.cqueuecommand_lck(持 scsi_lock):

  • 保证 us->srb 为空(同一时间 一条 SCSI 命令);
  • us->srb = srb
  • complete(&us->cmnd_ready) 唤醒 usb-storage 线程。

4.2 控制线程 usb_stor_control_threadusb.c

循环 wait_for_completion(&cmnd_ready),取 us->srb,校验 LUN/target/方向,处理 FIX_INQUIRY 等特殊路径,否则调用:

1
2
3
4
5
else {
US_DEBUG(usb_stor_show_command(us, srb));
us->proto_handler(srb, us);
usb_mark_last_busy(us->pusb_dev);
}

协议层入口

4.3 协议层(protocol.c

  • usb_stor_transparent_scsi_command:直接 usb_stor_invoke_transport
  • usb_stor_pad12_command:CDB padding 到 12 字节(RBC/8070 等)
  • usb_stor_ufi_commandUFI 命令长度与 INQUIRY/MODE_SENSE/REQUEST_SENSE 长度裁剪

4.4 传输与会聚:usb_stor_invoke_transporttransport.c

usb_stor_invoke_transport

  1. result = us->transport(srb, us) —— Bulk-OnlyCBW → Data → CSW(或 CB/CBI 控制传输路径);
  2. 根据返回值决定是否 自动 REQUEST_SENSE、是否 端口复位
  3. 处理 last sector 等与劣质固件相关的补丁逻辑。

传输返回值语义transport.h):USB_STOR_TRANSPORT_GOOD/FAILED/NO_SENSE/ERROR,区分 命令失败USB 链路错误


5. get_transport / get_protocolusb.c

接口 bInterfaceProtocol传输

  • USB_PR_BULKBulk-Only(绝大多数 U 盘)
  • USB_PR_CB / USB_PR_CBIControl-Bulk[-Interrupt]

bInterfaceSubClass协议处理器

  • USB_SC_SCSI:透明 SCSI
  • USB_SC_UFI:软驱类 UFI
  • USB_SC_RBCUSB_SC_8020USB_SC_QICUSB_SC_8070:各类缩减/光学命令集

6. SCSI Host 与块层(scsiglue.c

  • slave_allocINQUIRY 长度 36队列 DMA 对齐
  • slave_configure:限制 单次传输扇区数(兼容弱设备;SuperSpeed 提到 2048 sectors)、PIO HCDbounce limit
  • queuecommandDEF_SCSI_QCMD 包装锁
  • 错误处理abort、bus reset、device resetus->dflags、URB unlink 协作

7. uas.c(独立于 BOT 路径)

  • 不为每个命令占用单一 usb-storage 线程;使用 usb_anchorworkqueuetag ↔ scsi_cmnd 映射(MAX_CMNDS)。
  • 命令 URB、状态 URB、数据 IN/OUT URBUAS 规范并行;可选 Bulk Streams
  • uas-detect.h:与 usb-storage 协同 探测:若设备支持 UAS 且无黑名单,优先绑定 uas 驱动(避免同一设备双驱动冲突)。

原理BOT 串行 CSW、单队列UAS 多命令流水,更适合 SSD / USB3


8. 子驱动(ums-*

alauda.cdatafab.cisd200.c 等:面向 非标准桥片,实现私有 transport/init,编译为独立 ums-*.ko,由 usb_storage_usb_ids / unusual 表挂载。


9. 其它文件

  • initializers.c:部分 unusual 设备的 probe 阶段初始化
  • debug.cCONFIG_USB_STORAGE_DEBUG
  • sierra_ms.c / option_ms.c调制解调器 / 复合设备 存储相关 quirks

10. 数据流简图(BOT)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
blk_mq / sd


SCSI mid-layer ──queuecommand──► us->srb + complete(cmnd_ready)


usb_stor_control_thread


proto_handler (protocol.c)


usb_stor_invoke_transport (transport.c)


transport = Bulk/CB ──URB──► usbcore ──► DWC3/xHCI … ──► 设备固件

11. 延伸阅读(本仓库)

文档
drivers-usb-core详细分析.md
USB总线枚举匹配与数据传输分析.md

基于 rk3588/kernel-6.1/drivers/usb/storage 源码归纳。

文章互动

阅读 --

留言

0 条留言

正在加载留言…