diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2015-02-12 07:44:34 +0000 |
---|---|---|
committer | Rafał Miłecki <zajec5@gmail.com> | 2015-02-12 07:44:34 +0000 |
commit | 072759ff3968af3c1bbc1f6837829362591c69b3 (patch) | |
tree | 38b00ca02f33456f55dedd38ede5a900756950e3 /target/linux/generic/files/drivers | |
parent | 5673e0b703a1cb5037c8763dc7d9ea8e5c51ced4 (diff) | |
download | upstream-072759ff3968af3c1bbc1f6837829362591c69b3.tar.gz upstream-072759ff3968af3c1bbc1f6837829362591c69b3.tar.bz2 upstream-072759ff3968af3c1bbc1f6837829362591c69b3.zip |
kernel: mtdsplit_uimage: use separated buffer for reading data
We shouldn't read data directly into the header struct, as some devices
(e.g. Edimax) need more bytes due to some extra header.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
SVN-Revision: 44414
Diffstat (limited to 'target/linux/generic/files/drivers')
-rw-r--r-- | target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c | 34 |
1 files changed, 16 insertions, 18 deletions
diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c index 04a0eb47d7..eb4729a765 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c @@ -49,15 +49,15 @@ struct uimage_header { static int read_uimage_header(struct mtd_info *mtd, size_t offset, - struct uimage_header *header) + u_char *buf) { + struct uimage_header *header; size_t header_len; size_t retlen; int ret; header_len = sizeof(*header); - ret = mtd_read(mtd, offset, header_len, &retlen, - (unsigned char *) header); + ret = mtd_read(mtd, offset, header_len, &retlen, buf); if (ret) { pr_debug("read error in \"%s\"\n", mtd->name); return ret; @@ -83,6 +83,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, ssize_t (*find_header)(u_char *buf, size_t len)) { struct mtd_partition *parts; + u_char *buf; struct uimage_header *header; int nr_parts; size_t offset; @@ -98,8 +99,8 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, if (!parts) return -ENOMEM; - header = vmalloc(sizeof(*header)); - if (!header) { + buf = vmalloc(sizeof(*header)); + if (!buf) { ret = -ENOMEM; goto err_free_parts; } @@ -108,20 +109,17 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, for (offset = 0; offset < master->size; offset += master->erasesize) { uimage_size = 0; - ret = read_uimage_header(master, offset, header); + ret = read_uimage_header(master, offset, buf); if (ret) continue; - ret = find_header((u_char *)header, sizeof(*header)); + ret = find_header(buf, sizeof(*buf)); if (ret < 0) { pr_debug("no valid uImage found in \"%s\" at offset %llx\n", master->name, (unsigned long long) offset); continue; } - if (ret > 0) { - pr_warn("extra header offsets are not supported yet\n"); - continue; - } + header = (struct uimage_header *)(buf + ret); uimage_size = sizeof(*header) + be32_to_cpu(header->ih_size); if ((offset + uimage_size) > master->size) { @@ -135,7 +133,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, if (uimage_size == 0) { pr_debug("no uImage found in \"%s\"\n", master->name); ret = -ENODEV; - goto err_free_header; + goto err_free_buf; } uimage_offset = offset; @@ -152,7 +150,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, if (ret) { pr_debug("no rootfs after uImage in \"%s\"\n", master->name); - goto err_free_header; + goto err_free_buf; } rootfs_size = master->size - rootfs_offset; @@ -166,7 +164,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, if (ret) { pr_debug("no rootfs before uImage in \"%s\"\n", master->name); - goto err_free_header; + goto err_free_buf; } rootfs_offset = 0; @@ -176,7 +174,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, if (rootfs_size == 0) { pr_debug("no rootfs found in \"%s\"\n", master->name); ret = -ENODEV; - goto err_free_header; + goto err_free_buf; } parts[uimage_part].name = KERNEL_PART_NAME; @@ -187,13 +185,13 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, parts[rf_part].offset = rootfs_offset; parts[rf_part].size = rootfs_size; - vfree(header); + vfree(buf); *pparts = parts; return nr_parts; -err_free_header: - vfree(header); +err_free_buf: + vfree(buf); err_free_parts: kfree(parts); |