Add ATA PIO IRQ handler, documentation

Still WIP, doesn't look like IRQ handler works yet.
diff --git a/include/kernel/dri/ata_pio/ata_pio.h b/include/kernel/dri/ata_pio/ata_pio.h
index c509f52..667ed3b 100644
--- a/include/kernel/dri/ata_pio/ata_pio.h
+++ b/include/kernel/dri/ata_pio/ata_pio.h
@@ -29,6 +29,7 @@
 	ATA_PORT_LBA_LOW,
 	ATA_PORT_LBA_MID,
 	ATA_PORT_LBA_HIGH,
+	ATA_PORT_STATUS = ATA_PORT_CMD,
 };
 
 // Commands
@@ -36,12 +37,15 @@
 {
 	ATA_CMD_READ = 0x20,
 	ATA_CMD_WRITE = 0x30,
+	ATA_CMD_IDENTIFY = 0xec,
 };
 
 void ata_pio_wait_bsy();
 void ata_pio_wait_drq();
 void ata_pio_read_sectors(void *buffer, uint lba, uchar num_sectors);
-void ata_pio_write_sectors(uint lba, uchar num_sectors, void *buffer);
+void ata_pio_write_sectors(uint lba, uchar num_sectors, ushort *buffer);
 uint ata_pio_get_error();
 
 void test_ata_pio();
+
+void init_ata_pio();
\ No newline at end of file
diff --git a/include/kernel/io.h b/include/kernel/io.h
index 718bb20..be82998 100644
--- a/include/kernel/io.h
+++ b/include/kernel/io.h
@@ -3,34 +3,95 @@
 #include "kint.h"
 #include "registers.h"
 
+/**
+ * IO port for keyboard commands.
+ */
 #define KBD_CMD_PORT 0x64
+
+/**
+ * IO port for keyboard data
+ */
 #define KBD_DATA_PORT 0x60
 
-struct kbd_scan_code_info
-{
-	bool pressed;
-	bool escape;
-	char key;
-};
-
-extern struct kbd_scan_code_info scan_code_table[0xff];
-
+/**
+ * Write a byte to a port
+ */
 void outb(ushort port, uchar val);
+
+/**
+ * Write a double word to a port.
+ */
 void outl(ushort port, uint val);
+
+/**
+ * Read a byte from a port.
+ */
 uchar inb(ushort port);
+
+/**
+ * Read a word from a port.
+ */
 ushort inw(ushort port);
+
+/**
+ * Write a word to a port.
+ */
+void outw(ushort port, ushort val);
+
+/**
+ * Just waste some time.
+ */
+void nop();
+
+/**
+ * Read a double word from a port
+ */
 uint inl(ushort port);
 
-/* Random string.h stuff, TODO: move to own header */
+/**
+ * Set n bytes of s to c.
+ */
 void *memset(void *s, int c, size_t n);
+
+/**
+ * Copy n bytes from src to dest.
+ */
 void *memcpy(void *dest, const void *src, size_t n);
+
+/**
+ * Copy null terminated string src to dest.
+ */
 void strcpy(char *dest, char *src);
+
+/**
+ * Compare two strings. This might not work like the libc function, so be
+ * careful.
+ * @returns 0 if equal, non-0 otherwise.
+ */
 int strcmp(char *a, char *b);
+/**
+ * @returns the length of null-terminated string a.
+ */
 uint strlen(char *a);
 
 bool isdigit(char c);
+/**
+ * Ignores trailing non-digit characters.
+ * @returns 0 if string is not a valid decimal integer
+ */
 uint parse_int(char *string);
 
+/**
+ * Read a scan code from the keyboard
+ */
 uchar kbd_scan_code();
+
+/**
+ * Keyboard IRQ handler
+ */
 void kbd_handle_input(struct registers *registers);
+
+/**
+ * Set up keyboard driver.
+ */
 void init_kbd();
diff --git a/include/kernel/pic.h b/include/kernel/pic.h
new file mode 100644
index 0000000..de11f3f
--- /dev/null
+++ b/include/kernel/pic.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "kint.h"
+#include "registers.h"
+
+#define PIC1 0x20
+#define PIC2 0xa0
+#define PIC1_COMMAND PIC1
+#define PIC1_DATA (PIC1 + 1)
+#define PIC2_COMMAND PIC2
+#define PIC2_DATA (PIC2 + 1)
+
+#define PIC_EOI 0x20 // End of input
+
+#define IRQ_TO_INT(irq) ((irq) + 32)
+
+void pic_send_eoi(uchar interrupt);
+void add_interrupt_handler(uchar interrupt, void (*handler)(struct registers *));
+
+void pic_remap();
diff --git a/include/kernel/registers.h b/include/kernel/registers.h
index 687bd0e..8abe32f 100644
--- a/include/kernel/registers.h
+++ b/include/kernel/registers.h
@@ -2,6 +2,9 @@
 
 #include "kint.h"
 
