From 1ee640765a71a7b9ee2cf4ebad22ed5961aef8db Mon Sep 17 00:00:00 2001 From: Dmitry Lavnikevich Date: Mon, 10 Mar 2014 14:39:49 +0300 Subject: mtd: Update internal API to support 64-bit device size MTD internal API presently uses 32-bit values to represent device size. This patch updates them to 64-bits but leaves the external API unchanged. In general, changing from 32-bit to 64-bit values cause little or no changes to the majority of the code with the following exceptions: - printk message formats; - division and modulus of 64-bit values (mtd_div_by_wb, mtd_div_by_eb may be used in some of such cases). Was tested on phyFLEX i.MX6. Signed-off-by: Dmitry Lavnikevich Signed-off-by: Grigory Milev Signed-off-by: Sascha Hauer --- commands/nandtest.c | 2 +- commands/partition.c | 11 ++++++----- drivers/mtd/core.c | 2 +- drivers/mtd/devices/m25p80.c | 5 +++-- drivers/mtd/devices/mtd_dataflash.c | 2 +- drivers/mtd/mtdoob.c | 2 +- drivers/mtd/mtdraw.c | 2 +- include/linux/mtd/mtd-abi.h | 12 +++++++++++- include/linux/mtd/mtd.h | 11 +++++++++-- lib/libmtd.c | 10 +++++----- 10 files changed, 39 insertions(+), 20 deletions(-) diff --git a/commands/nandtest.c b/commands/nandtest.c index 0da5444c02..c64f2443a8 100644 --- a/commands/nandtest.c +++ b/commands/nandtest.c @@ -277,7 +277,7 @@ static int do_nandtest(int argc, char *argv[]) } if (length + flash_offset > meminfo.size) { printf("Length 0x%08llx + offset 0x%08llx exceeds " - "device size 0x%08x\n", length, + "device size 0x%08llx\n", length, flash_offset, meminfo.size); goto err; } diff --git a/commands/partition.c b/commands/partition.c index 6d37471f4f..f8257222a9 100644 --- a/commands/partition.c +++ b/commands/partition.c @@ -42,10 +42,11 @@ #define PART_ADD_DEVNAME (1 << 0) static int mtd_part_do_parse_one(char *devname, const char *partstr, - char **endp, unsigned long *offset, - off_t devsize, size_t *retsize, unsigned int pflags) + char **endp, loff_t *offset, + loff_t devsize, size_t *retsize, + unsigned int pflags) { - ulong size; + loff_t size; char *end; char buf[PATH_MAX] = {}; unsigned long flags = 0; @@ -114,8 +115,8 @@ static int do_addpart(int argc, char *argv[]) { char *devname; char *endp; - unsigned long offset = 0; - off_t devsize; + loff_t offset = 0; + loff_t devsize; struct stat s; int opt; unsigned int flags = PART_ADD_DEVNAME; diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c index 36a363fa37..c97c8c1403 100644 --- a/drivers/mtd/core.c +++ b/drivers/mtd/core.c @@ -401,7 +401,7 @@ int add_mtd_device(struct mtd_info *mtd, char *devname, int device_id) mtd->cdev.mtd = mtd; if (IS_ENABLED(CONFIG_PARAMETER)) { - dev_add_param_int_ro(&mtd->class_dev, "size", mtd->size, "%u"); + dev_add_param_int_ro(&mtd->class_dev, "size", mtd->size, "%llu"); dev_add_param_int_ro(&mtd->class_dev, "erasesize", mtd->erasesize, "%u"); dev_add_param_int_ro(&mtd->class_dev, "writesize", mtd->oobsize, "%u"); dev_add_param_int_ro(&mtd->class_dev, "oobsize", mtd->oobsize, "%u"); diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 56c69f35c0..50e04548e9 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -268,8 +268,9 @@ static int erase_sector(struct m25p *flash, u32 offset, u32 command) static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr) { struct m25p *flash = mtd_to_m25p(mtd); - u32 addr, len; + u32 addr; uint32_t rem; + uint64_t len; dev_dbg(&flash->spi->dev, "%s at 0x%llx, len %lld\n", __func__, (long long)instr->addr, @@ -897,7 +898,7 @@ static int m25p_probe(struct device_d *dev) flash->mtd.type = MTD_NORFLASH; flash->mtd.writesize = 1; flash->mtd.flags = MTD_CAP_NORFLASH; - flash->mtd.size = info->sector_size * info->n_sectors; + flash->mtd.size = (uint64_t)info->sector_size * info->n_sectors; flash->mtd.erase = m25p80_erase; flash->mtd.read = m25p80_read; diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index cdc0120c53..fa31b61464 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -625,7 +625,7 @@ add_dataflash_otp(struct spi_device *spi, char *name, device = &priv->mtd; device->name = (pdata && pdata->name) ? pdata->name : "dataflash"; - device->size = nr_pages * pagesize; + device->size = nr_pages * (uint64_t)pagesize; device->erasesize = pagesize; device->writesize = pagesize; device->type = MTD_DATAFLASH; diff --git a/drivers/mtd/mtdoob.c b/drivers/mtd/mtdoob.c index b9cac2ae69..10d17e90d2 100644 --- a/drivers/mtd/mtdoob.c +++ b/drivers/mtd/mtdoob.c @@ -78,7 +78,7 @@ static int add_mtdoob_device(struct mtd_info *mtd, char *devname, void **priv) mtdoob = xzalloc(sizeof(*mtdoob)); mtdoob->cdev.ops = &mtd_ops_oob; - mtdoob->cdev.size = (mtd->size / mtd->writesize) * mtd->oobsize; + mtdoob->cdev.size = mtd_div_by_wb(mtd->size, mtd) * mtd->oobsize; mtdoob->cdev.name = asprintf("%s_oob%d", devname, mtd->class_dev.id); mtdoob->cdev.priv = mtdoob; mtdoob->cdev.dev = &mtd->class_dev; diff --git a/drivers/mtd/mtdraw.c b/drivers/mtd/mtdraw.c index 006b28f9b2..c25e4062ee 100644 --- a/drivers/mtd/mtdraw.c +++ b/drivers/mtd/mtdraw.c @@ -293,7 +293,7 @@ static int add_mtdraw_device(struct mtd_info *mtd, char *devname, void **priv) mtdraw->mtd = mtd; mtdraw->cdev.ops = (struct file_operations *)&mtd_raw_fops; - mtdraw->cdev.size = mtd->size / mtd->writesize * + mtdraw->cdev.size = mtd_div_by_wb(mtd->size, mtd) * (mtd->writesize + mtd->oobsize); mtdraw->cdev.name = asprintf("%s.raw", mtd->cdev.name); mtdraw->cdev.priv = mtdraw; diff --git a/include/linux/mtd/mtd-abi.h b/include/linux/mtd/mtd-abi.h index 11d51e2744..c1ba55bd2d 100644 --- a/include/linux/mtd/mtd-abi.h +++ b/include/linux/mtd/mtd-abi.h @@ -9,6 +9,8 @@ #ifndef DOXYGEN_SHOULD_SKIP_THIS +#include + struct erase_info_user { uint32_t start; uint32_t length; @@ -73,7 +75,7 @@ enum { struct mtd_info_user { uint8_t type; uint32_t flags; - uint32_t size; // Total size of the MTD + uint64_t size; /* Total size of the MTD */ uint32_t erasesize; uint32_t writesize; uint32_t oobsize; // Amount of OOB data per block (e.g. 16) @@ -173,6 +175,14 @@ enum mtd_file_modes { MTD_MODE_RAW, }; + +static inline uint32_t mtd_user_div_by_eb(uint64_t sz, + struct mtd_info_user *mtd_user) +{ + do_div(sz, mtd_user->erasesize); + return sz; +} + #endif /* DOXYGEN_SHOULD_SKIP_THIS */ #endif /* __MTD_ABI_H__ */ diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index e02204a503..970cdb02fa 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -86,7 +86,7 @@ struct mtd_oob_ops { struct mtd_info { u_char type; u_int32_t flags; - u_int32_t size; // Total size of the MTD + u_int64_t size; /* Total size of the MTD */ /* "Major" erase size for the device. Naïve users may take this * to be the only erase size available, or may use the more detailed @@ -219,7 +219,7 @@ struct mtd_info { int p_allow_erasebad; struct mtd_info *master; - uint32_t master_offset; + loff_t master_offset; }; int mtd_erase(struct mtd_info *mtd, struct erase_info *instr); @@ -256,6 +256,13 @@ static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd) { return do_div(sz, mtd->erasesize); } + +static inline uint32_t mtd_div_by_wb(uint64_t sz, struct mtd_info *mtd) +{ + do_div(sz, mtd->writesize); + return sz; +} + /* Kernel-side ioctl definitions */ extern int add_mtd_device(struct mtd_info *mtd, char *devname, int device_id); diff --git a/lib/libmtd.c b/lib/libmtd.c index 1606b872fd..56672bd951 100644 --- a/lib/libmtd.c +++ b/lib/libmtd.c @@ -195,7 +195,7 @@ int libmtd_read(const struct mtd_dev_info *mtd, int fd, int eb, int offs, void *buf, int len) { int ret, rd = 0; - off_t seek; + loff_t seek; ret = mtd_valid_erase_block(mtd, eb); if (ret) @@ -209,7 +209,7 @@ int libmtd_read(const struct mtd_dev_info *mtd, int fd, int eb, int offs, } /* Seek to the beginning of the eraseblock */ - seek = (off_t)eb * mtd->eb_size + offs; + seek = (loff_t)eb * mtd->eb_size + offs; if (lseek(fd, seek, SEEK_SET) != seek) return sys_errmsg("cannot seek %s to offset %llu", mtd->node, (unsigned long long)seek); @@ -229,7 +229,7 @@ int libmtd_write(const struct mtd_dev_info *mtd, int fd, int eb, int offs, void *buf, int len) { int ret; - off_t seek; + loff_t seek; ret = mtd_valid_erase_block(mtd, eb); if (ret) @@ -255,7 +255,7 @@ int libmtd_write(const struct mtd_dev_info *mtd, int fd, int eb, int offs, } /* Seek to the beginning of the eraseblock */ - seek = (off_t)eb * mtd->eb_size + offs; + seek = (loff_t)eb * mtd->eb_size + offs; if (lseek(fd, seek, SEEK_SET) != seek) return sys_errmsg("cannot seek %s to offset %llu", mtd->node, (unsigned long long)seek); @@ -326,7 +326,7 @@ int mtd_get_dev_info(const char *node, struct mtd_dev_info *mtd) goto out_close; } - mtd->eb_cnt = ui.size / ui.erasesize; + mtd->eb_cnt = mtd_user_div_by_eb(ui.size, &ui); switch(mtd->type) { case MTD_ABSENT: -- cgit v1.2.3