]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/mtd/parsers/parser_trx.c
Merge tag 'kvm-4.13-2' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[karo-tx-linux.git] / drivers / mtd / parsers / parser_trx.c
1 /*
2  * Parser for TRX format partitions
3  *
4  * Copyright (C) 2012 - 2017 Rafał Miłecki <rafal@milecki.pl>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  */
11
12 #include <linux/module.h>
13 #include <linux/slab.h>
14 #include <linux/mtd/mtd.h>
15 #include <linux/mtd/partitions.h>
16
17 #define TRX_PARSER_MAX_PARTS            4
18
19 /* Magics */
20 #define TRX_MAGIC                       0x30524448
21 #define UBI_EC_MAGIC                    0x23494255      /* UBI# */
22
23 struct trx_header {
24         uint32_t magic;
25         uint32_t length;
26         uint32_t crc32;
27         uint16_t flags;
28         uint16_t version;
29         uint32_t offset[3];
30 } __packed;
31
32 static const char *parser_trx_data_part_name(struct mtd_info *master,
33                                              size_t offset)
34 {
35         uint32_t buf;
36         size_t bytes_read;
37         int err;
38
39         err  = mtd_read(master, offset, sizeof(buf), &bytes_read,
40                         (uint8_t *)&buf);
41         if (err && !mtd_is_bitflip(err)) {
42                 pr_err("mtd_read error while parsing (offset: 0x%zX): %d\n",
43                         offset, err);
44                 goto out_default;
45         }
46
47         if (buf == UBI_EC_MAGIC)
48                 return "ubi";
49
50 out_default:
51         return "rootfs";
52 }
53
54 static int parser_trx_parse(struct mtd_info *mtd,
55                             const struct mtd_partition **pparts,
56                             struct mtd_part_parser_data *data)
57 {
58         struct mtd_partition *parts;
59         struct mtd_partition *part;
60         struct trx_header trx;
61         size_t bytes_read;
62         uint8_t curr_part = 0, i = 0;
63         int err;
64
65         parts = kzalloc(sizeof(struct mtd_partition) * TRX_PARSER_MAX_PARTS,
66                         GFP_KERNEL);
67         if (!parts)
68                 return -ENOMEM;
69
70         err = mtd_read(mtd, 0, sizeof(trx), &bytes_read, (uint8_t *)&trx);
71         if (err) {
72                 pr_err("MTD reading error: %d\n", err);
73                 kfree(parts);
74                 return err;
75         }
76
77         if (trx.magic != TRX_MAGIC) {
78                 kfree(parts);
79                 return -ENOENT;
80         }
81
82         /* We have LZMA loader if there is address in offset[2] */
83         if (trx.offset[2]) {
84                 part = &parts[curr_part++];
85                 part->name = "loader";
86                 part->offset = trx.offset[i];
87                 i++;
88         }
89
90         if (trx.offset[i]) {
91                 part = &parts[curr_part++];
92                 part->name = "linux";
93                 part->offset = trx.offset[i];
94                 i++;
95         }
96
97         if (trx.offset[i]) {
98                 part = &parts[curr_part++];
99                 part->name = parser_trx_data_part_name(mtd, trx.offset[i]);
100                 part->offset = trx.offset[i];
101                 i++;
102         }
103
104         /*
105          * Assume that every partition ends at the beginning of the one it is
106          * followed by.
107          */
108         for (i = 0; i < curr_part; i++) {
109                 u64 next_part_offset = (i < curr_part - 1) ?
110                                        parts[i + 1].offset : mtd->size;
111
112                 parts[i].size = next_part_offset - parts[i].offset;
113         }
114
115         *pparts = parts;
116         return i;
117 };
118
119 static struct mtd_part_parser mtd_parser_trx = {
120         .parse_fn = parser_trx_parse,
121         .name = "trx",
122 };
123 module_mtd_part_parser(mtd_parser_trx);
124
125 MODULE_LICENSE("GPL v2");
126 MODULE_DESCRIPTION("Parser for TRX format partitions");