转自:http://blog.csdn.net/skdkjzz/article/details/38927943

我们知道host在扫描卡的过程中,其识别的顺序为SDIO  SD MMC,并且从它的注释可以看出,这个顺序是很重要的。那这篇文章,我们就看看SDIO的识别过程,它对应的函数就是mmc_attach_sdio(host) (函数位于文件drivers/mmc/core/sdio.c), 那么同一个控制器是如何区分mmc/sd/sdio设备的,软件会不停的轮训设备,发不同的指令,然后不同的设备会做出不同的反应。

这个函数大概来说做了如下的工作

1、向卡发送CMD5命令,该命令有两个作用:第一,通过判断卡是否有反馈信息来判断是否为SDIO设备(只有SDIO设备才对CMD5命令有反馈,其他卡是没有回馈的);第二,如果是SDIO设备,就会给host反馈电压信息,就是说告诉host,本卡所能支持的电压是多少多少。

2、host根据SDIO卡反馈回来的电压要求,给其提供合适的电压。

3、初始化该SDIO卡

4、注册SDIO的各个功能模块

5、注册SDIO卡

对于以上功能的具体解释,下面将结合程序娓娓道来

1、CMD5命令的发送

第789行的函数就是发送的CMD5命令,如果卡对该命令有回馈的话,err就是0,否则,err为非0,直接退出了;并且需要重点说明的一点就是,该函数的最后一个参数ocr,它是存储反馈命令的,SDIO设备对CMD5的反馈命令为R4,下面来仔细分析一下这个R4,因为后面要用到这个R4命令。从SDIO spec文档里面,我们能得到R4命令的格式

从上图可以看出,该命令有48位,但我们的ocr变量是32位的,那怎么存储呢?系统就去掉原命令的开头8位以及结尾的8位,只保留中间的32为,也就是截短后的命令格式是如下:

具体各位的描述如下:

C --   我还不知道

Number 0f IO functions   -- 每个SDIO设备都有功能块,这三位就记录了该设备有多少个功能块,最多7个

Memory Present – 指明该设备是纯粹只有功能块的设备,还是同时包含了存储空间,如果为0就是前者,如果是1就是后者

Stuff Bits  -- 没有实际用途一般为0

I/O OCR – 该设备所能支持的电压范围(具体描述见sdio spec)

2、配置电压

ocr就是我们上面讲的反馈命令R4(截短之后的32位),那么ocr&0x7f的意义是什么呢?从R4的格式就可以看出来,其低24位就代表了所能支持的电压范围,我们再来详细的看一下这24位的OCR格式

现在应该可以知道ocr&0x7f的意义了吧,就是摈弃那些保留的电压范围。

重点关注mmc_select_voltage

第1080行的相与 过程就是判断host实际所支持的电压与card所需要的电压是否匹配,如果匹配,那么ocr的值就非0,否则就为0

简单介绍下第1082行的ffs函数,它的作用就是返回参数中第一个为1的bit的位置(ffs(0)=0,ffs(1)=1,ffs(8)=4),那么该函数用在这里的作用就是取出card需要的实际电压是多少;

第1090行的mmc_set_ios函数里面通过调用sdhci_set_power将host->iOS.vdd所代表的电压写入寄存器PWRCONn中 完成那个对电压的重新配置(想要了解更详细的过程,请跟踪源代码)

3、初始化SDIO卡

第821行就是初始化SDIO卡的函数  这个函数很长,也很重要,这里笔者就不列出其程序代码了,只是列出其中最重要的几条:

1、通过函数mmc_alloc_card分配一个mmc_card的变量card

2、通过读取R4命令中的bit27(也就是Memory Present)来判断此卡是纯IO卡 ,还是同时包含存储功能。笔者使用的WIFI模块为纯IO功能,所以card->type = MMC_TYPE_SDIO(这个很重要,以后会用到) (接下来重点分析MMC_TYPE_SDIO的情况)

