sd/mmc驱动框架-(三)mmc子系统的数据结构
知识脉络框图:
一、host相关
1、struct mmc_host
struct mmc_host是mmc core由host controller抽象出来的结构体,用于代表一个mmc host控制器。
* 数据结构如下:
struct mmc_host {struct device *parent; // 对应的host controller的devicestruct device class_dev; // mmc_host的device结构体,会挂在class/mmc_host下int index; // 该host的索引号const struct mmc_host_ops *ops; // 该host的操作集,由host controller设置,后面说明unsigned int f_min; // 该host支持的最低频率unsigned int f_max; // 该host支持的最大频率unsigned int f_init; // 该host使用的初始化频率/// 以下是和clock相关的成员int clk_requests; /* internal reference counter */unsigned int clk_delay; /* number of MCI clk hold cycles */bool clk_gated; /* clock gated */struct delayed_work clk_gate_work; /* delayed clock gate */unsigned int clk_old; /* old clock value cache */spinlock_t clk_lock; /* lock for clk fields */struct mutex clk_gate_mutex; /* mutex for clock gating */struct device_attribute clkgate_delay_attr;unsigned long clkgate_delay;/* host specific block data */ // 被主控制器驱动的mmc块设备数据和块相关的成员unsigned int max_seg_size; /* see blk_queue_max_segment_size */unsigned short max_segs; /* see blk_queue_max_segments */unsigned short unused;unsigned int max_req_size; /* maximum number of bytes in one req */unsigned int max_blk_size; /* maximum size of one mmc block */unsigned int max_blk_count; /* maximum number of blocks in one req */unsigned int max_discard_to; /* max. discard timeout in ms *//* private data 私有数据*/spinlock_t lock; /* lock for claim and bus ops */ // host的bus使用的锁struct mmc_ios ios; /* current io bus settings */ // io setting,后续说明u32 ocr; /* the current OCR setting */ // 当前使用的ocr的值/* group bitfields together to minimize padding */unsigned int use_spi_crc:1;unsigned int claimed:1; /* host exclusively claimed */ // host是否已经被占用unsigned int bus_dead:1; /* bus has been released */ // host的bus是否处于激活状态int rescan_disable; /* disable card detection */ // 禁止rescan的标识,禁止搜索cardint rescan_entered; /* used with nonremovable devices */ // 是否已经rescan过的标识,对应不可移除的设备只能rescan一次struct mmc_card *card; /* device attached to this host */ // 和该host绑定在一起的cardwait_queue_head_t wq;struct task_struct *claimer; /* task that has host claimed */ // 该host的占有者进程struct task_struct *suspend_task;int claim_cnt; /* "claim" nesting count */ // 占有者进程对该host的占用计数struct delayed_work detect; // 检测卡槽变化的工作struct wake_lock detect_wake_lock; // 检测卡槽变化的工作使用的锁const char *wlock_name; // 锁名称int detect_change; /* card detect flag */ // 需要检测卡槽变化的标识struct mmc_slot slot; // 卡槽的结构体const struct mmc_bus_ops *bus_ops; /* current bus driver */ // host的mmc总线的操作集,后面说明unsigned int bus_refs; /* reference counter */ // host的mmc总线的使用计数unsigned int bus_resume_flags; // host的mmc总线的resume标识mmc_pm_flag_t pm_flags; /* requested pm features */#ifdef CONFIG_REGULATORbool regulator_enabled; /* regulator state */ // 代表regulator(LDO)的状态
#endifstruct mmc_supply supply;struct dentry *debugfs_root; // 对应的debug目录结构体struct mmc_async_req *areq; /* active async req */ // 当前正在处理的异步请求struct mmc_context_info context_info; /* async synchronization info */ // 异步请求的信息unsigned int actual_clock; /* Actual HC clock rate */ // 实际的时钟频率
};
- ocr值各个位代表的电压意义如下:
#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */
#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */
#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */
#define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */
#define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */
#define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */
#define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */
#define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */
#define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */
#define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */
#define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */
#define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */
#define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */
#define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */
#define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */
#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */
#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */
- host属性(mmc_host->caps)caps1支持的属性如下
#define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */
#define MMC_CAP_MMC_HIGHSPEED (1 << 1) /* Can do MMC high-speed timing */
#define MMC_CAP_SD_HIGHSPEED (1 << 2) /* Can do SD high-speed timing */
#define MMC_CAP_SDIO_IRQ (1 << 3) /* Can signal pending SDIO IRQs */
#define MMC_CAP_SPI (1 << 4) /* Talks only SPI protocols */
#define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */
#define MMC_CAP_8_BIT_DATA (1 << 6) /* Can the host do 8 bit transfers */#define MMC_CAP_NONREMOVABLE (1 << 8) /* Nonremovable e.g. eMMC */
#define MMC_CAP_WAIT_WHILE_BUSY (1 << 9) /* Waits while card is busy */
#define MMC_CAP_ERASE (1 << 10) /* Allow erase/trim commands */
#define MMC_CAP_1_8V_DDR (1 << 11) /* can support *//* DDR mode at 1.8V */
#define MMC_CAP_1_2V_DDR (1 << 12) /* can support *//* DDR mode at 1.2V */
#define MMC_CAP_POWER_OFF_CARD (1 << 13) /* Can power off after boot */
#define MMC_CAP_BUS_WIDTH_TEST (1 << 14) /* CMD14/CMD19 bus width ok */
#define MMC_CAP_UHS_SDR12 (1 << 15) /* Host supports UHS SDR12 mode */
#define MMC_CAP_UHS_SDR25 (1 << 16) /* Host supports UHS SDR25 mode */
#define MMC_CAP_UHS_SDR50 (1 << 17) /* Host supports UHS SDR50 mode */
#define MMC_CAP_UHS_SDR104 (1 << 18) /* Host supports UHS SDR104 mode */
#define MMC_CAP_UHS_DDR50 (1 << 19) /* Host supports UHS DDR50 mode */
#define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */
#define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */
#define MMC_CAP_DRIVER_TYPE_D (1 << 25) /* Host supports Driver Type D */
#define MMC_CAP_CMD23 (1 << 30) /* CMD23 supported. */
#define MMC_CAP_HW_RESET (1 << 31) /* Hardware reset */
2、struct mmc_host_ops
mmc core将host需要提供的一些操作方法封装成struct mmc_host_ops。
mmc core主模块的很多接口都是基于这里面的操作方法来实现的,通过这些方法来操作host硬件达到对应的目的。
所以struct mmc_host_ops也是host controller driver需要实现的核心部分。
struct mmc_host_ops {/** 'enable' is called when the host is claimed and 'disable' is called* when the host is released. 'enable' and 'disable' are deprecated.*/int (*enable)(struct mmc_host *host); // 使能host,当host被占用时(第一次调用mmc_claim_host)调用int (*disable)(struct mmc_host *host); // 禁用host,当host被释放时(第一次调用mmc_release_host)调用/** It is optional for the host to implement pre_req and post_req in* order to support double buffering of requests (prepare one* request while another request is active).* pre_req() must always be followed by a post_req().* To undo a call made to pre_req(), call post_req() with* a nonzero err condition.*/// post_req和pre_req是为了实现异步请求处理而设置的// 异步请求处理就是指,当另外一个异步请求还没有处理完成的时候,可以先准备另外一个异步请求而不必等待// 具体参考《mmc core主模块》void (*post_req)(struct mmc_host *host, struct mmc_request *req,int err);void (*pre_req)(struct mmc_host *host, struct mmc_request *req,bool is_first_req);void (*request)(struct mmc_host *host, struct mmc_request *req); // host处理mmc请求的方法,在mmc_start_request中会调用void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios); // 设置host的总线的io settingint (*get_ro)(struct mmc_host *host); // 获取host上的card的读写属性int (*get_cd)(struct mmc_host *host); // 检测host的卡槽中card的插入状态/* optional callback for HC quirks */void (*init_card)(struct mmc_host *host, struct mmc_card *card); // 初始化card的方法int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios); // 切换信号电压的方法/* Check if the card is pulling dat[0:3] low */int (*card_busy)(struct mmc_host *host); // 用于检测card是否处于busy状态/* The tuning command opcode value is different for SD and eMMC cards */int (*execute_tuning)(struct mmc_host *host, u32 opcode); // 执行tuning操作,为card选择一个合适的采样点int (*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv); // 选择信号的驱动强度void (*hw_reset)(struct mmc_host *host); // 硬件复位void (*card_event)(struct mmc_host *host); // unsigned long (*get_max_frequency)(struct mmc_host *host); // 获取host支持的最大频率的方法unsigned long (*get_min_frequency)(struct mmc_host *host); // 获取host支持的最小频率的方法int (*notify_load)(struct mmc_host *, enum mmc_load);int (*stop_request)(struct mmc_host *host); // 停止请求处理的方法unsigned int (*get_xfer_remain)(struct mmc_host *host);
};
3.s3c2440 host驱动中初始化hmmc_host结构体成员的实战代码分析:
/** Platform driver and initialization.*/
static void __init s3c2440mmc_host_init(struct s3c2440mmc_host *host, struct mmc_host *mmc)
{struct s3c2440mmc_platform_data *pdata = host->pdata;mmc->ops = &s3c2440mmc_ops;//主控制器操作函数集合mmc->f_min = 200000;//控制器的最小时钟频率mmc->f_max = pdata->max_freq;//控制器的最大时钟频率mmc->ocr_avail = pdata->ocr_avail;//控制器的供电范围mmc->caps |= pdata->capacity;//控制器的支持的特殊功能mmc->pm_flags |= pdata->pm_flags;
#ifdef CONFIG_MMC_BLOCK_BOUNCEmmc->max_blk_count = 65535;//mmc块设备的最大块数mmc->max_req_size = PAGE_SIZE * 16;//单个请求的最大数据长度,以字节为单位
#elsemmc->max_segs = MAX_SEGS;//mmc->max_blk_count = 4096;//单个请求的最大块数mmc->max_req_size = 4096 * 512; //单个请求的最大数据长度,以字节为单位
#endifmmc->max_blk_size = 512; //mmc块设备的最大块大小mmc->max_seg_size = mmc->max_req_size;//物理段的最大长度,以字节为单位host->mmc = mmc; setup_timer(&host->request_timer, s3c2440mmc_request_timeout,(unsigned long)host);mmc_add_host(mmc);//添加mmc host
}
参考文献:
1.《深入实践嵌入Linux系统移植 范展源 刘韬》
2. https://blog.csdn.net/ooonebook/article/details/55105481
sd/mmc驱动框架-(三)mmc子系统的数据结构相关推荐
- linux mmc驱动框架,Linux mmc framework2:基本组件之mmc
1.前言 本文主要mmc组件的主要流程,在介绍的过程中,将详细说明和mmc相关的流程,涉及到其它组件的详细流程再在相关文章中说明. 2.主要数据结构和API TODO 3. 主要流程 3.1 mmc_ ...
- mmc驱动框架基础介绍
mmc驱动框架基础介绍 本文主要介绍一下Linux内核的mmc子系统驱动的整体框架. (作者对SDIO设备不熟悉,所以不过多描述:鄙人才疏学浅,有不当之处,还请指教.) 大概包括以下几个部分: mmc ...
- Linux驱动分析之MMC子系统框架
前言 上一篇<一文搞懂SDIO>简单介绍了SDIO接口及相关的协议.接下来来看一下Linux提供的驱动框架. MMC子系统介绍 Linux内核中,MMC不仅是一个驱动,而是一个子系统.内核 ...
- Linux MMC 驱动子系统详解
Linxu MMC 驱动子系统 文章目录 Linxu MMC 驱动子系统 硬件关联 目录说明 mmc子系统的逻辑架构 设备-总线-驱动模型 一.MMC驱动抽象模型 二.SDIO驱动抽象模型 三.MMC ...
- Linux MMC驱动架构浅析
Linux MMC驱动架构浅析 MMC驱动模型 Linux内核设计了MMC子系统,用于管理MMC/SD等设备,MMC/SD存储设备是一种典型的块设备.MMC子系统的框架结构如下图所示. 块设备(MMC ...
- uboot环境下mmc操作_【记录】将Uboot 2011.06中mmc驱动移植到uboot 1.1.6的过程
[记录]将Uboot 2011.06中mmc驱动移植到uboot 1.1.6的过程 时间:2011-8-14 作者:crifan 联系方式:green-waste (at) 163.com 附上代码: ...
- Linux SD卡驱动开发(五) —— SD 卡驱动分析Core补充篇
Core层中有两个重要函数 mmc_alloc_host 用于构造host,前面已经学习过,这里不再阐述:另一个就是 mmc_add_host,用于注册host 前面探测函数s3cmci_probe, ...
- EDK2驱动框架之—Protocol
UEFI中的Protocol 1. 基本概念 1.1 什么是protocol? Protocol是UEFI中的一个重要概念(事实上<UEFI SPEC>中有超过70%的内容都是在讲Prot ...
- Linux内核(一) [ IMX RK ] TTY-UART驱动框架解析
平台:NXP imx6ull 内核版本:4.1.15 文章目录 一.Linux TTY驱动框架 二.Linux Uart驱动框架 三.UART相关结构体uart_driver(UART驱动结构体) . ...
最新文章
- [csu/coj 1078]多个序列的最长公共子序列
- before与after的一些应用总结
- 实战SSM_O2O商铺_37【商品】商品列表之View层的实现
- IDA*-洛谷P1379 八数码难题
- 剑指Offer(书):链表的倒数第K个节点
- java中删除node节点_[Java]LeetCode237. 删除链表中的节点 | Delete Node in a Linked List
- 下载并搭建VAuditDemo漏洞代码审计平台
- php简单环境,PHP 简单的环境搭建
- Map接口的实现类HashMap的操作
- 神经网络的全连接层_深度神经网络全连接层
- Python学习笔记之用户输入
- 063 模块的四种形式
- centos u盘安装_利用Win32 Disk Imager 实现U盘刻录ISO
- GNU make 汇总
- SSM框架面试题整理
- postgresql mysql数据类型_postgresql+java数据类型对照
- 冠希哥的英文还是diao 说的真好 瑞斯白
- 如何在7段和16段LED显示屏中表示数字和字母?
- Python class __int__容易理解
- 【JSP】用户信息界面操作 ---- 用户信息修改
热门文章
- 挖个冰块就能修自己,科学家用「冰」做了辆科考机器车,南极火星都能跑
- 一个简单的2DRoguelike游戏随机地图生成思路
- 酷派t2co1怎么升Android5,而且双清不了怎么办Coolpad725?酷 – 手机爱问
- 雅虎免费邮箱开通POP3和自动转发的方法
- vue 仿豆瓣 爬坑之旅
- 常识 | drm kms 详解
- RTKLIB_RTCM解码学习
- 身份证扫描到一个PDF或图片
- \node_modules\node-sass\build\src\libsass.vcxproj(20,3): error MSB4019: 未找到导入的项目“D:\Microsoft.Cpp.De
- opencv立方体的画法_美术生干货,最详细的立方体透视变化及画法讲解,不看后悔!...