關(guān)于linux mmc/sd驅(qū)動(dòng)程序架構(gòu)
今天花了時(shí)間簡(jiǎn)單看了mmc/sd部門內(nèi)容和代碼,我覺得形式上,這個(gè)部分和i2c非常相似系統(tǒng)也是分成core層,host層(對(duì)應(yīng)i2c的adapter),設(shè)備層如果這樣講,那么core層主要功能應(yīng)該是提供host注冊(cè),總線注冊(cè),設(shè)備注冊(cè)的幾個(gè)方法以及所謂sdio總線接口的算法了。host層已經(jīng)是注冊(cè)一個(gè)platform設(shè)備,其中應(yīng)該提供主要sdio接口算法的實(shí)現(xiàn)。設(shè)備層,應(yīng)該是提供幾個(gè)公司1)注冊(cè)塊設(shè)備,映射到/dev下面的設(shè)備節(jié)點(diǎn) 2)應(yīng)該還有設(shè)備其他信息。當(dāng)然,也有很多和i2c不一樣的地方,就是必須支持動(dòng)態(tài)掃描卡設(shè)備的方法,而i2c是靠i2c地址制定的。
有關(guān)MMC/SD/SDIO相關(guān)的知識(shí)這里就不多講了,請(qǐng)參考相關(guān)資料。這里主要涉及Linux下MMC相關(guān)內(nèi)容。
內(nèi)核版本(2.6.36)
首先說一下Linux相關(guān)MMC的代碼分布,主要有兩個(gè)目錄,一個(gè)頭文件目錄和一個(gè)源代碼目錄。
分別位置如下:
include/linux/mmc
drivers/mmc
要閱讀MMC相關(guān)代碼就必須要看這兩個(gè)目錄。在drivers/mmc目錄下分別有三個(gè)子目錄,其將對(duì)應(yīng)接下來要講的MMC的體系結(jié)構(gòu)。這三個(gè)子目錄分別為:
?card
?core
?host
它們的內(nèi)容后面講到體系結(jié)構(gòu)時(shí)自然就明了了。
?現(xiàn)在來說說MMC的體系結(jié)構(gòu),其分為三層
??????? /dev下設(shè)備文件訪問MMC/SD/SDIO
用戶空間???????????? |
---------------------|-----------------------------------------------------
內(nèi)核空間??????????? \ /
???????? MMC Card層(對(duì)應(yīng)具體的設(shè)備驅(qū)動(dòng),如MMC/SD卡塊設(shè)備驅(qū)動(dòng),SDIO UART)
???????????????????? |
??????????????????? \ /
????????? MMC core層(為上次設(shè)備驅(qū)動(dòng)實(shí)現(xiàn)提供操作接口,和下層host注冊(cè)提供機(jī)制)
???????????????????? |
??????????????????? \ /
?????????? Host層(具體MMC/SD/SDIO控制器驅(qū)動(dòng)層。如S3C2440 MMC/SD控制器驅(qū)動(dòng))
???????????????????? |
??????????????????? \ /
-----------------------------------------------------------------------------
??????????????????? 硬件層
對(duì)于我們來說,編寫MMC/SD卡相關(guān)驅(qū)動(dòng)主要涉及的就是Host層,其余層不用考慮。對(duì)于SDIO設(shè)備除了Host層以外,還有可能要編寫MMC Card層的設(shè)備驅(qū)動(dòng)。
編寫Host層驅(qū)動(dòng),主要是填充mmc_host結(jié)構(gòu)體相關(guān)內(nèi)容和實(shí)現(xiàn)mmc_host_ops結(jié)構(gòu)體中的函數(shù)。最后調(diào)用mmc_add_host向MMC core注冊(cè)host驅(qū)動(dòng)??梢詤⒖糞3C24XX的HOST驅(qū)動(dòng)程序(drivers/mmc/host/s3cmci.c,s3cmci.h),上層MMC Core主要調(diào)用mmc_host_ops中的函數(shù)來實(shí)現(xiàn)與硬件交互。如下是mmc_host_ops結(jié)構(gòu)體里面的函數(shù):
? struct mmc_host_ops {
??? /*使能和禁止HOST控制器*/
??? int (*enable)(struct mmc_host *host);
??? int (*disable)(struct mmc_host *host, int lazy);
?? ?
??????? /*這個(gè)是關(guān)鍵的函數(shù),所有對(duì)MMC/SD的操作,包括發(fā)命令和讀數(shù)據(jù),都通過該接口來實(shí)現(xiàn),所以實(shí)現(xiàn)該接口時(shí)要處理是命令還是數(shù)據(jù)操作,另外要考慮是否使用DMA來進(jìn)行數(shù)據(jù)傳輸。*/
??? void??? (*request)(struct mmc_host *host, struct mmc_request *req);
??????? /*用來設(shè)置MMC/SD的時(shí)鐘,電壓等操作*/
??? void??? (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);
??????? /*檢查MMC/SD是否寫保護(hù)了*/
??? 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);
};
接下來說說MMC Core層。
該層主要實(shí)現(xiàn)了幾個(gè)結(jié)構(gòu)體函數(shù)指針,用來構(gòu)建整個(gè)MMC設(shè)備驅(qū)動(dòng)模型。它們是:
struct bus_type mmc_bus_type? /*mmc總線,用來管理sd/mmc卡設(shè)備和驅(qū)動(dòng)*/
struct mmc_bus_ops mmc_ops??? /*MMC卡總線操作函數(shù),主要是在電源管理方面*/
struct mmc_bus_ops mmc_sd_op? /*SD卡總線操作函數(shù),主要是在電源管理方面*/
struct mmc_bus_ops mmc_sdio_ops? /*SDIO總線操作函數(shù),主要是在電源管理方面*/
struct bus_type sdio_bus_type? /*SDIO另外定義了一條總線*/
core.c文件中實(shí)現(xiàn)了幾個(gè)關(guān)鍵的函數(shù),用來提供給上層MMC Card調(diào)用和對(duì)SD/MMC卡的偵測(cè)函數(shù)以及初始化。
供給上層MMC Card調(diào)用主要有:
void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq);
int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries);
mmc card層就是通過這些函數(shù)來操作mmc/sd卡。而這些函數(shù)最終調(diào)用的是mmc_host_ops 結(jié)構(gòu)體中的request函數(shù)來進(jìn)行具體的操作。
對(duì)SD/MMC卡的偵測(cè)函數(shù)以及初始化,主要實(shí)現(xiàn)在
void mmc_rescan(struct work_struct *work);
函數(shù)中。
host層在調(diào)用mmc_add_host時(shí)會(huì)引發(fā)該函數(shù)的調(diào)用,偵測(cè)/初始化順序?yàn)椋?br />
? 先SDIO接口
? /*
???? * First we search for SDIO...
???? */
??? err = mmc_send_io_op_cond(host, 0, &ocr);
??? if (!err) {
??????? if (mmc_attach_sdio(host, ocr)) {
?? ...
在SD:
? /*
???? * ...then normal SD...
???? */
??? err = mmc_send_app_op_cond(host, 0, &ocr);
??? if (!err) {
??????? if (mmc_attach_sd(host, ocr))
最后是MMC:
?/*
???? * ...and finally MMC.
???? */
??? err = mmc_send_op_cond(host, 0, &ocr);
??? if (!err) {
??????? if (mmc_attach_mmc(host, ocr))
其中mmc_attach_xxx函數(shù)就是用來完成偵測(cè)和初始化的,選擇相應(yīng)的總線操作函數(shù),并產(chǎn)生struct mmc_card結(jié)構(gòu)體,并填充其內(nèi)容,最后注冊(cè)一個(gè)mmc_card(代表著一個(gè)設(shè)備),并在注冊(cè)中由mmc_bus_type結(jié)構(gòu)體的match和probe函數(shù)來查找到適合該設(shè)備的驅(qū)動(dòng)(這個(gè)又牽涉到設(shè)備驅(qū)動(dòng)模型,可以查看設(shè)備驅(qū)動(dòng)模型相關(guān)內(nèi)容,了解設(shè)備和驅(qū)動(dòng)匹配的過程),這里將匹配到mmc card層的MMC_Block(MMC塊設(shè)備驅(qū)動(dòng)程序,由 struct mmc_driver代表)。在完成設(shè)備偵測(cè)和初始化以后,以后的操作就是mmc card層中相關(guān)的設(shè)備驅(qū)動(dòng)程序發(fā)出的了。
再說說MMC card層,該層主要實(shí)現(xiàn)具體的設(shè)備驅(qū)動(dòng)程序,如MMC塊設(shè)備驅(qū)動(dòng)程序,通過mmc_register_driver注冊(cè)。如果是SDIO就有可能是其它字符設(shè)備驅(qū)動(dòng)程序了,其通過調(diào)用sdio_register_driver來注冊(cè)設(shè)備驅(qū)動(dòng)。
總體概括來說:
host層提供驅(qū)動(dòng)相關(guān)MMC/SD/SDIO控制器的功能。
Core層提供了具體MMC/SD/SDIO設(shè)備偵測(cè)和初始化功能,以及電源管理方面的內(nèi)容和通用的操作功能。
Card為實(shí)現(xiàn)具體的設(shè)備驅(qū)動(dòng)層。
這樣的分層結(jié)構(gòu)在Linux設(shè)備驅(qū)動(dòng)中非常常見,如I2C,SPI等都提供了這樣的驅(qū)動(dòng)模型。
最后簡(jiǎn)單說說SDIO相關(guān)部分。在core層注冊(cè)了新的sdio_bus_type總線,并且定義了新的sdio_driver來代表sdio設(shè)備驅(qū)動(dòng),并定義了struct sdio_func來代表設(shè)備。所以在SDIO設(shè)備除了struct mmc_card來代表設(shè)備以外,還有struct sdio_func來代表具體功能設(shè)備。所以在mmc_attach_sdio函數(shù)中除了注冊(cè)mmc_card以外,還注冊(cè)了sdio_func。具體代碼如下:
int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
{
?? ....
? /*
???? * First add the card to the driver model...
???? */
??? err = mmc_add_card(host->card);
??? if (err)
??????? goto remove_added;
??? /*
???? * ...then the SDIO functions.
???? */
??? for (i = 0;i < funcs;i++) {
??????? err = sdio_add_func(host->card->sdio_func[i]);
??????? if (err)
??????????? goto remove_added;
??? }
??? ....
}
所以它除了調(diào)用mmc_bus_type結(jié)構(gòu)體的match和probe函數(shù)來查找到適合該設(shè)備的驅(qū)動(dòng)外,也調(diào)用sdio_bus_type結(jié)構(gòu)體的match和probe函數(shù)來查找到適合該設(shè)備的驅(qū)動(dòng)。?
?
評(píng)論
查看更多