#include static struct vm_cache tty_driver_cache = { .c_name = "tty_driver", .c_obj_size = sizeof(struct tty_driver), }; static struct queue tty_drivers; static spin_lock_t tty_drivers_lock; kern_status_t tty_init(void) { vm_cache_init(&tty_driver_cache); tty_drivers = QUEUE_INIT; tty_drivers_lock = SPIN_LOCK_INIT; return KERN_OK; } struct tty_driver *tty_driver_create(struct kext *self, const char *name) { struct tty_driver *driver = vm_cache_alloc(&tty_driver_cache, VM_NORMAL); if (!driver) { return NULL; } kern_status_t status = driver_init(&driver->tty_base, self, name); if (status != KERN_OK) { vm_cache_free(&tty_driver_cache, driver); return NULL; } strncpy(driver->tty_name, name, sizeof driver->tty_name - 1); return driver; } kern_status_t tty_driver_destroy(struct tty_driver *driver) { /* TODO */ return KERN_UNIMPLEMENTED; } kern_status_t tty_driver_register(struct tty_driver *driver) { kern_status_t status = driver_register(&driver->tty_base); if (status != KERN_OK) { return status; } unsigned long flags; spin_lock_irqsave(&tty_drivers_lock, &flags); queue_push_back(&tty_drivers, &driver->tty_head); spin_unlock_irqrestore(&tty_drivers_lock, flags); return KERN_OK; } kern_status_t tty_driver_unregister(struct tty_driver *driver) { if (driver->tty_base.drv_major == DEV_MAJOR_INVALID) { return KERN_INVALID_ARGUMENT; } unsigned long flags; spin_lock_irqsave(&tty_drivers_lock, &flags); queue_delete(&tty_drivers, &driver->tty_head); spin_unlock_irqrestore(&tty_drivers_lock, flags); return driver_unregister(&driver->tty_base); }