blob: 3f5e6588506cf98b23ae600742e181e1bc280351 [file] [log] [blame]
/* 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 <ns.h>
void devfs_init(void)
{
int mode;
/* Make sure there is a dev directory */
struct dentry *dentry = lookup_dentry("/dev_vfs/", 0);
if (!dentry) {
assert(!do_mkdir("/dev_vfs/", S_IRWXU | S_IRWXG | S_IRWXO));
} else {
kref_put(&dentry->d_kref);
}
}
/* 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 | O_RDWR, 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;
}