SD卡驱动分析2
代码:linux/drivers/mmc/s
针对特定的mcu实现一个host驱动实例:主要是注册一个 host实体,中断处理函数,io设置函数,请求处理函数等 要做的工作.当有卡插入时,由4中实现的插卡中断激活卡初始化程序和总线探测函数. 由mmc总线探测函数会调用块设备的探测函数,在卡设备探测函数中会初始化块设备的请求队列和注册一个gendisk实体(以后文件系统会通过 gendisk实体访问 mmc 块设备),同时在sysfs中建立真正的 mmc/sd 设备.块设备通过具体的 host 注册的io设置函数和请求函数与具体的host通讯.
这里相应的代码是:
static irqreturn_t s
{
struct s
mmc_detect_change(host->mmc);
return IRQ_HANDLED;
}
/*同时,我们这个文档,这个部分还有两个重要的函数
static irqreturn_t s
和static void s
他们之间是怎样工作的:文档里的解释如下
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 s
我们注意到有这样一个结构体:
static struct mmc_host_ops s
.request = s
.set_ios = s
};
然后发现 mmc->ops = &s
我们往上追查,顺腾摸瓜,在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);这里很关键,是联系3,4层的关键
}
所以在申请request时,我们就回执行我们的request函数了,至于怎样执行就要根据host和mrq的具体情况来,这一层的代码就分析到这里,下篇文章继续摸索。
