diff --git a/dev/bus.c b/dev/bus.c index 3c1e542..570e014 100644 --- a/dev/bus.c +++ b/dev/bus.c @@ -1,4 +1,8 @@ #include +#include + +static struct queue all_buses; +static spin_lock_t all_buses_lock; struct bus_device *bus_device_create(void) { @@ -11,3 +15,43 @@ struct bus_device *bus_device_create(void) return BUS_DEVICE(dev); } + +kern_status_t scan_all_buses(void) +{ + kern_status_t status = KERN_OK; + + /* keep interrupts enabled while scanning for devices */ + spin_lock(&all_buses_lock); + + queue_foreach(struct bus_device, bus, &all_buses, b_buslist) { + if (bus->b_ops && bus->b_ops->scan) { + status = bus->b_ops->scan(bus_device_base(bus)); + } + + if (status != KERN_OK) { + break; + } + } + + spin_unlock(&all_buses_lock); + return status; +} + +static kern_status_t bus_device_register(struct device *dev) +{ + struct bus_device *bus = &dev->bus; + + unsigned long flags; + spin_lock_irqsave(&all_buses_lock, &flags); + queue_push_back(&all_buses, &bus->b_buslist); + spin_unlock_irqrestore(&all_buses_lock, flags); + + char path[OBJECT_PATH_MAX]; + snprintf(path, sizeof path, "/dev/bus/%s", dev->dev_name); + + return object_namespace_create_link(global_namespace(), path, &dev->dev_base); +} + +struct device_type_ops bus_type_ops = { + .register_device = bus_device_register, +}; diff --git a/dev/core.c b/dev/core.c index 8b54a3d..27e4bb8 100644 --- a/dev/core.c +++ b/dev/core.c @@ -21,6 +21,7 @@ extern kern_status_t init_driver_tree(void); 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, @@ -28,7 +29,7 @@ static struct device_type_ops *type_ops[] = { [DEV_TYPE_CHAR] = NULL, [DEV_TYPE_NET] = NULL, [DEV_TYPE_INPUT] = &input_type_ops, - [DEV_TYPE_BUS] = NULL, + [DEV_TYPE_BUS] = &bus_type_ops, [DEV_TYPE_FRAMEBUFFER] = &framebuffer_type_ops, }; @@ -108,6 +109,18 @@ struct device *device_alloc(void) return DEVICE_CAST(dev_object); } +struct device *generic_device_create(void) +{ + struct device *dev = device_alloc(); + if (!dev) { + return NULL; + } + + dev->dev_type = DEV_TYPE_UNKNOWN; + + return dev; +} + 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) { diff --git a/include/socks/device.h b/include/socks/device.h index 306d3be..4f15c59 100644 --- a/include/socks/device.h +++ b/include/socks/device.h @@ -92,6 +92,7 @@ struct input_device { }; struct bus_device { + struct queue_entry b_buslist; struct bus_device_ops *b_ops; }; @@ -175,6 +176,7 @@ extern kern_status_t device_write(struct device *dev, const void *buf, size_t si extern struct device *cast_to_device(struct object *obj); +extern struct device *generic_device_create(void); extern struct char_device *char_device_create(void); extern struct block_device *block_device_create(void); extern struct net_device *net_device_create(void); @@ -247,4 +249,6 @@ static inline void driver_unlock_irqrestore(struct driver *driver, unsigned long spin_unlock_irqrestore(&driver->drv_lock, flags); } +extern kern_status_t scan_all_buses(void); + #endif diff --git a/init/main.c b/init/main.c index 7b16fc3..5bde89a 100644 --- a/init/main.c +++ b/init/main.c @@ -180,6 +180,8 @@ void kernel_init(uintptr_t arg) panic("bring_internal_kexts_online() failed with code %s", kern_status_string(status)); } + scan_all_buses(); + printk("kernel_init() running on processor %u", this_cpu()); create_kernel_thread(background_thread); @@ -195,7 +197,7 @@ void kernel_init(uintptr_t arg) struct framebuffer_device *fb_info = FRAMEBUFFER_DEVICE(fb_dev); printk("fb: mode=%ux%ux%u type=%u cells=%ux%u", - fb_info->fb_varinfo.fb_xres, fb_info->fb_varinfo.fb_yres, + fb_info->fb_varinfo.fb_xres, fb_info->fb_varinfo.fb_yres, fb_info->fb_varinfo.fb_bpp, fb_info->fb_varinfo.fb_flags, fb_info->fb_varinfo.fb_xcells, fb_info->fb_varinfo.fb_ycells); } else {