diff --git a/dev/block.c b/dev/block.c index 61acc93..1fe57c2 100644 --- a/dev/block.c +++ b/dev/block.c @@ -1,4 +1,10 @@ #include +#include +#include +#include + +static DECLARE_BITMAP(block_device_ids, BLOCK_DEVICE_MAX); +static spin_lock_t block_device_ids_lock = SPIN_LOCK_INIT; struct block_device *block_device_create(void) { @@ -17,3 +23,43 @@ struct block_device *block_device_from_generic(struct device *dev) dev->dev_type = DEV_TYPE_BLOCK; return BLOCK_DEVICE(dev); } + +kern_status_t block_device_read(struct device *dev, void *buf, size_t size, size_t *bytes_read, socks_flags_t flags) +{ + return KERN_UNIMPLEMENTED; +} + +static kern_status_t generate_name(struct block_device *dev, char out[DEV_NAME_MAX]) +{ + snprintf(out, DEV_NAME_MAX, "disk%u", dev->b_id); + return KERN_OK; +} + +kern_status_t block_device_register(struct device *dev) +{ + unsigned long flags; + spin_lock_irqsave(&block_device_ids_lock, &flags); + unsigned int id = bitmap_lowest_clear(block_device_ids, BLOCK_DEVICE_MAX); + bitmap_set(block_device_ids, id); + spin_unlock_irqrestore(&block_device_ids_lock, flags); + + struct block_device *blockdev = &dev->blk; + blockdev->b_id = id; + + char name[DEV_NAME_MAX]; + generate_name(blockdev, name); + char path[OBJECT_PATH_MAX]; + snprintf(path, sizeof path, "/dev/block/%s", name); + + char size_string[32]; + data_size_to_string(blockdev->sector_size * blockdev->capacity, size_string, sizeof size_string); + + printk("dev: found %s %s block device '%s'", size_string, dev->dev_owner->drv_name, dev->dev_model_name); + + return object_namespace_create_link(global_namespace(), path, &dev->dev_base); +} + +struct device_type_ops block_type_ops = { + .register_device = block_device_register, + .read = block_device_read, +}; diff --git a/dev/core.c b/dev/core.c index c36b648..49e150e 100644 --- a/dev/core.c +++ b/dev/core.c @@ -20,13 +20,14 @@ static kern_status_t device_object_get_child_named(struct object *, const char * extern kern_status_t init_driver_tree(void); extern struct device_type_ops char_type_ops; +extern struct device_type_ops block_type_ops; extern struct device_type_ops input_type_ops; extern struct device_type_ops framebuffer_type_ops; extern struct device_type_ops bus_type_ops; static struct device_type_ops *type_ops[] = { [DEV_TYPE_UNKNOWN] = NULL, - [DEV_TYPE_BLOCK] = NULL, + [DEV_TYPE_BLOCK] = &block_type_ops, [DEV_TYPE_CHAR] = &char_type_ops, [DEV_TYPE_NET] = NULL, [DEV_TYPE_INPUT] = &input_type_ops, diff --git a/include/socks/device.h b/include/socks/device.h index 3c06fc0..2cb76c8 100644 --- a/include/socks/device.h +++ b/include/socks/device.h @@ -23,6 +23,7 @@ struct tty_device; #define INPUT_DEVICE_EVENT_QUEUE_SIZE 128 #define INPUT_DEVICE_MAX 4096 +#define BLOCK_DEVICE_MAX 4096 #define FRAMEBUFFER_DEVICE_MAX 4096 #define BLOCK_DEVICE(dev) ((dev)->dev_type == DEV_TYPE_BLOCK ? &(dev)->blk : NULL) @@ -80,6 +81,9 @@ struct framebuffer_device_ops { struct block_device { struct block_device_ops *b_ops; + unsigned int b_id; + unsigned int sector_size; + sectors_t capacity; }; struct char_device { @@ -161,6 +165,11 @@ struct driver { struct driver_ops *drv_ops; }; +struct iovec { + void *io_buf; + size_t io_len; +}; + extern kern_status_t device_init(void); extern struct device *root_device(void); extern struct device *misc_device(void); diff --git a/include/socks/types.h b/include/socks/types.h index e70992a..e21ef5c 100644 --- a/include/socks/types.h +++ b/include/socks/types.h @@ -7,6 +7,7 @@ typedef uintptr_t phys_addr_t; typedef uint64_t cycles_t; +typedef uint64_t sectors_t; typedef unsigned int umode_t;