feat: hook up the keyboard input into our vfs
[lunaix-os.git] / lunaix-os / kernel / device.c
1 #include <klibc/stdio.h>
2 #include <lunaix/device.h>
3 #include <lunaix/fs/twifs.h>
4 #include <lunaix/mm/valloc.h>
5
6 struct llist_header dev_list;
7
8 static struct twifs_node* dev_root;
9
10 int
11 __dev_read(struct v_file* file, void* buffer, size_t len, size_t fpos);
12
13 int
14 __dev_write(struct v_file* file, void* buffer, size_t len, size_t fpos);
15
16 void
17 device_init()
18 {
19     dev_root = twifs_toplevel_node("dev", 3, 0);
20
21     llist_init_head(&dev_list);
22 }
23
24 struct device*
25 __device_add(struct device* parent,
26              void* underlay,
27              char* name_fmt,
28              uint32_t type,
29              va_list args)
30 {
31     struct device* dev = vzalloc(sizeof(struct device));
32
33     size_t strlen =
34       __sprintf_internal(dev->name_val, name_fmt, DEVICE_NAME_SIZE, args);
35
36     dev->name = HSTR(dev->name_val, strlen);
37     dev->parent = parent;
38     dev->underlay = underlay;
39
40     hstr_rehash(&dev->name, HSTR_FULL_HASH);
41     llist_append(&dev_list, &dev->dev_list);
42
43     struct twifs_node* dev_node =
44       twifs_file_node(dev_root, dev->name_val, strlen, type);
45     dev_node->data = dev;
46     dev_node->ops.read = __dev_read;
47     dev_node->ops.write = __dev_write;
48
49     dev->fs_node = dev_node;
50
51     return dev;
52 }
53
54 struct device*
55 device_addseq(struct device* parent, void* underlay, char* name_fmt, ...)
56 {
57     va_list args;
58     va_start(args, name_fmt);
59
60     struct device* dev =
61       __device_add(parent, underlay, name_fmt, VFS_IFSEQDEV, args);
62
63     va_end(args);
64     return dev;
65 }
66
67 struct device*
68 device_addvol(struct device* parent, void* underlay, char* name_fmt, ...)
69 {
70     va_list args;
71     va_start(args, name_fmt);
72
73     struct device* dev =
74       __device_add(parent, underlay, name_fmt, VFS_IFVOLDEV, args);
75
76     va_end(args);
77     return dev;
78 }
79
80 int
81 __dev_read(struct v_file* file, void* buffer, size_t len, size_t fpos)
82 {
83     struct twifs_node* dev_node = (struct twifs_node*)file->inode->data;
84     struct device* dev = (struct device*)dev_node->data;
85
86     if (!dev->read) {
87         return ENOTSUP;
88     }
89     return dev->read(dev, buffer, fpos, len);
90 }
91
92 int
93 __dev_write(struct v_file* file, void* buffer, size_t len, size_t fpos)
94 {
95     struct twifs_node* dev_node = (struct twifs_node*)file->inode->data;
96     struct device* dev = (struct device*)dev_node->data;
97
98     if (!dev->write) {
99         return ENOTSUP;
100     }
101     return dev->write(dev, buffer, fpos, len);
102 }
103
104 void
105 device_remove(struct device* dev)
106 {
107     llist_delete(&dev->dev_list);
108     twifs_rm_node((struct twifs_node*)dev->fs_node);
109     vfree(dev);
110 }