2023-04-03 16:59:14 +01:00
|
|
|
#include <socks/device.h>
|
2023-06-09 21:24:51 +01:00
|
|
|
#include <socks/libc/stdio.h>
|
|
|
|
|
|
|
|
|
|
static struct queue all_buses;
|
|
|
|
|
static spin_lock_t all_buses_lock;
|
2023-04-03 16:59:14 +01:00
|
|
|
|
|
|
|
|
struct bus_device *bus_device_create(void)
|
|
|
|
|
{
|
|
|
|
|
struct device *dev = device_alloc();
|
|
|
|
|
if (!dev) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dev->dev_type = DEV_TYPE_BUS;
|
2023-06-02 19:35:07 +01:00
|
|
|
|
2023-04-03 16:59:14 +01:00
|
|
|
return BUS_DEVICE(dev);
|
|
|
|
|
}
|
2023-06-09 21:24:51 +01:00
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
};
|