summaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorRafał Miłecki <rafal@milecki.pl>2017-06-21 08:26:46 +0200
committerBrian Norris <computersforpeace@gmail.com>2017-06-22 22:13:09 +0200
commit1a0915be192606fee64830b9c5d70b7ed59426b6 (patch)
treeb8c5dcc0c867c8be40515b862b248bd00b0a9e6a /drivers/mtd
parentmtd: partitions: add support for subpartitions (diff)
downloadlinux-1a0915be192606fee64830b9c5d70b7ed59426b6.tar.xz
linux-1a0915be192606fee64830b9c5d70b7ed59426b6.zip
mtd: partitions: add support for partition parsers
Some devices have partitions that are kind of containers with extra subpartitions / volumes instead of e.g. a simple filesystem data. To support such cases we need to first create normal flash device partitions and then take care of these special ones. It's very common case for home routers. Depending on the vendor there are formats like TRX, Seama, TP-Link, WRGG & more. All of them are used to embed few partitions into a single one / single firmware file. Ideally all vendors would use some well documented / standardized format like UBI (and some probably start doing so), but there are still countless devices on the market using these poor vendor specific formats. This patch extends MTD subsystem by allowing to specify list of parsers that should be tried for a given partition. Supporting such poor formats is highly unlikely to be the top priority so these changes try to minimize maintenance cost to the minimum. It reuses existing code for these new parsers and just adds a one property and one new function. This implementation requires setting partition parsers in a flash parser. A proper change of bcm47xxpart will follow and in the future we will hopefully also find a solution for doing it with ofpart ("fixed-partitions"). Signed-off-by: Rafał Miłecki <rafal@milecki.pl> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/mtdpart.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index c0d464d192ee..2ad9493703f9 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -369,6 +369,35 @@ static inline void free_partition(struct mtd_part *p)
kfree(p);
}
+/**
+ * mtd_parse_part - parse MTD partition looking for subpartitions
+ *
+ * @slave: part that is supposed to be a container and should be parsed
+ * @types: NULL-terminated array with names of partition parsers to try
+ *
+ * Some partitions are kind of containers with extra subpartitions (volumes).
+ * There can be various formats of such containers. This function tries to use
+ * specified parsers to analyze given partition and registers found
+ * subpartitions on success.
+ */
+static int mtd_parse_part(struct mtd_part *slave, const char *const *types)
+{
+ struct mtd_partitions parsed;
+ int err;
+
+ err = parse_mtd_partitions(&slave->mtd, types, &parsed, NULL);
+ if (err)
+ return err;
+ else if (!parsed.nr_parts)
+ return -ENOENT;
+
+ err = add_mtd_partitions(&slave->mtd, parsed.parts, parsed.nr_parts);
+
+ mtd_part_parser_cleanup(&parsed);
+
+ return err;
+}
+
static struct mtd_part *allocate_partition(struct mtd_info *parent,
const struct mtd_partition *part, int partno,
uint64_t cur_offset)
@@ -758,6 +787,8 @@ int add_mtd_partitions(struct mtd_info *master,
add_mtd_device(&slave->mtd);
mtd_add_partition_attrs(slave);
+ if (parts[i].types)
+ mtd_parse_part(slave, parts[i].types);
cur_offset = slave->offset + slave->mtd.size;
}