Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision d4c472baf92535da28ffed49127c8526791c168f)
+++ uspace/lib/c/Makefile	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -76,4 +76,5 @@
 	generic/str.c \
 	generic/str_error.c \
+	generic/l18n/langs.c \
 	generic/fibril.c \
 	generic/fibril_synch.c \
Index: uspace/lib/c/generic/adt/hash_table.c
===================================================================
--- uspace/lib/c/generic/adt/hash_table.c	(revision d4c472baf92535da28ffed49127c8526791c168f)
+++ uspace/lib/c/generic/adt/hash_table.c	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -54,5 +54,5 @@
  *
  */
-int hash_table_create(hash_table_t *h, hash_count_t m, hash_count_t max_keys,
+bool hash_table_create(hash_table_t *h, hash_count_t m, hash_count_t max_keys,
     hash_table_operations_t *op)
 {
Index: uspace/lib/c/generic/as.c
===================================================================
--- uspace/lib/c/generic/as.c	(revision d4c472baf92535da28ffed49127c8526791c168f)
+++ uspace/lib/c/generic/as.c	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -35,4 +35,5 @@
 #include <as.h>
 #include <libc.h>
+#include <errno.h>
 #include <unistd.h>
 #include <align.h>
@@ -114,4 +115,30 @@
 }
 
+/** Find mapping to physical address.
+ *
+ * @param address Virtual address in question (virtual).
+ * @param[out] frame Frame address (physical).
+ * @return Error code.
+ * @retval EOK No error, @p frame holds the translation.
+ * @retval ENOENT Mapping not found.
+ */
+int as_get_physical_mapping(void *address, uintptr_t *frame)
+{
+	uintptr_t tmp_frame;
+	uintptr_t virt = (uintptr_t) address;
+	
+	int rc = (int) __SYSCALL2(SYS_PAGE_FIND_MAPPING,
+	    (sysarg_t) virt, (sysarg_t) &tmp_frame);
+	if (rc != EOK) {
+		return rc;
+	}
+	
+	if (frame != NULL) {
+		*frame = tmp_frame;
+	}
+	
+	return EOK;
+}
+
 /** @}
  */
Index: uspace/lib/c/generic/async.c
===================================================================
--- uspace/lib/c/generic/async.c	(revision d4c472baf92535da28ffed49127c8526791c168f)
+++ uspace/lib/c/generic/async.c	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -1569,4 +1569,18 @@
 }
 