3、通过发送CMD3命令获取设备的从地址(relative addr),并且存放在变量card->rca中。笔者使用的WIFI模块的card->rca = 1

4、通过发送CMD7,选中相应从地址的卡

5、通过调用函数mmc_set_clock设置卡工作的时钟频率

6、通过发送CMD52命令,设置4位数据传输模式

4、注册SDIO功能模块

847行的变量funcs存储该SDIO卡所包含的IO功能块的个数,851行到857行就是逐一初始化各个IO功能块,下面来重点看一下该函数的内容:

第71行就是分配sdio_func结构体变量,该结构体存储了功能块的参数。

第75行就是给功能块编号,编号是从1到7(因为一个SDIO设备最多只有7个功能块),存储在变量func->num中

第78行就是读取SDIO卡中的FBR寄存器中关于该卡的功能类型的数据,存储在func->class变量中(具体关于FBR寄存器内容,可以参考SDIO spec文档)

第82行就是读取SDIO卡中的CIS寄存器的内容

上面的程序就是将功能模块逐个的注册进设备模型,这里想重点说明一下注册的名称(name),它是由三部分组成的,每部分之间用冒号隔开,(即 host的名称:rca:功能块编号) 。具体到笔者使用的WIFI模块,因为其host名称是mmc2  ,rca = 1,并且有两个功能模块(功能模块编号分别是1和2),所以在/sys/bus/sdio/devices目录下能见到如下两个设备名

mmc2:0001:1

mmc2:0001:2

5、注册SDIO卡

上面的mmc_add_card函数就是注册card了(这个card是在第3部分,初始化SDIO卡 里面分配和定义的)

第259行就是给card命名,格式为host名字:从地址,对于笔者的WIFI模块 就是mmc2:0001

第261到273行就是根据card->type来分辨出card的类型,给赋予相应的字符串,笔者的WIFI模块就是"SDIO"

第275行就是打印信息,具体不解释 笔者的打印信息为  mmc2:new high speed SDIO card at address 0001(通常可以通过查看内核启动信息中是否有该语句来判断card是否被正确识别)

第283行 就是将card注册进Linux设备模型  注册结果就是可以在/sys/bus/mmc/devices目录下见到card 的名字,笔者的就是mmc2:0001

