summaryrefslogtreecommitdiffstats
path: root/fs/devfs.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2011-04-04 13:13:30 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2011-04-11 12:36:07 +0200
commit30be97aff25f618f3925d1733a39996d50fc2213 (patch)
tree58eae347941d2bc1197a374668c77cd0bf43d0f4 /fs/devfs.c
parentf1bb89fd9e5c6f3527ebaafcf57346fec19e4d5f (diff)
downloadbarebox-30be97aff25f618f3925d1733a39996d50fc2213.tar.gz
barebox-30be97aff25f618f3925d1733a39996d50fc2213.tar.xz
devfs: factor out core devfs functionality
This makes it possible to compile without devfs. devfs_create/devfs_remove is used by drivers and thus must still be present even without devfs support. Also, this patch adds cdev_open/cdev_close/cdev_flush/cdev_ioctl calls to work with devices without using the file api. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'fs/devfs.c')
-rw-r--r--fs/devfs.c167
1 files changed, 2 insertions, 165 deletions
diff --git a/fs/devfs.c b/fs/devfs.c
index f82fdddbc2..07ca16c553 100644
--- a/fs/devfs.c
+++ b/fs/devfs.c
@@ -36,34 +36,7 @@
#include <linux/mtd/mtd-abi.h>
#include <partition.h>
-static LIST_HEAD(cdev_list);
-
-struct cdev *cdev_by_name(const char *filename)
-{
- struct cdev *cdev;
-
- list_for_each_entry(cdev, &cdev_list, list) {
- if (!strcmp(cdev->name, filename))
- return cdev;
- }
- return NULL;
-}
-
-ssize_t cdev_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags)
-{
- if (!cdev->ops->read)
- return -ENOSYS;
-
- return cdev->ops->read(cdev, buf, count, cdev->offset +offset, flags);
-}
-
-ssize_t cdev_write(struct cdev *cdev, const void *buf, size_t count, ulong offset, ulong flags)
-{
- if (!cdev->ops->write)
- return -ENOSYS;
-
- return cdev->ops->write(cdev, buf, count, cdev->offset + offset, flags);
-}
+extern struct list_head cdev_list;
static int devfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size)
{
@@ -179,49 +152,11 @@ static int devfs_flush(struct device_d *_dev, FILE *f)
return 0;
}
-static int partition_ioctl(struct cdev *cdev, int request, void *buf)
-{
- size_t offset;
- struct mtd_info_user *user = buf;
-
- switch (request) {
- case MEMSETBADBLOCK:
- case MEMGETBADBLOCK:
- offset = (off_t)buf;
- offset += cdev->offset;
- return cdev->ops->ioctl(cdev, request, (void *)offset);
- case MEMGETINFO:
- if (cdev->mtd) {
- user->type = cdev->mtd->type;
- user->flags = cdev->mtd->flags;
- user->size = cdev->mtd->size;
- user->erasesize = cdev->mtd->erasesize;
- user->oobsize = cdev->mtd->oobsize;
- user->mtd = cdev->mtd;
- /* The below fields are obsolete */
- user->ecctype = -1;
- user->eccsize = 0;
- return 0;
- }
- if (!cdev->ops->ioctl)
- return -EINVAL;
- return cdev->ops->ioctl(cdev, request, buf);
- default:
- return -EINVAL;
- }
-}
-
static int devfs_ioctl(struct device_d *_dev, FILE *f, int request, void *buf)
{
struct cdev *cdev = f->inode;
- if (cdev->flags & DEVFS_IS_PARTITION)
- return partition_ioctl(cdev, request, buf);
-
- if (!cdev->ops->ioctl)
- return -EINVAL;
-
- return cdev->ops->ioctl(cdev, request, buf);
+ return cdev_ioctl(cdev, request, buf);
}
static int devfs_truncate(struct device_d *dev, FILE *f, ulong size)
@@ -322,101 +257,3 @@ static int devfs_init(void)
}
coredevice_initcall(devfs_init);
-
-int devfs_create(struct cdev *new)
-{
- struct cdev *cdev;
-
- cdev = cdev_by_name(new->name);
- if (cdev)
- return -EEXIST;
-
- list_add_tail(&new->list, &cdev_list);
- if (new->dev)
- list_add_tail(&new->devices_list, &new->dev->cdevs);
-
- return 0;
-}
-
-int devfs_remove(struct cdev *cdev)
-{
- if (cdev->open)
- return -EBUSY;
-
- list_del(&cdev->list);
- if (cdev->dev)
- list_del(&cdev->devices_list);
-
- return 0;
-}
-
-int devfs_add_partition(const char *devname, unsigned long offset, size_t size,
- int flags, const char *name)
-{
- struct cdev *cdev, *new;
-
- cdev = cdev_by_name(name);
- if (cdev)
- return -EEXIST;
-
- cdev = cdev_by_name(devname);
- if (!cdev)
- return -ENOENT;
-
- if (offset + size > cdev->size)
- return -EINVAL;
-
- new = xzalloc(sizeof (*new));
- new->name = strdup(name);
- new->ops = cdev->ops;
- new->priv = cdev->priv;
- new->size = size;
- new->offset = offset + cdev->offset;
- new->dev = cdev->dev;
- new->flags = flags | DEVFS_IS_PARTITION;
-
-#ifdef CONFIG_PARTITION_NEED_MTD
- if (cdev->mtd) {
- new->mtd = mtd_add_partition(cdev->mtd, offset, size, flags, name);
- if (IS_ERR(new->mtd)) {
- int ret = PTR_ERR(new->mtd);
- free(new);
- return ret;
- }
- }
-#endif
-
- devfs_create(new);
-
- return 0;
-}
-
-int devfs_del_partition(const char *name)
-{
- struct cdev *cdev;
- int ret;
-
- cdev = cdev_by_name(name);
- if (!cdev)
- return -ENOENT;
-
- if (!(cdev->flags & DEVFS_IS_PARTITION))
- return -EINVAL;
- if (cdev->flags & DEVFS_PARTITION_FIXED)
- return -EPERM;
-
-#ifdef CONFIG_PARTITION_NEED_MTD
- if (cdev->mtd)
- mtd_del_partition(cdev->mtd);
-#endif
-
- ret = devfs_remove(cdev);
- if (ret)
- return ret;
-
- free(cdev->name);
- free(cdev);
-
- return 0;
-}
-