Skip to contentSkip to conversation

mtd: Update internal API to support 64-bit device size

PATCH In review Dmitry Lavnikevich 3 participants 7 messages Mar 7, 2014 – Mar 12, 2014

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/5 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.

---
 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             |  9 ++++++++-
 lib/libmtd.c                        | 10 +++++-----
 10 files changed, 38 insertions(+), 19 deletions(-)
commands/nandtest.c +1 -1
index 0da5444..c64f244 100644
@@ -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;
 	}
commands/partition.c +6 -5
index 6d37471..f825722 100644
@@ -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;
drivers/mtd/core.c +1 -1
index 6db1c6d..7efb03c 100644
@@ -397,7 +397,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");

drivers/mtd/devices/m25p80.c +3 -2
index 9594011..757a717 100644
@@ -273,8 +273,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,
@@ -896,7 +897,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 cdc0120..fa31b61 100644

drivers/mtd/devices/mtd_dataflash.c +1 -1
@@ -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;
drivers/mtd/mtdoob.c +1 -1
index 1e88b53..54888cd 100644
@@ -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;
drivers/mtd/mtdraw.c +1 -1
index be34723..33ca05d 100644
@@ -290,7 +290,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;
include/linux/mtd/mtd-abi.h +9 -1
index 11d51e2..c1ba55b 100644
@@ -9,6 +9,8 @@
  #ifndef DOXYGEN_SHOULD_SKIP_THIS
 +#include <asm-generic/div64.h>
+
 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__ */
include/linux/mtd/mtd.h +8 -1
index 402e497..d337455 100644
@@ -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
@@ -253,6 +253,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);

lib/libmtd.c +5 -4
index 1606b87..56672bd 100644
@@ -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:
Signature · 7 lines
1.8.5.1


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#1 lore raw

Hi Dmitry,

Quoted 11 lines · Dmitry Lavnikevich

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).

Quoted 4 lines

Was tested on phyFLEX i.MX6.

Your patches look all good. Unfortunately I can't apply them because your mailer wraps lines.

drivers/mtd/core.c int add_mtd_device(struct mtd_info *mtd, char · line 402

Quoted 12 lines
drivers/mtd/core.c +1 -1
index 6db1c6d..7efb03c 100644
@@ -397,7 +397,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");

For example here.

Quoted 2 lines
drivers/mtd/core.c +0 -0
 	flash->mtd.read = m25p80_read;

diff --git a/drivers/mtd/devices/mtd_dataflash.c

Here is one space too much before 'diff'

include/linux/mtd/mtd-abi.h line 11

Quoted 8 lines
include/linux/mtd/mtd-abi.h +1 -0
index 11d51e2..c1ba55b 100644
@@ -9,6 +9,8 @@
  #ifndef DOXYGEN_SHOULD_SKIP_THIS
 +#include <asm-generic/div64.h>
+

Here also is one space too much.

Could you try resending it using git-send-email?

Sascha

Signature · 9 lines
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#2 lore raw

Hi Sascha,

we talked some time ago about >= 4GB mtd support. This patch series add only a size for uint64_t. But then we also need to change

uint32_t master_offset;

in mtd_info to:

uint64_t master_offset;

otherwise we can't create mtd partitions with a uint64_t offset. Or I am wrong with that? I mean... maybe they don't want to make a uint64_t offset but we should do it right at first time.

- Alex

_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox

#3 lore raw
Quoted 4 lines · Alexander Aring

Hi Sascha,

we talked some time ago about >= 4GB mtd support. This patch series add only a size for uint64_t. But then we also need to change

That even wasn't so long ago ;)

Quoted 10 lines

uint32_t master_offset;

in mtd_info to:

uint64_t master_offset;

otherwise we can't create mtd partitions with a uint64_t offset. Or I am wrong with that? I mean... maybe they don't want to make a uint64_t offset but we should do it right at first time.

Yes, right. We should make this uint64_t.

Sascha

Signature · 9 lines
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#5 lore raw
Quoted 8 lines · Alexander Aring
Quoted 4 lines · Sascha Hauer
Quoted 1 line

offset but we should do it right at first time.

Yes, right. We should make this uint64_t.

There are also more things which needs a uint64_t like the offset parameter of libmtd_* functions. :-/

The libmtd functions should be 64bit already. The remaining bits are in Dmitrys series.

Sascha

Signature · 9 lines
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#6 lore raw
In reply to Sascha Hauer

Hello Sascha,

eyah, I've had some problems sending mails with git send-email through my proxy so tried to use thunderbird to pass patches outside. Which apparently did some improvisation on them :)

Anyway, I have fixed my sendmail and will resend patches soon.

Best regards,
Lavnikevich Dmitry

Quoted 49 lines · Sascha Hauer

Hi Dmitry,

Quoted 11 lines · Dmitry Lavnikevich

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).

Quoted 4 lines

Was tested on phyFLEX i.MX6.

Your patches look all good. Unfortunately I can't apply them because your mailer wraps lines.

drivers/mtd/core.c int add_mtd_device(struct mtd_info *mtd, char · line 402

Quoted 12 lines
drivers/mtd/core.c +1 -1
index 6db1c6d..7efb03c 100644
@@ -397,7 +397,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");

For example here.

Quoted 2 lines
drivers/mtd/core.c +0 -0
  	flash->mtd.read = m25p80_read;
  diff --git a/drivers/mtd/devices/mtd_dataflash.c

Here is one space too much before 'diff'

include/linux/mtd/mtd-abi.h line 11

Quoted 8 lines
include/linux/mtd/mtd-abi.h +1 -0
index 11d51e2..c1ba55b 100644
@@ -9,6 +9,8 @@
   #ifndef DOXYGEN_SHOULD_SKIP_THIS
  +#include <asm-generic/div64.h>
+

Here also is one space too much.

Quoted 4 lines

Could you try resending it using git-send-email?

Sascha

_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox