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

本文详细介绍了mmc subsystem中的mmc core如何处理mmc type card的相关操作,包括mmc type card的初始化、协议操作、数据结构以及关键接口的实现。通过mmc_attach_mmc函数将card与host绑定,mmc_init_card进行实质性初始化,并通过mmc_ops接口执行CMD0至CMD13等指令进行mmc card的状态转换。内容涵盖mmc协议、mmc_bus的概念以及mmc_core的核心功能。
摘要由CSDN通过智能技术生成

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(第一章)——概述》对整体有一个了解。

=========================================================================================================

零、说明(重要,需要先搞清楚概念有助于后面的理解)

1、mmc core——card相关模块为对应card实现相应的操作,包括初始化操作、以及对应的总线操作集合。负责和对应card协议层相关的东西。
主要包括三种类型的card,分别是mmc type card、sd type card和sdio type card。
这里先学习mmc type card。后续再学习sd type card。
对应代码:
drivers/mmc/core/mmc.c(提供接口),
drivers/mmc/core/mmc-ops.c(提供和mmc type card协议相关的操作),
drivers/mmc/core/mmc-ops.h

2、另外,这里继续强调一下mmc的概念
mmc core是指mmc subsystem的核心实现,这里的mmc是表示mmc总线、接口、设备相关的一种统称,可以理解为一种软件架构。
而mmc type card则是指mmc卡或者emmc。
总之,这里的mmc是两种概念概念,需要自己先消化一下。

3、mmc总线和mmc_bus
在本文里面这两个是不同的概念。
mmc_bus是指mmc core抽象出来的虚拟总线,和mmc设备对应的硬件总线无关,是一种软件概念。
而本文的mmc总线是一种物理概念,是实际的总线,是和host controller直接相关联的。

一、API总览

1、mmc type card匹配相关

  • mmc_attach_mmc
    提供给mmc core主模块使用,用于绑定card到host bus上(也就是card和host的绑定)。
    通过mmc_host获取mmc type card信息,初始化mmc_card,并进行部分驱动,最后将其注册到mmc_bus上。
    原型:int mmc_attach_mmc(struct mmc_host *host)

2、mmc type card协议相关操作

mmc_ops提供了部分和mmc type card协议相关操作,这些操作会在mmc.c中mmc的初始化过程中被使用到。
建议先简单了解一下mmc协议的内容。后续会进行总结。

  • mmc_go_idle
    发送CMD0指令,GO_IDLE_STATE
    使mmc card进入idle state。
    虽然进入到了Idle State,但是上电复位过程并不一定完成了,这主要靠读取OCR的busy位来判断,而流程归结为下一步。

  • mmc_send_op_cond
    发送CMD1指令,SEND_OP_COND
    这里会设置card的工作电压寄存器OCR,并且通过busy位(bit31)来判断card的上电复位过程是否完成,如果没有完成的话需要重复发送。
    完成之后,mmc card进入ready state。

  • mmc_all_send_cid
    这里会发送CMD2指令,ALL_SEND_CID
    广播指令,使card回复对应的CID寄存器的值。在这里就相应获得了CID寄存器的值了,存储在cid中。
    完成之后,MMC card会进入Identification State。

  • mmc_set_relative_addr
    发送CMD3指令,SET_RELATIVE_ADDR
    设置该mmc card的关联地址为card->rca,也就是0x0001
    完成之后,该MMC card进入standby模式。

  • mmc_send_csd
    发送CMD9指令,MMC_SEND_CSD
    要求mmc card发送csd寄存器,存储到card->raw_csd中,也就是原始的csd寄存器的值。
    此时mmc card还是处于standby state

  • mmc_select_card & mmc_deselect_cards
    发送CMD7指令,SELECT/DESELECT CARD
    选择或者断开指定的card
    这时卡进入transfer state。后续可以通过各种指令进入到receive-data state或者sending-data state依次来进行数据的传输

  • mmc_get_ext_csd
    发送CMD8指令,SEND_EXT_CSD
    这里要求处于transfer state的card发送ext_csd寄存器,这里获取之后存放在ext_csd寄存器中
    这里会使card进入sending-data state,完成之后又退出到transfer state。

  • mmc_switch
    发送CMD6命令,MMC_SWITCH
    用于设置ext_csd寄存器的某些bit

  • mmc_send_status
    发送CMD13命令,MMC_SEND_STATUS
    要求card发送自己当前的状态寄存器

  • mmc_send_cid
    发送CMD10命令,MMC_SEND_CID
    要求mmc card回复cid寄存器

  • mmc_card_sleepawake
    发送CMD5命令,MMC_SLEEP_AWAKE
    使card进入或者退出sleep state,由参数决定。关于sleep state是指card的一种状态,具体参考emmc 5.1协议。

