热门关键字:  ubuntu  分区  Fedora  linux系统进程  函数

当前位置 :| 主页>Linux教程>内核研究>

SD卡驱动分析2

来源: 作者: 时间:2008-11-27 Tag: 点击:

SD卡驱动分析2

代码:linux/drivers/mmc/s3c2410mci

 针对特定的mcu实现一个host驱动实例:主要是注册一个 host实体,中断处理函数,io设置函数,请求处理函数等    要做的工作.当有卡插入时,4中实现的插卡中断激活卡初始化程序和总线探测函数. mmc总线探测函数会调用块设备的探测函数,在卡设备探测函数中会初始化块设备的请求队列和注册一个gendisk实体(以后文件系统会通过 gendisk实体访问 mmc 块设备),同时在sysfs中建立真正的 mmc/sd 设备.块设备通过具体的 host 注册的io设置函数和请求函数与具体的host通讯.

这里相应的代码是:

static irqreturn_t s3c2410sdi_irq_cd(int irq, void *dev_id, struct pt_regs *regs)

{

       struct s3c2410sdi_host *host = (struct s3c2410sdi_host *)dev_id;

       mmc_detect_change(host->mmc);

 

       return IRQ_HANDLED;

}

/*同时,我们这个文档,这个部分还有两个重要的函数

static irqreturn_t s3c2410sdi_irq(int irq, void *dev_id, struct pt_regs *regs)

static void   s3c2410sdi_request(struct mmc_host *mmc, struct mmc_request *mrq)

他们之间是怎样工作的:文档里的解释如下

1) Driver sets up host->mrq and host->complete_what

 * 2) Driver prepares the transfer

 * 3) Driver enables interrupts

 * 4) Driver starts transfer

 * 5) Driver waits for host->complete_rquest

 * 6) ISR checks for request status (errors and success)

 * 6) ISR sets host->mrq->cmd->error and host->mrq->data->error

 * 7) ISR completes host->complete_request

 * 8) ISR disables interrupts

 * 9) Driver wakes up and takes care of the request

*/

这里相当重要,可是static void   s3c2410sdi_request(struct mmc_host *mmc, struct mmc_request *mrq)这个函数是由谁调用呢,这个很关键:

我们注意到有这样一个结构体:

static struct mmc_host_ops s3c2410sdi_ops = {

       .request = s3c2410sdi_request,

       .set_ios  = s3c2410sdi_set_ios,

};

然后发现  mmc->ops   = &s3c2410sdi_ops;

我们往上追查,顺腾摸瓜,在MMC.c发现:

mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)

{

       DBG("MMC: starting cmd %02x arg %08x flags %08x\n",

           mrq->cmd->opcode, mrq->cmd->arg, mrq->cmd->flags);

 

       WARN_ON(host->card_busy == NULL);

 

       mrq->cmd->error = 0;

       mrq->cmd->mrq = mrq;

       if (mrq->data) {

              mrq->cmd->data = mrq->data;

              mrq->data->error = 0;

              mrq->data->mrq = mrq;

              if (mrq->stop) {

                     mrq->data->stop = mrq->stop;

                     mrq->stop->error = 0;

                     mrq->stop->mrq = mrq;

              }

       }

       host->ops->request(host, mrq);这里很关键,是联系34层的关键

}

所以在申请request时,我们就回执行我们的request函数了,至于怎样执行就要根据hostmrq的具体情况来,这一层的代码就分析到这里,下篇文章继续摸索。




相关文章:
精通initramfs构建step by step
Linux利用kexec迅速切换内核
进程上下文VS中断上下文
内核通知链 学习笔记
linux spi子系统驱动分析
menuconfig 配置选项
《Linux操作系统内核实习》之练习一
udev详解
什么叫微内核,宏内核?
Linux 信号signal处理机制
开发简单的 Linux2.6 内核模块
删除内核的perl脚本
Linux2.6内核usb gadget驱动移植
GCC hacks in the Linux kernel
iomem
kernel学习的想法
让自己的驱动支持udev
linux内核编译步骤
内核的等待队列
Linux内核wait_queue深入分析
升级和删除内核
SD卡驱动分析2
Linux Kernel VDSO本地权限提升漏洞
内核中的TCP的追踪分析-15-TCP(IPV4)的客户端与
linux 2.6内核可加载模块的编译
内核模块HelloWorld
在环回接口上发送一个数据报
ARP初始化
1分钟编译FreeBSD内核
linux设备模型之uart驱动架构分析