#include #include static struct queue all_buses; static spin_lock_t all_buses_lock; struct bus_device *bus_device_create(void) { struct device *dev = device_alloc(); if (!dev) { return NULL; } dev->dev_type = DEV_TYPE_BUS; 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; } struct bus_device *bus_device_from_generic(struct device *dev) { dev->dev_type = DEV_TYPE_BUS; return BUS_DEVICE(dev); } 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); kern_status_t status = object_namespace_create_link(global_namespace(), path, &dev->dev_base); if (status != KERN_OK) { spin_lock_irqsave(&all_buses_lock, &flags); queue_delete(&all_buses, &bus->b_buslist); spin_unlock_irqrestore(&all_buses_lock, flags); return status; } return status; } struct device_type_ops bus_type_ops = { .register_device = bus_device_register, };