零、说明

对应代码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.type = type; // 设置device type spin_lock_init(&card->bkops_info.bkops_stats.lock); // 初始化spin_lock
spin_lock_init(&card->wr_pack_stats.lock); // 初始化spin_lock return card;
}

4、mmc_add_card实现

用于注册struct mmc_card到mmc_bus上。

/*
* Register a new MMC card with the driver model.
*/
int mmc_add_card(struct mmc_card *card)
{
int ret; /* 以下用于打印card的注册信息 */
const char *type;
const char *uhs_bus_speed_mode = "";
// 设置速度模式的字符串,为了后面打印出card信息
//...... if (mmc_host_is_spi(card->host)) {
pr_info("%s: new %s%s%s card on SPI\n",
mmc_hostname(card->host),
mmc_card_highspeed(card) ? "high speed " : "",
mmc_card_ddr_mode(card) ? "DDR " : "",
type);
} else {
pr_info("%s: new %s%s%s%s%s%s card at address %04x\n",
mmc_hostname(card->host),
mmc_card_uhs(card) ? "ultra high speed " :
(mmc_card_highspeed(card) ? "high speed " : ""),
(mmc_card_hs400(card) ? "HS400 " : ""),
(mmc_card_hs200(card) ? "HS200 " : ""),
mmc_card_ddr_mode(card) ? "DDR " : "",
uhs_bus_speed_mode, type, card->rca);
}
// 在这里会打印出card信息的字符串
// eg:mmc0: new HS200 MMC card at address 0001 /* 设置card的debug节点 */
#ifdef CONFIG_DEBUG_FS
mmc_add_card_debugfs(card);
// 创建card对应的debug节点,对应路径例如:/sys/kernel/debug/mmc0/mmc0:0001
#endif
mmc_init_context_info(card->host); // 初始化同步的文本信息 /* 以下使能card device的pm runtime的功能 */
ret = pm_runtime_set_active(&card->dev);
if (ret)
pr_err("%s: %s: failed setting runtime active: ret: %d\n",
mmc_hostname(card->host), __func__, ret);
else if (!mmc_card_sdio(card) && mmc_use_core_runtime_pm(card->host))
pm_runtime_enable(&card->dev); /* 添加到设备驱动模型中 */
ret = device_add(&card->dev);
// 会创建/sys/bus/mmc/devices/mmc0:0001节点和/sys/class/mmc_host/mmc0/mmc0:0001节点 /* 使能异步device suspend,初始化runtime_pm_timeout属性 */
device_enable_async_suspend(&card->dev);
if (mmc_use_core_runtime_pm(card->host) && !mmc_card_sdio(card)) {
card->rpm_attrib.show = show_rpm_delay;
card->rpm_attrib.store = store_rpm_delay;
sysfs_attr_init(&card->rpm_attrib.attr);
card->rpm_attrib.attr.name = "runtime_pm_timeout";
card->rpm_attrib.attr.mode = S_IRUGO | S_IWUSR; ret = device_create_file(&card->dev, &card->rpm_attrib);
if (ret)
pr_err("%s: %s: creating runtime pm sysfs entry: failed: %d\n",
mmc_hostname(card->host), __func__, ret);
/* Default timeout is 10 seconds */
card->idle_timeout = RUNTIME_SUSPEND_DELAY_MS;
} /* 设置mmc card的state标识 */
mmc_card_set_present(card);
// 设置card的MMC_STATE_PRESENT状态
// #define MMC_STATE_PRESENT (1<<0) /* present in sysfs */
// 表示card已经合入到sysfs中了 return 0;
}

相关节点:

/sys/bus/mmc/devices/mmc0:0001

/sys/class/mmc_host/mmc0/mmc0:0001

/sys/kernel/debug/mmc0/mmc0:0001