+/** Start IPC_M_DATA_READ using the async framework.
+ *
+ * @param phoneid Phone that will be used to contact the receiving side.
+ * @param dst Address of the beginning of the destination buffer.
+ * @param size Size of the destination buffer (in bytes).
+ * @param dataptr Storage of call data (arg 2 holds actual data size).
+ * @return Hash of the sent message or 0 on error.
+ */
+aid_t async_data_read(int phoneid, void *dst, size_t size, ipc_call_t *dataptr)
+{
+	return async_send_2(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,
+	    (sysarg_t) size, dataptr);
+}
+
 /** Wrapper for IPC_M_DATA_READ calls using the async framework.
  *
Index: uspace/lib/c/generic/devman.c
===================================================================
--- uspace/lib/c/generic/devman.c	(revision d4c472baf92535da28ffed49127c8526791c168f)
+++ uspace/lib/c/generic/devman.c	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -374,4 +374,60 @@
 }
 
+int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
+{
+	int phone = devman_get_phone(DEVMAN_CLIENT, 0);
+
+	if (phone < 0)
+		return phone;
+
+	async_serialize_start();
+
+	ipc_call_t answer;
+	aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_DEVICE_PATH,
+	    handle, &answer);
+
+	ipc_call_t data_request_call;
+	aid_t data_request = async_data_read(phone, path, path_size,
+	    &data_request_call);
+	if (data_request == 0) {
+		async_wait_for(req, NULL);
+		async_serialize_end();
+		return ENOMEM;
+	}
+
+	sysarg_t data_request_rc;
+	sysarg_t opening_request_rc;
+	async_wait_for(data_request, &data_request_rc);
+	async_wait_for(req, &opening_request_rc);
+
+	async_serialize_end();
+
+	if (data_request_rc != EOK) {
+		/* Prefer the return code of the opening request. */
+		if (opening_request_rc != EOK) {
+			return (int) opening_request_rc;
+		} else {
+			return (int) data_request_rc;
+		}
+	}
+	if (opening_request_rc != EOK) {
+		return (int) opening_request_rc;
+	}
+
+	/* To be on the safe-side. */
+	path[path_size - 1] = 0;
+
+	size_t transferred_size = IPC_GET_ARG2(data_request_call);
+
+	if (transferred_size >= path_size) {
+		return ELIMIT;
+	}
+
+	/* Terminate the string (trailing 0 not send over IPC). */
+	path[transferred_size] = 0;
+
+	return EOK;
+}
+
 
 /** @}
Index: uspace/lib/c/generic/l18n/langs.c
===================================================================
--- uspace/lib/c/generic/l18n/langs.c	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
+++ uspace/lib/c/generic/l18n/langs.c	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2011 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ * Language and locale ids.
+ */
+
+#include <l18n/langs.h>
+#include <stdio.h>
+#include <fibril.h>
+
+#define UNKNOWN_LOCALE_LEN 64
+
+static fibril_local char unknown_locale[UNKNOWN_LOCALE_LEN];
+
+/** Get string representation of a given locale.
+ *
+ * @param locale The locale.
+ * @return Name of the locale.
+ */
+const char *str_l18_win_locale(l18_win_locales_t locale)
+{
+	/*
+	 * Static array with names might be better but it would be
+	 * way too big.
+	 */
+	switch (locale) {
+		case L18N_WIN_LOCALE_AFRIKAANS:
+			return "Afrikaans";
+		case L18N_WIN_LOCALE_CZECH:
+			return "Czech";
+		case L18N_WIN_LOCALE_ENGLISH_UNITED_STATES:
+			return "English (US)";
+		case L18N_WIN_LOCALE_SLOVAK:
+			return "Slovak";
+		case L18N_WIN_LOCALE_SPANISH_TRADITIONAL:
+			return "Spanish (traditional)";
+		case L18N_WIN_LOCALE_ZULU:
+			return "Zulu";
+	}
+
+	snprintf(unknown_locale, UNKNOWN_LOCALE_LEN, "Unknown locale 0x%04d",
+	    (int) locale);
+	return unknown_locale;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/str_error.c
===================================================================
--- uspace/lib/c/generic/str_error.c	(revision d4c472baf92535da28ffed49127c8526791c168f)
+++ uspace/lib/c/generic/str_error.c	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -33,4 +33,5 @@
  */
 
+#include <errno.h>
 #include <str_error.h>
 #include <stdio.h>
@@ -63,10 +64,24 @@
 static fibril_local char noerr[NOERR_LEN];
 
-const char *str_error(const int errno)
+const char *str_error(const int e)
 {
-	if ((errno <= 0) && (errno >= MIN_ERRNO))
-		return err_desc[-errno];
+	if ((e <= 0) && (e >= MIN_ERRNO))
+		return err_desc[-e];
 	
-	snprintf(noerr, NOERR_LEN, "Unkown error code %d", errno);
+	/* Ad hoc descriptions of error codes interesting for USB. */
+	switch (e) {
+		case EBADCHECKSUM:
+			return "Bad checksum";
+		case ESTALL:
+			return "Operation stalled";
+		case EAGAIN:
+			return "Resource temporarily unavailable";
+		case EEMPTY:
+			return "Resource is empty";
+		default:
+			break;
+	}
+
+	snprintf(noerr, NOERR_LEN, "Unkown error code %d", e);
 	return noerr;
 }
Index: uspace/lib/c/generic/time.c
===================================================================
--- uspace/lib/c/generic/time.c	(revision d4c472baf92535da28ffed49127c8526791c168f)
+++ uspace/lib/c/generic/time.c	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -207,4 +207,10 @@
 }
 
