备注:
1. Kernel版本:5.4
2. 使用工具:Source Insight 4.0
3. 参考博客:
2. [mmc subsystem] mmc core数据结构和宏定义说明
Linux MMC framework(2)_host controller driver
- Linux驱动——mmc数据结构(二)
- 数据结构关系
- host 相关
- struct mmc_host
- struct mmc_host_ops
- card相关
- struct mmc_card
- host的总线相关
- struct mmc_bus_ops
- struct mmc_ios
- mmc请求相关
- struct mmc_command
- struct mmc_data
- struct mmc_request
struct mmc_host是mmc core由host controller抽象出来的结构体,用于代表一个mmc host控制器。
struct mmc_host {
struct device *parent; //对应的host controller的device
struct device class_dev; // mmc_host的device结构体,会挂在class/mmc_host下
int index; // 该host的索引号
const struct mmc_host_ops *ops; // 该host的操作集,由host controller设置
struct mmc_pwrseq *pwrseq; // 该host电源管理有关的操作函数集
unsigned int f_min; // 该host支持的最低频率
unsigned int f_max; // 该host支持的最大频率
unsigned int f_init; // 该host使用的初始化频率
u32 ocr_avail; // 该host可支持的操作电压范围
u32 ocr_avail_sdio;
u32 ocr_avail_sd;
u32 ocr_avail_mmc;
#ifdef CONFIG_PM_SLEEP
struct notifier_block pm_notify;// 用于支持power management有关的notify实现
#endif
u32 max_current_330; // 3.3V时的最大电流
u32 max_current_300; // 3.0V时的最大电流
u32 max_current_180; // 1.8V时的最大电流
#define MMC_VDD_165_195 0x00000080
#define MMC_VDD_20_21 0x00000100
#define MMC_VDD_21_22 0x00000200
#define MMC_VDD_22_23 0x00000400
#define MMC_VDD_23_24 0x00000800
#define MMC_VDD_24_25 0x00001000
#define MMC_VDD_25_26 0x00002000
#define MMC_VDD_26_27 0x00004000
#define MMC_VDD_27_28 0x00008000
#define MMC_VDD_28_29 0x00010000
#define MMC_VDD_29_30 0x00020000
#define MMC_VDD_30_31 0x00040000
#define MMC_VDD_31_32 0x00080000
#define MMC_VDD_32_33 0x00100000
#define MMC_VDD_33_34 0x00200000
#define MMC_VDD_34_35 0x00400000
#define MMC_VDD_35_36 0x00800000
// 指示该MMC host所支持的功能特性
u32 caps;
#define MMC_CAP_4_BIT_DATA (1 << 0)
#define MMC_CAP_MMC_HIGHSPEED (1 << 1)
#define MMC_CAP_SD_HIGHSPEED (1 << 2)
#define MMC_CAP_SDIO_IRQ (1 << 3)
#define MMC_CAP_SPI (1 << 4)
#define MMC_CAP_NEEDS_POLL (1 << 5)
#define MMC_CAP_8_BIT_DATA (1 << 6)
#define MMC_CAP_AGGRESSIVE_PM (1 << 7)
#define MMC_CAP_NonREMOVABLE (1 << 8)
#define MMC_CAP_WAIT_WHILE_BUSY (1 << 9)
#define MMC_CAP_ERASE (1 << 10)
#define MMC_CAP_3_3V_DDR (1 << 11)
#define MMC_CAP_1_8V_DDR (1 << 12)
#define MMC_CAP_1_2V_DDR (1 << 13)
#define MMC_CAP_POWER_OFF_CARD (1 << 14)
#define MMC_CAP_BUS_WIDTH_TEST (1 << 15)
#define MMC_CAP_UHS_SDR12 (1 << 16)
#define MMC_CAP_UHS_SDR25 (1 << 17)
#define MMC_CAP_UHS_SDR50 (1 << 18)
#define MMC_CAP_UHS_SDR104 (1 << 19)
#define MMC_CAP_UHS_DDR50 (1 << 20)
#define MMC_CAP_UHS (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
MMC_CAP_UHS_DDR50)
#define MMC_CAP_SYNC_RUNTIME_PM (1 << 21)
#define MMC_CAP_NEED_RSP_BUSY (1 << 22)
#define MMC_CAP_DRIVER_TYPE_A (1 << 23)
#define MMC_CAP_DRIVER_TYPE_C (1 << 24)
#define MMC_CAP_DRIVER_TYPE_D (1 << 25)
#define MMC_CAP_DONE_COMPLETE (1 << 27)
#define MMC_CAP_CD_WAKE (1 << 28)
#define MMC_CAP_CMD_DURING_TFR (1 << 29)
#define MMC_CAP_CMD23 (1 << 30)
#define MMC_CAP_HW_RESET (1 << 31)
// 指示该MMC host所支持的功能特性
u32 caps2;
#define MMC_CAP2_BOOTPART_NOACC (1 << 0)
#define MMC_CAP2_FULL_PWR_CYCLE (1 << 2)
#define MMC_CAP2_HS200_1_8V_SDR (1 << 5)
#define MMC_CAP2_HS200_1_2V_SDR (1 << 6)
#define MMC_CAP2_HS200 (MMC_CAP2_HS200_1_8V_SDR |
MMC_CAP2_HS200_1_2V_SDR)
#define MMC_CAP2_CD_ACTIVE_HIGH (1 << 10)
#define MMC_CAP2_RO_ACTIVE_HIGH (1 << 11)
#define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14)
#define MMC_CAP2_HS400_1_8V (1 << 15)
#define MMC_CAP2_HS400_1_2V (1 << 16)
#define MMC_CAP2_HS400 (MMC_CAP2_HS400_1_8V |
MMC_CAP2_HS400_1_2V)
#define MMC_CAP2_HSX00_1_8V (MMC_CAP2_HS200_1_8V_SDR | MMC_CAP2_HS400_1_8V)
#define MMC_CAP2_HSX00_1_2V (MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V)
#define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17)
#define MMC_CAP2_NO_WRITE_PROTECT (1 << 18)
#define MMC_CAP2_NO_SDIO (1 << 19)
#define MMC_CAP2_HS400_ES (1 << 20)
#define MMC_CAP2_NO_SD (1 << 21)
#define MMC_CAP2_NO_MMC (1 << 22)
#define MMC_CAP2_CQE (1 << 23)
#define MMC_CAP2_CQE_DCMD (1 << 24)
#define MMC_CAP2_AVOID_3_3V (1 << 25)
#define MMC_CAP2_MERGE_CAPABLE (1 << 26)
int fixed_drv_type;
// 该host所支持的电源管理特性
mmc_pm_flag_t pm_caps;
unsigned int max_seg_size;
unsigned short max_segs;
unsigned short unused;
unsigned int max_req_size;
unsigned int max_blk_size;
unsigned int max_blk_count;
unsigned int max_busy_timeout;
// 该host的bus使用的锁
spinlock_t lock;
// 用于保存MMC bus的当前配置
struct mmc_ios ios;
unsigned int use_spi_crc:1;
unsigned int claimed:1; // host是否已经被占用
unsigned int bus_dead:1; // host的bus是否处于激活状态
unsigned int can_retune:1;
unsigned int doing_retune:1;
unsigned int retune_now:1;
unsigned int retune_paused:1;
unsigned int use_blk_mq:1;
unsigned int retune_crc_disable:1;
unsigned int can_dma_map_merge:1;
int rescan_disable; // 禁止rescan的标识,禁止搜索card
int rescan_entered; // 是否已经rescan过的标识,对应不可移除的设备只能rescan一次
int need_retune;
int hold_retune;
unsigned int retune_period;
struct timer_list retune_timer;
bool trigger_card_event;
struct mmc_card *card; // 和该host绑定在一起的card
wait_queue_head_t wq;
struct mmc_ctx *claimer; // 该host的占有者进程
int claim_cnt; // 占有者进程对该host的占用计数
struct mmc_ctx default_ctx;
struct delayed_work detect; // 检测卡槽变化的工作
int detect_change; // 需要检测卡槽变化的标识
struct mmc_slot slot; // 卡槽的结构体
const struct mmc_bus_ops *bus_ops; // host的mmc总线的操作集
unsigned int bus_refs; // host的mmc总线的使用计数
unsigned int sdio_irqs;
struct task_struct *sdio_irq_thread;
struct delayed_work sdio_irq_work;
bool sdio_irq_pending;
atomic_t sdio_irq_thread_abort;
mmc_pm_flag_t pm_flags;
struct led_trigger *led;
#ifdef CONFIG_REGULATOR
bool regulator_enabled; // 代表regulator(LDO)的状态
#endif
struct mmc_supply supply;
struct dentry *debugfs_root; // 对应的debug目录结构体
struct mmc_request *ongoing_mrq;
#ifdef CONFIG_FAIL_MMC_REQUEST
struct fault_attr fail_mmc_request;
#endif
unsigned int actual_clock;
unsigned int slotno;
int dsr_req;
u32 dsr;
const struct mmc_cqe_ops *cqe_ops;
void *cqe_private;
int cqe_qdepth;
bool cqe_enabled;
bool cqe_on;
unsigned long private[0] ____cacheline_aligned;
};
struct mmc_host_ops
mmc core将host需要提供的一些操作方法封装成struct mmc_host_ops。
mmc core主模块的很多接口都是基于这里面的操作方法来实现的,通过这些方法来操作host硬件达到对应的目的。
所以struct mmc_host_ops也是host controller driver需要实现的核心部分。
struct mmc_host_ops {
// post_req和pre_req是为了实现异步请求处理而设置的,是非必需的,
// 异步请求处理就是指,当另外一个异步请求还没有处理完成的时候,
// 可以先准备另外一个异步请求而不必等待
void (*post_req)(struct mmc_host *host, struct mmc_request *req,
int err);
void (*pre_req)(struct mmc_host *host, struct mmc_request *req);
// host处理mmc请求的方法,在mmc_start_request中会调用
void (*request)(struct mmc_host *host, struct mmc_request *req);
// 设置host的总线的io setting
void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);
int (*get_ro)(struct mmc_host *host); // 获取host上的card的读写属性
int (*get_cd)(struct mmc_host *host); // 检测host的卡槽中card的插入状态
void (*enable_sdio_irq)(struct mmc_host *host, int enable);
void (*ack_sdio_irq)(struct mmc_host *host);
// 初始化card的方法
void (*init_card)(struct mmc_host *host, struct mmc_card *card);
int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios);
int (*card_busy)(struct mmc_host *host); // 用于检测card是否处于busy状态
// 执行tuning操作,为card选择一个合适的采样点
int (*execute_tuning)(struct mmc_host *host, u32 opcode);
int (*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios);
int (*hs400_prepare_ddr)(struct mmc_host *host);
void (*hs400_downgrade)(struct mmc_host *host);
void (*hs400_complete)(struct mmc_host *host);
void (*hs400_enhanced_strobe)(struct mmc_host *host,
struct mmc_ios *ios);
int (*select_drive_strength)(struct mmc_card *card,
unsigned int max_dtr, int host_drv,
int card_drv, int *drv_type);
void (*hw_reset)(struct mmc_host *host); // 硬件复位
void (*card_event)(struct mmc_host *host); // 硬件复位
int (*multi_io_quirk)(struct mmc_card *card,
unsigned int direction, int blk_size);
};
card相关
struct mmc_card
struct mmc_card是mmc core由mmc设备抽象出来的card设备的结构体,用于代表一个mmc设备。
struct mmc_card {
struct mmc_host *host; // 该mmc_card所属host
struct device dev; // 对应的device
u32 ocr;
unsigned int rca;
unsigned int type; // card类型
#define MMC_TYPE_MMC 0
#define MMC_TYPE_SD 1
#define MMC_TYPE_SDIO 2
#define MMC_TYPE_SD_COMBO 3
unsigned int state; // card的当前状态
unsigned int quirks; // 该card的一些特点
unsigned int quirk_max_rate;
#define MMC_QUIRK_LENIENT_FN0 (1<<0)
#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1)
#define MMC_QUIRK_NONSTD_SDIO (1<<2)
#define MMC_QUIRK_NONSTD_FUNC_IF (1<<4)
#define MMC_QUIRK_DISABLE_CD (1<<5)
#define MMC_QUIRK_INAND_CMD38 (1<<6)
#define MMC_QUIRK_BLK_NO_CMD23 (1<<7)
#define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8)
#define MMC_QUIRK_LONG_READ_TIME (1<<9)
#define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10)
#define MMC_QUIRK_BROKEN_IRQ_POLLING (1<<11)
#define MMC_QUIRK_TRIM_BROKEN (1<<12)
#define MMC_QUIRK_BROKEN_HPI (1<<13)
bool reenable_cmdq;
unsigned int erase_size;
unsigned int erase_shift;
unsigned int pref_erase;
unsigned int eg_boundary;
unsigned int erase_arg;
u8 erased_byte;
u32 raw_cid[4]; // 原始的cid寄存器的值
u32 raw_csd[4]; // 原始的csd寄存器的值
u32 raw_scr[2]; // 原始的scr寄存器的值
u32 raw_ssr[16]; // 原始的ssr寄存器的值
struct mmc_cid cid; // 从cid寄存器的值解析出来的信息
struct mmc_csd csd; // 从csd寄存器的值解析出来的信息
struct mmc_ext_csd ext_csd; // 从ext_csd寄存器的值解析出来的信息
struct sd_scr scr; // 外部sd card的信息
struct sd_ssr ssr; // 更多关于sd card的信息
struct sd_switch_caps sw_caps; // sd的切换属性
unsigned int sdio_funcs; // sdio funcs的数量
atomic_t sdio_funcs_probed;
struct sdio_cccr cccr;
struct sdio_cis cis;
struct sdio_func *sdio_func[SDIO_MAX_FUNCS]; //sdio func指针
struct sdio_func *sdio_single_irq;
unsigned num_info;
const char **info;
struct sdio_func_tuple *tuples;
unsigned int sd_bus_speed;
unsigned int mmc_avail_type;
unsigned int drive_strength;
struct dentry *debugfs_root; // 对应debug目录的结构体
struct mmc_part part[MMC_NUM_PHY_PARTITION]; // 物理分区
unsigned int nr_parts; // 分区数量
unsigned int bouncesz;
struct workqueue_struct *complete_wq;
};
host的总线相关
struct mmc_bus_ops
host的mmc总线的操作集,由host插入的card决定。
不同类型的card对mmc总线的操作有所不同。
struct mmc_bus_ops {
void (*remove)(struct mmc_host *); // 从软件上注销mmc总线上的card
void (*detect)(struct mmc_host *); // 检测mmc总线上的card是否被移除
int (*pre_suspend)(struct mmc_host *); // suspend前的准备工作
int (*suspend)(struct mmc_host *); // 对应mmc总线的suspend操作
int (*resume)(struct mmc_host *); // 对应mmc总线的resume操作
int (*runtime_suspend)(struct mmc_host *); // 对应mmc总线的runtime suspend操作
int (*runtime_resume)(struct mmc_host *); // 对应mmc总线的runtime resume操作
int (*alive)(struct mmc_host *); // 检测mmc总线上的card的激活状态
int (*shutdown)(struct mmc_host *);// 关闭mmc总线的操作
int (*hw_reset)(struct mmc_host *);// mmc总线上的HW 复位
int (*sw_reset)(struct mmc_host *);// mmc总线上的SW 复位
};
struct mmc_ios
struct mmc_ios {
unsigned int clock; // 当前工作频率
unsigned short vdd; // 支持的电压表
unsigned int power_delay_ms;
unsigned char bus_mode; // 总线输出模式,包括开漏模式和上拉模式
#define MMC_BUSMODE_OPENDRAIN 1
#define MMC_BUSMODE_PUSHPULL 2
unsigned char chip_select; // spi片选
#define MMC_CS_DonTCARE 0
#define MMC_CS_HIGH 1
#define MMC_CS_LOW 2
unsigned char power_mode; // 电源状态模式
#define MMC_POWER_OFF 0
#define MMC_POWER_UP 1
#define MMC_POWER_ON 2
#define MMC_POWER_UNDEFINED 3
unsigned char bus_width; // 总线宽度
#define MMC_BUS_WIDTH_1 0
#define MMC_BUS_WIDTH_4 2
#define MMC_BUS_WIDTH_8 3
unsigned char timing; // 时序类型
#define MMC_TIMING_LEGACY 0
#define MMC_TIMING_MMC_HS 1
#define MMC_TIMING_SD_HS 2
#define MMC_TIMING_UHS_SDR12 3
#define MMC_TIMING_UHS_SDR25 4
#define MMC_TIMING_UHS_SDR50 5
#define MMC_TIMING_UHS_SDR104 6
#define MMC_TIMING_UHS_DDR50 7
#define MMC_TIMING_MMC_DDR52 8
#define MMC_TIMING_MMC_HS200 9
#define MMC_TIMING_MMC_HS400 10
unsigned char signal_voltage; // 信号的工作电压
#define MMC_SIGNAL_VOLTAGE_330 0
#define MMC_SIGNAL_VOLTAGE_180 1
#define MMC_SIGNAL_VOLTAGE_120 2
unsigned char drv_type; // 驱动类型
#define MMC_SET_DRIVER_TYPE_B 0
#define MMC_SET_DRIVER_TYPE_A 1
#define MMC_SET_DRIVER_TYPE_C 2
#define MMC_SET_DRIVER_TYPE_D 3
bool enhanced_strobe;
};
mmc请求相关
struct mmc_command
struct mmc_command {
u32 opcode; // 命令的操作码,如MMC_GO_IDLE_STATE、MMC_SEND_OP_COND等等
u32 arg; // 命令的参数
#define MMC_CMD23_ARG_REL_WR (1 << 31)
#define MMC_CMD23_ARG_PACKED ((0 << 31) | (1 << 30))
#define MMC_CMD23_ARG_TAG_REQ (1 << 29)
u32 resp[4];
unsigned int flags;
#define MMC_RSP_PRESENT (1 << 0)
#define MMC_RSP_136 (1 << 1)
#define MMC_RSP_CRC (1 << 2)
#define MMC_RSP_BUSY (1 << 3)
#define MMC_RSP_OPCODE (1 << 4)
#define MMC_CMD_MASK (3 << 5)
#define MMC_CMD_AC (0 << 5)
#define MMC_CMD_ADTC (1 << 5)
#define MMC_CMD_BC (2 << 5)
#define MMC_CMD_BCR (3 << 5)
#define MMC_RSP_SPI_S1 (1 << 7)
#define MMC_RSP_SPI_S2 (1 << 8)
#define MMC_RSP_SPI_B4 (1 << 9)
#define MMC_RSP_SPI_BUSY (1 << 10)
#define MMC_RSP_NONE (0)
#define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
#define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
#define MMC_RSP_R3 (MMC_RSP_PRESENT)
#define MMC_RSP_R4 (MMC_RSP_PRESENT)
#define MMC_RSP_R5 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R1_NO_CRC (MMC_RSP_PRESENT|MMC_RSP_OPCODE)
#define mmc_resp_type(cmd) ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE))
#define MMC_RSP_SPI_R1 (MMC_RSP_SPI_S1)
#define MMC_RSP_SPI_R1B (MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY)
#define MMC_RSP_SPI_R2 (MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)
#define MMC_RSP_SPI_R3 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
#define MMC_RSP_SPI_R4 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
#define MMC_RSP_SPI_R5 (MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)
#define MMC_RSP_SPI_R7 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
#define mmc_spi_resp_type(cmd) ((cmd)->flags &
(MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY|MMC_RSP_SPI_S2|MMC_RSP_SPI_B4))
#define mmc_cmd_type(cmd) ((cmd)->flags & MMC_CMD_MASK)
unsigned int retries; // 失败时的重复尝试次数
int error; // 命令的错误码
unsigned int busy_timeout;
bool sanitize_busy;
// 和该命令关联在一起的数据段
struct mmc_data *data;
// 该命令关联到哪个request
struct mmc_request *mrq;
};
struct mmc_data
mmc core用struct mmc_data来表示一个命令包。
struct mmc_data {
unsigned int timeout_ns; // 超时时间,以ns为单位
unsigned int timeout_clks; // 超时时间,以clock为单位
unsigned int blksz; // 块大小
unsigned int blocks; // 块数量
unsigned int blk_addr; // card地址
int error;
unsigned int flags; // 传输标识
#define MMC_DATA_WRITE BIT(8)
#define MMC_DATA_READ BIT(9)
#define MMC_DATA_QBR BIT(10)
#define MMC_DATA_PRIO BIT(11)
#define MMC_DATA_REL_WR BIT(12)
#define MMC_DATA_DAT_TAG BIT(13)
#define MMC_DATA_FORCED_PRG BIT(14)
unsigned int bytes_xfered;
struct mmc_command *stop; // 结束传输的命令
struct mmc_request *mrq; // 该命令关联到哪个request
unsigned int sg_len; sg数组的size
int sg_count; // 通过sg map出来的实际的entry的个
struct scatterlist *sg; //一个struct scatterlist类型的数组
s32 host_cookie; // host driver的私有数据
};
struct mmc_request
struct mmc_request是mmc core向host controller发起命令请求的处理单位。其包含了要传输的命令和数据。
struct mmc_request {
struct mmc_command *sbc; // 设置块数量的命令,怎么用的后续再补充
struct mmc_command *cmd; // 要传输的命令
struct mmc_data *data; // 要传输的数据
struct mmc_command *stop; // 要传输的stop命令
struct completion completion; // 完成量
struct completion cmd_completion;
// 传输结束后的回调函数
void (*done)(struct mmc_request *);
void (*recovery_notifier)(struct mmc_request *);
struct mmc_host *host; // 所属host
bool cap_cmd_during_tfr;
int tag;
};



