Index: kbd/generic/kbd.c
===================================================================
--- kbd/generic/kbd.c	(revision 250717cc879c7f068fa71fc6aab936263ef42849)
+++ kbd/generic/kbd.c	(revision ec153a05a58461d65a28c1f1bec1a537ed89ad7e)
@@ -53,7 +53,8 @@
 	
 	ipcarg_t retval, arg1, arg2;
-	
+
+	/* Counter of unsatisfied calls */
 	fifo_count_t callers_counter = 0;
-	
+	/* Fifo with callid's of unsatisfied calls requred for answer */
 	FIFO_INITIALIZE_STATIC(callers_buffer, ipc_callid_t, KBD_REQUEST_MAX);
 
@@ -81,65 +82,81 @@
 	//	printf("%s:Call phone=%lX..", NAME, call.in_phone_hash);
 		switch (IPC_GET_METHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			if (connected) {
-				if (--connected == 0) {
-					callers_counter = 0;
-					callers_buffer.head = callers_buffer.tail = 0;
-					key_buffer_free();	
+			case IPC_M_PHONE_HUNGUP:
+				if (connected) {
+					/* If nobody's connected, clear keybuffer and dont store new keys */
+					if (--connected == 0) {
+						callers_counter = 0;
+						callers_buffer.head = callers_buffer.tail = 0;
+						key_buffer_free();	
+					}
+					
+					printf("%s: Phone hung up.\n", NAME);
+				} else {
+					printf("%s: Oops, got phone hung up, but nobody connected.\n", NAME);
 				}
-			}
-			
-			printf("%s: Phone hung up.\n", NAME);
-			retval = 0;
-			break;
-		case IPC_M_CONNECT_TO_ME:
-			printf("%s: Somebody connecting phid=%zd.\n", NAME, IPC_GET_ARG3(call));
-			retval = 0;
-			break;
-		case IPC_M_CONNECT_ME_TO:
-		//	printf("%s: Connect me (%P) to: %zd\n",NAME, IPC_GET_ARG3(call), IPC_GET_ARG1(call));
-			if (connected) {
-				retval = ELIMIT;
-			} else {
+				
 				retval = 0;
-				connected = 1;
-			}
-			break;
-		case IPC_M_INTERRUPT:
-			if (connected) {
-				kbd_arch_process(IPC_GET_ARG2(call));
-			}
-			//printf("%s: GOT INTERRUPT: %c\n", NAME, IPC_GET_ARG2(call));
-			if (!callers_counter)
 				break;
-			/* Small trick - interrupt does not need answer so we can change callid to caller awaiting key */
-			callers_counter--;
-			callid = fifo_pop(callers_buffer);
-		case KBD_GETCHAR:
-//			printf("%s: Getchar: ", NAME);
-			retval = 0;
-			arg1 = 0;	
-			if (!key_buffer_pop((char *)&arg1)) {
-				if (callers_counter < KBD_REQUEST_MAX) {
-					callers_counter++;
-					fifo_push(callers_buffer, callid);
+			case IPC_M_CONNECT_TO_ME:
+				printf("%s: Somebody connecting phid=%zd.\n", NAME, IPC_GET_ARG3(call));
+				retval = 0;
+				break;
+			case IPC_M_CONNECT_ME_TO:
+			//	printf("%s: Connect me (%P) to: %zd\n",NAME, IPC_GET_ARG3(call), IPC_GET_ARG1(call));
+				/* Only one connected client allowed */
+				if (connected) {
+					retval = ELIMIT;
 				} else {
-					retval = ELIMIT;
+					retval = 0;
+					connected = 1;
 				}
-				continue;
-			};
-			arg2 = 0xbeef;
-		//	printf("GetChar return %c\n", arg1);
-			
-			break;
-		default:
-			printf("%s: Unknown method: %zd\n", NAME, IPC_GET_METHOD(call));
-			retval = ENOENT;
-			break;
+				break;
+			case IPC_M_INTERRUPT:
+				if (connected) {
+					/* recode scancode and store it into key buffer */
+					kbd_arch_process(IPC_GET_ARG2(call));
+					//printf("%s: GOT INTERRUPT: %c\n", NAME, IPC_GET_ARG2(call));
+
+					/* Some callers could awaiting keypress - if its true, we have to send keys to them.
+					 * One interrupt can store more than one key into buffer. */
+					retval = 0;
+					arg2 = 0xbeef;
+					while ((callers_counter) && (!key_buffer_empty())) {
+						callers_counter--;
+						if (!key_buffer_pop((char *)&arg1)) {
+							printf("%s: KeyBuffer empty but it should not be.\n");
+							break;
+						}
+						ipc_answer_fast(fifo_pop(callers_buffer), retval, arg1, arg2);
+					}
+				}
+				break;
+			case KBD_GETCHAR:
+	//			printf("%s: Getchar: ", NAME);
+				retval = 0;
+				arg1 = 0;	
+				if (!key_buffer_pop((char *)&arg1)) {
+					if (callers_counter < KBD_REQUEST_MAX) {
+						callers_counter++;
+						fifo_push(callers_buffer, callid);
+					} else {
+						retval = ELIMIT;
+					}
+					continue;
+				};
+				arg2 = 0xbeef;
+			//	printf("GetChar return %c\n", arg1);
+				
+				break;
+			default:
+				printf("%s: Unknown method: %zd\n", NAME, IPC_GET_METHOD(call));
+				retval = ENOENT;
+				break;
 		}
+
 		if (! (callid & IPC_CALLID_NOTIFICATION)) {
-		//	printf("%s: Answering\n", NAME);
 			ipc_answer_fast(callid, retval, arg1, arg2);
 		}
 	}
 }
