dev: implement bus device enumeration
This commit is contained in:
44
dev/bus.c
44
dev/bus.c
@@ -1,4 +1,8 @@
|
|||||||
#include <socks/device.h>
|
#include <socks/device.h>
|
||||||
|
#include <socks/libc/stdio.h>
|
||||||
|
|
||||||
|
static struct queue all_buses;
|
||||||
|
static spin_lock_t all_buses_lock;
|
||||||
|
|
||||||
struct bus_device *bus_device_create(void)
|
struct bus_device *bus_device_create(void)
|
||||||
{
|
{
|
||||||
@@ -11,3 +15,43 @@ struct bus_device *bus_device_create(void)
|
|||||||
|
|
||||||
return BUS_DEVICE(dev);
|
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,
|
||||||
|
};
|
||||||
|
|||||||
15
dev/core.c
15
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 input_type_ops;
|
||||||
extern struct device_type_ops framebuffer_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[] = {
|
static struct device_type_ops *type_ops[] = {
|
||||||
[DEV_TYPE_UNKNOWN] = NULL,
|
[DEV_TYPE_UNKNOWN] = NULL,
|
||||||
@@ -28,7 +29,7 @@ static struct device_type_ops *type_ops[] = {
|
|||||||
[DEV_TYPE_CHAR] = NULL,
|
[DEV_TYPE_CHAR] = NULL,
|
||||||
[DEV_TYPE_NET] = NULL,
|
[DEV_TYPE_NET] = NULL,
|
||||||
[DEV_TYPE_INPUT] = &input_type_ops,
|
[DEV_TYPE_INPUT] = &input_type_ops,
|
||||||
[DEV_TYPE_BUS] = NULL,
|
[DEV_TYPE_BUS] = &bus_type_ops,
|
||||||
[DEV_TYPE_FRAMEBUFFER] = &framebuffer_type_ops,
|
[DEV_TYPE_FRAMEBUFFER] = &framebuffer_type_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -108,6 +109,18 @@ struct device *device_alloc(void)
|
|||||||
return DEVICE_CAST(dev_object);
|
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)
|
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) {
|
switch (dev->dev_type) {
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ struct input_device {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct bus_device {
|
struct bus_device {
|
||||||
|
struct queue_entry b_buslist;
|
||||||
struct bus_device_ops *b_ops;
|
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 *cast_to_device(struct object *obj);
|
||||||
|
|
||||||
|
extern struct device *generic_device_create(void);
|
||||||
extern struct char_device *char_device_create(void);
|
extern struct char_device *char_device_create(void);
|
||||||
extern struct block_device *block_device_create(void);
|
extern struct block_device *block_device_create(void);
|
||||||
extern struct net_device *net_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);
|
spin_unlock_irqrestore(&driver->drv_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern kern_status_t scan_all_buses(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -180,6 +180,8 @@ void kernel_init(uintptr_t arg)
|
|||||||
panic("bring_internal_kexts_online() failed with code %s", kern_status_string(status));
|
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());
|
printk("kernel_init() running on processor %u", this_cpu());
|
||||||
|
|
||||||
create_kernel_thread(background_thread);
|
create_kernel_thread(background_thread);
|
||||||
@@ -195,7 +197,7 @@ void kernel_init(uintptr_t arg)
|
|||||||
struct framebuffer_device *fb_info = FRAMEBUFFER_DEVICE(fb_dev);
|
struct framebuffer_device *fb_info = FRAMEBUFFER_DEVICE(fb_dev);
|
||||||
|
|
||||||
printk("fb: mode=%ux%ux%u type=%u cells=%ux%u",
|
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_flags,
|
||||||
fb_info->fb_varinfo.fb_xcells, fb_info->fb_varinfo.fb_ycells);
|
fb_info->fb_varinfo.fb_xcells, fb_info->fb_varinfo.fb_ycells);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user