+/**
+ * Represents the full execution state before an interrupt.
+ */
 struct registers
 {
 	uint ds;
diff --git a/include/kernel/task.h b/include/kernel/task.h
index 87b412b..b0d0f97 100644
--- a/include/kernel/task.h
+++ b/include/kernel/task.h
@@ -7,6 +7,9 @@
 
 extern bool tasks_initialized;
 
+/**
+ * A process. For now there is only one, the kernel.
+ */
 struct process
 {
 	bool exists;
@@ -20,12 +23,15 @@
 	// NOTE: must be PAGE ALIGNED
 	uint last_stack_pos;
 };
-
+/**
+ * The smallest schedulable unit, a thread of a process.
+ */
 struct task
 {
 	int id;
 	struct process *proc;
-	uint stack_top_p; // stack frame PHYSICAL address
+	/// Physical address of the top of the stack.
+	uint stack_top_p;
 	uint esp, ebp, eip;
 };
 
@@ -53,7 +59,23 @@
 #define TASK_FUNCTION(f) ((task_function_t)(f))
 
 void spawn_thread(task_function_t function, void *data);
+
+/**
+ * Halt the current thread.
+ */
 void kill_this_thread();
+
+/**
+ * Force a task switch. Only call in a safe environment (ISR).
+ */
 extern void switch_task();
+
+/**
+ * Switch to a specific task. Only call in a safe environment (ISR).
+ */
 void switch_to_task(struct task *task);
+
+/**
+ * Internal. Do not call.
+ */
 void _sys_init_tasks_h(struct registers *regs);
diff --git a/include/kernel/vfs.h b/include/kernel/vfs.h
index 1da0d6e..40a8e87 100644
--- a/include/kernel/vfs.h
+++ b/include/kernel/vfs.h
@@ -6,18 +6,27 @@
 
 struct fs_node
 {
-	char name[128]; /* file name */
-	uint inode;     /* identifier */
-	uint flags;     /* type of node */
-	uint mask;      /* permissions */
-	uint gid;       /* group id */
-	uint uid;       /* user id */
-	size_t size;    /* size in bytes */
-	uint dri_res;   /* reserved for driver */
+	/** file name */
+	char name[128];
+	/** identifier */
+	uint inode;
+	/** type of node */
+	uint flags;
+	/** permissions */
+	uint mask;
+	/** group id */
+	uint gid;
+	/** user id */
+	uint uid;
+	/** size in bytes */
+	size_t size;
+	/** reserved for driver */
+	uint dri_res;
 
 	struct fs_vtable *vtable;
 
-	struct fs_node *mount; /* used for mounts */
+	/** used for mounts */
+	struct fs_node *mount;
 };
 
 struct fs_dirent
@@ -26,13 +35,13 @@
 	uint inode;
 };
 
-typedef uint (* fs_read_t)(struct fs_node *node, size_t offset, size_t size, uchar *buffer);
-typedef uint (* fs_write_t)(struct fs_node *node, size_t offset, size_t size, uchar *buffer);
-typedef void (* fs_open_t)(struct fs_node *node);
-typedef void (* fs_close_t)(struct fs_node *node);
+typedef uint (*fs_read_t)(struct fs_node *node, size_t offset, size_t size, uchar *buffer);
+typedef uint (*fs_write_t)(struct fs_node *node, size_t offset, size_t size, uchar *buffer);
+typedef void (*fs_open_t)(struct fs_node *node);
+typedef void (*fs_close_t)(struct fs_node *node);
 
-typedef bool (* fs_readdir_t)(struct fs_node *node, uint index, struct fs_dirent *dirent);
-typedef struct fs_node *(* fs_finddir_t)(struct fs_node *node, char *name);
+typedef bool (*fs_readdir_t)(struct fs_node *node, uint index, struct fs_dirent *dirent);
+typedef struct fs_node *(*fs_finddir_t)(struct fs_node *node, char *name);
 
 struct fs_vtable
 {
@@ -52,8 +61,8 @@
 	FS_BLOCKDEVICE,
 	FS_PIPE,
 	FS_SYMLINK,
-	
-	FS_MOUNT = 8,   /* Can be or'd with others */
+
+	FS_MOUNT = 8, /* Can be or'd with others */
 };
 
 extern struct fs_node root, dev, initrd;