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層