#include #include #include #include #include #include #include #include #include #include #include #if defined(__x86_64__) #include #endif static struct rb_node_link* device_tree = NULL; static spin_lock_t device_tree_lock; struct device* device_create (int id, device_op_func_t* ops, size_t ops_len, bool (*init) (void* arg), void (*fini) (void), void* arg) { if (ops_len >= fieldlengthof (struct device, ops)) return NULL; struct device* device = malloc (sizeof (*device)); if (device == NULL) return NULL; memset (device, 0, sizeof (*device)); device->id = id; device->init = init; device->fini = fini; if (ops != NULL) memcpy (device->ops, ops, ops_len * sizeof (device_op_func_t)); if (!device->init (arg)) { free (device); return NULL; } spin_lock (&device_tree_lock); rbtree_insert (struct device, &device_tree, &device->device_tree_link, device_tree_link, id); spin_unlock (&device_tree_lock); return device; } void device_delete (struct device* device) { spin_lock (&device_tree_lock); spin_lock (&device->lock); rbtree_delete (&device_tree, &device->device_tree_link); spin_unlock (&device->lock); spin_unlock (&device_tree_lock); device->fini (); } struct device* device_find (int id) { struct device* device = NULL; spin_lock (&device_tree_lock); rbtree_find (struct device, &device_tree, id, device, device_tree_link, id); spin_unlock (&device_tree_lock); return device; } void devices_init (void) { { device_op_func_t ops[] = { [TERMINAL_PUTSTR] = &terminal_putstr, }; device_create (TERMINAL_DEVICE, ops, lengthof (ops), &terminal_init, &terminal_fini, NULL); } #if defined(__x86_64__) { device_op_func_t ops[] = { [KB_READ_KEY] = &ps2kb_read_key, }; device_create (KB_DEVICE, ops, lengthof (ops), &ps2kb_init, &ps2kb_fini, NULL); } #endif }