diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2011-04-04 13:13:30 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2011-04-11 12:36:07 +0200 |
commit | 30be97aff25f618f3925d1733a39996d50fc2213 (patch) | |
tree | 58eae347941d2bc1197a374668c77cd0bf43d0f4 /fs/devfs.c | |
parent | f1bb89fd9e5c6f3527ebaafcf57346fec19e4d5f (diff) | |
download | barebox-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.c | 167 |
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; -} - |