Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision 306061aed98cdcf0119a9e630f19df95fd68ccc0)
+++ uspace/srv/devman/devman.c	(revision 9c0f158ec9d9a5b5e8917c8e5ed621caa6528a3f)
@@ -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 306061aed98cdcf0119a9e630f19df95fd68ccc0)
+++ uspace/srv/devman/main.c	(revision 9c0f158ec9d9a5b5e8917c8e5ed621caa6528a3f)
@@ -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/fs/fat/fat_dentry.c
===================================================================
--- uspace/srv/fs/fat/fat_dentry.c	(revision 306061aed98cdcf0119a9e630f19df95fd68ccc0)
+++ uspace/srv/fs/fat/fat_dentry.c	(revision 9c0f158ec9d9a5b5e8917c8e5ed621caa6528a3f)
@@ -42,5 +42,5 @@
 static bool is_d_char(const char ch)
 {
-	if (isalnum(ch) || ch == '_')
+	if (isalnum(ch) || ch == '_' || ch == '-')
 		return true;
 	else
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision 306061aed98cdcf0119a9e630f19df95fd68ccc0)
+++ uspace/srv/hid/console/console.c	(revision 9c0f158ec9d9a5b5e8917c8e5ed621caa6528a3f)
@@ -41,4 +41,5 @@
 #include <ipc/ns.h>
 #include <errno.h>
+#include <str_error.h>
 #include <ipc/console.h>
 #include <unistd.h>
@@ -64,4 +65,6 @@
 #define NAME       "console"
 #define NAMESPACE  "term"
+/** Interval for checking for new keyboard (1/4s). */
+#define HOTPLUG_WATCH_INTERVAL (1000 * 250)
 
 /** Phone to the keyboard driver. */
@@ -317,6 +320,7 @@
 static void change_console(console_t *cons)
 {
-	if (cons == active_console)
+	if (cons == active_console) {
 		return;
+	}
 	
 	fb_pending_flush();
@@ -458,6 +462,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,49 +715,123 @@
 }
 
