[mmc subsystem] mmc core(第三章)——bus模块说明
来源:互联网 发布:从unix到linux 乱码 编辑:程序博客网 时间:2024/05/21 10:23
mmc subsystem系列(持续更新中):
[mmc subsystem] 概念与框架
[mmc subsystem] mmc core(第一章)——概述
[mmc subsystem] mmc core(第二章)——数据结构和宏定义说明
[mmc subsystem] mmc core(第三章)——bus模块说明
[mmc subsystem] mmc core(第四章)——host模块说明
[mmc subsystem] mmc core(第五章)——card相关模块(mmc type card)
[mmc subsystem] mmc core(第六章)——mmc core主模块
建议先参考《[mmc subsystem] 概念与框架》和《[mmc subsystem] mmc core(第一章)——概述》对整体有一个了解。
=========================================================================================================
零、说明
对应代码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_register_driver & mmc_unregister_driver
用于注册和卸载struct mmc_driver *drv到mmc_bus上。mmc_driver就是mmc core抽象出来的card设备driver。
原型:int mmc_register_driver(struct mmc_driver *drv) 原型:void mmc_unregister_driver(struct mmc_driver *drv)
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
- [mmc subsystem] mmc core(第三章)——bus模块说明
- [mmc subsystem] mmc core(第四章)——host模块说明
- [mmc subsystem] mmc core(第六章)——mmc core主模块
- [mmc subsystem] mmc core(第五章)——card相关模块(mmc type card)
- [mmc subsystem] mmc core(第二章)——数据结构和宏定义说明
- [mmc subsystem] mmc core(第一章)——概述
- [mmc subsystem] host(第三章)——sdhci-pltfm说明
- [mmc subsystem] host(第四章)——host实例(sdhci-msm说明)
- [mmc subsystem] host(第二章)——sdhci
- [mmc subsystem] host(第一章)——概述
- 基于QualComm的mmc driver解析(Kernel-3.10)——(1)mmc bus
- [mmc subsystem] 概念与框架
- Linux 2.6 的 MMC Core
- MMC子系统调用过程浅析(Core层)
- 基于S3C2440——SD/MMC
- uboot源码——mmc驱动分析
- 利用mmc_test.c研究mmc模块
- 利用mmc_test.c研究mmc模块
- Theano 中文文档 0.9 - 5.2 Mac OS安装说明
- 有限状态机在C语言编程中的各种应用
- POJ-1680(递归模拟)
- java excel设置row 里面的宽度自适应
- 清除canvas的任何图形
- [mmc subsystem] mmc core(第三章)——bus模块说明
- Theano 中文文档 0.9 - 5.3 Windows安装说明
- python爬虫(一)
- 4.CSS图像绘制之:字渐变按钮
- Windows PE 第十章 加载配置信息
- Theano 中文文档 0.9 - 5.4 CentOS 6安装说明
- iOS实现先无动画pop再push,替换当前控制器
- Android----ContentProvider(内容提供者) ContentResolver(内容访问者)
- libeio的个人理解