Linux下sdio设备扫描过程,[mmc]Linux下MMC/SD/SDIO的识别与操作相关推荐

  1. linux内核静态添加sdio设备,Linux下sdio设备扫描过程

    前言 本文基于Linux version 3.10.52版本代码分析sdio设备的扫描过程,同时选择sdio wifi设备作为分析对象,在分析过程中,附带上sdio的协议内容,帮助初学人员学习sdio ...

  2. PCI总线---PCI设备扫描过程

    8.2 PCI设备扫描过程 Linux内核具备多种PCI的扫描方式,它们之间大同小异. 本节使用传统的扫描方式 执行 pci_legacy_init函数,定义在legacy.c 文件中 : stati ...

  3. Linux通常把设备对象抽象为,linux 设备模型(1)

    设备模型(一) 一.概述 从2.6内核引入了sysfs文件系统,与proc, devfs, devpty同类别,属于虚拟的文件系统.目的是展示设备驱动模型中各组件的层次关系,第一层目录:block, ...

  4. linux查看usb设备文件,技术|在 Linux 系统里识别 USB 设备名字的 4 种方法

    对于初学者来说,在 Linux 系统里你必须掌握的技术之一就是识别出插入系统里的各种设备.这也许是你的系统硬盘.外部的存储设备或者是可移动设备,比如 USB 设备或 SD 闪存卡等. 现如今,使用 U ...

  5. linux格式化时设备或资源忙,Linux下用fdisk命令和partprobe命令不重启系统新建分区并格式化...

    由于工作的需要,最近一段时间一直在学习Linux.学习一门新的知识,我是喜欢根据谋一本书或者某一个学习视频系统的学习,这样可以对学习的新知识有一个系统全面的认识和了解.所以学习之前,买了一本鸟哥的私房 ...

  6. linux格式化时设备或资源忙,Linux下使用fdisk命令和partprobe命令,在不重启系统的状况下新建分区并格式化...

    因为工做的须要,最近一段时间一直在学习Linux.学习一门新的知识,我是喜欢根据谋一本书或者某一个学习视频系统的学习,这样能够对学习的新知识有一个系统全面的认识和了解.因此学习以前,没了一本鸟哥的私房 ...

  7. linux格式化usb设备,如何在 usb linux下格式化磁盘

    慕田峪7331174 以格式化 /dev/sda1 分区为例:$ sudo umount /dev/sda1# 必须先卸载该分区# 格式化为 FAT 分区$ sudo mkfs.vfat -F 32 ...

  8. linux 内核块设备驱动,你了解Linux 块设备驱动?

    1 什么是Ramdisk Ramdisk是一种模拟磁盘,其数据实际上是存储在RAM中,它使用一部分内存空间来模拟出一个磁盘设备,并以块设备的方式来组织和访问这片内存.对于用户来说可以把Ramdisk与 ...

  9. linux内核与设备驱动,第二章 Linux内核与设备驱动程序

    2.1 Linux操作系统 Linux操作系统由系统的启动.进程调度.虚拟内存管理器.文件系统.设备驱动程序等多个组成 2.2Linux内核 设备驱动程序中使用的函数也用在内核上,并且影响着内核,因此 ...

  10. linux 查看 pci 设备驱动,如何写linux pci设备驱动程序

    PCI总线应用领域及其广泛并且令人惊奇.不同的pci设备有不同的需求以及不同的问题.因此,在linux内核中pci层支持就非常重要啦.本文档就是想为驱动程序设计开发人员解决pci处理中的各种问题. 0 ...

最新文章

  1. 【Unity_UWP】Unity 工程发布win10 UWP 时的本地文件读取 (上篇)
  2. javascript对表单的操作
  3. eclipse android环境配置
  4. 坐火车一定要带身份证
  5. android 线程锁Lock
  6. Google深度揭秘TPU:一文看懂内部原理,以及为何碾压GPU
  7. MATLAB函数参数个数控制
  8. MacOS中Elasticsearch的安装「借助Homebrew」
  9. [2005/05/03] 卡耐基选语
  10. 从头开始学Android之(一)——— Android架构
  11. Git 常用命令 和 安装
  12. 【BZOJ】1176: [Balkan2007]Mokia(cdq分治)
  13. Win10完美运行红色警戒2的安装包和补丁
  14. netbeans php下载,Netbeans7下载和安装
  15. 新技术在支付清算行业的创新应用
  16. meta是什么意思中文_Meta 的意思是什么?
  17. 最新版 Whatsapp 官网下载安装
  18. WebPack 学习:从阮神的15个DEMO开始
  19. 账号密码登录和注册业务逻辑
  20. 2022焊工(初级)特种作业证考试题库及答案

热门文章

  1. Thrift原理简析
  2. 朗逸发动机型号css和ea211的区别,css发动机是ea211吗
  3. matlab 矩阵逻辑与,MATLAB之逻辑
  4. os系统安装python_在MacOS系统上安装疯子Python
  5. 双系统bios如何设置默认启动系统_BIOS(主板)常用功能:设置启动磁盘顺序,迁移系统必备...
  6. Linux支持运行3dmax,Mesa的Panfrost Gallium3D驱动程序现在可以使用新的DRM驱动程序
  7. db powerdesign 入门
  8. VMwear安装Centos7超详细过程
  9. DotNetTextBox控件添加外挂插件功能的图文教程。
  10. webpack ,require.ensure配合oclazyload 实现ng1模块懒加载