您的位置:首页 > 其它

mmc流程

2014-02-25 15:36 267 查看
看mmc之前先看看mmc在Linux中的位置



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

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



上面这张图清晰的描述了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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: