X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-uboot.git;a=blobdiff_plain;f=common%2Fcmd_mtdparts.c;h=a2289df4f64c60228d76c05eb56a1956502bebbf;hp=17865b756b4c3ec1244904bb2c50d0b750f4ca2b;hb=f82ac7d1607465fdaacf007f79e88aebe91b8731;hpb=59a50d2de1f9c037166a6f86e6e6cdc1670aa155 diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c index 17865b756b..a2289df4f6 100644 --- a/common/cmd_mtdparts.c +++ b/common/cmd_mtdparts.c @@ -21,23 +21,7 @@ * $Id: cmdlinepart.c,v 1.17 2004/11/26 11:18:47 lavinen Exp $ * Copyright 2002 SYSGO Real-Time Solutions GmbH * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0+ */ /* @@ -106,6 +90,8 @@ #include #endif +DECLARE_GLOBAL_DATA_PTR; + /* special size referring to all the remaining space in a partition */ #define SIZE_REMAINING 0xFFFFFFFF @@ -147,10 +133,10 @@ static char last_partition[PARTITION_MAXLEN]; extern void jffs2_free_cache(struct part_info *part); /* mtdids mapping list, filled by parse_ids() */ -struct list_head mtdids; +static struct list_head mtdids; /* device/partition list, parse_cmdline() parses into here */ -struct list_head devices; +static struct list_head devices; /* current active device and partition number */ struct mtd_device *current_mtd_dev = NULL; @@ -230,7 +216,6 @@ static void memsize_format(char *buf, u32 size) */ static void index_partitions(void) { - char buf[16]; u16 mtddevnum; struct part_info *part; struct list_head *dentry; @@ -244,8 +229,7 @@ static void index_partitions(void) dev = list_entry(dentry, struct mtd_device, link); if (dev == current_mtd_dev) { mtddevnum += current_mtd_partnum; - sprintf(buf, "%d", mtddevnum); - setenv("mtddevnum", buf); + setenv_ulong("mtddevnum", mtddevnum); break; } mtddevnum += dev->num_parts; @@ -338,8 +322,7 @@ static int part_validate_eraseblock(struct mtdids *id, struct part_info *part) * checking for alignment is easy here */ if ((unsigned long)part->offset % mtd->erasesize) { - printf("%s%d: partition (%s) start offset" - "alignment incorrect\n", + printf("%s%d: partition (%s) start offset alignment incorrect\n", MTD_DEV_TYPE(id->type), id->num, part->name); return 1; } @@ -710,7 +693,7 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i * @param size a pointer to the size of the mtd device (output) * @return 0 if device is valid, 1 otherwise */ -int mtd_device_validate(u8 type, u8 num, u32 *size) +static int mtd_device_validate(u8 type, u8 num, u32 *size) { struct mtd_info *mtd = NULL; @@ -838,7 +821,8 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_ struct mtdids *id; const char *mtd_id; unsigned int mtd_id_len; - const char *p, *pend; + const char *p; + const char *pend; LIST_HEAD(tmp_list); struct list_head *entry, *n; u16 num_parts; @@ -868,10 +852,12 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_ return 1; } +#ifdef DEBUG + pend = strchr(p, ';'); +#endif debug("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, ';'); debug("parsing partitions %.*s\n", (pend ? pend - p : strlen(p)), p); @@ -1039,7 +1025,8 @@ static struct mtdids* id_find_by_mtd_id(const char *mtd_id, unsigned int mtd_id_ * @param dev_num parsed device number (output) * @return 0 on success, 1 otherwise */ -int mtd_id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num) +int mtd_id_parse(const char *id, const char **ret_id, u8 *dev_type, + u8 *dev_num) { const char *p = id; @@ -1228,19 +1215,32 @@ static int generate_mtdparts_save(char *buf, u32 buflen) */ static uint64_t net_part_size(struct mtd_info *mtd, struct part_info *part) { + uint64_t i, net_size = 0; + if (!mtd->block_isbad) return part->size; - uint64_t i, net_size = 0; - for (i = 0; i < part->size; i += mtd->erasesize) { if (!mtd->block_isbad(mtd, part->offset + i)) net_size += mtd->erasesize; } + return net_size; } #endif +static void show_ecc_stats(struct mtd_device *dev) +{ + struct mtd_info *mtd; + + if (get_mtd_info(dev->id->type, dev->id->num, &mtd)) + return; + + printf("ECC stats for device %s:\n", mtd->name); + printf(" corrected bit flips:\t%4u\n", mtd->ecc_stats.corrected); + printf(" uncorrectable errors:\t%4u\n", mtd->ecc_stats.failed); +} + static void print_partition_table(void) { struct list_head *dentry, *pentry; @@ -1288,6 +1288,7 @@ static void print_partition_table(void) #endif /* defined(CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES) */ part_num++; } + show_ecc_stats(dev); } if (list_empty(&devices)) @@ -1417,7 +1418,7 @@ static int delete_partition(const char *id) return 1; if (generate_mtdparts_save(last_parts, MTDPARTS_MAXLEN) != 0) { - printf("generated mtdparts too long, reseting to null\n"); + printf("generated mtdparts too long, resetting to null\n"); return 1; } return 0; @@ -1515,7 +1516,7 @@ static int spread_partitions(void) index_partitions(); if (generate_mtdparts_save(last_parts, MTDPARTS_MAXLEN) != 0) { - printf("generated mtdparts too long, reseting to null\n"); + printf("generated mtdparts too long, resetting to null\n"); return 1; } return 0; @@ -1534,6 +1535,7 @@ static int parse_mtdparts(const char *const mtdparts) const char *p = mtdparts; struct mtd_device *dev; int err = 1; + char tmp_parts[MTDPARTS_MAXLEN]; debug("\n---parse_mtdparts---\nmtdparts = %s\n\n", p); @@ -1544,7 +1546,12 @@ static int parse_mtdparts(const char *const mtdparts) } /* re-read 'mtdparts' variable, mtd_devices_init may be updating env */ - p = getenv("mtdparts"); + if (gd->flags & GD_FLG_ENV_READY) { + p = getenv("mtdparts"); + } else { + p = tmp_parts; + getenv_f("mtdparts", tmp_parts, MTDPARTS_MAXLEN); + } if (strncmp(p, "mtdparts=", 9) != 0) { printf("mtdparts variable doesn't start with 'mtdparts='\n"); @@ -1702,6 +1709,7 @@ int mtdparts_init(void) const char *current_partition; int ids_changed; char tmp_ep[PARTITION_MAXLEN]; + char tmp_parts[MTDPARTS_MAXLEN]; debug("\n---mtdparts_init---\n"); if (!initialized) { @@ -1715,7 +1723,17 @@ int mtdparts_init(void) /* get variables */ ids = getenv("mtdids"); - parts = getenv("mtdparts"); + /* + * The mtdparts variable tends to be long. If we need to access it + * before the env is relocated, then we need to use our own stack + * buffer. gd->env_buf will be too small. + */ + if (gd->flags & GD_FLG_ENV_READY) { + parts = getenv("mtdparts"); + } else { + parts = tmp_parts; + getenv_f("mtdparts", tmp_parts, MTDPARTS_MAXLEN); + } current_partition = getenv("partition"); /* save it for later parsing, cannot rely on current partition pointer @@ -1880,7 +1898,7 @@ static struct part_info* mtd_part_info(struct mtd_device *dev, unsigned int part * @param argv arguments list * @return 0 on success, 1 otherwise */ -int do_chpart(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_chpart(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { /* command line only */ struct mtd_device *dev; @@ -1918,7 +1936,8 @@ int do_chpart(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * @param argv arguments list * @return 0 on success, 1 otherwise */ -int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) { if (argc == 2) { if (strcmp(argv[1], "default") == 0) { @@ -2012,7 +2031,7 @@ int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } if (generate_mtdparts_save(last_parts, MTDPARTS_MAXLEN) != 0) { - printf("generated mtdparts too long, reseting to null\n"); + printf("generated mtdparts too long, resetting to null\n"); return 1; } @@ -2031,7 +2050,7 @@ int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return spread_partitions(); #endif /* CONFIG_CMD_MTDPARTS_SPREAD */ - return cmd_usage(cmdtp); + return CMD_RET_USAGE; } /***************************************************/ @@ -2042,9 +2061,8 @@ U_BOOT_CMD( " - change active partition (e.g. part-id = nand0,1)" ); -U_BOOT_CMD( - mtdparts, 6, 0, do_mtdparts, - "define flash/nand partitions", +#ifdef CONFIG_SYS_LONGHELP +static char mtdparts_help_text[] = "\n" " - list partition table\n" "mtdparts delall\n" @@ -2086,6 +2104,11 @@ U_BOOT_CMD( " := standard linux memsize OR '-' to denote all remaining space\n" " := partition start offset within the device\n" " := '(' NAME ')'\n" - " := when set to 'ro' makes partition read-only (not used, passed to kernel)" + " := when set to 'ro' makes partition read-only (not used, passed to kernel)"; +#endif + +U_BOOT_CMD( + mtdparts, 6, 0, do_mtdparts, + "define flash/nand partitions", mtdparts_help_text ); /***************************************************/