先结合协议理解上述几个mmc type card的操作函数有助于理解后续mmc card的初始化代码。具体参考第五节。

二、数据结构

1、mmc_ops & mmc_ops_unsafe

struct mmc_bus_ops表示mmc host在总线上的操作集合,由host的card 设备来决定,mmc type card、sd type card相应的操作集合是不一样的。
mmc_ops和mmc_ops_unsafe则表示mmc type card所属的host对于总线的操作集合。

static const struct mmc_bus_ops mmc_ops = {
    .awake = mmc_awake,  
    .sleep = mmc_sleep,     
    .remove = mmc_remove,   
    .detect = mmc_detect,
    .suspend = NULL,
    .resume = NULL,
    .power_restore = mmc_power_restore,
    .alive = mmc_alive,
    .change_bus_speed = mmc_change_bus_speed,
};

static const struct mmc_bus_ops mmc_ops_unsafe = {
    .awake = mmc_awake,    // 使mmc总线上的mmc type card退出sleep state
    .sleep = mmc_sleep,       // 使mmc总线的mmc type card进入sleep state
    .remove = mmc_remove,   // 释放mmc type card
    .detect = mmc_detect,   // 检测mmc总线的mmc type card是否拔出
    .suspend = mmc_suspend,   // suspend掉mmc总线上的mmc type card,注意不仅仅会使card进入sleep state,还会对clock以及mmc cache进行操作
    .resume = mmc_resume,   // resume上mmc总线上的mmc type card
    .power_restore = mmc_power_restore,   // 恢复mmc总线上的mmc type card的电源状态
    .alive = mmc_alive,   // 检测mmc总线上的mmc type card状态是否正常
    .change_bus_speed = mmc_change_bus_speed,   // 修改mmc总线时钟频率
};

mmc_ops_unsafe和mmc_ops的区别在于是否实现suspend和resume方法。
对于card不可移除的host来说,需要使用mmc_ops_unsafe这个mmc_bus_ops来支持suspend和resume。
之所以在上述注释中不断说明mmc总线,是为了强调应该和mmc_bus虚拟总线区分开来,这里的mmc总线是物理概念、是和host controller直接相关联的。

2、mmc_type

struct device_type mmc_type中为mmc_card定义了很多属性,可以在sysfs中进行查看。

/sys/class/mmc_host/mmc0/mmc0:0001
或者/sys/bus/mmc/devices/mmc0:0001下可以查看到如下属性
block    cid   csd   date   driver   enhanced_area_offset   enhanced_area_size   erase_size   fwrev   hwrev
manfid    name   oemid   power   preferred_erase_size   prv   raw_rpmb_size_mult   rel_sectors
runtime_pm_timeout    serial   subsystem   type   uevent

mmc_type对应实现如下:

static struct device_type mmc_type = {
    .groups = mmc_attr_groups,
};

static const struct attribute_group *mmc_attr_groups[] = {
    &mmc_std_attr_group,
    NULL,
};

static struct attribute_group mmc_std_attr_group = {
    .attrs = mmc_std_attrs,
};

MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
    card->raw_cid[2], card->raw_cid[3]);
MMC_DEV_ATTR(cs
[mcc子系统]是一个在Linux内核中用于支持基于存储介质的通信硬件设备的子系统。它通过提供统一的接口和管理机制来简化不同存储设备的驱动程序的开发和维护。 [mcc子系统]的框架由四个主要组件组成:核心层、总线层、主机层和设备层。核心层提供了与[mcc子系统]相关的数据结构和功能,如驱动程序模型和设备模型。总线层提供了[mcc子系统]与系统总线(如PCI和USB)之间的通信接口,并负责管理和配置[mcc子系统]中的设备。主机层对应于[mcc子系统]的主机控制器,负责与存储设备进行通信和传输数据。设备层则是每个[mcc子系统]设备的驱动程序,它们负责处理硬件与软件之间的通信。 [mcc子系统]的工作流程如下:首先,[mcc子系统]的驱动程序会注册到内核中,并与相应的总线层进行绑定。然后,总线层会扫描系统中的存储设备,并将其实例化为[mcc子系统]的设备对象。主机层会根据设备的类型和通信协议,初始化设备并建立与存储设备之间的通信通道。最后,应用程序通过[mcc子系统]的接口与存储设备进行交互,实现对存储设备的读写操作。 [mcc子系统]的设计目标是提供一个可扩展和可移植的存储设备驱动程序框架,它可以支持不同类型和厂商的存储设备。通过使用[mcc子系统],存储设备的开发和维护工作变得更加简单和高效,大大提高了Linux内核支持存储设备的能力。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值