emmc host是如果处理uboot 传递过来的flashlayout信息呢?
source/drivers/mmc/host/pxamci.c
static int pxamci_probe(struct platform_device *pdev)
637 {
653
654 mmc = mmc_alloc_host(sizeof(struct pxamci_host), &pdev->dev);
655 if (!mmc) {
656 ret = -ENOMEM;
657 goto out;
658 }
probe 函数中会调用mmc_alloc_host来增加一个host
drivers/mmc/core/host.c
337 struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
338 {
381 INIT_DELAYED_WORK(&host->detect, mmc_rescan);
396 }
这个函数总重要的是初始化一个workqueue,回调函数是mmc_rescan.
那这个workqueue是怎么启动的呢?
可以看到是mmc_start_host调用_mmc_detect_change
2649 void mmc_start_host(struct mmc_host *host)
2650 {
2663 _mmc_detect_change(host, 0, false);
2664 }
_mmc_detect_change 实现如下:
1872 static void _mmc_detect_change(struct mmc_host *host, unsigned long delay,
1873 bool cd_irq)
1874 {
1891 mmc_schedule_delayed_work(&host->detect, delay);
1892 }
可见是1891行启动这个workqueue的.
我们再来看看mmc_rescan是怎么处理flashlayout的.
mmc_rescan->mmc_attach_mmc->mmc_add_card->device_add->bus_probe_device->device_attach->bus_for_each_drv->device_probe_device->mmc_blk_probe->mmc_add_disk->add_disk->blkdev_get->__blkdev_get->rescan_partition->check_partition
142 check_partition(struct gendisk *hd, struct block_device *bdev)
143 {
163 i = res = err = 0;
164 while (!res && check_part[i]) {
165 memset(state->parts, 0, state->limit * sizeof(state->parts[0]));
166 res = check_part[i++](state);
check_partition会调用check_part数组
41 static int (*check_part[])(struct parsed_partitions *) = {
83 #endif
84 #ifdef CONFIG_OSF_PARTITION
85 osf_partition,
如果定义CONFIG_OSF_PARTITION,实际调用的就是osf_partition
15 int osf_partition(struct parsed_partitions *state)
16 {
73 }
74 for (i = 0 ; i < npartitions; i++, partition++) {
75 if (slot == state->limit)
76 break;
77 if (le32_to_cpu(partition->p_size))
78 put_partition(state, slot,
79 le32_to_cpu(partition->p_offset),
80 le32_to_cpu(partition->p_size));
81 slot++;
82 }
83 strlcat(state->pp_buf, "
", PAGE_SIZE);
84 put_dev_sector(sect);
85 return 1;
86 }
在78行会调用put_partition来初始化partition
40 static inline void
41 put_partition(struct parsed_partitions *p, int n, sector_t from, sector_t size)
42 {
43 if (n < p->limit) {
44 char tmp[1 + BDEVNAME_SIZE + 10 + 1];
45
46 p->parts[n].from = from;
47 p->parts[n].size = size;
48 snprintf(tmp, sizeof(tmp), " %s%d", p->name, n);
49 strlcat(p->pp_buf, tmp, PAGE_SIZE);
50 }
51 }
保存partition的起始地址和size,以及名字.