Orion
Barry Keyboard/Mouse drivers + POSIX names for structs 1628fcf (2 years, 4 months ago)/* * This file implements a keyboard driver. It generates the /dev/kbd device * file, which can be read and returns a structure of the keyboard data. This * driver produces raw keyboard data, not parsed text. */ #include <sys/kbd.h> #include "../drivers.h" #include "../../task/task.h" #include "../../proc/proc.h" #include "../../io.h" void tty_keypress(unsigned char key); size_t kbd_read(File *file, char *buf, size_t size, off_t offset); FileOps kbdFileOps = { .read = kbd_read, }; Driver kbdDriver = { .major = 10, .ops = &kbdFileOps, .next = NULL, }; TaskQueue keyWait; /* Ring buffer for keys */ struct KeyBuffer { int start, end; char key[1024]; } keyBuf; /* Add a key to the key buffer */ static void add_to_buf(char key) { /* No more space in buffer */ int start = (keyBuf.start + sizeof(keyBuf.key) - 1) % sizeof(keyBuf.key); if (keyBuf.end == start) return; keyBuf.key[keyBuf.end] = key; keyBuf.end++; keyBuf.end %= sizeof(keyBuf.key); } /* Get a key from the key buffer */ static char get_from_buf(void) { /* Nothing to read */ if (keyBuf.start == keyBuf.end) return 0x00; char key = keyBuf.key[keyBuf.start]; keyBuf.start++; keyBuf.start %= sizeof(keyBuf.key); return key; } /* Handle the keyboard interrupt */ static void keyboard_handler(InterruptFrame *frame) { unsigned char key; int i; for (i = 0; i < 1000; i++) { if ((inb(0x64) & 1) == 0) continue; key = inb(0x60); break; } if (i == 1000) return; add_to_buf(key); tty_keypress(key); for (Task *tmp = keyWait.start; tmp; tmp = tmp->next) unblock_task(pop_from_queue(&keyWait)); } /* Initialise the keyboard */ void init_kbd(void) { register_driver(&kbdDriver); mknod("/dev/kbd", S_IFCHR | 0666, MKDEV(kbdDriver.major, 0)); register_interrupt(1, keyboard_handler); } size_t kbd_read(File *file, char *buf, size_t size, off_t offset) { char c; size_t count = 0; while (count < size) { c = get_from_buf(); if (!c) { add_to_queue(&keyWait, current); block_task(WAITING_FOR_IO); } *(buf + count) = c; count++; } return count; }