summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-mxs/ocotp.c1
-rw-r--r--arch/sandbox/board/hostfile.c1
-rw-r--r--commands/Kconfig17
-rw-r--r--commands/Makefile1
-rw-r--r--commands/md.c12
-rw-r--r--commands/mem.c123
-rw-r--r--commands/memcmp.c16
-rw-r--r--commands/memcpy.c10
-rw-r--r--commands/memset.c2
-rw-r--r--commands/stddev.c4
-rw-r--r--common/block.c1
-rw-r--r--common/firmware.c2
-rw-r--r--common/ratp/md.c9
-rw-r--r--drivers/base/regmap/regmap.c1
-rw-r--r--drivers/eeprom/at24.c1
-rw-r--r--drivers/eeprom/at25.c1
-rw-r--r--drivers/hw_random/core.c1
-rw-r--r--drivers/mfd/act8846.c1
-rw-r--r--drivers/mfd/lp3972.c1
-rw-r--r--drivers/mfd/mc34704.c1
-rw-r--r--drivers/mfd/mc9sdz60.c1
-rw-r--r--drivers/mfd/stmpe-i2c.c1
-rw-r--r--drivers/mfd/twl-core.c1
-rw-r--r--drivers/misc/Kconfig3
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/mem.c73
-rw-r--r--drivers/misc/sram.c1
-rw-r--r--drivers/mtd/core.c1
-rw-r--r--drivers/mtd/mtdoob.c1
-rw-r--r--drivers/mtd/mtdraw.c1
-rw-r--r--drivers/mtd/nand/nand-bb.c7
-rw-r--r--drivers/mtd/ubi/barebox.c4
-rw-r--r--drivers/net/e1000/eeprom.c2
-rw-r--r--drivers/net/ksz8864rmn.c1
-rw-r--r--drivers/net/phy/mdio_bus.c1
-rw-r--r--drivers/nvmem/core.c2
-rw-r--r--drivers/video/fb.c1
-rw-r--r--drivers/w1/slaves/w1_ds2431.c1
-rw-r--r--drivers/w1/slaves/w1_ds2433.c1
-rw-r--r--fs/bpkfs.c4
-rw-r--r--fs/cramfs/cramfs.c7
-rw-r--r--fs/devfs-core.c52
-rw-r--r--fs/devfs.c22
-rw-r--r--fs/efi.c8
-rw-r--r--fs/efivarfs.c10
-rw-r--r--fs/ext4/ext_barebox.c8
-rw-r--r--fs/fat/fat.c7
-rw-r--r--fs/fs.c40
-rw-r--r--fs/nfs.c7
-rw-r--r--fs/omap4_usbbootfs.c9
-rw-r--r--fs/pstore/fs.c4
-rw-r--r--fs/ramfs.c9
-rw-r--r--fs/ratpfs.c11
-rw-r--r--fs/smhfs.c12
-rw-r--r--fs/squashfs/squashfs.c8
-rw-r--r--fs/tftp.c29
-rw-r--r--fs/ubifs/ubifs.c8
-rw-r--r--fs/uimagefs.c4
-rw-r--r--include/driver.h7
-rw-r--r--include/fs.h4
-rw-r--r--lib/libfile.c3
-rw-r--r--lib/misc.c42
62 files changed, 260 insertions, 365 deletions
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
index 01db731166..f230d9ad89 100644
--- a/arch/arm/mach-mxs/ocotp.c
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -174,7 +174,6 @@ free_mem:
static struct cdev_operations mxs_ocotp_ops = {
.read = mxs_ocotp_cdev_read,
- .lseek = dev_lseek_default,
};
static int mxs_ocotp_probe(struct device_d *dev)
diff --git a/arch/sandbox/board/hostfile.c b/arch/sandbox/board/hostfile.c
index 3fc1503799..745f078d1a 100644
--- a/arch/sandbox/board/hostfile.c
+++ b/arch/sandbox/board/hostfile.c
@@ -67,7 +67,6 @@ static void hf_info(struct device_d *dev)
static struct cdev_operations hf_fops = {
.read = hf_read,
.write = hf_write,
- .lseek = dev_lseek_default,
};
static int hf_probe(struct device_d *dev)
diff --git a/commands/Kconfig b/commands/Kconfig
index 1de4b9d604..c14332c9d7 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -14,11 +14,6 @@ config COMPILE_HASH
help
Turns on compilation of digest.c
-config COMPILE_MEMORY
- bool
- help
- Turns on compilation of mem.c
-
menu "Commands"
@@ -1493,7 +1488,7 @@ config CMD_CRC_CMP
config CMD_MD
tristate
default y
- select COMPILE_MEMORY
+ select DEV_MEM
prompt "md"
help
Memory display
@@ -1517,7 +1512,7 @@ config CMD_MD
config CMD_MEMCMP
tristate
default y
- select COMPILE_MEMORY
+ select DEV_MEM
prompt "memcmp"
help
Memory compare
@@ -1539,7 +1534,7 @@ config CMD_MEMCMP
config CMD_MEMCPY
tristate
default y
- select COMPILE_MEMORY
+ select DEV_MEM
prompt "memcpy"
help
Memory copy
@@ -1558,7 +1553,7 @@ config CMD_MEMCPY
config CMD_MEMSET
tristate
default y
- select COMPILE_MEMORY
+ select DEV_MEM
prompt "memset"
help
Memory fill
@@ -1591,7 +1586,7 @@ config CMD_MEMTEST
config CMD_MM
tristate
- select COMPILE_MEMORY
+ select DEV_MEM
prompt "memory modify (mm)"
help
Memory modify with mask
@@ -1609,7 +1604,7 @@ config CMD_MM
config CMD_MW
tristate
default y
- select COMPILE_MEMORY
+ select DEV_MEM
prompt "mw"
help
Memory write
diff --git a/commands/Makefile b/commands/Makefile
index eb4796389e..358671bb5b 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -1,7 +1,6 @@
obj-$(CONFIG_STDDEV) += stddev.o
obj-$(CONFIG_CMD_DIGEST) += digest.o
obj-$(CONFIG_COMPILE_HASH) += hashsum.o
-obj-$(CONFIG_COMPILE_MEMORY) += mem.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o
obj-$(CONFIG_CMD_UIMAGE) += uimage.o
obj-$(CONFIG_CMD_LINUX16) += linux16.o
diff --git a/commands/md.c b/commands/md.c
index a495fc8b41..2389c12d14 100644
--- a/commands/md.c
+++ b/commands/md.c
@@ -34,8 +34,6 @@
#include <linux/stat.h>
#include <xfuncs.h>
-extern char *mem_rw_buf;
-
static int do_mem_md(int argc, char *argv[])
{
loff_t start = 0, size = 0x100;
@@ -46,6 +44,7 @@ static int do_mem_md(int argc, char *argv[])
int mode = O_RWSIZE_4;
int swab = 0;
void *map;
+ void *buf = NULL;
if (argc < 2)
return COMMAND_ERROR_USAGE;
@@ -74,9 +73,11 @@ static int do_mem_md(int argc, char *argv[])
goto out;
}
+ buf = xmalloc(RW_BUF_SIZE);
+
do {
now = min(size, (loff_t)RW_BUF_SIZE);
- r = read(fd, mem_rw_buf, now);
+ r = read(fd, buf, now);
if (r < 0) {
perror("read");
goto out;
@@ -84,8 +85,8 @@ static int do_mem_md(int argc, char *argv[])
if (!r)
goto out;
- if ((ret = memory_display(mem_rw_buf, start, r,
- mode >> O_RWSIZE_SHIFT, swab)))
+ if ((ret = memory_display(buf, start, r,
+ mode >> O_RWSIZE_SHIFT, swab)))
goto out;
start += r;
@@ -93,6 +94,7 @@ static int do_mem_md(int argc, char *argv[])
} while (size);
out:
+ free(buf);
close(fd);
return ret ? 1 : 0;
diff --git a/commands/mem.c b/commands/mem.c
deleted file mode 100644
index a9e12f3e55..0000000000
--- a/commands/mem.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2011 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-/*
- * Memory Functions
- *
- * Copied from FADS ROM, Dan Malek (dmalek@jlc.net)
- */
-
-#include <common.h>
-#include <command.h>
-#include <init.h>
-#include <driver.h>
-#include <malloc.h>
-#include <errno.h>
-#include <fs.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <linux/stat.h>
-#include <xfuncs.h>
-
-#ifdef CMD_MEM_DEBUG
-#define PRINTF(fmt,args...) printf (fmt ,##args)
-#else
-#define PRINTF(fmt,args...)
-#endif
-
-char *mem_rw_buf;
-
-/*
- * Common function for parsing options for the 'md', 'mw', 'memcpy', 'memcmp'
- * commands.
- */
-int mem_parse_options(int argc, char *argv[], char *optstr, int *mode,
- char **sourcefile, char **destfile, int *swab)
-{
- int opt;
-
- while((opt = getopt(argc, argv, optstr)) > 0) {
- switch(opt) {
- case 'b':
- *mode = O_RWSIZE_1;
- break;
- case 'w':
- *mode = O_RWSIZE_2;
- break;
- case 'l':
- *mode = O_RWSIZE_4;
- break;
- case 'q':
- *mode = O_RWSIZE_8;
- break;
- case 's':
- *sourcefile = optarg;
- break;
- case 'd':
- *destfile = optarg;
- break;
- case 'x':
- *swab = 1;
- break;
- default:
- return COMMAND_ERROR_USAGE;
- }
- }
-
- return 0;
-}
-
-static struct cdev_operations memops = {
- .read = mem_read,
- .write = mem_write,
- .memmap = generic_memmap_rw,
- .lseek = dev_lseek_default,
-};
-
-static int mem_probe(struct device_d *dev)
-{
- struct cdev *cdev;
-
- cdev = xzalloc(sizeof (*cdev));
- dev->priv = cdev;
-
- cdev->name = (char*)dev->resource[0].name;
- cdev->size = min_t(unsigned long long, resource_size(&dev->resource[0]),
- S64_MAX);
- cdev->ops = &memops;
- cdev->dev = dev;
-
- devfs_create(cdev);
-
- return 0;
-}
-
-static struct driver_d mem_drv = {
- .name = "mem",
- .probe = mem_probe,
-};
-
-static int mem_init(void)
-{
- mem_rw_buf = malloc(RW_BUF_SIZE);
- if(!mem_rw_buf)
- return -ENOMEM;
-
- add_mem_device("mem", 0, ~0, IORESOURCE_MEM_WRITEABLE);
- return platform_driver_register(&mem_drv);
-}
-device_initcall(mem_init);
diff --git a/commands/memcmp.c b/commands/memcmp.c
index 981c8cb38d..48957b4500 100644
--- a/commands/memcmp.c
+++ b/commands/memcmp.c
@@ -34,8 +34,6 @@
#include <linux/stat.h>
#include <xfuncs.h>
-extern char *mem_rw_buf;
-
static char *devmem = "/dev/mem";
static int do_memcmp(int argc, char *argv[])
@@ -45,7 +43,7 @@ static int do_memcmp(int argc, char *argv[])
char *sourcefile = devmem;
char *destfile = devmem;
int sourcefd, destfd;
- char *rw_buf1;
+ char *buf, *source_data, *dest_data;
int ret = 1;
int offset = 0;
struct stat statbuf;
@@ -84,20 +82,22 @@ static int do_memcmp(int argc, char *argv[])
return 1;
}
- rw_buf1 = xmalloc(RW_BUF_SIZE);
+ buf = xmalloc(RW_BUF_SIZE + RW_BUF_SIZE);
+ source_data = buf;
+ dest_data = buf + RW_BUF_SIZE;
while (count > 0) {
int now, r1, r2, i;
now = min((loff_t)RW_BUF_SIZE, count);
- r1 = read_full(sourcefd, mem_rw_buf, now);
+ r1 = read_full(sourcefd, source_data, now);
if (r1 < 0) {
perror("read");
goto out;
}
- r2 = read_full(destfd, rw_buf1, now);
+ r2 = read_full(destfd, dest_data, now);
if (r2 < 0) {
perror("read");
goto out;
@@ -109,7 +109,7 @@ static int do_memcmp(int argc, char *argv[])
}
for (i = 0; i < now; i++) {
- if (mem_rw_buf[i] != rw_buf1[i]) {
+ if (source_data[i] != dest_data[i]) {
printf("files differ at offset %d\n", offset);
goto out;
}
@@ -124,7 +124,7 @@ static int do_memcmp(int argc, char *argv[])
out:
close(sourcefd);
close(destfd);
- free(rw_buf1);
+ free(buf);
return ret;
}
diff --git a/commands/memcpy.c b/commands/memcpy.c
index 168ef3b4fc..ddaf767eac 100644
--- a/commands/memcpy.c
+++ b/commands/memcpy.c
@@ -34,8 +34,6 @@
#include <linux/stat.h>
#include <xfuncs.h>
-extern char *mem_rw_buf;
-
static char *devmem = "/dev/mem";
static int do_memcpy(int argc, char *argv[])
@@ -47,6 +45,7 @@ static int do_memcpy(int argc, char *argv[])
int mode = 0;
struct stat statbuf;
int ret = 0;
+ char *buf;
if (mem_parse_options(argc, argv, "bwlqs:d:", &mode, &sourcefile,
&destfile, NULL) < 0)
@@ -82,12 +81,14 @@ static int do_memcpy(int argc, char *argv[])
return 1;
}
+ buf = xmalloc(RW_BUF_SIZE);
+
while (count > 0) {
int now, r, w, tmp;
now = min((loff_t)RW_BUF_SIZE, count);
- r = read(sourcefd, mem_rw_buf, now);
+ r = read(sourcefd, buf, now);
if (r < 0) {
perror("read");
goto out;
@@ -99,7 +100,7 @@ static int do_memcpy(int argc, char *argv[])
tmp = 0;
now = r;
while (now) {
- w = write(destfd, mem_rw_buf + tmp, now);
+ w = write(destfd, buf + tmp, now);
if (w < 0) {
perror("write");
goto out;
@@ -123,6 +124,7 @@ static int do_memcpy(int argc, char *argv[])
}
out:
+ free(buf);
close(sourcefd);
close(destfd);
diff --git a/commands/memset.c b/commands/memset.c
index f99bf86c04..b0770159f8 100644
--- a/commands/memset.c
+++ b/commands/memset.c
@@ -34,8 +34,6 @@
#include <linux/stat.h>
#include <xfuncs.h>
-extern char *mem_rw_buf;
-
static int do_memset(int argc, char *argv[])
{
loff_t s, c, n;
diff --git a/commands/stddev.c b/commands/stddev.c
index 4d1b6f5108..2b3d084c83 100644
--- a/commands/stddev.c
+++ b/commands/stddev.c
@@ -27,7 +27,6 @@ static ssize_t zero_read(struct cdev *cdev, void *buf, size_t count, loff_t offs
static struct cdev_operations zeroops = {
.read = zero_read,
- .lseek = dev_lseek_default,
};
static int zero_init(void)
@@ -55,7 +54,6 @@ static ssize_t full_read(struct cdev *cdev, void *buf, size_t count, loff_t offs
static struct cdev_operations fullops = {
.read = full_read,
- .lseek = dev_lseek_default,
};
static int full_init(void)
@@ -82,7 +80,6 @@ static ssize_t null_write(struct cdev *cdev, const void *buf, size_t count, loff
static struct cdev_operations nullops = {
.write = null_write,
- .lseek = dev_lseek_default,
};
static int null_init(void)
@@ -110,7 +107,6 @@ static ssize_t prng_read(struct cdev *cdev, void *buf, size_t count, loff_t offs
static struct cdev_operations prngops = {
.read = prng_read,
- .lseek = dev_lseek_default,
};
static int prng_init(void)
diff --git a/common/block.c b/common/block.c
index 8d0de42d90..d90c98948c 100644
--- a/common/block.c
+++ b/common/block.c
@@ -350,7 +350,6 @@ static struct cdev_operations block_ops = {
#endif
.close = block_op_close,
.flush = block_op_flush,
- .lseek = dev_lseek_default,
};
int blockdevice_register(struct block_device *blk)
diff --git a/common/firmware.c b/common/firmware.c
index 250fef5378..9d55d73e7a 100644
--- a/common/firmware.c
+++ b/common/firmware.c
@@ -177,7 +177,7 @@ int firmwaremgr_register(struct firmware_handler *fh)
cdev = &mgr->cdev;
cdev->name = xstrdup(fh->id);
- cdev->size = FILE_SIZE_STREAM;
+ cdev->flags = DEVFS_IS_CHARACTER_DEV;
cdev->ops = &firmware_ops;
cdev->priv = mgr;
cdev->dev = fh->dev;
diff --git a/common/ratp/md.c b/common/ratp/md.c
index ce343d7c7b..a25cbf1127 100644
--- a/common/ratp/md.c
+++ b/common/ratp/md.c
@@ -59,8 +59,6 @@ struct ratp_bb_md_response {
uint8_t buffer[];
} __packed;
-extern char *mem_rw_buf;
-
static int do_ratp_mem_md(const char *filename,
loff_t start,
loff_t size,
@@ -70,6 +68,7 @@ static int do_ratp_mem_md(const char *filename,
int ret = 0;
int fd;
void *map;
+ char *buf = NULL;
fd = open_and_lseek(filename, O_RWSIZE_1 | O_RDONLY, start);
if (fd < 0)
@@ -81,10 +80,11 @@ static int do_ratp_mem_md(const char *filename,
goto out;
}
+ buf = xmalloc(RW_BUF_SIZE);
t = 0;
do {
now = min(size, (loff_t)RW_BUF_SIZE);
- r = read(fd, mem_rw_buf, now);
+ r = read(fd, buf, now);
if (r < 0) {
ret = -errno;
perror("read");
@@ -93,13 +93,14 @@ static int do_ratp_mem_md(const char *filename,
if (!r)
goto out;
- memcpy(output + t, (uint8_t *)(mem_rw_buf), r);
+ memcpy(output + t, buf, r);
size -= r;
t += r;
} while (size);
out:
+ free(buf);
close(fd);
return ret;
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 8bbc2373fc..d2f8ec70e4 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -353,7 +353,6 @@ static ssize_t regmap_cdev_write(struct cdev *cdev, const void *buf, size_t coun
}
static struct cdev_operations regmap_fops = {
- .lseek = dev_lseek_default,
.read = regmap_cdev_read,
.write = regmap_cdev_write,
};
diff --git a/drivers/eeprom/at24.c b/drivers/eeprom/at24.c
index e79031a2d3..1fd4aeaba6 100644
--- a/drivers/eeprom/at24.c
+++ b/drivers/eeprom/at24.c
@@ -447,7 +447,6 @@ static int at24_probe(struct device_d *dev)
at24->cdev.priv = at24;
at24->cdev.dev = dev;
at24->cdev.ops = &at24->fops;
- at24->fops.lseek = dev_lseek_default;
at24->fops.read = at24_cdev_read,
at24->fops.protect = at24_cdev_protect,
at24->cdev.size = chip.byte_len;
diff --git a/drivers/eeprom/at25.c b/drivers/eeprom/at25.c
index a9050d6c16..1c9ef12321 100644
--- a/drivers/eeprom/at25.c
+++ b/drivers/eeprom/at25.c
@@ -235,7 +235,6 @@ static ssize_t at25_ee_write(struct cdev *cdev,
static struct cdev_operations at25_fops = {
.read = at25_ee_read,
.write = at25_ee_write,
- .lseek = dev_lseek_default,
};
static int at25_np_to_chip(struct device_d *dev,
diff --git a/drivers/hw_random/core.c b/drivers/hw_random/core.c
index 1c68a379f7..ee3d5a52dd 100644
--- a/drivers/hw_random/core.c
+++ b/drivers/hw_random/core.c
@@ -63,7 +63,6 @@ static ssize_t rng_dev_read(struct cdev *cdev, void *buf, size_t size,
static struct cdev_operations rng_chrdev_ops = {
.read = rng_dev_read,
- .lseek = dev_lseek_default,
};
static int hwrng_register_cdev(struct hwrng *rng)
diff --git a/drivers/mfd/act8846.c b/drivers/mfd/act8846.c
index 53ab70f5cc..b7a64c739c 100644
--- a/drivers/mfd/act8846.c
+++ b/drivers/mfd/act8846.c
@@ -117,7 +117,6 @@ static ssize_t act8846_write(struct cdev *cdev, const void *_buf, size_t count,
}
static struct cdev_operations act8846_fops = {
- .lseek = dev_lseek_default,
.read = act8846_read,
.write = act8846_write,
};
diff --git a/drivers/mfd/lp3972.c b/drivers/mfd/lp3972.c
index 42b28070ad..3ae9d1ac64 100644
--- a/drivers/mfd/lp3972.c
+++ b/drivers/mfd/lp3972.c
@@ -70,7 +70,6 @@ static ssize_t lp_read(struct cdev *cdev, void *_buf, size_t count, loff_t offse
}
static struct cdev_operations lp_fops = {
- .lseek = dev_lseek_default,
.read = lp_read,
};
diff --git a/drivers/mfd/mc34704.c b/drivers/mfd/mc34704.c
index f15f37ef6e..4aa02b74ff 100644
--- a/drivers/mfd/mc34704.c
+++ b/drivers/mfd/mc34704.c
@@ -100,7 +100,6 @@ static ssize_t mc34704_write(struct cdev *cdev, const void *_buf, size_t count,
}
static struct cdev_operations mc34704_fops = {
- .lseek = dev_lseek_default,
.read = mc34704_read,
.write = mc34704_write,
};
diff --git a/drivers/mfd/mc9sdz60.c b/drivers/mfd/mc9sdz60.c
index 2cb38d9784..408d746450 100644
--- a/drivers/mfd/mc9sdz60.c
+++ b/drivers/mfd/mc9sdz60.c
@@ -112,7 +112,6 @@ static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count, loff_
}
static struct cdev_operations mc_fops = {
- .lseek = dev_lseek_default,
.read = mc_read,
.write = mc_write,
};
diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c
index 084e4b43bb..f140f1bbc4 100644
--- a/drivers/mfd/stmpe-i2c.c
+++ b/drivers/mfd/stmpe-i2c.c
@@ -101,7 +101,6 @@ static ssize_t stmpe_write(struct cdev *cdev, const void *_buf, size_t count, lo
}
static struct cdev_operations stmpe_fops = {
- .lseek = dev_lseek_default,
.read = stmpe_read,
.write = stmpe_write,
};
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index fb435f510f..c3240b8542 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -150,7 +150,6 @@ static ssize_t twl_write(struct cdev *cdev, const void *_buf, size_t count,
}
struct cdev_operations twl_fops = {
- .lseek = dev_lseek_default,
.read = twl_read,
.write = twl_write,
};
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 6640a70792..4c8a769c4c 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -20,4 +20,7 @@ config STATE_DRV
depends on OFDEVICE
depends on STATE
+config DEV_MEM
+ bool "Generic memory I/O device (/dev/mem)"
+
endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 487e4b8ba2..d4e616d51a 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -5,3 +5,4 @@
obj-$(CONFIG_JTAG) += jtag.o
obj-$(CONFIG_SRAM) += sram.o
obj-$(CONFIG_STATE_DRV) += state.o
+obj-$(CONFIG_DEV_MEM) += mem.o
diff --git a/drivers/misc/mem.c b/drivers/misc/mem.c
new file mode 100644
index 0000000000..6dd7f687c9
--- /dev/null
+++ b/drivers/misc/mem.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2011 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+
+static struct cdev_operations memops = {
+ .read = mem_read,
+ .write = mem_write,
+ .memmap = generic_memmap_rw,
+};
+
+static int mem_probe(struct device_d *dev)
+{
+ struct cdev *cdev;
+
+ cdev = xzalloc(sizeof (*cdev));
+ dev->priv = cdev;
+
+ cdev->name = (char*)dev->resource[0].name;
+ if (dev->resource[0].start == 0 && dev->resource[0].end == ~0) {
+ /*
+ * Special case for /dev/mem. We can't express it's size as it's
+ * outside of our address range. Set DEVFS_IS_CHARACTER_DEV to
+ * bypass size checks.
+ */
+ cdev->size = 0;
+ cdev->flags = DEVFS_IS_CHARACTER_DEV;
+ } else {
+ cdev->size = resource_size(&dev->resource[0]);
+ }
+
+ cdev->ops = &memops;
+ cdev->dev = dev;
+
+ devfs_create(cdev);
+
+ return 0;
+}
+
+static struct driver_d mem_drv = {
+ .name = "mem",
+ .probe = mem_probe,
+};
+
+static int mem_init(void)
+{
+ struct device_d *dev;
+ struct resource res = {
+ .start = 0,
+ .end = ~0,
+ .flags = IORESOURCE_MEM,
+ .name = "mem",
+ };
+ int ret;
+
+ dev = device_alloc("mem", DEVICE_ID_DYNAMIC);
+ if (!dev)
+ return -ENOMEM;
+
+ dev->resource = xmemdup(&res, sizeof(res));
+ dev->num_resources = 1;
+
+ ret = platform_device_register(dev);
+ if (ret)
+ return ret;
+
+ return platform_driver_register(&mem_drv);
+}
+device_initcall(mem_init);
diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c
index 27b4c681fd..053b35150c 100644
--- a/drivers/misc/sram.c
+++ b/drivers/misc/sram.c
@@ -29,7 +29,6 @@ static struct cdev_operations memops = {
.read = mem_read,
.write = mem_write,
.memmap = generic_memmap_rw,
- .lseek = dev_lseek_default,
};
static int sram_probe(struct device_d *dev)
diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index f44c6cfc69..881b5f4864 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -462,7 +462,6 @@ static struct cdev_operations mtd_ops = {
.protect = mtd_op_protect,
#endif
.ioctl = mtd_ioctl,
- .lseek = dev_lseek_default,
};
static int mtd_partition_set(struct param_d *p, void *priv)
diff --git a/drivers/mtd/mtdoob.c b/drivers/mtd/mtdoob.c
index ffaf9506f3..4aef844485 100644
--- a/drivers/mtd/mtdoob.c
+++ b/drivers/mtd/mtdoob.c
@@ -66,7 +66,6 @@ static ssize_t mtd_op_read_oob(struct cdev *cdev, void *buf, size_t count,
static struct cdev_operations mtd_ops_oob = {
.read = mtd_op_read_oob,
.ioctl = mtd_ioctl,
- .lseek = dev_lseek_default,
};
static int add_mtdoob_device(struct mtd_info *mtd, const char *devname, void **priv)
diff --git a/drivers/mtd/mtdraw.c b/drivers/mtd/mtdraw.c
index 6e36dc5337..f63da7b3b2 100644
--- a/drivers/mtd/mtdraw.c
+++ b/drivers/mtd/mtdraw.c
@@ -291,7 +291,6 @@ static const struct cdev_operations mtd_raw_fops = {
.read = mtdraw_read,
.write = mtdraw_write,
.erase = mtdraw_erase,
- .lseek = dev_lseek_default,
};
static int add_mtdraw_device(struct mtd_info *mtd, const char *devname, void **priv)
diff --git a/drivers/mtd/nand/nand-bb.c b/drivers/mtd/nand/nand-bb.c
index 012163ebb2..e578d72a49 100644
--- a/drivers/mtd/nand/nand-bb.c
+++ b/drivers/mtd/nand/nand-bb.c
@@ -236,17 +236,16 @@ static int nand_bb_calc_size(struct nand_bb *bb)
return 0;
}
-static loff_t nand_bb_lseek(struct cdev *cdev, loff_t __offset)
+static int nand_bb_lseek(struct cdev *cdev, loff_t offset)
{
struct nand_bb *bb = cdev->priv;
loff_t raw_pos = 0;
- uint32_t offset = __offset;
/* lseek only in readonly mode */
if (bb->flags & O_ACCMODE)
return -ENOSYS;
while (raw_pos < bb->mtd->size) {
- off_t now = min(offset, bb->mtd->erasesize);
+ off_t now = min_t(loff_t, offset, bb->mtd->erasesize);
if (mtd_block_isbad(bb->mtd, raw_pos)) {
raw_pos += bb->mtd->erasesize;
@@ -257,7 +256,7 @@ static loff_t nand_bb_lseek(struct cdev *cdev, loff_t __offset)
if (!offset) {
bb->offset = raw_pos;
- return __offset;
+ return 0;
}
}
diff --git a/drivers/mtd/ubi/barebox.c b/drivers/mtd/ubi/barebox.c
index 65f5456455..781061d9a7 100644
--- a/drivers/mtd/ubi/barebox.c
+++ b/drivers/mtd/ubi/barebox.c
@@ -151,7 +151,7 @@ static int ubi_volume_cdev_close(struct cdev *cdev)
return 0;
}
-static loff_t ubi_volume_cdev_lseek(struct cdev *cdev, loff_t ofs)
+static int ubi_volume_cdev_lseek(struct cdev *cdev, loff_t ofs)
{
struct ubi_volume_cdev_priv *priv = cdev->priv;
@@ -159,7 +159,7 @@ static loff_t ubi_volume_cdev_lseek(struct cdev *cdev, loff_t ofs)
if (priv->written)
return -EINVAL;
- return ofs;
+ return 0;
}
static int ubi_volume_cdev_truncate(struct cdev *cdev, size_t size)
diff --git a/drivers/net/e1000/eeprom.c b/drivers/net/e1000/eeprom.c
index 36d818b3f3..5b34e9b8d1 100644
--- a/drivers/net/e1000/eeprom.c
+++ b/drivers/net/e1000/eeprom.c
@@ -1326,7 +1326,6 @@ exit:
static struct cdev_operations e1000_invm_ops = {
.read = e1000_invm_cdev_read,
.write = e1000_invm_cdev_write,
- .lseek = dev_lseek_default,
};
static ssize_t e1000_eeprom_cdev_read(struct cdev *cdev, void *buf,
@@ -1351,7 +1350,6 @@ static ssize_t e1000_eeprom_cdev_read(struct cdev *cdev, void *buf,
static struct cdev_operations e1000_eeprom_ops = {
.read = e1000_eeprom_cdev_read,
- .lseek = dev_lseek_default,
};
static int e1000_mtd_read_or_write(bool read,
diff --git a/drivers/net/ksz8864rmn.c b/drivers/net/ksz8864rmn.c
index 4a19dd8734..85063ff0d8 100644
--- a/drivers/net/ksz8864rmn.c
+++ b/drivers/net/ksz8864rmn.c
@@ -113,7 +113,6 @@ static ssize_t micel_switch_write(struct cdev *cdev, const void *_buf, size_t co
static struct cdev_operations micrel_switch_ops = {
.read = micel_switch_read,
.write = micel_switch_write,
- .lseek = dev_lseek_default,
};
static int micrel_switch_probe(struct device_d *dev)
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index e1dd8f0ae3..3480e2ffb4 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -392,7 +392,6 @@ static ssize_t phydev_write(struct cdev *cdev, const void *_buf, size_t count, l
static struct cdev_operations phydev_ops = {
.read = phydev_read,
.write = phydev_write,
- .lseek = dev_lseek_default,
};
static void of_set_phy_supported(struct phy_device *phydev)
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 63c0f997b3..6cf98f62af 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -85,7 +85,6 @@ static ssize_t nvmem_cdev_write(struct cdev *cdev, const void *buf, size_t count
static struct cdev_operations nvmem_chrdev_ops = {
.read = nvmem_cdev_read,
.write = nvmem_cdev_write,
- .lseek = dev_lseek_default,
};
static int nvmem_register_cdev(struct nvmem_device *nvmem, const char *name)
@@ -96,7 +95,6 @@ static int nvmem_register_cdev(struct nvmem_device *nvmem, const char *name)
alias = of_alias_get(dev->device_node);
nvmem->cdev.name = xstrdup(alias ?: name);
- nvmem->cdev.flags = DEVFS_IS_CHARACTER_DEV;
nvmem->cdev.ops = &nvmem_chrdev_ops;
nvmem->cdev.dev = &nvmem->dev;
nvmem->cdev.size = nvmem->size;
diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index 72f33a6db6..2d82bc01fa 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -228,7 +228,6 @@ static struct cdev_operations fb_ops = {
.read = mem_read,
.write = mem_write,
.memmap = generic_memmap_rw,
- .lseek = dev_lseek_default,
.ioctl = fb_ioctl,
.close = fb_close,
.flush = fb_op_flush,
diff --git a/drivers/w1/slaves/w1_ds2431.c b/drivers/w1/slaves/w1_ds2431.c
index 13691d7bab..6446f4ba05 100644
--- a/drivers/w1/slaves/w1_ds2431.c
+++ b/drivers/w1/slaves/w1_ds2431.c
@@ -260,7 +260,6 @@ out_up:
static struct cdev_operations ds2431_ops = {
.read = ds2431_cdev_read,
.write = ds2431_cdev_write,
- .lseek = dev_lseek_default,
};
static int ds2431_probe(struct w1_device *dev)
diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c
index f521a46a75..b24fb5b3b5 100644
--- a/drivers/w1/slaves/w1_ds2433.c
+++ b/drivers/w1/slaves/w1_ds2433.c
@@ -159,7 +159,6 @@ out_up:
static struct cdev_operations ds2433_ops = {
.read = ds2433_cdev_read,
.write = ds2433_cdev_write,
- .lseek = dev_lseek_default,
};
static int ds2433_cdev_create(struct w1_device *dev, int size, int id)
diff --git a/fs/bpkfs.c b/fs/bpkfs.c
index f1db963d09..655cde09b7 100644
--- a/fs/bpkfs.c
+++ b/fs/bpkfs.c
@@ -192,7 +192,7 @@ static int bpkfs_read(struct device_d *dev, FILE *file, void *buf, size_t insize
}
}
-static loff_t bpkfs_lseek(struct device_d *dev, FILE *file, loff_t pos)
+static int bpkfs_lseek(struct device_d *dev, FILE *file, loff_t pos)
{
struct bpkfs_handle_data *d = file->priv;
@@ -201,7 +201,7 @@ static loff_t bpkfs_lseek(struct device_d *dev, FILE *file, loff_t pos)
d->pos = pos;
- return pos;
+ return 0;
}
struct somfy_readdir {
diff --git a/fs/cramfs/cramfs.c b/fs/cramfs/cramfs.c
index a3ce354c92..3cc0fa787c 100644
--- a/fs/cramfs/cramfs.c
+++ b/fs/cramfs/cramfs.c
@@ -166,12 +166,6 @@ static int cramfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size)
return cramfs_read_file(f->f_inode, f->pos, buf, size);
}
-static loff_t cramfs_lseek(struct device_d *dev, FILE *f, loff_t pos)
-{
- f->pos = pos;
- return f->pos;
-}
-
#if 0
static int cramfs_info (struct device_d *dev)
{
@@ -491,7 +485,6 @@ static void cramfs_remove(struct device_d *dev)
static struct fs_driver_d cramfs_driver = {
.read = cramfs_read,
- .lseek = cramfs_lseek,
.drv = {
.probe = cramfs_probe,
.remove = cramfs_remove,
diff --git a/fs/devfs-core.c b/fs/devfs-core.c
index f017e1c55d..2b93a951f2 100644
--- a/fs/devfs-core.c
+++ b/fs/devfs-core.c
@@ -459,7 +459,6 @@ static const struct cdev_operations loop_ops = {
.read = loop_read,
.write = loop_write,
.memmap = generic_memmap_rw,
- .lseek = dev_lseek_default,
};
struct cdev *cdev_create_loop(const char *path, ulong flags, loff_t offset)
@@ -512,19 +511,29 @@ void cdev_remove_loop(struct cdev *cdev)
free(cdev);
}
-static void memcpy_sz(void *dst, const void *src, size_t count, int rwsize)
+static ssize_t mem_copy(struct device_d *dev, void *dst, const void *src,
+ resource_size_t count, resource_size_t offset,
+ unsigned long flags)
{
+ ssize_t size;
+ int rwsize = flags & O_RWSIZE_MASK;
+
+ if (!dev || dev->num_resources < 1)
+ return -1;
+
+ count = size = min(count, resource_size(&dev->resource[0]) - offset);
+
/* no rwsize specification given. Do whatever memcpy likes best */
if (!rwsize) {
memcpy(dst, src, count);
- return;
+ goto out;
}
rwsize = rwsize >> O_RWSIZE_SHIFT;
- count /= rwsize;
+ count = ALIGN_DOWN(count, rwsize);
- while (count-- > 0) {
+ while (count) {
switch (rwsize) {
case 1:
*((u8 *)dst) = *((u8 *)src);
@@ -541,41 +550,34 @@ static void memcpy_sz(void *dst, const void *src, size_t count, int rwsize)
}
dst += rwsize;
src += rwsize;
+ count -= rwsize;
}
+out:
+ return size;
}
ssize_t mem_read(struct cdev *cdev, void *buf, size_t count, loff_t offset,
unsigned long flags)
{
- unsigned long size;
- struct device_d *dev;
+ struct device_d *dev = cdev->dev;
- if (!cdev->dev || cdev->dev->num_resources < 1)
+ if (!dev)
return -1;
- dev = cdev->dev;
- size = min((resource_size_t)count,
- resource_size(&dev->resource[0]) -
- (resource_size_t)offset);
- memcpy_sz(buf, dev_get_mem_region(dev, 0) + offset, size, flags & O_RWSIZE_MASK);
- return size;
+ return mem_copy(dev, buf, dev_get_mem_region(dev, 0) + offset,
+ count, offset, flags);
}
EXPORT_SYMBOL(mem_read);
-ssize_t mem_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset,
- unsigned long flags)
+ssize_t mem_write(struct cdev *cdev, const void *buf, size_t count,
+ loff_t offset, unsigned long flags)
{
- unsigned long size;
- struct device_d *dev;
+ struct device_d *dev = cdev->dev;
- if (!cdev->dev || cdev->dev->num_resources < 1)
+ if (!dev)
return -1;
- dev = cdev->dev;
- size = min((resource_size_t)count,
- resource_size(&dev->resource[0]) -
- (resource_size_t)offset);
- memcpy_sz(dev_get_mem_region(dev, 0) + offset, buf, size, flags & O_RWSIZE_MASK);
- return size;
+ return mem_copy(dev, dev_get_mem_region(dev, 0) + offset, buf,
+ count, offset, flags);
}
EXPORT_SYMBOL(mem_write);
diff --git a/fs/devfs.c b/fs/devfs.c
index 81ae2c25a5..a7400df1c5 100644
--- a/fs/devfs.c
+++ b/fs/devfs.c
@@ -57,18 +57,18 @@ static int devfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t s
return cdev_write(cdev, buf, size, f->pos, f->flags);
}
-static loff_t devfs_lseek(struct device_d *_dev, FILE *f, loff_t pos)
+static int devfs_lseek(struct device_d *_dev, FILE *f, loff_t pos)
{
struct cdev *cdev = f->priv;
- loff_t ret = -1;
+ int ret;
- if (cdev->ops->lseek)
+ if (cdev->ops->lseek) {
ret = cdev->ops->lseek(cdev, pos + cdev->offset);
+ if (ret < 0)
+ return ret;
+ }
- if (ret != -1)
- f->pos = pos;
-
- return ret - cdev->offset;
+ return 0;
}
static int devfs_erase(struct device_d *_dev, FILE *f, loff_t count, loff_t offset)
@@ -168,18 +168,14 @@ static int devfs_ioctl(struct device_d *_dev, FILE *f, int request, void *buf)
return cdev_ioctl(cdev, request, buf);
}
-static int devfs_truncate(struct device_d *dev, FILE *f, ulong size)
+static int devfs_truncate(struct device_d *dev, FILE *f, loff_t size)
{
struct cdev *cdev = f->priv;
if (cdev->ops->truncate)
return cdev->ops->truncate(cdev, size);
- if (f->fsdev->dev.num_resources < 1)
- return -ENOSPC;
- if (size > resource_size(&f->fsdev->dev.resource[0]))
- return -ENOSPC;
- return 0;
+ return -EPERM;
}
static struct inode *devfs_alloc_inode(struct super_block *sb)
diff --git a/fs/efi.c b/fs/efi.c
index 692556b260..81c1ffe078 100644
--- a/fs/efi.c
+++ b/fs/efi.c
@@ -292,22 +292,20 @@ static int efifs_write(struct device_d *_dev, FILE *f, const void *buf, size_t i
return bufsize;
}
-static loff_t efifs_lseek(struct device_d *dev, FILE *f, loff_t pos)
+static int efifs_lseek(struct device_d *dev, FILE *f, loff_t pos)
{
struct efifs_file *ufile = f->priv;
efi_status_t efiret;
- f->pos = pos;
-
efiret = ufile->entry->set_position(ufile->entry, pos);
if (EFI_ERROR(efiret)) {
return -efi_errno(efiret);
}
- return f->pos;
+ return 0;
}
-static int efifs_truncate(struct device_d *dev, FILE *f, unsigned long size)
+static int efifs_truncate(struct device_d *dev, FILE *f, loff_t size)
{
struct efifs_file *ufile = f->priv;
efi_status_t efiret;
diff --git a/fs/efivarfs.c b/fs/efivarfs.c
index bf7351e6db..a911eac3bf 100644
--- a/fs/efivarfs.c
+++ b/fs/efivarfs.c
@@ -288,7 +288,7 @@ static int efivarfs_write(struct device_d *_dev, FILE *f, const void *buf, size_
return insize;
}
-static int efivarfs_truncate(struct device_d *dev, FILE *f, ulong size)
+static int efivarfs_truncate(struct device_d *dev, FILE *f, loff_t size)
{
struct efivars_file *efile = f->priv;
efi_status_t efiret;
@@ -307,13 +307,6 @@ static int efivarfs_truncate(struct device_d *dev, FILE *f, ulong size)
return 0;
}
-static loff_t efivarfs_lseek(struct device_d *dev, FILE *f, loff_t pos)
-{
- f->pos = pos;
-
- return f->pos;
-}
-
static DIR *efivarfs_opendir(struct device_d *dev, const char *pathname)
{
struct efivarfs_priv *priv = dev->priv;
@@ -437,7 +430,6 @@ static struct fs_driver_d efivarfs_driver = {
.read = efivarfs_read,
.write = efivarfs_write,
.truncate = efivarfs_truncate,
- .lseek = efivarfs_lseek,
.opendir = efivarfs_opendir,
.readdir = efivarfs_readdir,
.closedir = efivarfs_closedir,
diff --git a/fs/ext4/ext_barebox.c b/fs/ext4/ext_barebox.c
index 1e7da2a4b4..82d4c581e0 100644
--- a/fs/ext4/ext_barebox.c
+++ b/fs/ext4/ext_barebox.c
@@ -59,13 +59,6 @@ static int ext_read(struct device_d *_dev, FILE *f, void *buf, size_t insize)
return ext4fs_read_file(node, f->pos, insize, buf);
}
-static loff_t ext_lseek(struct device_d *dev, FILE *f, loff_t pos)
-{
- f->pos = pos;
-
- return f->pos;
-}
-
static struct inode *ext_alloc_inode(struct super_block *sb)
{
struct fs_device_d *fsdev = container_of(sb, struct fs_device_d, sb);
@@ -304,7 +297,6 @@ static void ext_remove(struct device_d *dev)
static struct fs_driver_d ext_driver = {
.read = ext_read,
- .lseek = ext_lseek,
.type = filetype_ext,
.flags = 0,
.drv = {
diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index 49cd78ff92..394c75ffc4 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -177,7 +177,7 @@ static int fat_write(struct device_d *_dev, FILE *f, const void *buf, size_t ins
return outsize;
}
-static int fat_truncate(struct device_d *dev, FILE *f, ulong size)
+static int fat_truncate(struct device_d *dev, FILE *f, loff_t size)
{
FIL *f_file = f->priv;
unsigned long lastofs;
@@ -268,7 +268,7 @@ static int fat_read(struct device_d *_dev, FILE *f, void *buf, size_t insize)
return outsize;
}
-static loff_t fat_lseek(struct device_d *dev, FILE *f, loff_t pos)
+static int fat_lseek(struct device_d *dev, FILE *f, loff_t pos)
{
FIL *f_file = f->priv;
int ret;
@@ -277,8 +277,7 @@ static loff_t fat_lseek(struct device_d *dev, FILE *f, loff_t pos)
if (ret)
return ret;
- f->pos = pos;
- return pos;
+ return 0;
}
static DIR* fat_opendir(struct device_d *dev, const char *pathname)
diff --git a/fs/fs.c b/fs/fs.c
index a304bf1863..1f6b3d3462 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -213,11 +213,16 @@ int ftruncate(int fd, loff_t length)
f = &files[fd];
+ if (f->size == FILE_SIZE_STREAM)
+ return 0;
+
fsdrv = f->fsdev->driver;
ret = fsdrv->truncate(&f->fsdev->dev, f, length);
- if (ret)
+ if (ret) {
+ errno = -ret;
return ret;
+ }
f->size = length;
@@ -413,41 +418,36 @@ loff_t lseek(int fildes, loff_t offset, int whence)
f = &files[fildes];
fsdrv = f->fsdev->driver;
- if (!fsdrv->lseek) {
- ret = -ENOSYS;
- goto out;
- }
ret = -EINVAL;
switch (whence) {
case SEEK_SET:
- if (f->size != FILE_SIZE_STREAM && offset > f->size)
- goto out;
- if (IS_ERR_VALUE(offset))
- goto out;
- pos = offset;
+ pos = 0;
break;
case SEEK_CUR:
- if (f->size != FILE_SIZE_STREAM && offset + f->pos > f->size)
- goto out;
- pos = f->pos + offset;
+ pos = f->pos;
break;
case SEEK_END:
- if (offset > 0)
- goto out;
- pos = f->size + offset;
+ pos = f->size;
break;
default:
goto out;
}
- pos = fsdrv->lseek(&f->fsdev->dev, f, pos);
- if (IS_ERR_VALUE(pos)) {
- errno = -pos;
- return -1;
+ pos += offset;
+
+ if (f->size != FILE_SIZE_STREAM && (pos < 0 || pos > f->size))
+ goto out;
+
+ if (fsdrv->lseek) {
+ ret = fsdrv->lseek(&f->fsdev->dev, f, pos);
+ if (ret < 0)
+ goto out;
}
+ f->pos = pos;
+
return pos;
out:
diff --git a/fs/nfs.c b/fs/nfs.c
index d7f156687f..43476d1c35 100644
--- a/fs/nfs.c
+++ b/fs/nfs.c
@@ -928,7 +928,7 @@ static void nfs_handler(void *ctx, char *packet, unsigned len)
nfs_len = len;
}
-static int nfs_truncate(struct device_d *dev, FILE *f, ulong size)
+static int nfs_truncate(struct device_d *dev, FILE *f, loff_t size)
{
return -ENOSYS;
}
@@ -1060,14 +1060,13 @@ static int nfs_read(struct device_d *dev, FILE *file, void *buf, size_t insize)
return kfifo_get(priv->fifo, buf, insize);
}
-static loff_t nfs_lseek(struct device_d *dev, FILE *file, loff_t pos)
+static int nfs_lseek(struct device_d *dev, FILE *file, loff_t pos)
{
struct file_priv *priv = file->priv;
- file->pos = pos;
kfifo_reset(priv->fifo);
- return file->pos;
+ return 0;
}
static int nfs_iterate(struct file *file, struct dir_context *ctx)
diff --git a/fs/omap4_usbbootfs.c b/fs/omap4_usbbootfs.c
index b35f411cbb..169cde7ddb 100644
--- a/fs/omap4_usbbootfs.c
+++ b/fs/omap4_usbbootfs.c
@@ -57,7 +57,7 @@ static int omap4_usbbootfs_write(
return -ENOSYS;
}
-static int omap4_usbbootfs_truncate(struct device_d *dev, FILE *f, ulong size)
+static int omap4_usbbootfs_truncate(struct device_d *dev, FILE *f, loff_t size)
{
return -ENOSYS;
}
@@ -149,12 +149,6 @@ static int omap4_usbbootfs_read(
return size;
}
-static loff_t omap4_usbbootfs_lseek(struct device_d *dev, FILE *f, loff_t pos)
-{
- f->pos = pos;
- return pos;
-}
-
static DIR *omap4_usbbootfs_opendir(struct device_d *dev, const char *pathname)
{
return NULL;
@@ -191,7 +185,6 @@ static struct fs_driver_d omap4_usbbootfs_driver = {
.open = omap4_usbbootfs_open,
.close = omap4_usbbootfs_close,
.read = omap4_usbbootfs_read,
- .lseek = omap4_usbbootfs_lseek,
.opendir = omap4_usbbootfs_opendir,
.stat = omap4_usbbootfs_stat,
/*
diff --git a/fs/pstore/fs.c b/fs/pstore/fs.c
index a879a68064..9a7e0b5526 100644
--- a/fs/pstore/fs.c
+++ b/fs/pstore/fs.c
@@ -172,13 +172,13 @@ static int pstore_read(struct device_d *dev, FILE *file, void *buf,
return insize;
}
-static loff_t pstore_lseek(struct device_d *dev, FILE *file, loff_t pos)
+static int pstore_lseek(struct device_d *dev, FILE *file, loff_t pos)
{
struct pstore_private *d = file->priv;
d->pos = pos;
- return pos;
+ return 0;
}
static DIR *pstore_opendir(struct device_d *dev, const char *pathname)
diff --git a/fs/ramfs.c b/fs/ramfs.c
index 84ecfa0ddb..4fba40d313 100644
--- a/fs/ramfs.c
+++ b/fs/ramfs.c
@@ -347,13 +347,7 @@ static int ramfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t i
return insize;
}
-static loff_t ramfs_lseek(struct device_d *dev, FILE *f, loff_t pos)
-{
- f->pos = pos;
- return f->pos;
-}
-
-static int ramfs_truncate(struct device_d *dev, FILE *f, ulong size)
+static int ramfs_truncate(struct device_d *dev, FILE *f, loff_t size)
{
struct inode *inode = f->f_inode;
struct ramfs_inode *node = to_ramfs_inode(inode);
@@ -448,7 +442,6 @@ static void ramfs_remove(struct device_d *dev)
static struct fs_driver_d ramfs_driver = {
.read = ramfs_read,
.write = ramfs_write,
- .lseek = ramfs_lseek,
.truncate = ramfs_truncate,
.flags = FS_DRIVER_NO_DEV,
.drv = {
diff --git a/fs/ratpfs.c b/fs/ratpfs.c
index 902289bab1..b6857c6016 100644
--- a/fs/ratpfs.c
+++ b/fs/ratpfs.c
@@ -77,7 +77,7 @@ static int ratpfs_rm(struct device_d __always_unused *dev,
}
static int ratpfs_truncate(struct device_d __always_unused *dev,
- FILE *f, ulong size)
+ FILE *f, loff_t size)
{
int len_tx = 1 /* type */
+ 4 /* handle */
@@ -284,14 +284,6 @@ out:
return ret;
}
-static loff_t ratpfs_lseek(struct device_d __always_unused *dev,
- FILE *f, loff_t pos)
-{
- pr_debug("%s\n", __func__);
- f->pos = pos;
- return f->pos;
-}
-
static DIR* ratpfs_opendir(struct device_d __always_unused *dev,
const char *pathname)
{
@@ -450,7 +442,6 @@ static struct fs_driver_d ratpfs_driver = {
.open = ratpfs_open,
.close = ratpfs_close,
.read = ratpfs_read,
- .lseek = ratpfs_lseek,
.opendir = ratpfs_opendir,
.readdir = ratpfs_readdir,
.closedir = ratpfs_closedir,
diff --git a/fs/smhfs.c b/fs/smhfs.c
index f1b6d6bb1b..2e99b05979 100644
--- a/fs/smhfs.c
+++ b/fs/smhfs.c
@@ -56,7 +56,7 @@ static int smhfs_rm(struct device_d __always_unused *dev,
static int smhfs_truncate(struct device_d __always_unused *dev,
FILE __always_unused *f,
- ulong __always_unused size)
+ loff_t __always_unused size)
{
return 0;
}
@@ -109,15 +109,13 @@ static int smhfs_read(struct device_d __always_unused *dev,
return -semihosting_errno();
}
-static loff_t smhfs_lseek(struct device_d __always_unused *dev,
+static int smhfs_lseek(struct device_d __always_unused *dev,
FILE *f, loff_t pos)
{
- if (semihosting_seek(file_to_fd(f), pos)) {
+ if (semihosting_seek(file_to_fd(f), pos))
return -semihosting_errno();
- } else {
- f->pos = pos;
- return f->pos;
- }
+
+ return 0;
}
static DIR* smhfs_opendir(struct device_d __always_unused *dev,
diff --git a/fs/squashfs/squashfs.c b/fs/squashfs/squashfs.c
index d9049b7523..38aff6d5b8 100644
--- a/fs/squashfs/squashfs.c
+++ b/fs/squashfs/squashfs.c
@@ -231,13 +231,6 @@ static int squashfs_read(struct device_d *_dev, FILE *f, void *buf,
return insize;
}
-static loff_t squashfs_lseek(struct device_d *dev, FILE *f, loff_t pos)
-{
- f->pos = pos;
-
- return pos;
-}
-
struct squashfs_dir {
struct file file;
struct dentry dentry;
@@ -253,7 +246,6 @@ static struct fs_driver_d squashfs_driver = {
.open = squashfs_open,
.close = squashfs_close,
.read = squashfs_read,
- .lseek = squashfs_lseek,
.type = filetype_squashfs,
.drv = {
.probe = squashfs_probe,
diff --git a/fs/tftp.c b/fs/tftp.c
index 1b50ba84f9..43293272d7 100644
--- a/fs/tftp.c
+++ b/fs/tftp.c
@@ -93,7 +93,7 @@ struct tftp_priv {
IPaddr_t server;
};
-static int tftp_truncate(struct device_d *dev, FILE *f, ulong size)
+static int tftp_truncate(struct device_d *dev, FILE *f, loff_t size)
{
return 0;
}
@@ -573,15 +573,17 @@ static int tftp_read(struct device_d *dev, FILE *f, void *buf, size_t insize)
return outsize;
}
-static loff_t tftp_lseek(struct device_d *dev, FILE *f, loff_t pos)
+static int tftp_lseek(struct device_d *dev, FILE *f, loff_t pos)
{
/* We cannot seek backwards without reloading or caching the file */
- if (pos >= f->pos) {
- loff_t ret;
+ loff_t f_pos = f->pos;
+
+ if (pos >= f_pos) {
+ int ret = 0;
char *buf = xmalloc(1024);
- while (pos > f->pos) {
- size_t len = min_t(size_t, 1024, pos - f->pos);
+ while (pos > f_pos) {
+ size_t len = min_t(size_t, 1024, pos - f_pos);
ret = tftp_read(dev, f, buf, len);
@@ -591,14 +593,21 @@ static loff_t tftp_lseek(struct device_d *dev, FILE *f, loff_t pos)
if (ret < 0)
goto out_free;
- f->pos += ret;
+ f_pos += ret;
}
- ret = pos;
-
out_free:
free(buf);
- return ret;
+ if (ret < 0) {
+ /*
+ * Update f->pos even if the overall request
+ * failed since we can't move backwards
+ */
+ f->pos = f_pos;
+ return ret;
+ }
+
+ return 0;
}
return -ENOSYS;
diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c
index 7545dd4c9b..494b1f2614 100644
--- a/fs/ubifs/ubifs.c
+++ b/fs/ubifs/ubifs.c
@@ -394,13 +394,6 @@ static int ubifs_read(struct device_d *_dev, FILE *f, void *buf, size_t insize)
return insize;
}
-static loff_t ubifs_lseek(struct device_d *dev, FILE *f, loff_t pos)
-{
- f->pos = pos;
-
- return pos;
-}
-
static void ubifs_set_rootarg(struct ubifs_priv *priv, struct fs_device_d *fsdev)
{
struct ubi_volume_info vi = {};
@@ -477,7 +470,6 @@ static struct fs_driver_d ubifs_driver = {
.open = ubifs_open,
.close = ubifs_close,
.read = ubifs_read,
- .lseek = ubifs_lseek,
.type = filetype_ubifs,
.flags = 0,
.drv = {
diff --git a/fs/uimagefs.c b/fs/uimagefs.c
index c120944a46..e5ada82da8 100644
--- a/fs/uimagefs.c
+++ b/fs/uimagefs.c
@@ -116,7 +116,7 @@ static int uimagefs_read(struct device_d *dev, FILE *file, void *buf, size_t ins
}
}
-static loff_t uimagefs_lseek(struct device_d *dev, FILE *file, loff_t pos)
+static int uimagefs_lseek(struct device_d *dev, FILE *file, loff_t pos)
{
struct uimagefs_handle_data *d = file->priv;
@@ -125,7 +125,7 @@ static loff_t uimagefs_lseek(struct device_d *dev, FILE *file, loff_t pos)
d->pos = pos;
- return pos;
+ return 0;
}
static DIR *uimagefs_opendir(struct device_d *dev, const char *pathname)
diff --git a/include/driver.h b/include/driver.h
index 7da184d3ab..a8e046ed7f 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -360,11 +360,6 @@ int dummy_probe(struct device_d *);
int generic_memmap_ro(struct cdev *dev, void **map, int flags);
int generic_memmap_rw(struct cdev *dev, void **map, int flags);
-static inline loff_t dev_lseek_default(struct cdev *cdev, loff_t ofs)
-{
- return ofs;
-}
-
static inline int dev_open_default(struct device_d *dev, struct filep *f)
{
return 0;
@@ -439,7 +434,7 @@ struct cdev_operations {
ssize_t (*write)(struct cdev*, const void* buf, size_t count, loff_t offset, ulong flags);
int (*ioctl)(struct cdev*, int, void *);
- loff_t (*lseek)(struct cdev*, loff_t);
+ int (*lseek)(struct cdev*, loff_t);
int (*open)(struct cdev*, unsigned long flags);
int (*close)(struct cdev*);
int (*flush)(struct cdev*);
diff --git a/include/fs.h b/include/fs.h
index f1514afa92..38debfc41b 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -46,14 +46,14 @@ struct fs_driver_d {
int (*unlink)(struct device_d *dev, const char *pathname);
/* Truncate a file to given size */
- int (*truncate)(struct device_d *dev, FILE *f, ulong size);
+ int (*truncate)(struct device_d *dev, FILE *f, loff_t size);
int (*open)(struct device_d *dev, FILE *f, const char *pathname);
int (*close)(struct device_d *dev, FILE *f);
int (*read)(struct device_d *dev, FILE *f, void *buf, size_t size);
int (*write)(struct device_d *dev, FILE *f, const void *buf, size_t size);
int (*flush)(struct device_d *dev, FILE *f);
- loff_t (*lseek)(struct device_d *dev, FILE *f, loff_t pos);
+ int (*lseek)(struct device_d *dev, FILE *f, loff_t pos);
int (*ioctl)(struct device_d *dev, FILE *f, int request, void *buf);
int (*erase)(struct device_d *dev, FILE *f, loff_t count,
diff --git a/lib/libfile.c b/lib/libfile.c
index 8f2aed2309..9a223d2328 100644
--- a/lib/libfile.c
+++ b/lib/libfile.c
@@ -556,8 +556,7 @@ int open_and_lseek(const char *filename, int mode, loff_t pos)
}
}
- ret = lseek(fd, pos, SEEK_SET);
- if (ret == -1) {
+ if (lseek(fd, pos, SEEK_SET) != pos) {
perror("lseek");
close(fd);
return -errno;
diff --git a/lib/misc.c b/lib/misc.c
index 1d20e1b092..cd420a57d8 100644
--- a/lib/misc.c
+++ b/lib/misc.c
@@ -23,6 +23,7 @@
#include <fs.h>
#include <string.h>
#include <linux/ctype.h>
+#include <getopt.h>
/*
* Like simple_strtoull() but handles an optional G, M, K or k
@@ -129,3 +130,44 @@ success:
return 0;
}
EXPORT_SYMBOL(parse_area_spec);
+
+/*
+ * Common function for parsing options for the 'md', 'mw', 'memcpy', 'memcmp'
+ * commands.
+ */
+int mem_parse_options(int argc, char *argv[], char *optstr, int *mode,
+ char **sourcefile, char **destfile, int *swab)
+{
+ int opt;
+
+ while((opt = getopt(argc, argv, optstr)) > 0) {
+ switch(opt) {
+ case 'b':
+ *mode = O_RWSIZE_1;
+ break;
+ case 'w':
+ *mode = O_RWSIZE_2;
+ break;
+ case 'l':
+ *mode = O_RWSIZE_4;
+ break;
+ case 'q':
+ *mode = O_RWSIZE_8;
+ break;
+ case 's':
+ *sourcefile = optarg;
+ break;
+ case 'd':
+ *destfile = optarg;
+ break;
+ case 'x':
+ *swab = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+