结构体mmc_host定义于/include/linux/mmc/host.c,可以认为是linux为SD卡控制器专门准备的一个类,该类里面的成员是所有SD卡控制器都需要的,是描述主机控制器的共有结构,具体的控制器结构体包含结构体mmc_host,如:
//该结构体有自己编写,根据实际项目来编写自己的host结构体
struct pxamci_host {
struct mmc_host *mmc;
struct mmc_request *mrq;
struct mmc_command *cmd;
struct mmc_data *data;
... ...
};
struct mmc_host {
const struct mmc_host_ops *ops; // SD卡主控制器的操作函数,即该控制器所具备的驱动能力
const struct mmc_bus_ops *bus_ops; // SD总线驱动的操作函数,即SD总线所具备的驱动能力
struct mmc_ios ios; // 配置时钟、总线、电源、片选、时序等
struct mmc_card *card; // 连接到此主控制器的SD卡设备
... ...
};
struct mmc_host_ops {
void (*request)(struct mmc_host *host, struct mmc_request *req); // 核心函数,完成主控制器与SD卡设备之间的数据通信
void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios); // 配置时钟、总线、电源、片选、时序等
int (*get_ro)(struct mmc_host *host); //获取gpio管脚,判断是否是写保护
void (*enable_sdio_irq)(struct mmc_host *host, int enable); //卡插入与拔出中断
};
struct mmc_bus_ops {
void (*remove)(struct mmc_host *); // 拔出SD卡的回调函数
void (*detect)(struct mmc_host *); // 探测SD卡是否还在SD总线上的回调函数
void (*suspend)(struct mmc_host *);
void (*resume)(struct mmc_host *);
};
struct mmc_card {
struct mmc_host *host; /* the host this device belongs to */
struct device dev; /* the device */
unsigned int rca; /* relative card address of device */
unsigned int type; /* card type */
unsigned int state; /* (our) card state */
unsigned int quirks; /* card quirks */
u32 raw_cid[4]; /* raw card CID */
u32 raw_csd[4]; /* raw card CSD */
u32 raw_scr[2]; /* raw card SCR */
struct mmc_cid cid; /* card identification */
struct mmc_csd csd; /* card specific */
struct mmc_ext_csd ext_csd; /* mmc v4 extended card specific */
struct sd_scr scr; /* extra SD information */
struct sd_switch_caps sw_caps; /* switch (CMD6) caps */ unsigned int sdio_funcs; /* number of SDIO functions */
struct sdio_cccr cccr; /* common card info */
struct sdio_cis cis; /* common tuple info */
... ...
};
mmc_card结构体内的数据结构主要存放SD卡的信息,其中RCA, CID, CSD, SCR为SD卡内部的32位寄存器
2.1.2 struct mmc_request
结构体mmc_request定义于/include/linux/mmc/core.h,它主要存放两大数据结构的指针,分别是cmd和data,顾名思意,一个为指令,一个为数据,也就是说,mmc_request结构体存放了进行主控制器与sd卡间通信所需要的指令和数据,struct mmc_request, struct mmc_command *cmd, struct mmc_data *data三者之间的关系如下所示,
struct mmc_request {
struct mmc_command *cmd;
struct mmc_data *data;
struct mmc_command *stop;
void *done_data; /* completion data */
void (*done)(struct mmc_request *);/* completion function */
};
- 物理结构
SD卡有9个pin脚(micro-SD为8个,少一个接地pin脚),如图所示,
SD的数据传输方式有两种,普通SD模式和SPI模式,以SD模式为例,9个pin脚分别是VDD,VSS,CLK,以及我们需要关注的一根指令线CMD,4根数据线DAT0~DAT3。
- 传输模式
首先由主机向SD卡发送命令command,等待SD卡的回复response,如果成功收到回复,则进行数据传输。其中,指令线和数据线上传输的指令和数据都要遵循相应的协议格式。
- 指令格式
一条指令command共48位,其中command index指代这条具体的指令名称,argument为该指令的参数。
一条回复response根据不同的指令有几种不同类型。
struct mmc_command {
u32 opcode; // 对应command index
u32 arg; // 对应argument
u32 resp[4]; // 对应response
unsigned int flags; /* expected response type */
... ...
unsigned int retries; /* max number of retries */
unsigned int error; /* command error */
struct mmc_data *data; /* data segment associated with cmd */
struct mmc_request *mrq; /* associated request */
};
- 数据格式
数据传输按数据线可分为一线传输和四线传输,按数据大小可分为字节传输和块传输(512字节)。
struct mmc_data {
unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */
unsigned int timeout_clks; /* data timeout (in clocks) */
unsigned int blksz; /* data block size */
unsigned int blocks; /* number of blocks */
unsigned int error; /* data error */
unsigned int flags;
#define MMC_DATA_WRITE (1 << 8)
#define MMC_DATA_READ (1 << 9)
#define MMC_DATA_STREAM (1 << 10)
unsigned int bytes_xfered;
struct mmc_command *stop; /* stop command */
struct mmc_request *mrq; /* associated request */
unsigned int sg_len; /* size of scatter list */
struct scatterlist *sg; /* I/O scatter list */
};