+void udelay(useconds_t time)
+{
+	(void) __SYSCALL1(SYS_THREAD_UDELAY, (sysarg_t) time);
+}
+
+
 /** Wait unconditionally for specified number of seconds
  *
Index: uspace/lib/c/include/adt/hash_table.h
===================================================================
--- uspace/lib/c/include/adt/hash_table.h	(revision d4c472baf92535da28ffed49127c8526791c168f)
+++ uspace/lib/c/include/adt/hash_table.h	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -38,4 +38,5 @@
 #include <adt/list.h>
 #include <unistd.h>
+#include <bool.h>
 
 typedef unsigned long hash_count_t;
@@ -83,5 +84,5 @@
     list_get_instance((item), type, member)
 
-extern int hash_table_create(hash_table_t *, hash_count_t, hash_count_t,
+extern bool hash_table_create(hash_table_t *, hash_count_t, hash_count_t,
     hash_table_operations_t *);
 extern void hash_table_insert(hash_table_t *, unsigned long [], link_t *);
Index: uspace/lib/c/include/as.h
===================================================================
--- uspace/lib/c/include/as.h	(revision d4c472baf92535da28ffed49127c8526791c168f)
+++ uspace/lib/c/include/as.h	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -60,4 +60,5 @@
 extern void *set_maxheapsize(size_t);
 extern void *as_get_mappable_page(size_t);
+extern int as_get_physical_mapping(void *, uintptr_t *);
 
 #endif
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision d4c472baf92535da28ffed49127c8526791c168f)
+++ uspace/lib/c/include/async.h	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -340,4 +340,5 @@
 	    (arg4), (answer))
 
+extern aid_t async_data_read(int, void *, size_t, ipc_call_t *);
 #define async_data_read_start(p, buf, len) \
 	async_data_read_start_generic((p), (buf), (len), IPC_XF_NONE)
Index: uspace/lib/c/include/devman.h
===================================================================
--- uspace/lib/c/include/devman.h	(revision d4c472baf92535da28ffed49127c8526791c168f)
+++ uspace/lib/c/include/devman.h	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -55,4 +55,5 @@
 extern int devman_device_get_handle_by_class(const char *, const char *,
     devman_handle_t *, unsigned int);
+extern int devman_get_device_path(devman_handle_t, char *, size_t);
 
 extern int devman_add_device_to_class(devman_handle_t, const char *);
Index: uspace/lib/c/include/errno.h
===================================================================
--- uspace/lib/c/include/errno.h	(revision d4c472baf92535da28ffed49127c8526791c168f)
+++ uspace/lib/c/include/errno.h	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -56,4 +56,16 @@
 #define EMLINK        (-266)
 
+/** Bad checksum. */
+#define EBADCHECKSUM  (-300)
+
+/** USB: stalled operation. */
+#define ESTALL (-301)
+
+/** Empty resource (no data). */
+#define EEMPTY (-302)
+
+/** Negative acknowledgment. */
+#define ENAK (-303)
+
 /** An API function is called while another blocking function is in progress. */
 #define EINPROGRESS  (-10036)
Index: uspace/lib/c/include/ipc/dev_iface.h
===================================================================
--- uspace/lib/c/include/ipc/dev_iface.h	(revision d4c472baf92535da28ffed49127c8526791c168f)
+++ uspace/lib/c/include/ipc/dev_iface.h	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -37,4 +37,15 @@
 	HW_RES_DEV_IFACE = 0,
 	CHAR_DEV_IFACE,
