--- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -30,11 +30,9 @@ #include #include #include -#include #include #include "mtdcore.h" -#include "mtdsplit/mtdsplit.h" #define MTD_ERASE_PARTIAL 0x8000 /* partition only covers parts of an erase block */ @@ -50,14 +48,13 @@ struct mtd_part { struct list_head list; }; -static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part); - /* * Given a pointer to the MTD object in the mtd_part structure, we can retrieve * the pointer to that structure with this macro. */ #define PART(x) ((struct mtd_part *)(x)) + /* * MTD methods which simply translate the effective address and pass through * to the _real_ device. @@ -521,12 +518,14 @@ static struct mtd_part *allocate_partiti if (slave->offset == MTDPART_OFS_APPEND) slave->offset = cur_offset; if (slave->offset == MTDPART_OFS_NXTBLK) { - /* Round up to next erasesize */ - slave->offset = mtd_roundup_to_eb(cur_offset, master); - if (slave->offset != cur_offset) + slave->offset = cur_offset; + if (mtd_mod_by_eb(cur_offset, master) != 0) { + /* Round up to next erasesize */ + slave->offset = (mtd_div_by_eb(cur_offset, master) + 1) * master->erasesize; printk(KERN_NOTICE "Moving partition %d: " "0x%012llx -> 0x%012llx\n", partno, (unsigned long long)cur_offset, (unsigned long long)slave->offset); + } } if (slave->offset == MTDPART_OFS_RETAIN) { slave->offset = cur_offset; @@ -627,10 +626,8 @@ out_register: return slave; } - -static int -__mtd_add_partition(struct mtd_info *master, const char *name, - long long offset, long long length, bool dup_check) +int mtd_add_partition(struct mtd_info *master, const char *name, + long long offset, long long length) { struct mtd_partition part; struct mtd_part *p, *new; @@ -662,24 +659,21 @@ __mtd_add_partition(struct mtd_info *mas end = offset + length; mutex_lock(&mtd_partitions_mutex); - if (dup_check) { - list_for_each_entry(p, &mtd_partitions, list) - if (p->master == master) { - if ((start >= p->offset) && - (start < (p->offset + p->mtd.size))) - goto err_inv; - - if ((end >= p->offset) && - (end < (p->offset + p->mtd.size))) - goto err_inv; - } - } + list_for_each_entry(p, &mtd_partitions, list) + if (p->master == master) { + if ((start >= p->offset) && + (start < (p->offset + p->mtd.size))) + goto err_inv; + + if ((end >= p->offset) && + (end < (p->offset + p->mtd.size))) + goto err_inv; + } list_add(&new->list, &mtd_partitions); mutex_unlock(&mtd_partitions_mutex); add_mtd_device(&new->mtd); - mtd_partition_split(master, new); return ret; err_inv: @@ -689,12 +683,6 @@ err_inv: } EXPORT_SYMBOL_GPL(mtd_add_partition); -int mtd_add_partition(struct mtd_info *master, const char *name, - long long offset, long long length) -{ - return __mtd_add_partition(master, name, offset, length, true); -} - int mtd_del_partition(struct mtd_info *master, int partno) { struct mtd_part *slave, *next; @@ -718,166 +706,6 @@ int mtd_del_partition(struct mtd_info *m } EXPORT_SYMBOL_GPL(mtd_del_partition); -static int -run_parsers_by_type(struct mtd_part *slave, enum mtd_parser_type type) -{ - struct mtd_partition *parts; - int nr_parts; - int i; - - nr_parts = parse_mtd_partitions_by_type(&slave->mtd, type, &parts, - NULL); - if (nr_parts <= 0) - return nr_parts; - - if (WARN_ON(!parts)) - return 0; - - for (i = 0; i < nr_parts; i++) { - /* adjust partition offsets */ - parts[i].offset += slave->offset; - - __mtd_add_partition(slave->master, - parts[i].name, - parts[i].offset, - parts[i].size, - false); - } - - kfree(parts); - - return nr_parts; -} - -static inline unsigned long -mtd_pad_erasesize(struct mtd_info *mtd, int offset, int len) -{ - unsigned long mask = mtd->erasesize - 1; - - len += offset & mask; - len = (len + mask) & ~mask; - len -= offset & mask; - return len; -} - -static int split_squashfs(struct mtd_info *master, int offset, int *split_offset) -{ - size_t squashfs_len; - int len, ret; - - ret = mtd_get_squashfs_len(master, offset, &squashfs_len); - if (ret) - return ret; - - len = mtd_pad_erasesize(master, offset, squashfs_len); - *split_offset = offset + len; - - return 0; -} - -static void split_rootfs_data(struct mtd_info *master, struct mtd_part *part) -{ - unsigned int split_offset = 0; - unsigned int split_size; - int ret; - - ret = split_squashfs(master, part->offset, &split_offset); - if (ret) - return; - - if (split_offset <= 0) - return; - - if (config_enabled(CONFIG_MTD_SPLIT_SQUASHFS_ROOT)) - pr_err("Dedicated partitioner didn't create \"rootfs_data\" partition, please fill a bug report!\n"); - else - pr_warn("Support for built-in \"rootfs_data\" splitter will be removed, please use CONFIG_MTD_SPLIT_SQUASHFS_ROOT\n"); - - split_size = part->mtd.size - (split_offset - part->offset); - printk(KERN_INFO "mtd: partition \"%s\" created automatically, ofs=0x%x, len=0x%x\n", - ROOTFS_SPLIT_NAME, split_offset, split_size); - - __mtd_add_partition(master, ROOTFS_SPLIT_NAME, split_offset, - split_size, false); -} - -#define UBOOT_MAGIC 0x27051956 - -static void split_uimage(struct mtd_info *master, struct mtd_part *part) -{ - struct { - __be32 magic; - __be32 pad[2]; - __be32 size; - } hdr; - size_t len; - - if (mtd_read(master, part->offset, sizeof(hdr), &len, (void *) &hdr)) - return; - - if (len != sizeof(hdr) || hdr.magic != cpu_to_be32(UBOOT_MAGIC)) - return; - - len = be32_to_cpu(hdr.size) + 0x40; - len = mtd_pad_erasesize(master, part->offset, len); - if (len + master->erasesize > part->mtd.size) - return; - - if (config_enabled(CONFIG_MTD_SPLIT_UIMAGE_FW)) - pr_err("Dedicated partitioner didn't split firmware partition, please fill a bug report!\n"); - else - pr_warn("Support for built-in firmware splitter will be removed, please use CONFIG_MTD_SPLIT_UIMAGE_FW\n"); - - __mtd_add_partition(master, "rootfs", part->offset + len, - part->mtd.size - len, false); -} - -#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME -#define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME -#else -#define SPLIT_FIRMWARE_NAME "unused" -#endif - -static void split_firmware(struct mtd_info *master, struct mtd_part *part) -{ - int ret; - - ret = run_parsers_by_type(part, MTD_PARSER_TYPE_FIRMWARE); - if (ret > 0) - return; - - if (config_enabled(CONFIG_MTD_UIMAGE_SPLIT)) - split_uimage(master, part); -} - -void __weak arch_split_mtd_part(struct mtd_info *master, const char *name, - int offset, int size) -{ -} - -static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part) -{ - static int rootfs_found = 0; - - if (rootfs_found) - return; - - if (!strcmp(part->mtd.name, "rootfs")) { - int num = run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS); - - if (num <= 0 && config_enabled(CONFIG_MTD_ROOTFS_SPLIT)) - split_rootfs_data(master, part); - - rootfs_found = 1; - } - - if (!strcmp(part->mtd.name, SPLIT_FIRMWARE_NAME) && - config_enabled(CONFIG_MTD_SPLIT_FIRMWARE)) - split_firmware(master, part); - - arch_split_mtd_part(master, part->mtd.name, part->offset, - part->mtd.size); -} /* * 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 @@ -907,7 +735,6 @@ int add_mtd_partitions(struct mtd_info * mutex_unlock(&mtd_partitions_mutex); add_mtd_device(&slave->mtd); - mtd_partition_split(master, slave); cur_offset = slave->offset + slave->mtd.size; } @@ -937,30 +764,6 @@ static struct mtd_part_parser *get_parti #define put_partition_parser(p) do { module_put((p)->owner); } while (0) -static struct mtd_part_parser * -get_partition_parser_by_type(enum mtd_parser_type type, - struct mtd_part_parser *start) -{ - struct mtd_part_parser *p, *ret = NULL; - - spin_lock(&part_parser_lock); - - p = list_prepare_entry(start, &part_parsers, list); - if (start) - put_partition_parser(start); - - list_for_each_entry_continue(p, &part_parsers, list) { - if (p->type == type && try_module_get(p->owner)) { - ret = p; - break; - } - } - - spin_unlock(&part_parser_lock); - - return ret; -} - void register_mtd_parser(struct mtd_part_parser *p) { spin_lock(&part_parser_lock); @@ -1076,38 +879,6 @@ int parse_mtd_partitions(struct mtd_info return ret; } -int parse_mtd_partitions_by_type(struct mtd_info *master, - enum mtd_parser_type type, - struct mtd_partition **pparts, - struct mtd_part_parser_data *data) -{ - struct mtd_part_parser *prev = NULL; - int ret = 0; - - while (1) { - struct mtd_part_parser *parser; - - parser = get_partition_parser_by_type(type, prev); - if (!parser) - break; - - ret = (*parser->parse_fn)(master, pparts, data); - - if (ret > 0) { - put_partition_parser(parser); - printk(KERN_NOTICE - "%d %s partitions found on MTD device %s\n", - ret, parser->name, master->name); - break; - } - - prev = parser; - } - - return ret; -} -EXPORT_SYMBOL_GPL(parse_mtd_partitions_by_type); - int mtd_is_partition(const struct mtd_info *mtd) { struct mtd_part *part;