零、说明
对应代码drivers/mmc/core/bus.c。
抽象出虚拟mmc bus,实现mmc bus的操作。
一、API总览
1、mmc bus相关
- mmc_register_bus & mmc_unregister_bus
用于注册和卸载mmc bus(虚拟mmc总线)到设备驱动模型中。
原型:int mmc_register_bus(void)
原型:void mmc_unregister_bus(void)
2、mmc driver相关
- mmc_alloc_card & mmc_release_card
3、mmc card相关
- mmc_alloc_card & mmc_release_card
用于分配或者释放一个struct mmc_card结构体,创建其于mmc host以及mmc bus之间的关联。
原型:struct mmc_card *mmc_alloc_card(struct mmc_host *host, struct device_type *type)
参数说明:host——》要分配的card所属的mmc_host,type——》对应的device type。
原型:static void mmc_release_card(struct device *dev)
- mmc_add_card & mmc_remove_card
用于注册或者卸载struct mmc_card到mmc_bus上。
原型:int mmc_add_card(struct mmc_card *card)
原型:void mmc_remove_card(struct mmc_card *card)
二、数据结构
1、mmc_bus_type
mmc_bus_type代表了mmc虚拟总线。其内容如下:
static struct bus_type mmc_bus_type = {
.name = "mmc", // 相应会在/sys/bus下生成mmc目录
.dev_attrs = mmc_dev_attrs, // bus下的device下继承的属性,可以看到/sys/bus/mmc/devices/mmc0:0001/type属性就是这里来的
.match = mmc_bus_match, // 用于mmc bus上device和driver的匹配
.uevent = mmc_bus_uevent,
.probe = mmc_bus_probe, // 当match成功的时候,执行的probe操作
.remove = mmc_bus_remove,
.shutdown = mmc_bus_shutdown,
.pm = &mmc_bus_pm_ops, // 挂在mmc bus上的device的电源管理操作集合
};
/***************************match方法***************************/
static int mmc_bus_match(struct device *dev, struct device_driver *drv)
{
return 1; // 无条件返回1,说明挂载mmc bus上的device(mmc_card)和driver(mmc_driver)是无条件匹配的。
}
/****************************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); // 直接调用mmc_driver中的probe操作,对于block.c来说就是mmc_blk_probe
}
补充说明,通过上述mmc_bus的match方法实现,我们可以知道挂载mmc bus上的mmc_card和mmc_driver是无条件匹配的。
三、接口代码说明
1、mmc_register_bus实现
用于注册mmc bus(虚拟mmc总线)到设备驱动模型中。
int mmc_register_bus(void)
{
return bus_register(&mmc_bus_type); // 以mmc_bus_type为bus_type注册一条虚拟bus,关于mmc_bus_type上面已经说明过了
}
后续我们将mmc_bus_type的这条bus称之为mmc_bus。
相关节点:/sys/bus/mmc。
2、mmc_register_driver实现
用于注册struct mmc_driver *drv到mmc_bus上。mmc_driver就是mmc core抽象出来的card设备driver。
int mmc_register_driver(struct mmc_driver *drv)
{
drv->drv.bus = &mmc_bus_type; // 通过设置mmc_driver——》device_driver——》bus_type来设置mmc_driver所属bus为mmc_bus
return driver_register(&drv->drv); // 这样就将mmc_driver挂在了mmc_bus上了。
}
相关节点:/sys/bus/mmc/drivers.
3、mmc_alloc_card实现
用于分配一个struct mmc_card结构体,创建其于mmc host以及mmc bus之间的关联。
struct mmc_card *mmc_alloc_card(struct mmc_host *host, struct device_type *type)
{
struct mmc_card *card;
card = kzalloc(sizeof(struct mmc_card), GFP_KERNEL); // 分配一个mmc_card
if (!card)
return ERR_PTR(-ENOMEM);
card->host = host; // 关联mmc_card与mmc_host
device_initialize(&card->dev);
card->dev.parent = mmc_classdev(host);
// 设置card的device的parent device为mmc_host的classdev,
// 注册到设备驱动模型中之后,会在/sys/class/mmc_host/mmc0目录下生成相应card的节点,如mmc0:0001
card->dev.bus = &mmc_bus_type;
// 设置card的bus为mmc_bus_type,这样,mmc_card注册到设备驱动模型中之后就会挂在mmc_bus下。
// 会在/sys/bus/mmc/devices/目录下生成相应card的节点,如mmc0:0001
card->dev.release = mmc_release_card;
card->dev