From d02d05d922dc05bd236c54af4ae47c5af8d34e36 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 14 May 2023 21:11:32 +0100 Subject: [PATCH] obj: add read() and write() object callbacks --- dev/core.c | 23 ++++++++++++++++++++--- dev/input.c | 8 ++++---- ds/ringbuffer.c | 8 ++++---- include/socks/device.h | 14 +++++++------- include/socks/flags.h | 11 +++++++++++ include/socks/object.h | 5 +++++ include/socks/ringbuffer.h | 9 ++------- include/socks/tty.h | 3 +++ init/main.c | 8 +++++--- obj/object.c | 30 ++++++++++++++++++++++++++++++ 10 files changed, 91 insertions(+), 28 deletions(-) create mode 100644 include/socks/flags.h diff --git a/dev/core.c b/dev/core.c index 38174ea..0d45e8a 100644 --- a/dev/core.c +++ b/dev/core.c @@ -9,13 +9,18 @@ static struct object *dev_folder = NULL; static struct device *__root_device = NULL; static struct device *__misc_device = NULL; static kern_status_t device_object_destroy(struct object *); +static kern_status_t device_object_read(struct object *obj, void *, size_t *, socks_flags_t); +static kern_status_t device_object_write(struct object *obj, const void *, size_t *, socks_flags_t); static kern_status_t device_object_query_name(struct object *, char out[OBJECT_NAME_MAX]); static kern_status_t device_object_get_child_at(struct object *, size_t, struct object **); static kern_status_t device_object_get_child_named(struct object *, const char *, struct object **); + static struct object_type device_type = { .ob_name = "device", .ob_size = sizeof(struct device), .ob_ops = { + .read = device_object_read, + .write = device_object_write, .destroy = device_object_destroy, .query_name = device_object_query_name, .get_at = device_object_get_child_at, @@ -91,17 +96,17 @@ struct device *device_alloc(void) return DEVICE_CAST(dev_object); } -kern_status_t device_read(struct device *dev, void *buf, size_t size, size_t *bytes_read) +kern_status_t device_read(struct device *dev, void *buf, size_t size, size_t *bytes_read, socks_flags_t flags) { switch (dev->dev_type) { case DEV_TYPE_INPUT: - return input_device_read(dev, buf, size, bytes_read); + return input_device_read(dev, buf, size, bytes_read, flags); default: return KERN_UNSUPPORTED; } } -kern_status_t device_write(struct device *dev, const void *buf, size_t size, size_t *bytes_written) +kern_status_t device_write(struct device *dev, const void *buf, size_t size, size_t *bytes_written, socks_flags_t flags) { return KERN_UNSUPPORTED; } @@ -111,6 +116,18 @@ struct device *cast_to_device(struct object *obj) return DEVICE_CAST(obj); } +static kern_status_t device_object_read(struct object *obj, void *p, size_t *count, socks_flags_t flags) +{ + struct device *dev = DEVICE_CAST(obj); + return device_read(dev, p, *count, count, flags); +} + +static kern_status_t device_object_write(struct object *obj, const void *p, size_t *count, socks_flags_t flags) +{ + struct device *dev = DEVICE_CAST(obj); + return device_write(dev, p, *count, count, flags); +} + static kern_status_t device_object_destroy(struct object *obj) { return KERN_OK; diff --git a/dev/input.c b/dev/input.c index e8272ec..f6c0917 100644 --- a/dev/input.c +++ b/dev/input.c @@ -35,9 +35,9 @@ struct input_device *input_device_create(void) kern_status_t input_device_report_event(struct input_device *dev, const struct input_event *ev, bool noblock) { struct ringbuffer *event_queue = &dev->i_events; - enum ringbuffer_flags flags = RB_NORMAL; + socks_flags_t flags = S_NORMAL; if (noblock) { - flags = RB_NOBLOCK; + flags = S_NOBLOCK; } size_t r = ringbuffer_write(event_queue, sizeof *ev, ev, flags); @@ -45,7 +45,7 @@ kern_status_t input_device_report_event(struct input_device *dev, const struct i return r == sizeof *ev ? KERN_OK : KERN_WOULD_BLOCK; } -kern_status_t input_device_read(struct device *dev, void *buf, size_t size, size_t *bytes_read) +kern_status_t input_device_read(struct device *dev, void *buf, size_t size, size_t *bytes_read, socks_flags_t flags) { if (dev->dev_type != DEV_TYPE_INPUT || (size % sizeof (struct input_event)) != 0) { return KERN_INVALID_ARGUMENT; @@ -54,7 +54,7 @@ kern_status_t input_device_read(struct device *dev, void *buf, size_t size, size struct input_device *input_dev = INPUT_DEVICE(dev); struct ringbuffer *event_queue = &input_dev->i_events; - size_t r = ringbuffer_read(event_queue, size, buf, RB_NORMAL); + size_t r = ringbuffer_read(event_queue, size, buf, flags); if (bytes_read) { *bytes_read = r; diff --git a/ds/ringbuffer.c b/ds/ringbuffer.c index ab6d47a..2a016e8 100644 --- a/ds/ringbuffer.c +++ b/ds/ringbuffer.c @@ -45,7 +45,7 @@ static inline void increment_write(struct ringbuffer *ring_buffer) } } -size_t ringbuffer_read(struct ringbuffer *ring_buffer, size_t size, void *p, enum ringbuffer_flags flags) +size_t ringbuffer_read(struct ringbuffer *ring_buffer, size_t size, void *p, socks_flags_t flags) { if (!ring_buffer) { return 0; @@ -65,7 +65,7 @@ size_t ringbuffer_read(struct ringbuffer *ring_buffer, size_t size, void *p, enu wakeup_queue(&ring_buffer->r_wait_writers); - if (flags & RB_NOBLOCK) { + if (flags & S_NOBLOCK) { spin_unlock_irqrestore(&ring_buffer->r_lock, lock_flags); break; } @@ -86,7 +86,7 @@ size_t ringbuffer_read(struct ringbuffer *ring_buffer, size_t size, void *p, enu return collected; } -size_t ringbuffer_write(struct ringbuffer *ring_buffer, size_t size, const void *p, enum ringbuffer_flags flags) +size_t ringbuffer_write(struct ringbuffer *ring_buffer, size_t size, const void *p, socks_flags_t flags) { if (!ring_buffer || !size) { return 0; @@ -107,7 +107,7 @@ size_t ringbuffer_write(struct ringbuffer *ring_buffer, size_t size, const void wakeup_queue(&ring_buffer->r_wait_readers); - if (flags & RB_NOBLOCK) { + if (flags & S_NOBLOCK) { spin_unlock_irqrestore(&ring_buffer->r_lock, lock_flags); break; } diff --git a/include/socks/device.h b/include/socks/device.h index 5d96553..1616beb 100644 --- a/include/socks/device.h +++ b/include/socks/device.h @@ -29,8 +29,8 @@ enum device_type { }; struct block_device_ops { - kern_status_t(*read_blocks)(struct device *, size_t, size_t *, void *); - kern_status_t(*write_blocks)(struct device *, size_t, size_t *, const void *); + kern_status_t(*read_blocks)(struct device *, size_t, size_t *, void *, socks_flags_t); + kern_status_t(*write_blocks)(struct device *, size_t, size_t *, const void *, socks_flags_t); kern_status_t(*ioctl)(struct device *, unsigned int, void *); }; @@ -42,8 +42,8 @@ struct net_device_ops { }; struct char_device_ops { - kern_status_t(*read)(struct device *, size_t, size_t *, void *); - kern_status_t(*write)(struct device *, size_t, size_t *, const void *); + kern_status_t(*read)(struct device *, size_t, size_t *, void *, socks_flags_t); + kern_status_t(*write)(struct device *, size_t, size_t *, const void *, socks_flags_t); }; struct input_device_ops { @@ -110,8 +110,8 @@ static inline void device_unlock_irqrestore(struct device *dev, unsigned long fl object_unlock(&dev->dev_base, flags); } -extern kern_status_t device_read(struct device *dev, void *buf, size_t size, size_t *bytes_read); -extern kern_status_t device_write(struct device *dev, const void *buf, size_t size, size_t *bytes_written); +extern kern_status_t device_read(struct device *dev, void *buf, size_t size, size_t *bytes_read, socks_flags_t flags); +extern kern_status_t device_write(struct device *dev, const void *buf, size_t size, size_t *bytes_written, socks_flags_t flags); extern struct device *cast_to_device(struct object *obj); @@ -149,7 +149,7 @@ static inline struct device *bus_device_base(struct bus_device *dev) extern kern_status_t device_register(struct device *dev, struct device *parent); extern kern_status_t input_device_report_event(struct input_device *dev, const struct input_event *ev, bool noblock); -extern kern_status_t input_device_read(struct device *dev, void *buf, size_t size, size_t *bytes_read); +extern kern_status_t input_device_read(struct device *dev, void *buf, size_t size, size_t *bytes_read, socks_flags_t flags); extern kern_status_t input_device_generate_name(struct input_device *dev); #endif diff --git a/include/socks/flags.h b/include/socks/flags.h new file mode 100644 index 0000000..8aa3150 --- /dev/null +++ b/include/socks/flags.h @@ -0,0 +1,11 @@ +#ifndef SOCKS_FLAGS_H_ +#define SOCKS_FLAGS_H_ + +#include + +typedef enum { + S_NORMAL = 0x00u, + S_NOBLOCK = 0x01u, +} socks_flags_t; + +#endif diff --git a/include/socks/object.h b/include/socks/object.h index 1f0bfdc..66b9384 100644 --- a/include/socks/object.h +++ b/include/socks/object.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -30,6 +31,8 @@ enum object_type_flags { struct object_ops { kern_status_t(*open)(struct object *obj); kern_status_t(*close)(struct object *obj); + kern_status_t(*read)(struct object *obj, void *p, size_t *r, socks_flags_t flags); + kern_status_t(*write)(struct object *obj, const void *p, size_t *w, socks_flags_t flags); kern_status_t(*destroy)(struct object *obj); kern_status_t(*query_name)(struct object *obj, char out[OBJECT_NAME_MAX]); kern_status_t(*parse)(struct object *obj, const char *path, struct object **out); @@ -85,6 +88,8 @@ static inline kern_status_t object_get(const char *path, struct object **out) { return object_namespace_get_object(global_namespace(), path, out); } +extern kern_status_t object_read(struct object *obj, void *p, size_t max, size_t *nr_read, socks_flags_t flags); +extern kern_status_t object_write(struct object *obj, const void *p, size_t max, size_t *nr_written, socks_flags_t flags); extern kern_status_t object_get_child_named(struct object *obj, const char *name, struct object **out); extern kern_status_t object_get_child_at(struct object *obj, size_t at, struct object **out); extern kern_status_t object_query_name(struct object *obj, char name[OBJECT_NAME_MAX]); diff --git a/include/socks/ringbuffer.h b/include/socks/ringbuffer.h index ab6af1d..1be91c4 100644 --- a/include/socks/ringbuffer.h +++ b/include/socks/ringbuffer.h @@ -14,11 +14,6 @@ struct ringbuffer { struct waitqueue r_wait_writers; }; -enum ringbuffer_flags { - RB_NORMAL = 0x00u, - RB_NOBLOCK = 0x01u, -}; - extern struct ringbuffer *ringbuffer_create(size_t size); extern void ringbuffer_destroy(struct ringbuffer *buf); @@ -27,8 +22,8 @@ extern kern_status_t ringbuffer_deinit(struct ringbuffer *buf); extern size_t ringbuffer_unread(struct ringbuffer *buf); extern size_t ringbuffer_avail(struct ringbuffer *buf); -extern size_t ringbuffer_read(struct ringbuffer *buf, size_t size, void *buffer, enum ringbuffer_flags flags); -extern size_t ringbuffer_write(struct ringbuffer *buf, size_t size, const void *buffer, enum ringbuffer_flags flags); +extern size_t ringbuffer_read(struct ringbuffer *buf, size_t size, void *buffer, socks_flags_t flags); +extern size_t ringbuffer_write(struct ringbuffer *buf, size_t size, const void *buffer, socks_flags_t flags); extern int ringbuffer_write_would_block(struct ringbuffer *buf); diff --git a/include/socks/tty.h b/include/socks/tty.h index 29993d5..a88a0e1 100644 --- a/include/socks/tty.h +++ b/include/socks/tty.h @@ -3,6 +3,7 @@ #include #include +#include #include /* The TTY system. @@ -58,6 +59,8 @@ enum tty_scroll_dir { typedef uint64_t tty_attrib_t; struct tty_driver { + struct object tty_base; + char tty_name[16]; enum tty_driver_type tty_type; struct queue_entry tty_list; diff --git a/init/main.c b/init/main.c index 276884b..cbac796 100644 --- a/init/main.c +++ b/init/main.c @@ -186,13 +186,14 @@ void kernel_init(uintptr_t arg) create_kernel_thread(background_thread); - struct object *kbd_obj; - status = object_namespace_get_object(global_namespace(), "/dev/system/misc/input0", &kbd_obj); + struct object *kbd; + status = object_namespace_get_object(global_namespace(), "/dev/system/misc/input0", &kbd); if (status != KERN_OK) { printk("no keyboard available"); hang(); } + #if 0 struct device *kbd_dev = cast_to_device(kbd_obj); if (!kbd_dev) { printk("no keyboard available"); @@ -204,11 +205,12 @@ void kernel_init(uintptr_t arg) printk("no keyboard available"); hang(); } + #endif while (1) { struct input_event ev; size_t r; - status = device_read(kbd_dev, &ev, sizeof ev, &r); + status = object_read(kbd, &ev, sizeof ev, &r, 0); if (status != KERN_OK || r != sizeof ev) { printk("keyboard read error: %s", kern_status_string(status)); diff --git a/obj/object.c b/obj/object.c index b450a88..d8be0ab 100644 --- a/obj/object.c +++ b/obj/object.c @@ -121,6 +121,36 @@ struct object *object_header(void *p) return obj; } +kern_status_t object_read(struct object *obj, void *p, size_t max, + size_t *nr_read, socks_flags_t flags) +{ + kern_status_t status = KERN_UNSUPPORTED; + + if (obj->ob_type->ob_ops.read) { + status = obj->ob_type->ob_ops.read(obj, p, &max, flags); + } else { + max = 0; + } + + if (nr_read) { + *nr_read = max; + } + + return status; +} + +kern_status_t object_write(struct object *obj, const void *p, size_t max, + size_t *nr_written, socks_flags_t flags) +{ + kern_status_t status = KERN_UNSUPPORTED; + + if (obj->ob_type->ob_ops.write) { + status = obj->ob_type->ob_ops.write(obj, p, &max, flags); + } + + return status; +} + kern_status_t object_get_child_named(struct object *obj, const char *name, struct object **out) { kern_status_t status = KERN_UNSUPPORTED;