/* Copyright (c) 2010 The Regents of the University of California
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * Devfs: filesystem interfaces to devices.  For now, we just create the
 * needed/discovered devices in KFS in its /dev/ folder, and only do this for
 * stdin and stdout. */

#include <devfs.h>
#include <kfs.h>
#include <error.h>
#include <syscall.h>
#include <process.h>
#include <smp.h>
#include <umem.h>
#include <kmalloc.h>
#include <console.h>

/* These structs are declared again and initialized farther down */
struct file_operations dev_f_op_stdin;
struct file_operations dev_f_op_stdout;
struct file_operations dev_f_op_null;

struct file *dev_stdin, *dev_stdout, *dev_stderr, *dev_null;

void devfs_init(void)
{
	int mode;
	/* Make sure there is a dev directory */
	struct dentry *dentry = lookup_dentry("/dev/", 0);	
	if (!dentry) {
		assert(!do_mkdir("/dev/", S_IRWXU | S_IRWXG | S_IRWXO));
	} else {
		kref_put(&dentry->d_kref);
	}
	/* Notice we don't kref_put().  We're storing the refs globally */
	dev_stdin = make_device("/dev/stdin", S_IRUSR | S_IRGRP | S_IROTH,
	                        __S_IFCHR, &dev_f_op_stdin);
	dev_stdout = make_device("/dev/stdout", S_IWUSR | S_IWGRP | S_IWOTH,
	                         __S_IFCHR, &dev_f_op_stdout);
	/* Note stderr uses the same f_op as stdout */
	dev_stderr = make_device("/dev/stderr", S_IWUSR | S_IWGRP | S_IWOTH,
	                         __S_IFCHR, &dev_f_op_stdout);
	dev_null = make_device("/dev/null", S_IWUSR | S_IWGRP | S_IWOTH,
	                       __S_IFCHR, &dev_f_op_null);
}

/* Creates a device node at a given location in the FS-tree */
/* TODO: consider making this only deal with the inode */
struct file *make_device(char *path, int mode, int type,
                         struct file_operations *fop)
{
	struct file *f_dev = do_file_open(path, O_CREAT, mode);
	assert(f_dev);
	/* Overwrite the f_op with our own f_ops */
	f_dev->f_dentry->d_inode->i_fop = fop;
	f_dev->f_op = fop;
	SET_FTYPE(f_dev->f_dentry->d_inode->i_mode, type);
	return f_dev;
}

/* We provide a separate set of f_ops for devices (char and block), and the fops
 * is the only thing that differs from the regular KFS.  We need to do some
 * ghetto-overriding of these ops after we create them. */
int dev_c_llseek(struct file *file, off64_t offset, off64_t *ret, int whence)
{
	set_errno(EINVAL);
	return -1;
}

/* we don't allow mmapping of any device file */
int dev_mmap(struct file *file, struct vm_region *vmr)
{
	set_errno(EINVAL);
	return -1;
}

/* this is really /dev/console, and will need some tty work.  for now, no matter
 * how much they ask for, we return one character at a time. */
ssize_t dev_stdin_read(struct file *file, char *buf, size_t count,
                       off64_t *offset)
{
	char c;
	extern struct kb_buffer cons_buf;
	kb_get_from_buf(&cons_buf, &c, 1);
	/* TODO UMEM */
	if (current)
		memcpy_to_user_errno(current, buf, &c, 1);
	else
		memcpy(buf, &c, 1);
	return 1;
}

ssize_t dev_stdout_write(struct file *file, const char *buf, size_t count,
                         off64_t *offset)
{
	char *t_buf;
	struct proc *p = current;
	if (p)
		t_buf = user_strdup_errno(p, buf, count);
	else
		t_buf = (char*)buf;
	if (!t_buf)
		return -1;
	/* TODO: tty hack.  they are sending us an escape sequence, and the keyboard
	 * would try to print it (which it can't do yet).  The hack is even dirtier
	 * in that we only detect it if it is the first char, and we ignore
	 * everything else. */
	if (t_buf[0] != '\033') /* 0x1b */
		cputbuf(t_buf, count);
	if (p)
		user_memdup_free(p, t_buf);
	return count;
}

/* stdin/stdout/stderr file ops */
struct file_operations dev_f_op_stdin = {
	dev_c_llseek,
	dev_stdin_read,
	0,	/* write - can't write to stdin */
	kfs_readdir,	/* this will fail gracefully */
	dev_mmap,
	kfs_open,
	kfs_flush,
	kfs_release,
	0,	/* fsync - makes no sense */
	kfs_poll,
	0,	/* readv */
	0,	/* writev */
	kfs_sendpage,
	kfs_check_flags,
};

struct file_operations dev_f_op_stdout = {
	dev_c_llseek,
	0,	/* read - can't read stdout */
	dev_stdout_write,
	kfs_readdir,	/* this will fail gracefully */
	dev_mmap,
	kfs_open,
	kfs_flush,
	kfs_release,
	0,	/* fsync - makes no sense */
	kfs_poll,
	0,	/* readv */
	0,	/* writev */
	kfs_sendpage,
	kfs_check_flags,
};

ssize_t dev_null_read(struct file *file, char *buf, size_t count,
                      off64_t *offset)
{
	return 0;
}

/* /dev/null: just take whatever was given and pretend it was written */
ssize_t dev_null_write(struct file *file, const char *buf, size_t count,
                       off64_t *offset)
{
	return count;
}

struct file_operations dev_f_op_null = {
	dev_c_llseek,
	dev_null_read,
	dev_null_write,
	kfs_readdir,	/* this will fail gracefully */
	dev_mmap,
	kfs_open,
	kfs_flush,
	kfs_release,
	0,	/* fsync - makes no sense */
	kfs_poll,
	0,	/* readv */
	0,	/* writev */
	kfs_sendpage,
	kfs_check_flags,
};
