2. MMC驱动核心数据结构

在ARM架构下,MMC(MultiMediaCard)块设备驱动的核心由四个关键数据结构支撑:struct mmc_host(主机控制器)、struct mmc_card(卡设备)、struct mmc_request(请求)和struct mmc_command(命令)。理解这些结构的字段含义与相互关系,是进行参数配置与性能调优的基础。

学习提示: 这四个结构体构成了MMC子系统的“四层模型”——主机层、卡管理层、请求层、命令层。调优时,80%的参数修改集中在 mmc_host 和 mmc_request 中。

2.1 struct mmc_host:主机控制器抽象

struct mmc_host 代表一个MMC/SD/SDIO主机控制器实例,是驱动与硬件交互的桥梁。其关键字段按功能分为三类:硬件能力、运行时状态、调优参数。

字段名 类型 功能描述 调优关注点
f_min / f_max unsigned int 主机支持的时钟频率范围(Hz) 决定传输速率上限,ARM平台通常f_max=50MHz(HS模式)或200MHz(UHS-II)
caps / caps2 unsigned int 主机能力位掩码(如MMC_CAP_4_BIT_DATA、MMC_CAP_UHS) 开启4位/8位总线、DDR模式、UHS-I等能力
ocr_avail u32 可用操作电压范围(如3.3V、1.8V) 低电压模式(1.8V)可降低功耗但需硬件支持
max_blk_count / max_blk_size unsigned int 单次请求最大块数(通常65535)和块大小(512字节) 增大块数可提升顺序读写吞吐
max_req_size unsigned int 单次请求最大数据字节数 受DMA引擎限制,ARM平台常见1MB~4MB
pm_caps unsigned int 电源管理能力(如MMC_PM_KEEP_POWER) 休眠唤醒策略影响响应延迟
ARM平台实战: 在i.MX8M或RK3588平台上,caps 字段必须设置 MMC_CAP_8_BIT_DATA | MMC_CAP_UHS_SDR104 才能发挥eMMC 5.1的HS400性能。若未配置,驱动会降级至4位SD模式,吞吐量下降60%。
struct mmc_host 核心字段分组 硬件能力 • f_min / f_max • caps / caps2 • ocr_avail • max_blk_count • max_blk_size • max_req_size • pm_caps 运行时状态 • clock (当前时钟) • ios (接口设置) • card (关联卡设备) • claimed (占用标志) • on (上电状态) • pm_flags • led (LED指示) 调优参数 • tuning_delay • retune_crc_disable • need_retune • hold_retune • retune_period • trigger_card_event • ios.timing (时序模式)

2.2 struct mmc_card:卡设备描述

struct mmc_card 描述一个已初始化的MMC/SD卡或eMMC设备。它包含卡的标识信息、几何参数和运行时状态。

字段名 类型 说明 典型值/作用
host struct mmc_host * 指向所属主机控制器 双向关联,用于回调
rca unsigned int 相对卡地址(Relative Card Address) CMD3分配,用于后续命令寻址
type enum mmc_card_type 卡类型(MMC、SD、SDIO等) 决定协议分支
csd / cid / ext_csd struct mmc_* 卡描述寄存器、识别寄存器、扩展寄存器 ext_csd[DEVICE_LIFE_TIME] 可监控eMMC寿命
erase_size unsigned int 擦除块大小(扇区数) eMMC典型值512KB~8MB,影响TRIM性能
pref_erase unsigned int 首选擦除大小 文件系统对齐时使用
quirks u32 卡特定兼容性修正位 如MMC_QUIRK_BROKEN_IRQ_POLL
避坑指南: ext_csd 中的 DEVICE_LIFE_TIME_EST_TYP 和 PRE_EOL_INFO 字段是判断eMMC健康状态的关键。在ARM嵌入式设备中,建议每1000小时读取一次,提前预警存储介质老化。
mmc_card ↔ mmc_host 双向关联 struct mmc_host • card: struct mmc_card * • ios: struct mmc_ios • ops: struct mmc_host_ops • f_min / f_max struct mmc_card • host: struct mmc_host * • rca: unsigned int • type: enum mmc_card_type • ext_csd: u8[512] host->card card->host

