X-Git-Url: https://git.kernelconcepts.de/?a=blobdiff_plain;f=common%2Fcmd_jffs2.c;h=513a226c43113db0aea70df980b7464859883237;hb=636400198228d96983c06657b17f760f5989958e;hp=7f5ebf90ebc23d58ced0a52d372adc306a0c7d36;hpb=c4e0e6860429da7fd7a53b8c1d7026a449e78bf1;p=karo-tx-uboot.git diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c index 7f5ebf90eb..513a226c43 100644 --- a/common/cmd_jffs2.c +++ b/common/cmd_jffs2.c @@ -45,7 +45,7 @@ * partition := * := ,part_num * - * + * * 'mtdids' - linux kernel mtd device id <-> u-boot device id mapping * * mtdids=[,,...] @@ -91,19 +91,26 @@ #include #include #include -#include #include #include -#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) +#if defined(CONFIG_CMD_JFFS2) #include +#if defined(CONFIG_CMD_NAND) +#ifdef CFG_NAND_LEGACY +#include +#else /* !CFG_NAND_LEGACY */ +#include +#include +#endif /* !CFG_NAND_LEGACY */ +#endif /* enable/disable debugging messages */ -#define DEBUG -#undef DEBUG +#define DEBUG_JFFS +#undef DEBUG_JFFS -#ifdef DEBUG +#ifdef DEBUG_JFFS # define DEBUGF(fmt, args...) printf(fmt ,##args) #else # define DEBUGF(fmt, args...) @@ -123,7 +130,7 @@ /* this flag needs to be set in part_info struct mask_flags * field for read-only partitions */ -#define MTD_WRITEABLE 1 +#define MTD_WRITEABLE_CMD 1 #ifdef CONFIG_JFFS2_CMDLINE /* default values for mtdids and mtdparts variables */ @@ -237,6 +244,46 @@ static void memsize_format(char *buf, u32 size) sprintf(buf, "%lu", size); } +/** + * This routine does global indexing of all partitions. Resulting index for + * current partition is saved in 'mtddevnum'. Current partition name in + * 'mtddevname'. + */ +static void index_partitions(void) +{ + char buf[16]; + u16 mtddevnum; + struct part_info *part; + struct list_head *dentry; + struct mtd_device *dev; + + DEBUGF("--- index partitions ---\n"); + + if (current_dev) { + mtddevnum = 0; + list_for_each(dentry, &devices) { + dev = list_entry(dentry, struct mtd_device, link); + if (dev == current_dev) { + mtddevnum += current_partnum; + sprintf(buf, "%d", mtddevnum); + setenv("mtddevnum", buf); + break; + } + mtddevnum += dev->num_parts; + } + + part = jffs2_part_info(current_dev, current_partnum); + setenv("mtddevname", part->name); + + DEBUGF("=> mtddevnum %d,\n=> mtddevname %s\n", mtddevnum, part->name); + } else { + setenv("mtddevnum", NULL); + setenv("mtddevname", NULL); + + DEBUGF("=> mtddevnum NULL\n=> mtddevname NULL\n"); + } +} + /** * Save current device and partition in environment variable 'partition'. */ @@ -260,6 +307,7 @@ static void current_save(void) DEBUGF("=> partition NULL\n"); } + index_partitions(); } /** @@ -273,9 +321,9 @@ static void current_save(void) */ static int part_validate_nor(struct mtdids *id, struct part_info *part) { -#if (CONFIG_COMMANDS & CFG_CMD_FLASH) +#if defined(CONFIG_CMD_FLASH) /* info for FLASH chips */ - extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + extern flash_info_t flash_info[]; flash_info_t *flash; int offset_aligned; u32 end_offset; @@ -322,12 +370,11 @@ static int part_validate_nor(struct mtdids *id, struct part_info *part) */ static int part_validate_nand(struct mtdids *id, struct part_info *part) { -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) +#if defined(CONFIG_JFFS2_NAND) && defined(CONFIG_CMD_NAND) /* info for NAND chips */ - extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; - struct nand_chip *nand; + nand_info_t *nand; - nand = &nand_dev_desc[id->num]; + nand = &nand_info[id->num]; if ((unsigned long)(part->offset) % nand->erasesize) { printf("%s%d: partition (%s) start offset alignment incorrect\n", @@ -398,12 +445,14 @@ static int part_validate(struct mtdids *id, struct part_info *part) */ static int part_del(struct mtd_device *dev, struct part_info *part) { + u8 current_save_needed = 0; + /* if there is only one partition, remove whole device */ if (dev->num_parts == 1) return device_del(dev); /* otherwise just delete this partition */ - + if (dev == current_dev) { /* we are modyfing partitions for the current device, * update current */ @@ -414,20 +463,25 @@ static int part_del(struct mtd_device *dev, struct part_info *part) if (curr_pi == part) { printf("current partition deleted, resetting current to 0\n"); current_partnum = 0; - current_save(); } else if (part->offset <= curr_pi->offset) { - current_partnum--; - current_save(); + current_partnum--; } + current_save_needed = 1; } } - +#ifdef CFG_NAND_LEGACY jffs2_free_cache(part); +#endif list_del(&part->link); free(part); dev->num_parts--; + if (current_save_needed > 0) + current_save(); + else + index_partitions(); + return 0; } @@ -445,7 +499,9 @@ static void part_delall(struct list_head *head) list_for_each_safe(entry, n, head) { part_tmp = list_entry(entry, struct part_info, link); +#ifdef CFG_NAND_LEGACY jffs2_free_cache(part_tmp); +#endif list_del(entry); free(part_tmp); } @@ -469,9 +525,11 @@ static int part_sort_add(struct mtd_device *dev, struct part_info *part) if (list_empty(&dev->parts)) { DEBUGF("part_sort_add: list empty\n"); list_add(&part->link, &dev->parts); + dev->num_parts++; + index_partitions(); return 0; } - + new_pi = list_entry(&part->link, struct part_info, link); /* get current partition info if we are updating current device */ @@ -492,18 +550,23 @@ static int part_sort_add(struct mtd_device *dev, struct part_info *part) if (new_pi->offset <= pi->offset) { list_add_tail(&part->link, entry); - + dev->num_parts++; + if (curr_pi && (pi->offset <= curr_pi->offset)) { /* we are modyfing partitions for the current * device, update current */ current_partnum++; current_save(); + } else { + index_partitions(); } - return 0; } } + list_add_tail(&part->link, &dev->parts); + dev->num_parts++; + index_partitions(); return 0; } @@ -516,7 +579,7 @@ static int part_sort_add(struct mtd_device *dev, struct part_info *part) */ static int part_add(struct mtd_device *dev, struct part_info *part) { - /* verify alignment and size */ + /* verify alignment and size */ if (part_validate(dev->id, part) != 0) return 1; @@ -524,7 +587,6 @@ static int part_add(struct mtd_device *dev, struct part_info *part) if (part_sort_add(dev, part) != 0) return 1; - dev->num_parts++; return 0; } @@ -565,14 +627,14 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i } } - /* check for offset */ + /* check for offset */ offset = OFFSET_NOT_SPECIFIED; if (*p == '@') { p++; offset = memsize_parse(p, &p); } - /* now look for the name */ + /* now look for the name */ if (*p == '(') { name = ++p; if ((p = strchr(name, ')')) == NULL) { @@ -591,10 +653,10 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i name = NULL; } - /* test for options */ + /* test for options */ mask_flags = 0; if (strncmp(p, "ro", 2) == 0) { - mask_flags |= MTD_WRITEABLE; + mask_flags |= MTD_WRITEABLE_CMD; p += 2; } @@ -657,10 +719,11 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i static int device_validate(u8 type, u8 num, u32 *size) { if (type == MTD_DEV_TYPE_NOR) { -#if (CONFIG_COMMANDS & CFG_CMD_FLASH) +#if defined(CONFIG_CMD_FLASH) if (num < CFG_MAX_FLASH_BANKS) { - extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + extern flash_info_t flash_info[]; *size = flash_info[num].size; + return 0; } @@ -670,10 +733,14 @@ static int device_validate(u8 type, u8 num, u32 *size) printf("support for FLASH devices not present\n"); #endif } else if (type == MTD_DEV_TYPE_NAND) { -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) +#if defined(CONFIG_JFFS2_NAND) && defined(CONFIG_CMD_NAND) if (num < CFG_MAX_NAND_DEVICE) { +#ifndef CFG_NAND_LEGACY + *size = nand_info[num].size; +#else extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; *size = nand_dev_desc[num].totlen; +#endif return 0; } @@ -735,9 +802,10 @@ static int device_del(struct mtd_device *dev) current_partnum = 0; } current_save(); + return 0; } - + index_partitions(); return 0; } @@ -771,13 +839,20 @@ static struct mtd_device* device_find(u8 type, u8 num) */ static void device_add(struct mtd_device *dev) { + u8 current_save_needed = 0; + if (list_empty(&devices)) { current_dev = dev; current_partnum = 0; - current_save(); + current_save_needed = 1; } list_add_tail(&dev->link, &devices); + + if (current_save_needed > 0) + current_save(); + else + index_partitions(); } /** @@ -823,8 +898,8 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_ printf("invalid mtd device '%.*s'\n", mtd_id_len - 1, mtd_id); return 1; } - - DEBUGF("dev type = %d (%s), dev num = %d, mtd-id = %s\n", + + DEBUGF("dev type = %d (%s), dev num = %d, mtd-id = %s\n", id->type, MTD_DEV_TYPE(id->type), id->num, id->mtd_id); pend = strchr(p, ';'); @@ -836,7 +911,7 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_ offset = 0; if ((dev = device_find(id->type, id->num)) != NULL) { - /* if device already exists start at the end of the last partition */ + /* if device already exists start at the end of the last partition */ part = list_entry(dev->parts.prev, struct part_info, link); offset = part->offset + part->size; } @@ -852,7 +927,7 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_ else offset = part->offset; - /* verify alignment and size */ + /* verify alignment and size */ if (part_validate(id, part) != 0) break; @@ -885,7 +960,7 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_ } else { printf("unexpected character '%c' at the end of device\n", *p); *ret = NULL; - return 1; + return 1; } } @@ -896,7 +971,7 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_ } memset(dev, 0, sizeof(struct mtd_device)); dev->id = id; - dev->num_parts = num_parts; + dev->num_parts = 0; /* part_sort_add increments num_parts */ INIT_LIST_HEAD(&dev->parts); INIT_LIST_HEAD(&dev->link); @@ -939,7 +1014,7 @@ static struct mtdids* id_find(u8 type, u8 num) { struct list_head *entry; struct mtdids *id; - + list_for_each(entry, &mtdids) { id = list_entry(entry, struct mtdids, link); @@ -951,7 +1026,7 @@ static struct mtdids* id_find(u8 type, u8 num) } /** - * Search global mtdids list and find id of a requested mtd_id. + * Search global mtdids list and find id of a requested mtd_id. * * Note: first argument is not null terminated. * @@ -963,7 +1038,7 @@ static struct mtdids* id_find_by_mtd_id(const char *mtd_id, unsigned int mtd_id_ { struct list_head *entry; struct mtdids *id; - + DEBUGF("--- id_find_by_mtd_id: '%.*s' (len = %d)\n", mtd_id_len, mtd_id, mtd_id_len); @@ -1045,13 +1120,13 @@ static int generate_mtdparts(char *buf, u32 buflen) buf[0] = '\0'; return 0; } - + sprintf(p, "mtdparts="); p += 9; list_for_each(dentry, &devices) { dev = list_entry(dentry, struct mtd_device, link); - + /* copy mtd_id */ len = strlen(dev->id->mtd_id) + 1; if (len > maxlen) @@ -1078,8 +1153,8 @@ static int generate_mtdparts(char *buf, u32 buflen) memcpy(p, tmpbuf, len); p += len; maxlen -= len; - - + + /* add offset only when there is a gap between * partitions */ if ((!prev_part && (offset != 0)) || @@ -1107,9 +1182,9 @@ static int generate_mtdparts(char *buf, u32 buflen) *(p++) = ')'; maxlen -= len; } - + /* ro mask flag */ - if (part->mask_flags && MTD_WRITEABLE) { + if (part->mask_flags && MTD_WRITEABLE_CMD) { len = 2; if (len > maxlen) goto cleanup; @@ -1188,12 +1263,12 @@ static void list_partitions(void) MTD_DEV_TYPE(dev->id->type), dev->id->num, dev->id->mtd_id, dev->num_parts); printf(" #: name\t\t\tsize\t\toffset\t\tmask_flags\n"); - + /* list partitions for given device */ part_num = 0; list_for_each(pentry, &dev->parts) { part = list_entry(pentry, struct part_info, link); - printf(" %d: %-22s\t0x%08x\t0x%08x\t%d\n", + printf("%2d: %-20s0x%08x\t0x%08x\t%d\n", part_num, part->name, part->size, part->offset, part->mask_flags); @@ -1225,7 +1300,7 @@ static void list_partitions(void) * Given partition identifier in form of , find * corresponding device and verify partition number. * - * @param id string describing device and partition + * @param id string describing device and partition or partition name * @param dev pointer to the requested device (output) * @param part_num verified partition number (output) * @param part pointer to requested partition (output) @@ -1234,11 +1309,23 @@ static void list_partitions(void) int find_dev_and_part(const char *id, struct mtd_device **dev, u8 *part_num, struct part_info **part) { + struct list_head *dentry, *pentry; u8 type, dnum, pnum; const char *p; DEBUGF("--- find_dev_and_part ---\nid = %s\n", id); + list_for_each(dentry, &devices) { + *part_num = 0; + *dev = list_entry(dentry, struct mtd_device, link); + list_for_each(pentry, &(*dev)->parts) { + *part = list_entry(pentry, struct part_info, link); + if (strcmp((*part)->name, id) == 0) + return 0; + (*part_num)++; + } + } + p = id; *dev = NULL; *part = NULL; @@ -1256,7 +1343,7 @@ int find_dev_and_part(const char *id, struct mtd_device **dev, printf("unexpected trailing character '%c'\n", *p); return 1; } - + if ((*dev = device_find(type, dnum)) == NULL) { printf("no such device %s%d\n", MTD_DEV_TYPE(type), dnum); return 1; @@ -1328,7 +1415,7 @@ static int parse_mtdparts(const char *const mtdparts) /* re-read 'mtdparts' variable, devices_init may be updating env */ p = getenv("mtdparts"); - + if (strncmp(p, "mtdparts=", 9) != 0) { printf("mtdparts variable doesn't start with 'mtdparts='\n"); return err; @@ -1548,7 +1635,7 @@ int mtdparts_init(void) ids_changed = 1; if (parse_mtdids(ids) != 0) { - device_delall(&devices); + devices_init(); return 1; } @@ -1615,7 +1702,7 @@ int mtdparts_init(void) /** * Parse and initialize global mtdids mapping and create global - * device/partition list. + * device/partition list. * * @return 0 on success, 1 otherwise */ @@ -1810,7 +1897,7 @@ int do_jffs2_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return !(size > 0); } - return 0; + return 1; } /** @@ -1846,9 +1933,9 @@ int do_jffs2_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ret = jffs2_1pass_ls(part, filename); } - return (ret == 1); + return ret ? 0 : 1; } - return 0; + return 1; } /** @@ -1870,7 +1957,7 @@ int do_jffs2_fsinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /* make sure we are in sync with env variables */ if (mtdparts_init() !=0) return 1; - + if ((part = jffs2_part_info(current_dev, current_partnum))){ /* check partition type for cramfs */ @@ -1884,9 +1971,9 @@ int do_jffs2_fsinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ret = jffs2_1pass_info(part); } - return (ret == 1); + return ret ? 0 : 1; } - return 0; + return 1; } /* command line only */ @@ -1968,7 +2055,7 @@ int do_jffs2_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) list_partitions(); return 0; } - + /* mtdparts add [@] [ro] */ if (((argc == 5) || (argc == 6)) && (strcmp(argv[1], "add") == 0)) { #define PART_ADD_DESC_MAXLEN 64 @@ -1998,7 +2085,7 @@ int do_jffs2_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } sprintf(tmpbuf, "%s:%s(%s)%s", - id->mtd_id, argv[3], argv[4], argv[5] ? argv[5] : ""); + id->mtd_id, argv[3], argv[4], argv[5] ? argv[5] : ""); DEBUGF("add tmpbuf: %s\n", tmpbuf); if ((device_parse(tmpbuf, NULL, &dev) != 0) || (!dev)) @@ -2105,4 +2192,4 @@ U_BOOT_CMD( /***************************************************/ -#endif /* CFG_CMD_JFFS2 */ +#endif