Lines Matching +full:part +full:- +full:number
1 // SPDX-License-Identifier: GPL-2.0+
10 * Kai-Uwe Bloem, Auerswald GmbH & Co KG, <linux-development@auerswald.de>
23 * Copyright 2002 SYSGO Real-Time Solutions GmbH
29 * 'partition' - keeps current partition identifier
31 * partition := <part-id>
32 * <part-id> := <dev-id>,part_num
35 * 'mtdids' - linux kernel mtd device id <-> u-boot device id mapping
39 * <idmap> := <dev-id>=<mtd-id>
40 * <dev-id> := 'nand'|'nor'|'onenand'|'spi-nand'<dev-num>
41 * <dev-num> := mtd device number, 0...
42 * <mtd-id> := unique device tag used by linux kernel to find mtd device (mtd->name)
45 * 'mtdparts' - partition list
47 * mtdparts=[mtdparts=]<mtd-def>[;<mtd-def>...]
49 * <mtd-def> := <mtd-id>:<part-def>[,<part-def>...]
50 * <mtd-id> := unique device tag used by linux kernel to find mtd device (mtd->name)
51 * <part-def> := <size>[@<offset>][<name>][<ro-flag>]
52 * <size> := standard linux memsize OR '-' to denote all remaining space
55 * <ro-flag> := when set to 'ro' makes partition read-only (not used, passed to kernel)
58 * - each <mtd-id> used in mtdparts must albo exist in 'mtddis' mapping
59 * - if the above variables are not set defaults for a given target are used
64 * mtdids=nor0=edb7312-nor
65 * mtdparts=[mtdparts=]edb7312-nor:-
68 * mtdids=nor0=edb7312-nor,nand0=edb7312-nand
69 * mtdparts=[mtdparts=]edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home)
107 * field for read-only partitions */
140 extern void jffs2_free_cache(struct part_info *part);
148 /* current active device and partition number */
161 * Parses a string into a number. The number stored at ptr is
164 * 1073741824). If the number is suffixed with K, M, or G, then
165 * the return value is the number multiplied by one kilobyte, one
232 struct part_info *part; in index_partitions() local
236 debug("--- index partitions ---\n"); in index_partitions()
248 mtddevnum += dev->num_parts; in index_partitions()
251 part = mtd_part_info(current_mtd_dev, current_mtd_partnum); in index_partitions()
252 if (part) { in index_partitions()
253 env_set("mtddevname", part->name); in index_partitions()
255 debug("=> mtddevname %s\n", part->name); in index_partitions()
276 debug("--- current_save ---\n"); in current_save()
279 sprintf(buf, "%s%d,%d", MTD_DEV_TYPE(current_mtd_dev->id->type), in current_save()
280 current_mtd_dev->id->num, current_mtd_partnum); in current_save()
300 * @param num mtd number
325 * @param part partition to validate
328 static int part_validate_eraseblock(struct mtdids *id, struct part_info *part) in part_validate_eraseblock() argument
335 if (get_mtd_info(id->type, id->num, &mtd)) in part_validate_eraseblock()
338 part->sector_size = mtd->erasesize; in part_validate_eraseblock()
340 if (!mtd->numeraseregions) { in part_validate_eraseblock()
342 * Only one eraseregion (NAND, SPI-NAND, OneNAND or uniform NOR), in part_validate_eraseblock()
345 offset = part->offset; in part_validate_eraseblock()
346 if (do_div(offset, mtd->erasesize)) { in part_validate_eraseblock()
349 MTD_DEV_TYPE(id->type), id->num, part->name); in part_validate_eraseblock()
353 size = part->size; in part_validate_eraseblock()
354 if (do_div(size, mtd->erasesize)) { in part_validate_eraseblock()
356 MTD_DEV_TYPE(id->type), id->num, part->name); in part_validate_eraseblock()
361 * Multiple eraseregions (non-uniform NOR), in part_validate_eraseblock()
366 for (i = 0; i < mtd->numeraseregions; i++) { in part_validate_eraseblock()
367 start = mtd->eraseregions[i].offset; in part_validate_eraseblock()
368 for (j = 0; j < mtd->eraseregions[i].numblocks; j++) { in part_validate_eraseblock()
369 if (part->offset == start) in part_validate_eraseblock()
371 start += mtd->eraseregions[i].erasesize; in part_validate_eraseblock()
376 MTD_DEV_TYPE(id->type), id->num, part->name); in part_validate_eraseblock()
382 for (i = 0; i < mtd->numeraseregions; i++) { in part_validate_eraseblock()
383 start = mtd->eraseregions[i].offset; in part_validate_eraseblock()
384 for (j = 0; j < mtd->eraseregions[i].numblocks; j++) { in part_validate_eraseblock()
385 if ((part->offset + part->size) == start) in part_validate_eraseblock()
387 start += mtd->eraseregions[i].erasesize; in part_validate_eraseblock()
391 if ((part->offset + part->size) == start) in part_validate_eraseblock()
395 MTD_DEV_TYPE(id->type), id->num, part->name); in part_validate_eraseblock()
409 * part_validate_eraseblock() is called with the argument of part.
412 * @param part partition to validate
415 static int part_validate(struct mtdids *id, struct part_info *part) in part_validate() argument
417 if (part->size == SIZE_REMAINING) in part_validate()
418 part->size = id->size - part->offset; in part_validate()
420 if (part->offset > id->size) { in part_validate()
422 id->mtd_id, part->offset, id->size); in part_validate()
426 if ((part->offset + part->size) <= part->offset) { in part_validate()
428 MTD_DEV_TYPE(id->type), id->num, part->name); in part_validate()
432 if (part->offset + part->size > id->size) { in part_validate()
433 printf("%s: partitioning exceeds flash size\n", id->mtd_id); in part_validate()
441 return part_validate_eraseblock(id, part); in part_validate()
448 * @param part partition to delete
451 static int part_del(struct mtd_device *dev, struct part_info *part) in part_del() argument
456 if (dev->num_parts == 1) in part_del()
468 if (curr_pi == part) { in part_del()
471 } else if (part->offset <= curr_pi->offset) { in part_del()
472 current_mtd_partnum--; in part_del()
478 list_del(&part->link); in part_del()
479 free(part); in part_del()
480 dev->num_parts--; in part_del()
516 static int part_sort_add(struct mtd_device *dev, struct part_info *part) in part_sort_add() argument
522 part->dev = dev; in part_sort_add()
524 if (list_empty(&dev->parts)) { in part_sort_add()
526 list_add(&part->link, &dev->parts); in part_sort_add()
527 dev->num_parts++; in part_sort_add()
532 new_pi = list_entry(&part->link, struct part_info, link); in part_sort_add()
539 list_for_each(entry, &dev->parts) { in part_sort_add()
545 if ((new_pi->offset == pi->offset) && (pi->offset == 0)) { in part_sort_add()
550 if (new_pi->offset <= pi->offset) { in part_sort_add()
551 list_add_tail(&part->link, entry); in part_sort_add()
552 dev->num_parts++; in part_sort_add()
554 if (curr_pi && (pi->offset <= curr_pi->offset)) { in part_sort_add()
566 list_add_tail(&part->link, &dev->parts); in part_sort_add()
567 dev->num_parts++; in part_sort_add()
576 * @param part partition to be added
579 static int part_add(struct mtd_device *dev, struct part_info *part) in part_add() argument
582 if (part_validate(dev->id, part) != 0) in part_add()
586 if (part_sort_add(dev, part) != 0) in part_add()
596 * @param partdef pointer to the partition definition string i.e. <part-def>
603 struct part_info *part; in part_parse() local
616 if (*p == '-') { in part_parse()
618 debug("'-': remaining size assigned\n"); in part_parse()
643 name_len = p - name + 1; in part_parse()
644 if ((name_len - 1) == 0) { in part_parse()
666 printf("no partitions allowed after a fill-up partition\n"); in part_parse()
679 part = (struct part_info *)malloc(sizeof(struct part_info) + name_len); in part_parse()
680 if (!part) { in part_parse()
684 memset(part, 0, sizeof(struct part_info) + name_len); in part_parse()
685 part->size = size; in part_parse()
686 part->offset = offset; in part_parse()
687 part->mask_flags = mask_flags; in part_parse()
688 part->name = (char *)(part + 1); in part_parse()
692 strncpy(part->name, name, name_len - 1); in part_parse()
693 part->auto_name = 0; in part_parse()
696 snprintf(part->name, name_len, "0x%08llx@0x%08llx", size, offset); in part_parse()
697 part->auto_name = 1; in part_parse()
700 part->name[name_len - 1] = '\0'; in part_parse()
701 INIT_LIST_HEAD(&part->link); in part_parse()
703 debug("+ partition: name %-22s size 0x%08llx offset 0x%08llx mask flags %d\n", in part_parse()
704 part->name, part->size, in part_parse()
705 part->offset, part->mask_flags); in part_parse()
707 *retpart = part; in part_parse()
712 * Check device number to be within valid range for given device type.
715 * @param num mtd number
726 *size = mtd->size; in mtd_device_validate()
746 part_delall(&dev_tmp->parts); in device_delall()
763 part_delall(&dev->parts); in device_del()
764 list_del(&dev->link); in device_del()
790 * @param num device number
801 if ((dev_tmp->id->type == type) && (dev_tmp->id->num == num)) in device_find()
823 list_add_tail(&dev->link, &devices); in device_add()
832 * Parse device type, name and mtd-id. If syntax is ok allocate memory and
835 * @param mtd_dev pointer to the device definition string i.e. <mtd-dev>
843 struct part_info *part; in device_parse() local
863 /* fetch <mtd-id> */ in device_parse()
866 printf("no <mtd-id> identifier\n"); in device_parse()
869 mtd_id_len = p - mtd_id + 1; in device_parse()
873 if ((id = id_find_by_mtd_id(mtd_id, mtd_id_len - 1)) == NULL) { in device_parse()
874 printf("invalid mtd device '%.*s'\n", mtd_id_len - 1, mtd_id); in device_parse()
879 debug("dev type = %d (%s), dev num = %d, mtd-id = %s\n", in device_parse()
880 id->type, MTD_DEV_TYPE(id->type), in device_parse()
881 id->num, id->mtd_id); in device_parse()
882 debug("parsing partitions %.*s\n", (int)(pend ? pend - p : strlen(p)), p); in device_parse()
888 if ((dev = device_find(id->type, id->num)) != NULL) { in device_parse()
890 part = list_entry(dev->parts.prev, struct part_info, link); in device_parse()
891 offset = part->offset + part->size; in device_parse()
896 if ((part_parse(p, &p, &part) != 0) || (!part)) in device_parse()
900 if (part->offset == OFFSET_NOT_SPECIFIED) in device_parse()
901 part->offset = offset; in device_parse()
903 offset = part->offset; in device_parse()
906 if (part_validate(id, part) != 0) in device_parse()
909 offset += part->size; in device_parse()
912 list_add_tail(&part->link, &tmp_list); in device_parse()
945 dev->id = id; in device_parse()
946 dev->num_parts = 0; /* part_sort_add increments num_parts */ in device_parse()
947 INIT_LIST_HEAD(&dev->parts); in device_parse()
948 INIT_LIST_HEAD(&dev->link); in device_parse()
950 /* move partitions from tmp_list to dev->parts */ in device_parse()
952 part = list_entry(entry, struct part_info, link); in device_parse()
954 if (part_sort_add(dev, part) != 0) { in device_parse()
981 * Search global mtdids list and find id of requested type and number.
993 if ((id->type == type) && (id->num == num)) in id_find()
1014 debug("--- id_find_by_mtd_id: '%.*s' (len = %d)\n", in id_find_by_mtd_id()
1021 id->mtd_id, strlen(id->mtd_id)); in id_find_by_mtd_id()
1023 if (mtd_id_len != strlen(id->mtd_id)) in id_find_by_mtd_id()
1025 if (strncmp(id->mtd_id, mtd_id, mtd_id_len) == 0) in id_find_by_mtd_id()
1033 * Parse device id string <dev-id> := 'nand'|'nor'|'onenand'|'spi-nand'<dev-num>,
1034 * return device type and number.
1039 * @param dev_num parsed device number (output)
1057 } else if (strncmp(p, "spi-nand", 8) == 0) { in mtd_id_parse()
1066 printf("incorrect device number in %s\n", id); in mtd_id_parse()
1088 struct part_info *part, *prev_part; in generate_mtdparts() local
1093 u32 maxlen = buflen - 1; in generate_mtdparts()
1095 debug("--- generate_mtdparts ---\n"); in generate_mtdparts()
1106 len = strlen(dev->id->mtd_id) + 1; in generate_mtdparts()
1109 memcpy(p, dev->id->mtd_id, len - 1); in generate_mtdparts()
1110 p += len - 1; in generate_mtdparts()
1112 maxlen -= len; in generate_mtdparts()
1117 list_for_each(pentry, &dev->parts) { in generate_mtdparts()
1118 part = list_entry(pentry, struct part_info, link); in generate_mtdparts()
1119 size = part->size; in generate_mtdparts()
1120 offset = part->offset; in generate_mtdparts()
1130 maxlen -= len; in generate_mtdparts()
1136 (prev_part && ((prev_part->offset + prev_part->size) != part->offset))) { in generate_mtdparts()
1143 memcpy(p, tmpbuf, len - 1); in generate_mtdparts()
1144 p += len - 1; in generate_mtdparts()
1145 maxlen -= len; in generate_mtdparts()
1149 if(!part->auto_name) { in generate_mtdparts()
1150 len = strlen(part->name) + 2; in generate_mtdparts()
1155 memcpy(p, part->name, len - 2); in generate_mtdparts()
1156 p += len - 2; in generate_mtdparts()
1158 maxlen -= len; in generate_mtdparts()
1162 if (part->mask_flags && MTD_WRITEABLE_CMD) { in generate_mtdparts()
1168 maxlen -= 2; in generate_mtdparts()
1173 if (dev->num_parts > part_cnt) { in generate_mtdparts()
1177 maxlen--; in generate_mtdparts()
1179 prev_part = part; in generate_mtdparts()
1182 if (dentry->next != &devices) { in generate_mtdparts()
1186 maxlen--; in generate_mtdparts()
1228 * @param part the partition
1231 static uint64_t net_part_size(struct mtd_info *mtd, struct part_info *part) in net_part_size() argument
1235 if (!mtd->block_isbad) in net_part_size()
1236 return part->size; in net_part_size()
1238 for (i = 0; i < part->size; i += mtd->erasesize) { in net_part_size()
1239 if (!mtd->block_isbad(mtd, part->offset + i)) in net_part_size()
1240 net_size += mtd->erasesize; in net_part_size()
1250 struct part_info *part; local
1261 if (get_mtd_info(dev->id->type, dev->id->num, &mtd))
1265 MTD_DEV_TYPE(dev->id->type), dev->id->num,
1266 dev->id->mtd_id, dev->num_parts);
1269 list_for_each(pentry, &dev->parts) {
1273 part = list_entry(pentry, struct part_info, link);
1274 net_size = net_part_size(mtd, part);
1275 size_note = part->size == net_size ? " " : " (!)";
1276 printf("%2d: %-20s0x%08x\t0x%08x%s\t0x%08x\t%d\n",
1277 part_num, part->name, part->size,
1278 net_size, size_note, part->offset,
1279 part->mask_flags);
1282 MTD_DEV_TYPE(dev->id->type), dev->id->num,
1283 dev->id->mtd_id, dev->num_parts);
1286 list_for_each(pentry, &dev->parts) {
1287 part = list_entry(pentry, struct part_info, link);
1288 printf("%2d: %-20s0x%08llx\t0x%08llx\t%d\n",
1289 part_num, part->name, part->size,
1290 part->offset, part->mask_flags);
1306 struct part_info *part; local
1308 debug("\n---list_partitions---\n");
1313 part = mtd_part_info(current_mtd_dev, current_mtd_partnum);
1314 if (part) {
1315 printf("\nactive partition: %s%d,%d - (%s) 0x%08llx @ 0x%08llx\n",
1316 MTD_DEV_TYPE(current_mtd_dev->id->type),
1317 current_mtd_dev->id->num, current_mtd_partnum,
1318 part->name, part->size, part->offset);
1339 * corresponding device and verify partition number.
1343 * @param part_num verified partition number (output)
1344 * @param part pointer to requested partition (output)
1348 u8 *part_num, struct part_info **part) argument
1354 debug("--- find_dev_and_part ---\nid = %s\n", id);
1359 list_for_each(pentry, &(*dev)->parts) {
1360 *part = list_entry(pentry, struct part_info, link);
1361 if (strcmp((*part)->name, id) == 0)
1369 *part = NULL;
1376 printf("no partition number specified\n");
1390 if ((*part = mtd_part_info(*dev, pnum)) == NULL) {
1411 struct part_info *part; local
1413 if (find_dev_and_part(id, &dev, &pnum, &part) == 0) {
1416 MTD_DEV_TYPE(dev->id->type), dev->id->num, pnum,
1417 part->name, part->size, part->offset);
1419 if (part_del(dev, part) != 0)
1440 * @param part the partition
1444 static void spread_partition(struct mtd_info *mtd, struct part_info *part, argument
1450 mtd_get_len_incl_bad(mtd, part->offset, part->size, &net_size,
1459 mtd_get_len_incl_bad(mtd, part->offset + net_size,
1460 mtd->erasesize, &padding_size, &truncated);
1464 padding_size -= mtd->erasesize;
1468 printf("truncated partition %s to %lld bytes\n", part->name,
1472 part->size = net_size + padding_size;
1473 *next_offset = part->offset + part->size;
1487 struct part_info *part; local
1495 if (get_mtd_info(dev->id->type, dev->id->num, &mtd))
1500 list_for_each(pentry, &dev->parts) {
1501 part = list_entry(pentry, struct part_info, link);
1505 MTD_DEV_TYPE(dev->id->type), dev->id->num,
1506 part_num, part->name, part->size,
1507 part->offset);
1509 if (cur_offs > part->offset)
1510 part->offset = cur_offs;
1512 spread_partition(mtd, part, &cur_offs);
1531 * buffer. gd->env_buf will be too small.
1538 if (gd->flags & GD_FLG_ENV_READY)
1540 if (env_get_f("mtdparts", buf, MTDPARTS_MAXLEN) != -1)
1559 debug("\n---parse_mtdparts---\nmtdparts = %s\n\n", mtdparts);
1567 /* re-read 'mtdparts' variable, mtd_devices_init may be updating env */
1581 debug("+ device: %s\t%d\t%s\n", MTD_DEV_TYPE(dev->id->type),
1582 dev->id->num, dev->id->mtd_id);
1585 if (device_find(dev->id->type, dev->id->num) != NULL) {
1587 MTD_DEV_TYPE(dev->id->type), dev->id->num);
1591 list_add_tail(&dev->link, &devices);
1622 debug("\n---parse_mtdids---\nmtdids = %s\n\n", ids);
1627 debug("mtdids del: %d %d\n", id_tmp->type, id_tmp->num);
1637 /* parse 'nor'|'nand'|'onenand'|'spi-nand'<dev-num> */
1642 printf("mtdids: incorrect <dev-num>\n");
1651 /* locate <mtd-id> */
1654 mtd_id_len = p - mtd_id + 1;
1660 printf("mtdids: no <mtd-id> identifier\n");
1668 if ((id_tmp->type == type) && (id_tmp->num == num)) {
1685 id->num = num;
1686 id->type = type;
1687 id->size = size;
1688 id->mtd_id = (char *)(id + 1);
1689 strncpy(id->mtd_id, mtd_id, mtd_id_len - 1);
1690 id->mtd_id[mtd_id_len - 1] = '\0';
1691 INIT_LIST_HEAD(&id->link);
1694 MTD_DEV_TYPE(id->type), id->num,
1695 id->size, id->mtd_id);
1697 list_add_tail(&id->link, &mtdids);
1729 debug("\n---mtdparts_init---\n");
1774 if (strlen(ids) > MTDIDS_MAXLEN - 1) {
1790 if (parts && (strlen(parts) > MTDPARTS_MAXLEN - 1)) {
1829 MTD_DEV_TYPE(current_mtd_dev->id->type),
1830 current_mtd_dev->id->num, current_mtd_partnum);
1847 debug("--- getting current partition: %s\n", tmp_ep);
1863 * Return pointer to the partition of a requested number from a requested
1867 * @param part_num requested partition number
1873 struct part_info *part; local
1879 debug("\n--- mtd_part_info: partition number %d for device %s%d (%s)\n",
1880 part_num, MTD_DEV_TYPE(dev->id->type),
1881 dev->id->num, dev->id->mtd_id);
1883 if (part_num >= dev->num_parts) {
1884 printf("invalid partition number %d for device %s%d (%s)\n",
1885 part_num, MTD_DEV_TYPE(dev->id->type),
1886 dev->id->num, dev->id->mtd_id);
1890 /* locate partition number, return it */
1892 list_for_each(entry, &dev->parts) {
1893 part = list_entry(entry, struct part_info, link);
1896 return part;
1904 /* U-Boot commands */
1908 * Routine implementing u-boot chpart command. Sets new current partition based
1913 * @param argc number of arguments supplied to the command
1921 struct part_info *part; local
1932 if (find_dev_and_part(argv[1], &dev, &pnum, &part) != 0)
1940 MTD_DEV_TYPE(dev->id->type), dev->id->num, pnum);
1946 * Routine implementing u-boot mtdparts command. Initialize/update default global
1951 * @param argc number of arguments supplied to the command
1987 /* mtdparts add <mtd-dev> <size>[@<offset>] <name> [ro] */
2009 len = strlen(id->mtd_id) + 1; /* 'mtd_id:' */
2020 id->mtd_id, argv[3], argv[4], argv[5] ? argv[5] : "");
2026 debug("+ %s\t%d\t%s\n", MTD_DEV_TYPE(dev->id->type),
2027 dev->id->num, dev->id->mtd_id);
2029 p = list_entry(dev->parts.next, struct part_info, link);
2032 if (get_mtd_info(dev->id->type, dev->id->num, &mtd))
2037 debug("increased %s to %llu bytes\n", p->name, p->size);
2041 dev_tmp = device_find(dev->id->type, dev->id->num);
2058 /* mtdparts del part-id */
2060 debug("del: part-id = %s\n", argv[2]);
2077 "part-id\n"
2078 " - change active partition (e.g. part-id = nand0,1)"
2084 " - list partition table\n"
2086 " - delete all partitions\n"
2087 "mtdparts del part-id\n"
2088 " - delete partition (e.g. part-id = nand0,1)\n"
2089 "mtdparts add <mtd-dev> <size>[@<offset>] [<name>] [ro]\n"
2090 " - add partition\n"
2092 "mtdparts add.spread <mtd-dev> <size>[@<offset>] [<name>] [ro]\n"
2093 " - add partition, padding size by skipping bad blocks\n"
2096 " - reset partition table to defaults\n"
2099 " - adjust the sizes of the partitions so they are\n"
2105 "-----\n\n"
2107 "'partition' - keeps current partition identifier\n\n"
2108 "partition := <part-id>\n"
2109 "<part-id> := <dev-id>,part_num\n\n"
2110 "'mtdids' - linux kernel mtd device id <-> u-boot device id mapping\n\n"
2112 "<idmap> := <dev-id>=<mtd-id>\n"
2113 "<dev-id> := 'nand'|'nor'|'onenand'|'spi-nand'<dev-num>\n"
2114 "<dev-num> := mtd device number, 0...\n"
2115 "<mtd-id> := unique device tag used by linux kernel to find mtd device (mtd->name)\n\n"
2116 "'mtdparts' - partition list\n\n"
2117 "mtdparts=mtdparts=<mtd-def>[;<mtd-def>...]\n\n"
2118 "<mtd-def> := <mtd-id>:<part-def>[,<part-def>...]\n"
2119 "<mtd-id> := unique device tag used by linux kernel to find mtd device (mtd->name)\n"
2120 "<part-def> := <size>[@<offset>][<name>][<ro-flag>]\n"
2121 "<size> := standard linux memsize OR '-' to denote all remaining space\n"
2124 "<ro-flag> := when set to 'ro' makes partition read-only (not used, passed to kernel)";