⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mtdpart.c

📁 基于linux-2.6.28的mtd驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
		mtd->ecc_stats.badblocks++;	return res;}/* * This function unregisters and destroy all slave MTD objects which are * attached to the given master MTD object. */int del_mtd_partitions(struct mtd_info *master){	struct mtd_part *slave, *next;	list_for_each_entry_safe(slave, next, &mtd_partitions, list)		if (slave->master == master) {			list_del(&slave->list);			if (slave->registered)				del_mtd_device(&slave->mtd);			kfree(slave);		}	return 0;}EXPORT_SYMBOL(del_mtd_partitions);static struct mtd_part *add_one_partition(struct mtd_info *master,		const struct mtd_partition *part, int partno,		u_int32_t cur_offset){	struct mtd_part *slave;	/* allocate the partition structure */	slave = kzalloc(sizeof(*slave), GFP_KERNEL);	if (!slave) {		printk(KERN_ERR"memory allocation error while creating partitions for \"%s\"\n",			master->name);		del_mtd_partitions(master);		return NULL;	}	list_add(&slave->list, &mtd_partitions);	/* set up the MTD object for this partition */	slave->mtd.type = master->type;	slave->mtd.flags = master->flags & ~part->mask_flags;	slave->mtd.size = part->size;	slave->mtd.writesize = master->writesize;	slave->mtd.oobsize = master->oobsize;	slave->mtd.oobavail = master->oobavail;	slave->mtd.subpage_sft = master->subpage_sft;	slave->mtd.name = part->name;	slave->mtd.owner = master->owner;	slave->mtd.read = part_read;	slave->mtd.write = part_write;	if (master->panic_write)		slave->mtd.panic_write = part_panic_write;	if (master->point && master->unpoint) {		slave->mtd.point = part_point;		slave->mtd.unpoint = part_unpoint;	}	if (master->read_oob)		slave->mtd.read_oob = part_read_oob;	if (master->write_oob)		slave->mtd.write_oob = part_write_oob;	if (master->read_user_prot_reg)		slave->mtd.read_user_prot_reg = part_read_user_prot_reg;	if (master->read_fact_prot_reg)		slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg;	if (master->write_user_prot_reg)		slave->mtd.write_user_prot_reg = part_write_user_prot_reg;	if (master->lock_user_prot_reg)		slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg;	if (master->get_user_prot_info)		slave->mtd.get_user_prot_info = part_get_user_prot_info;	if (master->get_fact_prot_info)		slave->mtd.get_fact_prot_info = part_get_fact_prot_info;	if (master->sync)		slave->mtd.sync = part_sync;	if (!partno && master->suspend && master->resume) {			slave->mtd.suspend = part_suspend;			slave->mtd.resume = part_resume;	}	if (master->writev)		slave->mtd.writev = part_writev;	if (master->lock)		slave->mtd.lock = part_lock;	if (master->unlock)		slave->mtd.unlock = part_unlock;	if (master->block_isbad)		slave->mtd.block_isbad = part_block_isbad;	if (master->block_markbad)		slave->mtd.block_markbad = part_block_markbad;	slave->mtd.erase = part_erase;	slave->master = master;	slave->offset = part->offset;	slave->index = partno;	if (slave->offset == MTDPART_OFS_APPEND)		slave->offset = cur_offset;	if (slave->offset == MTDPART_OFS_NXTBLK) {		slave->offset = cur_offset;		if ((cur_offset % master->erasesize) != 0) {			/* Round up to next erasesize */			slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize;			printk(KERN_NOTICE "Moving partition %d: "			       "0x%08x -> 0x%08x\n", partno,			       cur_offset, slave->offset);		}	}	if (slave->mtd.size == MTDPART_SIZ_FULL)		slave->mtd.size = master->size - slave->offset;	printk(KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset,		slave->offset + slave->mtd.size, slave->mtd.name);	/* let's do some sanity checks */	if (slave->offset >= master->size) {		/* let's register it anyway to preserve ordering */		slave->offset = 0;		slave->mtd.size = 0;		printk(KERN_ERR"mtd: partition \"%s\" is out of reach -- disabled\n",			part->name);		goto out_register;	}	if (slave->offset + slave->mtd.size > master->size) {		slave->mtd.size = master->size - slave->offset;		printk(KERN_WARNING"mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n",			part->name, master->name, slave->mtd.size);	}	if (master->numeraseregions > 1) {		/* Deal with variable erase size stuff */		int i, max = master->numeraseregions;		u32 end = slave->offset + slave->mtd.size;		struct mtd_erase_region_info *regions = master->eraseregions;		/* Find the first erase regions which is part of this		 * partition. */		for (i = 0; i < max && regions[i].offset <= slave->offset; i++)			;		/* The loop searched for the region _behind_ the first one */		i--;		/* Pick biggest erasesize */		for (; i < max && regions[i].offset < end; i++) {			if (slave->mtd.erasesize < regions[i].erasesize) {				slave->mtd.erasesize = regions[i].erasesize;			}		}		BUG_ON(slave->mtd.erasesize == 0);	} else {		/* Single erase size */		slave->mtd.erasesize = master->erasesize;	}	if ((slave->mtd.flags & MTD_WRITEABLE) &&	    (slave->offset % slave->mtd.erasesize)) {		/* Doesn't start on a boundary of major erase size */		/* FIXME: Let it be writable if it is on a boundary of		 * _minor_ erase size though */		slave->mtd.flags &= ~MTD_WRITEABLE;		printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",			part->name);	}	if ((slave->mtd.flags & MTD_WRITEABLE) &&	    (slave->mtd.size % slave->mtd.erasesize)) {		slave->mtd.flags &= ~MTD_WRITEABLE;		printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n",			part->name);	}	slave->mtd.ecclayout = master->ecclayout;	if (master->block_isbad) {		uint32_t offs = 0;		while (offs < slave->mtd.size) {			if (master->block_isbad(master,						offs + slave->offset))				slave->mtd.ecc_stats.badblocks++;			offs += slave->mtd.erasesize;		}	}out_register:	if (part->mtdp) {		/* store the object pointer (caller may or may not register it*/		*part->mtdp = &slave->mtd;		slave->registered = 0;	} else {		/* register our partition */		add_mtd_device(&slave->mtd);		slave->registered = 1;	}	return slave;}/* * This function, given a master MTD object and a partition table, creates * and registers slave MTD objects which are bound to the master according to * the partition definitions. * (Q: should we register the master MTD object as well?) */int add_mtd_partitions(struct mtd_info *master,		       const struct mtd_partition *parts,		       int nbparts){	struct mtd_part *slave;	u_int32_t cur_offset = 0;	int i;	printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);	for (i = 0; i < nbparts; i++) {		slave = add_one_partition(master, parts + i, i, cur_offset);		if (!slave)			return -ENOMEM;		cur_offset = slave->offset + slave->mtd.size;	}	return 0;}EXPORT_SYMBOL(add_mtd_partitions);static DEFINE_SPINLOCK(part_parser_lock);static LIST_HEAD(part_parsers);static struct mtd_part_parser *get_partition_parser(const char *name){	struct mtd_part_parser *p, *ret = NULL;	spin_lock(&part_parser_lock);	list_for_each_entry(p, &part_parsers, list)		if (!strcmp(p->name, name) && try_module_get(p->owner)) {			ret = p;			break;		}	spin_unlock(&part_parser_lock);	return ret;}int register_mtd_parser(struct mtd_part_parser *p){	spin_lock(&part_parser_lock);	list_add(&p->list, &part_parsers);	spin_unlock(&part_parser_lock);	return 0;}EXPORT_SYMBOL_GPL(register_mtd_parser);int deregister_mtd_parser(struct mtd_part_parser *p){	spin_lock(&part_parser_lock);	list_del(&p->list);	spin_unlock(&part_parser_lock);	return 0;}EXPORT_SYMBOL_GPL(deregister_mtd_parser);int parse_mtd_partitions(struct mtd_info *master, const char **types,			 struct mtd_partition **pparts, unsigned long origin){	struct mtd_part_parser *parser;	int ret = 0;	for ( ; ret <= 0 && *types; types++) {		parser = get_partition_parser(*types);		if (!parser && !request_module("%s", *types))				parser = get_partition_parser(*types);		if (!parser) {			printk(KERN_NOTICE "%s partition parsing not available\n",			       *types);			continue;		}		ret = (*parser->parse_fn)(master, pparts, origin);		if (ret > 0) {			printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",			       ret, parser->name, master->name);		}		put_partition_parser(parser);	}	return ret;}EXPORT_SYMBOL_GPL(parse_mtd_partitions);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -