您的位置 首页 IC

关于linux mmc/sd驱动程序架构,你了解多少?

关于linux mmc/sd驱动程序架构,你了解多少?-host层已经是注册一个platform设备,其中应该提供主要sdio接口算法的实现。设备层,应该是提供几个公司1)注册块设备,映射到/dev下面的设备节点 2)应该还有设备其他信息。当然,也有很多和i2c不一样的地方,就是必须支持动态扫描卡设备的方法,而i2c是靠i2c地址制定的。

关于linux mmc/sd驱动程序架构

今日花了时刻简略看了mmc/sd部分内容和代码,我觉得形式上,这个部分和i2c十分类似体系也是分红core层,host层(对应i2c的adapter),设备层假如这样讲,那么core层首要功用应该是供应host注册,总线注册,设备注册的几个办法以及所谓sdio总线接口的算法了。host层已经是注册一个platform设备,其间应该供应首要sdio接口算法的完结。设备层,应该是供应几个公司1)注册块设备,映射到/dev下面的设备节点 2)应该还有设备其他信息。当然,也有许多和i2c不一样的当地,便是有必要支撑动态扫描卡设备的办法,而i2c是靠i2c地址拟定的。

有关MMC/SD/SDIO相关的常识这儿就不多讲了,请参阅相关材料。这儿首要触及Linux下MMC相关内容。
内核版别(2.6.36)
首先说一下Linux相关MMC的代码散布,首要有两个目录,一个头文件目录和一个源代码目录。
别离方位如下:
include/linux/mmc
drivers/mmc
要阅览MMC相关代码就有必要要看这两个目录。在drivers/mmc目录下别离有三个子目录,其将对应接下来要讲的MMC的体系结构。这三个子目录别离为:
 card
 core
 host
它们的内容后边讲到体系结构时天然就明了了。
 现在来说说MMC的体系结构,其分为三层
        /dev下设备文件拜访MMC/SD/SDIO
用户空间             |
———————|—————————————————–
内核空间            \ /
         MMC Card层(对应详细的设备驱动,如MMC/SD卡块设备驱动,SDIO UART)
                     |
                    \ /
          MMC core层(为前次设备驱动完结供应操作接口,和基层host注册供应机制)
                     |
                    \ /
           Host层(详细MMC/SD/SDIO控制器驱动层。如S3C2440 MMC/SD控制器驱动)
                     |
                    \ /
—————————————————————————–
                    硬件层
关于咱们来说,编写MMC/SD卡相关驱动首要触及的便是Host层,其他层不必考虑。关于SDIO设备除了Host层以外,还有可能要编写MMC Card层的设备驱动。
编写Host层驱动,首要是填充mmc_host结构体相关内容和完结mmc_host_ops结构体中的函数。终究调用mmc_add_host向MMC core注册host驱动。能够参阅S3C24XX的HOST驱动程序(drivers/mmc/host/s3cmci.c,s3cmci.h),上层MMC Core首要调用mmc_host_ops中的函数来完结与硬件交互。如下是mmc_host_ops结构体里边的函数:
  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的时钟,电压等操作*/
    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);
};

接下来说说MMC Core层。
该层首要完结了几个结构体函数指针,用来构建整个MMC设备驱动模型。它们是:
struct bus_type mmc_bus_type  /*mmc总线,用来办理sd/mmc卡设备和驱动*/
struct mmc_bus_ops mmc_ops    /*MMC卡总线操作函数,首要是在电源办理方面*/
struct mmc_bus_ops mmc_sd_op  /*SD卡总线操作函数,首要是在电源办理方面*/
struct mmc_bus_ops mmc_sdio_ops  /*SDIO总线操作函数,首要是在电源办理方面*/
struct bus_type sdio_bus_type  /*SDIO别的界说了一条总线*/
core.c文件中完结了几个要害的函数,用来供应给上层MMC Card调用和对SD/MMC卡的侦测函数以及初始化。
供应上层MMC Card调用首要有:
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层便是经过这些函数来操作mmc/sd卡。而这些函数终究调用的是mmc_host_ops 结构体中的request函数来进行详细的操作。
对SD/MMC卡的侦测函数以及初始化,首要完结在
void mmc_rescan(struct work_struct *work);
函数中。
host层在调用mmc_add_host时会引发该函数的调用,侦测/初始化次序为:
  先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函数便是用来完结侦测和初始化的,挑选相应的总线操作函数,并发生struct mmc_card结构体,并填充其内容,终究注册一个mmc_card(代表着一个设备),并在注册中由mmc_bus_type结构体的match和probe函数来查找到适合该设备的驱动(这个又牵涉到设备驱动模型,能够检查设备驱动模型相关内容,了解设备和驱动匹配的进程),这儿将匹配到mmc card层的MMC_Block(MMC块设备驱动程序,由 struct mmc_driver代表)。在完结设备侦测和初始化今后,今后的操作便是mmc card层中相关的设备驱动程序宣布的了。

再说说MMC card层,该层首要完结详细的设备驱动程序,如MMC块设备驱动程序,经过mmc_register_driver注册。假如是SDIO就有可能是其它字符设备驱动程序了,其经过调用sdio_register_driver来注册设备驱动。
整体归纳来说:
host层供应驱动相关MMC/SD/SDIO控制器的功用。
Core层供应了详细MMC/SD/SDIO设备侦测和初始化功用,以及电源办理方面的内容和通用的操作功用。
Card为完结详细的设备驱动层。
这样的分层结构在Linux设备驱动中十分常见,如I2C,SPI等都供应了这样的驱动模型。

终究简略说说SDIO相关部分。在core层注册了新的sdio_bus_type总线,而且界说了新的sdio_driver来代表sdio设备驱动,并界说了struct sdio_func来代表设备。所以在SDIO设备除了struct mmc_card来代表设备以外,还有struct sdio_func来代表详细功用设备。所以在mmc_attach_sdio函数中除了注册mmc_card以外,还注册了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;
    }
    ….
}
所以它除了调用mmc_bus_type结构体的match和probe函数来查找到适合该设备的驱动外,也调用sdio_bus_type结构体的match和probe函数来查找到适合该设备的驱动。 

 

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/bandaoti/90249.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部