2.3 struct mmc_request:请求封装

struct mmc_request 封装一次完整的MMC总线事务,包含一个或多个命令以及可选的数据传输。它是块设备层与MMC核心层之间的传输单元。

字段名 类型 说明 性能影响
cmd struct mmc_command * 主命令(如CMD18读多块) 决定操作类型
sbc struct mmc_command * 设置块计数命令(CMD23) 开启CMD23可减少总线开销
stop struct mmc_command * 停止传输命令(CMD12) 多块传输结束必须
data struct mmc_data * 数据传输描述符(sg表、块数、方向) sg表长度影响DMA效率
done void (*)(struct mmc_request *) 请求完成回调函数 回调延迟影响IO栈响应
cap_cmd_during_tfr bool 是否支持传输中执行命令 CMD42(安全写)可并发
性能调优关键: sbc(CMD23)的使用是MMC高性能的关键。当 mmc_request 包含 sbc 时,驱动会发送“预置块计数”命令,避免多块传输后发送CMD12,减少约20%的命令开销。在顺序读写场景下,务必确保 MMC_CAP_CMD23 能力位已设置。
mmc_request 多块读命令序列(CMD23 + CMD18) CMD23 SET_BLOCK_COUNT CMD18 READ_MULTIPLE_BLOCK 数据传输 DMA / PIO CMD12 STOP_TRANSMISSION 性能对比 • 有CMD23:CMD23 → CMD18 → 数据 → 结束(无CMD12,节省约50μs) • 无CMD23:CMD18 → 数据 → CMD12(额外一次命令往返,增加延迟)

2.4 struct mmc_command:命令细节

struct mmc_command 描述一条具体的MMC总线命令,包括命令索引、参数、响应类型和超时设置。它是MMC协议的最小执行单元。

字段名 类型 说明 典型值/注意事项
opcode u32 命令索引(0~63) 如CMD0=GO_IDLE_STATE, CMD6=SWITCH
arg u32 命令参数(32位) 如CMD6的arg决定访问模式和寄存器
resp[4] u32 响应数据(最多128位) R1/R2/R3/R4/R5类型不同
flags u32 命令属性(方向、响应类型、CRC使能等) 使用 MMC_CMD_AC / MMC_CMD_ADTC 等宏
error int 命令执行错误码 0=成功,-ETIMEDOUT=超时,-EILSEQ=CRC错误
retries unsigned int 命令重试次数 默认3次,调优时可改为5次以增强稳定性
busy_timeout unsigned int 忙等待超时(ms) 擦除类命令需设置较大值(如500ms)
mrq struct mmc_request * 指向所属请求 用于回调时获取上下文
调试要点: 当遇到“mmc0: Timeout waiting for hardware interrupt”错误时,首先检查 busy_timeout 是否设置过小。对于eMMC的擦除/TRIM操作,建议设置为1000ms以上。同时检查 error 字段的返回值,-110表示超时,-84表示CRC校验失败(通常需要重新调优)。
mmc_command 生命周期与错误处理 初始化 opcode/arg/flags 发送 主机控制器执行 完成/错误 error字段赋值 重试机制:若 error != 0 且 retries > 0,驱动自动重发命令,retries--

2.5 四结构体协作关系总结

四个核心数据结构在MMC驱动中的协作关系可以概括为:mmc_host 管理硬件资源,mmc_card 描述卡设备属性,mmc_request 组织一次完整事务,mmc_command 执行具体协议命令。块设备层通过 mmc_blk_data 将bio请求转换为 mmc_request,最终由主机控制器驱动完成物理传输。

调优总结:
  • 吞吐量优先: 增大 mmc_host.max_blk_count 和 max_req_size,开启 MMC_CAP_CMD23 和 MMC_CAP_8_BIT_DATA。
  • 延迟优先: 减小 mmc_request 的数据块数,使用 MMC_CAP_SDIO_IRQ 实现中断驱动。
  • 稳定性优先: 增大 mmc_command.retries 至5次,设置合理的 busy_timeout,并定期检查 mmc_card.ext_csd 健康状态。
MMC驱动四核心结构体协作关系 struct mmc_host struct mmc_card struct mmc_request struct mmc_command host->card host->mrq mrq->cmd