Index: abi/include/syscall.h
===================================================================
--- abi/include/syscall.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ abi/include/syscall.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -92,4 +92,6 @@
 	SYS_IRQ_UNREGISTER,
 	
+	SYS_SYSINFO_GET_KEYS_SIZE,
+	SYS_SYSINFO_GET_KEYS,
 	SYS_SYSINFO_GET_VAL_TYPE,
 	SYS_SYSINFO_GET_VALUE,
Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ boot/Makefile.common	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -165,4 +165,5 @@
 	$(USPACE_PATH)/app/locinfo/locinfo \
 	$(USPACE_PATH)/app/mkfat/mkfat \
+	$(USPACE_PATH)/app/mkexfat/mkexfat \
 	$(USPACE_PATH)/app/mkmfs/mkmfs \
 	$(USPACE_PATH)/app/lsusb/lsusb \
Index: kernel/arch/amd64/include/context.h
===================================================================
--- kernel/arch/amd64/include/context.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/arch/amd64/include/context.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -38,5 +38,6 @@
 #include <typedefs.h>
 
-/* According to ABI the stack MUST be aligned on 
+/*
+ * According to ABI the stack MUST be aligned on
  * 16-byte boundary. If it is not, the va_arg calling will
  * panic sooner or later
Index: kernel/arch/arm32/include/context.h
===================================================================
--- kernel/arch/arm32/include/context.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/arch/arm32/include/context.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup arm32	
+/** @addtogroup arm32
  * @{
  */
Index: kernel/arch/ia64/include/context.h
===================================================================
--- kernel/arch/ia64/include/context.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/arch/ia64/include/context.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia64	
+/** @addtogroup ia64
  * @{
  */
@@ -47,14 +47,14 @@
  * One item is put onto the stack to support get_stack_base().
  */
-#define SP_DELTA	(0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
+#define SP_DELTA  (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
 
 /* RSE stack starts at the bottom of memory stack, hence the division by 2. */
-#define context_set(c, _pc, stack, size)								\
-	do {												\
-		(c)->pc = (uintptr_t) _pc;								\
-		(c)->bsp = ((uintptr_t) stack) + ALIGN_UP((size / 2), REGISTER_STACK_ALIGNMENT);	\
-		(c)->ar_pfs &= PFM_MASK; 								\
-		(c)->sp = ((uintptr_t) stack) + ALIGN_UP((size / 2), STACK_ALIGNMENT) - SP_DELTA;	\
-	} while (0);
+#define context_set(c, _pc, stack, size) \
+	do { \
+		(c)->pc = (uintptr_t) _pc; \
+		(c)->bsp = ((uintptr_t) stack) + ALIGN_UP((size / 2), REGISTER_STACK_ALIGNMENT); \
+		(c)->ar_pfs &= PFM_MASK; \
+		(c)->sp = ((uintptr_t) stack) + ALIGN_UP((size / 2), STACK_ALIGNMENT) - SP_DELTA; \
+	} while (0)
 
 /*
Index: kernel/arch/mips32/include/context.h
===================================================================
--- kernel/arch/mips32/include/context.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/arch/mips32/include/context.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -42,5 +42,5 @@
  * Put one item onto the stack to support get_stack_base() and align it up.
  */
-#define SP_DELTA  (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
+#define SP_DELTA  (ABI_STACK_FRAME + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
 
 #ifndef __ASM__
Index: kernel/arch/mips32/include/stack.h
===================================================================
--- kernel/arch/mips32/include/stack.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/arch/mips32/include/stack.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup mips32	
+/** @addtogroup mips32
  * @{
  */
@@ -36,6 +36,7 @@
 #define KERN_mips32_STACK_H_
 
-#define STACK_ITEM_SIZE		4
-#define STACK_ALIGNMENT		8
+#define STACK_ITEM_SIZE  4
+#define STACK_ALIGNMENT  8
+#define ABI_STACK_FRAME  32
 
 #endif
Index: kernel/arch/mips32/src/start.S
===================================================================
--- kernel/arch/mips32/src/start.S	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/arch/mips32/src/start.S	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -241,5 +241,5 @@
 	/* $a1 contains physical address of bootinfo_t */
 	jal arch_pre_main
-	nop
+	addiu $sp, -ABI_STACK_FRAME
 	
 	j main_bsp
@@ -281,6 +281,8 @@
 	
 	move $a1, $sp
+	move $a0, $k0
 	jal exc_dispatch     /* exc_dispatch(excno, register_space) */
-	move $a0, $k0
+	addiu $sp, -ABI_STACK_FRAME
+	addiu $sp, ABI_STACK_FRAME
 	
 	REGISTERS_LOAD $sp
@@ -323,4 +325,5 @@
 	sw $t0, ISTATE_OFFSET_T0($sp)  /* save the 5th argument on the stack */
 	sw $t1, ISTATE_OFFSET_T1($sp)  /* save the 6th argument on the stack */
+	
 	jal syscall_handler
 	sw $v0, ISTATE_OFFSET_V0($sp)  /* save the syscall number on the stack */
@@ -357,6 +360,8 @@
 	move $sp, $k0
 	
+	move $a0, $sp
 	jal tlb_refill
-	move $a0, $sp 
+	addiu $sp, -ABI_STACK_FRAME
+	addiu $sp, ABI_STACK_FRAME
 	
 	REGISTERS_LOAD $sp
@@ -366,11 +371,13 @@
 cache_error_handler:
 	KERNEL_STACK_TO_K0
-	sub $k0, ISTATE_SOFT_SIZE 
+	sub $k0, ISTATE_SOFT_SIZE
 	REGISTERS_STORE_AND_EXC_RESET $k0
 	sw $sp, ISTATE_OFFSET_SP($k0)
 	move $sp, $k0
 	
+	move $a0, $sp
 	jal cache_error
-	move $a0, $sp
+	addiu $sp, -ABI_STACK_FRAME
+	addiu $sp, ABI_STACK_FRAME
 	
 	REGISTERS_LOAD $sp
Index: kernel/arch/mips64/include/context.h
===================================================================
--- kernel/arch/mips64/include/context.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/arch/mips64/include/context.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -42,5 +42,5 @@
  * Put one item onto the stack to support get_stack_base() and align it up.
  */
-#define SP_DELTA  (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
+#define SP_DELTA  (ABI_STACK_FRAME + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
 
 #ifndef __ASM__
Index: kernel/arch/mips64/include/stack.h
===================================================================
--- kernel/arch/mips64/include/stack.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/arch/mips64/include/stack.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -38,4 +38,5 @@
 #define STACK_ITEM_SIZE  8
 #define STACK_ALIGNMENT  8
+#define ABI_STACK_FRAME  64
 
 #endif
Index: kernel/arch/mips64/src/start.S
===================================================================
--- kernel/arch/mips64/src/start.S	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/arch/mips64/src/start.S	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -241,5 +241,5 @@
 	/* $a1 contains physical address of bootinfo_t */
 	jal arch_pre_main
-	nop
+	addiu $sp, -ABI_STACK_FRAME
 	
 	j main_bsp
@@ -281,6 +281,8 @@
 	
 	move $a1, $sp
+	move $a0, $k0
 	jal exc_dispatch     /* exc_dispatch(excno, register_space) */
-	move $a0, $k0
+	addiu $sp, -ABI_STACK_FRAME
+	addiu $sp, ABI_STACK_FRAME
 	
 	REGISTERS_LOAD $sp
@@ -323,4 +325,5 @@
 	sw $t0, ISTATE_OFFSET_T0($sp)  /* save the 5th argument on the stack */
 	sw $t1, ISTATE_OFFSET_T1($sp)  /* save the 6th argument on the stack */
+	
 	jal syscall_handler
 	sw $v0, ISTATE_OFFSET_V0($sp)  /* save the syscall number on the stack */
@@ -357,6 +360,8 @@
 	move $sp, $k0
 	
+	move $a0, $sp
 	jal tlb_refill
-	move $a0, $sp 
+	addiu $sp, -ABI_STACK_FRAME
+	addiu $sp, ABI_STACK_FRAME
 	
 	REGISTERS_LOAD $sp
@@ -366,11 +371,13 @@
 cache_error_handler:
 	KERNEL_STACK_TO_K0
-	sub $k0, ISTATE_SOFT_SIZE 
+	sub $k0, ISTATE_SOFT_SIZE
 	REGISTERS_STORE_AND_EXC_RESET $k0
 	sw $sp, ISTATE_OFFSET_SP($k0)
 	move $sp, $k0
 	
+	move $a0, $sp
 	jal cache_error
-	move $a0, $sp
+	addiu $sp, -ABI_STACK_FRAME
+	addiu $sp, ABI_STACK_FRAME
 	
 	REGISTERS_LOAD $sp
Index: kernel/arch/ppc32/src/ppc32.c
===================================================================
--- kernel/arch/ppc32/src/ppc32.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/arch/ppc32/src/ppc32.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -173,4 +173,6 @@
 		ofw_tree_walk_by_device_type("display", display_register, NULL);
 #endif
+		/* Map OFW information into sysinfo */
+		ofw_sysinfo_map();
 		
 		/* Initialize IRQ routing */
Index: kernel/arch/sparc64/include/context.h
===================================================================
--- kernel/arch/sparc64/include/context.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/arch/sparc64/include/context.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64	
+/** @addtogroup sparc64
  * @{
  */
@@ -40,12 +40,13 @@
 #include <align.h>
 
-#define SP_DELTA	(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE)
+#define SP_DELTA  (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE)
 
-#define context_set(c, _pc, stack, size)			\
-	(c)->pc = ((uintptr_t) _pc) - 8;			\
-	(c)->sp = ((uintptr_t) stack) + ALIGN_UP((size), 	\
-		STACK_ALIGNMENT) - (STACK_BIAS + SP_DELTA);	\
-	(c)->fp = -STACK_BIAS
-	
+#define context_set(c, _pc, stack, size) \
+	do { \
+		(c)->pc = ((uintptr_t) _pc) - 8; \
+		(c)->sp = ((uintptr_t) stack) + ALIGN_UP((size), \
+		    STACK_ALIGNMENT) - (STACK_BIAS + SP_DELTA); \
+		(c)->fp = -STACK_BIAS; \
+	} while (0)
 
 /*
Index: kernel/arch/sparc64/src/sun4u/sparc64.c
===================================================================
--- kernel/arch/sparc64/src/sun4u/sparc64.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/arch/sparc64/src/sun4u/sparc64.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -94,4 +94,7 @@
 {
 	if (config.cpu_active == 1) {
+		/* Map OFW information into sysinfo */
+		ofw_sysinfo_map();
+		
 		/*
 		 * We have 2^11 different interrupt vectors.
Index: kernel/arch/sparc64/src/sun4v/sparc64.c
===================================================================
--- kernel/arch/sparc64/src/sun4v/sparc64.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/arch/sparc64/src/sun4v/sparc64.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -92,4 +92,7 @@
 {
 	if (config.cpu_active == 1) {
+		/* Map OFW information into sysinfo */
+		ofw_sysinfo_map();
+		
 		/*
 		 * We have 2^11 different interrupt vectors.
Index: kernel/genarch/include/ofw/ofw_tree.h
===================================================================
--- kernel/genarch/include/ofw/ofw_tree.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/genarch/include/ofw/ofw_tree.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -67,5 +67,5 @@
 
 extern void ofw_tree_init(ofw_tree_node_t *);
-extern void ofw_tree_print(void);
+extern void ofw_sysinfo_map(void);
 
 extern const char *ofw_tree_node_name(const ofw_tree_node_t *);
Index: kernel/genarch/src/ofw/ofw_tree.c
===================================================================
--- kernel/genarch/src/ofw/ofw_tree.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/genarch/src/ofw/ofw_tree.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -38,4 +38,5 @@
 #include <genarch/ofw/ofw_tree.h>
 #include <mm/slab.h>
+#include <sysinfo/sysinfo.h>
 #include <memstr.h>
 #include <str.h>
@@ -65,7 +66,5 @@
     const char *name)
 {
-	size_t i;
-	
-	for (i = 0; i < node->properties; i++) {
+	for (size_t i = 0; i < node->properties; i++) {
 		if (str_cmp(node->property[i].name, name) == 0)
 			return &node->property[i];
@@ -104,10 +103,8 @@
     const char *name)
 {
-	ofw_tree_node_t *cur;
-	
 	/*
 	 * Try to find the disambigued name.
 	 */
