Linux 的 MMC驱动主要管理MMC卡/SD卡,从上到下分为了MMC设备层,MMC Core层,MMC Host层,Host层负责底层硬件:
如下:
/dev下设备文件访问MMC/SD/SDIO
用户空间 |
---------------------|-----------------------------------------------------
内核空间 \ /
MMC Card层(对应具体的设备驱动,如MMC/SD卡块设备驱动,SDIO UART)
|
\ /
MMC core层(为上次设备驱动实现提供操作接口,和下层host注册提供机制)
|
\ /
Host层(具体MMC/SD/SDIO控制器驱动层。如S3C2440 MMC/SD控制器驱动)
|
\ /
-----------------------------------------------------------------------------
硬件层
这节主要介绍MMC Host层,以S3C2440驱动为例,文件/drivers/mmc/host/s3cmci.c 文件实现的接口。
MMC Core与Host层的沟通桥梁为:
struct mmc_host {
structdevice *parent;
structdevice class_dev;
int index;
const struct mmc_host_ops *ops; //Host层需要实现的接口
unsignedint f_min;
unsignedint f_max;
u32 ocr_avail;
unsignedlong caps; /* Host capabilities */
/*host specific block data */
unsignedint max_seg_size; /* see blk_queue_max_segment_size */
unsignedshort max_hw_segs; /* see blk_queue_max_hw_segments */
unsignedshort max_phys_segs; /* see blk_queue_max_phys_segments */
unsignedshort unused;
unsignedint max_req_size; /* maximum number of bytes in one req*/
unsignedint max_blk_size; /* maximum size of one mmc block */
unsignedint max_blk_count; /* maximum number of blocks in one req */
/*private data */
spinlock_t lock; /* lock for claim and bus ops */
structmmc_ios ios; /* current io bus settings */
u32 ocr; /* the current OCR setting */
/*group bitfields together to minimize padding */
unsignedint use_spi_crc:1;
unsignedint claimed:1; /* host exclusively claimed */
unsignedint bus_dead:1; /* bus has been released */
structmmc_card *card; /* device attached to this host*/
wait_queue_head_t wq;
structdelayed_work detect;
conststruct mmc_bus_ops *bus_ops; /* currentbus driver */
unsignedint bus_refs; /* reference counter */
unsignedint sdio_irqs;
structtask_struct *sdio_irq_thread;
atomic_t sdio_irq_thread_abort;
structdentry *debugfs_root;
unsignedlong private[0]____cacheline_aligned;
};
struct mmc_host_ops {
/*使能和禁止HOST控制器*/
int (*enable)(struct mmc_host *host);
int (*disable)(struct mmc_host *host, int lazy);
/*这个是关键的函数,所有对MMC/SD的操作,包括发命令和读数据,都通过该接口来实现,所以实现该接口时要处理是命令还是数据操作,另外要考虑是否使用DMA来进行数据传输。/用于命令和数据的发送接收 */
void (*request)(struct mmc_host *host, struct mmc_request *req);
/*用来设置MMC/SD的时钟,电压等操作IO,初始化的操作*/
void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);
/*检查MMC/SD是否写保护了 */
int (*get_ro)(struct mmc_host *host);
/*检查mmc/sd的插入和拔出 */
int (*get_cd)(struct mmc_host *host);
void (*enable_sdio_irq)(struct mmc_host *host, int enable);
/* optional callback for HC quirks */
void (*init_card)(struct mmc_host *host, struct mmc_card *card);
};
那么在s3cmci.c文件中 根据以上接口分别进行了实现,以上的mm_host通过Core层的mmc_add_host函数添加下面一节介绍Core层