Linux mmc驱动框架
概述
数据结构
描述
struct mmc_host
用来表示一个mmc host控制器
struct mmc_card
用来表示一个mmc设备(卡)
struct mmc_ios
IO总线相关设置
struct mmc_driver
用来表示 mmc 卡驱动
struct mmc_bus_ops
总线操作函数集, 有mmc、sd、sdio三种
struct mmc_host_ops
Host控制器操作函数集,用来描述卡控制器操作接口函数功能,用于从主机控制器层向 core 层注册操作函数,从而将core 层与具体的主机控制器隔离
struct mmc_command
表示一个mmc命令
struct mmc_data
表示一个mmc数据
struct mmc_request
表示一个mmc请求
struct sdio_func
一张sdio卡可以支持很多Functions,一个Function对应软件上的struct sdio_func结构体,最后反应到驱动模型上就是一个device
mmc_host
struct mmc_host {
int index;
const struct mmc_host_ops *ops; /* host控制器操作函数集*/
u32 ocr_avail;
u32 ocr_avail_sdio; /* SDIO-specific OCR */
u32 ocr_avail_sd; /* SD-specific OCR */
u32 ocr_avail_mmc; /* MMC-specific OCR */
u32 caps; /* Host能力标志位 */
u32 caps2; /* Host能力标志位2,32位不够再补一个32位 */
struct mmc_ios ios; /* current io bus settings */
int rescan_disable; /* disable card detection */
int rescan_entered; /* used with nonremovable devices */
struct mmc_card *card; /* 用来表示一个挂在当前host上的mmc设备(卡) */
struct delayed_work detect; /* 卡检测函数 */
int detect_change; /* 卡检测标志 */
struct mmc_slot slot;
const struct mmc_bus_ops *bus_ops; /* 当前总线操作函数集,mmc/sd/sdio */
struct mmc_supply supply;
unsigned int slotno; /* used for sdio acpi binding */
int dsr_req; /* DSR value is valid */
u32 dsr; /* optional driver stage (DSR) value */
unsigned long private[0] ____cacheline_aligned;
}
mmc_card
struct mmc_card {
struct mmc_host *host; /* 设备(卡)对应的host数据结构 */
struct device dev; /* the device */
u32 ocr; /* 当前 OCR 设定*/
unsigned int rca; /* relative card address of device */
unsigned int type; /* Card类型: MMC、SD、SDIO、COMBO */
unsigned int state; /* 当前卡的状态 */
unsigned int quirks; /* card quirks */
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_ssr ssr; /* yet more 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 */
struct sdio_func *sdio_func[7]; /* SDIO functions (devices) */
unsigned int sd_bus_speed; /* Bus Speed Mode set for the card */
unsigned int mmc_avail_type; /* supported device type by both host and card */
unsigned int drive_strength; /* for UHS-I, HS200 or HS400 */
};
mmc_ios
struct mmc_ios {
unsigned int clock; /* 时钟频率 */
unsigned short vdd;
unsigned char bus_mode; /* 命令输出模式: 开漏模式、上拉模式 */
unsigned char chip_select; /* SPI片选 */
unsigned char power_mode; /* 电源供应模式:UNDEFINED、OFF、UP、ON */
unsigned char bus_width; /* 数据总线宽度:1、4、8 */
unsigned char timing; /* timing specification used */
unsigned char signal_voltage; /* 信号电压值(1.8V or 3.3V) */
unsigned char drv_type; /* 驱动了恶性type (A, B, C, D) */
bool enhanced_strobe; /* hs400es selection */
}
mmc_dirver
struct mmc_driver {
struct device_driver drv;
int (*probe)(struct mmc_card *card);
void (*remove)(struct mmc_card *card);
void (*shutdown)(struct mmc_card *card);
};
mmc_bus_ops
struct mmc_bus_ops {
void (*remove)(struct mmc_host *);
void (*detect)(struct mmc_host *);
int (*pre_suspend)(struct mmc_host *);
int (*suspend)(struct mmc_host *);
int (*resume)(struct mmc_host *);
int (*runtime_suspend)(struct mmc_host *);
int (*runtime_resume)(struct mmc_host *);
int (*power_save)(struct mmc_host *);
int (*power_restore)(struct mmc_host *);
int (*alive)(struct mmc_host *);
int (*shutdown)(struct mmc_host *);
int (*reset)(struct mmc_host *);
};
mmc_host_ops
struct mmc_host_ops {
void (*post_req)(struct mmc_host *, struct mmc_request *, int err);
void (*pre_req)(struct mmc_host *, struct mmc_request *, bool is_first_req);
void (*request)(struct mmc_host *host, struct mmc_request *req);
void (*set_ios)(struct mmc_host *, struct mmc_ios *);
int (*get_ro)(struct mmc_host *);
int (*get_cd)(struct mmc_host *);
void (*enable_sdio_irq)(struct mmc_host *, int enable);
void (*init_card)(struct mmc_host *, struct mmc_card *card);
int (*start_signal_voltage_switch)(struct mmc_host *, struct mmc_ios *);
int (*card_busy)(struct mmc_host *);
int (*execute_tuning)(struct mmc_host *, u32 opcode);
int (*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios);
void (*hs400_enhanced_strobe)(struct mmc_host *, struct mmc_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 *);
void (*card_event)(struct mmc_host *);
int (*multi_io_quirk)(struct mmc_card *, unsigned int direction, int blk_size);
};
mmc_command
struct mmc_command {
u32 opcode; /* command的操作码 */
u32 arg; /* command携带的参数 */
u32 resp[4]; /* command发出后,如果需要应答,结果保存在resp数组中,最多可以保存128bits的应答 */
unsigned int flags; /* 期望的应答类型 */
unsigned int retries; /* 最大重发的次数 */
int error; /* 如果最终还是出错,通过该字段返回错误的原因 */
unsigned int busy_timeout; /* busy detect timeout in ms */
bool sanitize_busy; /* Set this flag only for blocking sanitize request */
struct mmc_data *data; /* data segment associated with cmd */
struct mmc_request *mrq; /* associated request */
}
mmc_data
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 blk_addr; /* block address */
int error; /* 如果数据出错,错误值保存在该字段 */
unsigned int flags; /* 指明数据传输的方向,可采用下面的宏定义 */
#define MMC_DATA_WRITE BIT(8)
#define MMC_DATA_READ BIT(9)
/* Extra flags used by CQE */
#define MMC_DATA_QBR BIT(10) /* CQE queue barrier*/
#define MMC_DATA_PRIO BIT(11) /* CQE high priority */
#define MMC_DATA_REL_WR BIT(12) /* Reliable write */
#define MMC_DATA_DAT_TAG BIT(13) /* Tag request */
#define MMC_DATA_FORCED_PRG BIT(14) /* Forced programming */
unsigned int bytes_xfered;
struct mmc_command *stop; /* stop command */
struct mmc_request *mrq; /* associated request */
unsigned int sg_len; /* sg数组的长度 */
int sg_count; /* sg数组的个数 */
struct scatterlist *sg; /* 保存需要传输的数据数组 */
s32 host_cookie; /* host private data */
}
mmc_request
struct mmc_request {
struct mmc_command *cmd; /* start command,必须设置 */
struct mmc_data *data; /* 传输的数据,非必须 */
struct mmc_command *stop;
void *done_data; /* completion data */
void (*done)(struct mmc_request *); /* 传输完成时的回调函数,用于通知传输请求的发起者 */
};
sdio_func
struct sdio_func {
struct mmc_card *card; /* the card this device belongs to */
struct device dev; /* the device */
sdio_irq_handler_t *irq_handler; /* IRQ callback */
unsigned int num; /* function number */
unsigned char class; /* standard interface class */
unsigned short vendor; /* vendor id */
unsigned short device; /* device id */
unsigned max_blksize; /* maximum block size */
unsigned cur_blksize; /* current block size */
unsigned enable_timeout; /* max enable timeout in msec */
unsigned int state; /* function state */
#define SDIO_STATE_PRESENT (1<<0) /* present in sysfs */
u8 *tmpbuf; /* DMA:able scratch buffer */
unsigned num_info; /* number of info strings */
const char **info; /* info strings */
struct sdio_func_tuple *tuples;
}
孟德尔爱豌豆
发布了9 篇原创文章 · 获赞 0 · 访问量 369
私信
关注