/*
 * devfs.c - a device file system for barebox
 *
 * 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.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <common.h>
#include <driver.h>
#include <init.h>
#include <malloc.h>
#include <fs.h>
#include <command.h>
#include <errno.h>
#include <xfuncs.h>
#include <linux/stat.h>
#include <ioctl.h>
#include <nand.h>
#include <linux/err.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/mtd-abi.h>
#include <partition.h>

extern struct list_head cdev_list;

static int devfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size)
{
	struct cdev *cdev = f->inode;

	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)
{
	struct cdev *cdev = f->inode;

	return cdev_write(cdev, buf, size, f->pos, f->flags);
}

static off_t devfs_lseek(struct device_d *_dev, FILE *f, off_t pos)
{
	struct cdev *cdev = f->inode;
	off_t ret = -1;

	if (cdev->ops->lseek)
		ret = cdev->ops->lseek(cdev, pos + cdev->offset);

	if (ret != -1)
		f->pos = pos;

	return ret - cdev->offset;
}

static int devfs_erase(struct device_d *_dev, FILE *f, size_t count, unsigned long offset)
{
	struct cdev *cdev = f->inode;

	if (!cdev->ops->erase)
		return -ENOSYS;

	return cdev->ops->erase(cdev, count, offset + cdev->offset);
}

static int devfs_protect(struct device_d *_dev, FILE *f, size_t count, unsigned long offset, int prot)
{
	struct cdev *cdev = f->inode;

	if (!cdev->ops->protect)
		return -ENOSYS;

	return cdev->ops->protect(cdev, count, offset + cdev->offset, prot);
}

static int devfs_memmap(struct device_d *_dev, FILE *f, void **map, int flags)
{
	struct cdev *cdev = f->inode;
	int ret = -ENOSYS;

	if (!cdev->ops->memmap)
		return -EINVAL;

	ret = cdev->ops->memmap(cdev, map, flags);

	if (!ret)
		*map = (void *)((unsigned long)*map + cdev->offset);

	return ret;
}

static int devfs_open(struct device_d *_dev, FILE *f, const char *filename)
{
	struct cdev *cdev;
	int ret;

	cdev = cdev_by_name(filename + 1);

	if (!cdev)
		return -ENOENT;

	f->size = cdev->size;
	f->inode = cdev;

	if (cdev->ops->open) {
		ret = cdev->ops->open(cdev);
		if (ret)
			return ret;
	}

	cdev->open++;

	return 0;
}

static int devfs_close(struct device_d *_dev, FILE *f)
{
	struct cdev *cdev = f->inode;
	int ret;

	if (cdev->ops->close) {
		ret = cdev->ops->close(cdev);
		if (ret)
			return ret;
	}

	cdev->open--;

	return 0;
}

static int devfs_flush(struct device_d *_dev, FILE *f)
{
	struct cdev *cdev = f->inode;

	if (cdev->ops->flush)
		return cdev->ops->flush(cdev);

	return 0;
}

static int devfs_ioctl(struct device_d *_dev, FILE *f, int request, void *buf)
{
	struct cdev *cdev = f->inode;

	return cdev_ioctl(cdev, request, buf);
}

static int devfs_truncate(struct device_d *dev, FILE *f, ulong size)
{
	if (size > f->dev->size)
		return -ENOSPC;
	return 0;
}

static DIR* devfs_opendir(struct device_d *dev, const char *pathname)
{
	DIR *dir;

	dir = xzalloc(sizeof(DIR));

	if (!list_empty(&cdev_list))
		dir->priv = list_first_entry(&cdev_list, struct cdev, list);

	return dir;
}

static struct dirent* devfs_readdir(struct device_d *_dev, DIR *dir)
{
	struct cdev *cdev = dir->priv;

	if (!cdev)
		return NULL;

	list_for_each_entry_from(cdev, &cdev_list, list) {
		strcpy(dir->d.d_name, cdev->name);
		dir->priv = list_entry(cdev->list.next, struct cdev, list);
		return &dir->d;
	}
	return NULL;
}

static int devfs_closedir(struct device_d *dev, DIR *dir)
{
	free(dir);
	return 0;
}

static int devfs_stat(struct device_d *_dev, const char *filename, struct stat *s)
{
	struct cdev *cdev;

	cdev = cdev_by_name(filename + 1);
	if (!cdev)
		return -ENOENT;

	s->st_mode = S_IFCHR;
	s->st_size = cdev->size;
	if (cdev->ops->write)
		s->st_mode |= S_IWUSR;
	if (cdev->ops->read)
		s->st_mode |= S_IRUSR;

	return 0;
}

static int devfs_probe(struct device_d *dev)
{
	return 0;
}

static void devfs_delete(struct device_d *dev)
{
}

static struct fs_driver_d devfs_driver = {
	.read      = devfs_read,
	.write     = devfs_write,
	.lseek     = devfs_lseek,
	.open      = devfs_open,
	.close     = devfs_close,
	.flush     = devfs_flush,
	.ioctl     = devfs_ioctl,
	.opendir   = devfs_opendir,
	.readdir   = devfs_readdir,
	.truncate  = devfs_truncate,
	.closedir  = devfs_closedir,
	.stat      = devfs_stat,
	.erase     = devfs_erase,
	.protect   = devfs_protect,
	.memmap    = devfs_memmap,
	.flags     = FS_DRIVER_NO_DEV,
	.drv = {
		.probe  = devfs_probe,
		.remove = devfs_delete,
		.name = "devfs",
		.type_data = &devfs_driver,
	}
};

static int devfs_init(void)
{
	return register_fs_driver(&devfs_driver);
}

coredevice_initcall(devfs_init);