-	for (cur = node->child; cur; cur = cur->peer) {
+	for (ofw_tree_node_t *cur = node->child; cur; cur = cur->peer) {
 		if (str_cmp(cur->da_name, name) == 0)
 			return cur;
@@ -121,5 +118,5 @@
 	 * are not always fully-qualified.
 	 */
-	for (cur = node->child; cur; cur = cur->peer) {
+	for (ofw_tree_node_t *cur = node->child; cur; cur = cur->peer) {
 		if (str_cmp(ofw_tree_node_name(cur), name) == 0)
 			return cur;
@@ -141,7 +138,5 @@
     const char *dtype)
 {
-	ofw_tree_node_t *cur;
-	
-	for (cur = node->child; cur; cur = cur->peer) {
+	for (ofw_tree_node_t *cur = node->child; cur; cur = cur->peer) {
 		ofw_tree_property_t *prop =
 		    ofw_tree_getprop(cur, "device_type");
@@ -172,13 +167,11 @@
     phandle handle)
 {
-	ofw_tree_node_t *cur;
-	
-	for (cur = root; cur; cur = cur->peer) {
+	for (ofw_tree_node_t *cur = root; cur; cur = cur->peer) {
 		if (cur->node_handle == handle)
 			return cur;
 		
 		if (cur->child) {
-			ofw_tree_node_t *node
-			    = ofw_tree_find_node_by_handle(cur->child, handle);
+			ofw_tree_node_t *node =
+			    ofw_tree_find_node_by_handle(cur->child, handle);
 			if (node)
 				return node;
@@ -201,7 +194,5 @@
     const char *dtype)
 {
-	ofw_tree_node_t *cur;
-	
-	for (cur = node->peer; cur; cur = cur->peer) {
+	for (ofw_tree_node_t *cur = node->peer; cur; cur = cur->peer) {
 		ofw_tree_property_t *prop =
 		    ofw_tree_getprop(cur, "device_type");
@@ -229,9 +220,7 @@
     const char *name)
 {
-	ofw_tree_node_t *cur;
-	
-	for (cur = node->peer; cur; cur = cur->peer) {
-		ofw_tree_property_t *prop
-		    = ofw_tree_getprop(cur, "name");
+	for (ofw_tree_node_t *cur = node->peer; cur; cur = cur->peer) {
+		ofw_tree_property_t *prop =
+		    ofw_tree_getprop(cur, "name");
 		
 		if ((!prop) || (!prop->value))
@@ -259,8 +248,7 @@
 	
 	ofw_tree_node_t *node = ofw_root;
-	size_t i;
 	size_t j;
 	
-	for (i = 1; (i < str_size(path)) && (node); i = j + 1) {
+	for (size_t i = 1; (i < str_size(path)) && (node); i = j + 1) {
 		for (j = i; (j < str_size(path)) && (path[j] != '/'); j++);
 		
@@ -294,7 +282,5 @@
     const char *dtype, ofw_tree_walker_t walker, void *arg)
 {
-	ofw_tree_node_t *cur;
-	
-	for (cur = node; cur; cur = cur->peer) {
+	for (ofw_tree_node_t *cur = node; cur; cur = cur->peer) {
 		ofw_tree_property_t *prop =
 		    ofw_tree_getprop(cur, "device_type");
@@ -334,5 +320,58 @@
 }
 
-/** Print OpenFirmware device subtree rooted in a node.
+/** Get OpenFirmware node properties.
+ *
+ * @param item    Sysinfo item (unused).
+ * @param size    Size of the returned data.
+ * @param dry_run Do not get the data, just calculate the size.
+ * @param data    OpenFirmware node.
+ *
+ * @return Data containing a serialized dump of all node
+ *         properties. If the return value is not NULL, it
+ *         should be freed in the context of the sysinfo request.
+ *
+ */
+static void *ofw_sysinfo_properties(struct sysinfo_item *item, size_t *size,
+    bool dry_run, void *data)
+{
+	ofw_tree_node_t *node = (ofw_tree_node_t *) data;
+	
+	/* Compute serialized data size */
+	*size = 0;
+	for (size_t i = 0; i < node->properties; i++)
+		*size += str_size(node->property[i].name) + 1 +
+		    sizeof(node->property[i].size) + node->property[i].size;
+	
+	if (dry_run)
+		return NULL;
+	
+	void *dump = malloc(*size, FRAME_ATOMIC);
+	if (dump == NULL) {
+		*size = 0;
+		return NULL;
+	}
+	
+	/* Serialize the data */
+	size_t pos = 0;
+	for (size_t i = 0; i < node->properties; i++) {
+		/* Property name */
+		str_cpy(dump + pos, *size - pos, node->property[i].name);
+		pos += str_size(node->property[i].name) + 1;
+		
+		/* Value size */
+		memcpy(dump + pos, &node->property[i].size,
+		    sizeof(node->property[i].size));
+		pos += sizeof(node->property[i].size);
+		
+		/* Value */
+		memcpy(dump + pos, node->property[i].value,
+		    node->property[i].size);
+		pos += node->property[i].size;
+	}
+	
+	return ((void *) dump);
+}
+
+/** Map OpenFirmware device subtree rooted in a node into sysinfo.
  *
  * Child nodes are processed recursively and peer nodes are processed
@@ -343,20 +382,19 @@
  *
  */
-static void ofw_tree_node_print(ofw_tree_node_t *node, const char *path)
+static void ofw_tree_node_sysinfo(ofw_tree_node_t *node, const char *path)
 {
 	char *cur_path = (char *) malloc(PATH_MAX_LEN, 0);
-	ofw_tree_node_t *cur;
-	
-	for (cur = node; cur; cur = cur->peer) {
-		if ((cur->parent) && (path)) {
-			snprintf(cur_path, PATH_MAX_LEN, "%s/%s", path, cur->da_name);
-			printf("%s\n", cur_path);
-		} else {
-			snprintf(cur_path, PATH_MAX_LEN, "%s", cur->da_name);
-			printf("/\n");
-		}
+	
+	for (ofw_tree_node_t *cur = node; cur; cur = cur->peer) {
+		if ((cur->parent) && (path))
+			snprintf(cur_path, PATH_MAX_LEN, "%s.%s", path, cur->da_name);
+		else
+			snprintf(cur_path, PATH_MAX_LEN, "firmware.%s", cur->da_name);
+		
+		sysinfo_set_item_gen_data(cur_path, NULL, ofw_sysinfo_properties,
+		    (void *) cur);
 		
 		if (cur->child)
-			ofw_tree_node_print(cur->child, cur_path);
+			ofw_tree_node_sysinfo(cur->child, cur_path);
 	}
 	
@@ -364,8 +402,8 @@
 }
 
-/** Print the structure of the OpenFirmware device tree. */
-void ofw_tree_print(void)
-{
-	ofw_tree_node_print(ofw_root, NULL);
+/** Map the OpenFirmware device tree into sysinfo. */
+void ofw_sysinfo_map(void)
+{
+	ofw_tree_node_sysinfo(ofw_root, NULL);
 }
 
Index: kernel/generic/include/context.h
===================================================================
--- kernel/generic/include/context.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/generic/include/context.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -41,6 +41,8 @@
 
 #define context_set_generic(ctx, _pc, stack, size) \
-	(ctx)->pc = (uintptr_t) (_pc); \
-	(ctx)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA;
+	do { \
+		(ctx)->pc = (uintptr_t) (_pc); \
+		(ctx)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA; \
+	} while (0)
 
 extern int context_save_arch(context_t *ctx) __attribute__((returns_twice));
Index: kernel/generic/include/sysinfo/sysinfo.h
===================================================================
--- kernel/generic/include/sysinfo/sysinfo.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/generic/include/sysinfo/sysinfo.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2006 Jakub Vana
+ * Copyright (c) 2012 Martin Decky
  * All rights reserved.
  *
@@ -54,9 +55,26 @@
 struct sysinfo_item;
 
-/** Gerated numeric value function */
-typedef sysarg_t (*sysinfo_fn_val_t)(struct sysinfo_item *);
+/** Generated numeric value function */
+typedef sysarg_t (*sysinfo_fn_val_t)(struct sysinfo_item *, void *);
+
+/** Sysinfo generated numberic value data
+ *
+ */
+typedef struct {
+	sysinfo_fn_val_t fn;  /**< Generated value function */
+	void *data;           /**< Private data */
+} sysinfo_gen_val_data_t;
 
 /** Generated binary data function */
-typedef void *(*sysinfo_fn_data_t)(struct sysinfo_item *, size_t *, bool);
+typedef void *(*sysinfo_fn_data_t)(struct sysinfo_item *, size_t *, bool,
+    void *);
+
+/** Sysinfo generated binary data data
+ *
+ */
+typedef struct {
+	sysinfo_fn_data_t fn;  /**< Generated binary data function */
+	void *data;            /**< Private data */
+} sysinfo_gen_data_data_t;
 
 /** Sysinfo item binary data
@@ -72,8 +90,8 @@
  */
 typedef union {
-	sysarg_t val;               /**< Constant numberic value */
-	sysinfo_fn_val_t fn_val;    /**< Generated numeric value function */
-	sysinfo_fn_data_t fn_data;  /**< Generated binary data function */
-	sysinfo_data_t data;        /**< Constant binary data */
+	sysarg_t val;                      /**< Constant numberic value */
+	sysinfo_data_t data;               /**< Constant binary data */
+	sysinfo_gen_val_data_t gen_val;    /**< Generated numeric value function */
+	sysinfo_gen_data_data_t gen_data;  /**< Generated binary data function */
 } sysinfo_item_val_t;
 
@@ -95,5 +113,13 @@
 
 /** Generated subtree function */
-typedef sysinfo_return_t (*sysinfo_fn_subtree_t)(const char *, bool);
+typedef sysinfo_return_t (*sysinfo_fn_subtree_t)(const char *, bool, void *);
+
+/** Sysinfo generated subtree data
+ *
+ */
+typedef struct {
+	sysinfo_fn_subtree_t fn;  /**< Generated subtree function */
+	void *data;               /**< Private data */
+} sysinfo_gen_subtree_data_t;
 
 /** Sysinfo subtree (union)
@@ -101,6 +127,6 @@
  */
 typedef union {
-	struct sysinfo_item *table;     /**< Fixed subtree (list of subitems) */
-	sysinfo_fn_subtree_t get_data;  /**< Generated subtree function */
+	struct sysinfo_item *table;            /**< Fixed subtree (list of subitems) */
+	sysinfo_gen_subtree_data_t generator;  /**< Generated subtree */
 } sysinfo_subtree_t;
 
@@ -123,16 +149,18 @@
 extern void sysinfo_set_item_data(const char *, sysinfo_item_t **, void *,
     size_t);
-extern void sysinfo_set_item_fn_val(const char *, sysinfo_item_t **,
-    sysinfo_fn_val_t);
-extern void sysinfo_set_item_fn_data(const char *, sysinfo_item_t **,
-    sysinfo_fn_data_t);
+extern void sysinfo_set_item_gen_val(const char *, sysinfo_item_t **,
+    sysinfo_fn_val_t, void *);
+extern void sysinfo_set_item_gen_data(const char *, sysinfo_item_t **,
+    sysinfo_fn_data_t, void *);
 extern void sysinfo_set_item_undefined(const char *, sysinfo_item_t **);
 
 extern void sysinfo_set_subtree_fn(const char *, sysinfo_item_t **,
-    sysinfo_fn_subtree_t);
+    sysinfo_fn_subtree_t, void *);
 
 extern void sysinfo_init(void);
 extern void sysinfo_dump(sysinfo_item_t *);
 
+extern sysarg_t sys_sysinfo_get_keys_size(void *, size_t, void *);
+extern sysarg_t sys_sysinfo_get_keys(void *, size_t, void *, size_t, size_t *);
 extern sysarg_t sys_sysinfo_get_val_type(void *, size_t);
 extern sysarg_t sys_sysinfo_get_value(void *, size_t, void *);
Index: kernel/generic/src/main/main.c
===================================================================
--- kernel/generic/src/main/main.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/generic/src/main/main.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -221,5 +221,5 @@
 	frame_init();
 	slab_cache_init();
-	ra_init();	
+	ra_init();
 	sysinfo_init();
 	btree_init();
Index: kernel/generic/src/mm/frame.c
===================================================================
--- kernel/generic/src/mm/frame.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/generic/src/mm/frame.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -1270,5 +1270,5 @@
 /** Adjust bounds of physical memory region according to low/high memory split.
  *
- * @param low[in]	If true, the adujstment is performed to make the region
+ * @param low[in]	If true, the adjustment is performed to make the region
  *			fit in the low memory. Otherwise the adjustment is
  *			performed to make the region fit in the high memory.
@@ -1282,8 +1282,5 @@
 bool frame_adjust_zone_bounds(bool low, uintptr_t *basep, size_t *sizep)
 {
-	// FIXME: This might lead to overflow if the identity_size is too big
-	// but it is necessary if the PA identity_base > identity_size
-	const uintptr_t limit =
-	    KA2PA(config.identity_base) + config.identity_size;
+	uintptr_t limit = KA2PA(config.identity_base) + config.identity_size;
 
 	if (low) {
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/generic/src/syscall/syscall.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -184,4 +184,6 @@
 	
 	/* Sysinfo syscalls. */
+	(syshandler_t) sys_sysinfo_get_keys_size,
+	(syshandler_t) sys_sysinfo_get_keys,
 	(syshandler_t) sys_sysinfo_get_val_type,
 	(syshandler_t) sys_sysinfo_get_value,
Index: kernel/generic/src/sysinfo/stats.c
===================================================================
--- kernel/generic/src/sysinfo/stats.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/generic/src/sysinfo/stats.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -83,9 +83,10 @@
  *
  * @param item Sysinfo item (unused).
+ * @param data Unused.
  *
  * @return System uptime (in secords).
  *
  */
-static sysarg_t get_stats_uptime(struct sysinfo_item *item)
+static sysarg_t get_stats_uptime(struct sysinfo_item *item, void *data)
 {
 	/* This doesn't have to be very accurate */
@@ -98,4 +99,5 @@
  * @param size    Size of the returned data.
  * @param dry_run Do not get the data, just calculate the size.
+ * @param data    Unused.
  *
  * @return Data containing several stats_cpu_t structures.
@@ -104,5 +106,5 @@
  */
 static void *get_stats_cpus(struct sysinfo_item *item, size_t *size,
-    bool dry_run)
+    bool dry_run, void *data)
 {
 	*size = sizeof(stats_cpu_t) * config.cpu_count;
@@ -249,5 +251,5 @@
 	ASSERT(interrupts_disabled());
 	ASSERT(irq_spinlock_locked(&task->lock));
-
+	
 	stats_task->task_id = task->taskid;
 	str_cpy(stats_task->name, TASK_NAME_BUFLEN, task->name);
@@ -293,4 +295,5 @@
  * @param size    Size of the returned data.
  * @param dry_run Do not get the data, just calculate the size.
+ * @param data    Unused.
  *
  * @return Data containing several stats_task_t structures.
@@ -299,5 +302,5 @@
  */
 static void *get_stats_tasks(struct sysinfo_item *item, size_t *size,
-    bool dry_run)
+    bool dry_run, void *data)
 {
 	/* Messing with task structures, avoid deadlock */
@@ -350,5 +353,5 @@
 	ASSERT(interrupts_disabled());
 	ASSERT(irq_spinlock_locked(&thread->lock));
-
+	
 	stats_thread->thread_id = thread->tid;
 	stats_thread->task_id = thread->task->taskid;
@@ -398,4 +401,5 @@
  * @param size    Size of the returned data.
  * @param dry_run Do not get the data, just calculate the size.
+ * @param data    Unused.
  *
  * @return Data containing several stats_task_t structures.
@@ -404,5 +408,5 @@
  */
 static void *get_stats_threads(struct sysinfo_item *item, size_t *size,
-    bool dry_run)
+    bool dry_run, void *data)
 {
 	/* Messing with threads structures, avoid deadlock */
@@ -451,4 +455,5 @@
  * @param name    Task ID (string-encoded number).
  * @param dry_run Do not get the data, just calculate the size.
+ * @param data    Unused.
  *
  * @return Sysinfo return holder. The type of the returned
@@ -460,5 +465,6 @@
  *
  */
-static sysinfo_return_t get_stats_task(const char *name, bool dry_run)
+static sysinfo_return_t get_stats_task(const char *name, bool dry_run,
+    void *data)
 {
 	/* Initially no return value */
@@ -520,4 +526,5 @@
  * @param name    Thread ID (string-encoded number).
  * @param dry_run Do not get the data, just calculate the size.
+ * @param data    Unused.
  *
  * @return Sysinfo return holder. The type of the returned
@@ -529,5 +536,6 @@
  *
  */
-static sysinfo_return_t get_stats_thread(const char *name, bool dry_run)
+static sysinfo_return_t get_stats_thread(const char *name, bool dry_run,
+    void *data)
 {
 	/* Initially no return value */
@@ -586,4 +594,5 @@
  * @param size    Size of the returned data.
  * @param dry_run Do not get the data, just calculate the size.
+ * @param data    Unused.
  *
  * @return Data containing several stats_exc_t structures.
@@ -592,5 +601,5 @@
  */
 static void *get_stats_exceptions(struct sysinfo_item *item, size_t *size,
-    bool dry_run)
+    bool dry_run, void *data)
 {
 	*size = sizeof(stats_exc_t) * IVT_ITEMS;
@@ -634,4 +643,5 @@
  * @param name    Exception number (string-encoded number).
  * @param dry_run Do not get the data, just calculate the size.
+ * @param data    Unused.
  *
  * @return Sysinfo return holder. The type of the returned
@@ -643,5 +653,6 @@
  *
  */
-static sysinfo_return_t get_stats_exception(const char *name, bool dry_run)
+static sysinfo_return_t get_stats_exception(const char *name, bool dry_run,
+    void *data)
 {
 	/* Initially no return value */
@@ -705,4 +716,5 @@
  * @param size    Size of the returned data.
  * @param dry_run Do not get the data, just calculate the size.
+ * @param data    Unused.
  *
  * @return Data containing stats_physmem_t.
@@ -711,5 +723,5 @@
  */
 static void *get_stats_physmem(struct sysinfo_item *item, size_t *size,
-    bool dry_run)
+    bool dry_run, void *data)
 {
 	*size = sizeof(stats_physmem_t);
@@ -735,4 +747,5 @@
  * @param size    Size of the returned data.
  * @param dry_run Do not get the data, just calculate the size.
+ * @param data    Unused.
  *
  * @return Data several load_t values.
@@ -741,5 +754,5 @@
  */
 static void *get_stats_load(struct sysinfo_item *item, size_t *size,
-    bool dry_run)
+    bool dry_run, void *data)
 {
 	*size = sizeof(load_t) * LOAD_STEPS;
@@ -810,14 +823,14 @@
 	mutex_initialize(&load_lock, MUTEX_PASSIVE);
 	
-	sysinfo_set_item_fn_val("system.uptime", NULL, get_stats_uptime);
-	sysinfo_set_item_fn_data("system.cpus", NULL, get_stats_cpus);
-	sysinfo_set_item_fn_data("system.physmem", NULL, get_stats_physmem);
-	sysinfo_set_item_fn_data("system.load", NULL, get_stats_load);
-	sysinfo_set_item_fn_data("system.tasks", NULL, get_stats_tasks);
-	sysinfo_set_item_fn_data("system.threads", NULL, get_stats_threads);
-	sysinfo_set_item_fn_data("system.exceptions", NULL, get_stats_exceptions);
-	sysinfo_set_subtree_fn("system.tasks", NULL, get_stats_task);
-	sysinfo_set_subtree_fn("system.threads", NULL, get_stats_thread);
-	sysinfo_set_subtree_fn("system.exceptions", NULL, get_stats_exception);
+	sysinfo_set_item_gen_val("system.uptime", NULL, get_stats_uptime, NULL);
+	sysinfo_set_item_gen_data("system.cpus", NULL, get_stats_cpus, NULL);
+	sysinfo_set_item_gen_data("system.physmem", NULL, get_stats_physmem, NULL);
+	sysinfo_set_item_gen_data("system.load", NULL, get_stats_load, NULL);
+	sysinfo_set_item_gen_data("system.tasks", NULL, get_stats_tasks, NULL);
+	sysinfo_set_item_gen_data("system.threads", NULL, get_stats_threads, NULL);
+	sysinfo_set_item_gen_data("system.exceptions", NULL, get_stats_exceptions, NULL);
+	sysinfo_set_subtree_fn("system.tasks", NULL, get_stats_task, NULL);
+	sysinfo_set_subtree_fn("system.threads", NULL, get_stats_thread, NULL);
+	sysinfo_set_subtree_fn("system.exceptions", NULL, get_stats_exception, NULL);
 }
 
Index: kernel/generic/src/sysinfo/sysinfo.c
===================================================================
--- kernel/generic/src/sysinfo/sysinfo.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ kernel/generic/src/sysinfo/sysinfo.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2006 Jakub Vana
+ * Copyright (c) 2012 Martin Decky
  * All rights reserved.
  *
@@ -99,5 +100,5 @@
 	    sizeof(sysinfo_item_t), 0, sysinfo_item_constructor,
 	    sysinfo_item_destructor, SLAB_CACHE_MAGDEFERRED);
-
+	
 	mutex_initialize(&sysinfo_lock, MUTEX_ACTIVE);
 }
@@ -110,5 +111,5 @@
  * @param subtree Current sysinfo (sub)tree root item.
  * @param ret     If the return value is NULL, this argument
- *                can be either also NULL (i.e. no item was
+ *                can be set either to NULL (i.e. no item was
  *                found and no data was generated) or the
  *                original pointer is used to store the value
@@ -125,5 +126,4 @@
 {
 	ASSERT(subtree != NULL);
-	ASSERT(ret != NULL);
 	
 	sysinfo_item_t *cur = subtree;
@@ -151,9 +151,14 @@
 			case SYSINFO_SUBTREE_FUNCTION:
 				/* Get generated data */
-				**ret = cur->subtree.get_data(name + i + 1, dry_run);
+				if (ret != NULL)
+					**ret = cur->subtree.generator.fn(name + i + 1,
+					    dry_run, cur->subtree.generator.data);
+				
 				return NULL;
 			default:
 				/* Not found, no data generated */
-				*ret = NULL;
+				if (ret != NULL)
+					*ret = NULL;
+				
 				return NULL;
 			}
@@ -164,5 +169,7 @@
 	
 	/* Not found, no data generated */
-	*ret = NULL;
+	if (ret != NULL)
+		*ret = NULL;
+	
 	return NULL;
 }
@@ -352,8 +359,9 @@
  *             a new root item (NULL for global sysinfo root).
  * @param fn   Numeric value generator function.
- *
- */
-void sysinfo_set_item_fn_val(const char *name, sysinfo_item_t **root,
-    sysinfo_fn_val_t fn)
+ * @param data Private data.
+ *
+ */
+void sysinfo_set_item_gen_val(const char *name, sysinfo_item_t **root,
+    sysinfo_fn_val_t fn, void *data)
 {
 	/* Protect sysinfo tree consistency */
@@ -366,5 +374,6 @@
 	if (item != NULL) {
 		item->val_type = SYSINFO_VAL_FUNCTION_VAL;
-		item->val.fn_val = fn;
+		item->val.gen_val.fn = fn;
+		item->val.gen_val.data = data;
 	}
 	
@@ -383,8 +392,9 @@
  *             a new root item (NULL for global sysinfo root).
  * @param fn   Binary data generator function.
- *
- */
-void sysinfo_set_item_fn_data(const char *name, sysinfo_item_t **root,
-    sysinfo_fn_data_t fn)
+ * @param data Private data.
+ *
+ */
+void sysinfo_set_item_gen_data(const char *name, sysinfo_item_t **root,
+    sysinfo_fn_data_t fn, void *data)
 {
 	/* Protect sysinfo tree consistency */
@@ -397,5 +407,6 @@
 	if (item != NULL) {
 		item->val_type = SYSINFO_VAL_FUNCTION_DATA;
-		item->val.fn_data = fn;
+		item->val.gen_data.fn = fn;
+		item->val.gen_data.data = data;
 	}
 	
@@ -431,8 +442,9 @@
  *             a new root item (NULL for global sysinfo root).
  * @param fn   Subtree generator function.
+ * @param data Private data to be passed to the generator.
  *
  */
 void sysinfo_set_subtree_fn(const char *name, sysinfo_item_t **root,
-    sysinfo_fn_subtree_t fn)
+    sysinfo_fn_subtree_t fn, void *data)
 {
 	/* Protect sysinfo tree consistency */
@@ -448,5 +460,6 @@
 	if ((item != NULL) && (item->subtree_type != SYSINFO_SUBTREE_TABLE)) {
 		item->subtree_type = SYSINFO_SUBTREE_FUNCTION;
-		item->subtree.get_data = fn;
+		item->subtree.generator.fn = fn;
+		item->subtree.generator.data = data;
 	}
 	
@@ -456,12 +469,11 @@
 /** Sysinfo dump indentation helper routine
  *
- * @param depth Number of indentation characters to print.
- *
- */
-NO_TRACE static void sysinfo_indent(unsigned int depth)
-{
-	unsigned int i;
-	for (i = 0; i < depth; i++)
-		printf("  ");
+ * @param depth Number of spaces to print.
+ *
+ */
+NO_TRACE static void sysinfo_indent(size_t spaces)
+{
+	for (size_t i = 0; i < spaces; i++)
+		printf(" ");
 }
 
@@ -470,15 +482,22 @@
  * Should be called with sysinfo_lock held.
  *
- * @param root  Root item of the current (sub)tree.
- * @param depth Current depth in the sysinfo tree.
- *
- */
-NO_TRACE static void sysinfo_dump_internal(sysinfo_item_t *root, unsigned int depth)
-{
-	sysinfo_item_t *cur = root;
-	
+ * @param root   Root item of the current (sub)tree.
+ * @param spaces Current indentation level.
+ *
+ */
+NO_TRACE static void sysinfo_dump_internal(sysinfo_item_t *root, size_t spaces)
+{
 	/* Walk all siblings */
-	while (cur != NULL) {
-		sysinfo_indent(depth);
+	for (sysinfo_item_t *cur = root; cur; cur = cur->next) {
+		size_t length;
+		
+		if (spaces == 0) {
+			printf("%s", cur->name);
+			length = str_length(cur->name);
+		} else {
+			sysinfo_indent(spaces);
+			printf(".%s", cur->name);
+			length = str_length(cur->name) + 1;
+		}
 		
 		sysarg_t val;
@@ -488,24 +507,23 @@
 		switch (cur->val_type) {
 		case SYSINFO_VAL_UNDEFINED:
-			printf("+ %s\n", cur->name);
+			printf(" [undefined]\n");
 			break;
 		case SYSINFO_VAL_VAL:
-			printf("+ %s -> %" PRIun" (%#" PRIxn ")\n", cur->name,
-			    cur->val.val, cur->val.val);
+			printf(" -> %" PRIun" (%#" PRIxn ")\n", cur->val.val,
+			    cur->val.val);
 			break;
 		case SYSINFO_VAL_DATA:
-			printf("+ %s (%zu bytes)\n", cur->name,
-			    cur->val.data.size);
+			printf(" (%zu bytes)\n", cur->val.data.size);
 			break;
 		case SYSINFO_VAL_FUNCTION_VAL:
-			val = cur->val.fn_val(cur);
-			printf("+ %s -> %" PRIun" (%#" PRIxn ") [generated]\n",
-			    cur->name, val, val);
+			val = cur->val.gen_val.fn(cur, cur->val.gen_val.data);
+			printf(" -> %" PRIun" (%#" PRIxn ") [generated]\n", val,
+			    val);
 			break;
 		case SYSINFO_VAL_FUNCTION_DATA:
 			/* N.B.: No data was actually returned (only a dry run) */
-			(void) cur->val.fn_data(cur, &size, true);
-			printf("+ %s (%zu bytes) [generated]\n", cur->name,
-			    size);
+			(void) cur->val.gen_data.fn(cur, &size, true,
+			    cur->val.gen_data.data);
+			printf(" (%zu bytes) [generated]\n", size);
 			break;
 		default:
@@ -518,16 +536,14 @@
 			break;
 		case SYSINFO_SUBTREE_TABLE:
-			sysinfo_dump_internal(cur->subtree.table, depth + 1);
+			sysinfo_dump_internal(cur->subtree.table, spaces + length);
 			break;
 		case SYSINFO_SUBTREE_FUNCTION:
-			sysinfo_indent(depth + 1);
-			printf("+ [generated subtree]\n");
+			sysinfo_indent(spaces + length);
+			printf("<generated subtree>\n");
 			break;
 		default:
-			sysinfo_indent(depth + 1);
-			printf("+ [unknown subtree]\n");
+			sysinfo_indent(spaces + length);
+			printf("<unknown subtree>\n");
 		}
-		
-		cur = cur->next;
 	}
 }
@@ -594,9 +610,9 @@
 			break;
 		case SYSINFO_VAL_FUNCTION_VAL:
-			ret.val = item->val.fn_val(item);
+			ret.val = item->val.gen_val.fn(item, item->val.gen_val.data);
 			break;
 		case SYSINFO_VAL_FUNCTION_DATA:
-			ret.data.data = item->val.fn_data(item, &ret.data.size,
-			    dry_run);
+			ret.data.data = item->val.gen_data.fn(item, &ret.data.size,
+			    dry_run, item->val.gen_data.data);
 			break;
 		}
@@ -635,6 +651,6 @@
 	ASSERT(path);
 	
-	if ((copy_from_uspace(path, ptr, size + 1) == 0)
-	    && (path[size] == 0)) {
+	if ((copy_from_uspace(path, ptr, size + 1) == 0) &&
+	    (path[size] == 0)) {
 		/*
 		 * Prevent other functions from messing with sysinfo while we
@@ -645,6 +661,201 @@
 		mutex_unlock(&sysinfo_lock);
 	}
+	
 	free(path);
 	return ret;
+}
+
+/** Return sysinfo keys determined by name
+ *
+ * Should be called with sysinfo_lock held.
+ *
+ * @param name    Sysinfo path.
+ * @param root    Root item of the sysinfo (sub)tree.
+ *                If it is NULL then consider the global
+ *                sysinfo tree.
+ * @param dry_run Do not actually get any generated
+ *                binary data, just calculate the size.
+ *
+ * @return Item value (constant or generated).
+ *
+ */
+NO_TRACE static sysinfo_return_t sysinfo_get_keys(const char *name,
+    sysinfo_item_t **root, bool dry_run)
+{
+	if (root == NULL)
+		root = &global_root;
+	
+	sysinfo_item_t *subtree = NULL;
+	
+	if (name[0] != 0) {
+		/* Try to find the item */
+		sysinfo_item_t *item =
+		    sysinfo_find_item(name, *root, NULL, dry_run);
+		if ((item != NULL) &&
+		    (item->subtree_type == SYSINFO_SUBTREE_TABLE))
+			subtree = item->subtree.table;
+	} else
+		subtree = *root;
+	
+	sysinfo_return_t ret;
+	
+	if (subtree != NULL) {
+		/*
+		 * Calculate the size of subkeys.
+		 */
+		size_t size = 0;
+		for (sysinfo_item_t *cur = subtree; cur; cur = cur->next)
+			size += str_size(cur->name) + 1;
+		
+		if (dry_run) {
+			ret.tag = SYSINFO_VAL_DATA;
+			ret.data.data = NULL;
+			ret.data.size = size;
+		} else {
+			/* Allocate buffer for subkeys */
+			char *names = (char *) malloc(size, FRAME_ATOMIC);
+			if (names == NULL)
+				return ret;
+			
+			size_t pos = 0;
+			for (sysinfo_item_t *cur = subtree; cur; cur = cur->next) {
+				str_cpy(names + pos, size - pos, cur->name);
+				pos += str_size(cur->name) + 1;
+			}
+			
+			/* Correct return value */
+			ret.tag = SYSINFO_VAL_DATA;
+			ret.data.data = (void *) names;
+			ret.data.size = size;
+		}
+	} else {
+		/* No item in the fixed sysinfo tree */
+		ret.tag = SYSINFO_VAL_UNDEFINED;
+	}
+	
+	return ret;
+}
+
+/** Return sysinfo keys determined by name from user space
+ *
+ * The path string passed from the user space has to be properly
+ * null-terminated (the last passed character must be null).
+ *
+ * @param ptr     Sysinfo path in the user address space.
+ * @param size    Size of the path string.
+ * @param dry_run Do not actually get any generated
+ *                binary data, just calculate the size.
+ *
+ */
+NO_TRACE static sysinfo_return_t sysinfo_get_keys_uspace(void *ptr, size_t size,
+    bool dry_run)
+{
+	sysinfo_return_t ret;
+	ret.tag = SYSINFO_VAL_UNDEFINED;
+	
+	if (size > SYSINFO_MAX_PATH)
+		return ret;
+	
+	char *path = (char *) malloc(size + 1, 0);
+	ASSERT(path);
+	
+	if ((copy_from_uspace(path, ptr, size + 1) == 0) &&
+	    (path[size] == 0)) {
+		/*
+		 * Prevent other functions from messing with sysinfo while we
+		 * are reading it.
+		 */
+		mutex_lock(&sysinfo_lock);
+		ret = sysinfo_get_keys(path, NULL, dry_run);
+		mutex_unlock(&sysinfo_lock);
+	}
+	
+	free(path);
+	return ret;
+}
+
+/** Get the sysinfo keys size (syscall)
+ *
+ * The path string passed from the user space has
+ * to be properly null-terminated (the last passed
+ * character must be null).
+ *
+ * @param path_ptr  Sysinfo path in the user address space.
+ * @param path_size Size of the path string.
+ * @param size_ptr  User space pointer where to store the
+ *                  keys size.
+ *
+ * @return Error code (EOK in case of no error).
+ *
+ */
+sysarg_t sys_sysinfo_get_keys_size(void *path_ptr, size_t path_size,
+    void *size_ptr)
+{
+	int rc;
+	
+	/*
+	 * Get the keys.
+	 *
+	 * N.B.: There is no need to free any potential keys
+	 * since we request a dry run.
+	 */
+	sysinfo_return_t ret =
+	    sysinfo_get_keys_uspace(path_ptr, path_size, true);
+	
+	/* Check return data tag */
+	if (ret.tag == SYSINFO_VAL_DATA)
+		rc = copy_to_uspace(size_ptr, &ret.data.size,
+		    sizeof(ret.data.size));
+	else
+		rc = EINVAL;
+	
+	return (sysarg_t) rc;
+}
+
+/** Get the sysinfo keys (syscall)
+ *
+ * The path string passed from the user space has
+ * to be properly null-terminated (the last passed
+ * character must be null).
+ *
+ * If the user space buffer size does not equal
+ * the actual size of the returned data, the data
+ * is truncated.
+ *
+ * The actual size of data returned is stored to
+ * size_ptr.
+ *
+ * @param path_ptr    Sysinfo path in the user address space.
+ * @param path_size   Size of the path string.
+ * @param buffer_ptr  User space pointer to the buffer where
+ *                    to store the binary data.
+ * @param buffer_size User space buffer size.
+ * @param size_ptr    User space pointer where to store the
+ *                    binary data size.
+ *
+ * @return Error code (EOK in case of no error).
+ *
+ */
+sysarg_t sys_sysinfo_get_keys(void *path_ptr, size_t path_size,
+    void *buffer_ptr, size_t buffer_size, size_t *size_ptr)
+{
+	int rc;
+	
+	/* Get the keys */
+	sysinfo_return_t ret = sysinfo_get_keys_uspace(path_ptr, path_size,
+	    false);
+	
+	/* Check return data tag */
+	if (ret.tag == SYSINFO_VAL_DATA) {
+		size_t size = min(ret.data.size, buffer_size);
+		rc = copy_to_uspace(buffer_ptr, ret.data.data, size);
+		if (rc == EOK)
+			rc = copy_to_uspace(size_ptr, &size, sizeof(size));
+		
+		free(ret.data.data);
+	} else
+		rc = EINVAL;
+	
+	return (sysarg_t) rc;
 }
 
@@ -672,6 +883,6 @@
 	
 	/*
-	 * Map generated value types to constant types (user space does not care
-	 * whether the value is constant or generated).
+	 * Map generated value types to constant types (user space does
+	 * not care whether the value is constant or generated).
 	 */
 	if (ret.tag == SYSINFO_VAL_FUNCTION_VAL)
@@ -701,10 +912,10 @@
 {
 	int rc;
-
+	
 	/*
 	 * Get the item.
 	 *
-	 * N.B.: There is no need to free any potential generated binary data
-	 * since we request a dry run.
+	 * N.B.: There is no need to free any potential generated binary
+	 * data since we request a dry run.
 	 */
 	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, true);
@@ -741,6 +952,6 @@
 	 * Get the item.
 	 *
-	 * N.B.: There is no need to free any potential generated binary data
-	 * since we request a dry run.
+	 * N.B.: There is no need to free any potential generated binary
+	 * data since we request a dry run.
 	 */
 	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, true);
Index: tools/toolchain.sh
===================================================================
--- tools/toolchain.sh	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ tools/toolchain.sh	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -53,8 +53,8 @@
 EOF
 
-BINUTILS_VERSION="2.21.1"
-BINUTILS_RELEASE="a"
-GCC_VERSION="4.6.2"
-GDB_VERSION="7.3.1"
+BINUTILS_VERSION="2.22"
+BINUTILS_RELEASE=""
+GCC_VERSION="4.6.3"
+GDB_VERSION="7.4"
 
 BASEDIR="`pwd`"
@@ -274,9 +274,9 @@
 	GDB_SOURCE="ftp://ftp.gnu.org/gnu/gdb/"
 	
-	download_fetch "${BINUTILS_SOURCE}" "${BINUTILS}" "bde820eac53fa3a8d8696667418557ad"
-	download_fetch "${GCC_SOURCE}" "${GCC_CORE}" "780f614ab18c7a9066dec6387d7490b2"
-	download_fetch "${GCC_SOURCE}" "${GCC_OBJC}" "94043cc0d08394eddebed73f30ecad89"
-	download_fetch "${GCC_SOURCE}" "${GCC_CPP}" "87ecd60431e41096419dd8a10f76e46b"
-	download_fetch "${GDB_SOURCE}" "${GDB}" "b89a5fac359c618dda97b88645ceab47"
+	download_fetch "${BINUTILS_SOURCE}" "${BINUTILS}" "ee0f10756c84979622b992a4a61ea3f5"
+	download_fetch "${GCC_SOURCE}" "${GCC_CORE}" "766091220c6a14fcaa2c06dd573e3758"
+	download_fetch "${GCC_SOURCE}" "${GCC_OBJC}" "48ba23770c34b1cb468f72618b4452c5"
+	download_fetch "${GCC_SOURCE}" "${GCC_CPP}" "37515158a0fb3d0800ec41a08c05e69e"
+	download_fetch "${GDB_SOURCE}" "${GDB}" "95a9a8305fed4d30a30a6dc28ff9d060"
 }
 
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/Makefile	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -48,4 +48,5 @@
 	app/lsusb \
 	app/mkfat \
+	app/mkexfat \
 	app/mkmfs \
 	app/redir \
Index: uspace/app/mkexfat/Makefile
===================================================================
--- uspace/app/mkexfat/Makefile	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/app/mkexfat/Makefile	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2012 Maurizio Lombardi
+# 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.
+#
+
+USPACE_PREFIX = ../..
+LIBS = $(LIBBLOCK_PREFIX)/libblock.a
+EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX)
+BINARY = mkexfat
+
+SOURCES = \
+	mkexfat.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/mkexfat/exfat.h
===================================================================
--- uspace/app/mkexfat/exfat.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/app/mkexfat/exfat.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2008 Jakub Jermar
+ * Copyright (c) 2011 Oleg Romanenko
+ * 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 fs
+ * @{
+ */
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <bool.h>
+
+#define EXFAT_FILENAME_LEN	255
+#define EXFAT_NAME_PART_LEN	15
+
+#define EXFAT_TYPE_UNUSED	0x00
+#define EXFAT_TYPE_USED		0x80
+#define EXFAT_TYPE_VOLLABEL	0x83
+#define EXFAT_TYPE_BITMAP	0x81
+#define EXFAT_TYPE_UCTABLE	0x82
+#define EXFAT_TYPE_GUID		0xA0
+#define EXFAT_TYPE_FILE		0x85
+#define EXFAT_TYPE_STREAM	0xC0
+#define EXFAT_TYPE_NAME		0xC1
+
+#define EXFAT_ATTR_RDONLY	0x01
+#define EXFAT_ATTR_HIDDEN	0x02
+#define EXFAT_ATTR_SYSTEM	0x04
+#define EXFAT_ATTR_SUBDIR	0x10
+#define EXFAT_ATTR_ARCHIVE	0x20
+
+
+/* All dentry structs should have 31 byte size */
+typedef struct {
+	uint8_t 	size;
+	uint16_t 	label[11];
+	uint8_t 	_reserved[8];
+} __attribute__ ((packed)) exfat_vollabel_dentry_t;
+
+typedef struct {
+	uint8_t 	flags;
+	uint8_t 	_reserved[18];
+	uint32_t 	firstc;
+	uint64_t 	size;
+} __attribute__ ((packed)) exfat_bitmap_dentry_t;
+
+typedef struct {
+	uint8_t 	_reserved1[3];
+	uint32_t 	checksum;
+	uint8_t 	_reserved2[12];
+	uint32_t 	firstc;
+	uint64_t 	size;
+} __attribute__ ((packed)) exfat_uctable_dentry_t;
+
+typedef struct {
+	uint8_t 	count; /* Always zero */ 
+	uint16_t 	checksum;
+	uint16_t 	flags;
+	uint8_t 	guid[16];
+	uint8_t 	_reserved[10];
+} __attribute__ ((packed)) exfat_guid_dentry_t;
+
+typedef struct {
+	uint8_t 	count;
+	uint16_t 	checksum;
+	uint16_t 	attr;
+	uint8_t 	_reserved1[2];
+	uint32_t 	ctime;
+	uint32_t 	mtime;
+	uint32_t 	atime;
+	uint8_t 	ctime_fine;
+	uint8_t 	mtime_fine;
+	uint8_t 	ctime_tz;
+	uint8_t 	mtime_tz;
+	uint8_t 	atime_tz;
+	uint8_t 	_reserved2[7];
+} __attribute__ ((packed)) exfat_file_dentry_t;
+
+typedef struct {
+	uint8_t 	flags;
+	uint8_t 	_reserved1[1];
+	uint8_t 	name_size;
+	uint16_t 	hash;
+	uint8_t 	_reserved2[2];
+	uint64_t 	valid_data_size;
+	uint8_t 	_reserved3[4];
+	uint32_t 	firstc;
+	uint64_t 	data_size;
+} __attribute__ ((packed)) exfat_stream_dentry_t;
+
+typedef struct {
+	uint8_t 	flags;
+	uint16_t 	name[EXFAT_NAME_PART_LEN];
+} __attribute__ ((packed)) exfat_name_dentry_t;
+
+
+typedef struct {
+	uint8_t type;
+	union {
+		exfat_vollabel_dentry_t	vollabel;
+		exfat_bitmap_dentry_t 	bitmap;
+		exfat_uctable_dentry_t 	uctable;
+		exfat_guid_dentry_t 	guid;
+		exfat_file_dentry_t 	file;
+		exfat_stream_dentry_t 	stream;
+		exfat_name_dentry_t 	name;
+	};
+} __attribute__ ((packed)) exfat_dentry_t;
+
+
+typedef enum {
+	EXFAT_DENTRY_SKIP,
+	EXFAT_DENTRY_LAST,
+	EXFAT_DENTRY_FREE,
+	EXFAT_DENTRY_VOLLABEL,
+	EXFAT_DENTRY_BITMAP,
+	EXFAT_DENTRY_UCTABLE,
+	EXFAT_DENTRY_GUID,
+	EXFAT_DENTRY_FILE,
+	EXFAT_DENTRY_STREAM,
+	EXFAT_DENTRY_NAME
+} exfat_dentry_clsf_t;
+
+
+typedef struct exfat_bs {
+	uint8_t jump[3];            /* 0x00 jmp and nop instructions */
+	uint8_t oem_name[8];        /* 0x03 "EXFAT   " */
+	uint8_t	__reserved[53];     /* 0x0B always 0 */
+	uint64_t volume_start;      /* 0x40 partition first sector */
+	uint64_t volume_count;      /* 0x48 partition sectors count */
+	uint32_t fat_sector_start;  /* 0x50 FAT first sector */
+	uint32_t fat_sector_count;  /* 0x54 FAT sectors count */
+	uint32_t data_start_sector; /* 0x58 Data region first cluster sector */
+	uint32_t data_clusters;     /* 0x5C total clusters count */
+	uint32_t rootdir_cluster;   /* 0x60 first cluster of the root dir */
+	uint32_t volume_serial;     /* 0x64 volume serial number */
+	struct {                    /* 0x68 FS version */
+		uint8_t minor;
+		uint8_t major;
+	} __attribute__ ((packed)) version;
+	uint16_t volume_flags;     /* 0x6A volume state flags */
+	uint8_t bytes_per_sector;  /* 0x6C sector size as (1 << n) */
+	uint8_t sec_per_cluster;   /* 0x6D sectors per cluster as (1 << n) */
+	uint8_t fat_count;         /* 0x6E always 1 */
+	uint8_t drive_no;          /* 0x6F always 0x80 */
+	uint8_t allocated_percent; /* 0x70 percentage of allocated space */
+	uint8_t _reserved2[7];     /* 0x71 reserved */
+	uint8_t bootcode[390];     /* Boot code */
+	uint16_t signature;        /* the value of 0xAA55 */
+} __attribute__((__packed__)) exfat_bs_t;
+
+/**
+ * @}
+ */
Index: uspace/app/mkexfat/mkexfat.c
===================================================================
--- uspace/app/mkexfat/mkexfat.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/app/mkexfat/mkexfat.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,952 @@
+/*
+ * Copyright (c) 2012 Maurizio Lombardi
+ * 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 fs
+ * @{
+ */
+
+/**
+ * @file	mkexfat.c
+ * @brief	Tool for creating new exFAT file systems.
+ *
+ */
+
+#include <stdio.h>
+#include <libblock.h>
+#include <assert.h>
+#include <errno.h>
+#include <malloc.h>
+#include <byteorder.h>
+#include <align.h>
+#include <sys/types.h>
+#include <sys/typefmt.h>
+#include <bool.h>
+#include <str.h>
+#include <getopt.h>
+#include "exfat.h"
+#include "upcase.h"
+
+#define NAME    "mkexfat"
+
+/** First sector of the FAT */
+#define FAT_SECTOR_START 128
+
+/** First sector of the Main Extended Boot Region */
+#define EBS_SECTOR_START 1
+
+/** First sector of the Main Extended Boot Region Backup */
+#define EBS_BACKUP_SECTOR_START 13
+
+/** First sector of the Main Boot Sector */
+#define MBS_SECTOR 0
+
+/** First sector of the Main Boot Sector Backup */
+#define MBS_BACKUP_SECTOR 12
+
+/** VBR Checksum sector */
+#define VBR_CHECKSUM_SECTOR 11
+
+/** VBR Backup Checksum sector */
+#define VBR_BACKUP_CHECKSUM_SECTOR 23
+
+/** Size of the Main Extended Boot Region */
+#define EBS_SIZE 8
+
+/** Divide and round up. */
+#define div_round_up(a, b) (((a) + (b) - 1) / (b))
+
+/** The default size of each cluster is 4096 byte */
+#define DEFAULT_CLUSTER_SIZE 4096
+
+/** Index of the first free cluster on the device */
+#define FIRST_FREE_CLUSTER   2
+
+#define min(x, y) ((x) < (y) ? (x) : (y))
+
+typedef struct exfat_cfg {
+	aoff64_t volume_start;
+	aoff64_t volume_count;
+	unsigned long fat_sector_count;
+	unsigned long data_start_sector;
+	unsigned long rootdir_cluster;
+	unsigned long upcase_table_cluster;
+	unsigned long bitmap_cluster;
+	unsigned long total_clusters;
+	unsigned long allocated_clusters;
+	size_t   bitmap_size;
+	size_t   sector_size;
+	size_t   cluster_size;
+} exfat_cfg_t;
+
+
+static unsigned log2(unsigned n);
+
+static uint32_t
+vbr_checksum_start(void const *octets, size_t nbytes);
+
+static void
+vbr_checksum_update(void const *octets, size_t nbytes, uint32_t *checksum);
+
+static int
+ebs_write(service_id_t service_id, exfat_cfg_t *cfg,
+    int base, uint32_t *chksum);
+
+static int
+bitmap_write(service_id_t service_id, exfat_cfg_t *cfg);
+
+static uint32_t
+upcase_table_checksum(void const *data, size_t nbytes);
+
+static struct option const long_options[] = {
+	{"help", no_argument, 0, 'h'},
+	{"cluster-size", required_argument, 0, 'c'},
+	{"fs-size", required_argument, 0, 's'},
+};
+
+static void usage(void)
+{
+	printf("Usage: mkexfat [options] <device>\n"
+	    "-c, --cluster-size ## Specify the cluster size (Kb)\n"
+	    "-s, --fs-size ##      Specify the filesystem size (sectors)\n");
+}
+
+/** Initialize the exFAT params structure.
+ *
+ * @param cfg Pointer to the exFAT params structure to initialize.
+ */
+static void
+cfg_params_initialize(exfat_cfg_t *cfg)
+{
+	unsigned long fat_bytes;
+	unsigned long fat_cls;
+	aoff64_t const volume_bytes = (cfg->volume_count - FAT_SECTOR_START) *
+	    cfg->sector_size;
+
+	if (cfg->cluster_size != 0) {
+		/* The user already choose the cluster size he wants */
+		cfg->total_clusters = volume_bytes / cfg->cluster_size;
+		goto skip_cluster_size_set;
+	}
+
+	cfg->total_clusters = volume_bytes / DEFAULT_CLUSTER_SIZE;
+	cfg->cluster_size = DEFAULT_CLUSTER_SIZE;
+
+	/* Compute the required cluster size to index
+	 * the entire storage device and to keep the FAT
+	 * size less or equal to 64 Mb.
+	 */
+	while (cfg->total_clusters > 16000000ULL &&
+	    (cfg->cluster_size < 32 * 1024 * 1024)) {
+
+		cfg->cluster_size <<= 1;
+		cfg->total_clusters = volume_bytes / cfg->cluster_size;
+	}
+
+skip_cluster_size_set:
+
+	/* Compute the FAT size in sectors */
+	fat_bytes = (cfg->total_clusters + 3) * sizeof(uint32_t);
+	cfg->fat_sector_count = div_round_up(fat_bytes, cfg->sector_size);
+
+	/* Compute the number of the first data sector */
+	cfg->data_start_sector = ROUND_UP(FAT_SECTOR_START +
+	    cfg->fat_sector_count, cfg->cluster_size / cfg->sector_size);
+
+	/* Subtract the FAT space from the total
+	 * number of available clusters.
+	 */
+	fat_cls = div_round_up((cfg->data_start_sector -
+	    FAT_SECTOR_START) * cfg->sector_size,
+	    cfg->cluster_size);
+	if (fat_cls >= cfg->total_clusters) {
+		/* Insufficient disk space on device */
+		cfg->total_clusters = 0;
+		return;
+	}
+	cfg->total_clusters -= fat_cls;
+
+	/* Compute the bitmap size */
+	cfg->bitmap_size = div_round_up(cfg->total_clusters, 8);
+
+	/* Compute the number of clusters reserved to the bitmap */
+	cfg->allocated_clusters = div_round_up(cfg->bitmap_size,
+	    cfg->cluster_size);
+
+	/* This account for the root directory */
+	cfg->allocated_clusters++;
+
+	/* Compute the number of clusters reserved to the upcase table */
+	cfg->allocated_clusters += div_round_up(sizeof(upcase_table),
+	    cfg->cluster_size);
+
+	/* Will be set later */
+	cfg->rootdir_cluster = 0;
+
+	/* Bitmap always starts at the first free cluster */
+	cfg->bitmap_cluster = FIRST_FREE_CLUSTER;
+
+	/* The first sector of the partition is zero */
+	cfg->volume_start = 0;
+}
+
+/** Prints the exFAT structure values
+ *
+ * @param cfg Pointer to the exfat_cfg_t structure.
+ */
+static void
+cfg_print_info(exfat_cfg_t *cfg)
+{
+	printf("Sector size:           %lu\n",
+	    (unsigned long) cfg->sector_size);
+	printf("Cluster size:          %lu\n",
+	    (unsigned long) cfg->cluster_size);
+	printf("FAT size in sectors:   %lu\n", cfg->fat_sector_count);
+	printf("Data start sector:     %lu\n", cfg->data_start_sector);
+	printf("Total num of clusters: %lu\n", cfg->total_clusters);
+	printf("Total used clusters:   %lu\n", cfg->allocated_clusters);
+	printf("Bitmap size:           %lu\n", (unsigned long)
+	    div_round_up(cfg->bitmap_size, cfg->cluster_size));
+	printf("Upcase table size:     %lu\n", (unsigned long)
+	    div_round_up(sizeof(upcase_table), cfg->cluster_size));
+}
+
+/** Initialize the Main Boot Sector fields.
+ *
+ * @param mbs Pointer to the Main Boot Sector structure.
+ * @param cfg Pointer to the exFAT configuration structure.
+ * @return    Initial checksum value.
+ */
+static uint32_t
+vbr_initialize(exfat_bs_t *mbs, exfat_cfg_t *cfg)
+{
+	/* Fill the structure with zeroes */
+	memset(mbs, 0, sizeof(exfat_bs_t));
+
+	/* Init Jump Boot section */
+	mbs->jump[0] = 0xEB;
+	mbs->jump[1] = 0x76;
+	mbs->jump[2] = 0x90;
+
+	/* Set the filesystem name */
+	memcpy(mbs->oem_name, "EXFAT   ", sizeof(mbs->oem_name));
+
+	mbs->volume_start = host2uint64_t_le(cfg->volume_start);
+	mbs->volume_count = host2uint64_t_le(cfg->volume_count);
+	mbs->fat_sector_start = host2uint32_t_le(FAT_SECTOR_START);
+	mbs->fat_sector_count = host2uint32_t_le(cfg->fat_sector_count);
+	mbs->data_start_sector = host2uint32_t_le(cfg->data_start_sector);
+
+	mbs->data_clusters = host2uint32_t_le(cfg->total_clusters);
+
+	mbs->rootdir_cluster = host2uint32_t_le(cfg->rootdir_cluster);
+	mbs->volume_serial = host2uint32_t_le(0xe1028172);
+	mbs->version.major = 1;
+	mbs->version.minor = 0;
+	mbs->volume_flags = host2uint16_t_le(0);
+	mbs->bytes_per_sector = log2(cfg->sector_size);
+	mbs->sec_per_cluster = log2(cfg->cluster_size / cfg->sector_size);
+
+	/* Maximum cluster size is 32 Mb */
+	assert((mbs->bytes_per_sector + mbs->sec_per_cluster) <= 25);
+
+	mbs->fat_count = 1;
+	mbs->drive_no = 0x80;
+	mbs->allocated_percent = 0;
+	mbs->signature = host2uint16_t_le(0xAA55);
+
+	return vbr_checksum_start(mbs, sizeof(exfat_bs_t));
+}
+
+static int
+bootsec_write(service_id_t service_id, exfat_cfg_t *cfg)
+{
+	exfat_bs_t mbs;
+	uint32_t vbr_checksum;
+	uint32_t *chksum_sector;
+	int rc;
+	unsigned idx;
+
+	chksum_sector = calloc(cfg->sector_size, sizeof(uint8_t));
+	if (!chksum_sector)
+		return ENOMEM;
+
+	vbr_checksum = vbr_initialize(&mbs, cfg);
+
+	/* Write the Main Boot Sector to disk */
+	rc = block_write_direct(service_id, MBS_SECTOR, 1, &mbs);
+	if (rc != EOK)
+		goto exit;
+
+	/* Write the Main extended boot sectors to disk */
+	rc = ebs_write(service_id, cfg, EBS_SECTOR_START, &vbr_checksum);
+	if (rc != EOK)
+		goto exit;
+
+	/* Write the Main Boot Sector backup to disk */
+	rc = block_write_direct(service_id, MBS_BACKUP_SECTOR, 1, &mbs);
+	if (rc != EOK)
+		goto exit;
+
+	/* Initialize the checksum sectors */
+	for (idx = 0; idx < cfg->sector_size / sizeof(uint32_t); ++idx)
+		chksum_sector[idx] = host2uint32_t_le(vbr_checksum);
+
+	/* Write the main checksum sector to disk */
+	rc = block_write_direct(service_id,
+	    VBR_CHECKSUM_SECTOR, 1, chksum_sector);
+	if (rc != EOK)
+		goto exit;
+
+	/* Write the backup checksum sector to disk */
+	rc = block_write_direct(service_id,
+	    VBR_BACKUP_CHECKSUM_SECTOR, 1, chksum_sector);
+	if (rc != EOK)
+		goto exit;
+
+	/* Write the Main extended boot sectors backup to disk */ 
+	rc = ebs_write(service_id, cfg,
+	    EBS_BACKUP_SECTOR_START, &vbr_checksum);
+
+exit:
+	free(chksum_sector);
+	return rc;
+}
+
+/** Write the Main Extended Boot Sector to disk
+ *
+ * @param service_id  The service id.
+ * @param cfg  Pointer to the exFAT configuration structure.
+ * @param base Base sector of the EBS.
+ * @return  EOK on success or a negative error code.
+ */
+static int
+ebs_write(service_id_t service_id, exfat_cfg_t *cfg, int base,
+    uint32_t *chksum)
+{
+	uint32_t *ebs = calloc(cfg->sector_size, sizeof(uint8_t));
+	int i, rc;
+
+	if (!ebs)
+		return ENOMEM;
+
+	ebs[cfg->sector_size / 4 - 1] = host2uint32_t_le(0xAA550000);
+
+	for (i = 0; i < EBS_SIZE; ++i) {
+		vbr_checksum_update(ebs, cfg->sector_size, chksum);
+
+		rc = block_write_direct(service_id,
+		    i + base, 1, ebs);
+
+		if (rc != EOK)
+			goto exit;
+	}
+
+	/* The OEM record is not yet used
+	 * by the official exFAT implementation, we'll fill
+	 * it with zeroes.
+	 */
+
+	memset(ebs, 0, cfg->sector_size);
+	vbr_checksum_update(ebs, cfg->sector_size, chksum);
+
+	rc = block_write_direct(service_id, i++ + base, 1, ebs);
+	if (rc != EOK)
+		goto exit;
+
+	/* The next sector is reserved, fill it with zeroes too */
+	vbr_checksum_update(ebs, cfg->sector_size, chksum);
+
+	rc = block_write_direct(service_id, i + base, 1, ebs);
+	if (rc != EOK)
+		goto exit;
+
+exit:
+	free(ebs);
+	return rc;
+}
+
+/** Initialize the FAT table.
+ *
+ * @param service_id  The service id.
+ * @param cfg Pointer to the exfat_cfg structure.
+ * @return EOK on success or a negative error code.
+ */
+static int
+fat_initialize(service_id_t service_id, exfat_cfg_t *cfg)
+{
+	unsigned long i;
+	uint32_t *pfat;
+	int rc;
+
+	pfat = calloc(cfg->sector_size, 1);
+	if (!pfat)
+		return ENOMEM;
+
+	pfat[0] = host2uint32_t_le(0xFFFFFFF8);
+	pfat[1] = host2uint32_t_le(0xFFFFFFFF);
+
+	rc = block_write_direct(service_id, FAT_SECTOR_START, 1, pfat);
+	if (rc != EOK)
+		goto error;
+
+	pfat[0] = pfat[1] = 0;
+
+	for (i = 1; i < cfg->fat_sector_count; ++i) {
+		rc = block_write_direct(service_id,
+		    FAT_SECTOR_START + i, 1, pfat);
+		if (rc != EOK)
+			goto error;
+	}
+
+error:
+	free(pfat);
+	return rc;
+}
+
+/** Allocate a given number of clusters and create a cluster chain.
+ *
+ * @param service_id  The service id.
+ * @param cfg  Pointer to the exfat configuration structure.
+ * @param cur_cls  Cluster index from where to start the allocation.
+ * @param ncls  Number of clusters to allocate.
+ * @return EOK on success or a negative error code.
+ */
+static int
+fat_allocate_clusters(service_id_t service_id, exfat_cfg_t *cfg,
+    uint32_t cur_cls, unsigned long ncls)
+{
+	int rc;
+	unsigned const fat_entries = cfg->sector_size / sizeof(uint32_t);
+	aoff64_t fat_sec = cur_cls / fat_entries + FAT_SECTOR_START;
+	uint32_t *fat;
+	uint32_t next_cls = cur_cls;
+
+	cur_cls %= fat_entries;
+
+	fat = malloc(cfg->sector_size);
+	if (!fat)
+		return ENOMEM;
+
+loop:
+	rc = block_read_direct(service_id, fat_sec, 1, fat);
+	if (rc != EOK)
+		goto exit;
+
+	assert(fat[cur_cls] == 0);
+	assert(ncls > 0);
+
+	for (; cur_cls < fat_entries && ncls > 1; ++cur_cls, --ncls)
+		fat[cur_cls] = host2uint32_t_le(++next_cls);
+
+	if (cur_cls == fat_entries) {
+		/* This sector is full, there are no more free entries,
+		 * commit the changes to disk and restart from the next
+		 * sector.
+		 */
+		rc = block_write_direct(service_id, fat_sec++, 1, fat);
+		if (rc != EOK)
+			goto exit;
+		cur_cls = 0;
+		goto loop;
+	} else if (ncls == 1) {
+		/* This is the last cluster of this chain, mark it
+		 * with EOF.
+		 */
+		fat[cur_cls] = host2uint32_t_le(0xFFFFFFFF);
+	}
+
+	rc = block_write_direct(service_id, fat_sec, 1, fat);
+
+exit:
+	free(fat);
+	return rc;
+}
+
+/** Initialize the allocation bitmap.
+ *
+ * @param service_id   The service id.
+ * @param cfg  Pointer to the exfat configuration structure.
+ * @return  EOK on success or a negative error code.
+ */
+static int
+bitmap_write(service_id_t service_id, exfat_cfg_t *cfg)
+{
+	unsigned long i, sec;
+	unsigned long allocated_cls;
+	int rc = EOK;
+	bool need_reset = true;
+
+	/* Bitmap size in sectors */
+	size_t const bss = div_round_up(cfg->bitmap_size, cfg->sector_size);
+
+	uint8_t *bitmap = malloc(cfg->sector_size);
+	if (!bitmap)
+		return ENOMEM;
+
+	allocated_cls = cfg->allocated_clusters;
+
+	for (sec = 0; sec < bss; ++sec) {
+		if (need_reset) {
+			need_reset = false;
+			memset(bitmap, 0, cfg->sector_size);
+		}
+		if (allocated_cls > 0) {
+			for (i = 0; i < allocated_cls; ++i) {
+				unsigned byte_idx = i / 8;
+				unsigned bit_idx = i % 8;
+
+				if (byte_idx == cfg->sector_size)
+					break;
+				bitmap[byte_idx] |= 1 << bit_idx;
+			}
+
+			allocated_cls -= i;
+			need_reset = true;
+		}
+
+		rc = block_write_direct(service_id,
+		    cfg->data_start_sector + sec, 1, bitmap);
+		if (rc != EOK)
+			goto exit;
+	}
+
+exit:
+	free(bitmap);
+	return rc;
+}
+
+/** Write the upcase table to disk. */
+static int
+upcase_table_write(service_id_t service_id, exfat_cfg_t *cfg)
+{
+	int rc = EOK;
+	aoff64_t start_sec, nsecs, i;
+	uint8_t *table_ptr;
+	uint8_t *buf;
+	size_t table_size = sizeof(upcase_table);
+
+	buf = malloc(cfg->sector_size);
+	if (!buf)
+		return ENOENT;
+
+	/* Compute the start sector of the upcase table */
+	start_sec = cfg->data_start_sector;
+	start_sec += ((cfg->upcase_table_cluster - 2) * cfg->cluster_size) /
+	    cfg->sector_size;
+
+	/* Compute the number of sectors needed to store the table on disk */
+	nsecs = div_round_up(sizeof(upcase_table), cfg->sector_size);
+	table_ptr = (uint8_t *) upcase_table;
+
+	for (i = 0; i < nsecs; ++i,
+	    table_ptr += min(table_size, cfg->sector_size),
+	    table_size -= cfg->sector_size) {
+
+		if (table_size < cfg->sector_size) {
+			/* Reset the content of the unused part
+			 * of the last sector.
+			 */
+			memset(buf, 0, cfg->sector_size);
+		}
+		memcpy(buf, table_ptr, min(table_size, cfg->sector_size));
+
+		rc = block_write_direct(service_id,
+		    start_sec + i, 1, buf);
+		if (rc != EOK)
+			goto exit;
+	}
+
+exit:
+	free(buf);
+	return rc;
+}
+
+/** Initialize and write the root directory entries to disk.
+ *
+ * @param service_id   The service id.
+ * @param cfg   Pointer to the exFAT configuration structure.
+ * @return   EOK on success or a negative error code.
+ */
+static int
+root_dentries_write(service_id_t service_id, exfat_cfg_t *cfg)
+{
+	exfat_dentry_t *d;
+	aoff64_t rootdir_sec;
+	int rc;
+	uint8_t *data;
+	unsigned long i;
+
+	data = calloc(cfg->sector_size, 1);
+	if (!data)
+		return ENOMEM;
+
+	d = (exfat_dentry_t *) data;
+
+	/* Initialize the volume label dentry */
+	d->type = EXFAT_TYPE_VOLLABEL;
+	str_to_utf16(d->vollabel.label, 8, "HELENOS ");
+	d->vollabel.size = 8;
+
+	d++;
+
+	/* Initialize the allocation bitmap dentry */
+	d->type = EXFAT_TYPE_BITMAP;
+	d->bitmap.flags = 0; /* First FAT */
+	d->bitmap.firstc = host2uint32_t_le(cfg->bitmap_cluster);
+	d->bitmap.size = host2uint64_t_le(cfg->bitmap_size);
+
+	d++;
+
+	/* Initialize the upcase table dentry */
+	d->type = EXFAT_TYPE_UCTABLE;
+	d->uctable.checksum = host2uint32_t_le(upcase_table_checksum(
+	    upcase_table, sizeof(upcase_table)));
+	d->uctable.firstc = host2uint32_t_le(cfg->upcase_table_cluster);
+	d->uctable.size = host2uint64_t_le(sizeof(upcase_table));
+
+	/* Compute the number of the sector where the rootdir resides */
+
+	rootdir_sec = cfg->data_start_sector;
+	rootdir_sec += ((cfg->rootdir_cluster - 2) * cfg->cluster_size) /
+	    cfg->sector_size;
+
+	rc = block_write_direct(service_id, rootdir_sec, 1, data);
+	if (rc != EOK)
+		goto exit;
+
+	/* Fill the content of the sectors not used by the
+	 * root directory with zeroes.
+	 */
+	memset(data, 0, cfg->sector_size);
+	for (i = 1; i < cfg->cluster_size / cfg->sector_size; ++i) {
+		rc = block_write_direct(service_id, rootdir_sec + i, 1, data);
+		if (rc != EOK)
+			goto exit;
+	}
+
+exit:
+	free(data);
+	return rc;
+}
+
+/** Given a number (n), returns the result of log2(n).
+ *
+ * It works only if n is a power of two.
+ */
+static unsigned
+log2(unsigned n)
+{
+	unsigned r;
+
+	for (r = 0;n >> r != 1; ++r);
+
+	return r;
+}
+
+/** Initialize the VBR checksum calculation */
+static uint32_t
+vbr_checksum_start(void const *data, size_t nbytes)
+{
+	uint32_t checksum = 0;
+	size_t index;
+	uint8_t const *octets = (uint8_t *) data;
+
+	for (index = 0; index < nbytes; ++index) {
+		if (index == 106 || index == 107 || index == 112) {
+			/* Skip volume_flags and allocated_percent fields */
+			continue;
+		}
+
+		checksum = ((checksum << 31) | (checksum >> 1)) +
+		    octets[index];
+	}
+
+	return checksum;
+}
+
+/** Update the VBR checksum */
+static void
+vbr_checksum_update(void const *data, size_t nbytes, uint32_t *checksum)
+{
+	size_t index;
+	uint8_t const *octets = (uint8_t *) data;
+
+	for (index = 0; index < nbytes; ++index) {
+		*checksum = ((*checksum << 31) | (*checksum >> 1)) +
+		    octets[index];
+	}
+}
+
+/** Compute the checksum of the upcase table.
+ *
+ * @param data   Pointer to the upcase table.
+ * @param nbytes size of the upcase table in bytes.
+ * @return   Checksum value.
+ */
+static uint32_t
+upcase_table_checksum(void const *data, size_t nbytes)
+{
+	size_t index;
+	uint32_t chksum = 0;
+	uint8_t const *octets = (uint8_t *) data;
+
+	for (index = 0; index < nbytes; ++index)
+		chksum = ((chksum << 31) | (chksum >> 1)) + octets[index];
+
+	return chksum;
+}
+
+/** Check if a given number is a power of two.
+ *
+ * @param n   The number to check.
+ * @return    true if n is a power of two, false otherwise.
+ */
+static bool
+is_power_of_two(unsigned long n)
+{
+	if (n == 0)
+		return false;
+
+	return (n & (n - 1)) == 0;
+}
+
+int main (int argc, char **argv)
+{
+	exfat_cfg_t cfg;
+	uint32_t next_cls;
+	char *dev_path;
+	service_id_t service_id;
+	int rc, c, opt_ind;
+	aoff64_t user_fs_size = 0;
+
+	if (argc < 2) {
+		printf(NAME ": Error, argument missing\n");
+		usage();
+		return 1;
+	}
+
+	cfg.cluster_size = 0;
+
+	for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
+		c = getopt_long(argc, argv, "hs:c:",
+		    long_options, &opt_ind);
+		switch (c) {
+		case 'h':
+			usage();
+			return 0;
+		case 's':
+			user_fs_size = (aoff64_t) strtol(optarg, NULL, 10);
+			break;
+
+		case 'c':
+			cfg.cluster_size = strtol(optarg, NULL, 10) * 1024;
+			if (cfg.cluster_size < 4096) {
+				printf(NAME ": Error, cluster size can't"
+				    " be less than 4096 byte.\n");
+				return 1;
+			} else if (cfg.cluster_size > 32 * 1024 * 1024) {
+				printf(NAME ": Error, cluster size can't"
+				    " be greater than 32 Mb");
+				return 1;
+			}
+
+			if (!is_power_of_two(cfg.cluster_size)) {
+				printf(NAME ": Error, the size of the cluster"
+				    " must be a power of two.\n");
+				return 1;
+			}
+			break;
+		}
+	}
+
+	argv += optind;
+	dev_path = *argv;
+
+	if (!dev_path) {
+		printf(NAME ": Error, you must specify a valid block"
+		    " device.\n");
+		usage();
+		return 1;
+	}
+
+	printf("Device = %s\n", dev_path);
+
+	rc = loc_service_get_id(dev_path, &service_id, 0);
+	if (rc != EOK) {
+		printf(NAME ": Error resolving device `%s'.\n", dev_path);
+		return 2;
+	}
+
+	rc = block_init(EXCHANGE_SERIALIZE, service_id, 2048);
+	if (rc != EOK) {
+		printf(NAME ": Error initializing libblock.\n");
+		return 2;
+	}
+
+	rc = block_get_bsize(service_id, &cfg.sector_size);
+	if (rc != EOK) {
+		printf(NAME ": Error determining device sector size.\n");
+		return 2;
+	}
+
+	user_fs_size *= cfg.sector_size;
+	if (user_fs_size > 0 && user_fs_size < 1024 * 1024) {
+		printf(NAME ": Error, fs size can't be less"
+		    " than 1 Mb.\n");
+		return 1;
+	}
+
+
+	if (cfg.sector_size > 4096) {
+		printf(NAME ": Error, sector size can't be greater" \
+		    " than 4096 bytes.\n");
+		return 2;
+	}
+
+	rc = block_get_nblocks(service_id, &cfg.volume_count);
+	if (rc != EOK) {
+		printf(NAME ": Warning, failed to obtain" \
+		    " block device size.\n");
+
+		if (user_fs_size == 0) {
+			printf(NAME ": You must specify the" \
+			    " filesystem size.\n");
+			return 1;
+		}
+	} else {
+		printf("Block device has %" PRIuOFF64 " blocks.\n",
+		    cfg.volume_count);
+	}
+
+	if (user_fs_size != 0) {
+		if (user_fs_size > cfg.volume_count * cfg.sector_size) {
+			printf(NAME ": Error, the device is not big enough"
+			    " to create a filesystem of"
+			    " the specified size.\n");
+			return 1;
+		}
+
+		cfg.volume_count = user_fs_size / cfg.sector_size;
+	}
+
+	cfg_params_initialize(&cfg);
+	cfg_print_info(&cfg);
+
+	if (cfg.total_clusters <= cfg.allocated_clusters + 2) {
+		printf(NAME ": Error, insufficient disk space on device.\n");
+		return 2;
+	}
+
+	printf("Writing the allocation table.\n");
+
+	/* Initialize the FAT table */
+	rc = fat_initialize(service_id, &cfg);
+	if (rc != EOK) {
+		printf(NAME ": Error, failed to write the FAT to disk\n");
+		return 2;
+	}
+
+	/* Allocate clusters for the bitmap */
+	rc = fat_allocate_clusters(service_id, &cfg, cfg.bitmap_cluster,
+	    div_round_up(cfg.bitmap_size, cfg.cluster_size));
+	if (rc != EOK) {
+		printf(NAME ": Error, failed to allocate" \
+		    " clusters for bitmap.\n");
+		return 2;
+	}
+
+	next_cls = cfg.bitmap_cluster +
+	    div_round_up(cfg.bitmap_size, cfg.cluster_size);
+	cfg.upcase_table_cluster = next_cls;
+
+	/* Allocate clusters for the upcase table */
+	rc = fat_allocate_clusters(service_id, &cfg, next_cls,
+	    div_round_up(sizeof(upcase_table), cfg.cluster_size));
+	if (rc != EOK) {
+		printf(NAME ":Error, failed to allocate clusters" \
+		    " for the upcase table.\n");
+		return 2;
+	}
+
+	next_cls += div_round_up(sizeof(upcase_table), cfg.cluster_size);
+	cfg.rootdir_cluster = next_cls;
+
+	/* Allocate a cluster for the root directory entry */
+	rc = fat_allocate_clusters(service_id, &cfg, next_cls, 1);
+	if (rc != EOK) {
+		printf(NAME ": Error, failed to allocate cluster" \
+		    " for the root dentry.\n");
+		return 2;
+	}
+
+	printf("Writing the allocation bitmap.\n");
+
+	/* Write the allocation bitmap to disk */
+	rc = bitmap_write(service_id, &cfg);
+	if (rc != EOK) {
+		printf(NAME ": Error, failed to write the allocation" \
+		    " bitmap to disk.\n");
+		return 2;
+	}
+
+	printf("Writing the upcase table.\n");
+
+	/* Write the upcase table to disk */
+	rc = upcase_table_write(service_id, &cfg);
+	if (rc != EOK) {
+		printf(NAME ": Error, failed to write the" \
+		    " upcase table to disk.\n");
+		return 2;
+	}
+
+	printf("Writing the root directory.\n");
+
+	rc = root_dentries_write(service_id, &cfg);
+	if (rc != EOK) {
+		printf(NAME ": Error, failed to write the root directory" \
+		    " entries to disk.\n");
+		return 2;
+	}
+
+	printf("Writing the boot sectors.\n");
+
+	rc = bootsec_write(service_id, &cfg);
+	if (rc != EOK) {
+		printf(NAME ": Error, failed to write the VBR to disk\n");
+		return 2;
+	}
+
+	printf("Success.\n");
+
+	return 0;
+}
+
+/**
+ * @}
+ */
+
Index: uspace/app/mkexfat/upcase.h
===================================================================
--- uspace/app/mkexfat/upcase.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/app/mkexfat/upcase.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,2964 @@
+/*
+ * Copyright (c) 2012 Maurizio Lombardi
+ * 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 fs
+ * @{
+ */
+
+#ifndef _UPCASE_H_
+#define _UPCASE_H_
+
+/** Up-case unicode table */
+static uint8_t const upcase_table[] = {
+    0x00, 0x00,
+    0x01, 0x00,
+    0x02, 0x00,
+    0x03, 0x00,
+    0x04, 0x00,
+    0x05, 0x00,
+    0x06, 0x00,
+    0x07, 0x00,
+    0x08, 0x00,
+    0x09, 0x00,
+    0x0a, 0x00,
+    0x0b, 0x00,
+    0x0c, 0x00,
+    0x0d, 0x00,
+    0x0e, 0x00,
+    0x0f, 0x00,
+    0x10, 0x00,
+    0x11, 0x00,
+    0x12, 0x00,
+    0x13, 0x00,
+    0x14, 0x00,
+    0x15, 0x00,
+    0x16, 0x00,
+    0x17, 0x00,
+    0x18, 0x00,
+    0x19, 0x00,
+    0x1a, 0x00,
+    0x1b, 0x00,
+    0x1c, 0x00,
+    0x1d, 0x00,
+    0x1e, 0x00,
+    0x1f, 0x00,
+    0x20, 0x00,
+    0x21, 0x00,
+    0x22, 0x00,
+    0x23, 0x00,
+    0x24, 0x00,
+    0x25, 0x00,
+    0x26, 0x00,
+    0x27, 0x00,
+    0x28, 0x00,
+    0x29, 0x00,
+    0x2a, 0x00,
+    0x2b, 0x00,
+    0x2c, 0x00,
+    0x2d, 0x00,
+    0x2e, 0x00,
+    0x2f, 0x00,
+    0x30, 0x00,
+    0x31, 0x00,
+    0x32, 0x00,
+    0x33, 0x00,
+    0x34, 0x00,
+    0x35, 0x00,
+    0x36, 0x00,
+    0x37, 0x00,
+    0x38, 0x00,
+    0x39, 0x00,
+    0x3a, 0x00,
+    0x3b, 0x00,
+    0x3c, 0x00,
+    0x3d, 0x00,
+    0x3e, 0x00,
+    0x3f, 0x00,
+    0x40, 0x00,
+    0x41, 0x00,
+    0x42, 0x00,
+    0x43, 0x00,
+    0x44, 0x00,
+    0x45, 0x00,
+    0x46, 0x00,
+    0x47, 0x00,
+    0x48, 0x00,
+    0x49, 0x00,
+    0x4a, 0x00,
+    0x4b, 0x00,
+    0x4c, 0x00,
+    0x4d, 0x00,
+    0x4e, 0x00,
+    0x4f, 0x00,
+    0x50, 0x00,
+    0x51, 0x00,
+    0x52, 0x00,
+    0x53, 0x00,
+    0x54, 0x00,
+    0x55, 0x00,
+    0x56, 0x00,
+    0x57, 0x00,
+    0x58, 0x00,
+    0x59, 0x00,
+    0x5a, 0x00,
+    0x5b, 0x00,
+    0x5c, 0x00,
+    0x5d, 0x00,
+    0x5e, 0x00,
+    0x5f, 0x00,
+    0x60, 0x00,
+    0x41, 0x00,
+    0x42, 0x00,
+    0x43, 0x00,
+    0x44, 0x00,
+    0x45, 0x00,
+    0x46, 0x00,
+    0x47, 0x00,
+    0x48, 0x00,
+    0x49, 0x00,
+    0x4a, 0x00,
+    0x4b, 0x00,
+    0x4c, 0x00,
+    0x4d, 0x00,
+    0x4e, 0x00,
+    0x4f, 0x00,
+    0x50, 0x00,
+    0x51, 0x00,
+    0x52, 0x00,
+    0x53, 0x00,
+    0x54, 0x00,
+    0x55, 0x00,
+    0x56, 0x00,
+    0x57, 0x00,
+    0x58, 0x00,
+    0x59, 0x00,
+    0x5a, 0x00,
+    0x7b, 0x00,
+    0x7c, 0x00,
+    0x7d, 0x00,
+    0x7e, 0x00,
+    0x7f, 0x00,
+    0x80, 0x00,
+    0x81, 0x00,
+    0x82, 0x00,
+    0x83, 0x00,
+    0x84, 0x00,
+    0x85, 0x00,
+    0x86, 0x00,
+    0x87, 0x00,
+    0x88, 0x00,
+    0x89, 0x00,
+    0x8a, 0x00,
+    0x8b, 0x00,
+    0x8c, 0x00,
+    0x8d, 0x00,
+    0x8e, 0x00,
+    0x8f, 0x00,
+    0x90, 0x00,
+    0x91, 0x00,
+    0x92, 0x00,
+    0x93, 0x00,
+    0x94, 0x00,
+    0x95, 0x00,
+    0x96, 0x00,
+    0x97, 0x00,
+    0x98, 0x00,
+    0x99, 0x00,
+    0x9a, 0x00,
+    0x9b, 0x00,
+    0x9c, 0x00,
+    0x9d, 0x00,
+    0x9e, 0x00,
+    0x9f, 0x00,
+    0xa0, 0x00,
+    0xa1, 0x00,
+    0xa2, 0x00,
+    0xa3, 0x00,
+    0xa4, 0x00,
+    0xa5, 0x00,
+    0xa6, 0x00,
+    0xa7, 0x00,
+    0xa8, 0x00,
+    0xa9, 0x00,
+    0xaa, 0x00,
+    0xab, 0x00,
+    0xac, 0x00,
+    0xad, 0x00,
+    0xae, 0x00,
+    0xaf, 0x00,
+    0xb0, 0x00,
+    0xb1, 0x00,
+    0xb2, 0x00,
+    0xb3, 0x00,
+    0xb4, 0x00,
+    0xb5, 0x00,
+    0xb6, 0x00,
+    0xb7, 0x00,
+    0xb8, 0x00,
+    0xb9, 0x00,
+    0xba, 0x00,
+    0xbb, 0x00,
+    0xbc, 0x00,
+    0xbd, 0x00,
+    0xbe, 0x00,
+    0xbf, 0x00,
+    0xc0, 0x00,
+    0xc1, 0x00,
+    0xc2, 0x00,
+    0xc3, 0x00,
+    0xc4, 0x00,
+    0xc5, 0x00,
+    0xc6, 0x00,
+    0xc7, 0x00,
+    0xc8, 0x00,
+    0xc9, 0x00,
+    0xca, 0x00,
+    0xcb, 0x00,
+    0xcc, 0x00,
+    0xcd, 0x00,
+    0xce, 0x00,
+    0xcf, 0x00,
+    0xd0, 0x00,
+    0xd1, 0x00,
+    0xd2, 0x00,
+    0xd3, 0x00,
+    0xd4, 0x00,
+    0xd5, 0x00,
+    0xd6, 0x00,
+    0xd7, 0x00,
+    0xd8, 0x00,
+    0xd9, 0x00,
+    0xda, 0x00,
+    0xdb, 0x00,
+    0xdc, 0x00,
+    0xdd, 0x00,
+    0xde, 0x00,
+    0xdf, 0x00,
+    0xc0, 0x00,
+    0xc1, 0x00,
+    0xc2, 0x00,
+    0xc3, 0x00,
+    0xc4, 0x00,
+    0xc5, 0x00,
+    0xc6, 0x00,
+    0xc7, 0x00,
+    0xc8, 0x00,
+    0xc9, 0x00,
+    0xca, 0x00,
+    0xcb, 0x00,
+    0xcc, 0x00,
+    0xcd, 0x00,
+    0xce, 0x00,
+    0xcf, 0x00,
+    0xd0, 0x00,
+    0xd1, 0x00,
+    0xd2, 0x00,
+    0xd3, 0x00,
+    0xd4, 0x00,
+    0xd5, 0x00,
+    0xd6, 0x00,
+    0xf7, 0x00,
+    0xd8, 0x00,
+    0xd9, 0x00,
+    0xda, 0x00,
+    0xdb, 0x00,
+    0xdc, 0x00,
+    0xdd, 0x00,
+    0xde, 0x00,
+    0x78, 0x01,
+    0x00, 0x01,
+    0x00, 0x01,
+    0x02, 0x01,
+    0x02, 0x01,
+    0x04, 0x01,
+    0x04, 0x01,
+    0x06, 0x01,
+    0x06, 0x01,
+    0x08, 0x01,
+    0x08, 0x01,
+    0x0a, 0x01,
+    0x0a, 0x01,
+    0x0c, 0x01,
+    0x0c, 0x01,
+    0x0e, 0x01,
+    0x0e, 0x01,
+    0x10, 0x01,
+    0x10, 0x01,
+    0x12, 0x01,
+    0x12, 0x01,
+    0x14, 0x01,
+    0x14, 0x01,
+    0x16, 0x01,
+    0x16, 0x01,
+    0x18, 0x01,
+    0x18, 0x01,
+    0x1a, 0x01,
+    0x1a, 0x01,
+    0x1c, 0x01,
+    0x1c, 0x01,
+    0x1e, 0x01,
+    0x1e, 0x01,
+    0x20, 0x01,
+    0x20, 0x01,
+    0x22, 0x01,
+    0x22, 0x01,
+    0x24, 0x01,
+    0x24, 0x01,
+    0x26, 0x01,
+    0x26, 0x01,
+    0x28, 0x01,
+    0x28, 0x01,
+    0x2a, 0x01,
+    0x2a, 0x01,
+    0x2c, 0x01,
+    0x2c, 0x01,
+    0x2e, 0x01,
+    0x2e, 0x01,
+    0x30, 0x01,
+    0x31, 0x01,
+    0x32, 0x01,
+    0x32, 0x01,
+    0x34, 0x01,
+    0x34, 0x01,
+    0x36, 0x01,
+    0x36, 0x01,
+    0x38, 0x01,
+    0x39, 0x01,
+    0x39, 0x01,
+    0x3b, 0x01,
+    0x3b, 0x01,
+    0x3d, 0x01,
+    0x3d, 0x01,
+    0x3f, 0x01,
+    0x3f, 0x01,
+    0x41, 0x01,
+    0x41, 0x01,
+    0x43, 0x01,
+    0x43, 0x01,
+    0x45, 0x01,
+    0x45, 0x01,
+    0x47, 0x01,
+    0x47, 0x01,
+    0x49, 0x01,
+    0x4a, 0x01,
+    0x4a, 0x01,
+    0x4c, 0x01,
+    0x4c, 0x01,
+    0x4e, 0x01,
+    0x4e, 0x01,
+    0x50, 0x01,
+    0x50, 0x01,
+    0x52, 0x01,
+    0x52, 0x01,
+    0x54, 0x01,
+    0x54, 0x01,
+    0x56, 0x01,
+    0x56, 0x01,
+    0x58, 0x01,
+    0x58, 0x01,
+    0x5a, 0x01,
+    0x5a, 0x01,
+    0x5c, 0x01,
+    0x5c, 0x01,
+    0x5e, 0x01,
+    0x5e, 0x01,
+    0x60, 0x01,
+    0x60, 0x01,
+    0x62, 0x01,
+    0x62, 0x01,
+    0x64, 0x01,
+    0x64, 0x01,
+    0x66, 0x01,
+    0x66, 0x01,
+    0x68, 0x01,
+    0x68, 0x01,
+    0x6a, 0x01,
+    0x6a, 0x01,
+    0x6c, 0x01,
+    0x6c, 0x01,
+    0x6e, 0x01,
+    0x6e, 0x01,
+    0x70, 0x01,
+    0x70, 0x01,
+    0x72, 0x01,
+    0x72, 0x01,
+    0x74, 0x01,
+    0x74, 0x01,
+    0x76, 0x01,
+    0x76, 0x01,
+    0x78, 0x01,
+    0x79, 0x01,
+    0x79, 0x01,
+    0x7b, 0x01,
+    0x7b, 0x01,
+    0x7d, 0x01,
+    0x7d, 0x01,
+    0x7f, 0x01,
+    0x43, 0x02,
+    0x81, 0x01,
+    0x82, 0x01,
+    0x82, 0x01,
+    0x84, 0x01,
+    0x84, 0x01,
+    0x86, 0x01,
+    0x87, 0x01,
+    0x87, 0x01,
+    0x89, 0x01,
+    0x8a, 0x01,
+    0x8b, 0x01,
+    0x8b, 0x01,
+    0x8d, 0x01,
+    0x8e, 0x01,
+    0x8f, 0x01,
+    0x90, 0x01,
+    0x91, 0x01,
+    0x91, 0x01,
+    0x93, 0x01,
+    0x94, 0x01,
+    0xf6, 0x01,
+    0x96, 0x01,
+    0x97, 0x01,
+    0x98, 0x01,
+    0x98, 0x01,
+    0x3d, 0x02,
+    0x9b, 0x01,
+    0x9c, 0x01,
+    0x9d, 0x01,
+    0x20, 0x02,
+    0x9f, 0x01,
+    0xa0, 0x01,
+    0xa0, 0x01,
+    0xa2, 0x01,
+    0xa2, 0x01,
+    0xa4, 0x01,
+    0xa4, 0x01,
+    0xa6, 0x01,
+    0xa7, 0x01,
+    0xa7, 0x01,
+    0xa9, 0x01,
+    0xaa, 0x01,
+    0xab, 0x01,
+    0xac, 0x01,
+    0xac, 0x01,
+    0xae, 0x01,
+    0xaf, 0x01,
+    0xaf, 0x01,
+    0xb1, 0x01,
+    0xb2, 0x01,
+    0xb3, 0x01,
+    0xb3, 0x01,
+    0xb5, 0x01,
+    0xb5, 0x01,
+    0xb7, 0x01,
+    0xb8, 0x01,
+    0xb8, 0x01,
+    0xba, 0x01,
+    0xbb, 0x01,
+    0xbc, 0x01,
+    0xbc, 0x01,
+    0xbe, 0x01,
+    0xf7, 0x01,
+    0xc0, 0x01,
+    0xc1, 0x01,
+    0xc2, 0x01,
+    0xc3, 0x01,
+    0xc4, 0x01,
+    0xc5, 0x01,
+    0xc4, 0x01,
+    0xc7, 0x01,
+    0xc8, 0x01,
+    0xc7, 0x01,
+    0xca, 0x01,
+    0xcb, 0x01,
+    0xca, 0x01,
+    0xcd, 0x01,
+    0xcd, 0x01,
+    0xcf, 0x01,
+    0xcf, 0x01,
+    0xd1, 0x01,
+    0xd1, 0x01,
+    0xd3, 0x01,
+    0xd3, 0x01,
+    0xd5, 0x01,
+    0xd5, 0x01,
+    0xd7, 0x01,
+    0xd7, 0x01,
+    0xd9, 0x01,
+    0xd9, 0x01,
+    0xdb, 0x01,
+    0xdb, 0x01,
+    0x8e, 0x01,
+    0xde, 0x01,
+    0xde, 0x01,
+    0xe0, 0x01,
+    0xe0, 0x01,
+    0xe2, 0x01,
+    0xe2, 0x01,
+    0xe4, 0x01,
+    0xe4, 0x01,
+    0xe6, 0x01,
+    0xe6, 0x01,
+    0xe8, 0x01,
+    0xe8, 0x01,
+    0xea, 0x01,
+    0xea, 0x01,
+    0xec, 0x01,
+    0xec, 0x01,
+    0xee, 0x01,
+    0xee, 0x01,
+    0xf0, 0x01,
+    0xf1, 0x01,
+    0xf2, 0x01,
+    0xf1, 0x01,
+    0xf4, 0x01,
+    0xf4, 0x01,
+    0xf6, 0x01,
+    0xf7, 0x01,
+    0xf8, 0x01,
+    0xf8, 0x01,
+    0xfa, 0x01,
+    0xfa, 0x01,
+    0xfc, 0x01,
+    0xfc, 0x01,
+    0xfe, 0x01,
+    0xfe, 0x01,
+    0x00, 0x02,
+    0x00, 0x02,
+    0x02, 0x02,
+    0x02, 0x02,
+    0x04, 0x02,
+    0x04, 0x02,
+    0x06, 0x02,
+    0x06, 0x02,
+    0x08, 0x02,
+    0x08, 0x02,
+    0x0a, 0x02,
+    0x0a, 0x02,
+    0x0c, 0x02,
+    0x0c, 0x02,
+    0x0e, 0x02,
+    0x0e, 0x02,
+    0x10, 0x02,
+    0x10, 0x02,
+    0x12, 0x02,
+    0x12, 0x02,
+    0x14, 0x02,
+    0x14, 0x02,
+    0x16, 0x02,
+    0x16, 0x02,
+    0x18, 0x02,
+    0x18, 0x02,
+    0x1a, 0x02,
+    0x1a, 0x02,
+    0x1c, 0x02,
+    0x1c, 0x02,
+    0x1e, 0x02,
+    0x1e, 0x02,
+    0x20, 0x02,
+    0x21, 0x02,
+    0x22, 0x02,
+    0x22, 0x02,
+    0x24, 0x02,
+    0x24, 0x02,
+    0x26, 0x02,
+    0x26, 0x02,
+    0x28, 0x02,
+    0x28, 0x02,
+    0x2a, 0x02,
+    0x2a, 0x02,
+    0x2c, 0x02,
+    0x2c, 0x02,
+    0x2e, 0x02,
+    0x2e, 0x02,
+    0x30, 0x02,
+    0x30, 0x02,
+    0x32, 0x02,
+    0x32, 0x02,
+    0x34, 0x02,
+    0x35, 0x02,
+    0x36, 0x02,
+    0x37, 0x02,
+    0x38, 0x02,
+    0x39, 0x02,
+    0x65, 0x2c,
+    0x3b, 0x02,
+    0x3b, 0x02,
+    0x3d, 0x02,
+    0x66, 0x2c,
+    0x3f, 0x02,
+    0x40, 0x02,
+    0x41, 0x02,
+    0x41, 0x02,
+    0x43, 0x02,
+    0x44, 0x02,
+    0x45, 0x02,
+    0x46, 0x02,
+    0x46, 0x02,
+    0x48, 0x02,
+    0x48, 0x02,
+    0x4a, 0x02,
+    0x4a, 0x02,
+    0x4c, 0x02,
+    0x4c, 0x02,
+    0x4e, 0x02,
+    0x4e, 0x02,
+    0x50, 0x02,
+    0x51, 0x02,
+    0x52, 0x02,
+    0x81, 0x01,
+    0x86, 0x01,
+    0x55, 0x02,
+    0x89, 0x01,
+    0x8a, 0x01,
+    0x58, 0x02,
+    0x8f, 0x01,
+    0x5a, 0x02,
+    0x90, 0x01,
+    0x5c, 0x02,
+    0x5d, 0x02,
+    0x5e, 0x02,
+    0x5f, 0x02,
+    0x93, 0x01,
+    0x61, 0x02,
+    0x62, 0x02,
+    0x94, 0x01,
+    0x64, 0x02,
+    0x65, 0x02,
+    0x66, 0x02,
+    0x67, 0x02,
+    0x97, 0x01,
+    0x96, 0x01,
+    0x6a, 0x02,
+    0x62, 0x2c,
+    0x6c, 0x02,
+    0x6d, 0x02,
+    0x6e, 0x02,
+    0x9c, 0x01,
+    0x70, 0x02,
+    0x71, 0x02,
+    0x9d, 0x01,
+    0x73, 0x02,
+    0x74, 0x02,
+    0x9f, 0x01,
+    0x76, 0x02,
+    0x77, 0x02,
+    0x78, 0x02,
+    0x79, 0x02,
+    0x7a, 0x02,
+    0x7b, 0x02,
+    0x7c, 0x02,
+    0x64, 0x2c,
+    0x7e, 0x02,
+    0x7f, 0x02,
+    0xa6, 0x01,
+    0x81, 0x02,
+    0x82, 0x02,
+    0xa9, 0x01,
+    0x84, 0x02,
+    0x85, 0x02,
+    0x86, 0x02,
+    0x87, 0x02,
+    0xae, 0x01,
+    0x44, 0x02,
+    0xb1, 0x01,
+    0xb2, 0x01,
+    0x45, 0x02,
+    0x8d, 0x02,
+    0x8e, 0x02,
+    0x8f, 0x02,
+    0x90, 0x02,
+    0x91, 0x02,
+    0xb7, 0x01,
+    0x93, 0x02,
+    0x94, 0x02,
+    0x95, 0x02,
+    0x96, 0x02,
+    0x97, 0x02,
+    0x98, 0x02,
+    0x99, 0x02,
+    0x9a, 0x02,
+    0x9b, 0x02,
+    0x9c, 0x02,
+    0x9d, 0x02,
+    0x9e, 0x02,
+    0x9f, 0x02,
+    0xa0, 0x02,
+    0xa1, 0x02,
+    0xa2, 0x02,
+    0xa3, 0x02,
+    0xa4, 0x02,
+    0xa5, 0x02,
+    0xa6, 0x02,
+    0xa7, 0x02,
+    0xa8, 0x02,
+    0xa9, 0x02,
+    0xaa, 0x02,
+    0xab, 0x02,
+    0xac, 0x02,
+    0xad, 0x02,
+    0xae, 0x02,
+    0xaf, 0x02,
+    0xb0, 0x02,
+    0xb1, 0x02,
+    0xb2, 0x02,
+    0xb3, 0x02,
+    0xb4, 0x02,
+    0xb5, 0x02,
+    0xb6, 0x02,
+    0xb7, 0x02,
+    0xb8, 0x02,
+    0xb9, 0x02,
+    0xba, 0x02,
+    0xbb, 0x02,
+    0xbc, 0x02,
+    0xbd, 0x02,
+    0xbe, 0x02,
+    0xbf, 0x02,
+    0xc0, 0x02,
+    0xc1, 0x02,
+    0xc2, 0x02,
+    0xc3, 0x02,
+    0xc4, 0x02,
+    0xc5, 0x02,
+    0xc6, 0x02,
+    0xc7, 0x02,
+    0xc8, 0x02,
+    0xc9, 0x02,
+    0xca, 0x02,
+    0xcb, 0x02,
+    0xcc, 0x02,
+    0xcd, 0x02,
+    0xce, 0x02,
+    0xcf, 0x02,
+    0xd0, 0x02,
+    0xd1, 0x02,
+    0xd2, 0x02,
+    0xd3, 0x02,
+    0xd4, 0x02,
+    0xd5, 0x02,
+    0xd6, 0x02,
+    0xd7, 0x02,
+    0xd8, 0x02,
+    0xd9, 0x02,
+    0xda, 0x02,
+    0xdb, 0x02,
+    0xdc, 0x02,
+    0xdd, 0x02,
+    0xde, 0x02,
+    0xdf, 0x02,
+    0xe0, 0x02,
+    0xe1, 0x02,
+    0xe2, 0x02,
+    0xe3, 0x02,
+    0xe4, 0x02,
+    0xe5, 0x02,
+    0xe6, 0x02,
+    0xe7, 0x02,
+    0xe8, 0x02,
+    0xe9, 0x02,
+    0xea, 0x02,
+    0xeb, 0x02,
+    0xec, 0x02,
+    0xed, 0x02,
+    0xee, 0x02,
+    0xef, 0x02,
+    0xf0, 0x02,
+    0xf1, 0x02,
+    0xf2, 0x02,
+    0xf3, 0x02,
+    0xf4, 0x02,
+    0xf5, 0x02,
+    0xf6, 0x02,
+    0xf7, 0x02,
+    0xf8, 0x02,
+    0xf9, 0x02,
+    0xfa, 0x02,
+    0xfb, 0x02,
+    0xfc, 0x02,
+    0xfd, 0x02,
+    0xfe, 0x02,
+    0xff, 0x02,
+    0x00, 0x03,
+    0x01, 0x03,
+    0x02, 0x03,
+    0x03, 0x03,
+    0x04, 0x03,
+    0x05, 0x03,
+    0x06, 0x03,
+    0x07, 0x03,
+    0x08, 0x03,
+    0x09, 0x03,
+    0x0a, 0x03,
+    0x0b, 0x03,
+    0x0c, 0x03,
+    0x0d, 0x03,
+    0x0e, 0x03,
+    0x0f, 0x03,
+    0x10, 0x03,
+    0x11, 0x03,
+    0x12, 0x03,
+    0x13, 0x03,
+    0x14, 0x03,
+    0x15, 0x03,
+    0x16, 0x03,
+    0x17, 0x03,
+    0x18, 0x03,
+    0x19, 0x03,
+    0x1a, 0x03,
+    0x1b, 0x03,
+    0x1c, 0x03,
+    0x1d, 0x03,
+    0x1e, 0x03,
+    0x1f, 0x03,
+    0x20, 0x03,
+    0x21, 0x03,
+    0x22, 0x03,
+    0x23, 0x03,
+    0x24, 0x03,
+    0x25, 0x03,
+    0x26, 0x03,
+    0x27, 0x03,
+    0x28, 0x03,
+    0x29, 0x03,
+    0x2a, 0x03,
+    0x2b, 0x03,
+    0x2c, 0x03,
+    0x2d, 0x03,
+    0x2e, 0x03,
+    0x2f, 0x03,
+    0x30, 0x03,
+    0x31, 0x03,
+    0x32, 0x03,
+    0x33, 0x03,
+    0x34, 0x03,
+    0x35, 0x03,
+    0x36, 0x03,
+    0x37, 0x03,
+    0x38, 0x03,
+    0x39, 0x03,
+    0x3a, 0x03,
+    0x3b, 0x03,
+    0x3c, 0x03,
+    0x3d, 0x03,
+    0x3e, 0x03,
+    0x3f, 0x03,
+    0x40, 0x03,
+    0x41, 0x03,
+    0x42, 0x03,
+    0x43, 0x03,
+    0x44, 0x03,
+    0x45, 0x03,
+    0x46, 0x03,
+    0x47, 0x03,
+    0x48, 0x03,
+    0x49, 0x03,
+    0x4a, 0x03,
+    0x4b, 0x03,
+    0x4c, 0x03,
+    0x4d, 0x03,
+    0x4e, 0x03,
+    0x4f, 0x03,
+    0x50, 0x03,
+    0x51, 0x03,
+    0x52, 0x03,
+    0x53, 0x03,
+    0x54, 0x03,
+    0x55, 0x03,
+    0x56, 0x03,
+    0x57, 0x03,
+    0x58, 0x03,
+    0x59, 0x03,
+    0x5a, 0x03,
+    0x5b, 0x03,
+    0x5c, 0x03,
+    0x5d, 0x03,
+    0x5e, 0x03,
+    0x5f, 0x03,
+    0x60, 0x03,
+    0x61, 0x03,
+    0x62, 0x03,
+    0x63, 0x03,
+    0x64, 0x03,
+    0x65, 0x03,
+    0x66, 0x03,
+    0x67, 0x03,
+    0x68, 0x03,
+    0x69, 0x03,
+    0x6a, 0x03,
+    0x6b, 0x03,
+    0x6c, 0x03,
+    0x6d, 0x03,
+    0x6e, 0x03,
+    0x6f, 0x03,
+    0x70, 0x03,
+    0x71, 0x03,
+    0x72, 0x03,
+    0x73, 0x03,
+    0x74, 0x03,
+    0x75, 0x03,
+    0x76, 0x03,
+    0x77, 0x03,
+    0x78, 0x03,
+    0x79, 0x03,
+    0x7a, 0x03,
+    0xfd, 0x03,
+    0xfe, 0x03,
+    0xff, 0x03,
+    0x7e, 0x03,
+    0x7f, 0x03,
+    0x80, 0x03,
+    0x81, 0x03,
+    0x82, 0x03,
+    0x83, 0x03,
+    0x84, 0x03,
+    0x85, 0x03,
+    0x86, 0x03,
+    0x87, 0x03,
+    0x88, 0x03,
+    0x89, 0x03,
+    0x8a, 0x03,
+    0x8b, 0x03,
+    0x8c, 0x03,
+    0x8d, 0x03,
+    0x8e, 0x03,
+    0x8f, 0x03,
+    0x90, 0x03,
+    0x91, 0x03,
+    0x92, 0x03,
+    0x93, 0x03,
+    0x94, 0x03,
+    0x95, 0x03,
+    0x96, 0x03,
+    0x97, 0x03,
+    0x98, 0x03,
+    0x99, 0x03,
+    0x9a, 0x03,
+    0x9b, 0x03,
+    0x9c, 0x03,
+    0x9d, 0x03,
+    0x9e, 0x03,
+    0x9f, 0x03,
+    0xa0, 0x03,
+    0xa1, 0x03,
+    0xa2, 0x03,
+    0xa3, 0x03,
+    0xa4, 0x03,
+    0xa5, 0x03,
+    0xa6, 0x03,
+    0xa7, 0x03,
+    0xa8, 0x03,
+    0xa9, 0x03,
+    0xaa, 0x03,
+    0xab, 0x03,
+    0x86, 0x03,
+    0x88, 0x03,
+    0x89, 0x03,
+    0x8a, 0x03,
+    0xb0, 0x03,
+    0x91, 0x03,
+    0x92, 0x03,
+    0x93, 0x03,
+    0x94, 0x03,
+    0x95, 0x03,
+    0x96, 0x03,
+    0x97, 0x03,
+    0x98, 0x03,
+    0x99, 0x03,
+    0x9a, 0x03,
+    0x9b, 0x03,
+    0x9c, 0x03,
+    0x9d, 0x03,
+    0x9e, 0x03,
+    0x9f, 0x03,
+    0xa0, 0x03,
+    0xa1, 0x03,
+    0xa3, 0x03,
+    0xa3, 0x03,
+    0xa4, 0x03,
+    0xa5, 0x03,
+    0xa6, 0x03,
+    0xa7, 0x03,
+    0xa8, 0x03,
+    0xa9, 0x03,
+    0xaa, 0x03,
+    0xab, 0x03,
+    0x8c, 0x03,
+    0x8e, 0x03,
+    0x8f, 0x03,
+    0xcf, 0x03,
+    0xd0, 0x03,
+    0xd1, 0x03,
+    0xd2, 0x03,
+    0xd3, 0x03,
+    0xd4, 0x03,
+    0xd5, 0x03,
+    0xd6, 0x03,
+    0xd7, 0x03,
+    0xd8, 0x03,
+    0xd8, 0x03,
+    0xda, 0x03,
+    0xda, 0x03,
+    0xdc, 0x03,
+    0xdc, 0x03,
+    0xde, 0x03,
+    0xde, 0x03,
+    0xe0, 0x03,
+    0xe0, 0x03,
+    0xe2, 0x03,
+    0xe2, 0x03,
+    0xe4, 0x03,
+    0xe4, 0x03,
+    0xe6, 0x03,
+    0xe6, 0x03,
+    0xe8, 0x03,
+    0xe8, 0x03,
+    0xea, 0x03,
+    0xea, 0x03,
+    0xec, 0x03,
+    0xec, 0x03,
+    0xee, 0x03,
+    0xee, 0x03,
+    0xf0, 0x03,
+    0xf1, 0x03,
+    0xf9, 0x03,
+    0xf3, 0x03,
+    0xf4, 0x03,
+    0xf5, 0x03,
+    0xf6, 0x03,
+    0xf7, 0x03,
+    0xf7, 0x03,
+    0xf9, 0x03,
+    0xfa, 0x03,
+    0xfa, 0x03,
+    0xfc, 0x03,
+    0xfd, 0x03,
+    0xfe, 0x03,
+    0xff, 0x03,
+    0x00, 0x04,
+    0x01, 0x04,
+    0x02, 0x04,
+    0x03, 0x04,
+    0x04, 0x04,
+    0x05, 0x04,
+    0x06, 0x04,
+    0x07, 0x04,
+    0x08, 0x04,
+    0x09, 0x04,
+    0x0a, 0x04,
+    0x0b, 0x04,
+    0x0c, 0x04,
+    0x0d, 0x04,
+    0x0e, 0x04,
+    0x0f, 0x04,
+    0x10, 0x04,
+    0x11, 0x04,
+    0x12, 0x04,
+    0x13, 0x04,
+    0x14, 0x04,
+    0x15, 0x04,
+    0x16, 0x04,
+    0x17, 0x04,
+    0x18, 0x04,
+    0x19, 0x04,
+    0x1a, 0x04,
+    0x1b, 0x04,
+    0x1c, 0x04,
+    0x1d, 0x04,
+    0x1e, 0x04,
+    0x1f, 0x04,
+    0x20, 0x04,
+    0x21, 0x04,
+    0x22, 0x04,
+    0x23, 0x04,
+    0x24, 0x04,
+    0x25, 0x04,
+    0x26, 0x04,
+    0x27, 0x04,
+    0x28, 0x04,
+    0x29, 0x04,
+    0x2a, 0x04,
+    0x2b, 0x04,
+    0x2c, 0x04,
+    0x2d, 0x04,
+    0x2e, 0x04,
+    0x2f, 0x04,
+    0x10, 0x04,
+    0x11, 0x04,
+    0x12, 0x04,
+    0x13, 0x04,
+    0x14, 0x04,
+    0x15, 0x04,
+    0x16, 0x04,
+    0x17, 0x04,
+    0x18, 0x04,
+    0x19, 0x04,
+    0x1a, 0x04,
+    0x1b, 0x04,
+    0x1c, 0x04,
+    0x1d, 0x04,
+    0x1e, 0x04,
+    0x1f, 0x04,
+    0x20, 0x04,
+    0x21, 0x04,
+    0x22, 0x04,
+    0x23, 0x04,
+    0x24, 0x04,
+    0x25, 0x04,
+    0x26, 0x04,
+    0x27, 0x04,
+    0x28, 0x04,
+    0x29, 0x04,
+    0x2a, 0x04,
+    0x2b, 0x04,
+    0x2c, 0x04,
+    0x2d, 0x04,
+    0x2e, 0x04,
+    0x2f, 0x04,
+    0x00, 0x04,
+    0x01, 0x04,
+    0x02, 0x04,
+    0x03, 0x04,
+    0x04, 0x04,
+    0x05, 0x04,
+    0x06, 0x04,
+    0x07, 0x04,
+    0x08, 0x04,
+    0x09, 0x04,
+    0x0a, 0x04,
+    0x0b, 0x04,
+    0x0c, 0x04,
+    0x0d, 0x04,
+    0x0e, 0x04,
+    0x0f, 0x04,
+    0x60, 0x04,
+    0x60, 0x04,
+    0x62, 0x04,
+    0x62, 0x04,
+    0x64, 0x04,
+    0x64, 0x04,
+    0x66, 0x04,
+    0x66, 0x04,
+    0x68, 0x04,
+    0x68, 0x04,
+    0x6a, 0x04,
+    0x6a, 0x04,
+    0x6c, 0x04,
+    0x6c, 0x04,
+    0x6e, 0x04,
+    0x6e, 0x04,
+    0x70, 0x04,
+    0x70, 0x04,
+    0x72, 0x04,
+    0x72, 0x04,
+    0x74, 0x04,
+    0x74, 0x04,
+    0x76, 0x04,
+    0x76, 0x04,
+    0x78, 0x04,
+    0x78, 0x04,
+    0x7a, 0x04,
+    0x7a, 0x04,
+    0x7c, 0x04,
+    0x7c, 0x04,
+    0x7e, 0x04,
+    0x7e, 0x04,
+    0x80, 0x04,
+    0x80, 0x04,
+    0x82, 0x04,
+    0x83, 0x04,
+    0x84, 0x04,
+    0x85, 0x04,
+    0x86, 0x04,
+    0x87, 0x04,
+    0x88, 0x04,
+    0x89, 0x04,
+    0x8a, 0x04,
+    0x8a, 0x04,
+    0x8c, 0x04,
+    0x8c, 0x04,
+    0x8e, 0x04,
+    0x8e, 0x04,
+    0x90, 0x04,
+    0x90, 0x04,
+    0x92, 0x04,
+    0x92, 0x04,
+    0x94, 0x04,
+    0x94, 0x04,
+    0x96, 0x04,
+    0x96, 0x04,
+    0x98, 0x04,
+    0x98, 0x04,
+    0x9a, 0x04,
+    0x9a, 0x04,
+    0x9c, 0x04,
+    0x9c, 0x04,
+    0x9e, 0x04,
+    0x9e, 0x04,
+    0xa0, 0x04,
+    0xa0, 0x04,
+    0xa2, 0x04,
+    0xa2, 0x04,
+    0xa4, 0x04,
+    0xa4, 0x04,
+    0xa6, 0x04,
+    0xa6, 0x04,
+    0xa8, 0x04,
+    0xa8, 0x04,
+    0xaa, 0x04,
+    0xaa, 0x04,
+    0xac, 0x04,
+    0xac, 0x04,
+    0xae, 0x04,
+    0xae, 0x04,
+    0xb0, 0x04,
+    0xb0, 0x04,
+    0xb2, 0x04,
+    0xb2, 0x04,
+    0xb4, 0x04,
+    0xb4, 0x04,
+    0xb6, 0x04,
+    0xb6, 0x04,
+    0xb8, 0x04,
+    0xb8, 0x04,
+    0xba, 0x04,
+    0xba, 0x04,
+    0xbc, 0x04,
+    0xbc, 0x04,
+    0xbe, 0x04,
+    0xbe, 0x04,
+    0xc0, 0x04,
+    0xc1, 0x04,
+    0xc1, 0x04,
+    0xc3, 0x04,
+    0xc3, 0x04,
+    0xc5, 0x04,
+    0xc5, 0x04,
+    0xc7, 0x04,
+    0xc7, 0x04,
+    0xc9, 0x04,
+    0xc9, 0x04,
+    0xcb, 0x04,
+    0xcb, 0x04,
+    0xcd, 0x04,
+    0xcd, 0x04,
+    0xc0, 0x04,
+    0xd0, 0x04,
+    0xd0, 0x04,
+    0xd2, 0x04,
+    0xd2, 0x04,
+    0xd4, 0x04,
+    0xd4, 0x04,
+    0xd6, 0x04,
+    0xd6, 0x04,
+    0xd8, 0x04,
+    0xd8, 0x04,
+    0xda, 0x04,
+    0xda, 0x04,
+    0xdc, 0x04,
+    0xdc, 0x04,
+    0xde, 0x04,
+    0xde, 0x04,
+    0xe0, 0x04,
+    0xe0, 0x04,
+    0xe2, 0x04,
+    0xe2, 0x04,
+    0xe4, 0x04,
+    0xe4, 0x04,
+    0xe6, 0x04,
+    0xe6, 0x04,
+    0xe8, 0x04,
+    0xe8, 0x04,
+    0xea, 0x04,
+    0xea, 0x04,
+    0xec, 0x04,
+    0xec, 0x04,
+    0xee, 0x04,
+    0xee, 0x04,
+    0xf0, 0x04,
+    0xf0, 0x04,
+    0xf2, 0x04,
+    0xf2, 0x04,
+    0xf4, 0x04,
+    0xf4, 0x04,
+    0xf6, 0x04,
+    0xf6, 0x04,
+    0xf8, 0x04,
+    0xf8, 0x04,
+    0xfa, 0x04,
+    0xfa, 0x04,
+    0xfc, 0x04,
+    0xfc, 0x04,
+    0xfe, 0x04,
+    0xfe, 0x04,
+    0x00, 0x05,
+    0x00, 0x05,
+    0x02, 0x05,
+    0x02, 0x05,
+    0x04, 0x05,
+    0x04, 0x05,
+    0x06, 0x05,
+    0x06, 0x05,
+    0x08, 0x05,
+    0x08, 0x05,
+    0x0a, 0x05,
+    0x0a, 0x05,
+    0x0c, 0x05,
+    0x0c, 0x05,
+    0x0e, 0x05,
+    0x0e, 0x05,
+    0x10, 0x05,
+    0x10, 0x05,
+    0x12, 0x05,
+    0x12, 0x05,
+    0x14, 0x05,
+    0x15, 0x05,
+    0x16, 0x05,
+    0x17, 0x05,
+    0x18, 0x05,
+    0x19, 0x05,
+    0x1a, 0x05,
+    0x1b, 0x05,
+    0x1c, 0x05,
+    0x1d, 0x05,
+    0x1e, 0x05,
+    0x1f, 0x05,
+    0x20, 0x05,
+    0x21, 0x05,
+    0x22, 0x05,
+    0x23, 0x05,
+    0x24, 0x05,
+    0x25, 0x05,
+    0x26, 0x05,
+    0x27, 0x05,
+    0x28, 0x05,
+    0x29, 0x05,
+    0x2a, 0x05,
+    0x2b, 0x05,
+    0x2c, 0x05,
+    0x2d, 0x05,
+    0x2e, 0x05,
+    0x2f, 0x05,
+    0x30, 0x05,
+    0x31, 0x05,
+    0x32, 0x05,
+    0x33, 0x05,
+    0x34, 0x05,
+    0x35, 0x05,
+    0x36, 0x05,
+    0x37, 0x05,
+    0x38, 0x05,
+    0x39, 0x05,
+    0x3a, 0x05,
+    0x3b, 0x05,
+    0x3c, 0x05,
+    0x3d, 0x05,
+    0x3e, 0x05,
+    0x3f, 0x05,
+    0x40, 0x05,
+    0x41, 0x05,
+    0x42, 0x05,
+    0x43, 0x05,
+    0x44, 0x05,
+    0x45, 0x05,
+    0x46, 0x05,
+    0x47, 0x05,
+    0x48, 0x05,
+    0x49, 0x05,
+    0x4a, 0x05,
+    0x4b, 0x05,
+    0x4c, 0x05,
+    0x4d, 0x05,
+    0x4e, 0x05,
+    0x4f, 0x05,
+    0x50, 0x05,
+    0x51, 0x05,
+    0x52, 0x05,
+    0x53, 0x05,
+    0x54, 0x05,
+    0x55, 0x05,
+    0x56, 0x05,
+    0x57, 0x05,
+    0x58, 0x05,
+    0x59, 0x05,
+    0x5a, 0x05,
+    0x5b, 0x05,
+    0x5c, 0x05,
+    0x5d, 0x05,
+    0x5e, 0x05,
+    0x5f, 0x05,
+    0x60, 0x05,
+    0x31, 0x05,
+    0x32, 0x05,
+    0x33, 0x05,
+    0x34, 0x05,
+    0x35, 0x05,
+    0x36, 0x05,
+    0x37, 0x05,
+    0x38, 0x05,
+    0x39, 0x05,
+    0x3a, 0x05,
+    0x3b, 0x05,
+    0x3c, 0x05,
+    0x3d, 0x05,
+    0x3e, 0x05,
+    0x3f, 0x05,
+    0x40, 0x05,
+    0x41, 0x05,
+    0x42, 0x05,
+    0x43, 0x05,
+    0x44, 0x05,
+    0x45, 0x05,
+    0x46, 0x05,
+    0x47, 0x05,
+    0x48, 0x05,
+    0x49, 0x05,
+    0x4a, 0x05,
+    0x4b, 0x05,
+    0x4c, 0x05,
+    0x4d, 0x05,
+    0x4e, 0x05,
+    0x4f, 0x05,
+    0x50, 0x05,
+    0x51, 0x05,
+    0x52, 0x05,
+    0x53, 0x05,
+    0x54, 0x05,
+    0x55, 0x05,
+    0x56, 0x05,
+    0xff, 0xff,
+    0xf6, 0x17,
+    0x63, 0x2c,
+    0x7e, 0x1d,
+    0x7f, 0x1d,
+    0x80, 0x1d,
+    0x81, 0x1d,
+    0x82, 0x1d,
+    0x83, 0x1d,
+    0x84, 0x1d,
+    0x85, 0x1d,
+    0x86, 0x1d,
+    0x87, 0x1d,
+    0x88, 0x1d,
+    0x89, 0x1d,
+    0x8a, 0x1d,
+    0x8b, 0x1d,
+    0x8c, 0x1d,
+    0x8d, 0x1d,
+    0x8e, 0x1d,
+    0x8f, 0x1d,
+    0x90, 0x1d,
+    0x91, 0x1d,
+    0x92, 0x1d,
+    0x93, 0x1d,
+    0x94, 0x1d,
+    0x95, 0x1d,
+    0x96, 0x1d,
+    0x97, 0x1d,
+    0x98, 0x1d,
+    0x99, 0x1d,
+    0x9a, 0x1d,
+    0x9b, 0x1d,
+    0x9c, 0x1d,
+    0x9d, 0x1d,
+    0x9e, 0x1d,
+    0x9f, 0x1d,
+    0xa0, 0x1d,
+    0xa1, 0x1d,
+    0xa2, 0x1d,
+    0xa3, 0x1d,
+    0xa4, 0x1d,
+    0xa5, 0x1d,
+    0xa6, 0x1d,
+    0xa7, 0x1d,
+    0xa8, 0x1d,
+    0xa9, 0x1d,
+    0xaa, 0x1d,
+    0xab, 0x1d,
+    0xac, 0x1d,
+    0xad, 0x1d,
+    0xae, 0x1d,
+    0xaf, 0x1d,
+    0xb0, 0x1d,
+    0xb1, 0x1d,
+    0xb2, 0x1d,
+    0xb3, 0x1d,
+    0xb4, 0x1d,
+    0xb5, 0x1d,
+    0xb6, 0x1d,
+    0xb7, 0x1d,
+    0xb8, 0x1d,
+    0xb9, 0x1d,
+    0xba, 0x1d,
+    0xbb, 0x1d,
+    0xbc, 0x1d,
+    0xbd, 0x1d,
+    0xbe, 0x1d,
+    0xbf, 0x1d,
+    0xc0, 0x1d,
+    0xc1, 0x1d,
+    0xc2, 0x1d,
+    0xc3, 0x1d,
+    0xc4, 0x1d,
+    0xc5, 0x1d,
+    0xc6, 0x1d,
+    0xc7, 0x1d,
+    0xc8, 0x1d,
+    0xc9, 0x1d,
+    0xca, 0x1d,
+    0xcb, 0x1d,
+    0xcc, 0x1d,
+    0xcd, 0x1d,
+    0xce, 0x1d,
+    0xcf, 0x1d,
+    0xd0, 0x1d,
+    0xd1, 0x1d,
+    0xd2, 0x1d,
+    0xd3, 0x1d,
+    0xd4, 0x1d,
+    0xd5, 0x1d,
+    0xd6, 0x1d,
+    0xd7, 0x1d,
+    0xd8, 0x1d,
+    0xd9, 0x1d,
+    0xda, 0x1d,
+    0xdb, 0x1d,
+    0xdc, 0x1d,
+    0xdd, 0x1d,
+    0xde, 0x1d,
+    0xdf, 0x1d,
+    0xe0, 0x1d,
+    0xe1, 0x1d,
+    0xe2, 0x1d,
+    0xe3, 0x1d,
+    0xe4, 0x1d,
+    0xe5, 0x1d,
+    0xe6, 0x1d,
+    0xe7, 0x1d,
+    0xe8, 0x1d,
+    0xe9, 0x1d,
+    0xea, 0x1d,
+    0xeb, 0x1d,
+    0xec, 0x1d,
+    0xed, 0x1d,
+    0xee, 0x1d,
+    0xef, 0x1d,
+    0xf0, 0x1d,
+    0xf1, 0x1d,
+    0xf2, 0x1d,
+    0xf3, 0x1d,
+    0xf4, 0x1d,
+    0xf5, 0x1d,
+    0xf6, 0x1d,
+    0xf7, 0x1d,
+    0xf8, 0x1d,
+    0xf9, 0x1d,
+    0xfa, 0x1d,
+    0xfb, 0x1d,
+    0xfc, 0x1d,
+    0xfd, 0x1d,
+    0xfe, 0x1d,
+    0xff, 0x1d,
+    0x00, 0x1e,
+    0x00, 0x1e,
+    0x02, 0x1e,
+    0x02, 0x1e,
+    0x04, 0x1e,
+    0x04, 0x1e,
+    0x06, 0x1e,
+    0x06, 0x1e,
+    0x08, 0x1e,
+    0x08, 0x1e,
+    0x0a, 0x1e,
+    0x0a, 0x1e,
+    0x0c, 0x1e,
+    0x0c, 0x1e,
+    0x0e, 0x1e,
+    0x0e, 0x1e,
+    0x10, 0x1e,
+    0x10, 0x1e,
+    0x12, 0x1e,
+    0x12, 0x1e,
+    0x14, 0x1e,
+    0x14, 0x1e,
+    0x16, 0x1e,
+    0x16, 0x1e,
+    0x18, 0x1e,
+    0x18, 0x1e,
+    0x1a, 0x1e,
+    0x1a, 0x1e,
+    0x1c, 0x1e,
+    0x1c, 0x1e,
+    0x1e, 0x1e,
+    0x1e, 0x1e,
+    0x20, 0x1e,
+    0x20, 0x1e,
+    0x22, 0x1e,
+    0x22, 0x1e,
+    0x24, 0x1e,
+    0x24, 0x1e,
+    0x26, 0x1e,
+    0x26, 0x1e,
+    0x28, 0x1e,
+    0x28, 0x1e,
+    0x2a, 0x1e,
+    0x2a, 0x1e,
+    0x2c, 0x1e,
+    0x2c, 0x1e,
+    0x2e, 0x1e,
+    0x2e, 0x1e,
+    0x30, 0x1e,
+    0x30, 0x1e,
+    0x32, 0x1e,
+    0x32, 0x1e,
+    0x34, 0x1e,
+    0x34, 0x1e,
+    0x36, 0x1e,
+    0x36, 0x1e,
+    0x38, 0x1e,
+    0x38, 0x1e,
+    0x3a, 0x1e,
+    0x3a, 0x1e,
+    0x3c, 0x1e,
+    0x3c, 0x1e,
+    0x3e, 0x1e,
+    0x3e, 0x1e,
+    0x40, 0x1e,
+    0x40, 0x1e,
+    0x42, 0x1e,
+    0x42, 0x1e,
+    0x44, 0x1e,
+    0x44, 0x1e,
+    0x46, 0x1e,
+    0x46, 0x1e,
+    0x48, 0x1e,
+    0x48, 0x1e,
+    0x4a, 0x1e,
+    0x4a, 0x1e,
+    0x4c, 0x1e,
+    0x4c, 0x1e,
+    0x4e, 0x1e,
+    0x4e, 0x1e,
+    0x50, 0x1e,
+    0x50, 0x1e,
+    0x52, 0x1e,
+    0x52, 0x1e,
+    0x54, 0x1e,
+    0x54, 0x1e,
+    0x56, 0x1e,
+    0x56, 0x1e,
+    0x58, 0x1e,
+    0x58, 0x1e,
+    0x5a, 0x1e,
+    0x5a, 0x1e,
+    0x5c, 0x1e,
+    0x5c, 0x1e,
+    0x5e, 0x1e,
+    0x5e, 0x1e,
+    0x60, 0x1e,
+    0x60, 0x1e,
+    0x62, 0x1e,
+    0x62, 0x1e,
+    0x64, 0x1e,
+    0x64, 0x1e,
+    0x66, 0x1e,
+    0x66, 0x1e,
+    0x68, 0x1e,
+    0x68, 0x1e,
+    0x6a, 0x1e,
+    0x6a, 0x1e,
+    0x6c, 0x1e,
+    0x6c, 0x1e,
+    0x6e, 0x1e,
+    0x6e, 0x1e,
+    0x70, 0x1e,
+    0x70, 0x1e,
+    0x72, 0x1e,
+    0x72, 0x1e,
+    0x74, 0x1e,
+    0x74, 0x1e,
+    0x76, 0x1e,
+    0x76, 0x1e,
+    0x78, 0x1e,
+    0x78, 0x1e,
+    0x7a, 0x1e,
+    0x7a, 0x1e,
+    0x7c, 0x1e,
+    0x7c, 0x1e,
+    0x7e, 0x1e,
+    0x7e, 0x1e,
+    0x80, 0x1e,
+    0x80, 0x1e,
+    0x82, 0x1e,
+    0x82, 0x1e,
+    0x84, 0x1e,
+    0x84, 0x1e,
+    0x86, 0x1e,
+    0x86, 0x1e,
+    0x88, 0x1e,
+    0x88, 0x1e,
+    0x8a, 0x1e,
+    0x8a, 0x1e,
+    0x8c, 0x1e,
+    0x8c, 0x1e,
+    0x8e, 0x1e,
+    0x8e, 0x1e,
+    0x90, 0x1e,
+    0x90, 0x1e,
+    0x92, 0x1e,
+    0x92, 0x1e,
+    0x94, 0x1e,
+    0x94, 0x1e,
+    0x96, 0x1e,
+    0x97, 0x1e,
+    0x98, 0x1e,
+    0x99, 0x1e,
+    0x9a, 0x1e,
+    0x9b, 0x1e,
+    0x9c, 0x1e,
+    0x9d, 0x1e,
+    0x9e, 0x1e,
+    0x9f, 0x1e,
+    0xa0, 0x1e,
+    0xa0, 0x1e,
+    0xa2, 0x1e,
+    0xa2, 0x1e,
+    0xa4, 0x1e,
+    0xa4, 0x1e,
+    0xa6, 0x1e,
+    0xa6, 0x1e,
+    0xa8, 0x1e,
+    0xa8, 0x1e,
+    0xaa, 0x1e,
+    0xaa, 0x1e,
+    0xac, 0x1e,
+    0xac, 0x1e,
+    0xae, 0x1e,
+    0xae, 0x1e,
+    0xb0, 0x1e,
+    0xb0, 0x1e,
+    0xb2, 0x1e,
+    0xb2, 0x1e,
+    0xb4, 0x1e,
+    0xb4, 0x1e,
+    0xb6, 0x1e,
+    0xb6, 0x1e,
+    0xb8, 0x1e,
+    0xb8, 0x1e,
+    0xba, 0x1e,
+    0xba, 0x1e,
+    0xbc, 0x1e,
+    0xbc, 0x1e,
+    0xbe, 0x1e,
+    0xbe, 0x1e,
+    0xc0, 0x1e,
+    0xc0, 0x1e,
+    0xc2, 0x1e,
+    0xc2, 0x1e,
+    0xc4, 0x1e,
+    0xc4, 0x1e,
+    0xc6, 0x1e,
+    0xc6, 0x1e,
+    0xc8, 0x1e,
+    0xc8, 0x1e,
+    0xca, 0x1e,
+    0xca, 0x1e,
+    0xcc, 0x1e,
+    0xcc, 0x1e,
+    0xce, 0x1e,
+    0xce, 0x1e,
+    0xd0, 0x1e,
+    0xd0, 0x1e,
+    0xd2, 0x1e,
+    0xd2, 0x1e,
+    0xd4, 0x1e,
+    0xd4, 0x1e,
+    0xd6, 0x1e,
+    0xd6, 0x1e,
+    0xd8, 0x1e,
+    0xd8, 0x1e,
+    0xda, 0x1e,
+    0xda, 0x1e,
+    0xdc, 0x1e,
+    0xdc, 0x1e,
+    0xde, 0x1e,
+    0xde, 0x1e,
+    0xe0, 0x1e,
+    0xe0, 0x1e,
+    0xe2, 0x1e,
+    0xe2, 0x1e,
+    0xe4, 0x1e,
+    0xe4, 0x1e,
+    0xe6, 0x1e,
+    0xe6, 0x1e,
+    0xe8, 0x1e,
+    0xe8, 0x1e,
+    0xea, 0x1e,
+    0xea, 0x1e,
+    0xec, 0x1e,
+    0xec, 0x1e,
+    0xee, 0x1e,
+    0xee, 0x1e,
+    0xf0, 0x1e,
+    0xf0, 0x1e,
+    0xf2, 0x1e,
+    0xf2, 0x1e,
+    0xf4, 0x1e,
+    0xf4, 0x1e,
+    0xf6, 0x1e,
+    0xf6, 0x1e,
+    0xf8, 0x1e,
+    0xf8, 0x1e,
+    0xfa, 0x1e,
+    0xfb, 0x1e,
+    0xfc, 0x1e,
+    0xfd, 0x1e,
+    0xfe, 0x1e,
+    0xff, 0x1e,
+    0x08, 0x1f,
+    0x09, 0x1f,
+    0x0a, 0x1f,
+    0x0b, 0x1f,
+    0x0c, 0x1f,
+    0x0d, 0x1f,
+    0x0e, 0x1f,
+    0x0f, 0x1f,
+    0x08, 0x1f,
+    0x09, 0x1f,
+    0x0a, 0x1f,
+    0x0b, 0x1f,
+    0x0c, 0x1f,
+    0x0d, 0x1f,
+    0x0e, 0x1f,
+    0x0f, 0x1f,
+    0x18, 0x1f,
+    0x19, 0x1f,
+    0x1a, 0x1f,
+    0x1b, 0x1f,
+    0x1c, 0x1f,
+    0x1d, 0x1f,
+    0x16, 0x1f,
+    0x17, 0x1f,
+    0x18, 0x1f,
+    0x19, 0x1f,
+    0x1a, 0x1f,
+    0x1b, 0x1f,
+    0x1c, 0x1f,
+    0x1d, 0x1f,
+    0x1e, 0x1f,
+    0x1f, 0x1f,
+    0x28, 0x1f,
+    0x29, 0x1f,
+    0x2a, 0x1f,
+    0x2b, 0x1f,
+    0x2c, 0x1f,
+    0x2d, 0x1f,
+    0x2e, 0x1f,
+    0x2f, 0x1f,
+    0x28, 0x1f,
+    0x29, 0x1f,
+    0x2a, 0x1f,
+    0x2b, 0x1f,
+    0x2c, 0x1f,
+    0x2d, 0x1f,
+    0x2e, 0x1f,
+    0x2f, 0x1f,
+    0x38, 0x1f,
+    0x39, 0x1f,
+    0x3a, 0x1f,
+    0x3b, 0x1f,
+    0x3c, 0x1f,
+    0x3d, 0x1f,
+    0x3e, 0x1f,
+    0x3f, 0x1f,
+    0x38, 0x1f,
+    0x39, 0x1f,
+    0x3a, 0x1f,
+    0x3b, 0x1f,
+    0x3c, 0x1f,
+    0x3d, 0x1f,
+    0x3e, 0x1f,
+    0x3f, 0x1f,
+    0x48, 0x1f,
+    0x49, 0x1f,
+    0x4a, 0x1f,
+    0x4b, 0x1f,
+    0x4c, 0x1f,
+    0x4d, 0x1f,
+    0x46, 0x1f,
+    0x47, 0x1f,
+    0x48, 0x1f,
+    0x49, 0x1f,
+    0x4a, 0x1f,
+    0x4b, 0x1f,
+    0x4c, 0x1f,
+    0x4d, 0x1f,
+    0x4e, 0x1f,
+    0x4f, 0x1f,
+    0x50, 0x1f,
+    0x59, 0x1f,
+    0x52, 0x1f,
+    0x5b, 0x1f,
+    0x54, 0x1f,
+    0x5d, 0x1f,
+    0x56, 0x1f,
+    0x5f, 0x1f,
+    0x58, 0x1f,
+    0x59, 0x1f,
+    0x5a, 0x1f,
+    0x5b, 0x1f,
+    0x5c, 0x1f,
+    0x5d, 0x1f,
+    0x5e, 0x1f,
+    0x5f, 0x1f,
+    0x68, 0x1f,
+    0x69, 0x1f,
+    0x6a, 0x1f,
+    0x6b, 0x1f,
+    0x6c, 0x1f,
+    0x6d, 0x1f,
+    0x6e, 0x1f,
+    0x6f, 0x1f,
+    0x68, 0x1f,
+    0x69, 0x1f,
+    0x6a, 0x1f,
+    0x6b, 0x1f,
+    0x6c, 0x1f,
+    0x6d, 0x1f,
+    0x6e, 0x1f,
+    0x6f, 0x1f,
+    0xba, 0x1f,
+    0xbb, 0x1f,
+    0xc8, 0x1f,
+    0xc9, 0x1f,
+    0xca, 0x1f,
+    0xcb, 0x1f,
+    0xda, 0x1f,
+    0xdb, 0x1f,
+    0xf8, 0x1f,
+    0xf9, 0x1f,
+    0xea, 0x1f,
+    0xeb, 0x1f,
+    0xfa, 0x1f,
+    0xfb, 0x1f,
+    0x7e, 0x1f,
+    0x7f, 0x1f,
+    0x88, 0x1f,
+    0x89, 0x1f,
+    0x8a, 0x1f,
+    0x8b, 0x1f,
+    0x8c, 0x1f,
+    0x8d, 0x1f,
+    0x8e, 0x1f,
+    0x8f, 0x1f,
+    0x88, 0x1f,
+    0x89, 0x1f,
+    0x8a, 0x1f,
+    0x8b, 0x1f,
+    0x8c, 0x1f,
+    0x8d, 0x1f,
+    0x8e, 0x1f,
+    0x8f, 0x1f,
+    0x98, 0x1f,
+    0x99, 0x1f,
+    0x9a, 0x1f,
+    0x9b, 0x1f,
+    0x9c, 0x1f,
+    0x9d, 0x1f,
+    0x9e, 0x1f,
+    0x9f, 0x1f,
+    0x98, 0x1f,
+    0x99, 0x1f,
+    0x9a, 0x1f,
+    0x9b, 0x1f,
+    0x9c, 0x1f,
+    0x9d, 0x1f,
+    0x9e, 0x1f,
+    0x9f, 0x1f,
+    0xa8, 0x1f,
+    0xa9, 0x1f,
+    0xaa, 0x1f,
+    0xab, 0x1f,
+    0xac, 0x1f,
+    0xad, 0x1f,
+    0xae, 0x1f,
+    0xaf, 0x1f,
+    0xa8, 0x1f,
+    0xa9, 0x1f,
+    0xaa, 0x1f,
+    0xab, 0x1f,
+    0xac, 0x1f,
+    0xad, 0x1f,
+    0xae, 0x1f,
+    0xaf, 0x1f,
+    0xb8, 0x1f,
+    0xb9, 0x1f,
+    0xb2, 0x1f,
+    0xbc, 0x1f,
+    0xb4, 0x1f,
+    0xb5, 0x1f,
+    0xb6, 0x1f,
+    0xb7, 0x1f,
+    0xb8, 0x1f,
+    0xb9, 0x1f,
+    0xba, 0x1f,
+    0xbb, 0x1f,
+    0xbc, 0x1f,
+    0xbd, 0x1f,
+    0xbe, 0x1f,
+    0xbf, 0x1f,
+    0xc0, 0x1f,
+    0xc1, 0x1f,
+    0xc2, 0x1f,
+    0xc3, 0x1f,
+    0xc4, 0x1f,
+    0xc5, 0x1f,
+    0xc6, 0x1f,
+    0xc7, 0x1f,
+    0xc8, 0x1f,
+    0xc9, 0x1f,
+    0xca, 0x1f,
+    0xcb, 0x1f,
+    0xc3, 0x1f,
+    0xcd, 0x1f,
+    0xce, 0x1f,
+    0xcf, 0x1f,
+    0xd8, 0x1f,
+    0xd9, 0x1f,
+    0xd2, 0x1f,
+    0xd3, 0x1f,
+    0xd4, 0x1f,
+    0xd5, 0x1f,
+    0xd6, 0x1f,
+    0xd7, 0x1f,
+    0xd8, 0x1f,
+    0xd9, 0x1f,
+    0xda, 0x1f,
+    0xdb, 0x1f,
+    0xdc, 0x1f,
+    0xdd, 0x1f,
+    0xde, 0x1f,
+    0xdf, 0x1f,
+    0xe8, 0x1f,
+    0xe9, 0x1f,
+    0xe2, 0x1f,
+    0xe3, 0x1f,
+    0xe4, 0x1f,
+    0xec, 0x1f,
+    0xe6, 0x1f,
+    0xe7, 0x1f,
+    0xe8, 0x1f,
+    0xe9, 0x1f,
+    0xea, 0x1f,
+    0xeb, 0x1f,
+    0xec, 0x1f,
+    0xed, 0x1f,
+    0xee, 0x1f,
+    0xef, 0x1f,
+    0xf0, 0x1f,
+    0xf1, 0x1f,
+    0xf2, 0x1f,
+    0xf3, 0x1f,
+    0xf4, 0x1f,
+    0xf5, 0x1f,
+    0xf6, 0x1f,
+    0xf7, 0x1f,
+    0xf8, 0x1f,
+    0xf9, 0x1f,
+    0xfa, 0x1f,
+    0xfb, 0x1f,
+    0xf3, 0x1f,
+    0xfd, 0x1f,
+    0xfe, 0x1f,
+    0xff, 0x1f,
+    0x00, 0x20,
+    0x01, 0x20,
+    0x02, 0x20,
+    0x03, 0x20,
+    0x04, 0x20,
+    0x05, 0x20,
+    0x06, 0x20,
+    0x07, 0x20,
+    0x08, 0x20,
+    0x09, 0x20,
+    0x0a, 0x20,
+    0x0b, 0x20,
+    0x0c, 0x20,
+    0x0d, 0x20,
+    0x0e, 0x20,
+    0x0f, 0x20,
+    0x10, 0x20,
+    0x11, 0x20,
+    0x12, 0x20,
+    0x13, 0x20,
+    0x14, 0x20,
+    0x15, 0x20,
+    0x16, 0x20,
+    0x17, 0x20,
+    0x18, 0x20,
+    0x19, 0x20,
+    0x1a, 0x20,
+    0x1b, 0x20,
+    0x1c, 0x20,
+    0x1d, 0x20,
+    0x1e, 0x20,
+    0x1f, 0x20,
+    0x20, 0x20,
+    0x21, 0x20,
+    0x22, 0x20,
+    0x23, 0x20,
+    0x24, 0x20,
+    0x25, 0x20,
+    0x26, 0x20,
+    0x27, 0x20,
+    0x28, 0x20,
+    0x29, 0x20,
+    0x2a, 0x20,
+    0x2b, 0x20,
+    0x2c, 0x20,
+    0x2d, 0x20,
+    0x2e, 0x20,
+    0x2f, 0x20,
+    0x30, 0x20,
+    0x31, 0x20,
+    0x32, 0x20,
+    0x33, 0x20,
+    0x34, 0x20,
+    0x35, 0x20,
+    0x36, 0x20,
+    0x37, 0x20,
+    0x38, 0x20,
+    0x39, 0x20,
+    0x3a, 0x20,
+    0x3b, 0x20,
+    0x3c, 0x20,
+    0x3d, 0x20,
+    0x3e, 0x20,
+    0x3f, 0x20,
+    0x40, 0x20,
+    0x41, 0x20,
+    0x42, 0x20,
+    0x43, 0x20,
+    0x44, 0x20,
+    0x45, 0x20,
+    0x46, 0x20,
+    0x47, 0x20,
+    0x48, 0x20,
+    0x49, 0x20,
+    0x4a, 0x20,
+    0x4b, 0x20,
+    0x4c, 0x20,
+    0x4d, 0x20,
+    0x4e, 0x20,
+    0x4f, 0x20,
+    0x50, 0x20,
+    0x51, 0x20,
+    0x52, 0x20,
+    0x53, 0x20,
+    0x54, 0x20,
+    0x55, 0x20,
+    0x56, 0x20,
+    0x57, 0x20,
+    0x58, 0x20,
+    0x59, 0x20,
+    0x5a, 0x20,
+    0x5b, 0x20,
+    0x5c, 0x20,
+    0x5d, 0x20,
+    0x5e, 0x20,
+    0x5f, 0x20,
+    0x60, 0x20,
+    0x61, 0x20,
+    0x62, 0x20,
+    0x63, 0x20,
+    0x64, 0x20,
+    0x65, 0x20,
+    0x66, 0x20,
+    0x67, 0x20,
+    0x68, 0x20,
+    0x69, 0x20,
+    0x6a, 0x20,
+    0x6b, 0x20,
+    0x6c, 0x20,
+    0x6d, 0x20,
+    0x6e, 0x20,
+    0x6f, 0x20,
+    0x70, 0x20,
+    0x71, 0x20,
+    0x72, 0x20,
+    0x73, 0x20,
+    0x74, 0x20,
+    0x75, 0x20,
+    0x76, 0x20,
+    0x77, 0x20,
+    0x78, 0x20,
+    0x79, 0x20,
+    0x7a, 0x20,
+    0x7b, 0x20,
+    0x7c, 0x20,
+    0x7d, 0x20,
+    0x7e, 0x20,
+    0x7f, 0x20,
+    0x80, 0x20,
+    0x81, 0x20,
+    0x82, 0x20,
+    0x83, 0x20,
+    0x84, 0x20,
+    0x85, 0x20,
+    0x86, 0x20,
+    0x87, 0x20,
+    0x88, 0x20,
+    0x89, 0x20,
+    0x8a, 0x20,
+    0x8b, 0x20,
+    0x8c, 0x20,
+    0x8d, 0x20,
+    0x8e, 0x20,
+    0x8f, 0x20,
+    0x90, 0x20,
+    0x91, 0x20,
+    0x92, 0x20,
+    0x93, 0x20,
+    0x94, 0x20,
+    0x95, 0x20,
+    0x96, 0x20,
+    0x97, 0x20,
+    0x98, 0x20,
+    0x99, 0x20,
+    0x9a, 0x20,
+    0x9b, 0x20,
+    0x9c, 0x20,
+    0x9d, 0x20,
+    0x9e, 0x20,
+    0x9f, 0x20,
+    0xa0, 0x20,
+    0xa1, 0x20,
+    0xa2, 0x20,
+    0xa3, 0x20,
+    0xa4, 0x20,
+    0xa5, 0x20,
+    0xa6, 0x20,
+    0xa7, 0x20,
+    0xa8, 0x20,
+    0xa9, 0x20,
+    0xaa, 0x20,
+    0xab, 0x20,
+    0xac, 0x20,
+    0xad, 0x20,
+    0xae, 0x20,
+    0xaf, 0x20,
+    0xb0, 0x20,
+    0xb1, 0x20,
+    0xb2, 0x20,
+    0xb3, 0x20,
+    0xb4, 0x20,
+    0xb5, 0x20,
+    0xb6, 0x20,
+    0xb7, 0x20,
+    0xb8, 0x20,
+    0xb9, 0x20,
+    0xba, 0x20,
+    0xbb, 0x20,
+    0xbc, 0x20,
+    0xbd, 0x20,
+    0xbe, 0x20,
+    0xbf, 0x20,
+    0xc0, 0x20,
+    0xc1, 0x20,
+    0xc2, 0x20,
+    0xc3, 0x20,
+    0xc4, 0x20,
+    0xc5, 0x20,
+    0xc6, 0x20,
+    0xc7, 0x20,
+    0xc8, 0x20,
+    0xc9, 0x20,
+    0xca, 0x20,
+    0xcb, 0x20,
+    0xcc, 0x20,
+    0xcd, 0x20,
+    0xce, 0x20,
+    0xcf, 0x20,
+    0xd0, 0x20,
+    0xd1, 0x20,
+    0xd2, 0x20,
+    0xd3, 0x20,
+    0xd4, 0x20,
+    0xd5, 0x20,
+    0xd6, 0x20,
+    0xd7, 0x20,
+    0xd8, 0x20,
+    0xd9, 0x20,
+    0xda, 0x20,
+    0xdb, 0x20,
+    0xdc, 0x20,
+    0xdd, 0x20,
+    0xde, 0x20,
+    0xdf, 0x20,
+    0xe0, 0x20,
+    0xe1, 0x20,
+    0xe2, 0x20,
+    0xe3, 0x20,
+    0xe4, 0x20,
+    0xe5, 0x20,
+    0xe6, 0x20,
+    0xe7, 0x20,
+    0xe8, 0x20,
+    0xe9, 0x20,
+    0xea, 0x20,
+    0xeb, 0x20,
+    0xec, 0x20,
+    0xed, 0x20,
+    0xee, 0x20,
+    0xef, 0x20,
+    0xf0, 0x20,
+    0xf1, 0x20,
+    0xf2, 0x20,
+    0xf3, 0x20,
+    0xf4, 0x20,
+    0xf5, 0x20,
+    0xf6, 0x20,
+    0xf7, 0x20,
+    0xf8, 0x20,
+    0xf9, 0x20,
+    0xfa, 0x20,
+    0xfb, 0x20,
+    0xfc, 0x20,
+    0xfd, 0x20,
+    0xfe, 0x20,
+    0xff, 0x20,
+    0x00, 0x21,
+    0x01, 0x21,
+    0x02, 0x21,
+    0x03, 0x21,
+    0x04, 0x21,
+    0x05, 0x21,
+    0x06, 0x21,
+    0x07, 0x21,
+    0x08, 0x21,
+    0x09, 0x21,
+    0x0a, 0x21,
+    0x0b, 0x21,
+    0x0c, 0x21,
+    0x0d, 0x21,
+    0x0e, 0x21,
+    0x0f, 0x21,
+    0x10, 0x21,
+    0x11, 0x21,
+    0x12, 0x21,
+    0x13, 0x21,
+    0x14, 0x21,
+    0x15, 0x21,
+    0x16, 0x21,
+    0x17, 0x21,
+    0x18, 0x21,
+    0x19, 0x21,
+    0x1a, 0x21,
+    0x1b, 0x21,
+    0x1c, 0x21,
+    0x1d, 0x21,
+    0x1e, 0x21,
+    0x1f, 0x21,
+    0x20, 0x21,
+    0x21, 0x21,
+    0x22, 0x21,
+    0x23, 0x21,
+    0x24, 0x21,
+    0x25, 0x21,
+    0x26, 0x21,
+    0x27, 0x21,
+    0x28, 0x21,
+    0x29, 0x21,
+    0x2a, 0x21,
+    0x2b, 0x21,
+    0x2c, 0x21,
+    0x2d, 0x21,
+    0x2e, 0x21,
+    0x2f, 0x21,
+    0x30, 0x21,
+    0x31, 0x21,
+    0x32, 0x21,
+    0x33, 0x21,
+    0x34, 0x21,
+    0x35, 0x21,
+    0x36, 0x21,
+    0x37, 0x21,
+    0x38, 0x21,
+    0x39, 0x21,
+    0x3a, 0x21,
+    0x3b, 0x21,
+    0x3c, 0x21,
+    0x3d, 0x21,
+    0x3e, 0x21,
+    0x3f, 0x21,
+    0x40, 0x21,
+    0x41, 0x21,
+    0x42, 0x21,
+    0x43, 0x21,
+    0x44, 0x21,
+    0x45, 0x21,
+    0x46, 0x21,
+    0x47, 0x21,
+    0x48, 0x21,
+    0x49, 0x21,
+    0x4a, 0x21,
+    0x4b, 0x21,
+    0x4c, 0x21,
+    0x4d, 0x21,
+    0x32, 0x21,
+    0x4f, 0x21,
+    0x50, 0x21,
+    0x51, 0x21,
+    0x52, 0x21,
+    0x53, 0x21,
+    0x54, 0x21,
+    0x55, 0x21,
+    0x56, 0x21,
+    0x57, 0x21,
+    0x58, 0x21,
+    0x59, 0x21,
+    0x5a, 0x21,
+    0x5b, 0x21,
+    0x5c, 0x21,
+    0x5d, 0x21,
+    0x5e, 0x21,
+    0x5f, 0x21,
+    0x60, 0x21,
+    0x61, 0x21,
+    0x62, 0x21,
+    0x63, 0x21,
+    0x64, 0x21,
+    0x65, 0x21,
+    0x66, 0x21,
+    0x67, 0x21,
+    0x68, 0x21,
+    0x69, 0x21,
+    0x6a, 0x21,
+    0x6b, 0x21,
+    0x6c, 0x21,
+    0x6d, 0x21,
+    0x6e, 0x21,
+    0x6f, 0x21,
+    0x60, 0x21,
+    0x61, 0x21,
+    0x62, 0x21,
+    0x63, 0x21,
+    0x64, 0x21,
+    0x65, 0x21,
+    0x66, 0x21,
+    0x67, 0x21,
+    0x68, 0x21,
+    0x69, 0x21,
+    0x6a, 0x21,
+    0x6b, 0x21,
+    0x6c, 0x21,
+    0x6d, 0x21,
+    0x6e, 0x21,
+    0x6f, 0x21,
+    0x80, 0x21,
+    0x81, 0x21,
+    0x82, 0x21,
+    0x83, 0x21,
+    0x83, 0x21,
+    0xff, 0xff,
+    0x4b, 0x03,
+    0xb6, 0x24,
+    0xb7, 0x24,
+    0xb8, 0x24,
+    0xb9, 0x24,
+    0xba, 0x24,
+    0xbb, 0x24,
+    0xbc, 0x24,
+    0xbd, 0x24,
+    0xbe, 0x24,
+    0xbf, 0x24,
+    0xc0, 0x24,
+    0xc1, 0x24,
+    0xc2, 0x24,
+    0xc3, 0x24,
+    0xc4, 0x24,
+    0xc5, 0x24,
+    0xc6, 0x24,
+    0xc7, 0x24,
+    0xc8, 0x24,
+    0xc9, 0x24,
+    0xca, 0x24,
+    0xcb, 0x24,
+    0xcc, 0x24,
+    0xcd, 0x24,
+    0xce, 0x24,
+    0xcf, 0x24,
+    0xff, 0xff,
+    0x46, 0x07,
+    0x00, 0x2c,
+    0x01, 0x2c,
+    0x02, 0x2c,
+    0x03, 0x2c,
+    0x04, 0x2c,
+    0x05, 0x2c,
+    0x06, 0x2c,
+    0x07, 0x2c,
+    0x08, 0x2c,
+    0x09, 0x2c,
+    0x0a, 0x2c,
+    0x0b, 0x2c,
+    0x0c, 0x2c,
+    0x0d, 0x2c,
+    0x0e, 0x2c,
+    0x0f, 0x2c,
+    0x10, 0x2c,
+    0x11, 0x2c,
+    0x12, 0x2c,
+    0x13, 0x2c,
+    0x14, 0x2c,
+    0x15, 0x2c,
+    0x16, 0x2c,
+    0x17, 0x2c,
+    0x18, 0x2c,
+    0x19, 0x2c,
+    0x1a, 0x2c,
+    0x1b, 0x2c,
+    0x1c, 0x2c,
+    0x1d, 0x2c,
+    0x1e, 0x2c,
+    0x1f, 0x2c,
+    0x20, 0x2c,
+    0x21, 0x2c,
+    0x22, 0x2c,
+    0x23, 0x2c,
+    0x24, 0x2c,
+    0x25, 0x2c,
+    0x26, 0x2c,
+    0x27, 0x2c,
+    0x28, 0x2c,
+    0x29, 0x2c,
+    0x2a, 0x2c,
+    0x2b, 0x2c,
+    0x2c, 0x2c,
+    0x2d, 0x2c,
+    0x2e, 0x2c,
+    0x5f, 0x2c,
+    0x60, 0x2c,
+    0x60, 0x2c,
+    0x62, 0x2c,
+    0x63, 0x2c,
+    0x64, 0x2c,
+    0x65, 0x2c,
+    0x66, 0x2c,
+    0x67, 0x2c,
+    0x67, 0x2c,
+    0x69, 0x2c,
+    0x69, 0x2c,
+    0x6b, 0x2c,
+    0x6b, 0x2c,
+    0x6d, 0x2c,
+    0x6e, 0x2c,
+    0x6f, 0x2c,
+    0x70, 0x2c,
+    0x71, 0x2c,
+    0x72, 0x2c,
+    0x73, 0x2c,
+    0x74, 0x2c,
+    0x75, 0x2c,
+    0x75, 0x2c,
+    0x77, 0x2c,
+    0x78, 0x2c,
+    0x79, 0x2c,
+    0x7a, 0x2c,
+    0x7b, 0x2c,
+    0x7c, 0x2c,
+    0x7d, 0x2c,
+    0x7e, 0x2c,
+    0x7f, 0x2c,
+    0x80, 0x2c,
+    0x80, 0x2c,
+    0x82, 0x2c,
+    0x82, 0x2c,
+    0x84, 0x2c,
+    0x84, 0x2c,
+    0x86, 0x2c,
+    0x86, 0x2c,
+    0x88, 0x2c,
+    0x88, 0x2c,
+    0x8a, 0x2c,
+    0x8a, 0x2c,
+    0x8c, 0x2c,
+    0x8c, 0x2c,
+    0x8e, 0x2c,
+    0x8e, 0x2c,
+    0x90, 0x2c,
+    0x90, 0x2c,
+    0x92, 0x2c,
+    0x92, 0x2c,
+    0x94, 0x2c,
+    0x94, 0x2c,
+    0x96, 0x2c,
+    0x96, 0x2c,
+    0x98, 0x2c,
+    0x98, 0x2c,
+    0x9a, 0x2c,
+    0x9a, 0x2c,
+    0x9c, 0x2c,
+    0x9c, 0x2c,
+    0x9e, 0x2c,
+    0x9e, 0x2c,
+    0xa0, 0x2c,
+    0xa0, 0x2c,
+    0xa2, 0x2c,
+    0xa2, 0x2c,
+    0xa4, 0x2c,
+    0xa4, 0x2c,
+    0xa6, 0x2c,
+    0xa6, 0x2c,
+    0xa8, 0x2c,
+    0xa8, 0x2c,
+    0xaa, 0x2c,
+    0xaa, 0x2c,
+    0xac, 0x2c,
+    0xac, 0x2c,
+    0xae, 0x2c,
+    0xae, 0x2c,
+    0xb0, 0x2c,
+    0xb0, 0x2c,
+    0xb2, 0x2c,
+    0xb2, 0x2c,
+    0xb4, 0x2c,
+    0xb4, 0x2c,
+    0xb6, 0x2c,
+    0xb6, 0x2c,
+    0xb8, 0x2c,
+    0xb8, 0x2c,
+    0xba, 0x2c,
+    0xba, 0x2c,
+    0xbc, 0x2c,
+    0xbc, 0x2c,
+    0xbe, 0x2c,
+    0xbe, 0x2c,
+    0xc0, 0x2c,
+    0xc0, 0x2c,
+    0xc2, 0x2c,
+    0xc2, 0x2c,
+    0xc4, 0x2c,
+    0xc4, 0x2c,
+    0xc6, 0x2c,
+    0xc6, 0x2c,
+    0xc8, 0x2c,
+    0xc8, 0x2c,
+    0xca, 0x2c,
+    0xca, 0x2c,
+    0xcc, 0x2c,
+    0xcc, 0x2c,
+    0xce, 0x2c,
+    0xce, 0x2c,
+    0xd0, 0x2c,
+    0xd0, 0x2c,
+    0xd2, 0x2c,
+    0xd2, 0x2c,
+    0xd4, 0x2c,
+    0xd4, 0x2c,
+    0xd6, 0x2c,
+    0xd6, 0x2c,
+    0xd8, 0x2c,
+    0xd8, 0x2c,
+    0xda, 0x2c,
+    0xda, 0x2c,
+    0xdc, 0x2c,
+    0xdc, 0x2c,
+    0xde, 0x2c,
+    0xde, 0x2c,
+    0xe0, 0x2c,
+    0xe0, 0x2c,
+    0xe2, 0x2c,
+    0xe2, 0x2c,
+    0xe4, 0x2c,
+    0xe5, 0x2c,
+    0xe6, 0x2c,
+    0xe7, 0x2c,
+    0xe8, 0x2c,
+    0xe9, 0x2c,
+    0xea, 0x2c,
+    0xeb, 0x2c,
+    0xec, 0x2c,
+    0xed, 0x2c,
+    0xee, 0x2c,
+    0xef, 0x2c,
+    0xf0, 0x2c,
+    0xf1, 0x2c,
+    0xf2, 0x2c,
+    0xf3, 0x2c,
+    0xf4, 0x2c,
+    0xf5, 0x2c,
+    0xf6, 0x2c,
+    0xf7, 0x2c,
+    0xf8, 0x2c,
+    0xf9, 0x2c,
+    0xfa, 0x2c,
+    0xfb, 0x2c,
+    0xfc, 0x2c,
+    0xfd, 0x2c,
+    0xfe, 0x2c,
+    0xff, 0x2c,
+    0xa0, 0x10,
+    0xa1, 0x10,
+    0xa2, 0x10,
+    0xa3, 0x10,
+    0xa4, 0x10,
+    0xa5, 0x10,
+    0xa6, 0x10,
+    0xa7, 0x10,
+    0xa8, 0x10,
+    0xa9, 0x10,
+    0xaa, 0x10,
+    0xab, 0x10,
+    0xac, 0x10,
+    0xad, 0x10,
+    0xae, 0x10,
+    0xaf, 0x10,
+    0xb0, 0x10,
+    0xb1, 0x10,
+    0xb2, 0x10,
+    0xb3, 0x10,
+    0xb4, 0x10,
+    0xb5, 0x10,
+    0xb6, 0x10,
+    0xb7, 0x10,
+    0xb8, 0x10,
+    0xb9, 0x10,
+    0xba, 0x10,
+    0xbb, 0x10,
+    0xbc, 0x10,
+    0xbd, 0x10,
+    0xbe, 0x10,
+    0xbf, 0x10,
+    0xc0, 0x10,
+    0xc1, 0x10,
+    0xc2, 0x10,
+    0xc3, 0x10,
+    0xc4, 0x10,
+    0xc5, 0x10,
+    0xff, 0xff,
+    0x1b, 0xd2,
+    0x21, 0xff,
+    0x22, 0xff,
+    0x23, 0xff,
+    0x24, 0xff,
+    0x25, 0xff,
+    0x26, 0xff,
+    0x27, 0xff,
+    0x28, 0xff,
+    0x29, 0xff,
+    0x2a, 0xff,
+    0x2b, 0xff,
+    0x2c, 0xff,
+    0x2d, 0xff,
+    0x2e, 0xff,
+    0x2f, 0xff,
+    0x30, 0xff,
+    0x31, 0xff,
+    0x32, 0xff,
+    0x33, 0xff,
+    0x34, 0xff,
+    0x35, 0xff,
+    0x36, 0xff,
+    0x37, 0xff,
+    0x38, 0xff,
+    0x39, 0xff,
+    0x3a, 0xff,
+    0x5b, 0xff,
+    0x5c, 0xff,
+    0x5d, 0xff,
+    0x5e, 0xff,
+    0x5f, 0xff,
+    0x60, 0xff,
+    0x61, 0xff,
+    0x62, 0xff,
+    0x63, 0xff,
+    0x64, 0xff,
+    0x65, 0xff,
+    0x66, 0xff,
+    0x67, 0xff,
+    0x68, 0xff,
+    0x69, 0xff,
+    0x6a, 0xff,
+    0x6b, 0xff,
+    0x6c, 0xff,
+    0x6d, 0xff,
+    0x6e, 0xff,
+    0x6f, 0xff,
+    0x70, 0xff,
+    0x71, 0xff,
+    0x72, 0xff,
+    0x73, 0xff,
+    0x74, 0xff,
+    0x75, 0xff,
+    0x76, 0xff,
+    0x77, 0xff,
+    0x78, 0xff,
+    0x79, 0xff,
+    0x7a, 0xff,
+    0x7b, 0xff,
+    0x7c, 0xff,
+    0x7d, 0xff,
+    0x7e, 0xff,
+    0x7f, 0xff,
+    0x80, 0xff,
+    0x81, 0xff,
+    0x82, 0xff,
+    0x83, 0xff,
+    0x84, 0xff,
+    0x85, 0xff,
+    0x86, 0xff,
+    0x87, 0xff,
+    0x88, 0xff,
+    0x89, 0xff,
+    0x8a, 0xff,
+    0x8b, 0xff,
+    0x8c, 0xff,
+    0x8d, 0xff,
+    0x8e, 0xff,
+    0x8f, 0xff,
+    0x90, 0xff,
+    0x91, 0xff,
+    0x92, 0xff,
+    0x93, 0xff,
+    0x94, 0xff,
+    0x95, 0xff,
+    0x96, 0xff,
+    0x97, 0xff,
+    0x98, 0xff,
+    0x99, 0xff,
+    0x9a, 0xff,
+    0x9b, 0xff,
+    0x9c, 0xff,
+    0x9d, 0xff,
+    0x9e, 0xff,
+    0x9f, 0xff,
+    0xa0, 0xff,
+    0xa1, 0xff,
+    0xa2, 0xff,
+    0xa3, 0xff,
+    0xa4, 0xff,
+    0xa5, 0xff,
+    0xa6, 0xff,
+    0xa7, 0xff,
+    0xa8, 0xff,
+    0xa9, 0xff,
+    0xaa, 0xff,
+    0xab, 0xff,
+    0xac, 0xff,
+    0xad, 0xff,
+    0xae, 0xff,
+    0xaf, 0xff,
+    0xb0, 0xff,
+    0xb1, 0xff,
+    0xb2, 0xff,
+    0xb3, 0xff,
+    0xb4, 0xff,
+    0xb5, 0xff,
+    0xb6, 0xff,
+    0xb7, 0xff,
+    0xb8, 0xff,
+    0xb9, 0xff,
+    0xba, 0xff,
+    0xbb, 0xff,
+    0xbc, 0xff,
+    0xbd, 0xff,
+    0xbe, 0xff,
+    0xbf, 0xff,
+    0xc0, 0xff,
+    0xc1, 0xff,
+    0xc2, 0xff,
+    0xc3, 0xff,
+    0xc4, 0xff,
+    0xc5, 0xff,
+    0xc6, 0xff,
+    0xc7, 0xff,
+    0xc8, 0xff,
+    0xc9, 0xff,
+    0xca, 0xff,
+    0xcb, 0xff,
+    0xcc, 0xff,
+    0xcd, 0xff,
+    0xce, 0xff,
+    0xcf, 0xff,
+    0xd0, 0xff,
+    0xd1, 0xff,
+    0xd2, 0xff,
+    0xd3, 0xff,
+    0xd4, 0xff,
+    0xd5, 0xff,
+    0xd6, 0xff,
+    0xd7, 0xff,
+    0xd8, 0xff,
+    0xd9, 0xff,
+    0xda, 0xff,
+    0xdb, 0xff,
+    0xdc, 0xff,
+    0xdd, 0xff,
+    0xde, 0xff,
+    0xdf, 0xff,
+    0xe0, 0xff,
+    0xe1, 0xff,
+    0xe2, 0xff,
+    0xe3, 0xff,
+    0xe4, 0xff,
+    0xe5, 0xff,
+    0xe6, 0xff,
+    0xe7, 0xff,
+    0xe8, 0xff,
+    0xe9, 0xff,
+    0xea, 0xff,
+    0xeb, 0xff,
+    0xec, 0xff,
+    0xed, 0xff,
+    0xee, 0xff,
+    0xef, 0xff,
+    0xf0, 0xff,
+    0xf1, 0xff,
+    0xf2, 0xff,
+    0xf3, 0xff,
+    0xf4, 0xff,
+    0xf5, 0xff,
+    0xf6, 0xff,
+    0xf7, 0xff,
+    0xf8, 0xff,
+    0xf9, 0xff,
+    0xfa, 0xff,
+    0xfb, 0xff,
+    0xfc, 0xff,
+    0xfd, 0xff,
+    0xfe, 0xff,
+    0xff, 0xff
+};
+
+#endif
+
+/**
+ * @}
+ */
+
+
Index: uspace/app/sysinfo/sysinfo.c
===================================================================
--- uspace/app/sysinfo/sysinfo.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/app/sysinfo/sysinfo.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -37,51 +37,24 @@
 #include <stdio.h>
 #include <sysinfo.h>
+#include <malloc.h>
 #include <sys/types.h>
 
-static int print_item_val(char *ipath);
-static int print_item_data(char *ipath);
-
-static void dump_bytes_hex(char *data, size_t size);
-static void dump_bytes_text(char *data, size_t size);
-
-static void print_syntax(void);
-
-int main(int argc, char *argv[])
-{
-	int rc;
-	char *ipath;
-	sysinfo_item_val_type_t tag;
-
-	if (argc != 2) {
-		print_syntax();
-		return 1;
-	}
-
-	ipath = argv[1];
-
-	tag = sysinfo_get_val_type(ipath);
-
-	/* Silence warning */
-	rc = EOK;
-
-	switch (tag) {
-	case SYSINFO_VAL_UNDEFINED:
-		printf("Error: Sysinfo item '%s' not defined.\n", ipath);
-		rc = 2;
-		break;
-	case SYSINFO_VAL_VAL:
-		rc = print_item_val(ipath);
-		break;
-	case SYSINFO_VAL_DATA:
-		rc = print_item_data(ipath);
-		break;
-	default:
-		printf("Error: Sysinfo item '%s' with unknown value type.\n",
-		    ipath);
-		rc = 2;
-		break;
-	}
-
-	return rc;
+static void dump_bytes_hex(char *data, size_t size)
+{
+	for (size_t i = 0; i < size; i++) {
+		if (i > 0)
+			putchar(' ');
+		printf("0x%02x", (uint8_t) data[i]);
+	}
+}
+
+static void dump_bytes_text(char *data, size_t size)
+{
+	size_t offset = 0;
+	
+	while (offset < size) {
+		wchar_t c = str_decode(data, &offset, size);
+		printf("%lc", (wint_t) c);
+	}
 }
 
@@ -89,15 +62,13 @@
 {
 	sysarg_t value;
-	int rc;
-
-	rc = sysinfo_get_value(ipath, &value);
+	int rc = sysinfo_get_value(ipath, &value);
 	if (rc != EOK) {
 		printf("Error reading item '%s'.\n", ipath);
 		return rc;
 	}
-
+	
 	printf("%s -> %" PRIu64 " (0x%" PRIx64 ")\n", ipath,
 	    (uint64_t) value, (uint64_t) value);
-
+	
 	return EOK;
 }
@@ -105,13 +76,11 @@
 static int print_item_data(char *ipath)
 {
-	void *data;
 	size_t size;
-
-	data = sysinfo_get_data(ipath, &size);
+	void *data = sysinfo_get_data(ipath, &size);
 	if (data == NULL) {
 		printf("Error reading item '%s'.\n", ipath);
 		return -1;
 	}
-
+	
 	printf("%s -> ", ipath);
 	dump_bytes_hex(data, size);
@@ -119,35 +88,115 @@
 	dump_bytes_text(data, size);
 	fputs("')\n", stdout);
-
+	
 	return EOK;
 }
 
-static void dump_bytes_hex(char *data, size_t size)
-{
-	size_t i;
-
-	for (i = 0; i < size; ++i) {
-		if (i > 0) putchar(' ');
-		printf("0x%02x", (uint8_t) data[i]);
-	}
-}
-
-static void dump_bytes_text(char *data, size_t size)
-{
-	wchar_t c;
-	size_t offset;
-
-	offset = 0;
-
-	while (offset < size) {
-		c = str_decode(data, &offset, size);
-		printf("%lc", (wint_t) c);
-	}
-}
-
-
-static void print_syntax(void)
-{
-	printf("Syntax: sysinfo <item_path>\n");
+static int print_item_property(char *ipath, char *iprop)
+{
+	size_t size;
+	void *data = sysinfo_get_property(ipath, iprop, &size);
+	if (data == NULL) {
+		printf("Error reading property '%s' of item '%s'.\n", iprop,
+		    ipath);
+		return -1;
+	}
+	
+	printf("%s property %s -> ", ipath, iprop);
+	dump_bytes_hex(data, size);
+	fputs(" ('", stdout);
+	dump_bytes_text(data, size);
+	fputs("')\n", stdout);
+	
+	return EOK;
+}
+
+static void print_spaces(size_t spaces)
+{
+	for (size_t i = 0; i < spaces; i++)
+		printf(" ");
+}
+
+static void print_keys(const char *path, size_t spaces)
+{
+	size_t size;
+	char *keys = sysinfo_get_keys(path, &size);
+	if ((keys == NULL) || (size == 0))
+		return;
+	
+	size_t pos = 0;
+	while (pos < size) {
+		/* Process each key with sanity checks */
+		size_t cur_size = str_nsize(keys + pos, size - pos);
+		if (keys[pos + cur_size] != 0)
+			break;
+		
+		size_t path_size = str_size(path) + cur_size + 2;
+		char *cur_path = (char *) malloc(path_size);
+		if (cur_path == NULL)
+			break;
+		
+		size_t length;
+		
+		if (path[0] != 0) {
+			print_spaces(spaces);
+			printf(".%s\n", keys + pos);
+			length = str_length(keys + pos) + 1;
+			
+			snprintf(cur_path, path_size, "%s.%s", path, keys + pos);
+		} else {
+			printf("%s\n", keys + pos);
+			length = str_length(keys + pos);
+			
+			snprintf(cur_path, path_size, "%s", keys + pos);
+		}
+		
+		print_keys(cur_path, spaces + length);
+		
+		free(cur_path);
+		pos += cur_size + 1;
+	}
+	
+	free(keys);
+}
+
+int main(int argc, char *argv[])
+{
+	int rc = 0;
+	
+	if (argc < 2) {
+		/* Print keys */
+		print_keys("", 0);
+		return rc;
+	}
+	
+	char *ipath = argv[1];
+	
+	if (argc < 3) {
+		sysinfo_item_val_type_t tag = sysinfo_get_val_type(ipath);
+		
+		switch (tag) {
+		case SYSINFO_VAL_UNDEFINED:
+			printf("Error: Sysinfo item '%s' not defined.\n", ipath);
+			rc = 2;
+			break;
+		case SYSINFO_VAL_VAL:
+			rc = print_item_val(ipath);
+			break;
+		case SYSINFO_VAL_DATA:
+			rc = print_item_data(ipath);
+			break;
+		default:
+			printf("Error: Sysinfo item '%s' with unknown value type.\n",
+			    ipath);
+			rc = 2;
+			break;
+		}
+		
+		return rc;
+	}
+	
+	char *iprop = argv[2];
+	rc = print_item_property(ipath, iprop);
+	return rc;
 }
 
Index: uspace/drv/bus/usb/ehci/Makefile
===================================================================
--- uspace/drv/bus/usb/ehci/Makefile	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/drv/bus/usb/ehci/Makefile	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -43,5 +43,5 @@
 SOURCES = \
 	main.c \
-	pci.c
+	res.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/bus/usb/ehci/main.c
===================================================================
--- uspace/drv/bus/usb/ehci/main.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/drv/bus/usb/ehci/main.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -44,5 +44,5 @@
 #include <usb/host/hcd.h>
 
-#include "pci.h"
+#include "res.h"
 
 #define NAME "ehci"
@@ -81,5 +81,5 @@
 	int irq = 0;
 
-	int ret = pci_get_my_registers(device, &reg_base, &reg_size, &irq);
+	int ret = get_my_registers(device, &reg_base, &reg_size, &irq);
 	CHECK_RET_RETURN(ret,
 	    "Failed to get memory addresses for %" PRIun ": %s.\n",
@@ -88,5 +88,5 @@
 	    reg_base, reg_size, irq);
 
-	ret = pci_disable_legacy(device, reg_base, reg_size, irq);
+	ret = disable_legacy(device, reg_base, reg_size);
 	CHECK_RET_RETURN(ret,
 	    "Failed to disable legacy USB: %s.\n", str_error(ret));
Index: pace/drv/bus/usb/ehci/pci.c
===================================================================
--- uspace/drv/bus/usb/ehci/pci.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ 	(revision )
@@ -1,391 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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 drvusbehci
- * @{
- */
-/**
- * @file
- * PCI related functions needed by the EHCI driver.
- */
-
-#include <errno.h>
-#include <str_error.h>
-#include <assert.h>
-#include <as.h>
-#include <devman.h>
-#include <ddi.h>
-#include <libarch/ddi.h>
-#include <device/hw_res.h>
-
-#include <usb/debug.h>
-#include <pci_dev_iface.h>
-
-#include "pci.h"
-
-#define PAGE_SIZE_MASK 0xfffff000
-
-#define HCC_PARAMS_OFFSET 0x8
-#define HCC_PARAMS_EECP_MASK 0xff
-#define HCC_PARAMS_EECP_OFFSET 8
-
-#define CMD_OFFSET 0x0
-#define STS_OFFSET 0x4
-#define INT_OFFSET 0x8
-#define CFG_OFFSET 0x40
-
-#define USBCMD_RUN 1
-#define USBSTS_HALTED (1 << 12)
-
-#define USBLEGSUP_OFFSET 0
-#define USBLEGSUP_BIOS_CONTROL (1 << 16)
-#define USBLEGSUP_OS_CONTROL (1 << 24)
-#define USBLEGCTLSTS_OFFSET 4
-
-#define DEFAULT_WAIT 1000
-#define WAIT_STEP 10
-
-#define PCI_READ(size) \
-do { \
-	async_sess_t *parent_sess = \
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle, \
-	    IPC_FLAG_BLOCKING); \
-	if (!parent_sess) \
-		return ENOMEM; \
-	\
-	sysarg_t add = (sysarg_t) address; \
-	sysarg_t val; \
-	\
-	async_exch_t *exch = async_exchange_begin(parent_sess); \
-	\
-	const int ret = \
-	    async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE), \
-	        IPC_M_CONFIG_SPACE_READ_##size, add, &val); \
-	\
-	async_exchange_end(exch); \
-	async_hangup(parent_sess); \
-	\
-	assert(value); \
-	\
-	*value = val; \
-	return ret; \
-} while (0)
-
-static int pci_read32(const ddf_dev_t *dev, int address, uint32_t *value)
-{
-	PCI_READ(32);
-}
-
-static int pci_read16(const ddf_dev_t *dev, int address, uint16_t *value)
-{
-	PCI_READ(16);
-}
-
-static int pci_read8(const ddf_dev_t *dev, int address, uint8_t *value)
-{
-	PCI_READ(8);
-}
-
-#define PCI_WRITE(size) \
-do { \
-	async_sess_t *parent_sess = \
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle, \
-	    IPC_FLAG_BLOCKING); \
-	if (!parent_sess) \
-		return ENOMEM; \
-	\
-	sysarg_t add = (sysarg_t) address; \
-	sysarg_t val = value; \
-	\
-	async_exch_t *exch = async_exchange_begin(parent_sess); \
-	\
-	const int ret = \
-	    async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE), \
-	        IPC_M_CONFIG_SPACE_WRITE_##size, add, val); \
-	\
-	async_exchange_end(exch); \
-	async_hangup(parent_sess); \
-	\
-	return ret; \
-} while(0)
-
-static int pci_write32(const ddf_dev_t *dev, int address, uint32_t value)
-{
-	PCI_WRITE(32);
-}
-
-static int pci_write16(const ddf_dev_t *dev, int address, uint16_t value)
-{
-	PCI_WRITE(16);
-}
-
-static int pci_write8(const ddf_dev_t *dev, int address, uint8_t value)
-{
-	PCI_WRITE(8);
-}
-
-/** Get address of registers and IRQ for given device.
- *
- * @param[in] dev Device asking for the addresses.
- * @param[out] mem_reg_address Base address of the memory range.
- * @param[out] mem_reg_size Size of the memory range.
- * @param[out] irq_no IRQ assigned to the device.
- * @return Error code.
- */
-int pci_get_my_registers(const ddf_dev_t *dev,
-    uintptr_t *mem_reg_address, size_t *mem_reg_size, int *irq_no)
-{
-	assert(dev != NULL);
-	
-	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
-	    IPC_FLAG_BLOCKING);
-	if (!parent_sess)
-		return ENOMEM;
-	
-	hw_resource_list_t hw_resources;
-	int rc = hw_res_get_resource_list(parent_sess, &hw_resources);
-	if (rc != EOK) {
-		async_hangup(parent_sess);
-		return rc;
-	}
-	
-	uintptr_t mem_address = 0;
-	size_t mem_size = 0;
-	bool mem_found = false;
-	
-	int irq = 0;
-	bool irq_found = false;
-	
-	size_t i;
-	for (i = 0; i < hw_resources.count; i++) {
-		hw_resource_t *res = &hw_resources.resources[i];
-		switch (res->type) {
-		case INTERRUPT:
-			irq = res->res.interrupt.irq;
-			irq_found = true;
-			usb_log_debug2("Found interrupt: %d.\n", irq);
-			break;
-		case MEM_RANGE:
-			if (res->res.mem_range.address != 0
-			    && res->res.mem_range.size != 0 ) {
-				mem_address = res->res.mem_range.address;
-				mem_size = res->res.mem_range.size;
-				usb_log_debug2("Found mem: %" PRIxn" %zu.\n",
-				    mem_address, mem_size);
-				mem_found = true;
-			}
-		default:
-			break;
-		}
-	}
-	
-	if (mem_found && irq_found) {
-		*mem_reg_address = mem_address;
-		*mem_reg_size = mem_size;
-		*irq_no = irq;
-		rc = EOK;
-	} else {
-		rc = ENOENT;
-	}
-	
-	async_hangup(parent_sess);
-	return rc;
-}
-/*----------------------------------------------------------------------------*/
-/** Calls the PCI driver with a request to enable interrupts
- *
- * @param[in] device Device asking for interrupts
- * @return Error code.
- */
-int pci_enable_interrupts(const ddf_dev_t *device)
-{
-	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
-	    IPC_FLAG_BLOCKING);
-	if (!parent_sess)
-		return ENOMEM;
-	
-	const bool enabled = hw_res_enable_interrupt(parent_sess);
-	async_hangup(parent_sess);
-	
-	return enabled ? EOK : EIO;
-}
-/*----------------------------------------------------------------------------*/
-/** Implements BIOS handoff routine as decribed in EHCI spec
- *
- * @param[in] device Device asking for interrupts
- * @return Error code.
- */
-int pci_disable_legacy(
-    const ddf_dev_t *device, uintptr_t reg_base, size_t reg_size, int irq)
-{
-	assert(device);
-	(void) pci_read16;
-	(void) pci_read8;
-	(void) pci_write16;
-
-#define CHECK_RET_RETURN(ret, message...) \
-	if (ret != EOK) { \
-		usb_log_error(message); \
-		return ret; \
-	} else (void)0
-
-	/* Map EHCI registers */
-	void *regs = NULL;
-	int ret = pio_enable((void*)reg_base, reg_size, &regs);
-	CHECK_RET_RETURN(ret, "Failed to map registers %p: %s.\n",
-	    (void *) reg_base, str_error(ret));
-
-	const uint32_t hcc_params =
-	    *(uint32_t*)(regs + HCC_PARAMS_OFFSET);
-	usb_log_debug("Value of hcc params register: %x.\n", hcc_params);
-
-	/* Read value of EHCI Extended Capabilities Pointer
-	 * position of EEC registers (points to PCI config space) */
-	const uint32_t eecp =
-	    (hcc_params >> HCC_PARAMS_EECP_OFFSET) & HCC_PARAMS_EECP_MASK;
-	usb_log_debug("Value of EECP: %x.\n", eecp);
-
-	/* Read the first EEC. i.e. Legacy Support register */
-	uint32_t usblegsup;
-	ret = pci_read32(device, eecp + USBLEGSUP_OFFSET, &usblegsup);
-	CHECK_RET_RETURN(ret, "Failed to read USBLEGSUP: %s.\n", str_error(ret));
-	usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup);
-
-	/* Request control from firmware/BIOS, by writing 1 to highest byte.
-	 * (OS Control semaphore)*/
-	usb_log_debug("Requesting OS control.\n");
-	ret = pci_write8(device, eecp + USBLEGSUP_OFFSET + 3, 1);
-	CHECK_RET_RETURN(ret, "Failed to request OS EHCI control: %s.\n",
-	    str_error(ret));
-
-	size_t wait = 0;
-	/* Wait for BIOS to release control. */
-	ret = pci_read32(device, eecp + USBLEGSUP_OFFSET, &usblegsup);
-	while ((wait < DEFAULT_WAIT) && (usblegsup & USBLEGSUP_BIOS_CONTROL)) {
-		async_usleep(WAIT_STEP);
-		ret = pci_read32(device, eecp + USBLEGSUP_OFFSET, &usblegsup);
-		wait += WAIT_STEP;
-	}
-
-
-	if ((usblegsup & USBLEGSUP_BIOS_CONTROL) == 0) {
-		usb_log_info("BIOS released control after %zu usec.\n", wait);
-	} else {
-		/* BIOS failed to hand over control, this should not happen. */
-		usb_log_warning( "BIOS failed to release control after "
-		    "%zu usecs, force it.\n", wait);
-		ret = pci_write32(device, eecp + USBLEGSUP_OFFSET,
-		    USBLEGSUP_OS_CONTROL);
-		CHECK_RET_RETURN(ret, "Failed to force OS control: %s.\n",
-		    str_error(ret));
-		/* Check capability type here, A value of 01h
-		 * identifies the capability as Legacy Support.
-		 * This extended capability requires one
-		 * additional 32-bit register for control/status information,
-		 * and this register is located at offset EECP+04h
-		 * */
-		if ((usblegsup & 0xff) == 1) {
-			/* Read the second EEC
-			 * Legacy Support and Control register */
-			uint32_t usblegctlsts;
-			ret = pci_read32(
-			    device, eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts);
-			CHECK_RET_RETURN(ret,
-			    "Failed to get USBLEGCTLSTS: %s.\n", str_error(ret));
-			usb_log_debug("USBLEGCTLSTS: %" PRIx32 ".\n",
-			    usblegctlsts);
-			/* Zero SMI enables in legacy control register.
-			 * It should prevent pre-OS code from interfering. */
-			ret = pci_write32(device, eecp + USBLEGCTLSTS_OFFSET,
-			    0xe0000000); /* three upper bits are WC */
-			CHECK_RET_RETURN(ret,
-			    "Failed(%d) zero USBLEGCTLSTS.\n", ret);
-			udelay(10);
-			ret = pci_read32(
-			    device, eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts);
-			CHECK_RET_RETURN(ret,
-			    "Failed to get USBLEGCTLSTS 2: %s.\n",
-			    str_error(ret));
-			usb_log_debug("Zeroed USBLEGCTLSTS: %" PRIx32 ".\n",
-			    usblegctlsts);
-		}
-	}
-
-
-	/* Read again Legacy Support register */
-	ret = pci_read32(device, eecp + USBLEGSUP_OFFSET, &usblegsup);
-	CHECK_RET_RETURN(ret, "Failed to read USBLEGSUP: %s.\n", str_error(ret));
-	usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup);
-
-	/*
-	 * TURN OFF EHCI FOR NOW, DRIVER WILL REINITIALIZE IT
-	 */
-
-	/* Get size of capability registers in memory space. */
-	const unsigned operation_offset = *(uint8_t*)regs;
-	usb_log_debug("USBCMD offset: %d.\n", operation_offset);
-
-	/* Zero USBCMD register. */
-	volatile uint32_t *usbcmd =
-	    (uint32_t*)((uint8_t*)regs + operation_offset + CMD_OFFSET);
-	volatile uint32_t *usbsts =
-	    (uint32_t*)((uint8_t*)regs + operation_offset + STS_OFFSET);
-	volatile uint32_t *usbconf =
-	    (uint32_t*)((uint8_t*)regs + operation_offset + CFG_OFFSET);
-	volatile uint32_t *usbint =
-	    (uint32_t*)((uint8_t*)regs + operation_offset + INT_OFFSET);
-	usb_log_debug("USBCMD value: %x.\n", *usbcmd);
-	if (*usbcmd & USBCMD_RUN) {
-		*usbsts = 0x3f; /* ack all interrupts */
-		*usbint = 0; /* disable all interrutps */
-		*usbconf = 0; /* relase control of RH ports */
-
-		*usbcmd = 0;
-		/* Wait until hc is halted */
-		while ((*usbsts & USBSTS_HALTED) == 0);
-		usb_log_info("EHCI turned off.\n");
-	} else {
-		usb_log_info("EHCI was not running.\n");
-	}
-	usb_log_debug("Registers: \n"
-	    "\t USBCMD: %x(0x00080000 = at least 1ms between interrupts)\n"
-	    "\t USBSTS: %x(0x00001000 = HC halted)\n"
-	    "\t USBINT: %x(0x0 = no interrupts).\n"
-	    "\t CONFIG: %x(0x0 = ports controlled by companion hc).\n",
-	    *usbcmd, *usbsts, *usbint, *usbconf);
-
-	return ret;
-#undef CHECK_RET_RETURN
-}
-
-/**
- * @}
- */
Index: pace/drv/bus/usb/ehci/pci.h
===================================================================
--- uspace/drv/bus/usb/ehci/pci.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * 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 drvusbehci
- * @{
- */
-/** @file
- * PCI related functions needed by EHCI driver.
- */
-#ifndef DRV_EHCI_PCI_H
-#define DRV_EHCI_PCI_H
-
-#include <ddf/driver.h>
-
-int pci_get_my_registers(const ddf_dev_t *, uintptr_t *, size_t *, int *);
-int pci_enable_interrupts(const ddf_dev_t *);
-int pci_disable_legacy(const ddf_dev_t *, uintptr_t, size_t, int);
-
-#endif
-/**
- * @}
- */
-
Index: uspace/drv/bus/usb/ehci/res.c
===================================================================
--- uspace/drv/bus/usb/ehci/res.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/drv/bus/usb/ehci/res.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * 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 drvusbehci
+ * @{
+ */
+/**
+ * @file
+ * PCI related functions needed by the EHCI driver.
+ */
+
+#include <errno.h>
+#include <str_error.h>
+#include <assert.h>
+#include <devman.h>
+#include <ddi.h>
+#include <usb/debug.h>
+#include <device/hw_res_parsed.h>
+#include <device/pci.h>
+
+#include "res.h"
+
+#define HCC_PARAMS_OFFSET 0x8
+#define HCC_PARAMS_EECP_MASK 0xff
+#define HCC_PARAMS_EECP_OFFSET 8
+
+#define CMD_OFFSET 0x0
+#define STS_OFFSET 0x4
+#define INT_OFFSET 0x8
+#define CFG_OFFSET 0x40
+
+#define USBCMD_RUN 1
+#define USBSTS_HALTED (1 << 12)
+
+#define USBLEGSUP_OFFSET 0
+#define USBLEGSUP_BIOS_CONTROL (1 << 16)
+#define USBLEGSUP_OS_CONTROL (1 << 24)
+#define USBLEGCTLSTS_OFFSET 4
+
+#define DEFAULT_WAIT 1000
+#define WAIT_STEP 10
+
+
+/** Get address of registers and IRQ for given device.
+ *
+ * @param[in] dev Device asking for the addresses.
+ * @param[out] mem_reg_address Base address of the memory range.
+ * @param[out] mem_reg_size Size of the memory range.
+ * @param[out] irq_no IRQ assigned to the device.
+ * @return Error code.
+ */
+int get_my_registers(const ddf_dev_t *dev,
+    uintptr_t *mem_reg_address, size_t *mem_reg_size, int *irq_no)
+{
+	assert(dev);
+	
+	async_sess_t *parent_sess = devman_parent_device_connect(
+	    EXCHANGE_SERIALIZE, dev->handle, IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+	
+	hw_res_list_parsed_t hw_res;
+	hw_res_list_parsed_init(&hw_res);
+	const int ret = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
+	async_hangup(parent_sess);
+	if (ret != EOK) {
+		return ret;
+	}
+
+	if (hw_res.irqs.count != 1 || hw_res.mem_ranges.count != 1) {
+		hw_res_list_parsed_clean(&hw_res);
+		return ENOENT;
+	}
+
+	if (mem_reg_address)
+		*mem_reg_address = hw_res.mem_ranges.ranges[0].address;
+	if (mem_reg_size)
+		*mem_reg_size = hw_res.mem_ranges.ranges[0].size;
+	if (irq_no)
+		*irq_no = hw_res.irqs.irqs[0];
+
+	hw_res_list_parsed_clean(&hw_res);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+/** Calls the PCI driver with a request to enable interrupts
+ *
+ * @param[in] device Device asking for interrupts
+ * @return Error code.
+ */
+int enable_interrupts(const ddf_dev_t *device)
+{
+	async_sess_t *parent_sess = devman_parent_device_connect(
+	    EXCHANGE_SERIALIZE, device->handle, IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+	
+	const bool enabled = hw_res_enable_interrupt(parent_sess);
+	async_hangup(parent_sess);
+	
+	return enabled ? EOK : EIO;
+}
+/*----------------------------------------------------------------------------*/
+/** Implements BIOS hands-off routine as described in EHCI spec
+ *
+ * @param device EHCI device
+ * @param eecp Value of EHCI Extended Capabilities pointer.
+ * @return Error code.
+ */
+static int disable_extended_caps(const ddf_dev_t *device, unsigned eecp)
+{
+	/* nothing to do */
+	if (eecp == 0)
+		return EOK;
+
+	async_sess_t *parent_sess = devman_parent_device_connect(
+	    EXCHANGE_SERIALIZE, device->handle, IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+
+#define CHECK_RET_HANGUP_RETURN(ret, message...) \
+	if (ret != EOK) { \
+		usb_log_error(message); \
+		async_hangup(parent_sess); \
+		return ret; \
+	} else (void)0
+
+	/* Read the first EEC. i.e. Legacy Support register */
+	uint32_t usblegsup;
+	int ret = pci_config_space_read_32(parent_sess,
+	    eecp + USBLEGSUP_OFFSET, &usblegsup);
+	CHECK_RET_HANGUP_RETURN(ret,
+	    "Failed to read USBLEGSUP: %s.\n", str_error(ret));
+	usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup);
+
+	/* Request control from firmware/BIOS by writing 1 to highest
+	 * byte. (OS Control semaphore)*/
+	usb_log_debug("Requesting OS control.\n");
+	ret = pci_config_space_write_8(parent_sess,
+	    eecp + USBLEGSUP_OFFSET + 3, 1);
+	CHECK_RET_HANGUP_RETURN(ret, "Failed to request OS EHCI control: %s.\n",
+	    str_error(ret));
+
+	size_t wait = 0;
+	/* Wait for BIOS to release control. */
+	ret = pci_config_space_read_32(
+	    parent_sess, eecp + USBLEGSUP_OFFSET, &usblegsup);
+	while ((wait < DEFAULT_WAIT) && (usblegsup & USBLEGSUP_BIOS_CONTROL)) {
+		async_usleep(WAIT_STEP);
+		ret = pci_config_space_read_32(parent_sess,
+		    eecp + USBLEGSUP_OFFSET, &usblegsup);
+		wait += WAIT_STEP;
+	}
+
+	if ((usblegsup & USBLEGSUP_BIOS_CONTROL) == 0) {
+		usb_log_info("BIOS released control after %zu usec.\n", wait);
+		async_hangup(parent_sess);
+		return EOK;
+	}
+
+	/* BIOS failed to hand over control, this should not happen. */
+	usb_log_warning( "BIOS failed to release control after "
+	    "%zu usecs, force it.\n", wait);
+	ret = pci_config_space_write_32(parent_sess,
+	    eecp + USBLEGSUP_OFFSET, USBLEGSUP_OS_CONTROL);
+	CHECK_RET_HANGUP_RETURN(ret, "Failed to force OS control: "
+	    "%s.\n", str_error(ret));
+	/*
+	 * Check capability type here, value of 01h identifies the capability
+	 * as Legacy Support. This extended capability requires one additional
+	 * 32-bit register for control/status information and this register is
+	 * located at offset EECP+04h
+	 */
+	if ((usblegsup & 0xff) == 1) {
+		/* Read the second EEC Legacy Support and Control register */
+		uint32_t usblegctlsts;
+		ret = pci_config_space_read_32(parent_sess,
+		    eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts);
+		CHECK_RET_HANGUP_RETURN(ret, "Failed to get USBLEGCTLSTS: %s.\n",
+		    str_error(ret));
+		usb_log_debug("USBLEGCTLSTS: %" PRIx32 ".\n", usblegctlsts);
+		/*
+		 * Zero SMI enables in legacy control register.
+		 * It should prevent pre-OS code from
+		 * interfering. NOTE: Three upper bits are WC
+		 */
+		ret = pci_config_space_write_32(parent_sess,
+		    eecp + USBLEGCTLSTS_OFFSET, 0xe0000000);
+		CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) zero USBLEGCTLSTS.\n", ret);
+		udelay(10);
+		ret = pci_config_space_read_32(parent_sess,
+		    eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts);
+		CHECK_RET_HANGUP_RETURN(ret, "Failed to get USBLEGCTLSTS 2: %s.\n",
+		    str_error(ret));
+		usb_log_debug("Zeroed USBLEGCTLSTS: %" PRIx32 ".\n",
+		    usblegctlsts);
+	}
+
+	/* Read again Legacy Support register */
+	ret = pci_config_space_read_32(parent_sess,
+	    eecp + USBLEGSUP_OFFSET, &usblegsup);
+	CHECK_RET_HANGUP_RETURN(ret, "Failed to read USBLEGSUP: %s.\n",
+	    str_error(ret));
+	usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup);
+	async_hangup(parent_sess);
+	return EOK;
+#undef CHECK_RET_HANGUP_RETURN
+}
+
+int disable_legacy(const ddf_dev_t *device, uintptr_t reg_base, size_t reg_size)
+{
+	assert(device);
+
+#define CHECK_RET_RETURN(ret, message...) \
+	if (ret != EOK) { \
+		usb_log_error(message); \
+		return ret; \
+	} else (void)0
+
+	/* Map EHCI registers */
+	void *regs = NULL;
+	int ret = pio_enable((void*)reg_base, reg_size, &regs);
+	CHECK_RET_RETURN(ret, "Failed to map registers %p: %s.\n",
+	    (void *) reg_base, str_error(ret));
+
+	const uint32_t hcc_params =
+	    *(uint32_t*)(regs + HCC_PARAMS_OFFSET);
+	usb_log_debug("Value of hcc params register: %x.\n", hcc_params);
+
+	/* Read value of EHCI Extended Capabilities Pointer
+	 * position of EEC registers (points to PCI config space) */
+	const uint32_t eecp =
+	    (hcc_params >> HCC_PARAMS_EECP_OFFSET) & HCC_PARAMS_EECP_MASK;
+	usb_log_debug("Value of EECP: %x.\n", eecp);
+
+	ret = disable_extended_caps(device, eecp);
+	CHECK_RET_RETURN(ret, "Failed to disable extended capabilities: %s.\n",
+	    str_error(ret));
+
+#undef CHECK_RET_RETURN
+
+	/*
+	 * TURN OFF EHCI FOR NOW, DRIVER WILL REINITIALIZE IT IF NEEDED
+	 */
+
+	/* Get size of capability registers in memory space. */
+	const unsigned operation_offset = *(uint8_t*)regs;
+	usb_log_debug("USBCMD offset: %d.\n", operation_offset);
+
+	/* Zero USBCMD register. */
+	volatile uint32_t *usbcmd =
+	    (uint32_t*)((uint8_t*)regs + operation_offset + CMD_OFFSET);
+	volatile uint32_t *usbsts =
+	    (uint32_t*)((uint8_t*)regs + operation_offset + STS_OFFSET);
+	volatile uint32_t *usbconf =
+	    (uint32_t*)((uint8_t*)regs + operation_offset + CFG_OFFSET);
+	volatile uint32_t *usbint =
+	    (uint32_t*)((uint8_t*)regs + operation_offset + INT_OFFSET);
+	usb_log_debug("USBCMD value: %x.\n", *usbcmd);
+	if (*usbcmd & USBCMD_RUN) {
+		*usbsts = 0x3f; /* ack all interrupts */
+		*usbint = 0; /* disable all interrutps */
+		*usbconf = 0; /* relase control of RH ports */
+
+		*usbcmd = 0;
+		/* Wait until hc is halted */
+		while ((*usbsts & USBSTS_HALTED) == 0);
+		usb_log_info("EHCI turned off.\n");
+	} else {
+		usb_log_info("EHCI was not running.\n");
+	}
+	usb_log_debug("Registers: \n"
+	    "\t USBCMD: %x(0x00080000 = at least 1ms between interrupts)\n"
+	    "\t USBSTS: %x(0x00001000 = HC halted)\n"
+	    "\t USBINT: %x(0x0 = no interrupts).\n"
+	    "\t CONFIG: %x(0x0 = ports controlled by companion hc).\n",
+	    *usbcmd, *usbsts, *usbint, *usbconf);
+
+	return ret;
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/bus/usb/ehci/res.h
===================================================================
--- uspace/drv/bus/usb/ehci/res.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/drv/bus/usb/ehci/res.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,48 @@
+/*
+ * 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 drvusbehci
+ * @{
+ */
+/** @file
+ * PCI related functions needed by EHCI driver.
+ */
+#ifndef DRV_EHCI_PCI_H
+#define DRV_EHCI_PCI_H
+
+#include <ddf/driver.h>
+
+int get_my_registers(const ddf_dev_t *, uintptr_t *, size_t *, int *);
+int enable_interrupts(const ddf_dev_t *);
+int disable_legacy(const ddf_dev_t *, uintptr_t, size_t);
+
+#endif
+/**
+ * @}
+ */
+
Index: uspace/drv/bus/usb/ohci/Makefile
===================================================================
--- uspace/drv/bus/usb/ohci/Makefile	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/drv/bus/usb/ohci/Makefile	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -50,5 +50,5 @@
 	ohci_batch.c \
 	ohci_endpoint.c \
-	pci.c \
+	res.c \
 	root_hub.c \
 	hw_struct/endpoint_descriptor.c \
Index: uspace/drv/bus/usb/ohci/hw_struct/hcca.h
===================================================================
--- uspace/drv/bus/usb/ohci/hw_struct/hcca.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/drv/bus/usb/ohci/hw_struct/hcca.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -46,6 +46,6 @@
 	uint16_t pad1;
 	uint32_t done_head;
-	uint32_t reserved[29];
-} __attribute__((packed, aligned)) hcca_t;
+	uint32_t reserved[30];
+} hcca_t;
 
 static inline void * hcca_get(void)
Index: uspace/drv/bus/usb/ohci/ohci.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/drv/bus/usb/ohci/ohci.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -42,5 +42,5 @@
 
 #include "ohci.h"
-#include "pci.h"
+#include "res.h"
 #include "hc.h"
 
@@ -180,5 +180,5 @@
 	int irq = 0;
 
-	ret = pci_get_my_registers(device, &reg_base, &reg_size, &irq);
+	ret = get_my_registers(device, &reg_base, &reg_size, &irq);
 	CHECK_RET_DEST_FREE_RETURN(ret,
 	    "Failed to get register memory addresses for %" PRIun ": %s.\n",
@@ -211,5 +211,5 @@
 	/* Try to enable interrupts */
 	bool interrupts = false;
-	ret = pci_enable_interrupts(device);
+	ret = enable_interrupts(device);
 	if (ret != EOK) {
 		usb_log_warning("Failed to enable interrupts: %s."
Index: pace/drv/bus/usb/ohci/pci.c
===================================================================
--- uspace/drv/bus/usb/ohci/pci.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ 	(revision )
@@ -1,116 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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 drvusbohci
- * @{
- */
-/**
- * @file
- * PCI related functions needed by the OHCI driver.
- */
-
-#include <errno.h>
-#include <assert.h>
-#include <as.h>
-#include <devman.h>
-#include <ddi.h>
-#include <libarch/ddi.h>
-#include <device/hw_res_parsed.h>
-
-#include <usb/debug.h>
-#include <pci_dev_iface.h>
-
-#include "pci.h"
-
-/** Get address of registers and IRQ for given device.
- *
- * @param[in] dev Device asking for the addresses.
- * @param[out] mem_reg_address Base address of the memory range.
- * @param[out] mem_reg_size Size of the memory range.
- * @param[out] irq_no IRQ assigned to the device.
- * @return Error code.
- */
-int pci_get_my_registers(ddf_dev_t *dev,
-    uintptr_t *mem_reg_address, size_t *mem_reg_size, int *irq_no)
-{
-	assert(dev);
-
-	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
-	    IPC_FLAG_BLOCKING);
-	if (!parent_sess)
-		return ENOMEM;
-
-	hw_res_list_parsed_t hw_res;
-	hw_res_list_parsed_init(&hw_res);
-	const int ret =  hw_res_get_list_parsed(parent_sess, &hw_res, 0);
-	async_hangup(parent_sess);
-	if (ret != EOK) {
-		return ret;
-	}
-
-	/* We want one irq and one mem range. */
-	if (hw_res.irqs.count != 1 || hw_res.mem_ranges.count != 1) {
-		hw_res_list_parsed_clean(&hw_res);
-		return EINVAL;
-	}
-
-	if (mem_reg_address)
-		*mem_reg_address = hw_res.mem_ranges.ranges[0].address;
-	if (mem_reg_size)
-		*mem_reg_size = hw_res.mem_ranges.ranges[0].size;
-	if (irq_no)
-		*irq_no = hw_res.irqs.irqs[0];
-
-	hw_res_list_parsed_clean(&hw_res);
-	return EOK;
-}
-
-/** Call the PCI driver with a request to enable interrupts
- *
- * @param[in] device Device asking for interrupts
- * @return Error code.
- */
-int pci_enable_interrupts(ddf_dev_t *device)
-{
-	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
-	    IPC_FLAG_BLOCKING);
-	if (!parent_sess)
-		return ENOMEM;
-	
-	bool enabled = hw_res_enable_interrupt(parent_sess);
-	async_hangup(parent_sess);
-	
-	return enabled ? EOK : EIO;
-}
-
-/**
- * @}
- */
Index: pace/drv/bus/usb/ohci/pci.h
===================================================================
--- uspace/drv/bus/usb/ohci/pci.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ 	(revision )
@@ -1,47 +1,0 @@
-/*
- * 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 drvusbohci
- * @{
- */
-/** @file
- * PCI related functions needed by OHCI driver.
- */
-#ifndef DRV_OHCI_PCI_H
-#define DRV_OHCI_PCI_H
-
-#include <ddf/driver.h>
-
-int pci_get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *);
-int pci_enable_interrupts(ddf_dev_t *);
-int pci_disable_legacy(ddf_dev_t *);
-
-#endif
-/**
- * @}
- */
-
Index: uspace/drv/bus/usb/ohci/res.c
===================================================================
--- uspace/drv/bus/usb/ohci/res.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/drv/bus/usb/ohci/res.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * 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 drvusbohci
+ * @{
+ */
+/**
+ * @file
+ * PCI related functions needed by the OHCI driver.
+ */
+
+#include <errno.h>
+#include <assert.h>
+#include <devman.h>
+#include <device/hw_res_parsed.h>
+
+#include <usb/debug.h>
+
+#include "res.h"
+
+/** Get address of registers and IRQ for given device.
+ *
+ * @param[in] dev Device asking for the addresses.
+ * @param[out] mem_reg_address Base address of the memory range.
+ * @param[out] mem_reg_size Size of the memory range.
+ * @param[out] irq_no IRQ assigned to the device.
+ * @return Error code.
+ */
+int get_my_registers(const ddf_dev_t *dev,
+    uintptr_t *mem_reg_address, size_t *mem_reg_size, int *irq_no)
+{
+	assert(dev);
+
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
+	    IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+
+	hw_res_list_parsed_t hw_res;
+	hw_res_list_parsed_init(&hw_res);
+	const int ret =  hw_res_get_list_parsed(parent_sess, &hw_res, 0);
+	async_hangup(parent_sess);
+	if (ret != EOK) {
+		return ret;
+	}
+
+	/* We want one irq and one mem range. */
+	if (hw_res.irqs.count != 1 || hw_res.mem_ranges.count != 1) {
+		hw_res_list_parsed_clean(&hw_res);
+		return EINVAL;
+	}
+
+	if (mem_reg_address)
+		*mem_reg_address = hw_res.mem_ranges.ranges[0].address;
+	if (mem_reg_size)
+		*mem_reg_size = hw_res.mem_ranges.ranges[0].size;
+	if (irq_no)
+		*irq_no = hw_res.irqs.irqs[0];
+
+	hw_res_list_parsed_clean(&hw_res);
+	return EOK;
+}
+
+/** Call the PCI driver with a request to enable interrupts
+ *
+ * @param[in] device Device asking for interrupts
+ * @return Error code.
+ */
+int enable_interrupts(const ddf_dev_t *device)
+{
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
+	    IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+	
+	const bool enabled = hw_res_enable_interrupt(parent_sess);
+	async_hangup(parent_sess);
+	
+	return enabled ? EOK : EIO;
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/bus/usb/ohci/res.h
===================================================================
--- uspace/drv/bus/usb/ohci/res.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/drv/bus/usb/ohci/res.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,46 @@
+/*
+ * 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 drvusbohci
+ * @{
+ */
+/** @file
+ * PCI related functions needed by OHCI driver.
+ */
+#ifndef DRV_OHCI_RES_H
+#define DRV_OHCI_RES_H
+
+#include <ddf/driver.h>
+
+int get_my_registers(const ddf_dev_t *, uintptr_t *, size_t *, int *);
+int enable_interrupts(const ddf_dev_t *);
+
+#endif
+/**
+ * @}
+ */
+
Index: uspace/drv/bus/usb/uhci/Makefile
===================================================================
--- uspace/drv/bus/usb/uhci/Makefile	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/drv/bus/usb/uhci/Makefile	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -44,5 +44,5 @@
 	hc.c \
 	main.c \
-	pci.c \
+	res.c \
 	root_hub.c \
 	transfer_list.c \
Index: pace/drv/bus/usb/uhci/pci.c
===================================================================
--- uspace/drv/bus/usb/uhci/pci.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ 	(revision )
@@ -1,146 +1,0 @@
-/*
- * 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 drvusbuhcihc
- * @{
- */
-/**
- * @file
- * PCI related functions needed by the UHCI driver.
- */
-
-#include <errno.h>
-#include <assert.h>
-#include <devman.h>
-#include <device/hw_res_parsed.h>
-
-#include <usb/debug.h>
-#include <pci_dev_iface.h>
-
-#include "pci.h"
-
-/** Get I/O address of registers and IRQ for given device.
- *
- * @param[in] dev Device asking for the addresses.
- * @param[out] io_reg_address Base address of the I/O range.
- * @param[out] io_reg_size Size of the I/O range.
- * @param[out] irq_no IRQ assigned to the device.
- * @return Error code.
- */
-int pci_get_my_registers(const ddf_dev_t *dev,
-    uintptr_t *io_reg_address, size_t *io_reg_size, int *irq_no)
-{
-	assert(dev);
-	assert(io_reg_address);
-	assert(io_reg_size);
-	assert(irq_no);
-
-	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
-	    IPC_FLAG_BLOCKING);
-	if (!parent_sess)
-		return ENOMEM;
-
-	hw_res_list_parsed_t hw_res;
-	hw_res_list_parsed_init(&hw_res);
-	const int ret =  hw_res_get_list_parsed(parent_sess, &hw_res, 0);
-	async_hangup(parent_sess);
-	if (ret != EOK) {
-		return ret;
-	}
-
-	/* We want one irq and one io range. */
-	if (hw_res.irqs.count != 1 || hw_res.io_ranges.count != 1) {
-		hw_res_list_parsed_clean(&hw_res);
-		return EINVAL;
-	}
-
-	if (io_reg_address)
-		*io_reg_address = hw_res.io_ranges.ranges[0].address;
-	if (io_reg_size)
-		*io_reg_size = hw_res.io_ranges.ranges[0].size;
-	if (irq_no)
-		*irq_no = hw_res.irqs.irqs[0];
-
-	hw_res_list_parsed_clean(&hw_res);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-/** Call the PCI driver with a request to enable interrupts
- *
- * @param[in] device Device asking for interrupts
- * @return Error code.
- */
-int pci_enable_interrupts(const ddf_dev_t *device)
-{
-	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
-	    IPC_FLAG_BLOCKING);
-	if (!parent_sess)
-		return ENOMEM;
-
-	const bool enabled = hw_res_enable_interrupt(parent_sess);
-	async_hangup(parent_sess);
-
-	return enabled ? EOK : EIO;
-}
-/*----------------------------------------------------------------------------*/
-/** Call the PCI driver with a request to clear legacy support register
- *
- * @param[in] device Device asking to disable interrupts
- * @return Error code.
- */
-int pci_disable_legacy(const ddf_dev_t *device)
-{
-	assert(device);
-
-	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
-	    IPC_FLAG_BLOCKING);
-	if (!parent_sess)
-		return ENOMEM;
-
-	/* See UHCI design guide for these values p.45,
-	 * write all WC bits in USB legacy register */
-	const sysarg_t address = 0xc0;
-	const sysarg_t value = 0xaf00;
-
-	async_exch_t *exch = async_exchange_begin(parent_sess);
-
-	const int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
-	    IPC_M_CONFIG_SPACE_WRITE_16, address, value);
-
-	async_exchange_end(exch);
-	async_hangup(parent_sess);
-
-	return rc;
-}
-
-/**
- * @}
- */
Index: pace/drv/bus/usb/uhci/pci.h
===================================================================
--- uspace/drv/bus/usb/uhci/pci.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * Copyright (c) 2010 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 drvusbuhcihc
- * @{
- */
-/** @file
- * @brief UHCI driver PCI helper functions
- */
-#ifndef DRV_UHCI_PCI_H
-#define DRV_UHCI_PCI_H
-
-#include <ddf/driver.h>
-
-int pci_get_my_registers(const ddf_dev_t *, uintptr_t *, size_t *, int *);
-int pci_enable_interrupts(const ddf_dev_t *);
-int pci_disable_legacy(const ddf_dev_t *);
-
-#endif
-/**
- * @}
- */
-
Index: uspace/drv/bus/usb/uhci/res.c
===================================================================
--- uspace/drv/bus/usb/uhci/res.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/drv/bus/usb/uhci/res.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,132 @@
+/*
+ * 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 drvusbuhcihc
+ * @{
+ */
+/**
+ * @file
+ * PCI related functions needed by the UHCI driver.
+ */
+
+#include <errno.h>
+#include <assert.h>
+#include <devman.h>
+#include <device/hw_res_parsed.h>
+#include <device/pci.h>
+
+#include "res.h"
+
+/** Get I/O address of registers and IRQ for given device.
+ *
+ * @param[in] dev Device asking for the addresses.
+ * @param[out] io_reg_address Base address of the I/O range.
+ * @param[out] io_reg_size Size of the I/O range.
+ * @param[out] irq_no IRQ assigned to the device.
+ * @return Error code.
+ */
+int get_my_registers(const ddf_dev_t *dev,
+    uintptr_t *io_reg_address, size_t *io_reg_size, int *irq_no)
+{
+	assert(dev);
+
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
+	    IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+
+	hw_res_list_parsed_t hw_res;
+	hw_res_list_parsed_init(&hw_res);
+	const int ret =  hw_res_get_list_parsed(parent_sess, &hw_res, 0);
+	async_hangup(parent_sess);
+	if (ret != EOK) {
+		return ret;
+	}
+
+	/* We want one irq and one io range. */
+	if (hw_res.irqs.count != 1 || hw_res.io_ranges.count != 1) {
+		hw_res_list_parsed_clean(&hw_res);
+		return EINVAL;
+	}
+
+	if (io_reg_address)
+		*io_reg_address = hw_res.io_ranges.ranges[0].address;
+	if (io_reg_size)
+		*io_reg_size = hw_res.io_ranges.ranges[0].size;
+	if (irq_no)
+		*irq_no = hw_res.irqs.irqs[0];
+
+	hw_res_list_parsed_clean(&hw_res);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+/** Call the PCI driver with a request to enable interrupts
+ *
+ * @param[in] device Device asking for interrupts
+ * @return Error code.
+ */
+int enable_interrupts(const ddf_dev_t *device)
+{
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
+	    IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+
+	const bool enabled = hw_res_enable_interrupt(parent_sess);
+	async_hangup(parent_sess);
+
+	return enabled ? EOK : EIO;
+}
+/*----------------------------------------------------------------------------*/
+/** Call the PCI driver with a request to clear legacy support register
+ *
+ * @param[in] device Device asking to disable interrupts
+ * @return Error code.
+ */
+int disable_legacy(const ddf_dev_t *device)
+{
+	assert(device);
+
+	async_sess_t *parent_sess = devman_parent_device_connect(
+	    EXCHANGE_SERIALIZE, device->handle, IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+
+	/* See UHCI design guide page 45 for these values.
+	 * Write all WC bits in USB legacy register */
+	const int rc = pci_config_space_write_16(parent_sess, 0xc0, 0xaf00);
+
+	async_hangup(parent_sess);
+	return rc;
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/bus/usb/uhci/res.h
===================================================================
--- uspace/drv/bus/usb/uhci/res.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/drv/bus/usb/uhci/res.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 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 drvusbuhcihc
+ * @{
+ */
+/** @file
+ * @brief UHCI driver PCI helper functions
+ */
+#ifndef DRV_UHCI_PCI_H
+#define DRV_UHCI_PCI_H
+
+#include <ddf/driver.h>
+
+int get_my_registers(const ddf_dev_t *, uintptr_t *, size_t *, int *);
+int enable_interrupts(const ddf_dev_t *);
+int disable_legacy(const ddf_dev_t *);
+
+#endif
+/**
+ * @}
+ */
+
Index: uspace/drv/bus/usb/uhci/uhci.c
===================================================================
--- uspace/drv/bus/usb/uhci/uhci.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/drv/bus/usb/uhci/uhci.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -41,6 +41,6 @@
 
 #include "uhci.h"
-#include "pci.h"
-
+
+#include "res.h"
 #include "hc.h"
 #include "root_hub.h"
@@ -49,12 +49,12 @@
  * and USB root hub */
 typedef struct uhci {
-	/** Pointer to DDF represenation of UHCI host controller */
+	/** Pointer to DDF representation of UHCI host controller */
 	ddf_fun_t *hc_fun;
-	/** Pointer to DDF represenation of UHCI root hub */
+	/** Pointer to DDF representation of UHCI root hub */
 	ddf_fun_t *rh_fun;
 
-	/** Internal driver's represenation of UHCI host controller */
+	/** Internal driver's representation of UHCI host controller */
 	hc_t hc;
-	/** Internal driver's represenation of UHCI root hub */
+	/** Internal driver's representation of UHCI root hub */
 	rh_t rh;
 } uhci_t;
@@ -187,5 +187,5 @@
 	int irq = 0;
 
-	ret = pci_get_my_registers(device, &reg_base, &reg_size, &irq);
+	ret = get_my_registers(device, &reg_base, &reg_size, &irq);
 	CHECK_RET_DEST_FREE_RETURN(ret,
 	    "Failed to get I/O addresses for %" PRIun ": %s.\n",
@@ -194,5 +194,5 @@
 	    (void *) reg_base, reg_size, irq);
 
-	ret = pci_disable_legacy(device);
+	ret = disable_legacy(device);
 	CHECK_RET_DEST_FREE_RETURN(ret,
 	    "Failed to disable legacy USB: %s.\n", str_error(ret));
@@ -220,5 +220,5 @@
 
 	bool interrupts = false;
-	ret = pci_enable_interrupts(device);
+	ret = enable_interrupts(device);
 	if (ret != EOK) {
 		usb_log_warning("Failed to enable interrupts: %s."
Index: uspace/lib/c/arch/amd64/include/fibril.h
===================================================================
--- uspace/lib/c/arch/amd64/include/fibril.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/arch/amd64/include/fibril.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -38,9 +38,10 @@
 #include <sys/types.h>
 
-/* According to ABI the stack MUST be aligned on 
+/*
+ * According to ABI the stack MUST be aligned on
  * 16-byte boundary. If it is not, the va_arg calling will
  * panic sooner or later
  */
-#define SP_DELTA     16
+#define SP_DELTA  16
 
 #define context_set(c, _pc, stack, size, ptls) \
Index: uspace/lib/c/arch/arm32/include/fibril.h
===================================================================
--- uspace/lib/c/arch/arm32/include/fibril.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/arch/arm32/include/fibril.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup libcarm32	
+/** @addtogroup libcarm32
  * @{
  */
@@ -42,14 +42,14 @@
 
 /** Size of a stack item */
-#define STACK_ITEM_SIZE		4
+#define STACK_ITEM_SIZE  4
 
 /** Stack alignment - see <a href="http://www.arm.com/support/faqdev/14269.html">ABI</a> for details */
-#define STACK_ALIGNMENT		8
+#define STACK_ALIGNMENT  8
 
-#define SP_DELTA	(0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
+#define SP_DELTA  (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
 
 
-/** Sets data to the context. 
- *  
+/** Sets data to the context.
+ *
  *  @param c     Context (#context_t).
  *  @param _pc   Program counter.
@@ -62,9 +62,9 @@
 		(c)->pc = (sysarg_t) (_pc); \
 		(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
- 		(c)->tls = ((sysarg_t)(ptls)) + sizeof(tcb_t) + ARM_TP_OFFSET; \
+		(c)->tls = ((sysarg_t)(ptls)) + sizeof(tcb_t) + ARM_TP_OFFSET; \
 		(c)->fp = 0; \
 	} while (0)
 
-/** Fibril context. 
+/** Fibril context.
  *
  *  Only registers preserved accross function calls are included. r9 is used 
@@ -91,5 +91,4 @@
 }
 
-
 #endif
 
Index: uspace/lib/c/arch/ia32/include/fibril.h
===================================================================
--- uspace/lib/c/arch/ia32/include/fibril.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/arch/ia32/include/fibril.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -38,5 +38,6 @@
 #include <sys/types.h>
 
-/* According to ABI the stack MUST be aligned on 
+/*
+ * According to ABI the stack MUST be aligned on
  * 16-byte boundary. If it is not, the va_arg calling will
  * panic sooner or later
Index: uspace/lib/c/arch/ia64/include/fibril.h
===================================================================
--- uspace/lib/c/arch/ia64/include/fibril.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/arch/ia64/include/fibril.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup libcia64	
+/** @addtogroup libcia64
  * @{
  */
@@ -45,21 +45,24 @@
  * No need to allocate scratch area.
  */
-#define SP_DELTA	(0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
+#define SP_DELTA  (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
 
-#define PFM_MASK        (~0x3fffffffff)
+#define PFM_MASK  (~0x3fffffffff)
 
-#define PSTHREAD_INITIAL_STACK_PAGES_NO 2
+#define PSTHREAD_INITIAL_STACK_PAGES_NO  2
+
 /* Stack is divided into two equal parts (for memory stack and register stack). */
-#define PSTHREAD_INITIAL_STACK_DIVISION 2  
+#define PSTHREAD_INITIAL_STACK_DIVISION  2
 
-#define context_set(c, _pc, stack, size, tls) 								\
-	do {												\
-		(c)->pc = (uint64_t) _pc;								\
-		(c)->bsp = ((uint64_t) stack) + size / PSTHREAD_INITIAL_STACK_DIVISION;								\
-		(c)->ar_pfs &= PFM_MASK; 								\
-		(c)->sp = ((uint64_t) stack) + ALIGN_UP((size / PSTHREAD_INITIAL_STACK_DIVISION), STACK_ALIGNMENT) - SP_DELTA;		\
-		(c)->tp = (uint64_t) tls;								\
-	} while (0);
-	
+#define context_set(c, _pc, stack, size, tls) \
+	do { \
+		(c)->pc = (uint64_t) _pc; \
+		(c)->bsp = ((uint64_t) stack) + \
+		    size / PSTHREAD_INITIAL_STACK_DIVISION; \
+		(c)->ar_pfs &= PFM_MASK; \
+		(c)->sp = ((uint64_t) stack) + \
+		    ALIGN_UP((size / PSTHREAD_INITIAL_STACK_DIVISION), STACK_ALIGNMENT) - \
+		    SP_DELTA; \
+		(c)->tp = (uint64_t) tls; \
+	} while (0)
 
 /*
Index: uspace/lib/c/arch/mips32/Makefile.inc
===================================================================
--- uspace/lib/c/arch/mips32/Makefile.inc	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/arch/mips32/Makefile.inc	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -28,7 +28,7 @@
 
 ARCH_SOURCES = \
-	arch/$(UARCH)/src/entry.s \
-	arch/$(UARCH)/src/entryjmp.s \
-	arch/$(UARCH)/src/thread_entry.s \
+	arch/$(UARCH)/src/entry.S \
+	arch/$(UARCH)/src/entryjmp.S \
+	arch/$(UARCH)/src/thread_entry.S \
 	arch/$(UARCH)/src/syscall.c \
 	arch/$(UARCH)/src/fibril.S \
Index: uspace/lib/c/arch/mips32/include/atomic.h
===================================================================
--- uspace/lib/c/arch/mips32/include/atomic.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/arch/mips32/include/atomic.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -67,5 +67,5 @@
 		"	ll %0, %1\n"
 		"	addu %0, %0, %3\n"	/* same as add, but never traps on overflow */
-		"       move %2, %0\n"
+		"	move %2, %0\n"
 		"	sc %0, %1\n"
 		"	beq %0, %4, 1b\n"	/* if the atomic operation failed, try again */
Index: uspace/lib/c/arch/mips32/include/config.h
===================================================================
--- uspace/lib/c/arch/mips32/include/config.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/arch/mips32/include/config.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -36,6 +36,6 @@
 #define LIBC_mips32_CONFIG_H_
 
-#define PAGE_WIDTH	14
-#define PAGE_SIZE	(1 << PAGE_WIDTH)
+#define PAGE_WIDTH  14
+#define PAGE_SIZE   (1 << PAGE_WIDTH)
 
 #endif
Index: uspace/lib/c/arch/mips32/include/faddr.h
===================================================================
--- uspace/lib/c/arch/mips32/include/faddr.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/arch/mips32/include/faddr.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -38,5 +38,5 @@
 #include <libarch/types.h>
 
-#define FADDR(fptr)		((uintptr_t) (fptr))
+#define FADDR(fptr)  ((uintptr_t) (fptr))
 
 #endif
Index: uspace/lib/c/arch/mips32/include/fibril.h
===================================================================
--- uspace/lib/c/arch/mips32/include/fibril.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/arch/mips32/include/fibril.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -38,20 +38,21 @@
 
 #include <sys/types.h>
+#include <libarch/stack.h>
+#include <align.h>
 
-/* We define our own context_set, because we need to set
- * the TLS pointer to the tcb+0x7000
+#define SP_DELTA  (ABI_STACK_FRAME + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
+
+/*
+ * We define our own context_set, because we need to set
+ * the TLS pointer to the tcb + 0x7000
  *
  * See tls_set in thread.h
  */
-#define context_set(c, _pc, stack, size, ptls) 			\
-	(c)->pc = (sysarg_t) (_pc);				\
-	(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; 	\
-        (c)->tls = ((sysarg_t)(ptls)) + 0x7000 + sizeof(tcb_t);
-
-
-/* +16 is just for sure that the called function
- * have space to store it's arguments
- */
-#define SP_DELTA	(8+16)
+#define context_set(c, _pc, stack, size, ptls) \
+	do { \
+		(c)->pc = (sysarg_t) (_pc); \
+		(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
+		(c)->tls = ((sysarg_t)(ptls)) + 0x7000 + sizeof(tcb_t); \
+	} while (0)
 
 typedef struct  {
Index: uspace/lib/c/arch/mips32/include/stack.h
===================================================================
--- uspace/lib/c/arch/mips32/include/stack.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/lib/c/arch/mips32/include/stack.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,1 @@
+../../../../../../kernel/arch/mips32/include/stack.h
Index: uspace/lib/c/arch/mips32/src/entry.S
===================================================================
--- uspace/lib/c/arch/mips32/src/entry.S	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/lib/c/arch/mips32/src/entry.S	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2005 Martin Decky
+# 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.
+#
+
+#include <libarch/stack.h>
+
+.text
+.section .init, "ax"
+
+.global __entry
+
+.set noreorder
+.option pic2
+
+## User-space task entry point
+#
+# $a0 ($4) contains the PCB pointer
+#
+.ent __entry
+__entry:
+	.frame $sp, ABI_STACK_FRAME, $ra
+	.cpload $t9
+	
+	# Allocate the stack frame.
+	addiu $sp, -ABI_STACK_FRAME
+	
+	# Allow PIC code
+	.cprestore 16
+	
+	# Pass pcb_ptr to __main() as the first argument. It is already
+	# in $a0. As the first argument is passed in $a0, no operation
+	# is needed.
+	
+	jal __main
+	nop
+	
+	#
+	# Not reached.
+	#
+	addiu $sp, ABI_STACK_FRAME
+.end __entry
Index: pace/lib/c/arch/mips32/src/entry.s
===================================================================
--- uspace/lib/c/arch/mips32/src/entry.s	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ 	(revision )
@@ -1,59 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# 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.
-#
-
-.text
-.section .init, "ax"
-
-.global __entry
-
-.set noreorder
-.option pic2
-
-## User-space task entry point
-#
-# $a0 ($4) contains the PCB pointer
-#
-.ent __entry
-__entry:
-	.frame $sp, 32, $31
-	.cpload $25
-
-	# Mips o32 may store its arguments on stack, make space (16 bytes),
-	# so that it could work with -O0
-	# Make space additional 16 bytes for the stack frame
-
-	addiu $sp, -32
-	.cprestore 16   # Allow PIC code
-
-	# Pass pcb_ptr to __main() as the first argument. pcb_ptr is already
-	# in $a0. As the first argument is passed in $a0, no operation
-	# is needed.
-
-	jal __main
-	nop
-.end
Index: uspace/lib/c/arch/mips32/src/entryjmp.S
===================================================================
--- uspace/lib/c/arch/mips32/src/entryjmp.S	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/lib/c/arch/mips32/src/entryjmp.S	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,53 @@
+#
+# Copyright (c) 2008 Jiri Svoboda
+# 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.
+#
+
+#include <libarch/stack.h>
+
+.text
+.section .text
+.global entry_point_jmp
+.set noreorder
+
+## void entry_point_jmp(void *entry_point, void *pcb);
+#
+# $a0 (=$4) contains entry_point
+# $a1 (=$5) contains pcb
+#
+# Jump to program entry point
+.ent entry_point_jmp
+entry_point_jmp:
+	# tmp := entry_point
+	move $t9, $a0
+	
+	# Pass pcb to the entry point in $a0
+	move $a0, $a1
+	
+	jr $t9
+	addiu $sp, -ABI_STACK_FRAME
+	addiu $sp, ABI_STACK_FRAME
+.end entry_point_jmp
Index: pace/lib/c/arch/mips32/src/entryjmp.s
===================================================================
--- uspace/lib/c/arch/mips32/src/entryjmp.s	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ 	(revision )
@@ -1,49 +1,0 @@
-#
-# Copyright (c) 2008 Jiri Svoboda
-# 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.
-#
-
-.text
-.section .text
-.global entry_point_jmp
-.set noreorder
-
-## void entry_point_jmp(void *entry_point, void *pcb);
-#
-# $a0 (=$4)	contains entry_point
-# $a1 (=$5)	contains pcb
-#
-# Jump to program entry point
-.ent entry_point_jmp
-entry_point_jmp:
-	# tmp := entry_point
-	move $25, $a0
-
-	# Pass pcb to the entry point in $a0
-	move $a0, $a1
-	jr $25
-	nop
-.end
Index: uspace/lib/c/arch/mips32/src/fibril.S
===================================================================
--- uspace/lib/c/arch/mips32/src/fibril.S	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/arch/mips32/src/fibril.S	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -33,23 +33,23 @@
 
 #include <libarch/context_offset.h>
-	
+
 .global context_save
 .global context_restore
-	
+
 context_save:
 	CONTEXT_SAVE_ARCH_CORE $a0
-
+	
 	# context_save returns 1
 	j $ra
-	li $v0, 1	
-	
+	li $v0, 1
+
 context_restore:
 	CONTEXT_RESTORE_ARCH_CORE $a0
-
-	# Just for the jump into first function, but one instruction
-	# should not bother us
-	move $t9, $ra	
+	
+	# Just for the jump into first function,
+	# but one instruction should not bother us
+	move $t9, $ra
+	
 	# context_restore returns 0
 	j $ra
-	xor $v0, $v0	
-
+	xor $v0, $v0
Index: uspace/lib/c/arch/mips32/src/syscall.c
===================================================================
--- uspace/lib/c/arch/mips32/src/syscall.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/arch/mips32/src/syscall.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -57,6 +57,9 @@
 		  "r" (__mips_reg_t1),
 		  "r" (__mips_reg_v0)
-		: "%ra" /* We are a function call, although C does not 
-			 * know it */
+		/*
+		 * We are a function call, although C
+		 * does not know it.
+		 */
+		: "%ra"
 	);
 	
Index: uspace/lib/c/arch/mips32/src/thread_entry.S
===================================================================
--- uspace/lib/c/arch/mips32/src/thread_entry.S	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/lib/c/arch/mips32/src/thread_entry.S	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2006 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.
+#
+
+#include <libarch/stack.h>
+
+.text
+
+.set noat
+.set noreorder
+.option pic2
+
+.globl __thread_entry
+
+## User-space thread entry point for all but the first threads.
+#
+#
+.ent __thread_entry
+__thread_entry:
+	.frame $sp, ABI_STACK_FRAME, $ra
+	.cpload $t9
+	
+	#
+	# v0 contains address of uarg.
+	#
+	add $a0, $v0, 0
+	
+	# Allocate the stack frame.
+	addiu $sp, -ABI_STACK_FRAME
+	
+	# Allow PIC code
+	.cprestore 16
+	
+	jal __thread_main
+	nop
+	
+	#
+	# Not reached.
+	#
+	addiu $sp, ABI_STACK_FRAME
+.end __thread_entry
Index: pace/lib/c/arch/mips32/src/thread_entry.s
===================================================================
--- uspace/lib/c/arch/mips32/src/thread_entry.s	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ 	(revision )
@@ -1,59 +1,0 @@
-#
-# Copyright (c) 2006 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.
-#
-
-.text
-	
-.set noat
-.set noreorder
-.option pic2
-	
-.globl __thread_entry
-
-## User-space thread entry point for all but the first threads.
-#
-#
-.ent __thread_entry
-__thread_entry:
-	.frame $sp, 32, $31
-	.cpload $25
-
-	#
-	# v0 contains address of uarg.
-	#
-	add $4, $2, 0
-	# Mips o32 may store its arguments on stack, make space
-	addiu $sp, -32
-	.cprestore 16
-	
-	jal __thread_main
-	nop
-		
-	#
-	# Not reached.
-	#
-.end __thread_entry
Index: uspace/lib/c/arch/mips32eb/Makefile.inc
===================================================================
--- uspace/lib/c/arch/mips32eb/Makefile.inc	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/arch/mips32eb/Makefile.inc	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -28,7 +28,7 @@
 
 ARCH_SOURCES = \
-	arch/$(UARCH)/src/entry.s \
-	arch/$(UARCH)/src/entryjmp.s \
-	arch/$(UARCH)/src/thread_entry.s \
+	arch/$(UARCH)/src/entry.S \
+	arch/$(UARCH)/src/entryjmp.S \
+	arch/$(UARCH)/src/thread_entry.S \
 	arch/$(UARCH)/src/syscall.c \
 	arch/$(UARCH)/src/fibril.S \
Index: uspace/lib/c/arch/mips32eb/include/stack.h
===================================================================
--- uspace/lib/c/arch/mips32eb/include/stack.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/lib/c/arch/mips32eb/include/stack.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,1 @@
+../../mips32/include/stack.h
Index: uspace/lib/c/arch/mips64/Makefile.inc
===================================================================
--- uspace/lib/c/arch/mips64/Makefile.inc	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/arch/mips64/Makefile.inc	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -28,7 +28,7 @@
 
 ARCH_SOURCES = \
-	arch/$(UARCH)/src/entry.s \
-	arch/$(UARCH)/src/entryjmp.s \
-	arch/$(UARCH)/src/thread_entry.s \
+	arch/$(UARCH)/src/entry.S \
+	arch/$(UARCH)/src/entryjmp.S \
+	arch/$(UARCH)/src/thread_entry.S \
 	arch/$(UARCH)/src/syscall.c \
 	arch/$(UARCH)/src/fibril.S \
Index: uspace/lib/c/arch/mips64/include/fibril.h
===================================================================
--- uspace/lib/c/arch/mips64/include/fibril.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/arch/mips64/include/fibril.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -38,19 +38,21 @@
 
 #include <sys/types.h>
+#include <libarch/stack.h>
+#include <align.h>
 
-/* We define our own context_set, because we need to set
- * the TLS pointer to the tcb+0x7000
+#define SP_DELTA  (ABI_STACK_FRAME + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
+
+/*
+ * We define our own context_set, because we need to set
+ * the TLS pointer to the tcb + 0x7000
  *
  * See tls_set in thread.h
  */
 #define context_set(c, _pc, stack, size, ptls) \
-	(c)->pc = (sysarg_t) (_pc); \
-	(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
-	(c)->tls = ((sysarg_t)(ptls)) + 0x7000 + sizeof(tcb_t);
-
-/* +16 is just for sure that the called function
- * have space to store it's arguments
- */
-#define SP_DELTA  (8 + 16)
+	do { \
+		(c)->pc = (sysarg_t) (_pc); \
+		(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
+		(c)->tls = ((sysarg_t)(ptls)) + 0x7000 + sizeof(tcb_t); \
+	} while (0)
 
 typedef struct {
Index: uspace/lib/c/arch/mips64/include/stack.h
===================================================================
--- uspace/lib/c/arch/mips64/include/stack.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/lib/c/arch/mips64/include/stack.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,1 @@
+../../../../../../kernel/arch/mips64/include/stack.h
Index: uspace/lib/c/arch/mips64/src/entry.S
===================================================================
--- uspace/lib/c/arch/mips64/src/entry.S	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/lib/c/arch/mips64/src/entry.S	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2005 Martin Decky
+# 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.
+#
+
+#include <libarch/stack.h>
+
+.text
+.section .init, "ax"
+
+.global __entry
+
+.set noreorder
+.option pic2
+
+## User-space task entry point
+#
+# $a0 ($4) contains the PCB pointer
+#
+.ent __entry
+__entry:
+	.frame $sp, ABI_STACK_FRAME, $ra
+	.cpload $t9
+	
+	# Allocate the stack frame.
+	addiu $sp, -ABI_STACK_FRAME
+	
+	# Allow PIC code
+	.cprestore 16
+	
+	# Pass pcb_ptr to __main() as the first argument. It is already
+	# in $a0. As the first argument is passed in $a0, no operation
+	# is needed.
+	
+	jal __main
+	nop
+	
+	#
+	# Not reached.
+	#
+	addiu $sp, ABI_STACK_FRAME
+.end __entry
Index: pace/lib/c/arch/mips64/src/entry.s
===================================================================
--- uspace/lib/c/arch/mips64/src/entry.s	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ 	(revision )
@@ -1,57 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# 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.
-#
-
-.text
-.section .init, "ax"
-
-.global __entry
-
-.set noreorder
-.option pic2
-
-## User-space task entry point
-#
-# $a0 ($4) contains the PCB pointer
-#
-.ent __entry
-__entry:
-	.frame $sp, 32, $31
-	.cpload $25
-	
-	# FIXME: Reflect exactly ABI specs here
-	
-	addiu $sp, -32
-	.cprestore 16   # Allow PIC code
-	
-	# Pass pcb_ptr to __main() as the first argument. pcb_ptr is already
-	# in $a0. As the first argument is passed in $a0, no operation
-	# is needed.
-	
-	jal __main
-	nop
-.end
Index: uspace/lib/c/arch/mips64/src/entryjmp.S
===================================================================
--- uspace/lib/c/arch/mips64/src/entryjmp.S	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/lib/c/arch/mips64/src/entryjmp.S	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,53 @@
+#
+# Copyright (c) 2008 Jiri Svoboda
+# 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.
+#
+
+#include <libarch/stack.h>
+
+.text
+.section .text
+.global entry_point_jmp
+.set noreorder
+
+## void entry_point_jmp(void *entry_point, void *pcb);
+#
+# $a0 (=$4) contains entry_point
+# $a1 (=$5) contains pcb
+#
+# Jump to program entry point
+.ent entry_point_jmp
+entry_point_jmp:
+	# tmp := entry_point
+	move $t9, $a0
+	
+	# Pass pcb to the entry point in $a0
+	move $a0, $a1
+	
+	jr $t9
+	addiu $sp, -ABI_STACK_FRAME
+	addiu $sp, ABI_STACK_FRAME
+.end entry_point_jmp
Index: pace/lib/c/arch/mips64/src/entryjmp.s
===================================================================
--- uspace/lib/c/arch/mips64/src/entryjmp.s	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ 	(revision )
@@ -1,49 +1,0 @@
-#
-# Copyright (c) 2008 Jiri Svoboda
-# 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.
-#
-
-.text
-.section .text
-.global entry_point_jmp
-.set noreorder
-
-## void entry_point_jmp(void *entry_point, void *pcb);
-#
-# $a0 (=$4) contains entry_point
-# $a1 (=$5) contains pcb
-#
-# Jump to program entry point
-.ent entry_point_jmp
-entry_point_jmp:
-	# tmp := entry_point
-	move $25, $a0
-	
-	# Pass pcb to the entry point in $a0
-	move $a0, $a1
-	jr $25
-	nop
-.end
Index: uspace/lib/c/arch/mips64/src/thread_entry.S
===================================================================
--- uspace/lib/c/arch/mips64/src/thread_entry.S	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
+++ uspace/lib/c/arch/mips64/src/thread_entry.S	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2006 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.
+#
+
+#include <libarch/stack.h>
+
+.text
+
+.set noat
+.set noreorder
+.option pic2
+
+.globl __thread_entry
+
+## User-space thread entry point for all but the first threads.
+#
+#
+.ent __thread_entry
+__thread_entry:
+	.frame $sp, ABI_STACK_FRAME, $ra
+	.cpload $t9
+	
+	#
+	# v0 contains address of uarg.
+	#
+	add $a0, $v0, 0
+	
+	# Allocate the stack frame.
+	addiu $sp, -ABI_STACK_FRAME
+	
+	# Allow PIC code
+	.cprestore 16
+	
+	jal __thread_main
+	nop
+	
+	#
+	# Not reached.
+	#
+	addiu $sp, ABI_STACK_FRAME
+.end __thread_entry
Index: pace/lib/c/arch/mips64/src/thread_entry.s
===================================================================
--- uspace/lib/c/arch/mips64/src/thread_entry.s	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ 	(revision )
@@ -1,59 +1,0 @@
-#
-# Copyright (c) 2006 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.
-#
-
-.text
-
-.set noat
-.set noreorder
-.option pic2
-
-.globl __thread_entry
-
-## User-space thread entry point for all but the first threads.
-#
-#
-.ent __thread_entry
-__thread_entry:
-	.frame $sp, 32, $31
-	.cpload $25
-	
-	#
-	# v0 contains address of uarg.
-	#
-	add $4, $2, 0
-	
-	addiu $sp, -32
-	.cprestore 16
-	
-	jal __thread_main
-	nop
-	
-	#
-	# Not reached.
-	#
-.end __thread_entry
Index: uspace/lib/c/arch/ppc32/include/fibril.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/fibril.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/arch/ppc32/include/fibril.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup libcppc32	
+/** @addtogroup libcppc32
  * @{
  */
@@ -38,15 +38,18 @@
 #include <sys/types.h>
 
-/* We define our own context_set, because we need to set
- * the TLS pointer to the tcb+0x7000
+#define SP_DELTA  16
+
+/*
+ * We define our own context_set, because we need to set
+ * the TLS pointer to the tcb + 0x7000
  *
  * See tls_set in thread.h
  */
-#define context_set(c, _pc, stack, size, ptls) 			\
-	(c)->pc = (sysarg_t) (_pc);				\
-	(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; 	\
-	(c)->tls = ((sysarg_t) (ptls)) + 0x7000 + sizeof(tcb_t);
-
-#define SP_DELTA	16
+#define context_set(c, _pc, stack, size, ptls) \
+	do { \
+		(c)->pc = (sysarg_t) (_pc); \
+		(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
+		(c)->tls = ((sysarg_t) (ptls)) + 0x7000 + sizeof(tcb_t); \
+	} while (0)
 
 typedef struct {
Index: uspace/lib/c/arch/sparc64/include/fibril.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/fibril.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/arch/sparc64/include/fibril.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -40,5 +40,5 @@
 #include <align.h>
 
-#define SP_DELTA	(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE)
+#define SP_DELTA  (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE)
 
 #define context_set(c, _pc, stack, size, ptls) \
@@ -50,5 +50,5 @@
 		(c)->tp = (uint64_t) ptls; \
 	} while (0)
-	
+
 /*
  * Save only registers that must be preserved across
Index: uspace/lib/c/generic/str.c
===================================================================
--- uspace/lib/c/generic/str.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/generic/str.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -259,4 +259,41 @@
 	
 	return offset;
+}
+
+/** Get size of string with size limit.
+ *
+ * Get the number of bytes which are used by the string @a str
+ * (excluding the NULL-terminator), but no more than @max_size bytes.
+ *
+ * @param str      String to consider.
+ * @param max_size Maximum number of bytes to measure.
+ *
+ * @return Number of bytes used by the string
+ *
+ */
+size_t str_nsize(const char *str, size_t max_size)
+{
+	size_t size = 0;
+	
+	while ((*str++ != 0) && (size < max_size))
+		size++;
+	
+	return size;
+}
+
+/** Get size of wide string with size limit.
+ *
+ * Get the number of bytes which are used by the wide string @a str
+ * (excluding the NULL-terminator), but no more than @max_size bytes.
+ *
+ * @param str      Wide string to consider.
+ * @param max_size Maximum number of bytes to measure.
+ *
+ * @return Number of bytes used by the wide string
+ *
+ */
+size_t wstr_nsize(const wchar_t *str, size_t max_size)
+{
+	return (wstr_nlength(str, max_size) * sizeof(wchar_t));
 }
 
Index: uspace/lib/c/generic/sysinfo.c
===================================================================
--- uspace/lib/c/generic/sysinfo.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/generic/sysinfo.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -40,4 +40,68 @@
 #include <bool.h>
 
+/** Get sysinfo keys size
+ *
+ * @param path  Sysinfo path.
+ * @param value Pointer to store the keys size.
+ *
+ * @return EOK if the keys were successfully read.
+ *
+ */
+static int sysinfo_get_keys_size(const char *path, size_t *size)
+{
+	return (int) __SYSCALL3(SYS_SYSINFO_GET_KEYS_SIZE, (sysarg_t) path,
+	    (sysarg_t) str_size(path), (sysarg_t) size);
+}
+
+/** Get sysinfo keys
+ *
+ * @param path  Sysinfo path.
+ * @param value Pointer to store the keys size.
+ *
+ * @return Keys read from sysinfo or NULL if the
+ *         sysinfo item has no subkeys.
+ *         The returned non-NULL pointer should be
+ *         freed by free().
+ *
+ */
+char *sysinfo_get_keys(const char *path, size_t *size)
+{
+	/*
+	 * The size of the keys might change during time.
+	 * Unfortunatelly we cannot allocate the buffer
+	 * and transfer the keys as a single atomic operation.
+	 */
+	
+	/* Get the keys size */
+	int ret = sysinfo_get_keys_size(path, size);
+	if ((ret != EOK) || (size == 0)) {
+		/*
+		 * Item with no subkeys.
+		 */
+		*size = 0;
+		return NULL;
+	}
+	
+	char *data = malloc(*size);
+	if (data == NULL) {
+		*size = 0;
+		return NULL;
+	}
+	
+	/* Get the data */
+	size_t sz;
+	ret = __SYSCALL5(SYS_SYSINFO_GET_KEYS, (sysarg_t) path,
+	    (sysarg_t) str_size(path), (sysarg_t) data, (sysarg_t) *size,
+	    (sysarg_t) &sz);
+	if (ret == EOK) {
+		*size = sz;
+		return data;
+	}
+	
+	free(data);
+	*size = 0;
+	return NULL;
+}
+
 /** Get sysinfo item type
  *
@@ -70,6 +134,6 @@
 /** Get sysinfo binary data size
  *
- * @param path  Sysinfo path.
- * @param value Pointer to store the binary data size.
+ * @param path Sysinfo path.
+ * @param size Pointer to store the binary data size.
  *
  * @return EOK if the value was successfully read and
@@ -85,6 +149,6 @@
 /** Get sysinfo binary data
  *
- * @param path  Sysinfo path.
- * @param value Pointer to store the binary data size.
+ * @param path Sysinfo path.
+ * @param size Pointer to store the binary data size.
  *
  * @return Binary data read from sysinfo or NULL if the
@@ -134,4 +198,67 @@
 }
 
+/** Get sysinfo property
+ *
+ * @param path Sysinfo path.
+ * @param name Property name.
+ * @param size Pointer to store the binary data size.
+ *
+ * @return Property value read from sysinfo or NULL if the
+ *         sysinfo item value type is not binary data.
+ *         The returned non-NULL pointer should be
+ *         freed by free().
+ *
+ */
+void *sysinfo_get_property(const char *path, const char *name, size_t *size)
+{
+	size_t total_size;
+	void *data = sysinfo_get_data(path, &total_size);
+	if ((data == NULL) || (total_size == 0)) {
+		*size = 0;
+		return NULL;
+	}
+	
+	size_t pos = 0;
+	while (pos < total_size) {
+		/* Process each property with sanity checks */
+		size_t cur_size = str_nsize(data + pos, total_size - pos);
+		if (((char *) data)[pos + cur_size] != 0)
+			break;
+		
+		bool found = (str_cmp(data + pos, name) == 0);
+		
+		pos += cur_size + 1;
+		if (pos >= total_size)
+			break;
+		
+		/* Process value size */
+		size_t value_size;
+		memcpy(&value_size, data + pos, sizeof(value_size));
+		
+		pos += sizeof(value_size);
+		if ((pos >= total_size) || (pos + value_size > total_size))
+			break;
+		
+		if (found) {
+			void *value = malloc(value_size);
+			if (value == NULL)
+				break;
+			
+			memcpy(value, data + pos, value_size);
+			free(data);
+			
+			*size = value_size;
+			return value;
+		}
+		
+		pos += value_size;
+	}
+	
+	free(data);
+	
+	*size = 0;
+	return NULL;
+}
+
 /** @}
  */
Index: uspace/lib/c/include/fibril.h
===================================================================
--- uspace/lib/c/include/fibril.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/include/fibril.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -41,7 +41,9 @@
 
 #define context_set_generic(c, _pc, stack, size, ptls) \
-	(c)->pc = (sysarg_t) (_pc); \
-	(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
-	(c)->tls = (sysarg_t) (ptls);
+	do { \
+		(c)->pc = (sysarg_t) (_pc); \
+		(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
+		(c)->tls = (sysarg_t) (ptls); \
+	} while (0)
 
 #define FIBRIL_SERIALIZED  1
Index: uspace/lib/c/include/str.h
===================================================================
--- uspace/lib/c/include/str.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/include/str.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -60,4 +60,7 @@
 extern size_t str_size(const char *str);
 extern size_t wstr_size(const wchar_t *str);
+
+extern size_t str_nsize(const char *str, size_t max_size);
+extern size_t wstr_nsize(const wchar_t *str, size_t max_size);
 
 extern size_t str_lsize(const char *str, size_t max_len);
Index: uspace/lib/c/include/sysinfo.h
===================================================================
--- uspace/lib/c/include/sysinfo.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/lib/c/include/sysinfo.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -40,7 +40,9 @@
 #include <abi/sysinfo.h>
 
+extern char *sysinfo_get_keys(const char *, size_t *);
 extern sysinfo_item_val_type_t sysinfo_get_val_type(const char *);
 extern int sysinfo_get_value(const char *, sysarg_t *);
 extern void *sysinfo_get_data(const char *, size_t *);
+extern void *sysinfo_get_property(const char *, const char *, size_t *);
 
 #endif
Index: uspace/srv/fs/exfat/exfat_bitmap.c
===================================================================
--- uspace/srv/fs/exfat/exfat_bitmap.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/srv/fs/exfat/exfat_bitmap.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -48,5 +48,5 @@
 
 
-int bitmap_is_free(exfat_bs_t *bs, service_id_t service_id, 
+int exfat_bitmap_is_free(exfat_bs_t *bs, service_id_t service_id, 
     exfat_cluster_t clst)
 {
@@ -89,5 +89,5 @@
 }
 
-int bitmap_set_cluster(exfat_bs_t *bs, service_id_t service_id, 
+int exfat_bitmap_set_cluster(exfat_bs_t *bs, service_id_t service_id, 
     exfat_cluster_t clst)
 {
@@ -124,5 +124,5 @@
 }
 
-int bitmap_clear_cluster(exfat_bs_t *bs, service_id_t service_id, 
+int exfat_bitmap_clear_cluster(exfat_bs_t *bs, service_id_t service_id, 
     exfat_cluster_t clst)
 {
@@ -160,5 +160,5 @@
 }
 
-int bitmap_set_clusters(exfat_bs_t *bs, service_id_t service_id, 
+int exfat_bitmap_set_clusters(exfat_bs_t *bs, service_id_t service_id, 
     exfat_cluster_t firstc, exfat_cluster_t count)
 {
@@ -168,8 +168,8 @@
 
 	while (clst < firstc + count ) {
-		rc = bitmap_set_cluster(bs, service_id, clst);
+		rc = exfat_bitmap_set_cluster(bs, service_id, clst);
 		if (rc != EOK) {
 			if (clst - firstc > 0)
-				(void) bitmap_clear_clusters(bs, service_id,
+				(void) exfat_bitmap_clear_clusters(bs, service_id,
 				    firstc, clst - firstc);
 			return rc;
@@ -180,5 +180,5 @@
 }
 
-int bitmap_clear_clusters(exfat_bs_t *bs, service_id_t service_id, 
+int exfat_bitmap_clear_clusters(exfat_bs_t *bs, service_id_t service_id, 
     exfat_cluster_t firstc, exfat_cluster_t count)
 {
@@ -188,5 +188,5 @@
 
 	while (clst < firstc + count) {
-		rc = bitmap_clear_cluster(bs, service_id, clst);
+		rc = exfat_bitmap_clear_cluster(bs, service_id, clst);
 		if (rc != EOK)
 			return rc;
@@ -196,5 +196,5 @@
 }
 
-int bitmap_alloc_clusters(exfat_bs_t *bs, service_id_t service_id, 
+int exfat_bitmap_alloc_clusters(exfat_bs_t *bs, service_id_t service_id, 
     exfat_cluster_t *firstc, exfat_cluster_t count)
 {
@@ -204,8 +204,8 @@
 	while (startc < DATA_CNT(bs) + 2) {
 		endc = startc;
-		while (bitmap_is_free(bs, service_id, endc) == EOK) {
+		while (exfat_bitmap_is_free(bs, service_id, endc) == EOK) {
 			if ((endc - startc) + 1 == count) {
 				*firstc = startc;
-				return bitmap_set_clusters(bs, service_id, startc, count);
+				return exfat_bitmap_set_clusters(bs, service_id, startc, count);
 			} else
 				endc++;
@@ -217,9 +217,9 @@
 
 
-int bitmap_append_clusters(exfat_bs_t *bs, exfat_node_t *nodep, 
+int exfat_bitmap_append_clusters(exfat_bs_t *bs, exfat_node_t *nodep, 
     exfat_cluster_t count)
 {
 	if (nodep->firstc == 0) {
-		return bitmap_alloc_clusters(bs, nodep->idx->service_id, 
+		return exfat_bitmap_alloc_clusters(bs, nodep->idx->service_id, 
 		    &nodep->firstc, count);
 	} else {
@@ -228,7 +228,7 @@
 
 		clst = lastc + 1;
-		while (bitmap_is_free(bs, nodep->idx->service_id, clst) == EOK) {
+		while (exfat_bitmap_is_free(bs, nodep->idx->service_id, clst) == EOK) {
 			if (clst - lastc == count){
-				return bitmap_set_clusters(bs, nodep->idx->service_id, 
+				return exfat_bitmap_set_clusters(bs, nodep->idx->service_id, 
 				    lastc + 1, count);
 			} else
@@ -240,5 +240,5 @@
 
 
-int bitmap_free_clusters(exfat_bs_t *bs, exfat_node_t *nodep, 
+int exfat_bitmap_free_clusters(exfat_bs_t *bs, exfat_node_t *nodep, 
     exfat_cluster_t count)
 {
@@ -247,9 +247,9 @@
 	lastc -= count;
 
-	return bitmap_clear_clusters(bs, nodep->idx->service_id, lastc + 1, count);
-}
-
-
-int bitmap_replicate_clusters(exfat_bs_t *bs, exfat_node_t *nodep)
+	return exfat_bitmap_clear_clusters(bs, nodep->idx->service_id, lastc + 1, count);
+}
+
+
+int exfat_bitmap_replicate_clusters(exfat_bs_t *bs, exfat_node_t *nodep)
 {
 	int rc;
Index: uspace/srv/fs/exfat/exfat_bitmap.h
===================================================================
--- uspace/srv/fs/exfat/exfat_bitmap.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/srv/fs/exfat/exfat_bitmap.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -42,20 +42,20 @@
 struct exfat_bs;
 
-extern int bitmap_alloc_clusters(struct exfat_bs *, service_id_t, 
+extern int exfat_bitmap_alloc_clusters(struct exfat_bs *, service_id_t, 
     exfat_cluster_t *, exfat_cluster_t);
-extern int bitmap_append_clusters(struct exfat_bs *, struct exfat_node *, 
+extern int exfat_bitmap_append_clusters(struct exfat_bs *, struct exfat_node *, 
     exfat_cluster_t);
-extern int bitmap_free_clusters(struct exfat_bs *, struct exfat_node *, 
+extern int exfat_bitmap_free_clusters(struct exfat_bs *, struct exfat_node *, 
     exfat_cluster_t);
-extern int bitmap_replicate_clusters(struct exfat_bs *, struct exfat_node *); 
+extern int exfat_bitmap_replicate_clusters(struct exfat_bs *, struct exfat_node *); 
 
-extern int bitmap_is_free(struct exfat_bs *, service_id_t, exfat_cluster_t);
-extern int bitmap_set_cluster(struct exfat_bs *, service_id_t, exfat_cluster_t);
-extern int bitmap_clear_cluster(struct exfat_bs *, service_id_t, 
+extern int exfat_bitmap_is_free(struct exfat_bs *, service_id_t, exfat_cluster_t);
+extern int exfat_bitmap_set_cluster(struct exfat_bs *, service_id_t, exfat_cluster_t);
+extern int exfat_bitmap_clear_cluster(struct exfat_bs *, service_id_t, 
     exfat_cluster_t);
 
-extern int bitmap_set_clusters(struct exfat_bs *, service_id_t, 
+extern int exfat_bitmap_set_clusters(struct exfat_bs *, service_id_t, 
     exfat_cluster_t, exfat_cluster_t);
-extern int bitmap_clear_clusters(struct exfat_bs *, service_id_t, 
+extern int exfat_bitmap_clear_clusters(struct exfat_bs *, service_id_t, 
     exfat_cluster_t, exfat_cluster_t);
 
Index: uspace/srv/fs/exfat/exfat_dentry.c
===================================================================
--- uspace/srv/fs/exfat/exfat_dentry.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/srv/fs/exfat/exfat_dentry.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -130,5 +130,5 @@
 }
 
-size_t utf16_length(const uint16_t *wstr)
+size_t exfat_utf16_length(const uint16_t *wstr)
 {
 	size_t len = 0;
Index: uspace/srv/fs/exfat/exfat_dentry.h
===================================================================
--- uspace/srv/fs/exfat/exfat_dentry.h	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/srv/fs/exfat/exfat_dentry.h	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -160,5 +160,5 @@
 extern bool exfat_valid_name(const char *);
 
-extern size_t utf16_length(const uint16_t *);
+extern size_t exfat_utf16_length(const uint16_t *);
 
 
Index: uspace/srv/fs/exfat/exfat_directory.c
===================================================================
--- uspace/srv/fs/exfat/exfat_directory.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/srv/fs/exfat/exfat_directory.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -371,5 +371,5 @@
 	ds.stream.valid_data_size = 0;
 	ds.stream.data_size = 0;
-	ds.stream.name_size = utf16_length(wname);
+	ds.stream.name_size = exfat_utf16_length(wname);
 	ds.stream.hash = host2uint16_t_le(exfat_name_hash(wname, uctable, 
 	    uctable_chars));
Index: uspace/srv/fs/exfat/exfat_fat.c
===================================================================
--- uspace/srv/fs/exfat/exfat_fat.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/srv/fs/exfat/exfat_fat.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -314,5 +314,5 @@
 	    clst++) {
 		/* Need to rewrite because of multiple exfat_bitmap_get calls */
-		if (bitmap_is_free(bs, service_id, clst) == EOK) {
+		if (exfat_bitmap_is_free(bs, service_id, clst) == EOK) {
 			/*
 			 * The cluster is free. Put it into our stack
@@ -325,5 +325,5 @@
 				goto exit_error;
 			found++;
-			rc = bitmap_set_cluster(bs, service_id, clst);
+			rc = exfat_bitmap_set_cluster(bs, service_id, clst);
 			if (rc != EOK)
 				goto exit_error;
@@ -346,5 +346,5 @@
 	/* If something wrong - free the clusters */
 	while (found--) {
-		(void) bitmap_clear_cluster(bs, service_id, lifo[found]);
+		(void) exfat_bitmap_clear_cluster(bs, service_id, lifo[found]);
 		(void) exfat_set_cluster(bs, service_id, lifo[found], 0);
 	}
@@ -378,5 +378,5 @@
 		if (rc != EOK)
 			return rc;
-		rc = bitmap_clear_cluster(bs, service_id, firstc);
+		rc = exfat_bitmap_clear_cluster(bs, service_id, firstc);
 		if (rc != EOK)
 			return rc;
Index: uspace/srv/fs/exfat/exfat_ops.c
===================================================================
--- uspace/srv/fs/exfat/exfat_ops.c	(revision 43cd4995323e5ad59552104e19f2a501c05c51d4)
+++ uspace/srv/fs/exfat/exfat_ops.c	(revision 14f8fd4b8057885912cc5c2ed1e6ef6316a18ddb)
@@ -405,5 +405,5 @@
 
 	if (!nodep->fragmented) {
-		rc = bitmap_append_clusters(bs, nodep, clusters);
+		rc = exfat_bitmap_append_clusters(bs, nodep, clusters);
 		if (rc != ENOSPC)
 			return rc;
@@ -411,5 +411,5 @@
 			nodep->fragmented = true;
 			nodep->dirty = true;		/* need to sync node */
-			rc = bitmap_replicate_clusters(bs, nodep);
+			rc = exfat_bitmap_replicate_clusters(bs, nodep);
 			if (rc != EOK)
 				return rc;
@@ -457,5 +457,5 @@
 
 		clsts = prev_clsts - new_clsts;
-		rc = bitmap_free_clusters(bs, nodep, clsts);
+		rc = exfat_bitmap_free_clusters(bs, nodep, clsts);
 		if (rc != EOK)
 			return rc;
@@ -704,5 +704,5 @@
 				nodep->firstc);
 		else
-			rc = bitmap_free_clusters(bs, nodep, 
+			rc = exfat_bitmap_free_clusters(bs, nodep, 
 			    ROUND_UP(nodep->size, BPC(bs)) / BPC(bs));
 	} 
@@ -758,9 +758,5 @@
 
 	fibril_mutex_unlock(&parentp->idx->lock);
-	if (rc != EOK)
-		return rc;
-
 	fibril_mutex_lock(&childp->idx->lock);
-
 
 	childp->idx->pfc = parentp->firstc;
@@ -1463,5 +1459,8 @@
 	}
 
-	(void) exfat_node_put(fn);
+	int rc2 = exfat_node_put(fn);
+	if (rc == EOK && rc2 != EOK)
+		rc = rc2;
+
 	return rc;
 }
