Commit ca75b20ebbfd40189a0157c7a2ef4360b0885cc4

Authored by Ben Gardiner
Committed by Scott Wood
1 parent 04ac380288

mtdparts: add new sub-command "spread"

This patch introduces the 'spread' sub-command of the mtdparts command.
This command will modify the existing mtdparts variable by increasing
the size of the partitions such that 1) each partition's net size is at
least as large as the size specified in the mtdparts variable and 2)
each partition starts on a good block.

The new subcommand is implemented by iterating over the mtd device
partitions and collecting a bad blocks count in each -- including any
trailing bad blocks -- and then modifying that partitions's part_info
structure and checking if the modification affects the next partition.

This patch is based on a port of the 'dynnamic partitions' feature by
Harald Welte <laforge@gnumonks.org>; ported from commit
e05835df019027391f58f9d8ce5e1257d6924798 of
git://git.openmoko.org/u-boot.git. Whereas Harald's feature used a
compile-time array to specify partitions, the feature introduced by
this patch uses the mtdparts environment variable.

Signed-off-by: Ben Gardiner <bengardiner@nanometrics.ca>
Signed-off-by: Harald Welte <laforge@gnumonks.org>
CC: Wolfgang Denk <wd@denx.de>
CC: Scott Wood <scottwood@freescale.com>

Showing 1 changed file with 112 additions and 1 deletions Side-by-side Diff

common/cmd_mtdparts.c
... ... @@ -15,6 +15,9 @@
15 15 * Parsing routines are based on driver/mtd/cmdline.c from the linux 2.4
16 16 * kernel tree.
17 17 *
  18 + * (C) Copyright 2008
  19 + * Harald Welte, OpenMoko, Inc., Harald Welte <laforge@openmoko.org>
  20 + *
18 21 * $Id: cmdlinepart.c,v 1.17 2004/11/26 11:18:47 lavinen Exp $
19 22 * Copyright 2002 SYSGO Real-Time Solutions GmbH
20 23 *
21 24  
... ... @@ -1424,7 +1427,102 @@
1424 1427 return 1;
1425 1428 }
1426 1429  
  1430 +#if defined(CONFIG_CMD_MTDPARTS_SPREAD)
1427 1431 /**
  1432 + * Increase the size of the given partition so that it's net size is at least
  1433 + * as large as the size member and such that the next partition would start on a
  1434 + * good block if it were adjacent to this partition.
  1435 + *
  1436 + * @param mtd the mtd device
  1437 + * @param part the partition
  1438 + * @param next_offset pointer to the offset of the next partition after this
  1439 + * partition's size has been modified (output)
  1440 + */
  1441 +static void spread_partition(struct mtd_info *mtd, struct part_info *part,
  1442 + uint64_t *next_offset)
  1443 +{
  1444 + uint64_t net_size, padding_size = 0;
  1445 + int truncated;
  1446 +
  1447 + mtd_get_len_incl_bad(mtd, part->offset, part->size, &net_size,
  1448 + &truncated);
  1449 +
  1450 + /*
  1451 + * Absorb bad blocks immediately following this
  1452 + * partition also into the partition, such that
  1453 + * the next partition starts with a good block.
  1454 + */
  1455 + if (!truncated) {
  1456 + mtd_get_len_incl_bad(mtd, part->offset + net_size,
  1457 + mtd->erasesize, &padding_size, &truncated);
  1458 + if (truncated)
  1459 + padding_size = 0;
  1460 + else
  1461 + padding_size -= mtd->erasesize;
  1462 + }
  1463 +
  1464 + if (truncated) {
  1465 + printf("truncated partition %s to %lld bytes\n", part->name,
  1466 + (uint64_t) net_size + padding_size);
  1467 + }
  1468 +
  1469 + part->size = net_size + padding_size;
  1470 + *next_offset = part->offset + part->size;
  1471 +}
  1472 +
  1473 +/**
  1474 + * Adjust all of the partition sizes, such that all partitions are at least
  1475 + * as big as their mtdparts environment variable sizes and they each start
  1476 + * on a good block.
  1477 + *
  1478 + * @return 0 on success, 1 otherwise
  1479 + */
  1480 +static int spread_partitions(void)
  1481 +{
  1482 + struct list_head *dentry, *pentry;
  1483 + struct mtd_device *dev;
  1484 + struct part_info *part;
  1485 + struct mtd_info *mtd;
  1486 + int part_num;
  1487 + uint64_t cur_offs;
  1488 +
  1489 + list_for_each(dentry, &devices) {
  1490 + dev = list_entry(dentry, struct mtd_device, link);
  1491 +
  1492 + if (get_mtd_info(dev->id->type, dev->id->num, &mtd))
  1493 + return 1;
  1494 +
  1495 + part_num = 0;
  1496 + cur_offs = 0;
  1497 + list_for_each(pentry, &dev->parts) {
  1498 + part = list_entry(pentry, struct part_info, link);
  1499 +
  1500 + debug("spread_partitions: device = %s%d, partition %d ="
  1501 + " (%s) 0x%08x@0x%08x\n",
  1502 + MTD_DEV_TYPE(dev->id->type), dev->id->num,
  1503 + part_num, part->name, part->size,
  1504 + part->offset);
  1505 +
  1506 + if (cur_offs > part->offset)
  1507 + part->offset = cur_offs;
  1508 +
  1509 + spread_partition(mtd, part, &cur_offs);
  1510 +
  1511 + part_num++;
  1512 + }
  1513 + }
  1514 +
  1515 + index_partitions();
  1516 +
  1517 + if (generate_mtdparts_save(last_parts, MTDPARTS_MAXLEN) != 0) {
  1518 + printf("generated mtdparts too long, reseting to null\n");
  1519 + return 1;
  1520 + }
  1521 + return 0;
  1522 +}
  1523 +#endif /* CONFIG_CMD_MTDPARTS_SPREAD */
  1524 +
  1525 +/**
1428 1526 * Accept character string describing mtd partitions and call device_parse()
1429 1527 * for each entry. Add created devices to the global devices list.
1430 1528 *
... ... @@ -1914,6 +2012,11 @@
1914 2012 return delete_partition(argv[2]);
1915 2013 }
1916 2014  
  2015 +#if defined(CONFIG_CMD_MTDPARTS_SPREAD)
  2016 + if ((argc == 2) && (strcmp(argv[1], "spread") == 0))
  2017 + return spread_partitions();
  2018 +#endif /* CONFIG_CMD_MTDPARTS_SPREAD */
  2019 +
1917 2020 return cmd_usage(cmdtp);
1918 2021 }
1919 2022  
... ... @@ -1937,7 +2040,15 @@
1937 2040 "mtdparts add <mtd-dev> <size>[@<offset>] [<name>] [ro]\n"
1938 2041 " - add partition\n"
1939 2042 "mtdparts default\n"
1940   - " - reset partition table to defaults\n\n"
  2043 + " - reset partition table to defaults\n"
  2044 +#if defined(CONFIG_CMD_MTDPARTS_SPREAD)
  2045 + "mtdparts spread\n"
  2046 + " - adjust the sizes of the partitions so they are\n"
  2047 + " at least as big as the mtdparts variable specifies\n"
  2048 + " and they each start on a good block\n\n"
  2049 +#else
  2050 + "\n"
  2051 +#endif /* CONFIG_CMD_MTDPARTS_SPREAD */
1941 2052 "-----\n\n"
1942 2053 "this command uses three environment variables:\n\n"
1943 2054 "'partition' - keeps current partition identifier\n\n"