Linux MMC子系统分析(一)——模型分析

Linux MMC子系统分析(一)——模型分析

MMC子系统的结构组成

在linux内核中,大多数驱动都会遵循设备总线驱动这个模型即device-bus-driver。mmc子系统也不例外,mmc子系统在内核中主要有三个目录,这三个目录也对应了三条虚拟总线。

Card层

card:card driver位于最上面的一层,负责驱动mmc core层抽象出来的虚拟card设备,并将其对接到内核的其它framework例如块设备,ttyy以及wireless等,从而实现具体的功能。

Core层

core:core层是实现mmc的核心实现,负责抽象host、bus、card等软件实体,并向host层提供统一的API接口,便于编写host controller driver。

Host层

host:host位于底层,主要是基于core提供的API框架编写实际操作硬件控制器的驱动代码,这部分是驱动开发人员需要去完成的。Host控制器驱动是以platform驱动的形式实现的,后续文章将以host/sdhci-s3c.c为例做进一步分析。

card、bus、card driver三者的关系

mmc子系统完全遵照device-bus-driver这个模型来实现的。当一个SD卡或者其他类型的设备接入到控制器时,我们的驱动会进行设备探测添加的流程(具体流程在后续文章中将详细讲述),其最终会触发调用bus中的match、probe等函数。接下来让我们看一下这些函数的具体实现:
mmc_bus_type结构体

static struct bus_type mmc_bus_type = {
        .name           = "mmc",
        .dev_groups     = mmc_dev_groups,
        .match          = mmc_bus_match,
        .uevent         = mmc_bus_uevent,
        .probe          = mmc_bus_probe,
        .remove         = mmc_bus_remove,
        .shutdown       = mmc_bus_shutdown,
        .pm             = &mmc_bus_pm_ops,
};

mmc_bus_match函数中定义了card和card driver中的匹配规则。在设备总线驱动模型中,这个设备和驱动的匹配规则通常是按名字来进行匹配的,如果同名即匹配成功,然后会继续调用probe函数进行后续的工作。但是在mmc子系统中,是一个无条件匹配的bus中的match函数始终返回1。

static int mmc_bus_match(struct device *dev, struct device_driver *drv)
{       
        return 1;
}

说明当一个设备接入控制器后,会无条件的执行probe函数,那么来看一下probe函数中具体做了什么吧。

static int mmc_bus_probe(struct device *dev) 
{       
        struct mmc_driver *drv = to_mmc_driver(dev->driver);
        struct mmc_card *card = mmc_dev_to_card(dev);
        
        return drv->probe(card);
}

从代码中可以看见,这里最后是调用了driver中的probe函数,mmc_driver结构体的具体实现在card/block.c中。看一下mmc_driver结构体中具体实现了哪些功能。

static struct mmc_driver mmc_driver = {           
        .drv            = {                       
                .name   = "mmcblk",               
                .pm     = &mmc_blk_pm_ops,        
        },                                        
        .probe          = mmc_blk_probe,          
        .remove         = mmc_blk_remove,         
        .shutdown       = mmc_blk_shutdown,       
};                                                

这里的probe函数对应bus->probe函数中最终调用的那个函数,该函数最终将设备的具体功能,会将SD卡实现为一个块设备。关于快设备的添加,不做相关介绍。

总结

本文介绍了mmc子系统的最基本模型,以及card、bus、card driver三者之间的如何关联在一起。后续文章将分别介绍host驱动的实现、mmc子系统中card的检测方式、card的添加流程等内容。

你可能感兴趣的:(linux驱动学习,linux,驱动程序,嵌入式)