Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision b927375984efc8c979a7d300d84c79a370dbd54d)
+++ uspace/srv/devman/devman.c	(revision dde2c909ae78adc75e2a57f90c8bc2db69a43bc9)
@@ -148,4 +148,12 @@
 	printf(NAME": the '%s' driver was added to the list of available "
 	    "drivers.\n", drv->name);
+
+	printf(NAME ": match ids:");
+	link_t *cur;
+	for (cur = drv->match_ids.ids.next; cur != &drv->match_ids.ids; cur = cur->next) {
+		match_id_t *match_id = list_get_instance(cur, match_id_t, link);
+		printf(" %d:%s", match_id->score, match_id->id);
+	}
+	printf("\n");
 }
 
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision b927375984efc8c979a7d300d84c79a370dbd54d)
+++ uspace/srv/devman/main.c	(revision dde2c909ae78adc75e2a57f90c8bc2db69a43bc9)
@@ -507,6 +507,7 @@
 	
 	if (driver == NULL) {
-		printf(NAME ": devman_forward error - the device is not in %" PRIun
-		    " usable state.\n", handle);
+		printf(NAME ": devman_forward error - the device %" PRIun \
+		    " (%s) is not in usable state.\n",
+		    handle, dev->pfun->pathname);
 		async_answer_0(iid, ENOENT);
 		return;
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision b927375984efc8c979a7d300d84c79a370dbd54d)
+++ uspace/srv/hid/console/console.c	(revision dde2c909ae78adc75e2a57f90c8bc2db69a43bc9)
@@ -317,6 +317,7 @@
 static void change_console(console_t *cons)
 {
-	if (cons == active_console)
+	if (cons == active_console) {
 		return;
+	}
 	
 	fb_pending_flush();
@@ -458,6 +459,7 @@
 			if (IPC_GET_ARG1(call) == 1) {
 				int newcon = gcons_mouse_btn((bool) IPC_GET_ARG2(call));
-				if (newcon != -1)
+				if (newcon != -1) {
 					change_console(&consoles[newcon]);
+				}
 			}
 			retval = 0;
@@ -710,26 +712,141 @@
 }
 