+
+	/** Interface provided by any PCI device. */
+	PCI_DEV_IFACE,
+
+	/** Interface provided by any USB device. */
+	USB_DEV_IFACE,
+	/** Interface provided by USB host controller. */
+	USBHC_DEV_IFACE,
+	/** Interface provided by USB HID devices. */
+	USBHID_DEV_IFACE,
+
 	DEV_IFACE_MAX
 } dev_inferface_idx_t;
@@ -48,4 +59,14 @@
 	DEV_IFACE_ID(DEV_FIRST_CUSTOM_METHOD_IDX)
 
+/*
+ * The first argument is actually method (as the "real" method is used
+ * for indexing into interfaces.
+ */
+
+#define DEV_IPC_GET_ARG1(call) IPC_GET_ARG2((call))
+#define DEV_IPC_GET_ARG2(call) IPC_GET_ARG3((call))
+#define DEV_IPC_GET_ARG3(call) IPC_GET_ARG4((call))
+#define DEV_IPC_GET_ARG4(call) IPC_GET_ARG5((call))
+
 
 #endif
Index: uspace/lib/c/include/ipc/devman.h
===================================================================
--- uspace/lib/c/include/ipc/devman.h	(revision d4c472baf92535da28ffed49127c8526791c168f)
+++ uspace/lib/c/include/ipc/devman.h	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -149,5 +149,6 @@
 typedef enum {
 	DEVMAN_DEVICE_GET_HANDLE = IPC_FIRST_USER_METHOD,
-	DEVMAN_DEVICE_GET_HANDLE_BY_CLASS
+	DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
+	DEVMAN_DEVICE_GET_DEVICE_PATH
 } client_to_devman_t;
 
Index: uspace/lib/c/include/ipc/kbd.h
===================================================================
--- uspace/lib/c/include/ipc/kbd.h	(revision d4c472baf92535da28ffed49127c8526791c168f)
+++ uspace/lib/c/include/ipc/kbd.h	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -39,7 +39,8 @@
 
 #include <ipc/common.h>
+#include <ipc/dev_iface.h>
 
 typedef enum {
-	KBD_YIELD = IPC_FIRST_USER_METHOD,
+	KBD_YIELD = DEV_FIRST_CUSTOM_METHOD,
 	KBD_RECLAIM
 } kbd_request_t;
Index: uspace/lib/c/include/l18n/langs.h
===================================================================
--- uspace/lib/c/include/l18n/langs.h	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
+++ uspace/lib/c/include/l18n/langs.h	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ * Language and locale ids.
+ */
+
+#ifndef LIBC_L18N_LANGS_H_
+#define LIBC_L18N_LANGS_H_
+
+/** Windows locale IDs.
+ * Codes taken from
+ * Developing International Software For Windows 95 and Windows NT
+ * by Nadine Kano (Microsoft Press).
+ * FIXME: add missing codes.
+ */
+typedef enum {
+	L18N_WIN_LOCALE_AFRIKAANS = 0x0436,
+	/* ... */
+	L18N_WIN_LOCALE_CZECH = 0x0405,
+	/* ... */
+	L18N_WIN_LOCALE_ENGLISH_UNITED_STATES = 0x0409,
+	/* ... */
+	L18N_WIN_LOCALE_SLOVAK = 0x041B,
+	/* ... */
+	L18N_WIN_LOCALE_SPANISH_TRADITIONAL = 0x040A,
+	/* ... */
+	L18N_WIN_LOCALE_ZULU = 0x0435
+} l18_win_locales_t;
+
+const char *str_l18_win_locale(l18_win_locales_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/sys/time.h
===================================================================
--- uspace/lib/c/include/sys/time.h	(revision d4c472baf92535da28ffed49127c8526791c168f)
+++ uspace/lib/c/include/sys/time.h	(revision 8d6c1f139a0fd8ef52d018e1c68b0dcca5ec1ec9)
@@ -62,4 +62,6 @@
 extern int gettimeofday(struct timeval *tv, struct timezone *tz);
 
+extern void udelay(useconds_t);
+
 #endif
 