+static int connect_keyboard_or_mouse(const char *devname,
+    async_client_conn_t handler, const 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;
+	}
+	
+	int rc = async_connect_to_me(phone, SERVICE_CONSOLE, 0, 0, handler);
+	if (rc != EOK) {
+		printf(NAME ": " \
+		    "Failed to create callback from input device: %s.\n",
+		    str_error(rc));
+		return rc;
+	}
+	
+	printf(NAME ": found %s \"%s\".\n", devname, path);
+
+	return phone;
+}
+
+static int connect_keyboard(const char *path)
+{
+	return connect_keyboard_or_mouse("keyboard", keyboard_events, path);
+}
+
+static int connect_mouse(const char *path)
+{
+	return connect_keyboard_or_mouse("mouse", mouse_events, path);
+}
+
+struct hid_class_info {
+	char *classname;
+	int (*connection_func)(const char *);
+};
+
+/** Periodically check for new keyboards in /dev/class/.
+ *
+ * @param arg Class name.
+ * @return This function should never exit.
+ */
+static int check_new_device_fibril(void *arg)
+{
+	struct hid_class_info *dev_info = arg;
+
+	size_t index = 1;
+
+	while (true) {
+		async_usleep(HOTPLUG_WATCH_INTERVAL);
+		char *path;
+		int rc = asprintf(&path, "/dev/class/%s\\%zu",
+		    dev_info->classname, index);
+		if (rc < 0) {
+			continue;
+		}
+		rc = 0;
+		rc = dev_info->connection_func(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_devices_in_background(int (*connection_func)(const char *),
+    const char *classname)
+{
+	struct hid_class_info *dev_info = malloc(sizeof(struct hid_class_info));
+	if (dev_info == NULL) {
+		printf(NAME ": " \
+		    "out of memory, will not start hot-plug-watch fibril.\n");
+		return;
+	}
+	int rc;
+
+	rc = asprintf(&dev_info->classname, "%s", classname);
+	if (rc < 0) {
+		printf(NAME ": failed to format classname: %s.\n",
+		    str_error(rc));
+		return;
+	}
+	dev_info->connection_func = connection_func;
+
+	fid_t fid = fibril_create(check_new_device_fibril, (void *)dev_info);
+	if (!fid) {
+		printf(NAME
+		    ": failed to create hot-plug-watch fibril for %s.\n",
+		    classname);
+		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;
-	int mouse_fd = open("/dev/hid_in/mouse", O_RDONLY);
-	
-	if (mouse_fd < 0) {
-		printf(NAME ": Notice - failed opening %s\n", "/dev/hid_in/mouse");
-		goto skip_mouse;
-	}
-	
-	mouse_phone = fd_phone(mouse_fd);
+
+	mouse_phone = connect_mouse("/dev/hid_in/mouse");
 	if (mouse_phone < 0) {
-		printf(NAME ": Failed to connect to mouse device\n");
-		goto skip_mouse;
-	}
-	
-	if (async_connect_to_me(mouse_phone, SERVICE_CONSOLE, 0, 0, mouse_events)
-	    != 0) {
-		printf(NAME ": Failed to create callback from mouse device\n");
-		mouse_phone = -1;
-		goto skip_mouse;
-	}
-	
-skip_mouse:
+		printf(NAME ": Failed to connect to mouse device: %s.\n",
+		    str_error(mouse_phone));
+	}
 	
 	/* Connect to framebuffer driver */
@@ -837,4 +916,8 @@
 		printf(NAME ": Error registering kconsole notifications\n");
 	
+	/* Start fibril for checking on hot-plugged keyboards. */
+	check_new_devices_in_background(connect_keyboard, "keyboard");
+	check_new_devices_in_background(connect_mouse, "mouse");
+
 	return true;
 }
@@ -856,5 +939,5 @@
 	if (!console_init(argv[1]))
 		return -1;
-	
+
 	printf(NAME ": Accepting connections\n");
 	async_manager();
Index: uspace/srv/hw/irc/apic/apic.c
===================================================================
--- uspace/srv/hw/irc/apic/apic.c	(revision 306061aed98cdcf0119a9e630f19df95fd68ccc0)
+++ uspace/srv/hw/irc/apic/apic.c	(revision 9c0f158ec9d9a5b5e8917c8e5ed621caa6528a3f)
@@ -54,4 +54,6 @@
 #define NAME  "apic"
 
+static bool apic_found = false;
+
 static int apic_enable_irq(sysarg_t irq)
 {
@@ -79,5 +81,15 @@
 		callid = async_get_call(&call);
 		
-		switch (IPC_GET_IMETHOD(call)) {
+		sysarg_t method = IPC_GET_IMETHOD(call);
+		if (method == IPC_M_PHONE_HUNGUP) {
+			return;
+		}
+
+		if (!apic_found) {
+			async_answer_0(callid, ENOTSUP);
+			break;
+		}
+
+		switch (method) {
 		case IRC_ENABLE_INTERRUPT:
 			async_answer_0(callid, apic_enable_irq(IPC_GET_ARG1(call)));
@@ -97,17 +109,15 @@
  *
  */
-static bool apic_init(void)
+static void apic_init(void)
 {
 	sysarg_t apic;
 	
-	if ((sysinfo_get_value("apic", &apic) != EOK) || (!apic)) {
-		printf(NAME ": No APIC found\n");
-		return false;
+	apic_found = sysinfo_get_value("apic", &apic) && apic;
+	if (!apic_found) {
+		printf(NAME ": Warning: no APIC found\n");
 	}
 	
 	async_set_client_connection(apic_connection);
 	service_register(SERVICE_APIC);
-	
-	return true;
 }
 
@@ -116,7 +126,6 @@
 	printf(NAME ": HelenOS APIC driver\n");
 	
-	if (!apic_init())
-		return -1;
-	
+	apic_init();
+
 	printf(NAME ": Accepting connections\n");
 	async_manager();
Index: uspace/srv/net/tl/udp/udp.c
===================================================================
--- uspace/srv/net/tl/udp/udp.c	(revision 306061aed98cdcf0119a9e630f19df95fd68ccc0)
+++ uspace/srv/net/tl/udp/udp.c	(revision 9c0f158ec9d9a5b5e8917c8e5ed621caa6528a3f)
@@ -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;
