MMC子系统调用过程浅析(Core层)
Core层关系图:
在Card层中,分析到调用mmc_start_req(card->host, areq, (int *) &status)来处理块设备数据请求。在Caed层实际上完成了一个复杂的封装过程,会把request_queue->reqeust上的信息转到areq(mmc_async_req)->mmc_request上。
下面继续对mmc_start_req分析:
/*** mmc_start_req - start a non-blocking request* @host: MMC host to start command* @areq: async request to start* @error: out parameter returns 0 for success, otherwise non zero** Start a new MMC custom command request for a host.* If there is on ongoing async request wait for completion* of that request and start the new one and return.* Does not wait for the new request to complete.** Returns the completed request, NULL in case of none completed.* Wait for the an ongoing request (previoulsy started) to complete and* return the completed request. If there is no ongoing request, NULL* is returned without waiting. NULL is not an error condition.*/
struct mmc_async_req *mmc_start_req(struct mmc_host *host,struct mmc_async_req *areq, int *error)
{int err = 0;int start_err = 0;struct mmc_async_req *data = host->areq;/* Prepare a new request */if (areq)mmc_pre_req(host, areq->mrq, !host->areq);if (host->areq) {err = mmc_wait_for_data_req_done(host, host->areq->mrq, areq);if (err == MMC_BLK_NEW_REQUEST) {if (error)*error = err;/** The previous request was not completed,* nothing to return*/return NULL;}/** Check BKOPS urgency for each R1 response*/if (host->card && mmc_card_mmc(host->card) &&((mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1) ||(mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1B)) &&(host->areq->mrq->cmd->resp[0] & R1_EXCEPTION_EVENT)) {/* Cancel the prepared request */if (areq)mmc_post_req(host, areq->mrq, -EINVAL);mmc_start_bkops(host->card, true);/* prepare the request again */if (areq)mmc_pre_req(host, areq->mrq, !host->areq);}}if (!err && areq)start_err = __mmc_start_data_req(host, areq->mrq);if (host->areq)mmc_post_req(host, host->areq->mrq, 0);/* Cancel a prepared request if it was not started. */if ((err || start_err) && areq)mmc_post_req(host, areq->mrq, -EINVAL);if (err)host->areq = NULL;elsehost->areq = areq;if (error)*error = err;return data;
}
mmc_wait_for_data_req_done对数据进行处理:
/** mmc_wait_for_data_req_done() - wait for request completed* @host: MMC host to prepare the command.* @mrq: MMC request to wait for** Blocks MMC context till host controller will ack end of data request* execution or new request notification arrives from the block layer.* Handles command retries.** Returns enum mmc_blk_status after checking errors.*/
static int mmc_wait_for_data_req_done(struct mmc_host *host,struct mmc_request *mrq,struct mmc_async_req *next_req)
{struct mmc_command *cmd;struct mmc_context_info *context_info = &host->context_info;int err;unsigned long flags;while (1) {wait_event_interruptible(context_info->wait,(context_info->is_done_rcv ||context_info->is_new_req));spin_lock_irqsave(&context_info->lock, flags);context_info->is_waiting_last_req = false;spin_unlock_irqrestore(&context_info->lock, flags);if (context_info->is_done_rcv) {context_info->is_done_rcv = false;context_info->is_new_req = false;cmd = mrq->cmd;if (!cmd->error || !cmd->retries ||mmc_card_removed(host->card)) {err = host->areq->err_check(host->card,host->areq);break; /* return err */} else {mmc_retune_recheck(host);pr_info("%s: req failed (CMD%u): %d, retrying...\n",mmc_hostname(host),cmd->opcode, cmd->error);cmd->retries--;cmd->error = 0;__mmc_start_request(host, mrq);continue; /* wait for done/new event again */}} else if (context_info->is_new_req) {context_info->is_new_req = false;if (!next_req)return MMC_BLK_NEW_REQUEST;}}mmc_retune_release(host);return err;
}
mmc_wait_for_data_req_done中调用__mmc_start_request(host, mrq)来执行一个请求。
static void __mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
{int err;/* Assumes host controller has been runtime resumed by mmc_claim_host */err = mmc_retune(host);if (err) {mrq->cmd->error = err;mmc_request_done(host, mrq);return;}/** For sdio rw commands we must wait for card busy otherwise some* sdio devices won't work properly.*/if (mmc_is_io_op(mrq->cmd->opcode) && host->ops->card_busy) {int tries = 500; /* Wait aprox 500ms at maximum */while (host->ops->card_busy(host) && --tries)mmc_delay(1);if (tries == 0) {mrq->cmd->error = -EBUSY;mmc_request_done(host, mrq);return;}}host->ops->request(host, mrq);
}
可以看到host->ops->request(host, mrq),来完成request。core层其实最终都是调用mmc_host->mmc_host_ops。mmc_host_ops中放着与硬件相关的操作。内核中封装好了Card和Core两层,厂商只要按照自己的mmc控制器,编写Host层操作方法即可。
MMC子系统调用过程浅析(Core层)相关推荐
- 浅析Linux内核之mmc子系统-sdio
现在的Linux内核中,mmc不仅是一个驱动,而是一个子系统.这里通过分析Linux3.2.0内核,结合TI的arm335x平台及omap_hsmmcd host分析下mmc子系统,重点关注sdio及 ...
- MMC子系统识别SD设备过程简述
一 :引子–WIFI 模块移植 二 : MMC 识别 SD设备过程 第一步: 注册虚拟总线 第二步: 初始化并挂载设备驱动 第三步:初始化注册主控驱动 第四步:Host驱动的prob() 4.1 mm ...
- 代码 or 指令,浅析ARM架构下的函数的调用过程
摘要:linux程序运行的状态以及如何推导调用栈. 1.背景知识 1.ARM64寄存器介绍: 2.STP指令详解(ARMV8手册): 我们先看一下指令格式(64bit),以及指令对于寄存机执行结果的影 ...
- Linux驱动分析之MMC子系统框架
前言 上一篇<一文搞懂SDIO>简单介绍了SDIO接口及相关的协议.接下来来看一下Linux提供的驱动框架. MMC子系统介绍 Linux内核中,MMC不仅是一个驱动,而是一个子系统.内核 ...
- linux设备模型之mmc子系统
翻开mmc子系统驱动代码在Linux源码中的位置linux-3.4.y/drivers/mmc,分别有card.core和host三个文件夹, card.core和host这三层的关系,如下图: 从这 ...
- Linux MMC子系统分析(二)——Host分析
Linux MMC子系统分析(二)--Host分析 前言 通过前面对mmc子系统的模型分析,我们能够知道host是对应于硬件控制器的具体操作.本文将以sdhci-s3c.c为例对host进行简单的分析 ...
- LINUX MMC 子系统分析之五 MMC driver模块分析
前面我们介绍了MMC 子系统驱动模型.mmc host模块,本篇主要介绍MMC Driver模块,在前面几篇文章中,我们已经说明mmc 子系统已实现mmc driver,即针对所有的mmc card( ...
- usb摄像头驱动-core层USB集线器(Hub)驱动
usb摄像头驱动-core层USB集线器(Hub)驱动 文章目录 usb摄像头驱动-core层USB集线器(Hub)驱动 usb_hub_init hub_probe hub_event port_e ...
- mmc子系统分析(二)
文章目录 前言 一.mcc host驱动介绍 二.相关数据结构 1.struct mmc_host 2.struct mmc_host_ops 3.struct mmc_pwrseq 4.struct ...
最新文章
- 联手中科大、浙大、华科大等高校,阿里研发4项最新AI安全技术
- 第2章 数字之魅——求二进制中1的个数
- python趣味编程入门 迈克 桑德斯_Python趣味编程入门
- 常用邮件客户端软件设置
- 从上往下打印出二叉树的每个节点,同层节点从左至右打印。
- 用户中心 - 查询用户信息
- 深入update语句(延伸学习)
- 远程调用 quartz_如何远程管理Quartz
- onvif学习笔记9:OSD命令学习
- python解释器的使用
- 海南工会云会员认证_“网上工会”大普惠全面升级 全体会员共享生活大福利...
- matlab 画点标号,学习笔记(四)——MATLAB画图
- 如何给PDF添加签名或盖章
- Python之基础详解(九):关于VisualMapOpts视觉映射配置项详解
- Excel同时打开多个窗口
- android 百度浏览器内核,百度推手机浏览器Android版 移植webkit内核
- 中考计算机考试辽宁,2019年辽宁中考考试时间安排,辽宁中考考试科目时间安排表...
- 心疼果粉,10V、4A,荣耀Magic2超级快充充电头正式曝光厉害了
- 阅读代码时,用excel做笔记。
- Android版数据结构与算法汇总十二章
热门文章
- 如何把PPT幻灯片压缩到最小
- 维山VS073高拍仪技术规格说明书
- 腾讯云8核16G18M轻量服务器CPU带宽流量性能测评
- RabbitMQ 可靠性、重复消费、顺序性、消息积压解决方案
- 华硕电脑重装系统后fn组合键部分屏幕无显示
- 【DFS】【剪枝】数独(简单版)
- 假设你有8个球,其中一个略微重一些,但是找出这个球的唯一方法是将两个球放在天平上对比。最少要称多少次才能找出这个较重的球?
- sonarqube如何导入规则_sonar如何添加自定义JAVA规则
- html表格··表格样式··长表格
- Java毕业设计-会议室预约小程序系统