mmc流程
看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 }
mmc_blk_probe
原文:http://blog.csdn.net/successcw/article/details/19913691