+
Index: kbd/generic/key_buffer.c
===================================================================
--- kbd/generic/key_buffer.c	(revision 250717cc879c7f068fa71fc6aab936263ef42849)
+++ kbd/generic/key_buffer.c	(revision ec153a05a58461d65a28c1f1bec1a537ed89ad7e)
@@ -30,9 +30,11 @@
 #include <fifo.h>
 
-#define KBD_BUFFER_SIZE 128
+#define KBD_BUFFER_SIZE 128 /**< Size of buffer for pressed keys */
 
-FIFO_INITIALIZE_STATIC(buffer, char, KBD_BUFFER_SIZE);
-fifo_count_t buffer_items;
+FIFO_INITIALIZE_STATIC(buffer, char, KBD_BUFFER_SIZE);	/**< Fifo for storing pressed keys */
+fifo_count_t buffer_items;	/**< Counter of used items for prevent fifo overflow */
 
+/** Clear key buffer.
+ */
 void key_buffer_free(void)
 {
@@ -41,4 +43,7 @@
 }
 
+/** Key buffer initialization.
+ *
+ */
 void key_buffer_init(void)
 {
@@ -46,5 +51,7 @@
 }
 
-/** 
+/** Get free space in buffer.
+ * This function is useful for processing some scancodes that are translated 
+ * to more than one character.
  * @return empty buffer space
  */
@@ -54,7 +61,18 @@
 }
 
+/**
+ * @return nonzero, if buffer is not empty.
+ */
+int key_buffer_empty(void)
+{
+	return (buffer_items == 0);
+}
+
+/** Push key to key buffer.
+ * If buffer is full, character is ignored.
+ * @param key code of stored key
+ */
 void key_buffer_push(char key)
 {
-	/* TODO: somebody may wait for key */
 	if (buffer_items < KBD_BUFFER_SIZE) {
 		fifo_push(buffer, key);
@@ -64,5 +82,5 @@
 
 /** Pop character from buffer.
- * @param c
+ * @param c pointer to space where to store character from buffer.
  * @return zero on empty buffer, nonzero else
  */
Index: kbd/include/key_buffer.h
===================================================================
--- kbd/include/key_buffer.h	(revision 250717cc879c7f068fa71fc6aab936263ef42849)
+++ kbd/include/key_buffer.h	(revision ec153a05a58461d65a28c1f1bec1a537ed89ad7e)
@@ -35,4 +35,5 @@
 void key_buffer_init(void);
 int key_buffer_available(void);
+int key_buffer_empty(void);
 void key_buffer_push(char key);
 int key_buffer_pop(char *c);
