mmc流程

时间:2014-02-26 04:15:33   收藏:0   阅读:480

看mmc之前先看看mmc在Linux中的位置


bubuko.com,布布扣

图片来自:http://free-electrons.com/doc/block_drivers.pdf

从上图可以看出,MMC与SCSI,IDE一样都属于block driver

bubuko.com,布布扣

上面这张图清晰的描述了mmc subsystem的结构,接下来我们分开来看

drivers/mmc/host/ 下面存放mmc host driver, 这些driver完成芯片的初始化之后会调用mmc_add_host向mmc core层注册这个host.

mmc_add_host (core/host.c)

        mmc_start_host (core/core.c)

                mmc_detect_change (core/core.c)

                        mmc_rescan (core/core.c)

                                mmc_rescan_try_freq (core/core.c)

                                        mmc_attach_sd (core/sd.c): starting point for SD card init

                                                mmc_sd_init_card (core/sd.c)

                                                        mmc_alloc_card (core/bus.c)

                                                mmc_add_card (core/bus.c)

                                                        device_add

这个调用关系中,主要是mmc_alloc_card和mmc_add_card

320 /*
321  * Allocate and initialise a new MMC card structure.
322  */
323 struct mmc_card *mmc_alloc_card(struct mmc_host *host, struct device_type *type)
324 {
325     struct mmc_card *card;
326 
327     card = kzalloc(sizeof(struct mmc_card), GFP_KERNEL);
328     if (!card)
329         return ERR_PTR(-ENOMEM);
330 
331     card->host = host;
332 
333     device_initialize(&card->dev);
334 
335     card->dev.parent = mmc_classdev(host);
336     card->dev.bus = &mmc_bus_type;
337     card->dev.release = mmc_release_card;
338     card->dev.type = type;
339 
340     spin_lock_init(&card->bkops_info.bkops_stats.lock);
341     spin_lock_init(&card->wr_pack_stats.lock);
342 
343     return card;
344 }

可以看到,第336行指定bus mmc_bus_type

263 static struct bus_type mmc_bus_type = {
264     .name       = "mmc",
265     .dev_attrs  = mmc_dev_attrs,
266     .match      = mmc_bus_match,
267     .uevent     = mmc_bus_uevent,
268     .probe      = mmc_bus_probe,
269     .remove     = mmc_bus_remove,
270     .shutdown        = mmc_bus_shutdown,
271     .pm     = &mmc_bus_pm_ops,
272 };

这样当mmc_add_card调用device_add的时候,根据linux device driver模型,会自动去找bus上对应的driver。

那首先会调用match去判断是否匹配

 60 static int mmc_bus_match(struct device *dev, struct device_driver *drv)
 61 {
 62     return 1;
 63 }

这里直接return 1,那接下来会调用mmc_bus_probe

108 static int mmc_bus_probe(struct device *dev)
109 {
110     struct mmc_driver *drv = to_mmc_driver(dev->driver);
111     struct mmc_card *card = mmc_dev_to_card(dev);
112 
113     return drv->probe(card);
114 }

从mmc_bus_probe的实现可以看出,会调用对应driver的probe函数

这个driver在mmc/card/block.c中注册,到这里,上图中host和core基本介绍完了

3597 static struct mmc_driver mmc_driver = {
3598     .drv        = {
3599         .name   = "mmcblk",
3600     },
3601     .probe      = mmc_blk_probe,
3602     .remove     = mmc_blk_remove,
3603     .suspend    = mmc_blk_suspend,
3604     .resume     = mmc_blk_resume,
3605     .shutdown   = mmc_blk_shutdown,
3606 };
3607     
3608 static int __init mmc_blk_init(void)
3609 {   
3610     int res;
3611 
3612     if (perdev_minors != CONFIG_MMC_BLOCK_MINORS)
3613         pr_info("mmcblk: using %d minors per device\n", perdev_minors);
3614 
3615     max_devices = 256 / perdev_minors;
3616 
3617     res = register_blkdev(MMC_BLOCK_MAJOR, "mmc");
3618     if (res)
3619         goto out;
3620 
3621     res = mmc_register_driver(&mmc_driver);
3622     if (res)
3623         goto out2;
3624 
3625     return 0;
3626  out2:
3627     unregister_blkdev(MMC_BLOCK_MAJOR, "mmc");
3628  out:
3629     return res; 
3630 }  

我们先来看 mmc_register_driver

288 int mmc_register_driver(struct mmc_driver *drv)
289 {
290     drv->drv.bus = &mmc_bus_type;
291     return driver_register(&drv->drv);
292 }


可以看到bus是mmc_bus_type,和刚刚的mmc_add_card中添加的device是同一个bus,这样的话device添加的时候就调用到了这个driver的probe

mmc_blk_probe





原文:http://blog.csdn.net/successcw/article/details/19913691

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!