\mmc_blk_init(void)
\register_blkdev(MMC_BLOCK_MAJOR,"mmc")
\mmc_register_driver(&mmc_driver);
\(&mmc_driver)->drv.bus=&mmc_bus_type;
\driver_register(&(&mmc_driver)->drv);
module_init(mmc_blk_init)
struct bus_type mmc_bus_type={
.match = mmc_bus_match;
.probe = mmc_bus_probe;
};
\mmc_bus_probe(struct device *dev)
\drv->probe();
struct mmc_driver mmc_driver={
.probe = mmc_blk_probe;
}
\mmc_blk_probe(card)
\struct mmc_blk_data *md;
\md = mmc_blk_alloc(card);
\mmc_blk_readonly(card)
\alloc_disk(1<<MMC_SHIFT)
\mmc_init_queue
\blk_init_queue(mmc_request,lock) //mmc_request里面有wake_up_process
\blk_queue_prep_rq
\blk_queue_ordered
\kthread_run(mmc_queue_thread,mq,"mmcqd")
\md->queue.issue_fn = mmc_blk_issue_rq
\常规的gendisk赋值工作
\mmc_blk_set_blksize
\mmc_claim_host //一个控制器可以服务多个对象所以需申请
\mmc_wait_for_cmd
\mmc_releaes_host //释放控制器
\mmc_set_drvdata //
\add_disk //使用add_disk向内核注册块设备驱动
struct mmc_blk_data{
struct gendisk * disk;
struct mmc_queue queue;
}
struct mmc_queue{
struct request *req;
struct request_queue *queue;
}
\mmc_request(q)
\wake_up_process(q->queuedata->thread)
\try_to_wake_up(mq->thread,TASK_ALL,0)
\...
\mmc_queue_thread(void *d)
\down(&d->thread_sem) //获得线程的信号量
\set_current_state(TASK_INTERRUPTIBLE) //设置当前线程运行状态为可中断
\up(&d->thread_sem) //释放线程的信号量
\schedule(); //内核发起调度
\mq->issue_fn(d,req)
\mmc_blk_issue_rq
\mmc_claim_host
\brq.mrq.cmd = &brq.cmd //因为struct mmc_request中的内容为指针,所以需要指代
\brq.mrq.data = &brq.data
\mmc_queue_map_sg
\mmc_wait_for_req(card->host,*brq.mrq)
struct mmc_blk_request{
struct mmc_request mrq; //传递给core和host层的一个mmc封装请求
struct mmc_command cmd;
struct mmc_command stop;
struct mmc_data data;
}
部分card层与core层的接口函数:
mmc_claim_host();
mmc_release_host();
mmc_wait_for_req();
mmc_wait_for_cmd();
几个代码树结构:
\blk_init_queue(rfn,lock)
\blk_init_queue_node(rfn,lock,-1)
\q->request_fn = rfn;
\blk_queue_make_request(q,__make_request)
\q->make_request_fn=__make_request;
blk_init_queue是和blk_cleanup_queue搭配使用的
\mmc_wait_for_cmd(host,cmd,retries)
\mmc_wait_for_req(host,mrq)
\mmc_start_request(host,mrq)
\host->ops->request(host,mrq)
\mrq->done_data = &complete
\mrq->done = mmc_wait_done
\wait_for_completion(&complete)