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层)相关推荐

  1. 浅析Linux内核之mmc子系统-sdio

    现在的Linux内核中,mmc不仅是一个驱动,而是一个子系统.这里通过分析Linux3.2.0内核,结合TI的arm335x平台及omap_hsmmcd host分析下mmc子系统,重点关注sdio及 ...

  2. MMC子系统识别SD设备过程简述

    一 :引子–WIFI 模块移植 二 : MMC 识别 SD设备过程 第一步: 注册虚拟总线 第二步: 初始化并挂载设备驱动 第三步:初始化注册主控驱动 第四步:Host驱动的prob() 4.1 mm ...

  3. 代码 or 指令,浅析ARM架构下的函数的调用过程

    摘要:linux程序运行的状态以及如何推导调用栈. 1.背景知识 1.ARM64寄存器介绍: 2.STP指令详解(ARMV8手册): 我们先看一下指令格式(64bit),以及指令对于寄存机执行结果的影 ...

  4. Linux驱动分析之MMC子系统框架

    前言 上一篇<一文搞懂SDIO>简单介绍了SDIO接口及相关的协议.接下来来看一下Linux提供的驱动框架. MMC子系统介绍 Linux内核中,MMC不仅是一个驱动,而是一个子系统.内核 ...

  5. linux设备模型之mmc子系统

    翻开mmc子系统驱动代码在Linux源码中的位置linux-3.4.y/drivers/mmc,分别有card.core和host三个文件夹, card.core和host这三层的关系,如下图: 从这 ...

  6. Linux MMC子系统分析(二)——Host分析

    Linux MMC子系统分析(二)--Host分析 前言 通过前面对mmc子系统的模型分析,我们能够知道host是对应于硬件控制器的具体操作.本文将以sdhci-s3c.c为例对host进行简单的分析 ...

  7. LINUX MMC 子系统分析之五 MMC driver模块分析

    前面我们介绍了MMC 子系统驱动模型.mmc host模块,本篇主要介绍MMC Driver模块,在前面几篇文章中,我们已经说明mmc 子系统已实现mmc driver,即针对所有的mmc card( ...

  8. usb摄像头驱动-core层USB集线器(Hub)驱动

    usb摄像头驱动-core层USB集线器(Hub)驱动 文章目录 usb摄像头驱动-core层USB集线器(Hub)驱动 usb_hub_init hub_probe hub_event port_e ...

  9. mmc子系统分析(二)

    文章目录 前言 一.mcc host驱动介绍 二.相关数据结构 1.struct mmc_host 2.struct mmc_host_ops 3.struct mmc_pwrseq 4.struct ...

最新文章

  1. 联手中科大、浙大、华科大等高校,阿里研发4项最新AI安全技术
  2. 第2章 数字之魅——求二进制中1的个数
  3. python趣味编程入门 迈克 桑德斯_Python趣味编程入门
  4. 常用邮件客户端软件设置
  5. 从上往下打印出二叉树的每个节点,同层节点从左至右打印。
  6. 用户中心 - 查询用户信息
  7. 深入update语句(延伸学习)
  8. 远程调用 quartz_如何远程管理Quartz
  9. onvif学习笔记9:OSD命令学习
  10. python解释器的使用
  11. 海南工会云会员认证_“网上工会”大普惠全面升级 全体会员共享生活大福利...
  12. matlab 画点标号,学习笔记(四)——MATLAB画图
  13. 如何给PDF添加签名或盖章
  14. Python之基础详解(九):关于VisualMapOpts视觉映射配置项详解
  15. Excel同时打开多个窗口
  16. android 百度浏览器内核,百度推手机浏览器Android版 移植webkit内核
  17. 中考计算机考试辽宁,2019年辽宁中考考试时间安排,辽宁中考考试科目时间安排表...
  18. 心疼果粉,10V、4A,荣耀Magic2超级快充充电头正式曝光厉害了
  19. 阅读代码时,用excel做笔记。
  20. Android版数据结构与算法汇总十二章

热门文章

  1. 如何把PPT幻灯片压缩到最小
  2. 维山VS073高拍仪技术规格说明书
  3. 腾讯云8核16G18M轻量服务器CPU带宽流量性能测评
  4. RabbitMQ 可靠性、重复消费、顺序性、消息积压解决方案
  5. 华硕电脑重装系统后fn组合键部分屏幕无显示
  6. 【DFS】【剪枝】数独(简单版)
  7. 假设你有8个球,其中一个略微重一些,但是找出这个球的唯一方法是将两个球放在天平上对比。最少要称多少次才能找出这个较重的球?
  8. sonarqube如何导入规则_sonar如何添加自定义JAVA规则
  9. html表格··表格样式··长表格
  10. Java毕业设计-会议室预约小程序系统