+static int connect_keyboard(char *path)
+{
+	int fd = open(path, O_RDONLY);
+	if (fd < 0) {
+		return fd;
+	}
+	
+	int phone = fd_phone(fd);
+	if (phone < 0) {
+		printf(NAME ": Failed to connect to input device\n");
+		return phone;
+	}
+	
+	/* NB: The callback connection is slotted for removal */
+	sysarg_t phonehash;
+	sysarg_t taskhash;
+	int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, SERVICE_CONSOLE,
+	    0, 0, NULL, NULL, NULL, &taskhash, &phonehash);
+	if (rc != EOK) {
+		printf(NAME ": Failed to create callback from input device\n");
+		return rc;
+	}
+	
+	async_new_connection(taskhash, phonehash, 0, NULL, keyboard_events);
+
+	printf(NAME ": we got a hit (new keyboard \"%s\").\n", path);
+
+	return phone;
+}
+
+/** Try to connect to given keyboard, bypassing provided libc routines.
+ *
+ * @param devmap_path Path to keyboard without /dev prefix.
+ * @return Phone or error code.
+ */
+static int connect_keyboard_bypass(char *devmap_path)
+{
+	int devmap_phone = async_connect_me_to_blocking(PHONE_NS,
+	    SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
+	if (devmap_phone < 0) {
+		return devmap_phone;
+	}
+	ipc_call_t answer;
+	aid_t req = async_send_2(devmap_phone, DEVMAP_DEVICE_GET_HANDLE,
+	    0, 0,  &answer);
+
+	sysarg_t retval = async_data_write_start(devmap_phone,
+	    devmap_path, str_size(devmap_path));
+	if (retval != EOK) {
+		async_wait_for(req, NULL);
+		async_hangup(devmap_phone);
+		return retval;
+	}
+
+	async_wait_for(req, &retval);
+
+	if (retval != EOK) {
+		async_hangup(devmap_phone);
+		return retval;
+	}
+
+	devmap_handle_t handle = (devmap_handle_t) IPC_GET_ARG1(answer);
+
+	async_hangup(devmap_phone);
+
+	int phone = async_connect_me_to(PHONE_NS,
+	    SERVICE_DEVMAP, DEVMAP_CONNECT_TO_DEVICE, handle);
+	if (phone < 0) {
+		return phone;
+	}
+
+	/* NB: The callback connection is slotted for removal */
+	sysarg_t phonehash;
+	sysarg_t taskhash;
+	int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, SERVICE_CONSOLE,
+	    0, 0, NULL, NULL, NULL, &taskhash, &phonehash);
+	if (rc != EOK) {
+		printf(NAME ": Failed to create callback from input device\n");
+		return rc;
+	}
+
+	async_new_connection(taskhash, phonehash, 0, NULL, keyboard_events);
+
+	printf(NAME ": we got a hit (new keyboard \"/dev/%s\").\n",
+	    devmap_path);
+
+	return phone;
+}
+
+
+static int check_new_keyboards(void *arg)
+{
+	char *class_name = (char *) arg;
+
+	int index = 1;
+
+	while (true) {
+		async_usleep(1 * 500 * 1000);
+		char *path;
+		int rc = asprintf(&path, "class/%s\\%d", class_name, index);
+		if (rc < 0) {
+			continue;
+		}
+		rc = 0;
+		rc = connect_keyboard_bypass(path);
+		if (rc > 0) {
+			/* We do not allow unplug. */
+			index++;
+		}
+
+		free(path);
+	}
+
+	return EOK;
+}
+
+
+/** Start a fibril monitoring hot-plugged keyboards.
+ */
+static void check_new_keyboards_in_background()
+{
+	fid_t fid = fibril_create(check_new_keyboards, (void *)"keyboard");
+	if (!fid) {
+		printf(NAME ": failed to create hot-plug-watch fibril.\n");
+		return;
+	}
+	fibril_add_ready(fid);
+}
+
 static bool console_init(char *input)
 {
 	/* Connect to input device */
-	int input_fd = open(input, O_RDONLY);
-	if (input_fd < 0) {
-		printf(NAME ": Failed opening %s\n", input);
+	kbd_phone = connect_keyboard(input);
+	if (kbd_phone < 0) {
 		return false;
 	}
-	
-	kbd_phone = fd_phone(input_fd);
-	if (kbd_phone < 0) {
-		printf(NAME ": Failed to connect to input device\n");
-		return false;
-	}
-	
-	/* NB: The callback connection is slotted for removal */
-	if (async_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, keyboard_events)
-	    != 0) {
-		printf(NAME ": Failed to create callback from input device\n");
-		return false;
-	}
-	
+
 	/* Connect to mouse device */
 	mouse_phone = -1;
@@ -837,4 +954,7 @@
 		printf(NAME ": Error registering kconsole notifications\n");
 	
+	/* Start fibril for checking on hot-plugged keyboards. */
+	check_new_keyboards_in_background();
+
 	return true;
 }
@@ -856,5 +976,5 @@
 	if (!console_init(argv[1]))
 		return -1;
-	
+
 	printf(NAME ": Accepting connections\n");
 	async_manager();
Index: uspace/srv/net/tl/udp/udp.c
===================================================================
--- uspace/srv/net/tl/udp/udp.c	(revision b927375984efc8c979a7d300d84c79a370dbd54d)
+++ uspace/srv/net/tl/udp/udp.c	(revision dde2c909ae78adc75e2a57f90c8bc2db69a43bc9)
@@ -740,5 +740,5 @@
 	int socket_id;
 	size_t addrlen;
-	size_t size;
+	size_t size = 0;
 	ipc_call_t answer;
 	size_t answer_count;