3. [mmc subsystem] mmc core(第三章)——bus模块说明的更多相关文章

  1. 9. [mmc subsystem] host(第三章)——sdhci-pltfm说明

    一.sdhci-pltfm说明 sdhci-pltfm并不是实际某个host的driver. sdhci-pltfm是指在sdhci core的基础上,提供了统一对sdhci_host的必要属性进行解 ...

  2. [HeadFrist-HTMLCSS学习笔记]第三章构建模块:Web页面建设

    [HeadFrist-HTMLCSS学习笔记]第三章构建模块:Web页面建设 敲黑板!! <q>元素添加短引用,<blockquote>添加长引用 在段落里添加引用就使用< ...

  3. 5. [mmc subsystem] mmc core(第五章)——card相关模块(mmc type card)

    零.说明(重要,需要先搞清楚概念有助于后面的理解) 1.mmc core card相关模块为对应card实现相应的操作,包括初始化操作.以及对应的总线操作集合.负责和对应card协议层相关的东西. 这 ...

  4. 6. [mmc subsystem] mmc core(第六章)——mmc core主模块

    一.说明 1.mmc core概述 mmc core主模块是mmc core的实现核心.也是本章的重点内容. 对应代码位置drivers/mmc/core/core.c. 其主要负责如下功能: mmc ...

  5. 10. [mmc subsystem] host(第四章)——host实例(sdhci-msm说明)

    一.说明 sdhci-msm是指高通的mmc host,其使用了标准SDHC标准.故可以使用前面说的<host(第二章)--sdhci>和<host(第三章)--sdhci-pltf ...

  6. 4. [mmc subsystem] mmc core(第四章)——host模块说明

    零.说明 对应代码drivers/mmc/core/host.c,drivers/mmc/core/host.h. 为底层host controller driver实现mmc host的申请以及注册 ...

  7. 2. [mmc subsystem] mmc core数据结构和宏定义说明

    一.host相关 1.struct mmc_host struct mmc_host是mmc core由host controller抽象出来的结构体,用于代表一个mmc host控制器. 数据结构如 ...

  8. 第三章:模块加载系统(requirejs)

    任何一门语言在大规模应用阶段,必然要经历拆分模块的过程.便于维护与团队协作,与java走的最近的dojo率先引入加载器,早期的加载器都是同步的,使用document.write与同步Ajax请求实现. ...

  9. 第三章 Models模块属性详解

    摘自:http://www.cnblogs.com/xdotnet/archive/2012/03/07/aspnet_mvc40_validate.html 了解了这些就可以对MVC进一步认识,相信 ...

随机推荐

  1. 为什么我离开Mac for Windows:苹果已经放弃了[译]

    为什么我离开Mac for Windows:苹果已经放弃了[译] 如果你问任何知道我的人,我可能是他们知道的最大的苹果粉丝.要求提供什么电脑可以获得的建议,我几乎肯定会告诉你MacBook Pro,还 ...

  2. 2017年BackBox5和Ubuntu16.04.1国内更新源

    BackBox是基于Ubuntu的Linux发行版,因此,我们可以使用Ubuntu的更新源作为BackBox的更新源. 1.查看系统版本信息: 输入: uname -a 显示计算机及操作系统的有关信息 ...

  3. python3的文件读取问题

    今天在调python程序时,遇到了一个报错:illegal multibyte sequence. 后来在网上查资料,是文件读取的编码问题. py3读取文件的时候是可以指定编码的:open('file ...

  4. c#Socket客户端和服务端的信息发送

    这是我制作的界面信息,c# Socket通信的简单使用,刚开始学习,不对的地方请大家指教,目前是可以运行的,之后自己在慢慢添加新的东西.同时了解Tcp协议的三次握手.希望对跟我一样的初学者有所帮助. ...

  5. React-router v4教程

    在这个教程里,我们会从一个例子React应用开始学习react-router-dom.其中你会学习如何使用Link.NavLink等来实现跳转,Switch和exact实现排他路由和浏览器路径历史. ...

  6. Spring IOC知识点一网打尽!

    前言 只有光头才能变强 回顾前面: 给女朋友讲解什么是代理模式 包装模式就是这么简单啦 单例模式你会几种写法? 工厂模式理解了没有? 在刷Spring书籍的时候花了点时间去学习了单例模式和工厂模式,总 ...

  7. 如何在markdown中打出上标、下标和一些特殊符号

    转自:https://www.jianshu.com/p/80ac23666a98 如何在markdown中打出上标.下标和一些特殊符号 这是朕的江山 关注 2016.08.16 17:07* 字数 ...

  8. get.go

    //获取空间文件 ))     resp, err := http.DefaultClient.Do(req)     if err != nil {         return nil, err ...

  9. selenium+python+eclipse 实现 “问卷星”网站,登录与检查登录示例!

    1.使用selenium+python+eclipse实现的登录"问卷星",问卷星访问地址:https://www.sojump.com/ 2.实现步骤:1)进入链接---首页-- ...

  10. ALS交替最小二乘法总结

    摘要: 1.算法概述 2.算法推导 3.算法特性及优缺点 4.注意事项 5.实现和具体例子 6.适用场合 内容: 1.算法概述 ALS是alternating least squares的缩写 , 意 ...