summaryrefslogtreecommitdiffstats
path: root/fs/devfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/devfs.c')
-rw-r--r--fs/devfs.c106
1 files changed, 39 insertions, 67 deletions
diff --git a/fs/devfs.c b/fs/devfs.c
index e1893d1bd0..c8ddbbdab0 100644
--- a/fs/devfs.c
+++ b/fs/devfs.c
@@ -3,9 +3,6 @@
*
* Copyright (c) 2007 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.
@@ -31,23 +28,22 @@
#include <linux/err.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/mtd-abi.h>
-#include <partition.h>
+#include <block.h>
struct devfs_inode {
struct inode inode;
struct cdev *cdev;
};
-extern struct list_head cdev_list;
-
-static int devfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size)
+static int devfs_read(struct device *_dev, FILE *f, void *buf, size_t size)
{
struct cdev *cdev = f->priv;
return cdev_read(cdev, buf, size, f->pos, f->flags);
}
-static int devfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t size)
+static int devfs_write(struct device *_dev, FILE *f, const void *buf,
+ size_t size)
{
struct cdev *cdev = f->priv;
@@ -57,21 +53,15 @@ 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 int devfs_lseek(struct device_d *_dev, FILE *f, loff_t pos)
+static int devfs_lseek(struct device *_dev, FILE *f, loff_t pos)
{
struct cdev *cdev = f->priv;
- int ret;
-
- if (cdev->ops->lseek) {
- ret = cdev->ops->lseek(cdev, pos + cdev->offset);
- if (ret < 0)
- return ret;
- }
- return 0;
+ return cdev_lseek(cdev, pos);
}
-static int devfs_erase(struct device_d *_dev, FILE *f, loff_t count, loff_t offset)
+static int devfs_erase(struct device *_dev, FILE *f, loff_t count,
+ loff_t offset)
{
struct cdev *cdev = f->priv;
@@ -84,53 +74,30 @@ static int devfs_erase(struct device_d *_dev, FILE *f, loff_t count, loff_t offs
return cdev_erase(cdev, count, offset);
}
-static int devfs_protect(struct device_d *_dev, FILE *f, size_t count, loff_t offset, int prot)
+static int devfs_protect(struct device *dev, FILE *f, size_t count,
+ loff_t offset, int prot)
{
struct cdev *cdev = f->priv;
- if (!cdev->ops->protect)
- return -ENOSYS;
-
- return cdev->ops->protect(cdev, count, offset + cdev->offset, prot);
+ return cdev_protect(cdev, count, offset, prot);
}
-static int devfs_discard_range(struct device_d *dev, FILE *f, loff_t count,
+static int devfs_discard_range(struct device *dev, FILE *f, loff_t count,
loff_t offset)
{
struct cdev *cdev = f->priv;
- if (!cdev->ops->discard_range)
- return -ENOSYS;
-
- if (cdev->flags & DEVFS_PARTITION_READONLY)
- return -EPERM;
-
- if (offset >= cdev->size)
- return 0;
-
- if (count + offset > cdev->size)
- count = cdev->size - offset;
-
- return cdev->ops->discard_range(cdev, count, offset + cdev->offset);
+ return cdev_discard_range(cdev, count, offset);
}
-static int devfs_memmap(struct device_d *_dev, FILE *f, void **map, int flags)
+static int devfs_memmap(struct device *_dev, FILE *f, void **map, int flags)
{
struct cdev *cdev = f->priv;
- int ret = -ENOSYS;
-
- if (!cdev->ops->memmap)
- return -EINVAL;
-
- ret = cdev->ops->memmap(cdev, map, flags);
- if (!ret)
- *map = (void *)((unsigned long)*map + (unsigned long)cdev->offset);
-
- return ret;
+ return cdev_memmap(cdev, map, flags);
}
-static int devfs_open(struct device_d *_dev, FILE *f, const char *filename)
+static int devfs_open(struct device *_dev, FILE *f, const char *filename)
{
struct inode *inode = f->f_inode;
struct devfs_inode *node = container_of(inode, struct devfs_inode, inode);
@@ -147,12 +114,10 @@ static int devfs_open(struct device_d *_dev, FILE *f, const char *filename)
return ret;
}
- cdev->open++;
-
return 0;
}
-static int devfs_close(struct device_d *_dev, FILE *f)
+static int devfs_close(struct device *_dev, FILE *f)
{
struct cdev *cdev = f->priv;
int ret;
@@ -163,33 +128,28 @@ static int devfs_close(struct device_d *_dev, FILE *f)
return ret;
}
- cdev->open--;
-
return 0;
}
-static int devfs_flush(struct device_d *_dev, FILE *f)
+static int devfs_flush(struct device *_dev, FILE *f)
{
struct cdev *cdev = f->priv;
return cdev_flush(cdev);
}
-static int devfs_ioctl(struct device_d *_dev, FILE *f, int request, void *buf)
+static int devfs_ioctl(struct device *_dev, FILE *f, int request, void *buf)
{
struct cdev *cdev = f->priv;
return cdev_ioctl(cdev, request, buf);
}
-static int devfs_truncate(struct device_d *dev, FILE *f, loff_t size)
+static int devfs_truncate(struct device *dev, FILE *f, loff_t size)
{
struct cdev *cdev = f->priv;
- if (cdev->ops->truncate)
- return cdev->ops->truncate(cdev, size);
-
- return -EPERM;
+ return cdev_truncate(cdev, size);
}
static struct inode *devfs_alloc_inode(struct super_block *sb)
@@ -203,13 +163,20 @@ static struct inode *devfs_alloc_inode(struct super_block *sb)
return &node->inode;
}
+static void devfs_destroy_inode(struct inode *inode)
+{
+ struct devfs_inode *node = container_of(inode, struct devfs_inode, inode);
+
+ free(node);
+}
+
static int devfs_iterate(struct file *file, struct dir_context *ctx)
{
struct cdev *cdev;
dir_emit_dots(file, ctx);
- list_for_each_entry(cdev, &cdev_list, list) {
+ for_each_cdev(cdev) {
dir_emit(ctx, cdev->name, strlen(cdev->name),
1 /* FIXME */, DT_REG);
}
@@ -263,6 +230,7 @@ static struct inode *devfs_get_inode(struct super_block *sb, const struct inode
default:
return NULL;
case S_IFCHR:
+ case S_IFBLK:
inode->i_op = &devfs_file_inode_operations;
inode->i_fop = &devfs_file_operations;
break;
@@ -282,12 +250,15 @@ static struct dentry *devfs_lookup(struct inode *dir, struct dentry *dentry,
struct devfs_inode *dinode;
struct inode *inode;
struct cdev *cdev;
+ umode_t mode;
cdev = cdev_by_name(dentry->name);
if (!cdev)
return ERR_PTR(-ENOENT);
- inode = devfs_get_inode(dir->i_sb, dir, S_IFCHR);
+ mode = cdev_get_block_device(cdev) ? S_IFBLK : S_IFCHR;
+
+ inode = devfs_get_inode(dir->i_sb, dir, mode);
if (!inode)
return ERR_PTR(-ENOMEM);
@@ -317,12 +288,13 @@ static const struct inode_operations devfs_dir_inode_operations =
static const struct super_operations devfs_ops = {
.alloc_inode = devfs_alloc_inode,
+ .destroy_inode = devfs_destroy_inode,
};
-static int devfs_probe(struct device_d *dev)
+static int devfs_probe(struct device *dev)
{
struct inode *inode;
- struct fs_device_d *fsdev = dev_to_fs_device(dev);
+ struct fs_device *fsdev = dev_to_fs_device(dev);
struct super_block *sb = &fsdev->sb;
sb->s_op = &devfs_ops;
@@ -334,11 +306,11 @@ static int devfs_probe(struct device_d *dev)
return 0;
}
-static void devfs_delete(struct device_d *dev)
+static void devfs_delete(struct device *dev)
{
}
-static struct fs_driver_d devfs_driver = {
+static struct fs_driver devfs_driver = {
.read = devfs_read,
.write = devfs_write,
.lseek = devfs_lseek,