#include #include #include static struct char_device_ops tty_ops = { .read = tty_read, .write = tty_write, }; struct device *tty_device_create(void) { struct char_device *cdev = char_device_create(); if (!cdev) { return NULL; } struct tty_device *tty_dev = kmalloc(sizeof *tty_dev, VM_NORMAL); if (!tty_dev) { /* TODO destroy cdev */ return NULL; } cdev->c_ops = &tty_ops; cdev->c_tty = tty_dev; return char_device_base(cdev); } static kern_status_t generate_name(struct tty_driver *owner, struct device *dev, char out[DEV_NAME_MAX]) { /* minor numbers start at 1. subtract 1 to start at 0 instead */ snprintf(out, DEV_NAME_MAX, "%s%u", owner->tty_name, dev->dev_minor - 1); return KERN_OK; } kern_status_t tty_device_register(struct device *dev, struct tty_driver *owner, struct device *parent) { kern_status_t status = device_register(dev, tty_driver_base(owner), parent); if (status != KERN_OK) { return status; } char link_name[DEV_NAME_MAX]; generate_name(owner, dev, link_name); char link_path[OBJECT_PATH_MAX]; snprintf(link_path, sizeof link_path, "/dev/tty/%s", link_name); return object_namespace_create_link(global_namespace(), link_path, &dev->dev_base); }