summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2008-06-06 09:25:13 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2008-06-06 09:30:48 +0200
commitee6d36a5405305f3bbdb0457948c219731b3d9cc (patch)
tree0a328bd96f2cf2f190372b654515e509c694930a /fs
parent3f73e61600f8fce0b6fa02e9a82124c1c89937c7 (diff)
downloadbarebox-ee6d36a5405305f3bbdb0457948c219731b3d9cc.tar.gz
barebox-ee6d36a5405305f3bbdb0457948c219731b3d9cc.tar.xz
- introduce ioctl call
- pass open/close/lseek through to drivers
Diffstat (limited to 'fs')
-rw-r--r--fs/cramfs/cramfs.c7
-rw-r--r--fs/devfs.c36
-rw-r--r--fs/fs.c34
-rw-r--r--fs/ramfs.c7
4 files changed, 74 insertions, 10 deletions
diff --git a/fs/cramfs/cramfs.c b/fs/cramfs/cramfs.c
index 9c08ad5a29..62f15d6271 100644
--- a/fs/cramfs/cramfs.c
+++ b/fs/cramfs/cramfs.c
@@ -352,6 +352,12 @@ static int cramfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size)
return outsize;
}
+static off_t cramfs_lseek(struct device_d *dev, FILE *f, off_t pos)
+{
+ f->pos = pos;
+ return f->pos;
+}
+
static int cramfs_stat(struct device_d *_dev, const char *filename, struct stat *stat)
{
struct cramfs_priv *priv = _dev->priv;
@@ -443,6 +449,7 @@ static struct fs_driver_d cramfs_driver = {
.open = cramfs_open,
.close = cramfs_close,
.read = cramfs_read,
+ .lseek = cramfs_lseek,
.opendir = cramfs_opendir,
.readdir = cramfs_readdir,
.closedir = cramfs_closedir,
diff --git a/fs/devfs.c b/fs/devfs.c
index 10c2dfeab6..12abc1829d 100644
--- a/fs/devfs.c
+++ b/fs/devfs.c
@@ -44,6 +44,19 @@ static int devfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t s
return dev_write(dev, buf, size, f->pos, f->flags);
}
+static off_t devfs_lseek(struct device_d *_dev, FILE *f, off_t pos)
+{
+ struct device_d *dev = f->inode;
+ int ret;
+
+ ret = dev_lseek(dev, pos);
+
+ if (ret >= 0)
+ f->pos = pos;
+
+ return ret;
+}
+
static int devfs_erase(struct device_d *_dev, FILE *f, size_t count, unsigned long offset)
{
struct device_d *dev = f->inode;
@@ -65,21 +78,30 @@ static int devfs_memmap(struct device_d *_dev, FILE *f, void **map, int flags)
return dev_memmap(dev, map, flags);
}
-static int devfs_open(struct device_d *_dev, FILE *file, const char *filename)
+static int devfs_open(struct device_d *_dev, FILE *f, const char *filename)
{
struct device_d *dev = get_device_by_id(filename + 1);
if (!dev)
return -ENOENT;
- file->size = dev->size;
- file->inode = dev;
- return 0;
+ f->size = dev->size;
+ f->inode = dev;
+ return dev_open(dev, f);
}
-static int devfs_close(struct device_d *dev, FILE *f)
+static int devfs_close(struct device_d *_dev, FILE *f)
{
- return 0;
+ struct device_d *dev = f->inode;
+
+ return dev_close(dev, f);
+}
+
+static int devfs_ioctl(struct device_d *_dev, FILE *f, int request, void *buf)
+{
+ struct device_d *dev = f->inode;
+
+ return dev_ioctl(dev, request, buf);
}
static int devfs_truncate(struct device_d *dev, FILE *f, ulong size)
@@ -156,8 +178,10 @@ static struct fs_driver_d devfs_driver = {
.type = FS_TYPE_DEVFS,
.read = devfs_read,
.write = devfs_write,
+ .lseek = devfs_lseek,
.open = devfs_open,
.close = devfs_close,
+ .ioctl = devfs_ioctl,
.opendir = devfs_opendir,
.readdir = devfs_readdir,
.truncate = devfs_truncate,
diff --git a/fs/fs.c b/fs/fs.c
index 2d90df3f5f..3f0f1345fb 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -451,6 +451,22 @@ int creat(const char *pathname, mode_t mode)
}
EXPORT_SYMBOL(creat);
+int ioctl(int fd, int request, void *buf)
+{
+ struct device_d *dev;
+ struct fs_driver_d *fsdrv;
+ FILE *f = &files[fd];
+
+ dev = f->dev;
+
+ fsdrv = (struct fs_driver_d *)dev->driver->type_data;
+
+ if (fsdrv->ioctl)
+ return fsdrv->ioctl(dev, f, request, buf);
+
+ return -ENOSYS;
+}
+
int read(int fd, void *buf, size_t count)
{
struct device_d *dev;
@@ -496,30 +512,40 @@ EXPORT_SYMBOL(write);
off_t lseek(int fildes, off_t offset, int whence)
{
+ struct device_d *dev;
+ struct fs_driver_d *fsdrv;
FILE *f = &files[fildes];
+ ulong pos;
+
errno = 0;
+ dev = f->dev;
+ fsdrv = (struct fs_driver_d *)dev->driver->type_data;
+ if (!fsdrv->lseek)
+ return -ENOSYS;
+
switch(whence) {
case SEEK_SET:
if (offset > f->size)
goto out;
- f->pos = offset;
+ pos = offset;
break;
case SEEK_CUR:
if (offset + f->pos > f->size)
goto out;
- f->pos += offset;
+ pos = f->pos + offset;
break;
case SEEK_END:
if (offset)
goto out;
- f->pos = f->size;
+ pos = f->size;
break;
default:
goto out;
}
- return 0;
+ return fsdrv->lseek(dev, f, pos);
+
out:
errno = -EINVAL;
return errno;
diff --git a/fs/ramfs.c b/fs/ramfs.c
index 38ef035d53..beee6b9256 100644
--- a/fs/ramfs.c
+++ b/fs/ramfs.c
@@ -403,6 +403,12 @@ static int ramfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t i
return insize;
}
+static off_t ramfs_lseek(struct device_d *dev, FILE *f, off_t pos)
+{
+ f->pos = pos;
+ return f->pos;
+}
+
static int ramfs_truncate(struct device_d *dev, FILE *f, ulong size)
{
struct ramfs_inode *node = (struct ramfs_inode *)f->inode;
@@ -540,6 +546,7 @@ static struct fs_driver_d ramfs_driver = {
.truncate = ramfs_truncate,
.read = ramfs_read,
.write = ramfs_write,
+ .lseek = ramfs_lseek,
.mkdir = ramfs_mkdir,
.rmdir = ramfs_rmdir,
.opendir = ramfs_opendir,