Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -45,9 +45,10 @@
 	app/edit \
 	app/getterm \
+	app/hdisk \
 	app/init \
 	app/inet \
 	app/kill \
 	app/killall \
-	app/klog \
+	app/kio \
 	app/loc \
 	app/logset \
@@ -68,4 +69,5 @@
 	app/trace \
 	app/top \
+	app/untar \
 	app/usbinfo \
 	app/vuhid \
@@ -90,4 +92,5 @@
 	srv/locsrv \
 	srv/logger \
+	srv/klog \
 	srv/devman \
 	srv/loader \
@@ -239,4 +242,5 @@
 	lib/softrend \
 	lib/draw \
+	lib/math \
 	lib/net \
 	lib/nic \
@@ -250,5 +254,7 @@
 	lib/pcm \
 	lib/bithenge \
-	lib/posix
+	lib/posix \
+	lib/mbr \
+	lib/gpt
 
 LIBC_BUILD = $(addsuffix .build,$(LIBC))
Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/Makefile.common	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -45,4 +45,5 @@
 #
 #   POSIX_COMPAT       set to 'y' to use POSIX compatibility layer
+#   NEEDS_MATH         set to 'y' to add implementation of mathematical functions
 #
 # Optionally, for a binary:
@@ -109,4 +110,5 @@
 LIBSOFTFLOAT_PREFIX = $(LIB_PREFIX)/softfloat
 LIBSOFTINT_PREFIX = $(LIB_PREFIX)/softint
+LIBMATH_PREFIX = $(LIB_PREFIX)/math
 
 LIBPOSIX_PREFIX = $(LIB_PREFIX)/posix
@@ -143,4 +145,7 @@
 LIBHTTP_PREFIX = $(LIB_PREFIX)/http
 LIBURI_PREFIX = $(LIB_PREFIX)/uri
+
+LIBMBR_PREFIX = $(LIB_PREFIX)/mbr
+LIBGPT_PREFIX = $(LIB_PREFIX)/gpt
 
 ifeq ($(STATIC_NEEDED),y)
@@ -233,4 +238,9 @@
 endif
 
+# Do we need math?
+ifeq ($(NEEDS_MATH),y)
+	BASE_LIBS += $(LIBMATH_PREFIX)/libmath.a
+endif
+
 ## Setup platform configuration
 #
Index: uspace/app/hdisk/Makefile
===================================================================
--- uspace/app/hdisk/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/hdisk/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+USPACE_PREFIX = ../..
+LIBS = $(LIBMBR_PREFIX)/libmbr.a $(LIBGPT_PREFIX)/libgpt.a \
+	$(LIBBLOCK_PREFIX)/libblock.a $(LIBCLUI_PREFIX)/libclui.a \
+	$(LIBC_PREFIX)/libc.a
+EXTRA_CFLAGS = -I$(LIBMBR_PREFIX) -I$(LIBGPT_PREFIX) -I$(LIBBLOCK_PREFIX) -I$(LIBCLUI_PREFIX)
+BINARY = hdisk
+
+SOURCES = \
+	hdisk.c \
+	input.c \
+	func_none.c \
+	func_mbr.c \
+	func_gpt.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/hdisk/common.h
===================================================================
--- uspace/app/hdisk/common.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/hdisk/common.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+#include <libmbr.h>
+#include <libgpt.h>
+
+typedef enum {
+	LYT_NONE,
+	LYT_MBR,
+	LYT_GPT,
+} layouts_t;
+
+typedef union {
+	mbr_label_t *mbr;
+	gpt_label_t *gpt;
+} label_data_t;
+
+typedef struct label {
+	layouts_t layout;
+	aoff64_t blocks;
+	service_id_t device;
+	label_data_t data;
+	unsigned int alignment;
+	int (* destroy_label)(struct label *);
+	int (* add_part)(struct label *, tinput_t *);
+	int (* delete_part)(struct label *, tinput_t *);
+	int (* new_label)(struct label *);
+	int (* print_parts)(struct label *);
+	int (* read_parts)(struct label *);
+	int (* write_parts)(struct label *);
+	int (* extra_funcs)(struct label *, tinput_t *);
+} label_t;
+
+#endif
Index: uspace/app/hdisk/func_gpt.c
===================================================================
--- uspace/app/hdisk/func_gpt.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/hdisk/func_gpt.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#include <stdio.h>
+#include <str.h>
+#include <errno.h>
+#include <str_error.h>
+#include <sys/types.h>
+#include <sys/typefmt.h>
+#include "func_gpt.h"
+#include "input.h"
+
+static void print_part_types(void);
+static int set_gpt_partition(tinput_t *, gpt_part_t *, label_t *);
+
+int construct_gpt_label(label_t *this)
+{
+	this->layout = LYT_GPT;
+	this->alignment = 1;
+	
+	this->add_part = add_gpt_part;
+	this->delete_part = delete_gpt_part;
+	this->destroy_label = destroy_gpt_label;
+	this->new_label = new_gpt_label;
+	this->print_parts = print_gpt_parts;
+	this->read_parts = read_gpt_parts;
+	this->write_parts = write_gpt_parts;
+	this->extra_funcs = extra_gpt_funcs;
+	
+	return this->new_label(this);
+}
+
+int add_gpt_part(label_t *this, tinput_t *in)
+{
+	gpt_part_t *partition = gpt_get_partition(this->data.gpt);
+	if (partition == NULL)
+		return ENOMEM;
+	
+	return set_gpt_partition(in, partition, this);
+}
+
+int delete_gpt_part(label_t *this, tinput_t *in)
+{
+	printf("Index of the partition to delete (counted from 0): ");
+	size_t idx = get_input_size_t(in);
+	
+	int rc = gpt_remove_partition(this->data.gpt, idx);
+	if (rc == ENOMEM) {
+		printf("Warning: Running out on memory, not resizing.\n");
+		return rc;
+	} else if (rc == EINVAL) {
+		printf("Invalid index.\n");
+		return rc;
+	}
+	
+	return EOK;
+}
+
+int destroy_gpt_label(label_t *this)
+{
+	gpt_free_label(this->data.gpt);
+	return EOK;
+}
+
+int new_gpt_label(label_t *this)
+{
+	this->data.gpt = gpt_alloc_label();
+	return EOK;
+}
+
+int print_gpt_parts(label_t *this)
+{
+	printf("Current partition scheme: GPT\n");
+	printf("Number of blocks: %" PRIu64 "\n", this->blocks);
+	
+	size_t i = 0;
+	gpt_part_foreach (this->data.gpt, iter) {
+		if (gpt_get_part_type(iter) == GPT_PTE_UNUSED)
+			continue;
+		
+		if (i % 20 == 0)
+			printf("%15s %10s %10s Type: Name:\n",
+			    "Start:", "End:", "Length:");
+		
+		printf("%3zu  %10" PRIu64 " %10" PRIu64 " %10" PRIu64 "    %3zu %s\n",
+		   i, gpt_get_start_lba(iter), gpt_get_end_lba(iter),
+		   gpt_get_end_lba(iter) - gpt_get_start_lba(iter), 
+		   gpt_get_part_type(iter), gpt_get_part_name(iter));
+		
+		i++;
+	}
+	
+	return EOK;
+}
+
+int read_gpt_parts(label_t *this)
+{
+	int rc = gpt_read_header(this->data.gpt, this->device);
+	if (rc != EOK) {
+		printf("Error: Reading header failed: %d (%s)\n", rc,
+		    str_error(rc));
+		return rc;
+	}
+	
+	rc = gpt_read_partitions(this->data.gpt);
+	if (rc != EOK) {
+		printf("Error: Reading partitions failed: %d (%s)\n", rc,
+		    str_error(rc));
+		return rc;
+	}
+	
+	return EOK;
+}
+
+int write_gpt_parts(label_t *this)
+{
+	int rc = gpt_write_partitions(this->data.gpt, this->device);
+	if (rc != EOK) {
+		printf("Error: Writing partitions failed: %d (%s)\n", rc,
+		    str_error(rc));
+		return rc;
+	}
+	
+	return EOK;
+}
+
+int extra_gpt_funcs(label_t *this, tinput_t *in)
+{
+	printf("Not implemented.\n");
+	return EOK;
+}
+
+static int set_gpt_partition(tinput_t *in, gpt_part_t *partition, label_t *this)
+{
+	printf("Set starting address: ");
+	uint64_t sa = get_input_uint64(in);
+	if ((this->alignment != 0) && (this->alignment != 1) &&
+	    (sa % this->alignment != 0))
+		sa = gpt_get_next_aligned(sa, this->alignment);
+	
+	printf("Set end address (max: %" PRIu64 "): ", this->blocks);
+	uint64_t ea = get_input_uint64(in);
+	
+	if (ea <= sa) {
+		printf("Invalid value.\n");
+		return EINVAL;
+	}
+	
+	gpt_set_start_lba(partition, sa);
+	gpt_set_end_lba(partition, ea);
+	
+	printf("Choose type: ");
+	print_part_types();
+	printf("Set type (1 for HelenOS System): ");
+	size_t idx = get_input_size_t(in);
+	gpt_set_part_type(partition, idx);
+	
+	gpt_set_random_uuid(partition->part_id);
+	
+	printf("Name the partition: ");
+	char *name;
+	int rc = get_input_line(in, &name);
+	if (rc != EOK) {
+		printf("Error reading name: %d (%s)\n", rc, str_error(rc));
+		return rc;
+	}
+	
+	gpt_set_part_name(partition, name, str_size(name));
+	
+	return EOK;
+}
+
+static void print_part_types(void)
+{
+	unsigned int count = 0;
+	const partition_type_t *ptype = gpt_ptypes;
+	
+	do {
+		printf("%u: %s\n", count, ptype->desc);
+		count++;
+		ptype++;
+		
+		if (count % 10 == 0) {
+			printf("Print (more) partition types? (y/n)\n");
+			int c = getchar();
+			if (c == 'n')
+				return;
+		}
+	} while (ptype->guid != NULL);
+}
Index: uspace/app/hdisk/func_gpt.h
===================================================================
--- uspace/app/hdisk/func_gpt.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/hdisk/func_gpt.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __FUNC_GPT_H__
+#define __FUNC_GPT_H__
+
+#include <loc.h>
+#include <tinput.h>
+#include <libgpt.h>
+#include "common.h"
+
+extern int construct_gpt_label(label_t *);
+extern int add_gpt_part(label_t *, tinput_t *);
+extern int delete_gpt_part(label_t *, tinput_t *);
+extern int destroy_gpt_label(label_t *);
+extern int new_gpt_label(label_t *);
+extern int print_gpt_parts(label_t *);
+extern int read_gpt_parts(label_t *);
+extern int write_gpt_parts(label_t *);
+extern int extra_gpt_funcs(label_t *, tinput_t *);
+
+#endif
Index: uspace/app/hdisk/func_mbr.c
===================================================================
--- uspace/app/hdisk/func_mbr.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/hdisk/func_mbr.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <str_error.h>
+#include <sys/types.h>
+#include "func_mbr.h"
+#include "input.h"
+
+static int set_mbr_partition(tinput_t *, mbr_part_t *, label_t *);
+
+int construct_mbr_label(label_t *this)
+{
+	this->layout = LYT_MBR;
+	this->alignment = 1;
+	
+	this->add_part      = add_mbr_part;
+	this->delete_part   = delete_mbr_part;
+	this->destroy_label = destroy_mbr_label;
+	this->new_label     = new_mbr_label;
+	this->print_parts   = print_mbr_parts;
+	this->read_parts    = read_mbr_parts;
+	this->write_parts   = write_mbr_parts;
+	this->extra_funcs   = extra_mbr_funcs;
+	
+	return this->new_label(this);
+}
+
+int add_mbr_part(label_t *this, tinput_t *in)
+{
+	mbr_part_t *partition = mbr_alloc_partition();
+	if (partition == NULL)
+		return ENOMEM;
+	
+	int rc = set_mbr_partition(in, partition, this);
+	if (rc != EOK)
+		return rc;
+	
+	rc = mbr_add_partition(this->data.mbr, partition);
+	if (rc != ERR_OK)
+		printf("Error adding partition: %d\n", rc);
+	
+	return EOK;
+}
+
+int delete_mbr_part(label_t *this, tinput_t *in)
+{
+	printf("Index of the partition to delete (counted from 0): ");
+	size_t idx = get_input_size_t(in);
+	
+	if ((idx == 0) && (errno != EOK))
+		return errno;
+	
+	int rc = mbr_remove_partition(this->data.mbr, idx);
+	if (rc != EOK)
+		printf("Error: partition does not exist?\n");
+	
+	return EOK;
+}
+
+int destroy_mbr_label(label_t *this)
+{
+	mbr_free_label(this->data.mbr);
+	return EOK;
+}
+
+int new_mbr_label(label_t *this)
+{
+	this->data.mbr = mbr_alloc_label();
+	if (this->data.mbr == NULL)
+		return ENOMEM;
+	
+	mbr_set_device(this->data.mbr, this->device);
+	return EOK;
+}
+
+int print_mbr_parts(label_t *this)
+{
+	printf("Current partition scheme: MBR\n");
+	printf("Number of blocks: %" PRIu64 "\n", this->blocks);
+	printf("\t\t%10s  %10s %10s %10s %7s\n",
+	    "Bootable:", "Start:", "End:", "Length:", "Type:");
+	
+	unsigned int num = 0;
+	mbr_part_t *it;
+	for (it = mbr_get_first_partition(this->data.mbr); it != NULL;
+	     it = mbr_get_next_partition(this->data.mbr, it)) {
+		if (it->type == PT_UNUSED)
+			continue;
+		
+		printf("\tP%u:\t", num);
+		if (mbr_get_flag(it, ST_BOOT))
+			printf("*");
+		else
+			printf(" ");
+		
+		printf("\t%10u %10u %10u %7u\n", it->start_addr,
+		    it->start_addr + it->length, it->length, it->type);
+		
+		num++;
+	}
+	
+	printf("%u partitions found.\n", num);
+	
+	return EOK;
+}
+
+int read_mbr_parts(label_t *this)
+{
+	int rc = mbr_read_mbr(this->data.mbr, this->device);
+	if (rc != EOK)
+		return rc;
+	
+	if (!mbr_is_mbr(this->data.mbr))
+		return EINVAL;
+	
+	rc = mbr_read_partitions(this->data.mbr);
+	if (rc != EOK)
+		return rc;
+	
+	return EOK;
+}
+
+int write_mbr_parts(label_t *this)
+{
+	int rc = mbr_write_partitions(this->data.mbr, this->device);
+	if (rc != EOK)
+		printf("Error occured during writing: ERR: %d: %s\n", rc,
+		    str_error(rc));
+	
+	return rc;
+}
+
+int extra_mbr_funcs(label_t *this, tinput_t *in)
+{
+	printf("Not implemented.\n");
+	return EOK;
+}
+
+static int set_mbr_partition(tinput_t *in, mbr_part_t *partition, label_t *this)
+{
+	printf("Primary (p) or logical (l): ");
+	int c = getchar();
+	printf("%c\n", c);
+
+	switch (c) {
+	case 'p':
+		mbr_set_flag(partition, ST_LOGIC, false);
+		break;
+	case 'l':
+		mbr_set_flag(partition, ST_LOGIC, true);
+		break;
+	default:
+		printf("Invalid type. Cancelled.\n");
+		return EINVAL;
+	}
+	
+	printf("Set type (0 - 255): ");
+	uint8_t type = get_input_uint8(in);
+	if ((type == 0) && (errno != EOK))
+		return errno;
+	
+	// FIXME: Make sure there is at most one bootable partition
+	printf("Bootable? (y/n): ");
+	c = getchar();
+	if ((c != 'y') && (c != 'Y') && (c != 'n') && (c != 'N')) {
+		printf("Invalid value. Cancelled.");
+		return EINVAL;
+	}
+	
+	printf("%c\n", c);
+	mbr_set_flag(partition, ST_BOOT, (c == 'y' || c == 'Y') ? true : false);
+	
+	printf("Set starting address: ");
+	uint32_t sa = get_input_uint32(in);
+	if ((sa == 0) && (errno != EOK))
+		return errno;
+	
+	if ((this->alignment != 0) && (this->alignment != 1) &&
+	    (sa % this->alignment != 0)) {
+		sa = mbr_get_next_aligned(sa, this->alignment);
+		printf("Starting address was aligned to %" PRIu32 ".\n", sa);
+	}
+	
+	printf("Set end addres (max: %" PRIu64 "): ", this->blocks);
+	uint32_t ea = get_input_uint32(in);
+	if ((ea == 0) && (errno != EOK))
+		return errno;
+	
+	if (ea < sa) {
+		printf("Invalid value. Canceled.\n");
+		return EINVAL;
+	}
+	
+	partition->type = type;
+	partition->start_addr = sa;
+	partition->length = ea - sa;
+	
+	return EOK;
+}
Index: uspace/app/hdisk/func_mbr.h
===================================================================
--- uspace/app/hdisk/func_mbr.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/hdisk/func_mbr.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __FUNC_MBR_H__
+#define __FUNC_MBR_H__
+
+#include <loc.h>
+#include <tinput.h>
+#include <libmbr.h>
+#include "common.h"
+
+extern int construct_mbr_label(label_t *);
+extern int add_mbr_part(label_t *, tinput_t *);
+extern int delete_mbr_part(label_t *, tinput_t *);
+extern int destroy_mbr_label(label_t *);
+extern int new_mbr_label(label_t *);
+extern int print_mbr_parts(label_t *);
+extern int read_mbr_parts(label_t *);
+extern int write_mbr_parts(label_t *);
+extern int extra_mbr_funcs(label_t *, tinput_t *);
+
+#endif
Index: uspace/app/hdisk/func_none.c
===================================================================
--- uspace/app/hdisk/func_none.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/hdisk/func_none.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#include <errno.h>
+#include "func_none.h"
+
+static void not_implemented(void);
+
+int construct_none_label(label_t *this)
+{
+	this->layout = LYT_NONE;
+	
+	this->add_part = add_none_part;
+	this->delete_part = delete_none_part;
+	this->destroy_label = destroy_none_label;
+	this->new_label = new_none_label;
+	this->print_parts = print_none_parts;
+	this->read_parts = read_none_parts;
+	this->write_parts = write_none_parts;
+	this->extra_funcs = extra_none_funcs;
+	
+	return EOK;
+}
+
+int add_none_part(label_t *this, tinput_t *in)
+{
+	not_implemented();
+	return EOK;
+}
+
+int delete_none_part(label_t *this, tinput_t *in)
+{
+	not_implemented();
+	return EOK;
+}
+
+int destroy_none_label(label_t *this)
+{
+	return EOK;
+}
+
+int new_none_label(label_t *this)
+{
+	not_implemented();
+	return EOK;
+}
+
+int print_none_parts(label_t *this)
+{
+	not_implemented();
+	return EOK;
+}
+
+int read_none_parts(label_t *this)
+{
+	not_implemented();
+	return EOK;
+}
+
+int write_none_parts(label_t *this)
+{
+	not_implemented();
+	return EOK;
+}
+
+int extra_none_funcs(label_t *this, tinput_t * in)
+{
+	not_implemented();
+	return EOK;
+}
+
+static void not_implemented(void)
+{
+	printf("No format selected.\n");
+}
Index: uspace/app/hdisk/func_none.h
===================================================================
--- uspace/app/hdisk/func_none.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/hdisk/func_none.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __FUNC_NONE_H__
+#define __FUNC_NONE_H__
+
+#include <loc.h>
+#include <tinput.h>
+#include "common.h"
+
+extern int construct_none_label(label_t *);
+extern int add_none_part(label_t *, tinput_t *);
+extern int delete_none_part(label_t *, tinput_t *);
+extern int destroy_none_label(label_t *);
+extern int new_none_label(label_t *);
+extern int print_none_parts(label_t *);
+extern int read_none_parts(label_t *);
+extern int write_none_parts(label_t *);
+extern int extra_none_funcs(label_t *, tinput_t *);
+
+#endif
Index: uspace/app/hdisk/hdisk.c
===================================================================
--- uspace/app/hdisk/hdisk.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/hdisk/hdisk.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/bd.h>
+#include <loc.h>
+#include <async.h>
+#include <stdio.h>
+#include <ipc/services.h>
+#include <block.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <str.h>
+#include <libmbr.h>
+#include <libgpt.h>
+#include <tinput.h>
+#include <str_error.h>
+#include "hdisk.h"
+#include "input.h"
+#include "func_gpt.h"
+#include "func_mbr.h"
+#include "func_none.h"
+
+static int interact(void);
+static void print_help(void);
+static void select_label_format(tinput_t *);
+static void construct_label(layouts_t);
+static void free_label(void);
+static int try_read(void);
+static int try_read_mbr(void);
+static int try_read_gpt(void);
+static void set_alignment(tinput_t *);
+
+static label_t label;
+
+int main(int argc, char *argv[])
+{
+	if (argc == 1) {
+		printf("Missing argument. Please specify a device to operate on.\n");
+		return 1;
+	}
+	
+	service_id_t dev_handle;
+	int rc = loc_service_get_id(argv[1], &dev_handle, IPC_FLAG_BLOCKING);
+	if (rc != EOK) {
+		printf("Unknown device. Exiting.\n");
+		return 2;
+	}
+	
+	init_label();
+	label.device = dev_handle;
+	
+	rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
+	if (rc != EOK) {
+		printf("Error during libblock init: %d - %s.\n", rc, str_error(rc));
+		return 3;
+	}
+	
+	aoff64_t blocks;
+	rc = block_get_nblocks(dev_handle, &blocks);
+	block_fini(dev_handle);
+	if (rc != EOK) {
+		printf("Error while getting number of blocks: %d - %s.\n",
+		    rc, str_error(rc));
+		return 4;
+	}
+	
+	label.blocks = blocks;
+	
+	rc = try_read_mbr();
+	if (rc == EOK)
+		goto interact;
+	
+	free_label();
+	
+	rc = try_read_gpt();
+	if (rc == EOK)
+		goto interact;
+	
+	printf("No label recognized. Create a new one.\n");
+	construct_label(LYT_NONE);
+	
+interact:
+	return interact();
+}
+
+/** Interact with user */
+int interact(void)
+{
+	tinput_t *in = tinput_new();
+	if (in == NULL) {
+		printf("Failed initing input. Free some memory.\n");
+		return ENOMEM;
+	}
+	tinput_set_prompt(in, "");
+	
+	printf("Welcome to hdisk.\nType 'h' for help.\n");
+	
+	while (true) {
+		printf("# ");
+		int input = getchar();
+		printf("%c\n", input);
+		
+		switch (input) {
+		case 'a':
+			label.add_part(&label, in);
+			break;
+		case 'd':
+			label.delete_part(&label, in);
+			break;
+		case 'e':
+			label.extra_funcs(&label, in);
+			break;
+		case 'f':
+			free_label();
+			select_label_format(in);
+			break;
+		case 'h':
+			print_help();
+			break;
+		case 'l':
+			set_alignment(in);
+			break;
+		case 'n':
+			printf("Discarding label...\n");
+			free_label();
+			label.new_label(&label);
+			break;
+		case 'p':
+			label.print_parts(&label);
+			break;
+		case 'q':
+			putchar('\n');
+			free_label();
+			goto end;
+		case 'r':
+			label.read_parts(&label);
+		case 'w':
+			label.write_parts(&label);
+			break;
+		default:
+			printf("Unknown command. Try 'h' for help.\n");
+			break;
+		}
+	}
+	
+end:
+	tinput_destroy(in);
+	return EOK;
+}
+
+void print_help(void)
+{
+	printf(
+	    "\t 'a' \t\t Add partition.\n"
+	    "\t 'd' \t\t Delete partition.\n"
+	    "\t 'e' \t\t Extra functions (per label format).\n"
+	    "\t 'f' \t\t Switch the format of the partition label.\n"
+	    "\t 'h' \t\t Prints help. See help for more.\n"
+	    "\t 'l' \t\t Set alignment.\n"
+	    "\t 'n' \t\t Create new label (discarding the old one).\n"
+	    "\t 'p' \t\t Prints label contents.\n"
+	    "\t 'q' \t\t Quit.\n"
+	    "\t 'r' \t\t Read label from disk.\n"
+	    "\t 'w' \t\t Write label to disk.\n");
+}
+
+void select_label_format(tinput_t *in)
+{
+	printf("Available formats are: \n"
+	    "1) MBR\n"
+	    "2) GPT\n");
+	
+	uint8_t val = get_input_uint8(in);
+	switch (val) {
+	case 1:
+		construct_label(LYT_MBR);
+		break;
+	case 2:
+		construct_label(LYT_GPT);
+		break;
+	default:
+		construct_label(LYT_NONE);
+		break;
+	}
+}
+
+void construct_label(layouts_t layout)
+{
+	switch (layout) {
+	case LYT_MBR:
+		label.layout = LYT_MBR;
+		construct_mbr_label(&label);
+		break;
+	case LYT_GPT:
+		label.layout = LYT_GPT;
+		construct_gpt_label(&label);
+		break;
+	default:
+		label.layout = LYT_NONE;
+		construct_none_label(&label);
+		break;
+	}
+}
+
+void free_label(void)
+{
+	label.destroy_label(&label);
+}
+
+int try_read(void)
+{
+	return label.read_parts(&label);
+}
+
+int try_read_mbr(void)
+{
+	construct_label(LYT_MBR);
+	return try_read();
+}
+
+int try_read_gpt(void)
+{
+	construct_label(LYT_GPT);
+	return try_read();
+}
+
+void set_alignment(tinput_t *in)
+{
+	printf("Set alignment to sectors: ");
+	label.alignment = get_input_uint32(in);
+	printf("Alignment set to %u sectors.\n", label.alignment);
+}
Index: uspace/app/hdisk/hdisk.h
===================================================================
--- uspace/app/hdisk/hdisk.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/hdisk/hdisk.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __HDISK_H__
+#define __HDISK_H__
+
+#include "common.h"
+
+#define init_label() \
+	label.layout = LYT_NONE
+
+#endif
Index: uspace/app/hdisk/input.c
===================================================================
--- uspace/app/hdisk/input.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/hdisk/input.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#include <str.h>
+#include <errno.h>
+#include <stdlib.h>
+#include "input.h"
+
+typedef int (*conv_f)(const char *, char **, unsigned int, bool, void *);
+
+static int convert(tinput_t *, conv_f, void *);
+
+int get_input_line(tinput_t *in, char **str)
+{
+	int rc = tinput_read(in, str);
+	if (rc == ENOENT)
+		return EINTR;
+	
+	if (rc != EOK)
+		return rc;
+	
+	/* Check for empty input. */
+	if (str_cmp(*str, "") == 0) {
+		free(*str);
+		*str = NULL;
+		return EINVAL;
+	}
+	
+	return EOK;
+}
+
+uint8_t get_input_uint8(tinput_t *in)
+{
+	uint32_t val;
+	int rc = convert(in, (conv_f) str_uint8_t, &val);
+	if (rc != EOK) {
+		errno = rc;
+		return 0;
+	}
+	
+	errno = EOK;
+	return val;
+}
+
+uint32_t get_input_uint32(tinput_t *in)
+{
+	uint32_t val;
+	int rc = convert(in, (conv_f) str_uint32_t, &val);
+	if (rc != EOK) {
+		errno = rc;
+		return 0;
+	}
+	
+	errno = EOK;
+	return val;
+}
+
+uint64_t get_input_uint64(tinput_t *in)
+{
+	uint64_t val;
+	int rc = convert(in, (conv_f) str_uint64_t, &val);
+	if (rc != EOK) {
+		errno = rc;
+		return 0;
+	}
+	
+	errno = EOK;
+	return val;
+}
+
+size_t get_input_size_t(tinput_t *in)
+{
+	size_t val;
+	int rc = convert(in, (conv_f) str_size_t, &val);
+	if (rc != EOK) {
+		errno = rc;
+		return 0;
+	}
+	
+	errno = EOK;
+	return val;
+}
+
+static int convert(tinput_t *in, conv_f str_f, void *val)
+{
+	char *str;
+	int rc = get_input_line(in, &str);
+	if (rc != EOK) {
+		printf("Error reading input.\n");
+		return rc;
+	}
+	
+	rc = str_f(str, NULL, 10, true, val);
+	if (rc != EOK)
+		printf("Invalid value.\n");
+	
+	free(str);
+	return rc;
+}
Index: uspace/app/hdisk/input.h
===================================================================
--- uspace/app/hdisk/input.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/hdisk/input.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __INPUT_H__
+#define __INPUT_H__
+
+#include <tinput.h>
+
+extern int get_input_line(tinput_t *, char **);
+extern uint8_t get_input_uint8(tinput_t *);
+extern uint32_t get_input_uint32(tinput_t *);
+extern uint64_t get_input_uint64(tinput_t *);
+extern size_t get_input_size_t(tinput_t *);
+
+#endif
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/init/init.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -336,4 +336,5 @@
 		srv_start("/srv/tmpfs");
 	
+	srv_start("/srv/klog");
 	srv_start("/srv/locfs");
 	srv_start("/srv/taskmon");
Index: uspace/app/kio/Makefile
===================================================================
--- uspace/app/kio/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/kio/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+USPACE_PREFIX = ../..
+LIBS = $(LIBCLUI_PREFIX)/libclui.a
+EXTRA_CFLAGS = -I$(LIBCLUI_PREFIX)
+BINARY = kio
+
+SOURCES = \
+	kio.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/kio/kio.c
===================================================================
--- uspace/app/kio/kio.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/kio/kio.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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 kio KIO
+ * @brief HelenOS KIO
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <async.h>
+#include <as.h>
+#include <ddi.h>
+#include <event.h>
+#include <errno.h>
+#include <str_error.h>
+#include <io/kio.h>
+#include <sysinfo.h>
+#include <malloc.h>
+#include <fibril_synch.h>
+#include <adt/list.h>
+#include <adt/prodcons.h>
+#include <tinput.h>
+
+#define NAME       "kio"
+#define LOG_FNAME  "/log/kio"
+
+/* Producer/consumer buffers */
+typedef struct {
+	link_t link;
+	size_t length;
+	wchar_t *data;
+} item_t;
+
+static prodcons_t pc;
+
+/* Pointer to kio area */
+static wchar_t *kio;
+static size_t kio_length;
+
+/* Notification mutex */
+static FIBRIL_MUTEX_INITIALIZE(mtx);
+
+/** Klog producer
+ *
+ * Copies the contents of a character buffer to local
+ * producer/consumer queue.
+ *
+ * @param length Number of characters to copy.
+ * @param data   Pointer to the kernel kio buffer.
+ *
+ */
+static void producer(size_t length, wchar_t *data)
+{
+	item_t *item = (item_t *) malloc(sizeof(item_t));
+	if (item == NULL)
+		return;
+	
+	size_t sz = sizeof(wchar_t) * length;
+	wchar_t *buf = (wchar_t *) malloc(sz);
+	if (data == NULL) {
+		free(item);
+		return;
+	}
+	
+	memcpy(buf, data, sz);
+	
+	link_initialize(&item->link);
+	item->length = length;
+	item->data = buf;
+	prodcons_produce(&pc, &item->link);
+}
+
+/** Klog consumer
+ *
+ * Waits in an infinite loop for the character data created by
+ * the producer and outputs them to stdout and optionally into
+ * a file.
+ *
+ * @param data Unused.
+ *
+ * @return Always EOK (unreachable).
+ *
+ */
+static int consumer(void *data)
+{
+	FILE *log = fopen(LOG_FNAME, "a");
+	if (log == NULL)
+		printf("%s: Unable to create log file %s (%s)\n", NAME, LOG_FNAME,
+		    str_error(errno));
+	
+	while (true) {
+		link_t *link = prodcons_consume(&pc);
+		item_t *item = list_get_instance(link, item_t, link);
+		
+		for (size_t i = 0; i < item->length; i++)
+			putchar(item->data[i]);
+		
+		if (log != NULL) {
+			for (size_t i = 0; i < item->length; i++)
+				fputc(item->data[i], log);
+			
+			fflush(log);
+			fsync(fileno(log));
+		}
+		
+		free(item->data);
+		free(item);
+	}
+	
+	fclose(log);
+	return EOK;
+}
+
+/** Kernel notification handler
+ *
+ * Receives kernel kio notifications.
+ *
+ * @param callid IPC call ID
+ * @param call   IPC call structure
+ * @param arg    Local argument
+ *
+ */
+static void notification_received(ipc_callid_t callid, ipc_call_t *call)
+{
+	/*
+	 * Make sure we process only a single notification
+	 * at any time to limit the chance of the consumer
+	 * starving.
+	 *
+	 * Note: Usually the automatic masking of the kio
+	 * notifications on the kernel side does the trick
+	 * of limiting the chance of accidentally copying
+	 * the same data multiple times. However, due to
+	 * the non-blocking architecture of kio notifications,
+	 * this possibility cannot be generally avoided.
+	 */
+	
+	fibril_mutex_lock(&mtx);
+	
+	size_t kio_start = (size_t) IPC_GET_ARG1(*call);
+	size_t kio_len = (size_t) IPC_GET_ARG2(*call);
+	size_t kio_stored = (size_t) IPC_GET_ARG3(*call);
+	
+	size_t offset = (kio_start + kio_len - kio_stored) % kio_length;
+	
+	/* Copy data from the ring buffer */
+	if (offset + kio_stored >= kio_length) {
+		size_t split = kio_length - offset;
+		
+		producer(split, kio + offset);
+		producer(kio_stored - split, kio);
+	} else
+		producer(kio_stored, kio + offset);
+	
+	event_unmask(EVENT_KIO);
+	fibril_mutex_unlock(&mtx);
+}
+
+int main(int argc, char *argv[])
+{
+	size_t pages;
+	int rc = sysinfo_get_value("kio.pages", &pages);
+	if (rc != EOK) {
+		fprintf(stderr, "%s: Unable to get number of kio pages\n",
+		    NAME);
+		return rc;
+	}
+	
+	uintptr_t faddr;
+	rc = sysinfo_get_value("kio.faddr", &faddr);
+	if (rc != EOK) {
+		fprintf(stderr, "%s: Unable to get kio physical address\n",
+		    NAME);
+		return rc;
+	}
+	
+	size_t size = pages * PAGE_SIZE;
+	kio_length = size / sizeof(wchar_t);
+	
+	rc = physmem_map(faddr, pages, AS_AREA_READ | AS_AREA_CACHEABLE,
+	    (void *) &kio);
+	if (rc != EOK) {
+		fprintf(stderr, "%s: Unable to map kio\n", NAME);
+		return rc;
+	}
+	
+	prodcons_initialize(&pc);
+	async_set_interrupt_received(notification_received);
+	rc = event_subscribe(EVENT_KIO, 0);
+	if (rc != EOK) {
+		fprintf(stderr, "%s: Unable to register kio notifications\n",
+		    NAME);
+		return rc;
+	}
+	
+	fid_t fid = fibril_create(consumer, NULL);
+	if (!fid) {
+		fprintf(stderr, "%s: Unable to create consumer fibril\n",
+		    NAME);
+		return ENOMEM;
+	}
+	
+	tinput_t *input = tinput_new();
+	if (!input) {
+		fprintf(stderr, "%s: Could not create input\n", NAME);
+		return ENOMEM;
+	}	
+
+	fibril_add_ready(fid);
+	event_unmask(EVENT_KIO);
+	kio_update();
+	
+	tinput_set_prompt(input, "kio> ");
+
+	char *str;
+	while ((rc = tinput_read(input, &str)) == EOK) {
+		if (str_cmp(str, "") == 0) {
+			free(str);
+			continue;
+		}
+
+		kio_command(str, str_size(str));
+		free(str);
+	}
+ 
+	if (rc == ENOENT)
+		rc = EOK;	
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/app/klog/Makefile
===================================================================
--- uspace/app/klog/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,38 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# Copyright (c) 2007 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.
-#
-
-USPACE_PREFIX = ../..
-LIBS = $(LIBCLUI_PREFIX)/libclui.a
-EXTRA_CFLAGS = -I$(LIBCLUI_PREFIX)
-BINARY = klog
-
-SOURCES = \
-	klog.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/klog/klog.c
===================================================================
--- uspace/app/klog/klog.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,261 +1,0 @@
-/*
- * Copyright (c) 2006 Ondrej Palkovsky
- * 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 klog KLog
- * @brief HelenOS KLog
- * @{
- */
-/**
- * @file
- */
-
-#include <stdio.h>
-#include <async.h>
-#include <as.h>
-#include <ddi.h>
-#include <event.h>
-#include <errno.h>
-#include <str_error.h>
-#include <io/klog.h>
-#include <sysinfo.h>
-#include <malloc.h>
-#include <fibril_synch.h>
-#include <adt/list.h>
-#include <adt/prodcons.h>
-#include <tinput.h>
-
-#define NAME       "klog"
-#define LOG_FNAME  "/log/klog"
-
-/* Producer/consumer buffers */
-typedef struct {
-	link_t link;
-	size_t length;
-	wchar_t *data;
-} item_t;
-
-static prodcons_t pc;
-
-/* Pointer to klog area */
-static wchar_t *klog;
-static size_t klog_length;
-
-/* Notification mutex */
-static FIBRIL_MUTEX_INITIALIZE(mtx);
-
-/** Klog producer
- *
- * Copies the contents of a character buffer to local
- * producer/consumer queue.
- *
- * @param length Number of characters to copy.
- * @param data   Pointer to the kernel klog buffer.
- *
- */
-static void producer(size_t length, wchar_t *data)
-{
-	item_t *item = (item_t *) malloc(sizeof(item_t));
-	if (item == NULL)
-		return;
-	
-	size_t sz = sizeof(wchar_t) * length;
-	wchar_t *buf = (wchar_t *) malloc(sz);
-	if (data == NULL) {
-		free(item);
-		return;
-	}
-	
-	memcpy(buf, data, sz);
-	
-	link_initialize(&item->link);
-	item->length = length;
-	item->data = buf;
-	prodcons_produce(&pc, &item->link);
-}
-
-/** Klog consumer
- *
- * Waits in an infinite loop for the character data created by
- * the producer and outputs them to stdout and optionally into
- * a file.
- *
- * @param data Unused.
- *
- * @return Always EOK (unreachable).
- *
- */
-static int consumer(void *data)
-{
-	FILE *log = fopen(LOG_FNAME, "a");
-	if (log == NULL)
-		printf("%s: Unable to create log file %s (%s)\n", NAME, LOG_FNAME,
-		    str_error(errno));
-	
-	while (true) {
-		link_t *link = prodcons_consume(&pc);
-		item_t *item = list_get_instance(link, item_t, link);
-		
-		for (size_t i = 0; i < item->length; i++)
-			putchar(item->data[i]);
-		
-		if (log != NULL) {
-			for (size_t i = 0; i < item->length; i++)
-				fputc(item->data[i], log);
-			
-			fflush(log);
-			fsync(fileno(log));
-		}
-		
-		free(item->data);
-		free(item);
-	}
-	
-	fclose(log);
-	return EOK;
-}
-
-/** Kernel notification handler
- *
- * Receives kernel klog notifications.
- *
- * @param callid IPC call ID
- * @param call   IPC call structure
- * @param arg    Local argument
- *
- */
-static void notification_received(ipc_callid_t callid, ipc_call_t *call)
-{
-	/*
-	 * Make sure we process only a single notification
-	 * at any time to limit the chance of the consumer
-	 * starving.
-	 *
-	 * Note: Usually the automatic masking of the klog
-	 * notifications on the kernel side does the trick
-	 * of limiting the chance of accidentally copying
-	 * the same data multiple times. However, due to
-	 * the non-blocking architecture of klog notifications,
-	 * this possibility cannot be generally avoided.
-	 */
-	
-	fibril_mutex_lock(&mtx);
-	
-	size_t klog_start = (size_t) IPC_GET_ARG1(*call);
-	size_t klog_len = (size_t) IPC_GET_ARG2(*call);
-	size_t klog_stored = (size_t) IPC_GET_ARG3(*call);
-	
-	size_t offset = (klog_start + klog_len - klog_stored) % klog_length;
-	
-	/* Copy data from the ring buffer */
-	if (offset + klog_stored >= klog_length) {
-		size_t split = klog_length - offset;
-		
-		producer(split, klog + offset);
-		producer(klog_stored - split, klog);
-	} else
-		producer(klog_stored, klog + offset);
-	
-	event_unmask(EVENT_KLOG);
-	fibril_mutex_unlock(&mtx);
-}
-
-int main(int argc, char *argv[])
-{
-	size_t pages;
-	int rc = sysinfo_get_value("klog.pages", &pages);
-	if (rc != EOK) {
-		fprintf(stderr, "%s: Unable to get number of klog pages\n",
-		    NAME);
-		return rc;
-	}
-	
-	uintptr_t faddr;
-	rc = sysinfo_get_value("klog.faddr", &faddr);
-	if (rc != EOK) {
-		fprintf(stderr, "%s: Unable to get klog physical address\n",
-		    NAME);
-		return rc;
-	}
-	
-	size_t size = pages * PAGE_SIZE;
-	klog_length = size / sizeof(wchar_t);
-	
-	rc = physmem_map(faddr, pages, AS_AREA_READ | AS_AREA_CACHEABLE,
-	    (void *) &klog);
-	if (rc != EOK) {
-		fprintf(stderr, "%s: Unable to map klog\n", NAME);
-		return rc;
-	}
-	
-	prodcons_initialize(&pc);
-	async_set_interrupt_received(notification_received);
-	rc = event_subscribe(EVENT_KLOG, 0);
-	if (rc != EOK) {
-		fprintf(stderr, "%s: Unable to register klog notifications\n",
-		    NAME);
-		return rc;
-	}
-	
-	fid_t fid = fibril_create(consumer, NULL);
-	if (!fid) {
-		fprintf(stderr, "%s: Unable to create consumer fibril\n",
-		    NAME);
-		return ENOMEM;
-	}
-	
-	tinput_t *input = tinput_new();
-	if (!input) {
-		fprintf(stderr, "%s: Could not create input\n", NAME);
-		return ENOMEM;
-	}	
-
-	fibril_add_ready(fid);
-	event_unmask(EVENT_KLOG);
-	klog_update();
-	
-	tinput_set_prompt(input, "klog> ");
-
-	char *str;
-	while ((rc = tinput_read(input, &str)) == EOK) {
-		if (str_cmp(str, "") == 0) {
-			free(str);
-			continue;
-		}
-
-		klog_command(str, str_size(str));
-		free(str);
-	}
- 
-	if (rc == ENOENT)
-		rc = EOK;	
-
-	return EOK;
-}
-
-/** @}
- */
Index: uspace/app/mkbd/Makefile
===================================================================
--- uspace/app/mkbd/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/mkbd/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -34,5 +34,6 @@
 	$(LIBUSBDEV_PREFIX)/libusbdev.a \
 	$(LIBUSB_PREFIX)/libusb.a \
-	$(LIBDRV_PREFIX)/libdrv.a 
+	$(LIBDRV_PREFIX)/libdrv.a
+
 EXTRA_CFLAGS = \
 	-I$(LIBUSB_PREFIX)/include \
Index: uspace/app/mkbd/main.c
===================================================================
--- uspace/app/mkbd/main.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/mkbd/main.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -45,5 +45,5 @@
 #include <loc.h>
 #include <usb/dev/hub.h>
-#include <usb/hid/iface.h>
+#include <usbhid_iface.h>
 #include <usb/dev/pipes.h>
 #include <async.h>
Index: uspace/app/sportdmp/Makefile
===================================================================
--- uspace/app/sportdmp/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/sportdmp/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -28,6 +28,6 @@
 
 USPACE_PREFIX = ../..
-#LIBS = 
-#EXTRA_CFLAGS = 
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS = -I$(LIBDRV_PREFIX)/include
 BINARY = sportdmp
 
Index: uspace/app/sportdmp/sportdmp.c
===================================================================
--- uspace/app/sportdmp/sportdmp.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/sportdmp/sportdmp.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -27,5 +27,5 @@
  */
 
-#include <device/char_dev.h>
+#include <char_dev_iface.h>
 #include <errno.h>
 #include <ipc/serial_ctl.h>
Index: uspace/app/tester/Makefile
===================================================================
--- uspace/app/tester/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/tester/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -29,6 +29,14 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBSOFTFLOAT_PREFIX)/libsoftfloat.a
-EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX) -I$(LIBSOFTFLOAT_PREFIX)
+LIBS = \
+	$(LIBBLOCK_PREFIX)/libblock.a \
+	$(LIBSOFTFLOAT_PREFIX)/libsoftfloat.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+
+EXTRA_CFLAGS = \
+	-I$(LIBBLOCK_PREFIX) \
+	-I$(LIBSOFTFLOAT_PREFIX) \
+	-I$(LIBDRV_PREFIX)/include
+
 BINARY = tester
 
@@ -37,4 +45,5 @@
 	util.c \
 	thread/thread1.c \
+	thread/setjmp1.c \
 	print/print1.c \
 	print/print2.c \
Index: uspace/app/tester/hw/misc/virtchar1.c
===================================================================
--- uspace/app/tester/hw/misc/virtchar1.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/tester/hw/misc/virtchar1.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -40,5 +40,5 @@
 #include <sys/types.h>
 #include <async.h>
-#include <device/char_dev.h>
+#include <char_dev_iface.h>
 #include <str.h>
 #include <vfs/vfs.h>
Index: uspace/app/tester/hw/serial/serial1.c
===================================================================
--- uspace/app/tester/hw/serial/serial1.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/tester/hw/serial/serial1.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -43,5 +43,5 @@
 #include <ipc/services.h>
 #include <loc.h>
-#include <device/char_dev.h>
+#include <char_dev_iface.h>
 #include <str.h>
 #include <ipc/serial_ctl.h>
Index: uspace/app/tester/tester.c
===================================================================
--- uspace/app/tester/tester.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/tester/tester.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -48,4 +48,5 @@
 test_t tests[] = {
 #include "thread/thread1.def"
+#include "thread/setjmp1.def"
 #include "print/print1.def"
 #include "print/print2.def"
Index: uspace/app/tester/tester.h
===================================================================
--- uspace/app/tester/tester.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/tester/tester.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -39,4 +39,5 @@
 #include <stdbool.h>
 #include <stacktrace.h>
+#include <stdio.h>
 
 #define IPC_TEST_SERVICE  10240
@@ -80,4 +81,5 @@
 
 extern const char *test_thread1(void);
+extern const char *test_setjmp1(void);
 extern const char *test_print1(void);
 extern const char *test_print2(void);
Index: uspace/app/tester/thread/setjmp1.c
===================================================================
--- uspace/app/tester/thread/setjmp1.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/tester/thread/setjmp1.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2013 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.
+ */
+
+#include <setjmp.h>
+#include <stdlib.h>
+#include "../tester.h"
+
+static jmp_buf jmp_env;
+static int counter;
+
+static void do_the_long_jump(void) {
+	TPRINTF("Will do a long jump back to test_it().\n");
+	longjmp(jmp_env, 1);
+}
+
+static const char *test_it(void) {
+	int second_round = setjmp(jmp_env);
+	counter++;
+	TPRINTF("Just after setjmp(), counter is %d.\n", counter);
+	if (second_round) {
+		if (counter != 2) {
+			return "setjmp() have not returned twice";
+		} else {
+			return NULL;
+		}
+	}
+
+	if (counter != 1) {
+		return "Shall not reach here more than once";
+	}
+
+	do_the_long_jump();
+
+	return "Survived a long jump";
+}
+
+const char *test_setjmp1(void)
+{
+	counter = 0;
+	
+	const char *err_msg = test_it();
+	
+	return err_msg;
+}
Index: uspace/app/tester/thread/setjmp1.def
===================================================================
--- uspace/app/tester/thread/setjmp1.def	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/tester/thread/setjmp1.def	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,6 @@
+{
+	"setjmp1",
+	"Long jump test",
+	&test_setjmp1,
+	true
+},
Index: uspace/app/trace/syscalls.c
===================================================================
--- uspace/app/trace/syscalls.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/trace/syscalls.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -38,5 +38,5 @@
 
 const sc_desc_t syscall_desc[] = {
-    [SYS_KLOG] ={ "klog",				3,	V_INT_ERRNO },
+    [SYS_KIO] ={ "kio",					3,	V_INT_ERRNO },
     [SYS_TLS_SET] = { "tls_set",			1,	V_ERRNO },
 
Index: uspace/app/untar/Makefile
===================================================================
--- uspace/app/untar/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/untar/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2013 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.
+#
+
+USPACE_PREFIX = ../..
+BINARY = untar
+
+SOURCES = \
+	main.c \
+	tar.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/untar/main.c
===================================================================
--- uspace/app/untar/main.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/untar/main.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2013 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 untar
+ * @{
+ */
+/** @file
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <str_error.h>
+#include "tar.h"
+
+static size_t get_block_count(size_t bytes) {
+	return (bytes + TAR_BLOCK_SIZE - 1) / TAR_BLOCK_SIZE;
+}
+
+static int skip_blocks(FILE *tarfile, size_t valid_data_size)
+{
+	size_t blocks_to_read = get_block_count(valid_data_size);
+	while (blocks_to_read > 0) {
+		uint8_t block[TAR_BLOCK_SIZE];
+		size_t actually_read = fread(block, TAR_BLOCK_SIZE, 1, tarfile);
+		if (actually_read != 1) {
+			return errno;
+		}
+		blocks_to_read--;
+	}
+	return EOK;
+}
+
+static int handle_normal_file(const tar_header_t *header, FILE *tarfile)
+{
+	// FIXME: create the directory first
+
+	FILE *file = fopen(header->filename, "wb");
+	if (file == NULL) {
+		fprintf(stderr, "Failed to create %s: %s.\n", header->filename,
+		    str_error(errno));
+		return errno;
+	}
+
+	int rc = EOK;
+	size_t bytes_remaining = header->size;
+	size_t blocks = get_block_count(bytes_remaining);
+	while (blocks > 0) {
+		uint8_t block[TAR_BLOCK_SIZE];
+		size_t actually_read = fread(block, 1, TAR_BLOCK_SIZE, tarfile);
+		if (actually_read != TAR_BLOCK_SIZE) {
+			rc = errno;
+			fprintf(stderr, "Failed to read block for %s: %s.\n",
+			    header->filename, str_error(rc));
+			break;
+		}
+		size_t to_write = TAR_BLOCK_SIZE;
+		if (bytes_remaining < TAR_BLOCK_SIZE) {
+			to_write = bytes_remaining;
+		}
+		size_t actually_written = fwrite(block, 1, to_write, file);
+		if (actually_written != to_write) {
+			rc = errno;
+			fprintf(stderr, "Failed to write to %s: %s.\n",
+			    header->filename, str_error(rc));
+			break;
+		}
+		blocks--;
+		bytes_remaining -= TAR_BLOCK_SIZE;
+	}
+
+	fclose(file);
+
+	return rc;
+}
+
+static int handle_directory(const tar_header_t *header, FILE *tarfile)
+{
+	int rc = mkdir(header->filename, 0755);
+	if ((rc == EEXIST) || (rc == EEXISTS)) {
+		// printf("Note: directory %s already exists.\n", header->filename);
+		rc = EOK;
+	}
+	if (rc != EOK) {
+		fprintf(stderr, "Failed to create directory %s: %s.\n",
+		    header->filename, str_error(rc));
+		return rc;
+	}
+
+	return skip_blocks(tarfile, header->size);
+}
+
+int main(int argc, char *argv[])
+{
+	if (argc != 2) {
+		fprintf(stderr, "Usage: %s tar-file\n", argv[0]);
+		return 1;
+	}
+
+	const char *filename = argv[1];
+
+	FILE *tarfile = fopen(filename, "rb");
+	if (tarfile == NULL) {
+		fprintf(stderr, "Failed to open `%s': %s.\n", filename, str_error(errno));
+		return 2;
+	}
+
+	while (true) {
+		size_t header_ok;
+		tar_header_raw_t header_raw;
+		tar_header_t header;
+		header_ok = fread(&header_raw, sizeof(header_raw), 1, tarfile);
+		if (header_ok != 1) {
+			break;
+		}
+		int rc = tar_header_parse(&header, &header_raw);
+		if (rc == EEMPTY) {
+			continue;
+		}
+		if (rc != EOK) {
+			fprintf(stderr, "Failed parsing TAR header: %s.\n", str_error(rc));
+			break;
+		}
+
+		//printf(" ==> %s (%zuB, type %s)\n", header.filename,
+		//    header.size, tar_type_str(header.type));
+
+		switch (header.type) {
+		case TAR_TYPE_DIRECTORY:
+			rc = handle_directory(&header, tarfile);
+			break;
+		case TAR_TYPE_NORMAL:
+			rc = handle_normal_file(&header, tarfile);
+			break;
+		default:
+			rc = skip_blocks(tarfile, header.size);
+			break;
+		}
+		if (rc != EOK) {
+			break;
+		}
+
+	}
+
+	fclose(tarfile);
+
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/untar/tar.c
===================================================================
--- uspace/app/untar/tar.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/untar/tar.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2013 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 untar
+ * @{
+ */
+/** @file
+ */
+
+#include <str.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "tar.h"
+
+tar_type_t tar_type_parse(const char type) {
+	switch (type) {
+	case '0':
+	case 0:
+		return TAR_TYPE_NORMAL;
+	case '5':
+		return TAR_TYPE_DIRECTORY;
+	default:
+		return TAR_TYPE_UNKNOWN;
+	}
+}
+
+const char *tar_type_str(tar_type_t type) {
+	switch (type) {
+	case TAR_TYPE_UNKNOWN:
+		return "unknown";
+	case TAR_TYPE_NORMAL:
+		return "normal";
+	case TAR_TYPE_DIRECTORY:
+		return "directory";
+	default:
+		assert(false && "unexpected tar_type_t enum value");
+		return "?";
+	}
+}
+
+int tar_header_parse(tar_header_t *parsed, const tar_header_raw_t *raw)
+{
+	int rc;
+
+	if (str_length(raw->filename) == 0) {
+		return EEMPTY;
+	}
+
+	size_t size;
+	rc = str_size_t(raw->size, NULL, 8, true, &size);
+	if (rc != EOK) {
+		return rc;
+	}
+	parsed->size = size;
+
+	str_cpy(parsed->filename, 100, raw->filename);
+
+	parsed->type = tar_type_parse(raw->type);
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/app/untar/tar.h
===================================================================
--- uspace/app/untar/tar.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/app/untar/tar.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2013 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 untar
+ * @{
+ */
+/** @file
+ */
+#ifndef TAR_H_GUARD
+#define TAR_H_GUARD
+
+#define TAR_BLOCK_SIZE 512
+
+typedef struct tar_header_raw {
+	char filename[100];
+	char permissions[8];
+	char owner[8];
+	char group[8];
+	char size[12];
+	char modification_time[12];
+	char checksum[8];
+	char type;
+	char name[100];
+	char ustar_magic[6];
+	char ustar_version[2];
+	char ustar_owner_name[32];
+	char ustar_group_name[32];
+	char ustar_device_major[8];
+	char ustar_device_minor[8];
+	char ustar_prefix[155];
+	char ignored[12];
+} tar_header_raw_t;
+
+typedef enum tar_type {
+	TAR_TYPE_UNKNOWN,
+	TAR_TYPE_NORMAL,
+	TAR_TYPE_DIRECTORY
+} tar_type_t;
+
+typedef struct tar_header {
+	char filename[100];
+	size_t size;
+	tar_type_t type;
+} tar_header_t;
+
+
+extern int tar_header_parse(tar_header_t *, const tar_header_raw_t *);
+extern tar_type_t tar_type_parse(const char);
+extern const char *tar_type_str(tar_type_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/app/vdemo/vdemo.c
===================================================================
--- uspace/app/vdemo/vdemo.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/vdemo/vdemo.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -110,5 +110,5 @@
 {
 	if (argc >= 2) {
-		window_t *main_window = window_open(argv[1], true, true, "vdemo", 0, 0);
+		window_t *main_window = window_open(argv[1], true, true, "vdemo");
 		if (!main_window) {
 			printf("Cannot open main window.\n");
@@ -117,12 +117,18 @@
 
 		pixel_t grd_bg = PIXEL(255, 240, 240, 240);
-		pixel_t btn_bg = PIXEL(255, 0, 0, 0);
-		pixel_t btn_fg = PIXEL(255, 240, 240, 240);
+		
+		pixel_t btn_bg = PIXEL(255, 240, 240, 240);
+		pixel_t btn_fg = PIXEL(255, 186, 186, 186);
+		pixel_t btn_text = PIXEL(255, 0, 0, 0);
+		
 		pixel_t lbl_bg = PIXEL(255, 240, 240, 240);
-		pixel_t lbl_fg = PIXEL(255, 0, 0, 0);
+		pixel_t lbl_text = PIXEL(255, 0, 0, 0);
 
-		my_label_t *lbl_action = create_my_label(NULL, "Hello there!", 16, lbl_bg, lbl_fg);
-		button_t *btn_confirm = create_button(NULL, "Confirm", 16, btn_bg, btn_fg);
-		button_t *btn_cancel = create_button(NULL, "Cancel", 16, btn_bg, btn_fg);
+		my_label_t *lbl_action = create_my_label(NULL, "Hello there!", 16,
+		    lbl_bg, lbl_text);
+		button_t *btn_confirm = create_button(NULL, "Confirm", 16, btn_bg,
+		    btn_fg, btn_text);
+		button_t *btn_cancel = create_button(NULL, "Cancel", 16, btn_bg,
+		    btn_fg, btn_text);
 		grid_t *grid = create_grid(window_root(main_window), 2, 2, grd_bg);
 		if (!lbl_action || !btn_confirm || !btn_cancel || !grid) {
@@ -144,5 +150,6 @@
 		grid->add(grid, &btn_confirm->widget, 0, 1, 1, 1);
 		grid->add(grid, &btn_cancel->widget, 1, 1, 1, 1);
-		window_resize(main_window, 200, 76);
+		window_resize(main_window, 0, 0, 200, 76,
+		    WINDOW_PLACEMENT_CENTER);
 
 		window_exec(main_window);
Index: uspace/app/viewer/viewer.c
===================================================================
--- uspace/app/viewer/viewer.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/viewer/viewer.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -166,5 +166,5 @@
 	}
 	
-	main_window = window_open(argv[1], true, false, "viewer", 0, 0);
+	main_window = window_open(argv[1], true, false, "viewer");
 	if (!main_window) {
 		printf("Cannot open main window.\n");
@@ -192,5 +192,6 @@
 	}
 	
-	window_resize(main_window, WINDOW_WIDTH, WINDOW_HEIGHT);
+	window_resize(main_window, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT,
+	    WINDOW_PLACEMENT_ABSOLUTE);
 	window_exec(main_window);
 	
Index: uspace/app/vlaunch/vlaunch.c
===================================================================
--- uspace/app/vlaunch/vlaunch.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/vlaunch/vlaunch.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -115,5 +115,5 @@
 	
 	winreg = argv[1];
-	window_t *main_window = window_open(argv[1], true, true, "vlaunch", 0, 0);
+	window_t *main_window = window_open(argv[1], true, true, "vlaunch");
 	if (!main_window) {
 		printf("Cannot open main window.\n");
@@ -122,19 +122,22 @@
 	
 	pixel_t grd_bg = PIXEL(255, 255, 255, 255);
-	pixel_t btn_bg = PIXEL(255, 0, 0, 0);
-	pixel_t btn_fg = PIXEL(255, 240, 240, 240);
+	
+	pixel_t btn_bg = PIXEL(255, 255, 255, 255);
+	pixel_t btn_fg = PIXEL(255, 186, 186, 186);
+	pixel_t btn_text = PIXEL(255, 0, 0, 0);
+	
 	pixel_t lbl_bg = PIXEL(255, 255, 255, 255);
-	pixel_t lbl_fg = PIXEL(255, 0, 0, 0);
+	pixel_t lbl_text = PIXEL(255, 0, 0, 0);
 	
 	canvas_t *logo_canvas = create_canvas(NULL, LOGO_WIDTH, LOGO_HEIGHT,
 	    logo);
 	label_t *lbl_caption = create_label(NULL, "Launch application:", 16,
-	    lbl_bg, lbl_fg);
+	    lbl_bg, lbl_text);
 	button_t *btn_vterm = create_button(NULL, "vterm", 16, btn_bg,
-	    btn_fg);
+	    btn_fg, btn_text);
 	button_t *btn_vdemo = create_button(NULL, "vdemo", 16, btn_bg,
-	    btn_fg);
+	    btn_fg, btn_text);
 	button_t *btn_vlaunch = create_button(NULL, "vlaunch", 16, btn_bg,
-	    btn_fg);
+	    btn_fg, btn_text);
 	grid_t *grid = create_grid(window_root(main_window), 1, 5, grd_bg);
 	
@@ -156,5 +159,6 @@
 	grid->add(grid, &btn_vlaunch->widget, 0, 4, 1, 1);
 	
-	window_resize(main_window, 210, 130 + LOGO_HEIGHT);
+	window_resize(main_window, 0, 0, 210, 130 + LOGO_HEIGHT,
+	    WINDOW_PLACEMENT_RIGHT | WINDOW_PLACEMENT_TOP);
 	window_exec(main_window);
 	
Index: uspace/app/vterm/vterm.c
===================================================================
--- uspace/app/vterm/vterm.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/vterm/vterm.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -49,5 +49,5 @@
 	}
 	
-	window_t *main_window = window_open(argv[1], true, true, "vterm", 0, 0);
+	window_t *main_window = window_open(argv[1], true, true, "vterm");
 	if (!main_window) {
 		printf("%s: Cannot open main window.\n", NAME);
@@ -55,5 +55,5 @@
 	}
 	
-	window_resize(main_window, 650, 510);
+	window_resize(main_window, 0, 0, 648, 508, WINDOW_PLACEMENT_ANY);
 	terminal_t *terminal_widget =
 	    create_terminal(window_root(main_window), 640, 480);
Index: uspace/dist/src/c/demos/hello/build.gcc
===================================================================
--- uspace/dist/src/c/demos/hello/build.gcc	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/dist/src/c/demos/hello/build.gcc	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,2 @@
+gcc -nostdlib -nostdinc -I/inc/c -Wl,-T/inc/_link.ld -L/lib -lc -lsoftint -o hello hello.c
+
Index: uspace/dist/src/c/demos/tetris/build.gcc
===================================================================
--- uspace/dist/src/c/demos/tetris/build.gcc	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/dist/src/c/demos/tetris/build.gcc	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,6 @@
+gcc -nostdinc -I/inc/c -c -Drestrict= scores.c
+gcc -nostdinc -I/inc/c -c -Drestrict= screen.c
+gcc -nostdinc -I/inc/c -c -Drestrict= shapes.c
+gcc -nostdinc -I/inc/c -c -Drestrict= tetris.c
+gcc -nostdlib -Wl,-T/inc/_link.ld -L/lib -o tetris_ scores.o screen.o shapes.o tetris.o -lc -lsoftint
+
Index: uspace/dist/src/c/demos/tetris/screen.c
===================================================================
--- uspace/dist/src/c/demos/tetris/screen.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/dist/src/c/demos/tetris/screen.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -344,7 +344,7 @@
 	
 	while (timeout > 0) {
-		kbd_event_t event;
-		
-		if (!console_get_kbd_event_timeout(console, &event, &timeout))
+		cons_event_t event;
+		
+		if (!console_get_event_timeout(console, &event, &timeout))
 			break;
 	}
@@ -376,13 +376,13 @@
 	
 	while (c == 0) {
-		kbd_event_t event;
-		
-		if (!console_get_kbd_event_timeout(console, &event, &timeleft)) {
+		cons_event_t event;
+		
+		if (!console_get_event_timeout(console, &event, &timeleft)) {
 			timeleft = 0;
 			return -1;
 		}
 		
-		if (event.type == KEY_PRESS)
-			c = event.c;
+		if (event.type == CEV_KEY && event.ev.key.type == KEY_PRESS)
+			c = event.ev.key.c;
 	}
 	
@@ -398,11 +398,11 @@
 	
 	while (c == 0) {
-		kbd_event_t event;
-		
-		if (!console_get_kbd_event(console, &event))
+		cons_event_t event;
+		
+		if (!console_get_event(console, &event))
 			return -1;
 		
-		if (event.type == KEY_PRESS)
-			c = event.c;
+		if (event.type == CEV_KEY && event.ev.key.type == KEY_PRESS)
+			c = event.ev.key.c;
 	}
 	
Index: uspace/dist/src/python/demo/hello.py
===================================================================
--- uspace/dist/src/python/demo/hello.py	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/dist/src/python/demo/hello.py	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,4 @@
+#!/usr/bin/python
+
+print("Hello, World!")
+
Index: uspace/dist/src/python/demo/sintab.py
===================================================================
--- uspace/dist/src/python/demo/sintab.py	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/dist/src/python/demo/sintab.py	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,23 @@
+#!/usr/bin/python
+
+# Probably not very Pythonic, but it runs well with both Python2 and Python3
+
+import math
+import sys
+
+sys.stdout.write("    ")
+for frac_part in range(0,10):
+	sys.stdout.write(" %5d" % frac_part)
+print("")
+
+for angle_deg in range(0,90):
+	sys.stdout.write("%3d " % angle_deg)
+	for angle_deg_frac in range(0,10):
+		angle = math.radians(angle_deg + angle_deg_frac/10.)
+		value = math.sin(angle) * 10000 + 0.5
+		if value > 10000:
+			sys.stdout.write(" %05d" % (value))
+		else:
+			sys.stdout.write("  %04d" % (value))
+	print("")
+
Index: uspace/dist/src/python/modules.py
===================================================================
--- uspace/dist/src/python/modules.py	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/dist/src/python/modules.py	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,15 @@
+#!/usr/bin/python
+
+import sys
+
+for m in sys.builtin_module_names:
+	print("Built-in module '%s'." % m)
+
+try:
+	import pkgutil
+	for (loader, name, ispkg) in pkgutil.iter_modules():
+		print("Loadable module '%s'." % name)
+except ImportError:
+	print("Cannot determine list of loadable modules (pkgutil not found)!")
+
+
Index: uspace/drv/block/ahci/ahci.c
===================================================================
--- uspace/drv/block/ahci/ahci.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/block/ahci/ahci.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -37,5 +37,5 @@
 #include <ddf/log.h>
 #include <device/hw_res_parsed.h>
-#include <device/pci.h>
+#include <pci_dev_iface.h>
 #include <sysinfo.h>
 #include <ipc/irc.h>
@@ -111,9 +111,9 @@
 	}
 
-static int ahci_get_sata_device_name(ddf_fun_t *, size_t, char *);
-static int ahci_get_num_blocks(ddf_fun_t *, uint64_t *);
-static int ahci_get_block_size(ddf_fun_t *, size_t *);
-static int ahci_read_blocks(ddf_fun_t *, uint64_t, size_t, void *);
-static int ahci_write_blocks(ddf_fun_t *, uint64_t, size_t, void *);
+static int get_sata_device_name(ddf_fun_t *, size_t, char *);
+static int get_num_blocks(ddf_fun_t *, uint64_t *);
+static int get_block_size(ddf_fun_t *, size_t *);
+static int read_blocks(ddf_fun_t *, uint64_t, size_t, void *);
+static int write_blocks(ddf_fun_t *, uint64_t, size_t, void *);
 
 static int ahci_identify_device(sata_dev_t *);
@@ -139,9 +139,9 @@
 
 static ahci_iface_t ahci_interface = {
-	.get_sata_device_name = &ahci_get_sata_device_name,
-	.get_num_blocks = &ahci_get_num_blocks,
-	.get_block_size = &ahci_get_block_size,
-	.read_blocks = &ahci_read_blocks,
-	.write_blocks = &ahci_write_blocks
+	.get_sata_device_name = &get_sata_device_name,
+	.get_num_blocks = &get_num_blocks,
+	.get_block_size = &get_block_size,
+	.read_blocks = &read_blocks,
+	.write_blocks = &write_blocks
 };
 
@@ -180,5 +180,5 @@
  *
  */
-static int ahci_get_sata_device_name(ddf_fun_t *fun,
+static int get_sata_device_name(ddf_fun_t *fun,
     size_t sata_dev_name_length, char *sata_dev_name)
 {
@@ -196,5 +196,5 @@
  *
  */
-static int ahci_get_num_blocks(ddf_fun_t *fun, uint64_t *num_blocks)
+static int get_num_blocks(ddf_fun_t *fun, uint64_t *num_blocks)
 {
 	sata_dev_t *sata = fun_sata_dev(fun);
@@ -211,5 +211,5 @@
  *
  */
-static int ahci_get_block_size(ddf_fun_t *fun, size_t *block_size)
+static int get_block_size(ddf_fun_t *fun, size_t *block_size)
 {
 	sata_dev_t *sata = fun_sata_dev(fun);
@@ -228,5 +228,5 @@
  *
  */
-static int ahci_read_blocks(ddf_fun_t *fun, uint64_t blocknum,
+static int read_blocks(ddf_fun_t *fun, uint64_t blocknum,
     size_t count, void *buf)
 {
@@ -271,5 +271,5 @@
  *
  */
-static int ahci_write_blocks(ddf_fun_t *fun, uint64_t blocknum,
+static int write_blocks(ddf_fun_t *fun, uint64_t blocknum,
     size_t count, void *buf)
 {
Index: uspace/drv/bus/amba/Makefile
===================================================================
--- uspace/drv/bus/amba/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/drv/bus/amba/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2010 Lenka Trochtova
+# 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 = $(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
+BINARY = amba
+
+SOURCES = \
+	amba.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/bus/amba/amba.c
===================================================================
--- uspace/drv/bus/amba/amba.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/drv/bus/amba/amba.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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.
+ */
+
+/**
+ * @defgroup amba AMBA bus driver.
+ * @brief HelenOS AMBA bus driver.
+ * @{
+ */
+/** @file
+ */
+
+#include <assert.h>
+#include <byteorder.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <fibril_synch.h>
+#include <str.h>
+#include <ctype.h>
+#include <macros.h>
+#include <str_error.h>
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <ipc/dev_iface.h>
+#include <ipc/irc.h>
+#include <ns.h>
+#include <ipc/services.h>
+#include <sysinfo.h>
+#include <ops/hw_res.h>
+#include <device/hw_res.h>
+#include <ddi.h>
+#include "ambapp.h"
+
+#define NAME  "amba"
+#define ID_MAX_STR_LEN  32
+
+#define LVL_DEBUG  LVL_ERROR
+
+typedef struct leon_amba_bus {
+	/** DDF device node */
+	ddf_dev_t *dnode;
+	uintptr_t master_area_addr;
+	uintptr_t slave_area_addr;
+	size_t master_area_size;
+	size_t slave_area_size;
+	void *master_area;
+	void *slave_area;
+	fibril_mutex_t area_mutex;
+} amba_bus_t;
+
+typedef struct amba_fun_data {
+	amba_bus_t *busptr;
+	ddf_fun_t *fnode;
+	int bus;
+	int index;
+	uint8_t vendor_id;
+	uint32_t device_id;
+	int version;
+	hw_resource_list_t hw_resources;
+	hw_resource_t resources[AMBA_MAX_HW_RES];
+} amba_fun_t;
+
+static amba_fun_t *amba_fun_new(amba_bus_t *);
+static void amba_fun_set_name(amba_fun_t *);
+static void amba_fun_create_match_ids(amba_fun_t *);
+static int amba_fun_online(ddf_fun_t *);
+static int amba_fun_offline(ddf_fun_t *);
+static hw_resource_list_t *amba_get_resources(ddf_fun_t *);
+static bool amba_enable_interrupt(ddf_fun_t *);
+static void amba_add_bar(amba_fun_t *, uintptr_t, size_t);
+static void amba_add_interrupt(amba_fun_t *, int);
+static int amba_bus_scan(amba_bus_t *, void *, unsigned int);
+static void amba_fake_scan(amba_bus_t *);
+static int amba_dev_add(ddf_dev_t *);
+
+static hw_res_ops_t amba_fun_hw_res_ops = {
+	.get_resource_list = &amba_get_resources,
+	.enable_interrupt = &amba_enable_interrupt
+};
+
+static ddf_dev_ops_t amba_fun_ops = {
+	.interfaces[HW_RES_DEV_IFACE] = &amba_fun_hw_res_ops
+};
+
+static driver_ops_t amba_ops = {
+	.dev_add = &amba_dev_add,
+	.fun_online = &amba_fun_online,
+	.fun_offline = &amba_fun_offline
+};
+
+static driver_t amba_driver = {
+	.name = NAME,
+	.driver_ops = &amba_ops
+};
+
+static amba_fun_t *amba_fun_new(amba_bus_t *bus)
+{
+	ddf_msg(LVL_DEBUG, "amba_fun_new(): bus=%p, bus->dnode=%p", bus,
+	    bus->dnode);
+	
+	ddf_fun_t *fnode = ddf_fun_create(bus->dnode, fun_inner, NULL);
+	if (fnode == NULL)
+		return NULL;
+	
+	ddf_msg(LVL_DEBUG, "amba_fun_new(): created");
+	
+	amba_fun_t *fun = ddf_fun_data_alloc(fnode, sizeof(amba_fun_t));
+	if (fun == NULL)
+		return NULL;
+	
+	ddf_msg(LVL_DEBUG, "amba_fun_new(): allocated data");
+	
+	fun->busptr = bus;
+	fun->fnode = fnode;
+	return fun;
+}
+
+static void amba_fun_set_name(amba_fun_t *fun)
+{
+	char *name = NULL;
+	
+	asprintf(&name, "%02x:%02x", fun->bus, fun->index);
+	ddf_fun_set_name(fun->fnode, name);
+}
+
+static void amba_fun_create_match_ids(amba_fun_t *fun)
+{
+	/* Vendor ID & Device ID */
+	char match_id_str[ID_MAX_STR_LEN];
+	int rc = snprintf(match_id_str, ID_MAX_STR_LEN, "amba/ven=%02x&dev=%08x",
+	    fun->vendor_id, fun->device_id);
+	if (rc < 0) {
+		ddf_msg(LVL_ERROR, "Failed creating match ID str: %s",
+		    str_error(rc));
+	}
+	
+	rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 90);
+}
+
+static int amba_fun_online(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "amba_fun_online()");
+	return ddf_fun_online(fun);
+
+}
+
+static int amba_fun_offline(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "amba_fun_offline()");
+	return ddf_fun_offline(fun);
+}
+
+static hw_resource_list_t *amba_get_resources(ddf_fun_t *fnode)
+{
+	amba_fun_t *fun = ddf_fun_data_get(fnode);
+	
+	if (fun == NULL)
+		return NULL;
+	
+	return &fun->hw_resources;
+}
+
+static bool amba_enable_interrupt(ddf_fun_t *fnode)
+{
+	return true;
+}
+
+static void amba_alloc_resource_list(amba_fun_t *fun)
+{
+	fun->hw_resources.resources = fun->resources;
+}
+
+static void amba_add_bar(amba_fun_t *fun, uintptr_t addr, size_t size)
+{
+	hw_resource_list_t *hw_res_list = &fun->hw_resources;
+	hw_resource_t *hw_resources =  hw_res_list->resources;
+	size_t count = hw_res_list->count;
+	
+	assert(hw_resources != NULL);
+	assert(count < AMBA_MAX_HW_RES);
+	
+	hw_resources[count].type = MEM_RANGE;
+	hw_resources[count].res.mem_range.address = addr;
+	hw_resources[count].res.mem_range.size = size;
+	hw_resources[count].res.mem_range.endianness = BIG_ENDIAN;
+	
+	hw_res_list->count++;
+}
+
+static void amba_add_interrupt(amba_fun_t *fun, int irq)
+{
+	hw_resource_list_t *hw_res_list = &fun->hw_resources;
+	hw_resource_t *hw_resources = hw_res_list->resources;
+	size_t count = hw_res_list->count;
+	
+	assert(NULL != hw_resources);
+	assert(count < AMBA_MAX_HW_RES);
+	
+	hw_resources[count].type = INTERRUPT;
+	hw_resources[count].res.interrupt.irq = irq;
+	
+	hw_res_list->count++;
+	
+	ddf_msg(LVL_NOTE, "Function %s uses irq %x.", ddf_fun_get_name(fun->fnode), irq);
+}
+
+static int amba_bus_scan(amba_bus_t *bus, void *area, unsigned int max_entries)
+{
+	ddf_msg(LVL_DEBUG, "amba_bus_scan(): area=%p, max_entries=%u", area, max_entries);
+	
+	ambapp_entry_t *devices = (ambapp_entry_t *) area;
+	int found = 0;
+	
+	for (unsigned int i = 0; i < max_entries; i++) {
+		ambapp_entry_t *entry = &devices[i];
+		if (entry->vendor_id == 0xff)
+			continue;
+		
+		amba_fun_t *fun = amba_fun_new(bus);
+		fun->bus = 0;
+		fun->index = i;
+		fun->vendor_id = entry->vendor_id;
+		fun->device_id = entry->device_id;
+		fun->version = entry->version;
+		
+		for (unsigned int bnum = 0; bnum < 4; bnum++) {
+			ambapp_bar_t *bar = &entry->bar[bnum];
+			amba_add_bar(fun, bar->addr << 20, bar->mask);
+		}
+		
+		if (entry->irq != -1)
+			amba_add_interrupt(fun, entry->irq);
+		
+		ddf_fun_set_ops(fun->fnode, &amba_fun_ops);
+		ddf_fun_bind(fun->fnode);
+	}
+	
+	return found;
+}
+
+static void amba_fake_scan(amba_bus_t *bus)
+{
+	ddf_msg(LVL_DEBUG, "amba_fake_scan()");
+	
+	/* UART */
+	amba_fun_t *fun = amba_fun_new(bus);
+	fun->bus = 0;
+	fun->index = 0;
+	fun->vendor_id = GAISLER;
+	fun->device_id = GAISLER_APBUART;
+	fun->version = 1;
+	amba_alloc_resource_list(fun);
+	amba_add_bar(fun, 0x80000100, 0x100);
+	amba_add_interrupt(fun, 3);
+	amba_fun_set_name(fun);
+	amba_fun_create_match_ids(fun);
+	ddf_fun_set_ops(fun->fnode, &amba_fun_ops);
+	ddf_fun_bind(fun->fnode);
+	
+	ddf_msg(LVL_DEBUG, "added uart");
+	
+	/* IRQMP */
+	fun = amba_fun_new(bus);
+	fun->bus = 0;
+	fun->index = 1;
+	fun->vendor_id = GAISLER;
+	fun->device_id = GAISLER_IRQMP;
+	fun->version = 1;
+	amba_alloc_resource_list(fun);
+	amba_add_bar(fun, 0x80000200, 0x100);
+	amba_fun_set_name(fun);
+	amba_fun_create_match_ids(fun);
+	ddf_fun_set_ops(fun->fnode, &amba_fun_ops);
+	ddf_fun_bind(fun->fnode);
+	
+	ddf_msg(LVL_DEBUG, "added irqmp");
+	
+	/* GPTIMER */
+	fun = amba_fun_new(bus);
+	fun->bus = 0;
+	fun->index = 2;
+	fun->vendor_id = GAISLER;
+	fun->device_id = GAISLER_GPTIMER;
+	fun->version = 1;
+	amba_alloc_resource_list(fun);
+	amba_add_bar(fun, 0x80000300, 0x100);
+	amba_add_interrupt(fun, 8);
+	amba_fun_set_name(fun);
+	amba_fun_create_match_ids(fun);
+	ddf_fun_set_ops(fun->fnode, &amba_fun_ops);
+	ddf_fun_bind(fun->fnode);
+	
+	ddf_msg(LVL_DEBUG, "added timer");
+}
+
+static int amba_dev_add(ddf_dev_t *dnode)
+{
+	int rc = 0;
+	int found = 0;
+	bool got_res = false;
+	
+	amba_bus_t *bus = ddf_dev_data_alloc(dnode, sizeof(amba_bus_t));
+	if (bus == NULL) {
+		ddf_msg(LVL_ERROR, "amba_dev_add: allocation failed.");
+		rc = ENOMEM;
+		goto fail;
+	}
+	
+	bus->dnode = dnode;
+	async_sess_t *sess = ddf_dev_parent_sess_create(dnode, EXCHANGE_SERIALIZE);
+	if (sess == NULL) {
+		ddf_msg(LVL_ERROR, "amba_dev_add failed to connect to the "
+		    "parent driver.");
+		rc = ENOENT;
+		goto fail;
+	}
+	
+	hw_resource_list_t hw_resources;
+	rc = hw_res_get_resource_list(sess, &hw_resources);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "amba_dev_add failed to get hw resources "
+		    "for the device.");
+		goto fail;
+	}
+	
+	got_res = true;
+	assert(hw_resources.count > 1);
+	
+	bus->master_area_addr = hw_resources.resources[0].res.mem_range.address;
+	bus->master_area_size = hw_resources.resources[0].res.mem_range.size;
+	bus->slave_area_addr = hw_resources.resources[1].res.mem_range.address;
+	bus->slave_area_size = hw_resources.resources[1].res.mem_range.size;
+	
+	ddf_msg(LVL_DEBUG, "AMBA master area: 0x%08x", bus->master_area_addr);
+	ddf_msg(LVL_DEBUG, "AMBA slave area: 0x%08x", bus->slave_area_addr);
+	
+	if (pio_enable((void *)bus->master_area_addr, bus->master_area_size, &bus->master_area)) {
+		ddf_msg(LVL_ERROR, "Failed to enable master area.");
+		rc = EADDRNOTAVAIL;
+		goto fail;
+	}
+	
+	if (pio_enable((void *)bus->slave_area_addr, bus->slave_area_size, &bus->slave_area)) {
+		ddf_msg(LVL_ERROR, "Failed to enable slave area.");
+		rc = EADDRNOTAVAIL;
+		goto fail;
+	}
+	
+	/*
+	 * If nothing is found, we are probably running inside QEMU
+	 * and need to fake AMBA P&P entries.
+	 */
+	if (found == 0)
+		amba_fake_scan(bus);
+	
+	ddf_msg(LVL_DEBUG, "done");
+	
+	return EOK;
+	
+fail:
+	if (got_res)
+		hw_res_clean_resource_list(&hw_resources);
+	
+	return rc;
+}
+
+int main(int argc, char *argv[])
+{
+	printf("%s: HelenOS LEON3 AMBA bus driver\n", NAME);
+	ddf_log_init(NAME);
+	return ddf_driver_main(&amba_driver);
+}
Index: uspace/drv/bus/amba/amba.ma
===================================================================
--- uspace/drv/bus/amba/amba.ma	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/drv/bus/amba/amba.ma	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,1 @@
+10 amba
Index: uspace/drv/bus/amba/ambapp.h
===================================================================
--- uspace/drv/bus/amba/ambapp.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/drv/bus/amba/ambapp.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * Copyright (c) 2011 Jiri Svoboda
+ * Copyright (c) 2013 Jakub Klama
+ * 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 amba
+ * @{
+ */
+/** @file
+ */
+
+#ifndef AMBAPP_H_
+#define AMBAPP_H_
+
+#include <ddf/driver.h>
+
+#define AMBAPP_MAX_DEVICES     64
+#define AMBAPP_AHBMASTER_AREA  0xfffff000
+#define AMBAPP_AHBSLAVE_AREA   0xfffff800
+#define AMBAPP_CONF_AREA       0xff000
+
+#define AMBA_MAX_HW_RES  (4 + 1)
+
+typedef enum {
+	GAISLER = 1,
+	ESA = 4
+} amba_vendor_id_t;
+
+typedef enum {
+	GAISLER_LEON3    = 0x003,
+	GAISLER_LEON3DSU = 0x004,
+	GAISLER_ETHAHB   = 0x005,
+	GAISLER_APBMST   = 0x006,
+	GAISLER_AHBUART  = 0x007,
+	GAISLER_SRCTRL   = 0x008,
+	GAISLER_SDCTRL   = 0x009,
+	GAISLER_APBUART  = 0x00c,
+	GAISLER_IRQMP    = 0x00d,
+	GAISLER_AHBRAM   = 0x00e,
+	GAISLER_GPTIMER  = 0x011,
+	GAISLER_PCITRG   = 0x012,
+	GAISLER_PCISBRG  = 0x013,
+	GAISLER_PCIFBRG  = 0x014,
+	GAISLER_PCITRACE = 0x015,
+	GAISLER_PCIDMA   = 0x016,
+	GAISLER_AHBTRACE = 0x017,
+	GAISLER_ETHDSU   = 0x018,
+	GAISLER_PIOPORT  = 0x01a,
+	GAISLER_AHBJTAG  = 0x01c,
+	GAISLER_SPW      = 0x01f,
+	GAISLER_ATACTRL  = 0x024,
+	GAISLER_VGA      = 0x061,
+	GAISLER_KBD      = 0x060,
+	GAISLER_ETHMAC   = 0x01d,
+	GAISLER_DDRSPA   = 0x025,
+	GAISLER_EHCI     = 0x026,
+	GAISLER_UHCI     = 0x027,
+	GAISLER_SPW2     = 0x029,
+	GAISLER_DDR2SPA  = 0x02e,
+	GAISLER_AHBSTAT  = 0x052,
+	GAISLER_FTMCTRL  = 0x054,
+	ESA_MCTRL        = 0x00f
+} amba_device_id_t;
+
+typedef struct {
+	unsigned int addr : 12;
+	unsigned int reserved : 2;
+	unsigned int prefetchable : 1;
+	unsigned int cacheable : 1;
+	unsigned int mask : 12;
+	unsigned int type : 4;
+} __attribute__((packed)) ambapp_bar_t;
+
+typedef struct {
+	unsigned int vendor_id : 8;
+	unsigned int device_id : 24;
+	unsigned int reserved : 2;
+	unsigned int version : 5;
+	unsigned int irq : 5;
+	uint32_t user_defined[3];
+	ambapp_bar_t bar[4];
+} __attribute__((packed)) ambapp_entry_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/drv/bus/pci/pciintel/pci.c
===================================================================
--- uspace/drv/bus/pci/pciintel/pci.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/bus/pci/pciintel/pci.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -153,5 +153,5 @@
 
 
-static int pci_config_space_write_32(ddf_fun_t *fun, uint32_t address,
+static int config_space_write_32(ddf_fun_t *fun, uint32_t address,
     uint32_t data)
 {
@@ -162,5 +162,5 @@
 }
 
-static int pci_config_space_write_16(
+static int config_space_write_16(
     ddf_fun_t *fun, uint32_t address, uint16_t data)
 {
@@ -171,5 +171,5 @@
 }
 
-static int pci_config_space_write_8(
+static int config_space_write_8(
     ddf_fun_t *fun, uint32_t address, uint8_t data)
 {
@@ -180,5 +180,5 @@
 }
 
-static int pci_config_space_read_32(
+static int config_space_read_32(
     ddf_fun_t *fun, uint32_t address, uint32_t *data)
 {
@@ -189,5 +189,5 @@
 }
 
-static int pci_config_space_read_16(
+static int config_space_read_16(
     ddf_fun_t *fun, uint32_t address, uint16_t *data)
 {
@@ -198,5 +198,5 @@
 }
 
-static int pci_config_space_read_8(
+static int config_space_read_8(
     ddf_fun_t *fun, uint32_t address, uint8_t *data)
 {
@@ -217,10 +217,10 @@
 
 static pci_dev_iface_t pci_dev_ops = {
-	.config_space_read_8 = &pci_config_space_read_8,
-	.config_space_read_16 = &pci_config_space_read_16,
-	.config_space_read_32 = &pci_config_space_read_32,
-	.config_space_write_8 = &pci_config_space_write_8,
-	.config_space_write_16 = &pci_config_space_write_16,
-	.config_space_write_32 = &pci_config_space_write_32
+	.config_space_read_8 = &config_space_read_8,
+	.config_space_read_16 = &config_space_read_16,
+	.config_space_read_32 = &config_space_read_32,
+	.config_space_write_8 = &config_space_write_8,
+	.config_space_write_16 = &config_space_write_16,
+	.config_space_write_32 = &config_space_write_32
 };
 
Index: uspace/drv/bus/usb/ehci/res.c
===================================================================
--- uspace/drv/bus/usb/ehci/res.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/bus/usb/ehci/res.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -43,5 +43,5 @@
 #include <usb/debug.h>
 #include <device/hw_res_parsed.h>
-#include <device/pci.h>
+#include <pci_dev_iface.h>
 
 #include "res.h"
Index: uspace/drv/bus/usb/uhci/res.c
===================================================================
--- uspace/drv/bus/usb/uhci/res.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/bus/usb/uhci/res.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -39,5 +39,5 @@
 #include <devman.h>
 #include <device/hw_res_parsed.h>
-#include <device/pci.h>
+#include <pci_dev_iface.h>
 
 #include "res.h"
@@ -62,5 +62,5 @@
 	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);
+	const int ret = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
 	async_hangup(parent_sess);
 	if (ret != EOK) {
Index: uspace/drv/bus/usb/uhci/root_hub.c
===================================================================
--- uspace/drv/bus/usb/uhci/root_hub.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/bus/usb/uhci/root_hub.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -36,4 +36,5 @@
 #include <str_error.h>
 #include <stdio.h>
+#include <device/hw_res_parsed.h>
 
 #include <usb/debug.h>
@@ -48,8 +49,16 @@
  * @return Error code.
  */
-int rh_init(rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size)
+int
+rh_init(rh_t *instance, ddf_fun_t *fun, addr_range_t *regs, uintptr_t reg_addr,
+    size_t reg_size)
 {
 	assert(instance);
 	assert(fun);
+
+	/* Crop the PIO window to the absolute address range of UHCI I/O. */
+	instance->pio_window.mem.base = 0;
+	instance->pio_window.mem.size = 0;
+	instance->pio_window.io.base = RNGABS(*regs);
+	instance->pio_window.io.size = RNGSZ(*regs);
 
 	/* Initialize resource structure */
@@ -60,4 +69,5 @@
 	instance->io_regs.res.io_range.address = reg_addr;
 	instance->io_regs.res.io_range.size = reg_size;
+	instance->io_regs.res.io_range.relative = true;
 	instance->io_regs.res.io_range.endianness = LITTLE_ENDIAN;
 
Index: uspace/drv/bus/usb/uhci/root_hub.h
===================================================================
--- uspace/drv/bus/usb/uhci/root_hub.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/bus/usb/uhci/root_hub.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -38,4 +38,5 @@
 #include <ddf/driver.h>
 #include <ops/hw_res.h>
+#include <ops/pio_window.h>
 
 /** DDF support structure for uhci_rhd driver, provides I/O resources */
@@ -45,8 +46,9 @@
 	/** The only resource in the RH resource list */
 	hw_resource_t io_regs;
+	/** PIO window in which the RH will operate. */
+	pio_window_t pio_window;	
 } rh_t;
 
-int rh_init(
-    rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size);
+extern int rh_init(rh_t *, ddf_fun_t *, addr_range_t *, uintptr_t, size_t);
 
 #endif
Index: uspace/drv/bus/usb/uhci/uhci.c
===================================================================
--- uspace/drv/bus/usb/uhci/uhci.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/bus/usb/uhci/uhci.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -132,8 +132,22 @@
 };
 
+static pio_window_t *get_pio_window(ddf_fun_t *fun)
+{
+	rh_t *rh = ddf_fun_data_get(fun);
+	
+	if (rh == NULL)
+		return NULL;
+	return &rh->pio_window;
+}
+
+static pio_window_ops_t pio_window_iface = {
+	.get_pio_window = get_pio_window
+};
+
 /** RH function support for uhci_rhd */
 static ddf_dev_ops_t rh_ops = {
 	.interfaces[USB_DEV_IFACE] = &usb_iface,
-	.interfaces[HW_RES_DEV_IFACE] = &hw_res_iface
+	.interfaces[HW_RES_DEV_IFACE] = &hw_res_iface,
+	.interfaces[PIO_WINDOW_DEV_IFACE] = &pio_window_iface
 };
 
@@ -246,6 +260,5 @@
 	}
 
-	rc = rh_init(&instance->rh, instance->rh_fun,
-	    (uintptr_t)instance->hc.registers + 0x10, 4);
+	rc = rh_init(&instance->rh, instance->rh_fun, &regs, 0x10, 4);
 	if (rc != EOK) {
 		usb_log_error("Failed to setup UHCI root hub: %s.\n",
Index: uspace/drv/bus/usb/uhcirh/main.c
===================================================================
--- uspace/drv/bus/usb/uhcirh/main.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/bus/usb/uhcirh/main.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -138,5 +138,5 @@
 	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);
+	const int ret = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
 	async_hangup(parent_sess);
 	if (ret != EOK) {
Index: uspace/drv/char/grlib_uart/Makefile
===================================================================
--- uspace/drv/char/grlib_uart/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/drv/char/grlib_uart/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2013 Jakub Klama
+# 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 = $(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
+BINARY = grlib_uart
+
+SOURCES = \
+	grlib_uart.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/char/grlib_uart/cyclic_buffer.h
===================================================================
--- uspace/drv/char/grlib_uart/cyclic_buffer.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/drv/char/grlib_uart/cyclic_buffer.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * 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 ns8250
+ * @{
+ */
+/** @file
+ */
+
+#ifndef CYCLIC_BUFFER_H_
+#define CYCLIC_BUFFER_H_
+
+#define BUF_LEN 4096
+
+typedef struct cyclic_buffer {
+	uint8_t buf[BUF_LEN];
+	int start;
+	int cnt;
+}  cyclic_buffer_t;
+
+/*
+ * @return		False if the buffer is full.
+ */
+static inline bool buf_push_back(cyclic_buffer_t *buf, uint8_t item)
+{
+	if (buf->cnt >= BUF_LEN)
+		return false;
+	
+	int pos = (buf->start + buf->cnt) % BUF_LEN;
+	buf->buf[pos] = item;
+	buf->cnt++;
+	return true;
+}
+
+static inline bool buf_is_empty(cyclic_buffer_t *buf)
+{
+	return buf->cnt == 0;
+}
+
+static inline uint8_t buf_pop_front(cyclic_buffer_t *buf)
+{
+	assert(!buf_is_empty(buf));
+	
+	uint8_t res = buf->buf[buf->start];
+	buf->start = (buf->start + 1) % BUF_LEN;
+	buf->cnt--;
+	return res;
+}
+
+static inline void buf_clear(cyclic_buffer_t *buf)
+{
+	buf->cnt = 0;
+}
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/drv/char/grlib_uart/grlib_uart.c
===================================================================
--- uspace/drv/char/grlib_uart/grlib_uart.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/drv/char/grlib_uart/grlib_uart.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,872 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * Copyright (c) 2011 Jiri Svoboda
+ * Copyright (c) 2013 Jakub Klama
+ * 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.
+ */
+
+/**
+ * @defgroup grlib_uart Serial port driver.
+ * @brief HelenOS serial port driver.
+ * @{
+ */
+
+/** @file
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <fibril_synch.h>
+#include <stdlib.h>
+#include <str.h>
+#include <ctype.h>
+#include <macros.h>
+#include <malloc.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <ddi.h>
+
+#include <ddf/driver.h>
+#include <ddf/interrupt.h>
+#include <ddf/log.h>
+#include <ops/char_dev.h>
+
+#include <ns.h>
+#include <ipc/services.h>
+#include <ipc/irc.h>
+#include <device/hw_res.h>
+#include <ipc/serial_ctl.h>
+
+#include "cyclic_buffer.h"
+
+#define NAME "grlib_uart"
+
+#define REG_COUNT 5
+#define MAX_BAUD_RATE 115200
+
+#define LVL_DEBUG LVL_ERROR
+
+#define GRLIB_UART_STATUS_DR  (1 << 0)
+#define GRLIB_UART_STATUS_TS  (1 << 1)
+#define GRLIB_UART_STATUS_TE  (1 << 2)
+#define GRLIB_UART_STATUS_BR  (1 << 3)
+#define GRLIB_UART_STATUS_OV  (1 << 4)
+#define GRLIB_UART_STATUS_PE  (1 << 5)
+#define GRLIB_UART_STATUS_FE  (1 << 6)
+#define GRLIB_UART_STATUS_TH  (1 << 7)
+#define GRLIB_UART_STATUS_RH  (1 << 8)
+#define GRLIB_UART_STATUS_TF  (1 << 9)
+#define GRLIB_UART_STATUS_RF  (1 << 10)
+
+#define GRLIB_UART_CONTROL_RE  (1 << 0)
+#define GRLIB_UART_CONTROL_TE  (1 << 1)
+#define GRLIB_UART_CONTROL_RI  (1 << 2)
+#define GRLIB_UART_CONTROL_TI  (1 << 3)
+#define GRLIB_UART_CONTROL_PS  (1 << 4)
+#define GRLIB_UART_CONTROL_PE  (1 << 5)
+#define GRLIB_UART_CONTROL_FL  (1 << 6)
+#define GRLIB_UART_CONTROL_LB  (1 << 7)
+#define GRLIB_UART_CONTROL_EC  (1 << 8)
+#define GRLIB_UART_CONTROL_TF  (1 << 9)
+#define GRLIB_UART_CONTROL_RF  (1 << 10)
+#define GRLIB_UART_CONTROL_DB  (1 << 11)
+#define GRLIB_UART_CONTROL_BI  (1 << 12)
+#define GRLIB_UART_CONTROL_DI  (1 << 13)
+#define GRLIB_UART_CONTROL_SI  (1 << 14)
+#define GRLIB_UART_CONTROL_FA  (1 << 31)
+
+typedef struct {
+	unsigned int fa : 1;
+	unsigned int : 16;
+	unsigned int si : 1;
+	unsigned int di : 1;
+	unsigned int bi : 1;
+	unsigned int db : 1;
+	unsigned int rf : 1;
+	unsigned int tf : 1;
+	unsigned int ec : 1;
+	unsigned int lb : 1;
+	unsigned int fl : 1;
+	unsigned int pe : 1;
+	unsigned int ps : 1;
+	unsigned int ti : 1;
+	unsigned int ri : 1;
+	unsigned int te : 1;
+	unsigned int re : 1;
+} grlib_uart_control_t;
+
+/** GRLIB UART registers */
+typedef struct {
+	ioport32_t data;
+	ioport32_t status;
+	ioport32_t control;
+	ioport32_t scaler;
+	ioport32_t debug;
+} grlib_uart_regs_t;
+
+/** The number of bits of one data unit send by the serial port. */
+typedef enum {
+	WORD_LENGTH_5,
+	WORD_LENGTH_6,
+	WORD_LENGTH_7,
+	WORD_LENGTH_8
+} word_length_t;
+
+/** The number of stop bits used by the serial port. */
+typedef enum {
+	/** Use one stop bit. */
+	ONE_STOP_BIT,
+	/** 1.5 stop bits for word length 5, 2 stop bits otherwise. */
+	TWO_STOP_BITS
+} stop_bit_t;
+
+/** The driver data for the serial port devices. */
+typedef struct grlib_uart {
+	/** DDF device node */
+	ddf_dev_t *dev;
+	/** DDF function node */
+	ddf_fun_t *fun;
+	/** I/O registers **/
+	grlib_uart_regs_t *regs;
+	/** Are there any clients connected to the device? */
+	unsigned client_connections;
+	/** The irq assigned to this device. */
+	int irq;
+	/** The base i/o address of the devices registers. */
+	uintptr_t regs_addr;
+	/** The buffer for incoming data. */
+	cyclic_buffer_t input_buffer;
+	/** The fibril mutex for synchronizing the access to the device. */
+	fibril_mutex_t mutex;
+	/** Indicates that some data has become available */
+	fibril_condvar_t input_buffer_available;
+	/** True if device is removed. */
+	bool removed;
+} grlib_uart_t;
+
+/** Obtain soft-state structure from device node */
+static grlib_uart_t *dev_grlib_uart(ddf_dev_t *dev)
+{
+	return ddf_dev_data_get(dev);
+}
+
+/** Obtain soft-state structure from function node */
+static grlib_uart_t *fun_grlib_uart(ddf_fun_t *fun)
+{
+	return dev_grlib_uart(ddf_fun_get_dev(fun));
+}
+
+/** Find out if there is some incoming data available on the serial port.
+ *
+ * @param port The base address of the serial port device's ports.
+ *
+ * @return True if there are data waiting to be read.
+ * @return False otherwise.
+ *
+ */
+static bool grlib_uart_received(grlib_uart_regs_t *regs)
+{
+	return ((pio_read_32(&regs->status) & GRLIB_UART_STATUS_DR) != 0);
+}
+
+/** Read one byte from the serial port.
+ *
+ * @param port The base address of the serial port device's ports.
+ *
+ * @return The data read.
+ *
+ */
+static uint8_t grlib_uart_read_8(grlib_uart_regs_t *regs)
+{
+	return (uint8_t) pio_read_32(&regs->data);
+}
+
+/** Find out wheter it is possible to send data.
+ *
+ * @param port The base address of the serial port device's ports.
+ *
+ */
+static bool is_transmit_empty(grlib_uart_regs_t *regs)
+{
+	return ((pio_read_32(&regs->status) & GRLIB_UART_STATUS_TS) != 0);
+}
+
+/** Write one character on the serial port.
+ *
+ * @param port The base address of the serial port device's ports.
+ * @param c    The character to be written to the serial port device.
+ *
+ */
+static void grlib_uart_write_8(grlib_uart_regs_t *regs, uint8_t c)
+{
+	while (!is_transmit_empty(regs));
+	
+	pio_write_32(&regs->data, (uint32_t) c);
+}
+
+/** Read data from the serial port device.
+ *
+ * @param fun   The serial port function
+ * @param buf   The output buffer for read data.
+ * @param count The number of bytes to be read.
+ *
+ * @return The number of bytes actually read on success,
+ * @return Negative error number otherwise.
+ *
+ */
+static int grlib_uart_read(ddf_fun_t *fun, char *buf, size_t count)
+{
+	if (count == 0)
+		return 0;
+	
+	grlib_uart_t *ns = fun_grlib_uart(fun);
+	
+	fibril_mutex_lock(&ns->mutex);
+	
+	while (buf_is_empty(&ns->input_buffer))
+		fibril_condvar_wait(&ns->input_buffer_available, &ns->mutex);
+	
+	int ret = 0;
+	while ((!buf_is_empty(&ns->input_buffer)) && ((size_t) ret < count)) {
+		buf[ret] = (char) buf_pop_front(&ns->input_buffer);
+		ret++;
+	}
+	
+	fibril_mutex_unlock(&ns->mutex);
+	
+	return ret;
+}
+
+/** Write a character to the serial port.
+ *
+ * @param ns Serial port device
+ * @param c  The character to be written
+ *
+ */
+static inline void grlib_uart_putchar(grlib_uart_t *ns, uint8_t c)
+{
+	fibril_mutex_lock(&ns->mutex);
+	grlib_uart_write_8(ns->regs, c);
+	fibril_mutex_unlock(&ns->mutex);
+}
+
+/** Write data to the serial port.
+ *
+ * @param fun   The serial port function
+ * @param buf   The data to be written
+ * @param count The number of bytes to be written
+ *
+ * @return Zero on success
+ *
+ */
+static int grlib_uart_write(ddf_fun_t *fun, char *buf, size_t count)
+{
+	grlib_uart_t *ns = fun_grlib_uart(fun);
+	
+	for (size_t idx = 0; idx < count; idx++)
+		grlib_uart_putchar(ns, (uint8_t) buf[idx]);
+	
+	return count;
+}
+
+static ddf_dev_ops_t grlib_uart_dev_ops;
+
+/** The character interface's callbacks. */
+static char_dev_ops_t grlib_uart_char_dev_ops = {
+	.read = &grlib_uart_read,
+	.write = &grlib_uart_write
+};
+
+static int grlib_uart_dev_add(ddf_dev_t *);
+static int grlib_uart_dev_remove(ddf_dev_t *);
+
+/** The serial port device driver's standard operations. */
+static driver_ops_t grlib_uart_ops = {
+	.dev_add = &grlib_uart_dev_add,
+	.dev_remove = &grlib_uart_dev_remove
+};
+
+/** The serial port device driver structure. */
+static driver_t grlib_uart_driver = {
+	.name = NAME,
+	.driver_ops = &grlib_uart_ops
+};
+
+/** Clean up the serial port soft-state
+ *
+ * @param ns Serial port device
+ *
+ */
+static void grlib_uart_dev_cleanup(grlib_uart_t *ns)
+{
+}
+
+/** Enable the i/o ports of the device.
+ *
+ * @param ns Serial port device
+ *
+ * @return True on success, false otherwise
+ *
+ */
+static bool grlib_uart_pio_enable(grlib_uart_t *ns)
+{
+	ddf_msg(LVL_DEBUG, "grlib_uart_pio_enable %s", ddf_dev_get_name(ns->dev));
+	
+	/* Gain control over port's registers. */
+	if (pio_enable((void *) ns->regs_addr, REG_COUNT,
+	    (void **) &ns->regs)) {
+		ddf_msg(LVL_ERROR, "Cannot map the port %#" PRIx32
+		    " for device %s.", ns->regs_addr, ddf_dev_get_name(ns->dev));
+		return false;
+	}
+	
+	return true;
+}
+
+/** Probe the serial port device for its presence.
+ *
+ * @param ns Serial port device
+ *
+ * @return True if the device is present, false otherwise
+ *
+ */
+static bool grlib_uart_dev_probe(grlib_uart_t *ns)
+{
+	ddf_msg(LVL_DEBUG, "grlib_uart_dev_probe %s", ddf_dev_get_name(ns->dev));
+	
+	return true;
+}
+
+/** Initialize serial port device.
+ *
+ * @param ns Serial port device
+ *
+ * @return Zero on success, negative error number otherwise
+ *
+ */
+static int grlib_uart_dev_initialize(grlib_uart_t *ns)
+{
+	ddf_msg(LVL_DEBUG, "grlib_uart_dev_initialize %s", ddf_dev_get_name(ns->dev));
+	
+	hw_resource_list_t hw_resources;
+	memset(&hw_resources, 0, sizeof(hw_resource_list_t));
+	
+	int ret = EOK;
+	
+	/* Connect to the parent's driver. */
+	async_sess_t *parent_sess = ddf_dev_parent_sess_create(ns->dev,
+	    EXCHANGE_SERIALIZE);
+	if (parent_sess == NULL) {
+		ddf_msg(LVL_ERROR, "Failed to connect to parent driver of "
+		    "device %s.", ddf_dev_get_name(ns->dev));
+		ret = ENOENT;
+		goto failed;
+	}
+	
+	/* Get hw resources. */
+	ret = hw_res_get_resource_list(parent_sess, &hw_resources);
+	if (ret != EOK) {
+		ddf_msg(LVL_ERROR, "Failed to get HW resources for device "
+		    "%s.", ddf_dev_get_name(ns->dev));
+		goto failed;
+	}
+	
+	bool irq = false;
+	bool ioport = false;
+	
+	for (size_t i = 0; i < hw_resources.count; i++) {
+		hw_resource_t *res = &hw_resources.resources[i];
+		switch (res->type) {
+		case INTERRUPT:
+			ns->irq = res->res.interrupt.irq;
+			irq = true;
+			ddf_msg(LVL_NOTE, "Device %s was assigned irq = 0x%x.",
+			    ddf_dev_get_name(ns->dev), ns->irq);
+			break;
+			
+		case MEM_RANGE:
+			ns->regs_addr = res->res.mem_range.address;
+			if (res->res.mem_range.size < REG_COUNT) {
+				ddf_msg(LVL_ERROR, "I/O range assigned to "
+				    "device %s is too small.", ddf_dev_get_name(ns->dev));
+				ret = ELIMIT;
+				goto failed;
+			}
+			ioport = true;
+			ddf_msg(LVL_NOTE, "Device %s was assigned I/O address = "
+			    "0x%x.", ddf_dev_get_name(ns->dev), ns->regs_addr);
+    			break;
+			
+		default:
+			break;
+		}
+	}
+	
+	if ((!irq) || (!ioport)) {
+		ddf_msg(LVL_ERROR, "Missing HW resource(s) for device %s.",
+		    ddf_dev_get_name(ns->dev));
+		ret = ENOENT;
+		goto failed;
+	}
+	
+	hw_res_clean_resource_list(&hw_resources);
+	return ret;
+	
+failed:
+	grlib_uart_dev_cleanup(ns);
+	hw_res_clean_resource_list(&hw_resources);
+	return ret;
+}
+
+/** Enable interrupts on the serial port device.
+ *
+ * Interrupt when data is received
+ *
+ * @param port The base address of the serial port device's ports.
+ *
+ */
+static inline void grlib_uart_port_interrupts_enable(grlib_uart_regs_t *regs)
+{
+	/* Interrupt when data received. */
+	uint32_t control = pio_read_32(&regs->control);
+	pio_write_32(&regs->control, control | GRLIB_UART_CONTROL_RE);
+}
+
+/** Disable interrupts on the serial port device.
+ *
+ * @param port The base address of the serial port device's ports.
+ *
+ */
+static inline void grlib_uart_port_interrupts_disable(grlib_uart_regs_t *regs)
+{
+	uint32_t control = pio_read_32(&regs->control);
+	pio_write_32(&regs->control, control & (~GRLIB_UART_CONTROL_RE));
+}
+
+/** Enable interrupts for the serial port device.
+ *
+ * @param ns Serial port device
+ *
+ * @return Zero on success, negative error number otherwise
+ *
+ */
+static int grlib_uart_interrupt_enable(grlib_uart_t *ns)
+{
+	/* Enable interrupt on the serial port. */
+	grlib_uart_port_interrupts_enable(ns->regs);
+	
+	return EOK;
+}
+
+static int grlib_uart_port_set_baud_rate(grlib_uart_regs_t *regs,
+    unsigned int baud_rate)
+{
+	if ((baud_rate < 50) || (MAX_BAUD_RATE % baud_rate != 0)) {
+		ddf_msg(LVL_ERROR, "Invalid baud rate %d requested.",
+		    baud_rate);
+		return EINVAL;
+	}
+	
+	/* XXX: Set baud rate */
+	
+	return EOK;
+}
+
+/** Set the parameters of the serial communication on the serial port device.
+ *
+ * @param parity      The parity to be used.
+ * @param word_length The length of one data unit in bits.
+ * @param stop_bits   The number of stop bits used (one or two).
+ *
+ * @return Zero on success.
+ * @return EINVAL if some of the specified values is invalid.
+ *
+ */
+static int grlib_uart_port_set_com_props(grlib_uart_regs_t *regs,
+    unsigned int parity, unsigned int word_length, unsigned int stop_bits)
+{
+	uint32_t val = pio_read_32(&regs->control);
+	
+	switch (parity) {
+	case SERIAL_NO_PARITY:
+	case SERIAL_ODD_PARITY:
+	case SERIAL_EVEN_PARITY:
+	case SERIAL_MARK_PARITY:
+	case SERIAL_SPACE_PARITY:
+		val |= GRLIB_UART_CONTROL_PE;
+		break;
+	default:
+		return EINVAL;
+	}
+	
+	pio_write_32(&regs->control, val);
+	
+	return EOK;
+}
+
+/** Initialize the serial port device.
+ *
+ * Set the default parameters of the serial communication.
+ *
+ * @param ns Serial port device
+ *
+ */
+static void grlib_uart_initialize_port(grlib_uart_t *ns)
+{
+	/* Disable interrupts. */
+	grlib_uart_port_interrupts_disable(ns->regs);
+	
+	/* Set baud rate. */
+	grlib_uart_port_set_baud_rate(ns->regs, 38400);
+	
+	/* 8 bits, no parity, two stop bits. */
+	grlib_uart_port_set_com_props(ns->regs, SERIAL_NO_PARITY, 8, 2);
+	
+	/*
+	 * Enable FIFO, clear them, with 4-byte threshold for greater
+	 * reliability.
+	 */
+	pio_write_32(&ns->regs->control, GRLIB_UART_CONTROL_RE |
+	    GRLIB_UART_CONTROL_TE | GRLIB_UART_CONTROL_RF |
+	    GRLIB_UART_CONTROL_TF | GRLIB_UART_CONTROL_RI |
+	    GRLIB_UART_CONTROL_FA);
+}
+
+/** Deinitialize the serial port device.
+ *
+ * @param ns Serial port device
+ *
+ */
+static void grlib_uart_port_cleanup(grlib_uart_t *ns)
+{
+	grlib_uart_port_interrupts_disable(ns->regs);
+}
+
+/** Read the data from the serial port device and store them to the input
+ * buffer.
+ *
+ * @param ns Serial port device
+ *
+ */
+static void grlib_uart_read_from_device(grlib_uart_t *ns)
+{
+	grlib_uart_regs_t *regs = ns->regs;
+	bool cont = true;
+	
+	fibril_mutex_lock(&ns->mutex);
+	
+	while (cont) {
+		cont = grlib_uart_received(regs);
+		if (cont) {
+			uint8_t val = grlib_uart_read_8(regs);
+			
+			if (ns->client_connections > 0) {
+				bool buf_was_empty = buf_is_empty(&ns->input_buffer);
+				if (!buf_push_back(&ns->input_buffer, val)) {
+					ddf_msg(LVL_WARN, "Buffer overflow on "
+					    "%s.", ddf_dev_get_name(ns->dev));
+					break;
+				} else {
+					ddf_msg(LVL_DEBUG2, "Character %c saved "
+					    "to the buffer of %s.",
+					    val, ddf_dev_get_name(ns->dev));
+					if (buf_was_empty)
+						fibril_condvar_broadcast(&ns->input_buffer_available);
+				}
+			}
+		}
+	}
+	
+	fibril_mutex_unlock(&ns->mutex);
+	fibril_yield();
+}
+
+/** The interrupt handler.
+ *
+ * The serial port is initialized to interrupt when some data come or line
+ * status register changes, so the interrupt is handled by reading the incoming
+ * data and reading the line status register.
+ *
+ * @param dev The serial port device.
+ *
+ */
+static inline void grlib_uart_interrupt_handler(ddf_dev_t *dev,
+    ipc_callid_t iid, ipc_call_t *icall)
+{
+	grlib_uart_t *ns = dev_grlib_uart(dev);
+	
+	uint32_t status = pio_read_32(&ns->regs->status);
+	
+	if (status & GRLIB_UART_STATUS_RF) {
+		if (status & GRLIB_UART_STATUS_OV)
+			ddf_msg(LVL_WARN, "Overrun error on %s", ddf_dev_get_name(ns->dev));
+	}
+	
+	grlib_uart_read_from_device(ns);
+}
+
+/** Register the interrupt handler for the device.
+ *
+ * @param ns Serial port device
+ *
+ */
+static inline int grlib_uart_register_interrupt_handler(grlib_uart_t *ns)
+{
+	return register_interrupt_handler(ns->dev, ns->irq,
+	    grlib_uart_interrupt_handler, NULL);
+}
+
+/** Unregister the interrupt handler for the device.
+ *
+ * @param ns Serial port device
+ *
+ */
+static inline int grlib_uart_unregister_interrupt_handler(grlib_uart_t *ns)
+{
+	return unregister_interrupt_handler(ns->dev, ns->irq);
+}
+
+/** The dev_add callback method of the serial port driver.
+ *
+ * Probe and initialize the newly added device.
+ *
+ * @param dev The serial port device.
+ *
+ */
+static int grlib_uart_dev_add(ddf_dev_t *dev)
+{
+	grlib_uart_t *ns = NULL;
+	ddf_fun_t *fun = NULL;
+	bool need_cleanup = false;
+	bool need_unreg_intr_handler = false;
+	int rc;
+	
+	ddf_msg(LVL_DEBUG, "grlib_uart_dev_add %s (handle = %d)",
+	    ddf_dev_get_name(dev), (int) ddf_dev_get_handle(dev));
+	
+	/* Allocate soft-state for the device */
+	ns = ddf_dev_data_alloc(dev, sizeof(grlib_uart_t));
+	if (ns == NULL) {
+		rc = ENOMEM;
+		goto fail;
+	}
+	
+	fibril_mutex_initialize(&ns->mutex);
+	fibril_condvar_initialize(&ns->input_buffer_available);
+	ns->dev = dev;
+	
+	rc = grlib_uart_dev_initialize(ns);
+	if (rc != EOK)
+		goto fail;
+	
+	need_cleanup = true;
+	
+	if (!grlib_uart_pio_enable(ns)) {
+		rc = EADDRNOTAVAIL;
+		goto fail;
+	}
+	
+	/* Find out whether the device is present. */
+	if (!grlib_uart_dev_probe(ns)) {
+		rc = ENOENT;
+		goto fail;
+	}
+	
+	/* Serial port initialization (baud rate etc.). */
+	grlib_uart_initialize_port(ns);
+	
+	/* Register interrupt handler. */
+	if (grlib_uart_register_interrupt_handler(ns) != EOK) {
+		ddf_msg(LVL_ERROR, "Failed to register interrupt handler.");
+		rc = EADDRNOTAVAIL;
+		goto fail;
+	}
+	need_unreg_intr_handler = true;
+	
+	/* Enable interrupt. */
+	rc = grlib_uart_interrupt_enable(ns);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed to enable the interrupt. Error code = "
+		    "%d.", rc);
+		goto fail;
+	}
+	
+	fun = ddf_fun_create(dev, fun_exposed, "a");
+	if (fun == NULL) {
+		ddf_msg(LVL_ERROR, "Failed creating function.");
+		goto fail;
+	}
+	
+	/* Set device operations. */
+	ddf_fun_set_ops(fun, &grlib_uart_dev_ops);
+	rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed binding function.");
+		goto fail;
+	}
+	
+	ns->fun = fun;
+	
+	ddf_fun_add_to_category(fun, "serial");
+	
+	ddf_msg(LVL_NOTE, "Device %s successfully initialized.",
+	    ddf_dev_get_name(dev));
+	
+	return EOK;
+	
+fail:
+	if (fun != NULL)
+		ddf_fun_destroy(fun);
+	
+	if (need_unreg_intr_handler)
+		grlib_uart_unregister_interrupt_handler(ns);
+	
+	if (need_cleanup)
+		grlib_uart_dev_cleanup(ns);
+	
+	return rc;
+}
+
+static int grlib_uart_dev_remove(ddf_dev_t *dev)
+{
+	grlib_uart_t *ns = dev_grlib_uart(dev);
+	
+	fibril_mutex_lock(&ns->mutex);
+	if (ns->client_connections > 0) {
+		fibril_mutex_unlock(&ns->mutex);
+		return EBUSY;
+	}
+	ns->removed = true;
+	fibril_mutex_unlock(&ns->mutex);
+	
+	int rc = ddf_fun_unbind(ns->fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed to unbind function.");
+		return rc;
+	}
+	
+	ddf_fun_destroy(ns->fun);
+	
+	grlib_uart_port_cleanup(ns);
+	grlib_uart_unregister_interrupt_handler(ns);
+	grlib_uart_dev_cleanup(ns);
+	return EOK;
+}
+
+/** Open the device.
+ *
+ * This is a callback function called when a client tries to connect to the
+ * device.
+ *
+ * @param dev The device.
+ *
+ */
+static int grlib_uart_open(ddf_fun_t *fun)
+{
+	grlib_uart_t *ns = fun_grlib_uart(fun);
+	int res;
+	
+	fibril_mutex_lock(&ns->mutex);
+	if (ns->removed) {
+		res = ENXIO;
+	} else {
+		res = EOK;
+		ns->client_connections++;
+	}
+	fibril_mutex_unlock(&ns->mutex);
+	
+	return res;
+}
+
+/** Close the device.
+ *
+ * This is a callback function called when a client tries to disconnect from
+ * the device.
+ *
+ * @param dev The device.
+ *
+ */
+static void grlib_uart_close(ddf_fun_t *fun)
+{
+	grlib_uart_t *data = fun_grlib_uart(fun);
+	
+	fibril_mutex_lock(&data->mutex);
+	
+	assert(data->client_connections > 0);
+	
+	if (!(--data->client_connections))
+		buf_clear(&data->input_buffer);
+	
+	fibril_mutex_unlock(&data->mutex);
+}
+
+/** Default handler for client requests which are not handled by the standard
+ * interfaces.
+ *
+ * Configure the parameters of the serial communication.
+ *
+ */
+static void grlib_uart_default_handler(ddf_fun_t *fun, ipc_callid_t callid,
+    ipc_call_t *call)
+{
+	sysarg_t method = IPC_GET_IMETHOD(*call);
+	
+	switch (method) {
+	default:
+		async_answer_0(callid, ENOTSUP);
+	}
+}
+
+/** Initialize the serial port driver.
+ *
+ * Initialize device operations structures with callback methods for handling
+ * client requests to the serial port devices.
+ *
+ */
+static void grlib_uart_init(void)
+{
+	ddf_log_init(NAME);
+	
+	grlib_uart_dev_ops.open = &grlib_uart_open;
+	grlib_uart_dev_ops.close = &grlib_uart_close;
+	
+	grlib_uart_dev_ops.interfaces[CHAR_DEV_IFACE] = &grlib_uart_char_dev_ops;
+	grlib_uart_dev_ops.default_handler = &grlib_uart_default_handler;
+}
+
+int main(int argc, char *argv[])
+{
+	printf("%s: HelenOS serial port driver\n", NAME);
+	grlib_uart_init();
+	return ddf_driver_main(&grlib_uart_driver);
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/char/grlib_uart/grlib_uart.ma
===================================================================
--- uspace/drv/char/grlib_uart/grlib_uart.ma	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/drv/char/grlib_uart/grlib_uart.ma	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,1 @@
+10 amba/ven=01&dev=0000000c
Index: uspace/drv/infrastructure/rootleon3/Makefile
===================================================================
--- uspace/drv/infrastructure/rootleon3/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/drv/infrastructure/rootleon3/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2012 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.
+#
+
+USPACE_PREFIX = ../../..
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
+BINARY = rootleon3
+
+SOURCES = \
+	rootleon3.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/infrastructure/rootleon3/rootleon3.c
===================================================================
--- uspace/drv/infrastructure/rootleon3/rootleon3.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/drv/infrastructure/rootleon3/rootleon3.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2012 Jan Vesely
+ * Copyright (c) 2013 Jakub Klama
+ * 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.
+ */
+
+/**
+ * @defgroup root_leon3 SPARC LEON3 platform driver.
+ * @brief HelenOS SPARC LEON3 platform driver.
+ * @{
+ */
+/** @file
+ */
+
+#include <ddf/log.h>
+#include <errno.h>
+#include <ops/hw_res.h>
+#include <stdio.h>
+#include "rootleon3.h"
+
+#define NAME  "rootleon3"
+
+typedef struct {
+	const char *name;
+	match_id_t match_id;
+	hw_resource_list_t hw_resources;
+} rootleon3_fun_t;
+
+static hw_resource_t amba_res[] = {
+	{
+		.type = MEM_RANGE,
+		.res.mem_range = {
+			.address = AMBAPP_MASTER_AREA,
+			.size = AMBAPP_MASTER_SIZE,
+			.endianness = BIG_ENDIAN
+		}
+	},
+	{
+		.type = MEM_RANGE,
+		.res.mem_range = {
+			.address = AMBAPP_SLAVE_AREA,
+			.size = AMBAPP_SLAVE_SIZE,
+			.endianness = BIG_ENDIAN,
+		}
+	}
+};
+
+static const rootleon3_fun_t leon3_func = {
+	.name = "leon_amba",
+	.match_id = {
+		.id =  "leon_amba",
+		.score = 90 
+	},
+	.hw_resources = {
+		.count = 2,
+		.resources = amba_res
+	}
+};
+
+static hw_resource_list_t *rootleon3_get_resources(ddf_fun_t *);
+static bool rootleon3_enable_interrupt(ddf_fun_t *);
+
+static hw_res_ops_t fun_hw_res_ops = {
+	.get_resource_list = &rootleon3_get_resources,
+	.enable_interrupt = &rootleon3_enable_interrupt
+};
+
+static ddf_dev_ops_t rootleon3_fun_ops = {
+	.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops
+};
+
+static int rootleon3_add_fun(ddf_dev_t *dev, const rootleon3_fun_t *fun)
+{
+	assert(dev);
+	assert(fun);
+	
+	ddf_msg(LVL_DEBUG, "Adding new function '%s'.", fun->name);
+	
+	/* Create new device function. */
+	ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, fun->name);
+	if (fnode == NULL)
+		return ENOMEM;
+	
+	/* Add match id */
+	int ret = ddf_fun_add_match_id(fnode, fun->match_id.id,
+	    fun->match_id.score);
+	if (ret != EOK) {
+		ddf_fun_destroy(fnode);
+		return ret;
+	}
+	
+	/* Allocate needed data */
+	rootleon3_fun_t *rf =
+	    ddf_fun_data_alloc(fnode, sizeof(rootleon3_fun_t));
+	if (!rf) {
+		ddf_fun_destroy(fnode);
+		return ENOMEM;
+	}
+	*rf = *fun;
+	
+	/* Set provided operations to the device. */
+	ddf_fun_set_ops(fnode, &rootleon3_fun_ops);
+	
+	/* Register function. */
+	ret = ddf_fun_bind(fnode);
+	if (ret != EOK) {
+		ddf_msg(LVL_ERROR, "Failed binding function %s.", fun->name);
+		ddf_fun_destroy(fnode);
+		return ret;
+	}
+	
+	return EOK;
+}
+
+/** Add the root device.
+ *
+ * @param dev Device which is root of the whole device tree
+ *            (both of HW and pseudo devices).
+ *
+ * @return Zero on success, negative error number otherwise.
+ *
+ */
+static int rootleon3_dev_add(ddf_dev_t *dev)
+{
+	assert(dev);
+	
+	/* Register functions */
+	if (rootleon3_add_fun(dev, &leon3_func) != EOK) {
+		ddf_msg(LVL_ERROR, "Failed to add %s function for "
+		    "LEON3 platform.", leon3_func.name);
+	}
+	
+	return EOK;
+}
+
+/** The root device driver's standard operations. */
+static driver_ops_t rootleon3_ops = {
+	.dev_add = &rootleon3_dev_add
+};
+
+/** The root device driver structure. */
+static driver_t rootleon3_driver = {
+	.name = NAME,
+	.driver_ops = &rootleon3_ops
+};
+
+static hw_resource_list_t *rootleon3_get_resources(ddf_fun_t *fnode)
+{
+	rootleon3_fun_t *fun = ddf_fun_data_get(fnode);
+	assert(fun != NULL);
+	
+	printf("rootleon3_get_resources() called\n");
+	
+	return &fun->hw_resources;
+}
+
+static bool rootleon3_enable_interrupt(ddf_fun_t *fun)
+{
+	// FIXME TODO
+	return false;
+}
+
+int main(int argc, char *argv[])
+{
+	printf("%s: HelenOS SPARC LEON3 platform driver\n", NAME);
+	ddf_log_init(NAME);
+	return ddf_driver_main(&rootleon3_driver);
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/infrastructure/rootleon3/rootleon3.h
===================================================================
--- uspace/drv/infrastructure/rootleon3/rootleon3.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/drv/infrastructure/rootleon3/rootleon3.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 leon3drv
+ * @{
+ */
+/** @file
+ * @brief LEON3 root device.
+ */
+
+#ifndef ROOTLEON3_H
+#define ROOTLEON3_H
+
+#define AMBAPP_MASTER_AREA  0xfffff000
+#define AMBAPP_SLAVE_AREA   0xfffff800
+#define AMBAPP_MASTER_SIZE  0x800
+#define AMBAPP_SLAVE_SIZE   0x800
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/drv/infrastructure/rootleon3/rootleon3.ma
===================================================================
--- uspace/drv/infrastructure/rootleon3/rootleon3.ma	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/drv/infrastructure/rootleon3/rootleon3.ma	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,1 @@
+100 platform/leon3
Index: uspace/drv/infrastructure/rootmalta/rootmalta.c
===================================================================
--- uspace/drv/infrastructure/rootmalta/rootmalta.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/infrastructure/rootmalta/rootmalta.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -52,7 +52,5 @@
 #include <ipc/dev_iface.h>
 #include <ops/hw_res.h>
-#include <device/hw_res.h>
 #include <ops/pio_window.h>
-#include <device/pio_window.h>
 #include <byteorder.h>
 
Index: uspace/drv/infrastructure/rootpc/rootpc.c
===================================================================
--- uspace/drv/infrastructure/rootpc/rootpc.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/infrastructure/rootpc/rootpc.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -50,7 +50,5 @@
 #include <ipc/dev_iface.h>
 #include <ops/hw_res.h>
-#include <device/hw_res.h>
 #include <ops/pio_window.h>
-#include <device/pio_window.h>
 
 #define NAME "rootpc"
Index: uspace/drv/nic/e1k/e1k.c
===================================================================
--- uspace/drv/nic/e1k/e1k.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/nic/e1k/e1k.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -50,5 +50,5 @@
 #include <ddf/interrupt.h>
 #include <device/hw_res_parsed.h>
-#include <device/pci.h>
+#include <pci_dev_iface.h>
 #include <nic.h>
 #include <ops/nic.h>
Index: uspace/drv/nic/rtl8139/driver.c
===================================================================
--- uspace/drv/nic/rtl8139/driver.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/nic/rtl8139/driver.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -41,5 +41,5 @@
 #include <io/log.h>
 #include <nic.h>
-#include <device/pci.h>
+#include <pci_dev_iface.h>
 
 #include <ipc/irc.h>
@@ -190,6 +190,4 @@
 	return;
 }
-
-#include <device/pci.h>
 
 /** Set PmEn (Power management enable) bit value
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -61,5 +61,4 @@
 	generic/bd.c \
 	generic/bd_srv.c \
-	generic/bitops.c \
 	generic/cap.c \
 	generic/cfg.c \
@@ -70,11 +69,5 @@
 	generic/device/hw_res_parsed.c \
 	generic/device/pio_window.c \
-	generic/device/char_dev.c \
 	generic/device/clock_dev.c \
-	generic/device/battery_dev.c \
-	generic/device/graph_dev.c \
-	generic/device/nic.c \
-	generic/device/pci.c \
-	generic/device/ahci.c \
 	generic/dhcp.c \
 	generic/dnsr.c \
@@ -108,4 +101,5 @@
 	generic/io/log.c \
 	generic/io/logctl.c \
+	generic/io/kio.c \
 	generic/io/klog.c \
 	generic/io/snprintf.c \
@@ -129,4 +123,5 @@
 	generic/loader.c \
 	generic/getopt.c \
+	generic/adt/checksum.c \
 	generic/adt/list.c \
 	generic/adt/hash_table.c \
@@ -143,4 +138,5 @@
 	generic/net/socket_client.c \
 	generic/net/socket_parse.c \
+	generic/setjmp.c \
 	generic/stack.c \
 	generic/stacktrace.c \
Index: uspace/lib/c/arch/abs32le/include/libarch/atomic.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/atomic.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/arch/abs32le/include/libarch/atomic.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -53,5 +53,6 @@
 }
 
-static inline void atomic_inc(atomic_t *val) {
+static inline void atomic_inc(atomic_t *val)
+{
 	/* On real hardware the increment has to be done
 	   as an atomic action. */
@@ -60,5 +61,6 @@
 }
 
-static inline void atomic_dec(atomic_t *val) {
+static inline void atomic_dec(atomic_t *val)
+{
 	/* On real hardware the decrement has to be done
 	   as an atomic action. */
Index: uspace/lib/c/arch/amd64/_link.ld.in
===================================================================
--- uspace/lib/c/arch/amd64/_link.ld.in	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/arch/amd64/_link.ld.in	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -39,4 +39,5 @@
 	.data : {
 		*(.data);
+		*(.data.rel*);
 	} :data
 	
Index: uspace/lib/c/arch/ia32/Makefile.inc
===================================================================
--- uspace/lib/c/arch/ia32/Makefile.inc	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/arch/ia32/Makefile.inc	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -34,5 +34,4 @@
 	arch/$(UARCH)/src/fibril.S \
 	arch/$(UARCH)/src/tls.c \
-	arch/$(UARCH)/src/setjmp.S \
 	arch/$(UARCH)/src/stacktrace.c \
 	arch/$(UARCH)/src/stacktrace_asm.S \
Index: uspace/lib/c/arch/ia32/src/setjmp.S
===================================================================
--- uspace/lib/c/arch/ia32/src/setjmp.S	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,55 +1,0 @@
-#
-# Copyright (c) 2008 Josef Cejka
-# 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/context_offset.h>
-
-.text
-.global setjmp
-.global longjmp
-
-.type setjmp,@function
-setjmp:
-	movl 0(%esp), %eax  # save pc value into eax
-	movl 4(%esp), %edx  # address of the jmp_buf structure to save context to
-	
-	# save registers to the jmp_buf structure
-	CONTEXT_SAVE_ARCH_CORE %edx %eax
-	
-	xorl %eax, %eax     # set_jmp returns 0
-	ret
-
-.type longjmp,@function
-longjmp:
-	movl 4(%esp), %ecx  # put address of jmp_buf into ecx
-	movl 8(%esp), %eax  # put return value into eax
-	
-	# restore registers from the jmp_buf structure
-	CONTEXT_RESTORE_ARCH_CORE %ecx %edx
-	
-	movl %edx, 0(%esp)  # put saved pc on stack
-	ret
Index: uspace/lib/c/arch/sparc32/Makefile.common
===================================================================
--- uspace/lib/c/arch/sparc32/Makefile.common	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/Makefile.common	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2006 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.
+#
+
+LFLAGS = -no-check-sections
+
+ENDIANESS = BE
+
+BFD_NAME = elf32-sparc
+BFD_ARCH = sparc
Index: uspace/lib/c/arch/sparc32/Makefile.inc
===================================================================
--- uspace/lib/c/arch/sparc32/Makefile.inc	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/Makefile.inc	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2006 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.
+#
+
+ARCH_SOURCES = \
+	arch/$(UARCH)/src/entry.s \
+	arch/$(UARCH)/src/entryjmp.s \
+	arch/$(UARCH)/src/thread_entry.s \
+	arch/$(UARCH)/src/fibril.S \
+	arch/$(UARCH)/src/tls.c \
+	arch/$(UARCH)/src/stacktrace.c \
+	arch/$(UARCH)/src/stacktrace_asm.S
+
+.PRECIOUS: arch/$(UARCH)/src/entry.o
Index: uspace/lib/c/arch/sparc32/_link.ld.in
===================================================================
--- uspace/lib/c/arch/sparc32/_link.ld.in	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/_link.ld.in	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,68 @@
+STARTUP(LIBC_PATH/arch/UARCH/src/entry.o)
+ENTRY(__entry)
+
+PHDRS {
+#ifdef LOADER
+	interp PT_INTERP;
+	text PT_LOAD FILEHDR PHDRS FLAGS(5);
+#else
+	text PT_LOAD FLAGS(5);
+#endif
+	data PT_LOAD FLAGS(6);
+}
+
+SECTIONS {
+#ifdef LOADER
+	. = 0x70004000 + SIZEOF_HEADERS;
+#else
+	. = 0x4000 + SIZEOF_HEADERS;
+#endif
+	
+	.init : {
+		*(.init);
+	} :text
+	
+	.text : {
+		*(.text .text.*);
+		*(.rodata .rodata.*);
+	} :text
+	
+#ifdef LOADER
+	.interp : {
+		*(.interp);
+	} :interp :text
+#endif
+	
+	. = . + 0x4000;
+	
+	.got : {
+		 _gp = .;
+		 *(.got*);
+	} :data
+	
+	.data : {
+		*(.data);
+		*(.sdata);
+	} :data
+	
+	.tdata : {
+		_tdata_start = .;
+		*(.tdata);
+		_tdata_end = .;
+		_tbss_start = .;
+		*(.tbss);
+		_tbss_end = .;
+	} :data
+	
+	_tls_alignment = ALIGNOF(.tdata);
+	
+	.bss : {
+		*(.sbss);
+		*(COMMON);
+		*(.bss);
+	} :data
+	
+	/DISCARD/ : {
+		*(*);
+	}
+}
Index: uspace/lib/c/arch/sparc32/include/libarch/atomic.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/atomic.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/include/libarch/atomic.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_ATOMIC_H_
+#define LIBC_sparc32_ATOMIC_H_
+
+#define LIBC_ARCH_ATOMIC_H_
+
+#define CAS
+
+#include <atomicdflt.h>
+#include <sys/types.h>
+
+static inline bool cas(atomic_t *val, atomic_count_t ov, atomic_count_t nv)
+{
+	if (val->count == ov) {
+		val->count = nv;
+		return true;
+	}
+	
+	return false;
+}
+
+static inline void atomic_inc(atomic_t *val)
+{
+	// FIXME TODO
+	val->count++;
+}
+
+static inline void atomic_dec(atomic_t *val)
+{
+	// FIXME TODO
+	val->count++;
+}
+
+static inline atomic_count_t atomic_postinc(atomic_t *val)
+{
+	// FIXME TODO
+	
+	atomic_count_t prev = val->count;
+	
+	val->count++;
+	return prev;
+}
+
+static inline atomic_count_t atomic_postdec(atomic_t *val)
+{
+	// FIXME TODO
+	
+	atomic_count_t prev = val->count;
+	
+	val->count--;
+	return prev;
+}
+
+#define atomic_preinc(val) (atomic_postinc(val) + 1)
+#define atomic_predec(val) (atomic_postdec(val) - 1)
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/barrier.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/barrier.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/include/libarch/barrier.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,1 @@
+../../../../../../../kernel/arch/sparc32/include/arch/barrier.h
Index: uspace/lib/c/arch/sparc32/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/config.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/include/libarch/config.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_CONFIG_H_
+#define LIBC_sparc32_CONFIG_H_
+
+#define PAGE_WIDTH  12
+#define PAGE_SIZE   (1 << PAGE_WIDTH)
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/context_offset.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/context_offset.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/include/libarch/context_offset.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,1 @@
+../../../../../../../kernel/arch/sparc32/include/arch/context_offset.h
Index: uspace/lib/c/arch/sparc32/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/ddi.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/include/libarch/ddi.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2009 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.
+ */
+
+/** @file
+ * @ingroup libsparc32
+ */
+
+#ifndef LIBC_sparc32_DDI_H_
+#define LIBC_sparc32_DDI_H_
+
+#include <sys/types.h>
+#include <libarch/types.h>
+
+static inline void memory_barrier(void)
+{
+	asm volatile (
+		"stbar\n"
+		::: "memory"
+	);
+}
+
+static inline void arch_pio_write_8(ioport8_t *port, uint8_t v)
+{
+	*port = v;
+	memory_barrier();
+}
+
+static inline void arch_pio_write_16(ioport16_t *port, uint16_t v)
+{
+	*port = v;
+	memory_barrier();
+}
+
+static inline void arch_pio_write_32(ioport32_t *port, uint32_t v)
+{
+	*port = v;
+	memory_barrier();
+}
+
+static inline uint8_t arch_pio_read_8(const ioport8_t *port)
+{
+	uint8_t rv = *port;
+	memory_barrier();
+	
+	return rv;
+}
+
+static inline uint16_t arch_pio_read_16(const ioport16_t *port)
+{
+	uint16_t rv = *port;
+	memory_barrier();
+	
+	return rv;
+}
+
+static inline uint32_t arch_pio_read_32(const ioport32_t *port)
+{
+	uint32_t rv = *port;
+	memory_barrier();
+	
+	return rv;
+}
+
+#endif
Index: uspace/lib/c/arch/sparc32/include/libarch/elf.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/elf.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/include/libarch/elf.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,1 @@
+../../../../../../../kernel/arch/sparc32/include/arch/elf.h
Index: uspace/lib/c/arch/sparc32/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/elf_linux.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/include/libarch/elf_linux.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011 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.
+ */
+
+/** @addtogroup libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_ELF_LINUX_H_
+#define LBIC_sparc32_ELF_LINUX_H_
+
+#include <libarch/istate.h>
+#include <sys/types.h>
+
+typedef struct {
+	/* TODO */
+	uint64_t pad[16];
+} elf_regs_t;
+
+static inline void istate_to_elf_regs(istate_t *istate, elf_regs_t *elf_regs)
+{
+	/* TODO */
+	(void) istate;
+	(void) elf_regs;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/faddr.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/include/libarch/faddr.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2005 Ondrej Palkovsky
+ * 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 libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_FADDR_H_
+#define LIBC_sparc32_FADDR_H_
+
+#include <libarch/types.h>
+
+#define FADDR(fptr)  ((uintptr_t) (fptr))
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/fibril.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/include/libarch/fibril.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_FIBRIL_H_
+#define LIBC_sparc32_FIBRIL_H_
+
+#include <libarch/stack.h>
+#include <sys/types.h>
+#include <align.h>
+
+#define SP_DELTA  (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE)
+
+#define context_set(c, _pc, stack, size, ptls) \
+	do { \
+		(c)->pc = ((uintptr_t) _pc) - 8; \
+		(c)->sp = ((uintptr_t) stack) + ALIGN_UP((size), \
+		    STACK_ALIGNMENT) - (SP_DELTA); \
+		(c)->fp = 0; \
+		(c)->tp = (uint32_t) ptls; \
+	} while (0)
+
+/*
+ * Save only registers that must be preserved across
+ * function calls.
+ */
+typedef struct {
+	uintptr_t sp;  /* %o6 */
+	uintptr_t pc;  /* %o7 */
+	uint32_t i0;
+	uint32_t i1;
+	uint32_t i2;
+	uint32_t i3;
+	uint32_t i4;
+	uint32_t i5;
+	uintptr_t fp;  /* %i6 */
+	uintptr_t i7;
+	uint32_t l0;
+	uint32_t l1;
+	uint32_t l2;
+	uint32_t l3;
+	uint32_t l4;
+	uint32_t l5;
+	uint32_t l6;
+	uint32_t l7;
+	uint32_t tp;  /* %g7 */
+} context_t;
+
+static inline uintptr_t context_get_fp(context_t *ctx)
+{
+	return ctx->sp;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/inttypes.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/inttypes.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/include/libarch/inttypes.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 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.
+ */
+
+/** @addtogroup libcsparc32
+ * @{
+ */
+
+#ifndef LIBC_sparc32_INTTYPES_H_
+#define LIBC_sparc32_INTTYPES_H_
+
+#define PRIdn  PRId32  /**< Format for native_t. */
+#define PRIun  PRIu32  /**< Format for sysarg_t. */
+#define PRIxn  PRIx32  /**< Format for hexadecimal sysarg_t. */
+#define PRIua  PRIu32  /**< Format for atomic_count_t. */
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/istate.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/istate.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/include/libarch/istate.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,1 @@
+../../../../../../../kernel/arch/sparc32/include/arch/istate.h
Index: uspace/lib/c/arch/sparc32/include/libarch/stack.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/stack.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/include/libarch/stack.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_STACK_H_
+#define LIBC_sparc32_STACK_H_
+
+#define STACK_ITEM_SIZE  4
+
+#define STACK_ALIGNMENT  8
+
+/** 16-extended-word save area for %i[0-7] and %l[0-7] registers. */
+#define STACK_WINDOW_SAVE_AREA_SIZE  (16 * STACK_ITEM_SIZE)
+
+/* Six extended words for first six arguments. */
+#define STACK_ARG_SAVE_AREA_SIZE  (6 * STACK_ITEM_SIZE)
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/stackarg.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/stackarg.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/include/libarch/stackarg.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * 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 libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_STACKARG_H_
+#define LIBC_sparc32_STACKARG_H_
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/syscall.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/include/libarch/syscall.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_SYSCALL_H_
+#define LIBC_sparc32_SYSCALL_H_
+
+#include <sys/types.h>
+#include <abi/syscall.h>
+
+#define __syscall0  __syscall
+#define __syscall1  __syscall
+#define __syscall2  __syscall
+#define __syscall3  __syscall
+#define __syscall4  __syscall
+#define __syscall5  __syscall
+#define __syscall6  __syscall
+
+static inline sysarg_t __syscall(const sysarg_t p1, const sysarg_t p2,
+    const sysarg_t p3, const sysarg_t p4, const sysarg_t p5, const sysarg_t p6,
+    const syscall_t id)
+{
+	register uint32_t a1 asm("o0") = p1;
+	register uint32_t a2 asm("o1") = p2;
+	register uint32_t a3 asm("o2") = p3;
+	register uint32_t a4 asm("o3") = p4;
+	register uint32_t a5 asm("o4") = p5;
+	register uint32_t a6 asm("o5") = p6;
+	
+	asm volatile (
+		"ta %7\n"
+		: "=r" (a1)
+		: "r" (a1),
+		  "r" (a2),
+		  "r" (a3),
+		  "r" (a4),
+		  "r" (a5),
+		  "r" (a6),
+		  "i" (id)
+		: "memory"
+	);
+	
+	return a1;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/thread.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/include/libarch/thread.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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.
+ */
+
+/** @addtogroup libcsparc32
+ * @{
+ */
+
+#ifndef LIBC_sparc32_THREAD_H_
+#define LIBC_sparc32_THREAD_H_
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/tls.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/include/libarch/tls.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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.
+ */
+
+/** @addtogroup libcsparc32
+ * @{
+ */
+/** @file
+ * @brief sparc32 TLS functions.
+ */
+
+#ifndef LIBC_sparc32_TLS_H_
+#define LIBC_sparc32_TLS_H_
+
+#define CONFIG_TLS_VARIANT_2
+
+typedef struct {
+	void *self;
+	void *fibril_data;
+} tcb_t;
+
+static inline void __tcb_set(tcb_t *tcb)
+{
+	asm volatile (
+		"mov %0, %%g7\n"
+		:: "r" (tcb)
+		: "g7"
+	);
+}
+
+static inline tcb_t *__tcb_get(void)
+{
+	void *retval;
+	
+	asm volatile (
+		"mov %%g7, %0\n"
+		: "=r" (retval)
+	);
+	
+	return retval;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/types.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/types.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/include/libarch/types.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_TYPES_H_
+#define LIBC_sparc32_TYPES_H_
+
+#define __32_BITS__
+
+#include <libarch/common.h>
+
+#define SIZE_MIN  UINT32_MIN
+#define SIZE_MAX  UINT32_MAX
+
+#define SSIZE_MIN  INT32_MIN
+#define SSIZE_MAX  INT32_MAX
+
+typedef uint32_t sysarg_t;
+typedef int32_t native_t;
+
+typedef int32_t ssize_t;
+typedef uint32_t size_t;
+
+typedef uint32_t uintptr_t;
+typedef int32_t intptr_t;
+typedef uint32_t atomic_count_t;
+typedef int32_t atomic_signed_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/src/entry.s
===================================================================
--- uspace/lib/c/arch/sparc32/src/entry.s	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/src/entry.s	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,67 @@
+#
+# Copyright (c) 2006 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.
+#
+
+.section .init, "ax"
+
+.org 0
+
+.globl __entry
+
+## User-space task entry point
+#
+# %o0 contains uarg
+# %o1 contains pcb_ptr
+#
+__entry:
+	#
+	# Create the first stack frame.
+	#
+	
+	save %sp, -176, %sp
+	## XXX	flushw
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		save %sp, -64, %sp
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		restore
+	
+	## XXX end flush
+	## add %g0, -0x7ff, %fp
+	set 0x80000000, %fp
+	
+	# Pass pcb_ptr as the first argument to __main()
+	mov %i1, %o0
+	sethi %hi(_gp), %l7
+	call __main
+	or %l7, %lo(_gp), %l7
Index: uspace/lib/c/arch/sparc32/src/entryjmp.s
===================================================================
--- uspace/lib/c/arch/sparc32/src/entryjmp.s	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/src/entryjmp.s	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,42 @@
+#
+# 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.
+#
+
+.globl entry_point_jmp
+
+## void entry_point_jmp(void *entry_point, void *pcb);
+#
+# %o0	contains entry_point
+# %o1	contains pcb
+#
+# Jump to program entry point
+entry_point_jmp:
+	# Pass pcb pointer to entry point in %o1. As it is already
+	# there, no action is needed.
+	call %o0
+	nop
+	# FIXME: use branch instead of call
Index: uspace/lib/c/arch/sparc32/src/fibril.S
===================================================================
--- uspace/lib/c/arch/sparc32/src/fibril.S	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/src/fibril.S	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,85 @@
+#
+# Copyright (c) 2005 Jakub Jermar
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+#include <libarch/context_offset.h>
+
+.text
+
+.global flush_windows
+.global context_save
+.global context_restore
+
+context_save:
+	#
+	# We rely on the kernel to flush our active register windows to memory
+	# should a thread switch occur.
+	#
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		save %sp, -64, %sp
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		restore
+	
+	CONTEXT_SAVE_ARCH_CORE %o0
+	retl
+	mov 1, %o0              ! context_save_arch returns 1
+
+context_restore:
+	#
+	# Flush all active windows.
+	# This is essential, because CONTEXT_RESTORE_ARCH_CORE overwrites %sp of
+	# CWP - 1 with the value written to %fp of CWP.  Flushing all active
+	# windows mitigates this problem as CWP - 1 becomes the overlap window.
+	#
+	
+	## XXX
+	## flushw
+	## ta 0x4f
+	## nop
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		save %sp, -64, %sp
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		restore
+	
+	CONTEXT_RESTORE_ARCH_CORE %o0
+	retl
+	xor %o0, %o0, %o0       ! context_restore_arch returns 0
Index: uspace/lib/c/arch/sparc32/src/stacktrace.c
===================================================================
--- uspace/lib/c/arch/sparc32/src/stacktrace.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/src/stacktrace.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * Copyright (c) 2010 Jiri Svoboda
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <libarch/stack.h>
+#include <errno.h>
+#include <stacktrace.h>
+
+#define FRAME_OFFSET_FP_PREV  (14 * 4)
+#define FRAME_OFFSET_RA       (15 * 4)
+
+bool stacktrace_fp_valid(stacktrace_t *st, uintptr_t fp)
+{
+	(void) st;
+	return fp != 0;
+}
+
+int stacktrace_fp_prev(stacktrace_t *st, uintptr_t fp, uintptr_t *prev)
+{
+	uintptr_t bprev;
+	int rc = (*st->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_FP_PREV,
+	    &bprev);
+	if (rc == EOK)
+		*prev = bprev;
+	
+	return rc;
+}
+
+int stacktrace_ra_get(stacktrace_t *st, uintptr_t fp, uintptr_t *ra)
+{
+	return (*st->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_RA, ra);
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/src/stacktrace_asm.S
===================================================================
--- uspace/lib/c/arch/sparc32/src/stacktrace_asm.S	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/src/stacktrace_asm.S	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2009 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
+
+.global stacktrace_prepare
+.global stacktrace_fp_get
+.global stacktrace_pc_get
+
+stacktrace_prepare:
+	save %sp, -(STACK_WINDOW_SAVE_AREA_SIZE+STACK_ARG_SAVE_AREA_SIZE), %sp
+	
+	# Flush all other windows to memory so that we can read their contents.
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		save %sp, -64, %sp
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+	
+	ret
+	restore
+
+stacktrace_fp_get:
+	# Add the stack bias to %sp to get the actual address.
+	retl
+	mov %sp,  %o0
+
+stacktrace_pc_get:
+	retl
+	mov %o7, %o0
Index: uspace/lib/c/arch/sparc32/src/thread_entry.s
===================================================================
--- uspace/lib/c/arch/sparc32/src/thread_entry.s	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/src/thread_entry.s	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,69 @@
+#
+# 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
+
+.globl __thread_entry
+
+## User-space thread entry point for all but the first threads.
+#
+#
+__thread_entry:
+	#
+	# Create the first stack frame.
+	#
+	
+	save %sp, -176, %sp
+	## XXX flushw
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		save %sp, -64, %sp
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+	
+	## XXX end flushw
+	set 0x80000000, %fp
+	
+	#
+	# Propagate the input arguments to the new window.
+	#
+	
+	mov %i0, %o0
+	
+	sethi %hi(_gp), %l7
+	call __thread_main      ! %o0 contains address of uarg
+	or %l7, %lo(_gp), %l7
+	
+	! not reached
+	
+.end __thread_entry
Index: uspace/lib/c/arch/sparc32/src/tls.c
===================================================================
--- uspace/lib/c/arch/sparc32/src/tls.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/arch/sparc32/src/tls.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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 libcsparc32 sparc32
+ * @ingroup lc
+ * @{
+ */
+/** @file
+ *
+ */
+
+#include <tls.h>
+#include <sys/types.h>
+
+tcb_t *tls_alloc_arch(void **data, size_t size)
+{
+	return tls_alloc_variant_2(data, size);
+}
+
+void tls_free_arch(tcb_t *tcb, size_t size)
+{
+	tls_free_variant_2(tcb, size);
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/adt/checksum.c
===================================================================
--- uspace/lib/c/generic/adt/checksum.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/generic/adt/checksum.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2012 Dominik Taborsky
+ * 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 <adt/checksum.h>
+
+/**
+ * 256-value table of precomputed polynomials for CRC32. Note
+ * the values depend on the selected divisor polynomial (currently
+ * 0xedb88320) and whether the CRC computation is reflected or not.
+ * See http://www.repairfaq.org/filipg/LINK/F_crc_v3.html for a perfect
+ * source of info about this.
+ */
+uint32_t poly_table[256] = {
+	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+/** Compute CRC32 value.
+ *
+ * See wiki.osdev.org/CRC32 for reference.
+ *
+ * @param[in] data   Data to process.
+ * @param[in] length Length of the data in bytes.
+ *
+ * @return Computed CRC32 of the data.
+ *
+ */
+uint32_t compute_crc32(uint8_t *data, size_t length)
+{
+	return compute_crc32_seed(data, length, 0);
+}
+
+/** Compute CRC32 value with initial seed.
+ *
+ * Use this when checksumming non-continous data (linked lists, trees,
+ * etc.). On the first data block call compute_crc32() and use the result
+ * as the seed for the following call of compute_crc32_seed() on the next
+ * block. Then use the result of that call as the seed of the following
+ * call, etc.
+ *
+ * @param[in] data   Fata to process.
+ * @param[in] length Length of the data in bytes.
+ * @param[in] seed   The starting value of the CRC.
+ *
+ * @return Computed CRC32 of the data of all the previous blocks.
+ *
+ */
+uint32_t compute_crc32_seed(uint8_t *data, size_t length, uint32_t seed)
+{
+	uint32_t crc;
+	
+	for (crc = ~seed; length > 0; length--)
+		crc = poly_table[((uint8_t) crc ^ *(data++))] ^ (crc >> 8);
+	
+	return (~crc);
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/assert.c
===================================================================
--- uspace/lib/c/generic/assert.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/generic/assert.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -33,5 +33,5 @@
 #include <assert.h>
 #include <stdio.h>
-#include <io/klog.h>
+#include <io/kio.h>
 #include <stdlib.h>
 #include <atomic.h>
@@ -44,7 +44,7 @@
 {
 	/*
-	 * Send the message safely to klog. Nested asserts should not occur.
+	 * Send the message safely to kio. Nested asserts should not occur.
 	 */
-	klog_printf("Assertion failed (%s) in file \"%s\", line %u.\n",
+	kio_printf("Assertion failed (%s) in file \"%s\", line %u.\n",
 	    cond, file, line);
 	
Index: uspace/lib/c/generic/bitops.c
===================================================================
--- uspace/lib/c/generic/bitops.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * Copyright (c) 2013 Vojtech Horky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-
-#include <bitops.h>
-
-int __popcountsi2(int a)
-{
-	int bits = 0;
-	for (unsigned int i = 0; i < sizeof(a) * 8; i++)	 {
-		if (((a >> i) & 1) != 0) {
-			bits++;
-		}
-	}
-	return bits;									
-}
-
-
-/** @}
- */
Index: uspace/lib/c/generic/ddi.c
===================================================================
--- uspace/lib/c/generic/ddi.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/generic/ddi.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -280,5 +280,5 @@
  *
  */
-int irq_register(int inr, int devno, int method, irq_code_t *ucode)
+int irq_register(int inr, int devno, int method, const irq_code_t *ucode)
 {
 	return __SYSCALL4(SYS_IRQ_REGISTER, inr, devno, method,
Index: uspace/lib/c/generic/device/ahci.c
===================================================================
--- uspace/lib/c/generic/device/ahci.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,185 +1,0 @@
-/*
- * Copyright (c) 2012 Petr Jerman
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#include <ipc/dev_iface.h>
-#include <assert.h>
-#include <device/ahci.h>
-#include <errno.h>
-#include <async.h>
-#include <ipc/services.h>
-#include <stdio.h>
-#include <as.h>
-
-typedef enum {
-	IPC_M_AHCI_GET_SATA_DEVICE_NAME,
-	IPC_M_AHCI_GET_NUM_BLOCKS,
-	IPC_M_AHCI_GET_BLOCK_SIZE,
-	IPC_M_AHCI_READ_BLOCKS,
-	IPC_M_AHCI_WRITE_BLOCKS,
-} ahci_iface_funcs_t;
-
-#define MAX_NAME_LENGTH  1024
-
-#define LO(ptr) \
-	((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) & 0xffffffff))
-
-#define HI(ptr) \
-	((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) >> 32))
-
-async_sess_t* ahci_get_sess(devman_handle_t funh, char **name)
-{
-	// FIXME: Use a better way than substring match
-	
-	*name = NULL;
-	
-	char devn[MAX_NAME_LENGTH];
-	int rc = devman_fun_get_name(funh, devn, MAX_NAME_LENGTH);
-	if (rc != EOK)
-		return NULL;
-	
-	size_t devn_size = str_size(devn);
-	
-	if ((devn_size > 5) && (str_lcmp(devn, "ahci_", 5) == 0)) {
-		async_sess_t *sess = devman_device_connect(EXCHANGE_PARALLEL,
-		    funh, IPC_FLAG_BLOCKING);
-		
-		if (sess) {
-			*name = str_dup(devn);
-			return sess;
-		}
-	}
-	
-	return NULL;
-}
-
-int ahci_get_sata_device_name(async_sess_t *sess, size_t sata_dev_name_length,
-    char *sata_dev_name)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	if (!exch)
-		return EINVAL;
-	
-	aid_t req = async_send_2(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
-	    IPC_M_AHCI_GET_SATA_DEVICE_NAME, sata_dev_name_length, NULL);
-	
-	async_data_read_start(exch, sata_dev_name, sata_dev_name_length);
-	
-	sysarg_t rc;
-	async_wait_for(req, &rc);
-	
-	return rc;
-}
-
-int ahci_get_num_blocks(async_sess_t *sess, uint64_t *blocks)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	if (!exch)
-		return EINVAL;
-	
-	sysarg_t blocks_hi;
-	sysarg_t blocks_lo;
-	int rc = async_req_1_2(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
-	    IPC_M_AHCI_GET_NUM_BLOCKS, &blocks_hi, &blocks_lo);
-	
-	async_exchange_end(exch);
-	
-	if (rc == EOK) {
-		*blocks = (((uint64_t) blocks_hi) << 32)
-		    | (((uint64_t) blocks_lo) & 0xffffffff);
-	}
-	
-	return rc;
-}
-
-int ahci_get_block_size(async_sess_t *sess, size_t *blocks_size)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	if (!exch)
-		return EINVAL;
-	
-	sysarg_t bs;
-	int rc = async_req_1_1(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
-	    IPC_M_AHCI_GET_BLOCK_SIZE, &bs);
-	
-	async_exchange_end(exch);
-	
-	if (rc == EOK)
-		*blocks_size = (size_t) bs;
-	
-	return rc;
-}
-
-int ahci_read_blocks(async_sess_t *sess, uint64_t blocknum, size_t count,
-    void *buf)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	if (!exch)
-		return EINVAL;
-	
-	aid_t req;
-	req = async_send_4(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
-	    IPC_M_AHCI_READ_BLOCKS, HI(blocknum),  LO(blocknum), count, NULL);
-	
-	async_share_out_start(exch, buf, AS_AREA_READ | AS_AREA_WRITE);
-	
-	async_exchange_end(exch);
-	
-	sysarg_t rc;
-	async_wait_for(req, &rc);
-	
-	return rc;
-}
-
-int ahci_write_blocks(async_sess_t *sess, uint64_t blocknum, size_t count,
-    void* buf)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	if (!exch)
-		return EINVAL;
-	
-	aid_t req = async_send_4(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
-	    IPC_M_AHCI_WRITE_BLOCKS, HI(blocknum),  LO(blocknum), count, NULL);
-	
-	async_share_out_start(exch, buf, AS_AREA_READ | AS_AREA_WRITE);
-	
-	async_exchange_end(exch);
-	
-	sysarg_t rc;
-	async_wait_for(req, &rc);
-	
-	return rc;
-}
-
-/** @}
- */
Index: uspace/lib/c/generic/device/battery_dev.c
===================================================================
--- uspace/lib/c/generic/device/battery_dev.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,93 +1,0 @@
-/*
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#include <ipc/dev_iface.h>
-#include <device/battery_dev.h>
-#include <errno.h>
-#include <async.h>
-#include <time.h>
-
-/** Read the current battery status from the device
- *
- * @param sess     Session of the device
- * @param status   Current status of the battery
- *
- * @return         EOK on success or a negative error code
- */
-int
-battery_status_get(async_sess_t *sess, battery_status_t *batt_status)
-{
-	sysarg_t status;
-
-	async_exch_t *exch = async_exchange_begin(sess);
-
-	int const rc = async_req_1_1(exch, DEV_IFACE_ID(BATTERY_DEV_IFACE),
-	    BATTERY_STATUS_GET, &status);
-
-	async_exchange_end(exch);
-
-	if (rc == EOK)
-		*batt_status = (battery_status_t) status;
-
-	return rc;
-}
-
-/** Read the current battery charge level from the device
- *
- * @param sess     Session of the device
- * @param level    Battery charge level (0 - 100)
- *
- * @return         EOK on success or a negative error code
- */
-int
-battery_charge_level_get(async_sess_t *sess, int *level)
-{
-	sysarg_t charge_level;
-
-	async_exch_t *exch = async_exchange_begin(sess);
-
-	int const rc = async_req_1_1(exch, DEV_IFACE_ID(BATTERY_DEV_IFACE),
-	    BATTERY_CHARGE_LEVEL_GET, &charge_level);
-
-	async_exchange_end(exch);
-
-	if (rc == EOK)
-		*level = (int) charge_level;
-
-	return rc;
-}
-
-/** @}
- */
-
Index: uspace/lib/c/generic/device/char_dev.c
===================================================================
--- uspace/lib/c/generic/device/char_dev.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,127 +1,0 @@
-/*
- * Copyright (c) 2010 Lenka Trochtova
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- /** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#include <ipc/dev_iface.h>
-#include <device/char_dev.h>
-#include <errno.h>
-#include <async.h>
-#include <malloc.h>
-#include <stdio.h>
-
-/** Read to or write from device.
- *
- * Helper function to read to or write from a device
- * using its character interface.
- *
- * @param sess Session to the device.
- * @param buf  Buffer for the data read from or written to the device.
- * @param size Maximum size of data (in bytes) to be read or written.
- * @param read Read from the device if true, write to it otherwise.
- *
- * @return Non-negative number of bytes actually read from or
- *         written to the device on success, negative error number
- *         otherwise.
- *
- */
-static ssize_t char_dev_rw(async_sess_t *sess, void *buf, size_t size, bool read)
-{
-	ipc_call_t answer;
-	aid_t req;
-	int ret;
-	
-	async_exch_t *exch = async_exchange_begin(sess);
-	
-	if (read) {
-		req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE),
-		    CHAR_DEV_READ, &answer);
-		ret = async_data_read_start(exch, buf, size);
-	} else {
-		req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE),
-		    CHAR_DEV_WRITE, &answer);
-		ret = async_data_write_start(exch, buf, size);
-	}
-	
-	async_exchange_end(exch);
-	
-	sysarg_t rc;
-	if (ret != EOK) {
-		async_wait_for(req, &rc);
-		if (rc == EOK)
-			return (ssize_t) ret;
-		
-		return (ssize_t) rc;
-	}
-	
-	async_wait_for(req, &rc);
-	
-	ret = (int) rc;
-	if (ret != EOK)
-		return (ssize_t) ret;
-	
-	return (ssize_t) IPC_GET_ARG1(answer);
-}
-
-/** Read from character device.
- *
- * @param sess Session to the device.
- * @param buf  Output buffer for the data read from the device.
- * @param size Maximum size (in bytes) of the data to be read.
- *
- * @return Non-negative number of bytes actually read from the
- *         device on success, negative error number otherwise.
- *
- */
-ssize_t char_dev_read(async_sess_t *sess, void *buf, size_t size)
-{
-	return char_dev_rw(sess, buf, size, true);
-}
-
-/** Write to character device.
- *
- * @param sess Session to the device.
- * @param buf  Input buffer containg the data to be written to the
- *             device.
- * @param size Maximum size (in bytes) of the data to be written.
- *
- * @return Non-negative number of bytes actually written to the
- *         device on success, negative error number otherwise.
- *
- */
-ssize_t char_dev_write(async_sess_t *sess, void *buf, size_t size)
-{
-	return char_dev_rw(sess, buf, size, false);
-}
-
-/** @}
- */
Index: uspace/lib/c/generic/device/graph_dev.c
===================================================================
--- uspace/lib/c/generic/device/graph_dev.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2011 Petr Koupy
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- /** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#include <errno.h>
-#include <ipc/dev_iface.h>
-#include <device/graph_dev.h>
-
-int graph_dev_connect(async_sess_t *sess)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	int ret = async_req_1_0(exch, DEV_IFACE_ID(GRAPH_DEV_IFACE), GRAPH_DEV_CONNECT);
-	async_exchange_end(exch);
-
-	return ret;
-}
-
-/** @}
- */
Index: uspace/lib/c/generic/device/nic.c
===================================================================
--- uspace/lib/c/generic/device/nic.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,1292 +1,0 @@
-/*
- * Copyright (c) 2011 Radim Vansa
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/**
- * @file
- * @brief Client-side RPC stubs for DDF NIC
- */
-
-#include <ipc/dev_iface.h>
-#include <assert.h>
-#include <device/nic.h>
-#include <errno.h>
-#include <async.h>
-#include <malloc.h>
-#include <stdio.h>
-#include <ipc/services.h>
-
-/** Send frame from NIC
- *
- * @param[in] dev_sess
- * @param[in] data     Frame data
- * @param[in] size     Frame size in bytes
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_send_frame(async_sess_t *dev_sess, void *data, size_t size)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	ipc_call_t answer;
-	aid_t req = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_SEND_MESSAGE, &answer);
-	sysarg_t retval = async_data_write_start(exch, data, size);
-	
-	async_exchange_end(exch);
-	
-	if (retval != EOK) {
-		async_forget(req);
-		return retval;
-	}
-
-	async_wait_for(req, &retval);
-	return retval;
-}
-
-/** Create callback connection from NIC service
- *
- * @param[in] dev_sess
- * @param[in] device_id
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_callback_create(async_sess_t *dev_sess, async_client_conn_t cfun,
-    void *carg)
-{
-	ipc_call_t answer;
-	int rc;
-	sysarg_t retval;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	aid_t req = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_CALLBACK_CREATE, &answer);
-	
-	rc = async_connect_to_me(exch, 0, 0, 0, cfun, carg);
-	if (rc != EOK) {
-		async_forget(req);
-		return rc;
-	}
-	async_exchange_end(exch);
-	
-	async_wait_for(req, &retval);
-	return (int) retval;
-}
-
-/** Get the current state of the device
- *
- * @param[in]  dev_sess
- * @param[out] state    Current state
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_get_state(async_sess_t *dev_sess, nic_device_state_t *state)
-{
-	assert(state);
-	
-	sysarg_t _state;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_GET_STATE, &_state);
-	async_exchange_end(exch);
-	
-	*state = (nic_device_state_t) _state;
-	
-	return rc;
-}
-
-/** Request the device to change its state
- *
- * @param[in] dev_sess
- * @param[in] state    New state
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_set_state(async_sess_t *dev_sess, nic_device_state_t state)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_SET_STATE, state);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Request the MAC address of the device
- *
- * @param[in]  dev_sess
- * @param[out] address  Structure with buffer for the address
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_get_address(async_sess_t *dev_sess, nic_address_t *address)
-{
-	assert(address);
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	aid_t aid = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_GET_ADDRESS, NULL);
-	int rc = async_data_read_start(exch, address, sizeof(nic_address_t));
-	async_exchange_end(exch);
-	
-	sysarg_t res;
-	async_wait_for(aid, &res);
-	
-	if (rc != EOK)
-		return rc;
-	
-	return (int) res;
-}
-
-/** Set the address of the device (e.g. MAC on Ethernet)
- *
- * @param[in] dev_sess
- * @param[in] address  Pointer to the address
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_set_address(async_sess_t *dev_sess, const nic_address_t *address)
-{
-	assert(address);
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	aid_t aid = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_SET_ADDRESS, NULL);
-	int rc = async_data_write_start(exch, address, sizeof(nic_address_t));
-	async_exchange_end(exch);
-	
-	sysarg_t res;
-	async_wait_for(aid, &res);
-	
-	if (rc != EOK)
-		return rc;
-	
-	return (int) res;
-}
-
-/** Request statistic data about NIC operation.
- *
- * @param[in]  dev_sess
- * @param[out] stats    Structure with the statistics
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_get_stats(async_sess_t *dev_sess, nic_device_stats_t *stats)
-{
-	assert(stats);
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_GET_STATS);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	rc = async_data_read_start(exch, stats, sizeof(nic_device_stats_t));
-	
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Request information about the device.
- *
- * @see nic_device_info_t
- *
- * @param[in]  dev_sess
- * @param[out] device_info Information about the device
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_get_device_info(async_sess_t *dev_sess, nic_device_info_t *device_info)
-{
-	assert(device_info);
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_GET_DEVICE_INFO);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	rc = async_data_read_start(exch, device_info, sizeof(nic_device_info_t));
-	
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Request status of the cable (plugged/unplugged)
- *
- * @param[in]  dev_sess
- * @param[out] cable_state Current cable state
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_get_cable_state(async_sess_t *dev_sess, nic_cable_state_t *cable_state)
-{
-	assert(cable_state);
-	
-	sysarg_t _cable_state;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_GET_CABLE_STATE, &_cable_state);
-	async_exchange_end(exch);
-	
-	*cable_state = (nic_cable_state_t) _cable_state;
-	
-	return rc;
-}
-
-/** Request current operation mode.
- *
- * @param[in]  dev_sess
- * @param[out] speed    Current operation speed in Mbps. Can be NULL.
- * @param[out] duplex   Full duplex/half duplex. Can be NULL.
- * @param[out] role     Master/slave/auto. Can be NULL.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_get_operation_mode(async_sess_t *dev_sess, int *speed,
-   nic_channel_mode_t *duplex, nic_role_t *role)
-{
-	sysarg_t _speed;
-	sysarg_t _duplex;
-	sysarg_t _role;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_GET_OPERATION_MODE, &_speed, &_duplex, &_role);
-	async_exchange_end(exch);
-	
-	if (speed)
-		*speed = (int) _speed;
-	
-	if (duplex)
-		*duplex = (nic_channel_mode_t) _duplex;
-	
-	if (role)
-		*role = (nic_role_t) _role;
-	
-	return rc;
-}
-
-/** Set current operation mode.
- *
- * If the NIC has auto-negotiation enabled, this command
- * disables auto-negotiation and sets the operation mode.
- *
- * @param[in] dev_sess
- * @param[in] speed    Operation speed in Mbps
- * @param[in] duplex   Full duplex/half duplex
- * @param[in] role     Master/slave/auto (e.g. in Gbit Ethernet]
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_set_operation_mode(async_sess_t *dev_sess, int speed,
-    nic_channel_mode_t duplex, nic_role_t role)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_SET_OPERATION_MODE, (sysarg_t) speed, (sysarg_t) duplex,
-	    (sysarg_t) role);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Enable auto-negotiation.
- *
- * The advertisement argument can only limit some modes,
- * it can never force the NIC to advertise unsupported modes.
- *
- * The allowed modes are defined in "nic/eth_phys.h" in the C library.
- *
- * @param[in] dev_sess
- * @param[in] advertisement Allowed advertised modes. Use 0 for all modes.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_autoneg_enable(async_sess_t *dev_sess, uint32_t advertisement)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_AUTONEG_ENABLE, (sysarg_t) advertisement);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Disable auto-negotiation.
- *
- * @param[in] dev_sess
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_autoneg_disable(async_sess_t *dev_sess)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_AUTONEG_DISABLE);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Probe current state of auto-negotiation.
- *
- * Modes are defined in the "nic/eth_phys.h" in the C library.
- *
- * @param[in]  dev_sess
- * @param[out] our_advertisement   Modes advertised by this NIC.
- *                                 Can be NULL.
- * @param[out] their_advertisement Modes advertised by the other side.
- *                                 Can be NULL.
- * @param[out] result              General state of auto-negotiation.
- *                                 Can be NULL.
- * @param[out]  their_result       State of other side auto-negotiation.
- *                                 Can be NULL.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_autoneg_probe(async_sess_t *dev_sess, uint32_t *our_advertisement,
-    uint32_t *their_advertisement, nic_result_t *result,
-    nic_result_t *their_result)
-{
-	sysarg_t _our_advertisement;
-	sysarg_t _their_advertisement;
-	sysarg_t _result;
-	sysarg_t _their_result;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_4(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_AUTONEG_PROBE, &_our_advertisement, &_their_advertisement,
-	    &_result, &_their_result);
-	async_exchange_end(exch);
-	
-	if (our_advertisement)
-		*our_advertisement = (uint32_t) _our_advertisement;
-	
-	if (*their_advertisement)
-		*their_advertisement = (uint32_t) _their_advertisement;
-	
-	if (result)
-		*result = (nic_result_t) _result;
-	
-	if (their_result)
-		*their_result = (nic_result_t) _their_result;
-	
-	return rc;
-}
-
-/** Restart the auto-negotiation process.
- *
- * @param[in] dev_sess
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_autoneg_restart(async_sess_t *dev_sess)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_AUTONEG_RESTART);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Query party's sending and reception of the PAUSE frame.
- *
- * @param[in]  dev_sess
- * @param[out] we_send    This NIC sends the PAUSE frame (true/false)
- * @param[out] we_receive This NIC receives the PAUSE frame (true/false)
- * @param[out] pause      The time set to transmitted PAUSE frames.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_get_pause(async_sess_t *dev_sess, nic_result_t *we_send,
-    nic_result_t *we_receive, uint16_t *pause)
-{
-	sysarg_t _we_send;
-	sysarg_t _we_receive;
-	sysarg_t _pause;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_GET_PAUSE, &_we_send, &_we_receive, &_pause);
-	async_exchange_end(exch);
-	
-	if (we_send)
-		*we_send = _we_send;
-	
-	if (we_receive)
-		*we_receive = _we_receive;
-	
-	if (pause)
-		*pause = _pause;
-	
-	return rc;
-}
-
-/** Control sending and reception of the PAUSE frame.
- *
- * @param[in] dev_sess
- * @param[in] allow_send    Allow sending the PAUSE frame (true/false)
- * @param[in] allow_receive Allow reception of the PAUSE frame (true/false)
- * @param[in] pause         Pause length in 512 bit units written
- *                          to transmitted frames. The value 0 means
- *                          auto value (the best). If the requested
- *                          time cannot be set the driver is allowed
- *                          to set the nearest supported value.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_set_pause(async_sess_t *dev_sess, int allow_send, int allow_receive,
-    uint16_t pause)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_SET_PAUSE, allow_send, allow_receive, pause);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Retrieve current settings of unicast frames reception.
- *
- * Note: In case of mode != NIC_UNICAST_LIST the contents of
- * address_list and address_count are undefined.
- *
- * @param[in]   dev_sess
- * @param[out]  mode          Current operation mode
- * @param[in]   max_count     Maximal number of addresses that could
- *                            be written into the list buffer.
- * @param[out]  address_list  Buffer for the list (array). Can be NULL.
- * @param[out]  address_count Number of addresses in the list before
- *                            possible truncation due to the max_count.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_unicast_get_mode(async_sess_t *dev_sess, nic_unicast_mode_t *mode,
-    size_t max_count, nic_address_t *address_list, size_t *address_count)
-{
-	assert(mode);
-	
-	sysarg_t _mode;
-	sysarg_t _address_count;
-	
-	if (!address_list)
-		max_count = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	int rc = async_req_2_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_UNICAST_GET_MODE, max_count, &_mode, &_address_count);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	*mode = (nic_unicast_mode_t) _mode;
-	if (address_count)
-		*address_count = (size_t) _address_count;
-	
-	if ((max_count) && (_address_count))
-		rc = async_data_read_start(exch, address_list,
-		    max_count * sizeof(nic_address_t));
-	
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Set which unicast frames are received.
- *
- * @param[in] dev_sess
- * @param[in] mode          Current operation mode
- * @param[in] address_list  The list of addresses. Can be NULL.
- * @param[in] address_count Number of addresses in the list.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_unicast_set_mode(async_sess_t *dev_sess, nic_unicast_mode_t mode,
-    const nic_address_t *address_list, size_t address_count)
-{
-	if (address_list == NULL)
-		address_count = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_UNICAST_SET_MODE, (sysarg_t) mode, address_count, NULL);
-	
-	int rc;
-	if (address_count)
-		rc = async_data_write_start(exch, address_list,
-		    address_count * sizeof(nic_address_t));
-	else
-		rc = EOK;
-	
-	async_exchange_end(exch);
-	
-	sysarg_t res;
-	async_wait_for(message_id, &res);
-	
-	if (rc != EOK)
-		return rc;
-	
-	return (int) res;
-}
-
-/** Retrieve current settings of multicast frames reception.
- *
- * Note: In case of mode != NIC_MULTICAST_LIST the contents of
- * address_list and address_count are undefined.
- *
- * @param[in]  dev_sess
- * @param[out] mode          Current operation mode
- * @param[in]  max_count     Maximal number of addresses that could
- *                           be written into the list buffer.
- * @param[out] address_list  Buffer for the list (array). Can be NULL.
- * @param[out] address_count Number of addresses in the list before
- *                           possible truncation due to the max_count.
- *                           Can be NULL.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_multicast_get_mode(async_sess_t *dev_sess, nic_multicast_mode_t *mode,
-    size_t max_count, nic_address_t *address_list, size_t *address_count)
-{
-	assert(mode);
-	
-	sysarg_t _mode;
-	
-	if (!address_list)
-		max_count = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	sysarg_t ac;
-	int rc = async_req_2_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_MULTICAST_GET_MODE, max_count, &_mode, &ac);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	*mode = (nic_multicast_mode_t) _mode;
-	if (address_count)
-		*address_count = (size_t) ac;
-	
-	if ((max_count) && (ac))
-		rc = async_data_read_start(exch, address_list,
-		    max_count * sizeof(nic_address_t));
-	
-	async_exchange_end(exch);
-	return rc;
-}
-
-/** Set which multicast frames are received.
- *
- * @param[in] dev_sess
- * @param[in] mode          Current operation mode
- * @param[in] address_list  The list of addresses. Can be NULL.
- * @param[in] address_count Number of addresses in the list.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_multicast_set_mode(async_sess_t *dev_sess, nic_multicast_mode_t mode,
-    const nic_address_t *address_list, size_t address_count)
-{
-	if (address_list == NULL)
-		address_count = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_MULTICAST_SET_MODE, (sysarg_t) mode, address_count, NULL);
-	
-	int rc;
-	if (address_count)
-		rc = async_data_write_start(exch, address_list,
-		    address_count * sizeof(nic_address_t));
-	else
-		rc = EOK;
-	
-	async_exchange_end(exch);
-	
-	sysarg_t res;
-	async_wait_for(message_id, &res);
-	
-	if (rc != EOK)
-		return rc;
-	
-	return (int) res;
-}
-
-/** Determine if broadcast packets are received.
- *
- * @param[in]  dev_sess
- * @param[out] mode     Current operation mode
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_broadcast_get_mode(async_sess_t *dev_sess, nic_broadcast_mode_t *mode)
-{
-	assert(mode);
-	
-	sysarg_t _mode;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_BROADCAST_GET_MODE, &_mode);
-	async_exchange_end(exch);
-	
-	*mode = (nic_broadcast_mode_t) _mode;
-	
-	return rc;
-}
-
-/** Set whether broadcast packets are received.
- *
- * @param[in] dev_sess
- * @param[in] mode     Current operation mode
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_broadcast_set_mode(async_sess_t *dev_sess, nic_broadcast_mode_t mode)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_BROADCAST_SET_MODE, mode);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Determine if defective (erroneous) packets are received.
- *
- * @param[in]  dev_sess
- * @param[out] mode     Bitmask specifying allowed errors
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_defective_get_mode(async_sess_t *dev_sess, uint32_t *mode)
-{
-	assert(mode);
-	
-	sysarg_t _mode;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_DEFECTIVE_GET_MODE, &_mode);
-	async_exchange_end(exch);
-	
-	*mode = (uint32_t) _mode;
-	
-	return rc;
-}
-
-/** Set whether defective (erroneous) packets are received.
- *
- * @param[in]  dev_sess
- * @param[out] mode     Bitmask specifying allowed errors
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_defective_set_mode(async_sess_t *dev_sess, uint32_t mode)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_DEFECTIVE_SET_MODE, mode);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Retrieve the currently blocked source MAC addresses.
- *
- * @param[in]  dev_sess
- * @param[in]  max_count     Maximal number of addresses that could
- *                           be written into the list buffer.
- * @param[out] address_list  Buffer for the list (array). Can be NULL.
- * @param[out] address_count Number of addresses in the list before
- *                           possible truncation due to the max_count.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_blocked_sources_get(async_sess_t *dev_sess, size_t max_count,
-    nic_address_t *address_list, size_t *address_count)
-{
-	if (!address_list)
-		max_count = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	sysarg_t ac;
-	int rc = async_req_2_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_BLOCKED_SOURCES_GET, max_count, &ac);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	if (address_count)
-		*address_count = (size_t) ac;
-	
-	if ((max_count) && (ac))
-		rc = async_data_read_start(exch, address_list,
-		    max_count * sizeof(nic_address_t));
-	
-	async_exchange_end(exch);
-	return rc;
-}
-
-/** Set which source MACs are blocked
- *
- * @param[in] dev_sess
- * @param[in] address_list  The list of addresses. Can be NULL.
- * @param[in] address_count Number of addresses in the list.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_blocked_sources_set(async_sess_t *dev_sess,
-    const nic_address_t *address_list, size_t address_count)
-{
-	if (address_list == NULL)
-		address_count = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	aid_t message_id = async_send_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_BLOCKED_SOURCES_SET, address_count, NULL);
-	
-	int rc;
-	if (address_count)
-		rc = async_data_write_start(exch, address_list,
-			address_count * sizeof(nic_address_t));
-	else
-		rc = EOK;
-	
-	async_exchange_end(exch);
-	
-	sysarg_t res;
-	async_wait_for(message_id, &res);
-	
-	if (rc != EOK)
-		return rc;
-	
-	return (int) res;
-}
-
-/** Request current VLAN filtering mask.
- *
- * @param[in]  dev_sess
- * @param[out] stats    Structure with the statistics
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_vlan_get_mask(async_sess_t *dev_sess, nic_vlan_mask_t *mask)
-{
-	assert(mask);
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_VLAN_GET_MASK);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	rc = async_data_read_start(exch, mask, sizeof(nic_vlan_mask_t));
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Set the mask used for VLAN filtering.
- *
- * If NULL, VLAN filtering is disabled.
- *
- * @param[in] dev_sess
- * @param[in] mask     Pointer to mask structure or NULL to disable.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_vlan_set_mask(async_sess_t *dev_sess, const nic_vlan_mask_t *mask)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	aid_t message_id = async_send_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_VLAN_SET_MASK, mask != NULL, NULL);
-	
-	int rc;
-	if (mask != NULL)
-		rc = async_data_write_start(exch, mask, sizeof(nic_vlan_mask_t));
-	else
-		rc = EOK;
-	
-	async_exchange_end(exch);
-	
-	sysarg_t res;
-	async_wait_for(message_id, &res);
-	
-	if (rc != EOK)
-		return rc;
-	
-	return (int) res;
-}
-
-/** Set VLAN (802.1q) tag.
- *
- * Set whether the tag is to be signaled in offload info and
- * if the tag should be stripped from received frames and added
- * to sent frames automatically. Not every combination of add
- * and strip must be supported.
- *
- * @param[in] dev_sess
- * @param[in] tag      VLAN priority (top 3 bits) and
- *                     the VLAN tag (bottom 12 bits)
- * @param[in] add      Add the VLAN tag automatically (boolean)
- * @param[in] strip    Strip the VLAN tag automatically (boolean)
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_vlan_set_tag(async_sess_t *dev_sess, uint16_t tag, bool add, bool strip)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_VLAN_SET_TAG, (sysarg_t) tag, (sysarg_t) add, (sysarg_t) strip);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Add new Wake-On-LAN virtue.
- *
- * @param[in]  dev_sess
- * @param[in]  type     Type of the virtue
- * @param[in]  data     Data required for this virtue
- *                      (depends on type)
- * @param[in]  length   Length of the data
- * @param[out] id       Identifier of the new virtue
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_wol_virtue_add(async_sess_t *dev_sess, nic_wv_type_t type,
-    const void *data, size_t length, nic_wv_id_t *id)
-{
-	assert(id);
-	
-	bool send_data = ((data != NULL) && (length != 0));
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	ipc_call_t result;
-	aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_WOL_VIRTUE_ADD, (sysarg_t) type, send_data, &result);
-	
-	sysarg_t res;
-	if (send_data) {
-		int rc = async_data_write_start(exch, data, length);
-		if (rc != EOK) {
-			async_exchange_end(exch);
-			async_wait_for(message_id, &res);
-			return rc;
-		}
-	}
-	
-	async_exchange_end(exch);
-	async_wait_for(message_id, &res);
-	
-	*id = IPC_GET_ARG1(result);
-	return (int) res;
-}
-
-/** Remove Wake-On-LAN virtue.
- *
- * @param[in] dev_sess
- * @param[in] id       Virtue identifier
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_wol_virtue_remove(async_sess_t *dev_sess, nic_wv_id_t id)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_WOL_VIRTUE_REMOVE, (sysarg_t) id);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Get information about virtue.
- *
- * @param[in]  dev_sess
- * @param[in]  id         Virtue identifier
- * @param[out] type       Type of the filter. Can be NULL.
- * @param[out] max_length Size of the data buffer.
- * @param[out] data       Buffer for data used when the
- *                        virtue was created. Can be NULL.
- * @param[out] length     Length of the data. Can be NULL.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_wol_virtue_probe(async_sess_t *dev_sess, nic_wv_id_t id,
-    nic_wv_type_t *type, size_t max_length, void *data, size_t *length)
-{
-	sysarg_t _type;
-	sysarg_t _length;
-	
-	if (data == NULL)
-		max_length = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	int rc = async_req_3_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_WOL_VIRTUE_PROBE, (sysarg_t) id, max_length,
-	    &_type, &_length);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	if (type)
-		*type = _type;
-	
-	if (length)
-		*length = _length;
-	
-	if ((max_length) && (_length != 0))
-		rc = async_data_read_start(exch, data, max_length);
-	
-	async_exchange_end(exch);
-	return rc;
-}
-
-/** Get a list of all virtues of the specified type.
- *
- * When NIC_WV_NONE is specified as the virtue type the function
- * lists virtues of all types.
- *
- * @param[in]  dev_sess
- * @param[in]  type      Type of the virtues
- * @param[in]  max_count Maximum number of ids that can be
- *                       written into the list buffer.
- * @param[out] id_list   Buffer for to the list of virtue ids.
- *                       Can be NULL.
- * @param[out] id_count  Number of virtue identifiers in the list
- *                       before possible truncation due to the
- *                       max_count. Can be NULL.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_wol_virtue_list(async_sess_t *dev_sess, nic_wv_type_t type,
-    size_t max_count, nic_wv_id_t *id_list, size_t *id_count)
-{
-	if (id_list == NULL)
-		max_count = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	sysarg_t count;
-	int rc = async_req_3_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_WOL_VIRTUE_LIST, (sysarg_t) type, max_count, &count);
-	
-	if (id_count)
-		*id_count = (size_t) count;
-	
-	if ((rc != EOK) || (!max_count)) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	rc = async_data_read_start(exch, id_list,
-	    max_count * sizeof(nic_wv_id_t));
-	
-	async_exchange_end(exch);
-	return rc;
-}
-
-/** Get number of virtues that can be enabled yet.
- *
- * Count: < 0 => Virtue of this type can be never used
- *        = 0 => No more virtues can be enabled
- *        > 0 => #count virtues can be enabled yet
- *
- * @param[in]  dev_sess
- * @param[in]  type     Virtue type
- * @param[out] count    Number of virtues
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_wol_virtue_get_caps(async_sess_t *dev_sess, nic_wv_type_t type,
-    int *count)
-{
-	assert(count);
-	
-	sysarg_t _count;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_2_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_WOL_VIRTUE_GET_CAPS, (sysarg_t) type, &_count);
-	async_exchange_end(exch);
-	
-	*count = (int) _count;
-	return rc;
-}
-
-/** Load the frame that issued the wakeup.
- *
- * The NIC can support only matched_type,  only part of the frame
- * can be available or not at all. Sometimes even the type can be
- * uncertain -- in this case the matched_type contains NIC_WV_NONE.
- *
- * Frame_length can be greater than max_length, but at most max_length
- * bytes will be copied into the frame buffer.
- *
- * Note: Only the type of the filter can be detected, not the concrete
- * filter, because the driver is probably not running when the wakeup
- * is issued.
- *
- * @param[in]  dev_sess
- * @param[out] matched_type Type of the filter that issued wakeup.
- * @param[in]  max_length   Size of the buffer
- * @param[out] frame        Buffer for the frame. Can be NULL.
- * @param[out] frame_length Length of the stored frame. Can be NULL.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_wol_load_info(async_sess_t *dev_sess, nic_wv_type_t *matched_type,
-    size_t max_length, uint8_t *frame, size_t *frame_length)
-{
-	assert(matched_type);
-	
-	sysarg_t _matched_type;
-	sysarg_t _frame_length;
-	
-	if (frame == NULL)
-		max_length = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	int rc = async_req_2_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_WOL_LOAD_INFO, max_length, &_matched_type, &_frame_length);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	*matched_type = (nic_wv_type_t) _matched_type;
-	if (frame_length)
-		*frame_length = (size_t) _frame_length;
-	
-	if ((max_length != 0) && (_frame_length != 0))
-		rc = async_data_read_start(exch, frame, max_length);
-	
-	async_exchange_end(exch);
-	return rc;
-}
-
-/** Probe supported options and current setting of offload computations
- *
- * @param[in]  dev_sess
- * @param[out] supported Supported offload options
- * @param[out] active    Currently active offload options
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_offload_probe(async_sess_t *dev_sess, uint32_t *supported,
-    uint32_t *active)
-{
-	assert(supported);
-	assert(active);
-	
-	sysarg_t _supported;
-	sysarg_t _active;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_OFFLOAD_PROBE, &_supported, &_active);
-	async_exchange_end(exch);
-	
-	*supported = (uint32_t) _supported;
-	*active = (uint32_t) _active;
-	return rc;
-}
-
-/** Set which offload computations can be performed on the NIC.
- *
- * @param[in] dev_sess
- * @param[in] mask     Mask for the options (only those set here will be set)
- * @param[in] active   Which options should be enabled and which disabled
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_offload_set(async_sess_t *dev_sess, uint32_t mask, uint32_t active)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_3_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_AUTONEG_RESTART, (sysarg_t) mask, (sysarg_t) active);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Query the current interrupt/poll mode of the NIC
- *
- * @param[in]  dev_sess
- * @param[out] mode     Current poll mode
- * @param[out] period   Period used in periodic polling.
- *                      Can be NULL.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_poll_get_mode(async_sess_t *dev_sess, nic_poll_mode_t *mode,
-    struct timeval *period)
-{
-	assert(mode);
-	
-	sysarg_t _mode;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	int rc = async_req_2_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_POLL_GET_MODE, period != NULL, &_mode);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	*mode = (nic_poll_mode_t) _mode;
-	
-	if (period != NULL)
-		rc = async_data_read_start(exch, period, sizeof(struct timeval));
-	
-	async_exchange_end(exch);
-	return rc;
-}
-
-/** Set the interrupt/poll mode of the NIC.
- *
- * @param[in] dev_sess
- * @param[in] mode     New poll mode
- * @param[in] period   Period used in periodic polling. Can be NULL.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_poll_set_mode(async_sess_t *dev_sess, nic_poll_mode_t mode,
-    const struct timeval *period)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_POLL_SET_MODE, (sysarg_t) mode, period != NULL, NULL);
-	
-	int rc;
-	if (period)
-		rc = async_data_write_start(exch, period, sizeof(struct timeval));
-	else
-		rc = EOK;
-	
-	async_exchange_end(exch);
-	
-	sysarg_t res;
-	async_wait_for(message_id, &res);
-	
-	if (rc != EOK)
-		return rc;
-	
-	return (int) res;
-}
-
-/** Request the driver to poll the NIC.
- *
- * @param[in] dev_sess
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_poll_now(async_sess_t *dev_sess)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_POLL_NOW);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** @}
- */
Index: uspace/lib/c/generic/device/pci.c
===================================================================
--- uspace/lib/c/generic/device/pci.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,116 +1,0 @@
-/*
- * Copyright (c) 2011 Jiri Michalec
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#include <ipc/dev_iface.h>
-#include <assert.h>
-#include <device/pci.h>
-#include <errno.h>
-#include <async.h>
-#include <ipc/services.h>
-
-int pci_config_space_read_8(async_sess_t *sess, uint32_t address, uint8_t *val)
-{
-	sysarg_t res = 0;
-	
-	async_exch_t *exch = async_exchange_begin(sess);
-	int rc = async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
-	    IPC_M_CONFIG_SPACE_READ_8, address, &res);
-	async_exchange_end(exch);
-	
-	*val = (uint8_t) res;
-	return rc;
-}
-
-int pci_config_space_read_16(async_sess_t *sess, uint32_t address,
-    uint16_t *val)
-{
-	sysarg_t res = 0;
-	
-	async_exch_t *exch = async_exchange_begin(sess);
-	int rc = async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
-	    IPC_M_CONFIG_SPACE_READ_16, address, &res);
-	async_exchange_end(exch);
-	
-	*val = (uint16_t) res;
-	return rc;
-}
-
-int pci_config_space_read_32(async_sess_t *sess, uint32_t address,
-    uint32_t *val)
-{
-	sysarg_t res = 0;
-	
-	async_exch_t *exch = async_exchange_begin(sess);
-	int rc = async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
-	    IPC_M_CONFIG_SPACE_READ_32, address, &res);
-	async_exchange_end(exch);
-	
-	*val = (uint32_t) res;
-	return rc;
-}
-
-int pci_config_space_write_8(async_sess_t *sess, uint32_t address, uint8_t val)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
-	    IPC_M_CONFIG_SPACE_WRITE_8, address, val);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-int pci_config_space_write_16(async_sess_t *sess, uint32_t address,
-    uint16_t val)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
-	    IPC_M_CONFIG_SPACE_WRITE_16, address, val);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-int pci_config_space_write_32(async_sess_t *sess, uint32_t address,
-    uint32_t val)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
-	    IPC_M_CONFIG_SPACE_WRITE_32, address, val);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** @}
- */
Index: uspace/lib/c/generic/io/io.c
===================================================================
--- uspace/lib/c/generic/io/io.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/generic/io/io.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -42,5 +42,5 @@
 #include <malloc.h>
 #include <async.h>
-#include <io/klog.h>
+#include <io/kio.h>
 #include <vfs/vfs.h>
 #include <vfs/vfs_sess.h>
@@ -57,5 +57,5 @@
 	.error = true,
 	.eof = true,
-	.klog = false,
+	.kio = false,
 	.sess = NULL,
 	.btype = _IONBF,
@@ -67,9 +67,9 @@
 };
 
-static FILE stdout_klog = {
+static FILE stdout_kio = {
 	.fd = -1,
 	.error = false,
 	.eof = false,
-	.klog = true,
+	.kio = true,
 	.sess = NULL,
 	.btype = _IOLBF,
@@ -81,9 +81,9 @@
 };
 
-static FILE stderr_klog = {
+static FILE stderr_kio = {
 	.fd = -1,
 	.error = false,
 	.eof = false,
-	.klog = true,
+	.kio = true,
 	.sess = NULL,
 	.btype = _IONBF,
@@ -113,5 +113,5 @@
 		stdout = fdopen(1, "w");
 	} else {
-		stdout = &stdout_klog;
+		stdout = &stdout_kio;
 		list_append(&stdout->link, &files);
 	}
@@ -120,5 +120,5 @@
 		stderr = fdopen(2, "w");
 	} else {
-		stderr = &stderr_klog;
+		stderr = &stderr_kio;
 		list_append(&stderr->link, &files);
 	}
@@ -267,5 +267,5 @@
 	stream->error = false;
 	stream->eof = false;
-	stream->klog = false;
+	stream->kio = false;
 	stream->sess = NULL;
 	stream->need_sync = false;
@@ -289,5 +289,5 @@
 	stream->error = false;
 	stream->eof = false;
-	stream->klog = false;
+	stream->kio = false;
 	stream->sess = NULL;
 	stream->need_sync = false;
@@ -314,6 +314,6 @@
 	
 	if ((stream != &stdin_null)
-	    && (stream != &stdout_klog)
-	    && (stream != &stderr_klog))
+	    && (stream != &stdout_kio)
+	    && (stream != &stderr_kio))
 		free(stream);
 	
@@ -382,6 +382,6 @@
 		ssize_t wr;
 		
-		if (stream->klog)
-			wr = klog_write(buf + done, left);
+		if (stream->kio)
+			wr = kio_write(buf + done, left);
 		else
 			wr = write(stream->fd, buf + done, left);
@@ -705,6 +705,6 @@
 	_fflushbuf(stream);
 	
-	if (stream->klog) {
-		klog_update();
+	if (stream->kio) {
+		kio_update();
 		return EOK;
 	}
@@ -740,5 +740,5 @@
 int fileno(FILE *stream)
 {
-	if (stream->klog) {
+	if (stream->kio) {
 		errno = EBADF;
 		return -1;
Index: uspace/lib/c/generic/io/kio.c
===================================================================
--- uspace/lib/c/generic/io/kio.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/generic/io/kio.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * Copyright (c) 2006 Jakub Vana
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#include <libc.h>
+#include <str.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <abi/kio.h>
+#include <io/kio.h>
+#include <io/printf_core.h>
+
+size_t kio_write(const void *buf, size_t size)
+{
+	ssize_t ret = (ssize_t) __SYSCALL3(SYS_KIO, KIO_WRITE, (sysarg_t) buf, size);
+	
+	if (ret >= 0)
+		return (size_t) ret;
+	
+	return 0;
+}
+
+void kio_update(void)
+{
+	(void) __SYSCALL3(SYS_KIO, KIO_UPDATE, (uintptr_t) NULL, 0);
+}
+
+void kio_command(const void *buf, size_t size)
+{
+	(void) __SYSCALL3(SYS_KIO, KIO_COMMAND, (sysarg_t) buf, (sysarg_t) size);
+}
+
+/** Print formatted text to kio.
+ *
+ * @param fmt Format string
+ *
+ * \see For more details about format string see printf_core.
+ *
+ */
+int kio_printf(const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	
+	int ret = kio_vprintf(fmt, args);
+	
+	va_end(args);
+	
+	return ret;
+}
+
+static int kio_vprintf_str_write(const char *str, size_t size, void *data)
+{
+	size_t wr = kio_write(str, size);
+	return str_nlength(str, wr);
+}
+
+static int kio_vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
+{
+	size_t offset = 0;
+	size_t chars = 0;
+	
+	while (offset < size) {
+		char buf[STR_BOUNDS(1)];
+		size_t sz = 0;
+		
+		if (chr_encode(str[chars], buf, &sz, STR_BOUNDS(1)) == EOK)
+			kio_write(buf, sz);
+		
+		chars++;
+		offset += sizeof(wchar_t);
+	}
+	
+	return chars;
+}
+
+/** Print formatted text to kio.
+ *
+ * @param fmt Format string
+ * @param ap  Format parameters
+ *
+ * \see For more details about format string see printf_core.
+ *
+ */
+int kio_vprintf(const char *fmt, va_list ap)
+{
+	printf_spec_t ps = {
+		kio_vprintf_str_write,
+		kio_vprintf_wstr_write,
+		NULL
+	};
+	
+	return printf_core(fmt, &ps, ap);
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/io/klog.c
===================================================================
--- uspace/lib/c/generic/io/klog.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/generic/io/klog.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -1,5 +1,4 @@
 /*
- * Copyright (c) 2006 Josef Cejka
- * Copyright (c) 2006 Jakub Vana
+ * Copyright (c) 2013 Martin Sucha
  * All rights reserved.
  *
@@ -41,9 +40,10 @@
 #include <abi/klog.h>
 #include <io/klog.h>
-#include <io/printf_core.h>
+#include <abi/log.h>
 
-size_t klog_write(const void *buf, size_t size)
+size_t klog_write(log_level_t lvl, const void *buf, size_t size)
 {
-	ssize_t ret = (ssize_t) __SYSCALL3(SYS_KLOG, KLOG_WRITE, (sysarg_t) buf, size);
+	ssize_t ret = (ssize_t) __SYSCALL4(SYS_KLOG, KLOG_WRITE, (sysarg_t) buf,
+	    size, lvl);
 	
 	if (ret >= 0)
@@ -53,75 +53,7 @@
 }
 
-void klog_update(void)
+int klog_read(void *data, size_t size)
 {
-	(void) __SYSCALL3(SYS_KLOG, KLOG_UPDATE, (uintptr_t) NULL, 0);
-}
-
-void klog_command(const void *buf, size_t size)
-{
-	(void) __SYSCALL3(SYS_KLOG, KLOG_COMMAND, (sysarg_t) buf, (sysarg_t) size);
-}
-
-/** Print formatted text to klog.
- *
- * @param fmt Format string
- *
- * \see For more details about format string see printf_core.
- *
- */
-int klog_printf(const char *fmt, ...)
-{
-	va_list args;
-	va_start(args, fmt);
-	
-	int ret = klog_vprintf(fmt, args);
-	
-	va_end(args);
-	
-	return ret;
-}
-
-static int klog_vprintf_str_write(const char *str, size_t size, void *data)
-{
-	size_t wr = klog_write(str, size);
-	return str_nlength(str, wr);
-}
-
-static int klog_vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
-{
-	size_t offset = 0;
-	size_t chars = 0;
-	
-	while (offset < size) {
-		char buf[STR_BOUNDS(1)];
-		size_t sz = 0;
-		
-		if (chr_encode(str[chars], buf, &sz, STR_BOUNDS(1)) == EOK)
-			klog_write(buf, sz);
-		
-		chars++;
-		offset += sizeof(wchar_t);
-	}
-	
-	return chars;
-}
-
-/** Print formatted text to klog.
- *
- * @param fmt Format string
- * @param ap  Format parameters
- *
- * \see For more details about format string see printf_core.
- *
- */
-int klog_vprintf(const char *fmt, va_list ap)
-{
-	printf_spec_t ps = {
-		klog_vprintf_str_write,
-		klog_vprintf_wstr_write,
-		NULL
-	};
-	
-	return printf_core(fmt, &ps, ap);
+	return (int) __SYSCALL4(SYS_KLOG, KLOG_READ, (uintptr_t) data, size, 0);
 }
 
Index: uspace/lib/c/generic/io/window.c
===================================================================
--- uspace/lib/c/generic/io/window.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/generic/io/window.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -40,11 +40,10 @@
 #include <stdio.h>
 
-int win_register(async_sess_t *sess, service_id_t *in, service_id_t *out, 
-    sysarg_t x_offset, sysarg_t y_offset)
+int win_register(async_sess_t *sess, service_id_t *in, service_id_t *out)
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-	int ret = async_req_2_2(exch, WINDOW_REGISTER, x_offset, y_offset, in, out);
+	int ret = async_req_0_2(exch, WINDOW_REGISTER, in, out);
 	async_exchange_end(exch);
-
+	
 	return ret;
 }
@@ -92,25 +91,26 @@
 }
 
-int win_resize(async_sess_t *sess, sysarg_t width, sysarg_t height, void *cells)
+int win_resize(async_sess_t *sess, sysarg_t x, sysarg_t y, sysarg_t width,
+    sysarg_t height, window_placement_flags_t placement_flags, void *cells)
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-
+	
 	ipc_call_t answer;
-	aid_t req = async_send_2(exch, WINDOW_RESIZE, width, height, &answer);
-
+	aid_t req = async_send_5(exch, WINDOW_RESIZE, x, y, width, height,
+	    (sysarg_t) placement_flags, &answer);
+	
 	int rc = async_share_out_start(exch, cells, AS_AREA_READ | AS_AREA_CACHEABLE);
-
+	
 	async_exchange_end(exch);
-
+	
 	sysarg_t ret;
 	async_wait_for(req, &ret);
-
-	if (rc != EOK) {
+	
+	if (rc != EOK)
 		return rc;
-	} else if (ret != EOK) {
+	else if (ret != EOK)
 		return ret;
-	} else {
-		return EOK;
-	}
+	
+	return EOK;
 }
 
Index: uspace/lib/c/generic/private/stdio.h
===================================================================
--- uspace/lib/c/generic/private/stdio.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/generic/private/stdio.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -53,6 +53,6 @@
 	int eof;
 	
-	/** Klog indicator */
-	int klog;
+	/** KIO indicator */
+	int kio;
 	
 	/** Session to the file provider */
Index: uspace/lib/c/generic/setjmp.c
===================================================================
--- uspace/lib/c/generic/setjmp.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/generic/setjmp.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file Long jump implementation.
+ *
+ * Implementation inspired by Jiri Zarevucky's code from
+ * http://bazaar.launchpad.net/~zarevucky-jiri/helenos/stdc/revision/1544/uspace/lib/posix/setjmp.h
+ */
+
+#include <setjmp.h>
+#include <libarch/fibril.h>
+#include <fibril.h>
+
+/**
+ * Restore environment previously stored by setjmp.
+ *
+ * This function never returns.
+ *
+ * @param env Variable with the environment previously stored by call
+ * to setjmp.
+ * @param val Value to fake when returning from setjmp (0 is transformed to 1).
+ */
+void longjmp(jmp_buf env, int val) {
+	env[0].return_value = (val == 0) ? 1 : val;
+	context_restore(&env[0].context);
+	__builtin_unreachable();
+}
+
+/** @}
+ */
Index: uspace/lib/c/include/adt/checksum.h
===================================================================
--- uspace/lib/c/include/adt/checksum.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/include/adt/checksum.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012 Dominik Taborsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_CHECKSUM_H_
+#define LIBC_CHECKSUM_H_
+
+#include <sys/types.h>
+
+extern uint32_t compute_crc32(uint8_t *, size_t);
+extern uint32_t compute_crc32_seed(uint8_t *, size_t, uint32_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/bitops.h
===================================================================
--- uspace/lib/c/include/bitops.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/include/bitops.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -107,6 +107,4 @@
 }
 
-extern int __popcountsi2(int);
-
 #endif
 
Index: uspace/lib/c/include/ddi.h
===================================================================
--- uspace/lib/c/include/ddi.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/include/ddi.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -130,5 +130,5 @@
 }
 
-extern int irq_register(int, int, int, irq_code_t *);
+extern int irq_register(int, int, int, const irq_code_t *);
 extern int irq_unregister(int, int);
 
Index: uspace/lib/c/include/device/ahci.h
===================================================================
--- uspace/lib/c/include/device/ahci.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,53 +1,0 @@
-/*
- * Copyright (c) 2012 Petr Jerman
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- * @brief AHCI interface definition.
- */
-
-#ifndef LIBC_DEVICE_AHCI_H_
-#define LIBC_DEVICE_AHCI_H_
-
-#include <async.h>
-#include <devman.h>
-
-extern async_sess_t* ahci_get_sess(devman_handle_t, char **);
-
-extern int ahci_get_sata_device_name(async_sess_t *, size_t, char *);
-extern int ahci_get_num_blocks(async_sess_t *, uint64_t *);
-extern int ahci_get_block_size(async_sess_t *, size_t *);
-extern int ahci_read_blocks(async_sess_t *, uint64_t, size_t, void *);
-extern int ahci_write_blocks(async_sess_t *, uint64_t, size_t, void *);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/device/battery_dev.h
===================================================================
--- uspace/lib/c/include/device/battery_dev.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,55 +1,0 @@
-/*
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_DEVICE_BATTERY_DEV_H_
-#define LIBC_DEVICE_BATTERY_DEV_H_
-
-#include <async.h>
-
-typedef enum {
-	BATTERY_OK,
-	BATTERY_LOW,
-	BATTERY_NOT_PRESENT,
-} battery_status_t;
-
-typedef enum {
-	BATTERY_STATUS_GET = 0,
-	BATTERY_CHARGE_LEVEL_GET,
-} battery_dev_method_t;
-
-extern int battery_status_get(async_sess_t *, battery_status_t *);
-extern int battery_charge_level_get(async_sess_t *, int *);
-
-#endif
-
Index: uspace/lib/c/include/device/char_dev.h
===================================================================
--- uspace/lib/c/include/device/char_dev.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,51 +1,0 @@
-/*
- * Copyright (c) 2010 Lenka Trochtova
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_DEVICE_CHAR_DEV_H_
-#define LIBC_DEVICE_CHAR_DEV_H_
-
-#include <async.h>
-
-typedef enum {
-	CHAR_DEV_READ = 0,
-	CHAR_DEV_WRITE
-} char_dev_method_t;
-
-extern ssize_t char_dev_read(async_sess_t *, void *, size_t);
-extern ssize_t char_dev_write(async_sess_t *, void *, size_t);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/device/graph_dev.h
===================================================================
--- uspace/lib/c/include/device/graph_dev.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2011 Petr Koupy
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_DEVICE_GRAPH_DEV_H_
-#define LIBC_DEVICE_GRAPH_DEV_H_
-
-#include <async.h>
-
-typedef enum {
-	GRAPH_DEV_CONNECT = 0
-} graph_dev_method_t;
-
-extern int graph_dev_connect(async_sess_t *);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/device/nic.h
===================================================================
--- uspace/lib/c/include/device/nic.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,159 +1,0 @@
-/*
- * Copyright (c) 2010 Radim Vansa
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- /** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_DEVICE_NIC_H_
-#define LIBC_DEVICE_NIC_H_
-
-#include <async.h>
-#include <nic/nic.h>
-#include <ipc/common.h>
-
-typedef enum {
-	NIC_SEND_MESSAGE = 0,
-	NIC_CALLBACK_CREATE,
-	NIC_GET_STATE,
-	NIC_SET_STATE,
-	NIC_GET_ADDRESS,
-	NIC_SET_ADDRESS,
-	NIC_GET_STATS,
-	NIC_GET_DEVICE_INFO,
-	NIC_GET_CABLE_STATE,
-	NIC_GET_OPERATION_MODE,
-	NIC_SET_OPERATION_MODE,
-	NIC_AUTONEG_ENABLE,
-	NIC_AUTONEG_DISABLE,
-	NIC_AUTONEG_PROBE,
-	NIC_AUTONEG_RESTART,
-	NIC_GET_PAUSE,
-	NIC_SET_PAUSE,
-	NIC_UNICAST_GET_MODE,
-	NIC_UNICAST_SET_MODE,
-	NIC_MULTICAST_GET_MODE,
-	NIC_MULTICAST_SET_MODE,
-	NIC_BROADCAST_GET_MODE,
-	NIC_BROADCAST_SET_MODE,
-	NIC_DEFECTIVE_GET_MODE,
-	NIC_DEFECTIVE_SET_MODE,
-	NIC_BLOCKED_SOURCES_GET,
-	NIC_BLOCKED_SOURCES_SET,
-	NIC_VLAN_GET_MASK,
-	NIC_VLAN_SET_MASK,
-	NIC_VLAN_SET_TAG,
-	NIC_WOL_VIRTUE_ADD,
-	NIC_WOL_VIRTUE_REMOVE,
-	NIC_WOL_VIRTUE_PROBE,
-	NIC_WOL_VIRTUE_LIST,
-	NIC_WOL_VIRTUE_GET_CAPS,
-	NIC_WOL_LOAD_INFO,
-	NIC_OFFLOAD_PROBE,
-	NIC_OFFLOAD_SET,
-	NIC_POLL_GET_MODE,
-	NIC_POLL_SET_MODE,
-	NIC_POLL_NOW
-} nic_funcs_t;
-
-typedef enum {
-	NIC_EV_ADDR_CHANGED = IPC_FIRST_USER_METHOD,
-	NIC_EV_RECEIVED,
-	NIC_EV_DEVICE_STATE
-} nic_event_t;
-
-extern int nic_send_frame(async_sess_t *, void *, size_t);
-extern int nic_callback_create(async_sess_t *, async_client_conn_t, void *);
-extern int nic_get_state(async_sess_t *, nic_device_state_t *);
-extern int nic_set_state(async_sess_t *, nic_device_state_t);
-extern int nic_get_address(async_sess_t *, nic_address_t *);
-extern int nic_set_address(async_sess_t *, const nic_address_t *);
-extern int nic_get_stats(async_sess_t *, nic_device_stats_t *);
-extern int nic_get_device_info(async_sess_t *, nic_device_info_t *);
-extern int nic_get_cable_state(async_sess_t *, nic_cable_state_t *);
-
-extern int nic_get_operation_mode(async_sess_t *, int *, nic_channel_mode_t *,
-    nic_role_t *);
-extern int nic_set_operation_mode(async_sess_t *, int, nic_channel_mode_t,
-    nic_role_t);
-extern int nic_autoneg_enable(async_sess_t *, uint32_t);
-extern int nic_autoneg_disable(async_sess_t *);
-extern int nic_autoneg_probe(async_sess_t *, uint32_t *, uint32_t *,
-    nic_result_t *, nic_result_t *);
-extern int nic_autoneg_restart(async_sess_t *);
-extern int nic_get_pause(async_sess_t *, nic_result_t *, nic_result_t *,
-    uint16_t *);
-extern int nic_set_pause(async_sess_t *, int, int, uint16_t);
-
-extern int nic_unicast_get_mode(async_sess_t *, nic_unicast_mode_t *, size_t,
-    nic_address_t *, size_t *);
-extern int nic_unicast_set_mode(async_sess_t *, nic_unicast_mode_t,
-    const nic_address_t *, size_t);
-extern int nic_multicast_get_mode(async_sess_t *, nic_multicast_mode_t *,
-    size_t, nic_address_t *, size_t *);
-extern int nic_multicast_set_mode(async_sess_t *, nic_multicast_mode_t,
-    const nic_address_t *, size_t);
-extern int nic_broadcast_get_mode(async_sess_t *, nic_broadcast_mode_t *);
-extern int nic_broadcast_set_mode(async_sess_t *, nic_broadcast_mode_t);
-extern int nic_defective_get_mode(async_sess_t *, uint32_t *);
-extern int nic_defective_set_mode(async_sess_t *, uint32_t);
-extern int nic_blocked_sources_get(async_sess_t *, size_t, nic_address_t *,
-    size_t *);
-extern int nic_blocked_sources_set(async_sess_t *, const nic_address_t *,
-    size_t);
-
-extern int nic_vlan_get_mask(async_sess_t *, nic_vlan_mask_t *);
-extern int nic_vlan_set_mask(async_sess_t *, const nic_vlan_mask_t *);
-extern int nic_vlan_set_tag(async_sess_t *, uint16_t, bool, bool);
-
-extern int nic_wol_virtue_add(async_sess_t *, nic_wv_type_t, const void *,
-    size_t, nic_wv_id_t *);
-extern int nic_wol_virtue_remove(async_sess_t *, nic_wv_id_t);
-extern int nic_wol_virtue_probe(async_sess_t *, nic_wv_id_t, nic_wv_type_t *,
-    size_t, void *, size_t *);
-extern int nic_wol_virtue_list(async_sess_t *, nic_wv_type_t, size_t,
-    nic_wv_id_t *, size_t *);
-extern int nic_wol_virtue_get_caps(async_sess_t *, nic_wv_type_t, int *);
-extern int nic_wol_load_info(async_sess_t *, nic_wv_type_t *, size_t, uint8_t *,
-    size_t *);
-
-extern int nic_offload_probe(async_sess_t *, uint32_t *, uint32_t *);
-extern int nic_offload_set(async_sess_t *, uint32_t, uint32_t);
-
-extern int nic_poll_get_mode(async_sess_t *, nic_poll_mode_t *,
-    struct timeval *);
-extern int nic_poll_set_mode(async_sess_t *, nic_poll_mode_t,
-    const struct timeval *);
-extern int nic_poll_now(async_sess_t *);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/device/pci.h
===================================================================
--- uspace/lib/c/include/device/pci.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,63 +1,0 @@
-/*
- * Copyright (c) 2011 Jiri Michalec
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_DEVICE_PCI_H_
-#define LIBC_DEVICE_PCI_H_
-
-#include <async.h>
-
-#define PCI_DEVICE_ID  0x02
-
-typedef enum {
-	IPC_M_CONFIG_SPACE_READ_8,
-	IPC_M_CONFIG_SPACE_READ_16,
-	IPC_M_CONFIG_SPACE_READ_32,
-	
-	IPC_M_CONFIG_SPACE_WRITE_8,
-	IPC_M_CONFIG_SPACE_WRITE_16,
-	IPC_M_CONFIG_SPACE_WRITE_32
-} pci_dev_iface_funcs_t;
-
-extern int pci_config_space_read_8(async_sess_t *, uint32_t, uint8_t *);
-extern int pci_config_space_read_16(async_sess_t *, uint32_t, uint16_t *);
-extern int pci_config_space_read_32(async_sess_t *, uint32_t, uint32_t *);
-
-extern int pci_config_space_write_8(async_sess_t *, uint32_t, uint8_t);
-extern int pci_config_space_write_16(async_sess_t *, uint32_t, uint16_t);
-extern int pci_config_space_write_32(async_sess_t *, uint32_t, uint32_t);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/io/kio.h
===================================================================
--- uspace/lib/c/include/io/kio.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/include/io/kio.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2006 Jakub Vana
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_IO_KIO_H_
+#define LIBC_IO_KIO_H_
+
+#include <sys/types.h>
+#include <stdarg.h>
+#include <io/verify.h>
+
+extern size_t kio_write(const void *, size_t);
+extern void kio_update(void);
+extern void kio_command(const void *, size_t);
+extern int kio_printf(const char *, ...)
+    PRINTF_ATTRIBUTE(1, 2);
+extern int kio_vprintf(const char *, va_list);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/io/klog.h
===================================================================
--- uspace/lib/c/include/io/klog.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/include/io/klog.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2006 Jakub Vana
+ * Copyright (c) 2013 Martin Sucha
  * All rights reserved.
  *
@@ -39,11 +39,26 @@
 #include <stdarg.h>
 #include <io/verify.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <str.h>
+#include <abi/log.h>
 
-extern size_t klog_write(const void *, size_t);
-extern void klog_update(void);
-extern void klog_command(const void *, size_t);
-extern int klog_printf(const char *, ...)
-    PRINTF_ATTRIBUTE(1, 2);
-extern int klog_vprintf(const char *, va_list);
+extern size_t klog_write(log_level_t, const void *, size_t);
+extern int klog_read(void *, size_t);
+
+#define KLOG_PRINTF(lvl, fmt, ...) ({ \
+	char *_fmt = str_dup(fmt); \
+	size_t _fmtsize = str_size(_fmt); \
+	if (_fmtsize > 0 && _fmt[_fmtsize - 1] == '\n') \
+		_fmt[_fmtsize - 1] = 0; \
+	char *_s; \
+	int _c = asprintf(&_s, _fmt, ##__VA_ARGS__); \
+	free(_fmt); \
+	if (_c >= 0) { \
+		_c = klog_write((lvl), _s, str_size(_s)); \
+		free(_s); \
+	}; \
+	(_c >= 0); \
+})
 
 #endif
Index: uspace/lib/c/include/io/log.h
===================================================================
--- uspace/lib/c/include/io/log.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/include/io/log.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -39,22 +39,5 @@
 #include <io/verify.h>
 
-/** Log message level. */
-typedef enum {
-	/** Fatal error, program is not able to recover at all. */
-	LVL_FATAL,
-	/** Serious error but the program can recover from it. */
-	LVL_ERROR,
-	/** Easily recoverable problem. */
-	LVL_WARN,
-	/** Information message that ought to be printed by default. */
-	LVL_NOTE,
-	/** Debugging purpose message. */
-	LVL_DEBUG,
-	/** More detailed debugging message. */
-	LVL_DEBUG2,
-	
-	/** For checking range of values */
-	LVL_LIMIT
-} log_level_t;
+#include <abi/log.h>
 
 /** Log itself (logging target). */
Index: uspace/lib/c/include/io/window.h
===================================================================
--- uspace/lib/c/include/io/window.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/include/io/window.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -43,14 +43,43 @@
 #include <io/pos_event.h>
 
+typedef enum {
+	GF_EMPTY = 0,
+	GF_MOVE_X = 1,
+	GF_MOVE_Y = 2,
+	GF_RESIZE_X = 4,
+	GF_RESIZE_Y = 8,
+	GF_SCALE_X = 16,
+	GF_SCALE_Y = 32
+} window_grab_flags_t;
+
+typedef enum {
+	WINDOW_PLACEMENT_ANY = 0,
+	WINDOW_PLACEMENT_CENTER_X = 1,
+	WINDOW_PLACEMENT_CENTER_Y = 2,
+	WINDOW_PLACEMENT_CENTER =
+	    WINDOW_PLACEMENT_CENTER_X | WINDOW_PLACEMENT_CENTER_Y,
+	WINDOW_PLACEMENT_LEFT = 4,
+	WINDOW_PLACEMENT_RIGHT = 8,
+	WINDOW_PLACEMENT_TOP = 16,
+	WINDOW_PLACEMENT_BOTTOM = 32,
+	WINDOW_PLACEMENT_ABSOLUTE_X = 64,
+	WINDOW_PLACEMENT_ABSOLUTE_Y = 128,
+	WINDOW_PLACEMENT_ABSOLUTE =
+	    WINDOW_PLACEMENT_ABSOLUTE_X | WINDOW_PLACEMENT_ABSOLUTE_Y
+} window_placement_flags_t;
+
 typedef struct {
 	sysarg_t object;
 	sysarg_t slot;
 	sysarg_t argument;
-} sig_event_t;
+} signal_event_t;
 
 typedef struct {
+	sysarg_t offset_x;
+	sysarg_t offset_y;
 	sysarg_t width;
 	sysarg_t height;
-} rsz_event_t;
+	window_placement_flags_t placement_flags;
+} resize_event_t;
 
 typedef enum {
@@ -69,6 +98,6 @@
 	kbd_event_t kbd;
 	pos_event_t pos;
-	sig_event_t sig;
-	rsz_event_t rsz;
+	signal_event_t signal;
+	resize_event_t resize;
 } window_event_data_t;
 
@@ -79,15 +108,5 @@
 } window_event_t;
 
-typedef enum {
-	GF_EMPTY = 0,
-	GF_MOVE_X = 1,
-	GF_MOVE_Y = 2,
-	GF_RESIZE_X = 4,
-	GF_RESIZE_Y = 8,
-	GF_SCALE_X = 16,
-	GF_SCALE_Y = 32
-} window_grab_flags_t;
-
-extern int win_register(async_sess_t *, service_id_t *, service_id_t *, sysarg_t, sysarg_t);
+extern int win_register(async_sess_t *, service_id_t *, service_id_t *);
 
 extern int win_get_event(async_sess_t *, window_event_t *);
@@ -95,5 +114,6 @@
 extern int win_damage(async_sess_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
 extern int win_grab(async_sess_t *, sysarg_t, sysarg_t);
-extern int win_resize(async_sess_t *, sysarg_t, sysarg_t, void *);
+extern int win_resize(async_sess_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
+    window_placement_flags_t, void *);
 extern int win_close(async_sess_t *);
 extern int win_close_request(async_sess_t *);
Index: uspace/lib/c/include/math.h
===================================================================
--- uspace/lib/c/include/math.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/c/include/math.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2011 Petr Koupy
+ * 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 libposix
+ * @{
+ */
+/** @file Mathematical operations.
+ *
+ * The implementation is provided by a separate library to allow
+ * switching of the implementations.
+ */
+
+#ifndef LIBC_MATH_H_
+#define LIBC_MATH_H_
+
+#ifdef __GNUC__
+	#define HUGE_VAL (__builtin_huge_val())
+#endif
+
+extern double ldexp(double, int);
+extern double frexp(double, int *);
+
+extern double fabs(double);
+extern double floor(double);
+extern double ceil(double);
+extern double modf(double, double *);
+extern double fmod(double, double);
+extern double pow(double, double);
+extern double exp(double);
+extern double expm1(double);
+extern double sqrt(double);
+extern double log(double);
+extern double log10(double);
+extern double sin(double);
+extern double sinh(double);
+extern double asin(double);
+extern double asinh(double);
+extern double cos(double);
+extern double cosh(double);
+extern double acos(double);
+extern double acosh(double);
+extern double tan(double);
+extern double tanh(double);
+extern double atan(double);
+extern double atanh(double);
+extern double atan2(double, double);
+
+double copysign(double, double);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/setjmp.h
===================================================================
--- uspace/lib/c/include/setjmp.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/include/setjmp.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2008 Josef Cejka
+ * Copyright (c) 2013 Vojtech Horky
  * All rights reserved.
  *
@@ -30,5 +31,8 @@
  * @{
  */
-/** @file
+/** @file Long jump implementation.
+ *
+ * Implementation inspired by Jiri Zarevucky's code from
+ * http://bazaar.launchpad.net/~zarevucky-jiri/helenos/stdc/revision/1544/uspace/lib/posix/setjmp.h
  */
 
@@ -38,7 +42,31 @@
 #include <libarch/fibril.h>
 
-typedef context_t jmp_buf[1];
+struct jmp_buf_interal {
+	context_t context;
+	int return_value;
+};
+typedef struct jmp_buf_interal jmp_buf[1];
 
-extern int setjmp(jmp_buf env);
+/*
+ * Specified as extern to minimize number of included headers
+ * because this file is used as is in libposix too.
+ */
+extern int context_save(context_t *ctx) __attribute__((returns_twice));
+
+/**
+ * Save current environment (registers).
+ *
+ * This function may return twice.
+ *
+ * @param env Variable where to save the environment (of type jmp_buf).
+ * @return Whether the call returned after longjmp.
+ * @retval 0 Environment was saved, normal execution.
+ * @retval other longjmp was executed and returned here.
+ */
+#define setjmp(env) \
+	((env)[0].return_value = 0, \
+	context_save(&(env)[0].context), \
+	(env)[0].return_value)
+
 extern void longjmp(jmp_buf env, int val) __attribute__((noreturn));
 
Index: uspace/lib/c/include/stdio.h
===================================================================
--- uspace/lib/c/include/stdio.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/include/stdio.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -40,5 +40,5 @@
 #include <str.h>
 #include <io/verify.h>
-#include <abi/klog.h>
+#include <abi/kio.h>
 
 #define EOF  (-1)
@@ -52,5 +52,5 @@
 		int _n = snprintf(_buf, sizeof(_buf), fmt, ##__VA_ARGS__); \
 		if (_n > 0) \
-			(void) __SYSCALL3(SYS_KLOG, KLOG_WRITE, (sysarg_t) _buf, str_size(_buf)); \
+			(void) __SYSCALL3(SYS_KIO, KIO_WRITE, (sysarg_t) _buf, str_size(_buf)); \
 	}
 
Index: uspace/lib/draw/cursor/embedded.c
===================================================================
--- uspace/lib/draw/cursor/embedded.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/draw/cursor/embedded.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -46,5 +46,5 @@
 	assert(state_count);
 	assert(data);
-
+	
 	(*state_count) = 1;
 	(*data) = NULL;
@@ -53,13 +53,10 @@
 static surface_t *cde_render(uint8_t state)
 {
-	if (state != 0) {
+	if (state != 0)
 		return NULL;
-	}
-
+	
 	surface_t *surface = surface_create(CURSOR_WIDTH, CURSOR_HEIGHT, NULL, 0);
-
-	if (!surface) {
+	if (!surface)
 		return NULL;
-	}
 	
 	for (unsigned int y = 0; y < CURSOR_HEIGHT; ++y) {
@@ -69,8 +66,10 @@
 			pixel_t pixel = (cursor_texture[offset] & (1 << (x % 8))) ?
 			    PIXEL(255, 0, 0, 0) : PIXEL(255, 255, 255, 255);
-			surface_put_pixel(surface, x, y, visible ? pixel : PIXEL(0, 0, 0, 0));
+			
+			if (visible)
+				surface_put_pixel(surface, x, y, pixel);
 		}
 	}
-
+	
 	return surface;
 }
Index: uspace/lib/drv/Makefile
===================================================================
--- uspace/lib/drv/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -29,5 +29,9 @@
 
 USPACE_PREFIX = ../..
-EXTRA_CFLAGS = -Iinclude -I$(LIBUSB_PREFIX)/include -I$(LIBPCM_PREFIX)/include
+EXTRA_CFLAGS = \
+	-Iinclude \
+	-Igeneric/private \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBPCM_PREFIX)/include
 LIBRARY = libdrv
 
Index: uspace/lib/drv/generic/dev_iface.c
===================================================================
--- uspace/lib/drv/generic/dev_iface.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/dev_iface.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -69,9 +69,9 @@
 		[CLOCK_DEV_IFACE] = &remote_clock_dev_iface,
 		[BATTERY_DEV_IFACE] = &remote_battery_dev_iface,
-		[AHCI_DEV_IFACE] = &remote_ahci_iface
+		[AHCI_DEV_IFACE] = &remote_ahci_iface,
 	}
 };
 
-remote_iface_t *get_remote_iface(int idx)
+const remote_iface_t *get_remote_iface(int idx)
 {
 	assert(is_valid_iface_idx(idx));
@@ -80,5 +80,5 @@
 
 remote_iface_func_ptr_t
-get_remote_method(remote_iface_t *rem_iface, sysarg_t iface_method_idx)
+get_remote_method(const remote_iface_t *rem_iface, sysarg_t iface_method_idx)
 {
 	if (iface_method_idx >= rem_iface->method_count)
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/driver.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -63,5 +63,5 @@
 
 /** Driver structure */
-static driver_t *driver;
+static const driver_t *driver;
 
 /** Devices */
@@ -413,5 +413,5 @@
 		 * handling ("remote interface").
 		 */
-		remote_iface_t *rem_iface = get_remote_iface(iface_idx);
+		const remote_iface_t *rem_iface = get_remote_iface(iface_idx);
 		assert(rem_iface != NULL);
 		
@@ -956,5 +956,5 @@
 }
 
-int ddf_driver_main(driver_t *drv)
+int ddf_driver_main(const driver_t *drv)
 {
 	/*
Index: uspace/lib/drv/generic/interrupt.c
===================================================================
--- uspace/lib/drv/generic/interrupt.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/interrupt.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -39,4 +39,5 @@
 #include <errno.h>
 #include <sys/types.h>
+#include <macros.h>
 
 #include "ddf/interrupt.h"
@@ -55,7 +56,4 @@
 static interrupt_context_t *find_interrupt_context(
     interrupt_context_list_t *list, ddf_dev_t *dev, int irq);
-int register_interrupt_handler(ddf_dev_t *dev, int irq,
-    interrupt_handler_t *handler, irq_code_t *pseudocode);
-int unregister_interrupt_handler(ddf_dev_t *dev, int irq);
 
 /** Interrupts */
@@ -68,8 +66,8 @@
 };
 
-static irq_code_t default_pseudocode = {
+static const irq_code_t default_pseudocode = {
 	0,
 	NULL,
-	sizeof(default_cmds) / sizeof(irq_cmd_t),
+	ARRAY_SIZE(default_cmds),
 	default_cmds
 };
@@ -169,5 +167,5 @@
 
 int register_interrupt_handler(ddf_dev_t *dev, int irq,
-    interrupt_handler_t *handler, irq_code_t *pseudocode)
+    interrupt_handler_t *handler, const irq_code_t *pseudocode)
 {
 	interrupt_context_t *ctx = create_interrupt_context();
Index: uspace/lib/drv/generic/private/remote_ahci.h
===================================================================
--- uspace/lib/drv/generic/private/remote_ahci.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/generic/private/remote_ahci.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012 Petr Jerman
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_AHCI_H_
+#define LIBDRV_REMOTE_AHCI_H_
+
+extern remote_iface_t remote_ahci_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/private/remote_audio_mixer.h
===================================================================
--- uspace/lib/drv/generic/private/remote_audio_mixer.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/generic/private/remote_audio_mixer.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,45 @@
+/*
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_AUDIO_MIXER_H_
+#define LIBDRV_REMOTE_AUDIO_MIXER_H_
+
+extern remote_iface_t remote_audio_mixer_iface;
+
+#endif
+
+/**
+ * @}
+ */
+
Index: uspace/lib/drv/generic/private/remote_audio_pcm.h
===================================================================
--- uspace/lib/drv/generic/private/remote_audio_pcm.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/generic/private/remote_audio_pcm.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,44 @@
+/*
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_AUDIO_PCM_H_
+#define LIBDRV_REMOTE_AUDIO_PCM_H_
+
+extern remote_iface_t remote_audio_pcm_iface;
+
+#endif
+
+/**
+ * @}
+ */
+
Index: uspace/lib/drv/generic/private/remote_battery_dev.h
===================================================================
--- uspace/lib/drv/generic/private/remote_battery_dev.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/generic/private/remote_battery_dev.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,45 @@
+/*
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_BATTERY_DEV_H_
+#define LIBDRV_REMOTE_BATTERY_DEV_H_
+
+extern remote_iface_t remote_battery_dev_iface;
+
+#endif
+
+/**
+ * @}
+ */
+
Index: uspace/lib/drv/generic/private/remote_char_dev.h
===================================================================
--- uspace/lib/drv/generic/private/remote_char_dev.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/generic/private/remote_char_dev.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_CHAR_DEV_H_
+#define LIBDRV_REMOTE_CHAR_DEV_H_
+
+extern remote_iface_t remote_char_dev_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/private/remote_clock_dev.h
===================================================================
--- uspace/lib/drv/generic/private/remote_clock_dev.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/generic/private/remote_clock_dev.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,45 @@
+/*
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_CLOCK_DEV_H_
+#define LIBDRV_REMOTE_CLOCK_DEV_H_
+
+extern remote_iface_t remote_clock_dev_iface;
+
+#endif
+
+/**
+ * @}
+ */
+
Index: uspace/lib/drv/generic/private/remote_graph_dev.h
===================================================================
--- uspace/lib/drv/generic/private/remote_graph_dev.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/generic/private/remote_graph_dev.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011 Petr Koupy
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_GRAPH_DEV_H_
+#define LIBDRV_REMOTE_GRAPH_DEV_H_
+
+extern remote_iface_t remote_graph_dev_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/private/remote_hw_res.h
===================================================================
--- uspace/lib/drv/generic/private/remote_hw_res.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/generic/private/remote_hw_res.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_HW_RES_H_
+#define LIBDRV_REMOTE_HW_RES_H_
+
+extern remote_iface_t remote_hw_res_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/private/remote_nic.h
===================================================================
--- uspace/lib/drv/generic/private/remote_nic.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/generic/private/remote_nic.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011 Radim Vansa
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_NIC_H_
+#define LIBDRV_REMOTE_NIC_H_
+
+extern remote_iface_t remote_nic_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/private/remote_pci.h
===================================================================
--- uspace/lib/drv/generic/private/remote_pci.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/generic/private/remote_pci.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,45 @@
+/*
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_PCI_H_
+#define LIBDRV_REMOTE_PCI_H_
+
+extern remote_iface_t remote_pci_iface;
+
+#endif
+
+/**
+ * @}
+ */
+
Index: uspace/lib/drv/generic/private/remote_pio_window.h
===================================================================
--- uspace/lib/drv/generic/private/remote_pio_window.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/generic/private/remote_pio_window.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013 Jakub Jermar 
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_PIO_WINDOW_H_
+#define LIBDRV_REMOTE_PIO_WINDOW_H_
+
+extern remote_iface_t remote_pio_window_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/private/remote_usb.h
===================================================================
--- uspace/lib/drv/generic/private/remote_usb.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/generic/private/remote_usb.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,44 @@
+/*
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_USB_H_
+#define LIBDRV_REMOTE_USB_H_
+
+extern remote_iface_t remote_usb_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/private/remote_usbhc.h
===================================================================
--- uspace/lib/drv/generic/private/remote_usbhc.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/generic/private/remote_usbhc.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,44 @@
+/*
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_USBHC_H_
+#define LIBDRV_REMOTE_USBHC_H_
+
+extern remote_iface_t remote_usbhc_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/private/remote_usbhid.h
===================================================================
--- uspace/lib/drv/generic/private/remote_usbhid.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/generic/private/remote_usbhid.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,44 @@
+/*
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_USBHID_H_
+#define LIBDRV_REMOTE_USBHID_H_
+
+extern remote_iface_t remote_usbhid_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/remote_ahci.c
===================================================================
--- uspace/lib/drv/generic/remote_ahci.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_ahci.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -33,7 +33,10 @@
  */
 
+#include <as.h>
 #include <async.h>
+#include <devman.h>
 #include <errno.h>
 #include <stdio.h>
+#include <macros.h>
 #include "ahci_iface.h"
 #include "ddf/driver.h"
@@ -47,4 +50,6 @@
 } ahci_iface_funcs_t;
 
+#define MAX_NAME_LENGTH  1024
+
 #define LO(ptr) \
 	((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) & 0xffffffff))
@@ -53,4 +58,128 @@
 	((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) >> 32))
 
+async_sess_t* ahci_get_sess(devman_handle_t funh, char **name)
+{
+	// FIXME: Use a better way than substring match
+	
+	*name = NULL;
+	
+	char devn[MAX_NAME_LENGTH];
+	int rc = devman_fun_get_name(funh, devn, MAX_NAME_LENGTH);
+	if (rc != EOK)
+		return NULL;
+	
+	size_t devn_size = str_size(devn);
+	
+	if ((devn_size > 5) && (str_lcmp(devn, "ahci_", 5) == 0)) {
+		async_sess_t *sess = devman_device_connect(EXCHANGE_PARALLEL,
+		    funh, IPC_FLAG_BLOCKING);
+		
+		if (sess) {
+			*name = str_dup(devn);
+			return sess;
+		}
+	}
+	
+	return NULL;
+}
+
+int ahci_get_sata_device_name(async_sess_t *sess, size_t sata_dev_name_length,
+    char *sata_dev_name)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	if (!exch)
+		return EINVAL;
+	
+	aid_t req = async_send_2(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
+	    IPC_M_AHCI_GET_SATA_DEVICE_NAME, sata_dev_name_length, NULL);
+	
+	async_data_read_start(exch, sata_dev_name, sata_dev_name_length);
+	
+	sysarg_t rc;
+	async_wait_for(req, &rc);
+	
+	return rc;
+}
+
+int ahci_get_num_blocks(async_sess_t *sess, uint64_t *blocks)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	if (!exch)
+		return EINVAL;
+	
+	sysarg_t blocks_hi;
+	sysarg_t blocks_lo;
+	int rc = async_req_1_2(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
+	    IPC_M_AHCI_GET_NUM_BLOCKS, &blocks_hi, &blocks_lo);
+	
+	async_exchange_end(exch);
+	
+	if (rc == EOK) {
+		*blocks = (((uint64_t) blocks_hi) << 32)
+		    | (((uint64_t) blocks_lo) & 0xffffffff);
+	}
+	
+	return rc;
+}
+
+int ahci_get_block_size(async_sess_t *sess, size_t *blocks_size)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	if (!exch)
+		return EINVAL;
+	
+	sysarg_t bs;
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
+	    IPC_M_AHCI_GET_BLOCK_SIZE, &bs);
+	
+	async_exchange_end(exch);
+	
+	if (rc == EOK)
+		*blocks_size = (size_t) bs;
+	
+	return rc;
+}
+
+int ahci_read_blocks(async_sess_t *sess, uint64_t blocknum, size_t count,
+    void *buf)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	if (!exch)
+		return EINVAL;
+	
+	aid_t req;
+	req = async_send_4(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
+	    IPC_M_AHCI_READ_BLOCKS, HI(blocknum),  LO(blocknum), count, NULL);
+	
+	async_share_out_start(exch, buf, AS_AREA_READ | AS_AREA_WRITE);
+	
+	async_exchange_end(exch);
+	
+	sysarg_t rc;
+	async_wait_for(req, &rc);
+	
+	return rc;
+}
+
+int ahci_write_blocks(async_sess_t *sess, uint64_t blocknum, size_t count,
+    void* buf)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	if (!exch)
+		return EINVAL;
+	
+	aid_t req = async_send_4(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
+	    IPC_M_AHCI_WRITE_BLOCKS, HI(blocknum),  LO(blocknum), count, NULL);
+	
+	async_share_out_start(exch, buf, AS_AREA_READ | AS_AREA_WRITE);
+	
+	async_exchange_end(exch);
+	
+	sysarg_t rc;
+	async_wait_for(req, &rc);
+	
+	return rc;
+}
+
 static void remote_ahci_get_sata_device_name(ddf_fun_t *, void *, ipc_callid_t,
     ipc_call_t *);
@@ -65,5 +194,5 @@
 
 /** Remote AHCI interface operations. */
-static remote_iface_func_ptr_t remote_ahci_iface_ops [] = {
+static const remote_iface_func_ptr_t remote_ahci_iface_ops [] = {
 	[IPC_M_AHCI_GET_SATA_DEVICE_NAME] = remote_ahci_get_sata_device_name,
 	[IPC_M_AHCI_GET_NUM_BLOCKS] = remote_ahci_get_num_blocks,
@@ -75,7 +204,6 @@
 /** Remote AHCI interface structure.
  */
-remote_iface_t remote_ahci_iface = {
-	.method_count = sizeof(remote_ahci_iface_ops) /
-	    sizeof(remote_ahci_iface_ops[0]),
+const remote_iface_t remote_ahci_iface = {
+	.method_count = ARRAY_SIZE(remote_ahci_iface_ops),
 	.methods = remote_ahci_iface_ops
 };
Index: uspace/lib/drv/generic/remote_audio_mixer.c
===================================================================
--- uspace/lib/drv/generic/remote_audio_mixer.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_audio_mixer.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -37,4 +37,5 @@
 #include <assert.h>
 #include <str.h>
+#include <macros.h>
 
 #include "audio_mixer_iface.h"
@@ -204,5 +205,5 @@
 
 /** Remote audio mixer interface operations. */
-static remote_iface_func_ptr_t remote_audio_mixer_iface_ops[] = {
+static const remote_iface_func_ptr_t remote_audio_mixer_iface_ops[] = {
 	[IPC_M_AUDIO_MIXER_GET_INFO] = remote_audio_mixer_get_info,
 	[IPC_M_AUDIO_MIXER_GET_ITEM_INFO] = remote_audio_mixer_get_item_info,
@@ -212,7 +213,6 @@
 
 /** Remote audio mixer interface structure. */
-remote_iface_t remote_audio_mixer_iface = {
-	.method_count = sizeof(remote_audio_mixer_iface_ops) /
-	    sizeof(remote_audio_mixer_iface_ops[0]),
+const remote_iface_t remote_audio_mixer_iface = {
+	.method_count = ARRAY_SIZE(remote_audio_mixer_iface_ops),
 	.methods = remote_audio_mixer_iface_ops
 };
Index: uspace/lib/drv/generic/remote_audio_pcm.c
===================================================================
--- uspace/lib/drv/generic/remote_audio_pcm.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_audio_pcm.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -38,5 +38,4 @@
 #include <macros.h>
 #include <str.h>
-#include <as.h>
 #include <sys/mman.h>
 
@@ -611,5 +610,5 @@
 
 /** Remote audio pcm buffer interface operations. */
-static remote_iface_func_ptr_t remote_audio_pcm_iface_ops[] = {
+static const remote_iface_func_ptr_t remote_audio_pcm_iface_ops[] = {
 	[IPC_M_AUDIO_PCM_GET_INFO_STR] = remote_audio_pcm_get_info_str,
 	[IPC_M_AUDIO_PCM_QUERY_CAPS] = remote_audio_pcm_query_caps,
@@ -627,7 +626,6 @@
 
 /** Remote audio mixer interface structure. */
-remote_iface_t remote_audio_pcm_iface = {
-	.method_count = sizeof(remote_audio_pcm_iface_ops) /
-	    sizeof(remote_audio_pcm_iface_ops[0]),
+const remote_iface_t remote_audio_pcm_iface = {
+	.method_count = ARRAY_SIZE(remote_audio_pcm_iface_ops),
 	.methods = remote_audio_pcm_iface_ops
 };
Index: uspace/lib/drv/generic/remote_battery_dev.c
===================================================================
--- uspace/lib/drv/generic/remote_battery_dev.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_battery_dev.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -36,6 +36,57 @@
 #include <errno.h>
 #include <ops/battery_dev.h>
-#include <device/battery_dev.h>
+#include <battery_iface.h>
 #include <ddf/driver.h>
+#include <macros.h>
+
+/** Read the current battery status from the device
+ *
+ * @param sess     Session of the device
+ * @param status   Current status of the battery
+ *
+ * @return         EOK on success or a negative error code
+ */
+int
+battery_status_get(async_sess_t *sess, battery_status_t *batt_status)
+{
+	sysarg_t status;
+
+	async_exch_t *exch = async_exchange_begin(sess);
+
+	int const rc = async_req_1_1(exch, DEV_IFACE_ID(BATTERY_DEV_IFACE),
+	    BATTERY_STATUS_GET, &status);
+
+	async_exchange_end(exch);
+
+	if (rc == EOK)
+		*batt_status = (battery_status_t) status;
+
+	return rc;
+}
+
+/** Read the current battery charge level from the device
+ *
+ * @param sess     Session of the device
+ * @param level    Battery charge level (0 - 100)
+ *
+ * @return         EOK on success or a negative error code
+ */
+int
+battery_charge_level_get(async_sess_t *sess, int *level)
+{
+	sysarg_t charge_level;
+
+	async_exch_t *exch = async_exchange_begin(sess);
+
+	int const rc = async_req_1_1(exch, DEV_IFACE_ID(BATTERY_DEV_IFACE),
+	    BATTERY_CHARGE_LEVEL_GET, &charge_level);
+
+	async_exchange_end(exch);
+
+	if (rc == EOK)
+		*level = (int) charge_level;
+
+	return rc;
+}
 
 static void remote_battery_status_get(ddf_fun_t *, void *, ipc_callid_t,
@@ -45,7 +96,7 @@
 
 /** Remote battery interface operations */
-static remote_iface_func_ptr_t remote_battery_dev_iface_ops[] = {
-	&remote_battery_status_get,
-	&remote_battery_charge_level_get,
+static const remote_iface_func_ptr_t remote_battery_dev_iface_ops[] = {
+	[BATTERY_STATUS_GET] = remote_battery_status_get,
+	[BATTERY_CHARGE_LEVEL_GET] = remote_battery_charge_level_get,
 };
 
@@ -56,7 +107,6 @@
  *
  */
-remote_iface_t remote_battery_dev_iface = {
-	.method_count = sizeof(remote_battery_dev_iface_ops) /
-	    sizeof(remote_iface_func_ptr_t),
+const remote_iface_t remote_battery_dev_iface = {
+	.method_count = ARRAY_SIZE(remote_battery_dev_iface_ops),
 	.methods = remote_battery_dev_iface_ops,
 };
Index: uspace/lib/drv/generic/remote_char_dev.c
===================================================================
--- uspace/lib/drv/generic/remote_char_dev.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_char_dev.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -35,9 +35,95 @@
 #include <async.h>
 #include <errno.h>
+#include <macros.h>
 
 #include "ops/char_dev.h"
+#include "char_dev_iface.h"
 #include "ddf/driver.h"
 
 #define MAX_CHAR_RW_COUNT 256
+
+/** Read to or write from device.
+ *
+ * Helper function to read to or write from a device
+ * using its character interface.
+ *
+ * @param sess Session to the device.
+ * @param buf  Buffer for the data read from or written to the device.
+ * @param size Maximum size of data (in bytes) to be read or written.
+ * @param read Read from the device if true, write to it otherwise.
+ *
+ * @return Non-negative number of bytes actually read from or
+ *         written to the device on success, negative error number
+ *         otherwise.
+ *
+ */
+static ssize_t char_dev_rw(async_sess_t *sess, void *buf, size_t size, bool read)
+{
+	ipc_call_t answer;
+	aid_t req;
+	int ret;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	
+	if (read) {
+		req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE),
+		    CHAR_DEV_READ, &answer);
+		ret = async_data_read_start(exch, buf, size);
+	} else {
+		req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE),
+		    CHAR_DEV_WRITE, &answer);
+		ret = async_data_write_start(exch, buf, size);
+	}
+	
+	async_exchange_end(exch);
+	
+	sysarg_t rc;
+	if (ret != EOK) {
+		async_wait_for(req, &rc);
+		if (rc == EOK)
+			return (ssize_t) ret;
+		
+		return (ssize_t) rc;
+	}
+	
+	async_wait_for(req, &rc);
+	
+	ret = (int) rc;
+	if (ret != EOK)
+		return (ssize_t) ret;
+	
+	return (ssize_t) IPC_GET_ARG1(answer);
+}
+
+/** Read from character device.
+ *
+ * @param sess Session to the device.
+ * @param buf  Output buffer for the data read from the device.
+ * @param size Maximum size (in bytes) of the data to be read.
+ *
+ * @return Non-negative number of bytes actually read from the
+ *         device on success, negative error number otherwise.
+ *
+ */
+ssize_t char_dev_read(async_sess_t *sess, void *buf, size_t size)
+{
+	return char_dev_rw(sess, buf, size, true);
+}
+
+/** Write to character device.
+ *
+ * @param sess Session to the device.
+ * @param buf  Input buffer containg the data to be written to the
+ *             device.
+ * @param size Maximum size (in bytes) of the data to be written.
+ *
+ * @return Non-negative number of bytes actually written to the
+ *         device on success, negative error number otherwise.
+ *
+ */
+ssize_t char_dev_write(async_sess_t *sess, void *buf, size_t size)
+{
+	return char_dev_rw(sess, buf, size, false);
+}
 
 static void remote_char_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
@@ -45,7 +131,7 @@
 
 /** Remote character interface operations. */
-static remote_iface_func_ptr_t remote_char_dev_iface_ops[] = {
-	&remote_char_read,
-	&remote_char_write
+static const remote_iface_func_ptr_t remote_char_dev_iface_ops[] = {
+	[CHAR_DEV_READ] = remote_char_read,
+	[CHAR_DEV_WRITE] = remote_char_write
 };
 
@@ -55,7 +141,6 @@
  * character interface.
  */
-remote_iface_t remote_char_dev_iface = {
-	.method_count = sizeof(remote_char_dev_iface_ops) /
-	    sizeof(remote_iface_func_ptr_t),
+const remote_iface_t remote_char_dev_iface = {
+	.method_count = ARRAY_SIZE(remote_char_dev_iface_ops),
 	.methods = remote_char_dev_iface_ops
 };
Index: uspace/lib/drv/generic/remote_clock_dev.c
===================================================================
--- uspace/lib/drv/generic/remote_clock_dev.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_clock_dev.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -36,4 +36,6 @@
 #include <errno.h>
 #include <time.h>
+#include <macros.h>
+#include <device/clock_dev.h>
 
 #include <ops/clock_dev.h>
@@ -46,7 +48,7 @@
 
 /** Remote clock interface operations */
-static remote_iface_func_ptr_t remote_clock_dev_iface_ops[] = {
-	&remote_clock_time_get,
-	&remote_clock_time_set,
+static const remote_iface_func_ptr_t remote_clock_dev_iface_ops[] = {
+	[CLOCK_DEV_TIME_GET] = remote_clock_time_get,
+	[CLOCK_DEV_TIME_SET] = remote_clock_time_set,
 };
 
@@ -56,7 +58,6 @@
  * addressed by the clock interface.
  */
-remote_iface_t remote_clock_dev_iface = {
-	.method_count = sizeof(remote_clock_dev_iface_ops) /
-	    sizeof(remote_iface_func_ptr_t),
+const remote_iface_t remote_clock_dev_iface = {
+	.method_count = ARRAY_SIZE(remote_clock_dev_iface_ops),
 	.methods = remote_clock_dev_iface_ops,
 };
Index: uspace/lib/drv/generic/remote_graph_dev.c
===================================================================
--- uspace/lib/drv/generic/remote_graph_dev.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_graph_dev.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -35,17 +35,31 @@
 #include <errno.h>
 #include <async.h>
+#include <macros.h>
 
 #include "ops/graph_dev.h"
+#include "graph_iface.h"
 #include "ddf/driver.h"
+
+typedef enum {
+	GRAPH_DEV_CONNECT = 0
+} graph_dev_method_t;
+
+int graph_dev_connect(async_sess_t *sess)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	int ret = async_req_1_0(exch, DEV_IFACE_ID(GRAPH_DEV_IFACE), GRAPH_DEV_CONNECT);
+	async_exchange_end(exch);
+
+	return ret;
+}
 
 static void remote_graph_connect(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
 
-static remote_iface_func_ptr_t remote_graph_dev_iface_ops[] = {
-	&remote_graph_connect
+static const remote_iface_func_ptr_t remote_graph_dev_iface_ops[] = {
+	[GRAPH_DEV_CONNECT] = remote_graph_connect
 };
 
-remote_iface_t remote_graph_dev_iface = {
-	.method_count = sizeof(remote_graph_dev_iface_ops) /
-	    sizeof(remote_iface_func_ptr_t),
+const remote_iface_t remote_graph_dev_iface = {
+	.method_count = ARRAY_SIZE(remote_graph_dev_iface_ops),
 	.methods = remote_graph_dev_iface_ops
 };
Index: uspace/lib/drv/generic/remote_hw_res.c
===================================================================
--- uspace/lib/drv/generic/remote_hw_res.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_hw_res.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -36,4 +36,5 @@
 #include <async.h>
 #include <errno.h>
+#include <macros.h>
 
 #include "ops/hw_res.h"
@@ -49,5 +50,5 @@
     ipc_call_t *);
 
-static remote_iface_func_ptr_t remote_hw_res_iface_ops [] = {
+static const remote_iface_func_ptr_t remote_hw_res_iface_ops [] = {
 	[HW_RES_GET_RESOURCE_LIST] = &remote_hw_res_get_resource_list,
 	[HW_RES_ENABLE_INTERRUPT] = &remote_hw_res_enable_interrupt,
@@ -56,7 +57,6 @@
 };
 
-remote_iface_t remote_hw_res_iface = {
-	.method_count = sizeof(remote_hw_res_iface_ops) /
-	    sizeof(remote_iface_func_ptr_t),
+const remote_iface_t remote_hw_res_iface = {
+	.method_count = ARRAY_SIZE(remote_hw_res_iface_ops),
 	.methods = remote_hw_res_iface_ops
 };
Index: uspace/lib/drv/generic/remote_nic.c
===================================================================
--- uspace/lib/drv/generic/remote_nic.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_nic.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -40,5 +40,1297 @@
 #include <ipc/services.h>
 #include <sys/time.h>
+#include <macros.h>
+
 #include "ops/nic.h"
+#include "nic_iface.h"
+
+typedef enum {
+	NIC_SEND_MESSAGE = 0,
+	NIC_CALLBACK_CREATE,
+	NIC_GET_STATE,
+	NIC_SET_STATE,
+	NIC_GET_ADDRESS,
+	NIC_SET_ADDRESS,
+	NIC_GET_STATS,
+	NIC_GET_DEVICE_INFO,
+	NIC_GET_CABLE_STATE,
+	NIC_GET_OPERATION_MODE,
+	NIC_SET_OPERATION_MODE,
+	NIC_AUTONEG_ENABLE,
+	NIC_AUTONEG_DISABLE,
+	NIC_AUTONEG_PROBE,
+	NIC_AUTONEG_RESTART,
+	NIC_GET_PAUSE,
+	NIC_SET_PAUSE,
+	NIC_UNICAST_GET_MODE,
+	NIC_UNICAST_SET_MODE,
+	NIC_MULTICAST_GET_MODE,
+	NIC_MULTICAST_SET_MODE,
+	NIC_BROADCAST_GET_MODE,
+	NIC_BROADCAST_SET_MODE,
+	NIC_DEFECTIVE_GET_MODE,
+	NIC_DEFECTIVE_SET_MODE,
+	NIC_BLOCKED_SOURCES_GET,
+	NIC_BLOCKED_SOURCES_SET,
+	NIC_VLAN_GET_MASK,
+	NIC_VLAN_SET_MASK,
+	NIC_VLAN_SET_TAG,
+	NIC_WOL_VIRTUE_ADD,
+	NIC_WOL_VIRTUE_REMOVE,
+	NIC_WOL_VIRTUE_PROBE,
+	NIC_WOL_VIRTUE_LIST,
+	NIC_WOL_VIRTUE_GET_CAPS,
+	NIC_WOL_LOAD_INFO,
+	NIC_OFFLOAD_PROBE,
+	NIC_OFFLOAD_SET,
+	NIC_POLL_GET_MODE,
+	NIC_POLL_SET_MODE,
+	NIC_POLL_NOW
+} nic_funcs_t;
+
+/** Send frame from NIC
+ *
+ * @param[in] dev_sess
+ * @param[in] data     Frame data
+ * @param[in] size     Frame size in bytes
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_send_frame(async_sess_t *dev_sess, void *data, size_t size)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	ipc_call_t answer;
+	aid_t req = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_SEND_MESSAGE, &answer);
+	sysarg_t retval = async_data_write_start(exch, data, size);
+	
+	async_exchange_end(exch);
+	
+	if (retval != EOK) {
+		async_forget(req);
+		return retval;
+	}
+
+	async_wait_for(req, &retval);
+	return retval;
+}
+
+/** Create callback connection from NIC service
+ *
+ * @param[in] dev_sess
+ * @param[in] device_id
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_callback_create(async_sess_t *dev_sess, async_client_conn_t cfun,
+    void *carg)
+{
+	ipc_call_t answer;
+	int rc;
+	sysarg_t retval;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	aid_t req = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_CALLBACK_CREATE, &answer);
+	
+	rc = async_connect_to_me(exch, 0, 0, 0, cfun, carg);
+	if (rc != EOK) {
+		async_forget(req);
+		return rc;
+	}
+	async_exchange_end(exch);
+	
+	async_wait_for(req, &retval);
+	return (int) retval;
+}
+
+/** Get the current state of the device
+ *
+ * @param[in]  dev_sess
+ * @param[out] state    Current state
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_get_state(async_sess_t *dev_sess, nic_device_state_t *state)
+{
+	assert(state);
+	
+	sysarg_t _state;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_GET_STATE, &_state);
+	async_exchange_end(exch);
+	
+	*state = (nic_device_state_t) _state;
+	
+	return rc;
+}
+
+/** Request the device to change its state
+ *
+ * @param[in] dev_sess
+ * @param[in] state    New state
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_set_state(async_sess_t *dev_sess, nic_device_state_t state)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_SET_STATE, state);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Request the MAC address of the device
+ *
+ * @param[in]  dev_sess
+ * @param[out] address  Structure with buffer for the address
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_get_address(async_sess_t *dev_sess, nic_address_t *address)
+{
+	assert(address);
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	aid_t aid = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_GET_ADDRESS, NULL);
+	int rc = async_data_read_start(exch, address, sizeof(nic_address_t));
+	async_exchange_end(exch);
+	
+	sysarg_t res;
+	async_wait_for(aid, &res);
+	
+	if (rc != EOK)
+		return rc;
+	
+	return (int) res;
+}
+
+/** Set the address of the device (e.g. MAC on Ethernet)
+ *
+ * @param[in] dev_sess
+ * @param[in] address  Pointer to the address
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_set_address(async_sess_t *dev_sess, const nic_address_t *address)
+{
+	assert(address);
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	aid_t aid = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_SET_ADDRESS, NULL);
+	int rc = async_data_write_start(exch, address, sizeof(nic_address_t));
+	async_exchange_end(exch);
+	
+	sysarg_t res;
+	async_wait_for(aid, &res);
+	
+	if (rc != EOK)
+		return rc;
+	
+	return (int) res;
+}
+
+/** Request statistic data about NIC operation.
+ *
+ * @param[in]  dev_sess
+ * @param[out] stats    Structure with the statistics
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_get_stats(async_sess_t *dev_sess, nic_device_stats_t *stats)
+{
+	assert(stats);
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_GET_STATS);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	rc = async_data_read_start(exch, stats, sizeof(nic_device_stats_t));
+	
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Request information about the device.
+ *
+ * @see nic_device_info_t
+ *
+ * @param[in]  dev_sess
+ * @param[out] device_info Information about the device
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_get_device_info(async_sess_t *dev_sess, nic_device_info_t *device_info)
+{
+	assert(device_info);
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_GET_DEVICE_INFO);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	rc = async_data_read_start(exch, device_info, sizeof(nic_device_info_t));
+	
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Request status of the cable (plugged/unplugged)
+ *
+ * @param[in]  dev_sess
+ * @param[out] cable_state Current cable state
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_get_cable_state(async_sess_t *dev_sess, nic_cable_state_t *cable_state)
+{
+	assert(cable_state);
+	
+	sysarg_t _cable_state;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_GET_CABLE_STATE, &_cable_state);
+	async_exchange_end(exch);
+	
+	*cable_state = (nic_cable_state_t) _cable_state;
+	
+	return rc;
+}
+
+/** Request current operation mode.
+ *
+ * @param[in]  dev_sess
+ * @param[out] speed    Current operation speed in Mbps. Can be NULL.
+ * @param[out] duplex   Full duplex/half duplex. Can be NULL.
+ * @param[out] role     Master/slave/auto. Can be NULL.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_get_operation_mode(async_sess_t *dev_sess, int *speed,
+   nic_channel_mode_t *duplex, nic_role_t *role)
+{
+	sysarg_t _speed;
+	sysarg_t _duplex;
+	sysarg_t _role;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_GET_OPERATION_MODE, &_speed, &_duplex, &_role);
+	async_exchange_end(exch);
+	
+	if (speed)
+		*speed = (int) _speed;
+	
+	if (duplex)
+		*duplex = (nic_channel_mode_t) _duplex;
+	
+	if (role)
+		*role = (nic_role_t) _role;
+	
+	return rc;
+}
+
+/** Set current operation mode.
+ *
+ * If the NIC has auto-negotiation enabled, this command
+ * disables auto-negotiation and sets the operation mode.
+ *
+ * @param[in] dev_sess
+ * @param[in] speed    Operation speed in Mbps
+ * @param[in] duplex   Full duplex/half duplex
+ * @param[in] role     Master/slave/auto (e.g. in Gbit Ethernet]
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_set_operation_mode(async_sess_t *dev_sess, int speed,
+    nic_channel_mode_t duplex, nic_role_t role)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_SET_OPERATION_MODE, (sysarg_t) speed, (sysarg_t) duplex,
+	    (sysarg_t) role);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Enable auto-negotiation.
+ *
+ * The advertisement argument can only limit some modes,
+ * it can never force the NIC to advertise unsupported modes.
+ *
+ * The allowed modes are defined in "nic/eth_phys.h" in the C library.
+ *
+ * @param[in] dev_sess
+ * @param[in] advertisement Allowed advertised modes. Use 0 for all modes.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_autoneg_enable(async_sess_t *dev_sess, uint32_t advertisement)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_AUTONEG_ENABLE, (sysarg_t) advertisement);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Disable auto-negotiation.
+ *
+ * @param[in] dev_sess
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_autoneg_disable(async_sess_t *dev_sess)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_AUTONEG_DISABLE);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Probe current state of auto-negotiation.
+ *
+ * Modes are defined in the "nic/eth_phys.h" in the C library.
+ *
+ * @param[in]  dev_sess
+ * @param[out] our_advertisement   Modes advertised by this NIC.
+ *                                 Can be NULL.
+ * @param[out] their_advertisement Modes advertised by the other side.
+ *                                 Can be NULL.
+ * @param[out] result              General state of auto-negotiation.
+ *                                 Can be NULL.
+ * @param[out]  their_result       State of other side auto-negotiation.
+ *                                 Can be NULL.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_autoneg_probe(async_sess_t *dev_sess, uint32_t *our_advertisement,
+    uint32_t *their_advertisement, nic_result_t *result,
+    nic_result_t *their_result)
+{
+	sysarg_t _our_advertisement;
+	sysarg_t _their_advertisement;
+	sysarg_t _result;
+	sysarg_t _their_result;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_4(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_AUTONEG_PROBE, &_our_advertisement, &_their_advertisement,
+	    &_result, &_their_result);
+	async_exchange_end(exch);
+	
+	if (our_advertisement)
+		*our_advertisement = (uint32_t) _our_advertisement;
+	
+	if (*their_advertisement)
+		*their_advertisement = (uint32_t) _their_advertisement;
+	
+	if (result)
+		*result = (nic_result_t) _result;
+	
+	if (their_result)
+		*their_result = (nic_result_t) _their_result;
+	
+	return rc;
+}
+
+/** Restart the auto-negotiation process.
+ *
+ * @param[in] dev_sess
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_autoneg_restart(async_sess_t *dev_sess)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_AUTONEG_RESTART);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Query party's sending and reception of the PAUSE frame.
+ *
+ * @param[in]  dev_sess
+ * @param[out] we_send    This NIC sends the PAUSE frame (true/false)
+ * @param[out] we_receive This NIC receives the PAUSE frame (true/false)
+ * @param[out] pause      The time set to transmitted PAUSE frames.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_get_pause(async_sess_t *dev_sess, nic_result_t *we_send,
+    nic_result_t *we_receive, uint16_t *pause)
+{
+	sysarg_t _we_send;
+	sysarg_t _we_receive;
+	sysarg_t _pause;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_GET_PAUSE, &_we_send, &_we_receive, &_pause);
+	async_exchange_end(exch);
+	
+	if (we_send)
+		*we_send = _we_send;
+	
+	if (we_receive)
+		*we_receive = _we_receive;
+	
+	if (pause)
+		*pause = _pause;
+	
+	return rc;
+}
+
+/** Control sending and reception of the PAUSE frame.
+ *
+ * @param[in] dev_sess
+ * @param[in] allow_send    Allow sending the PAUSE frame (true/false)
+ * @param[in] allow_receive Allow reception of the PAUSE frame (true/false)
+ * @param[in] pause         Pause length in 512 bit units written
+ *                          to transmitted frames. The value 0 means
+ *                          auto value (the best). If the requested
+ *                          time cannot be set the driver is allowed
+ *                          to set the nearest supported value.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_set_pause(async_sess_t *dev_sess, int allow_send, int allow_receive,
+    uint16_t pause)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_SET_PAUSE, allow_send, allow_receive, pause);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Retrieve current settings of unicast frames reception.
+ *
+ * Note: In case of mode != NIC_UNICAST_LIST the contents of
+ * address_list and address_count are undefined.
+ *
+ * @param[in]   dev_sess
+ * @param[out]  mode          Current operation mode
+ * @param[in]   max_count     Maximal number of addresses that could
+ *                            be written into the list buffer.
+ * @param[out]  address_list  Buffer for the list (array). Can be NULL.
+ * @param[out]  address_count Number of addresses in the list before
+ *                            possible truncation due to the max_count.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_unicast_get_mode(async_sess_t *dev_sess, nic_unicast_mode_t *mode,
+    size_t max_count, nic_address_t *address_list, size_t *address_count)
+{
+	assert(mode);
+	
+	sysarg_t _mode;
+	sysarg_t _address_count;
+	
+	if (!address_list)
+		max_count = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	int rc = async_req_2_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_UNICAST_GET_MODE, max_count, &_mode, &_address_count);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	*mode = (nic_unicast_mode_t) _mode;
+	if (address_count)
+		*address_count = (size_t) _address_count;
+	
+	if ((max_count) && (_address_count))
+		rc = async_data_read_start(exch, address_list,
+		    max_count * sizeof(nic_address_t));
+	
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Set which unicast frames are received.
+ *
+ * @param[in] dev_sess
+ * @param[in] mode          Current operation mode
+ * @param[in] address_list  The list of addresses. Can be NULL.
+ * @param[in] address_count Number of addresses in the list.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_unicast_set_mode(async_sess_t *dev_sess, nic_unicast_mode_t mode,
+    const nic_address_t *address_list, size_t address_count)
+{
+	if (address_list == NULL)
+		address_count = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_UNICAST_SET_MODE, (sysarg_t) mode, address_count, NULL);
+	
+	int rc;
+	if (address_count)
+		rc = async_data_write_start(exch, address_list,
+		    address_count * sizeof(nic_address_t));
+	else
+		rc = EOK;
+	
+	async_exchange_end(exch);
+	
+	sysarg_t res;
+	async_wait_for(message_id, &res);
+	
+	if (rc != EOK)
+		return rc;
+	
+	return (int) res;
+}
+
+/** Retrieve current settings of multicast frames reception.
+ *
+ * Note: In case of mode != NIC_MULTICAST_LIST the contents of
+ * address_list and address_count are undefined.
+ *
+ * @param[in]  dev_sess
+ * @param[out] mode          Current operation mode
+ * @param[in]  max_count     Maximal number of addresses that could
+ *                           be written into the list buffer.
+ * @param[out] address_list  Buffer for the list (array). Can be NULL.
+ * @param[out] address_count Number of addresses in the list before
+ *                           possible truncation due to the max_count.
+ *                           Can be NULL.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_multicast_get_mode(async_sess_t *dev_sess, nic_multicast_mode_t *mode,
+    size_t max_count, nic_address_t *address_list, size_t *address_count)
+{
+	assert(mode);
+	
+	sysarg_t _mode;
+	
+	if (!address_list)
+		max_count = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	sysarg_t ac;
+	int rc = async_req_2_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_MULTICAST_GET_MODE, max_count, &_mode, &ac);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	*mode = (nic_multicast_mode_t) _mode;
+	if (address_count)
+		*address_count = (size_t) ac;
+	
+	if ((max_count) && (ac))
+		rc = async_data_read_start(exch, address_list,
+		    max_count * sizeof(nic_address_t));
+	
+	async_exchange_end(exch);
+	return rc;
+}
+
+/** Set which multicast frames are received.
+ *
+ * @param[in] dev_sess
+ * @param[in] mode          Current operation mode
+ * @param[in] address_list  The list of addresses. Can be NULL.
+ * @param[in] address_count Number of addresses in the list.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_multicast_set_mode(async_sess_t *dev_sess, nic_multicast_mode_t mode,
+    const nic_address_t *address_list, size_t address_count)
+{
+	if (address_list == NULL)
+		address_count = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_MULTICAST_SET_MODE, (sysarg_t) mode, address_count, NULL);
+	
+	int rc;
+	if (address_count)
+		rc = async_data_write_start(exch, address_list,
+		    address_count * sizeof(nic_address_t));
+	else
+		rc = EOK;
+	
+	async_exchange_end(exch);
+	
+	sysarg_t res;
+	async_wait_for(message_id, &res);
+	
+	if (rc != EOK)
+		return rc;
+	
+	return (int) res;
+}
+
+/** Determine if broadcast packets are received.
+ *
+ * @param[in]  dev_sess
+ * @param[out] mode     Current operation mode
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_broadcast_get_mode(async_sess_t *dev_sess, nic_broadcast_mode_t *mode)
+{
+	assert(mode);
+	
+	sysarg_t _mode;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_BROADCAST_GET_MODE, &_mode);
+	async_exchange_end(exch);
+	
+	*mode = (nic_broadcast_mode_t) _mode;
+	
+	return rc;
+}
+
+/** Set whether broadcast packets are received.
+ *
+ * @param[in] dev_sess
+ * @param[in] mode     Current operation mode
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_broadcast_set_mode(async_sess_t *dev_sess, nic_broadcast_mode_t mode)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_BROADCAST_SET_MODE, mode);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Determine if defective (erroneous) packets are received.
+ *
+ * @param[in]  dev_sess
+ * @param[out] mode     Bitmask specifying allowed errors
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_defective_get_mode(async_sess_t *dev_sess, uint32_t *mode)
+{
+	assert(mode);
+	
+	sysarg_t _mode;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_DEFECTIVE_GET_MODE, &_mode);
+	async_exchange_end(exch);
+	
+	*mode = (uint32_t) _mode;
+	
+	return rc;
+}
+
+/** Set whether defective (erroneous) packets are received.
+ *
+ * @param[in]  dev_sess
+ * @param[out] mode     Bitmask specifying allowed errors
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_defective_set_mode(async_sess_t *dev_sess, uint32_t mode)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_DEFECTIVE_SET_MODE, mode);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Retrieve the currently blocked source MAC addresses.
+ *
+ * @param[in]  dev_sess
+ * @param[in]  max_count     Maximal number of addresses that could
+ *                           be written into the list buffer.
+ * @param[out] address_list  Buffer for the list (array). Can be NULL.
+ * @param[out] address_count Number of addresses in the list before
+ *                           possible truncation due to the max_count.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_blocked_sources_get(async_sess_t *dev_sess, size_t max_count,
+    nic_address_t *address_list, size_t *address_count)
+{
+	if (!address_list)
+		max_count = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	sysarg_t ac;
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_BLOCKED_SOURCES_GET, max_count, &ac);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	if (address_count)
+		*address_count = (size_t) ac;
+	
+	if ((max_count) && (ac))
+		rc = async_data_read_start(exch, address_list,
+		    max_count * sizeof(nic_address_t));
+	
+	async_exchange_end(exch);
+	return rc;
+}
+
+/** Set which source MACs are blocked
+ *
+ * @param[in] dev_sess
+ * @param[in] address_list  The list of addresses. Can be NULL.
+ * @param[in] address_count Number of addresses in the list.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_blocked_sources_set(async_sess_t *dev_sess,
+    const nic_address_t *address_list, size_t address_count)
+{
+	if (address_list == NULL)
+		address_count = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	aid_t message_id = async_send_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_BLOCKED_SOURCES_SET, address_count, NULL);
+	
+	int rc;
+	if (address_count)
+		rc = async_data_write_start(exch, address_list,
+			address_count * sizeof(nic_address_t));
+	else
+		rc = EOK;
+	
+	async_exchange_end(exch);
+	
+	sysarg_t res;
+	async_wait_for(message_id, &res);
+	
+	if (rc != EOK)
+		return rc;
+	
+	return (int) res;
+}
+
+/** Request current VLAN filtering mask.
+ *
+ * @param[in]  dev_sess
+ * @param[out] stats    Structure with the statistics
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_vlan_get_mask(async_sess_t *dev_sess, nic_vlan_mask_t *mask)
+{
+	assert(mask);
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_VLAN_GET_MASK);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	rc = async_data_read_start(exch, mask, sizeof(nic_vlan_mask_t));
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Set the mask used for VLAN filtering.
+ *
+ * If NULL, VLAN filtering is disabled.
+ *
+ * @param[in] dev_sess
+ * @param[in] mask     Pointer to mask structure or NULL to disable.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_vlan_set_mask(async_sess_t *dev_sess, const nic_vlan_mask_t *mask)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	aid_t message_id = async_send_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_VLAN_SET_MASK, mask != NULL, NULL);
+	
+	int rc;
+	if (mask != NULL)
+		rc = async_data_write_start(exch, mask, sizeof(nic_vlan_mask_t));
+	else
+		rc = EOK;
+	
+	async_exchange_end(exch);
+	
+	sysarg_t res;
+	async_wait_for(message_id, &res);
+	
+	if (rc != EOK)
+		return rc;
+	
+	return (int) res;
+}
+
+/** Set VLAN (802.1q) tag.
+ *
+ * Set whether the tag is to be signaled in offload info and
+ * if the tag should be stripped from received frames and added
+ * to sent frames automatically. Not every combination of add
+ * and strip must be supported.
+ *
+ * @param[in] dev_sess
+ * @param[in] tag      VLAN priority (top 3 bits) and
+ *                     the VLAN tag (bottom 12 bits)
+ * @param[in] add      Add the VLAN tag automatically (boolean)
+ * @param[in] strip    Strip the VLAN tag automatically (boolean)
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_vlan_set_tag(async_sess_t *dev_sess, uint16_t tag, bool add, bool strip)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_VLAN_SET_TAG, (sysarg_t) tag, (sysarg_t) add, (sysarg_t) strip);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Add new Wake-On-LAN virtue.
+ *
+ * @param[in]  dev_sess
+ * @param[in]  type     Type of the virtue
+ * @param[in]  data     Data required for this virtue
+ *                      (depends on type)
+ * @param[in]  length   Length of the data
+ * @param[out] id       Identifier of the new virtue
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_wol_virtue_add(async_sess_t *dev_sess, nic_wv_type_t type,
+    const void *data, size_t length, nic_wv_id_t *id)
+{
+	assert(id);
+	
+	bool send_data = ((data != NULL) && (length != 0));
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	ipc_call_t result;
+	aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_WOL_VIRTUE_ADD, (sysarg_t) type, send_data, &result);
+	
+	sysarg_t res;
+	if (send_data) {
+		int rc = async_data_write_start(exch, data, length);
+		if (rc != EOK) {
+			async_exchange_end(exch);
+			async_wait_for(message_id, &res);
+			return rc;
+		}
+	}
+	
+	async_exchange_end(exch);
+	async_wait_for(message_id, &res);
+	
+	*id = IPC_GET_ARG1(result);
+	return (int) res;
+}
+
+/** Remove Wake-On-LAN virtue.
+ *
+ * @param[in] dev_sess
+ * @param[in] id       Virtue identifier
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_wol_virtue_remove(async_sess_t *dev_sess, nic_wv_id_t id)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_WOL_VIRTUE_REMOVE, (sysarg_t) id);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Get information about virtue.
+ *
+ * @param[in]  dev_sess
+ * @param[in]  id         Virtue identifier
+ * @param[out] type       Type of the filter. Can be NULL.
+ * @param[out] max_length Size of the data buffer.
+ * @param[out] data       Buffer for data used when the
+ *                        virtue was created. Can be NULL.
+ * @param[out] length     Length of the data. Can be NULL.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_wol_virtue_probe(async_sess_t *dev_sess, nic_wv_id_t id,
+    nic_wv_type_t *type, size_t max_length, void *data, size_t *length)
+{
+	sysarg_t _type;
+	sysarg_t _length;
+	
+	if (data == NULL)
+		max_length = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	int rc = async_req_3_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_WOL_VIRTUE_PROBE, (sysarg_t) id, max_length,
+	    &_type, &_length);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	if (type)
+		*type = _type;
+	
+	if (length)
+		*length = _length;
+	
+	if ((max_length) && (_length != 0))
+		rc = async_data_read_start(exch, data, max_length);
+	
+	async_exchange_end(exch);
+	return rc;
+}
+
+/** Get a list of all virtues of the specified type.
+ *
+ * When NIC_WV_NONE is specified as the virtue type the function
+ * lists virtues of all types.
+ *
+ * @param[in]  dev_sess
+ * @param[in]  type      Type of the virtues
+ * @param[in]  max_count Maximum number of ids that can be
+ *                       written into the list buffer.
+ * @param[out] id_list   Buffer for to the list of virtue ids.
+ *                       Can be NULL.
+ * @param[out] id_count  Number of virtue identifiers in the list
+ *                       before possible truncation due to the
+ *                       max_count. Can be NULL.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_wol_virtue_list(async_sess_t *dev_sess, nic_wv_type_t type,
+    size_t max_count, nic_wv_id_t *id_list, size_t *id_count)
+{
+	if (id_list == NULL)
+		max_count = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	sysarg_t count;
+	int rc = async_req_3_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_WOL_VIRTUE_LIST, (sysarg_t) type, max_count, &count);
+	
+	if (id_count)
+		*id_count = (size_t) count;
+	
+	if ((rc != EOK) || (!max_count)) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	rc = async_data_read_start(exch, id_list,
+	    max_count * sizeof(nic_wv_id_t));
+	
+	async_exchange_end(exch);
+	return rc;
+}
+
+/** Get number of virtues that can be enabled yet.
+ *
+ * Count: < 0 => Virtue of this type can be never used
+ *        = 0 => No more virtues can be enabled
+ *        > 0 => #count virtues can be enabled yet
+ *
+ * @param[in]  dev_sess
+ * @param[in]  type     Virtue type
+ * @param[out] count    Number of virtues
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_wol_virtue_get_caps(async_sess_t *dev_sess, nic_wv_type_t type,
+    int *count)
+{
+	assert(count);
+	
+	sysarg_t _count;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_WOL_VIRTUE_GET_CAPS, (sysarg_t) type, &_count);
+	async_exchange_end(exch);
+	
+	*count = (int) _count;
+	return rc;
+}
+
+/** Load the frame that issued the wakeup.
+ *
+ * The NIC can support only matched_type,  only part of the frame
+ * can be available or not at all. Sometimes even the type can be
+ * uncertain -- in this case the matched_type contains NIC_WV_NONE.
+ *
+ * Frame_length can be greater than max_length, but at most max_length
+ * bytes will be copied into the frame buffer.
+ *
+ * Note: Only the type of the filter can be detected, not the concrete
+ * filter, because the driver is probably not running when the wakeup
+ * is issued.
+ *
+ * @param[in]  dev_sess
+ * @param[out] matched_type Type of the filter that issued wakeup.
+ * @param[in]  max_length   Size of the buffer
+ * @param[out] frame        Buffer for the frame. Can be NULL.
+ * @param[out] frame_length Length of the stored frame. Can be NULL.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_wol_load_info(async_sess_t *dev_sess, nic_wv_type_t *matched_type,
+    size_t max_length, uint8_t *frame, size_t *frame_length)
+{
+	assert(matched_type);
+	
+	sysarg_t _matched_type;
+	sysarg_t _frame_length;
+	
+	if (frame == NULL)
+		max_length = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	int rc = async_req_2_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_WOL_LOAD_INFO, max_length, &_matched_type, &_frame_length);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	*matched_type = (nic_wv_type_t) _matched_type;
+	if (frame_length)
+		*frame_length = (size_t) _frame_length;
+	
+	if ((max_length != 0) && (_frame_length != 0))
+		rc = async_data_read_start(exch, frame, max_length);
+	
+	async_exchange_end(exch);
+	return rc;
+}
+
+/** Probe supported options and current setting of offload computations
+ *
+ * @param[in]  dev_sess
+ * @param[out] supported Supported offload options
+ * @param[out] active    Currently active offload options
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_offload_probe(async_sess_t *dev_sess, uint32_t *supported,
+    uint32_t *active)
+{
+	assert(supported);
+	assert(active);
+	
+	sysarg_t _supported;
+	sysarg_t _active;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_OFFLOAD_PROBE, &_supported, &_active);
+	async_exchange_end(exch);
+	
+	*supported = (uint32_t) _supported;
+	*active = (uint32_t) _active;
+	return rc;
+}
+
+/** Set which offload computations can be performed on the NIC.
+ *
+ * @param[in] dev_sess
+ * @param[in] mask     Mask for the options (only those set here will be set)
+ * @param[in] active   Which options should be enabled and which disabled
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_offload_set(async_sess_t *dev_sess, uint32_t mask, uint32_t active)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_3_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_AUTONEG_RESTART, (sysarg_t) mask, (sysarg_t) active);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Query the current interrupt/poll mode of the NIC
+ *
+ * @param[in]  dev_sess
+ * @param[out] mode     Current poll mode
+ * @param[out] period   Period used in periodic polling.
+ *                      Can be NULL.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_poll_get_mode(async_sess_t *dev_sess, nic_poll_mode_t *mode,
+    struct timeval *period)
+{
+	assert(mode);
+	
+	sysarg_t _mode;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_POLL_GET_MODE, period != NULL, &_mode);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	*mode = (nic_poll_mode_t) _mode;
+	
+	if (period != NULL)
+		rc = async_data_read_start(exch, period, sizeof(struct timeval));
+	
+	async_exchange_end(exch);
+	return rc;
+}
+
+/** Set the interrupt/poll mode of the NIC.
+ *
+ * @param[in] dev_sess
+ * @param[in] mode     New poll mode
+ * @param[in] period   Period used in periodic polling. Can be NULL.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_poll_set_mode(async_sess_t *dev_sess, nic_poll_mode_t mode,
+    const struct timeval *period)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_POLL_SET_MODE, (sysarg_t) mode, period != NULL, NULL);
+	
+	int rc;
+	if (period)
+		rc = async_data_write_start(exch, period, sizeof(struct timeval));
+	else
+		rc = EOK;
+	
+	async_exchange_end(exch);
+	
+	sysarg_t res;
+	async_wait_for(message_id, &res);
+	
+	if (rc != EOK)
+		return rc;
+	
+	return (int) res;
+}
+
+/** Request the driver to poll the NIC.
+ *
+ * @param[in] dev_sess
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_poll_now(async_sess_t *dev_sess)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_POLL_NOW);
+	async_exchange_end(exch);
+	
+	return rc;
+}
 
 static void remote_nic_send_frame(ddf_fun_t *dev, void *iface,
@@ -1198,46 +2490,46 @@
  *
  */
-static remote_iface_func_ptr_t remote_nic_iface_ops[] = {
-	&remote_nic_send_frame,
-	&remote_nic_callback_create,
-	&remote_nic_get_state,
-	&remote_nic_set_state,
-	&remote_nic_get_address,
-	&remote_nic_set_address,
-	&remote_nic_get_stats,
-	&remote_nic_get_device_info,
-	&remote_nic_get_cable_state,
-	&remote_nic_get_operation_mode,
-	&remote_nic_set_operation_mode,
-	&remote_nic_autoneg_enable,
-	&remote_nic_autoneg_disable,
-	&remote_nic_autoneg_probe,
-	&remote_nic_autoneg_restart,
-	&remote_nic_get_pause,
-	&remote_nic_set_pause,
-	&remote_nic_unicast_get_mode,
-	&remote_nic_unicast_set_mode,
-	&remote_nic_multicast_get_mode,
-	&remote_nic_multicast_set_mode,
-	&remote_nic_broadcast_get_mode,
-	&remote_nic_broadcast_set_mode,
-	&remote_nic_defective_get_mode,
-	&remote_nic_defective_set_mode,
-	&remote_nic_blocked_sources_get,
-	&remote_nic_blocked_sources_set,
-	&remote_nic_vlan_get_mask,
-	&remote_nic_vlan_set_mask,
-	&remote_nic_vlan_set_tag,
-	&remote_nic_wol_virtue_add,
-	&remote_nic_wol_virtue_remove,
-	&remote_nic_wol_virtue_probe,
-	&remote_nic_wol_virtue_list,
-	&remote_nic_wol_virtue_get_caps,
-	&remote_nic_wol_load_info,
-	&remote_nic_offload_probe,
-	&remote_nic_offload_set,
-	&remote_nic_poll_get_mode,
-	&remote_nic_poll_set_mode,
-	&remote_nic_poll_now
+static const remote_iface_func_ptr_t remote_nic_iface_ops[] = {
+	[NIC_SEND_MESSAGE] = remote_nic_send_frame,
+	[NIC_CALLBACK_CREATE] = remote_nic_callback_create,
+	[NIC_GET_STATE] = remote_nic_get_state,
+	[NIC_SET_STATE] = remote_nic_set_state,
+	[NIC_GET_ADDRESS] = remote_nic_get_address,
+	[NIC_SET_ADDRESS] = remote_nic_set_address,
+	[NIC_GET_STATS] = remote_nic_get_stats,
+	[NIC_GET_DEVICE_INFO] = remote_nic_get_device_info,
+	[NIC_GET_CABLE_STATE] = remote_nic_get_cable_state,
+	[NIC_GET_OPERATION_MODE] = remote_nic_get_operation_mode,
+	[NIC_SET_OPERATION_MODE] = remote_nic_set_operation_mode,
+	[NIC_AUTONEG_ENABLE] = remote_nic_autoneg_enable,
+	[NIC_AUTONEG_DISABLE] = remote_nic_autoneg_disable,
+	[NIC_AUTONEG_PROBE] = remote_nic_autoneg_probe,
+	[NIC_AUTONEG_RESTART] = remote_nic_autoneg_restart,
+	[NIC_GET_PAUSE] = remote_nic_get_pause,
+	[NIC_SET_PAUSE] = remote_nic_set_pause,
+	[NIC_UNICAST_GET_MODE] = remote_nic_unicast_get_mode,
+	[NIC_UNICAST_SET_MODE] = remote_nic_unicast_set_mode,
+	[NIC_MULTICAST_GET_MODE] = remote_nic_multicast_get_mode,
+	[NIC_MULTICAST_SET_MODE] = remote_nic_multicast_set_mode,
+	[NIC_BROADCAST_GET_MODE] = remote_nic_broadcast_get_mode,
+	[NIC_BROADCAST_SET_MODE] = remote_nic_broadcast_set_mode,
+	[NIC_DEFECTIVE_GET_MODE] = remote_nic_defective_get_mode,
+	[NIC_DEFECTIVE_SET_MODE] = remote_nic_defective_set_mode,
+	[NIC_BLOCKED_SOURCES_GET] = remote_nic_blocked_sources_get,
+	[NIC_BLOCKED_SOURCES_SET] = remote_nic_blocked_sources_set,
+	[NIC_VLAN_GET_MASK] = remote_nic_vlan_get_mask,
+	[NIC_VLAN_SET_MASK] = remote_nic_vlan_set_mask,
+	[NIC_VLAN_SET_TAG] = remote_nic_vlan_set_tag,
+	[NIC_WOL_VIRTUE_ADD] = remote_nic_wol_virtue_add,
+	[NIC_WOL_VIRTUE_REMOVE] = remote_nic_wol_virtue_remove,
+	[NIC_WOL_VIRTUE_PROBE] = remote_nic_wol_virtue_probe,
+	[NIC_WOL_VIRTUE_LIST] = remote_nic_wol_virtue_list,
+	[NIC_WOL_VIRTUE_GET_CAPS] = remote_nic_wol_virtue_get_caps,
+	[NIC_WOL_LOAD_INFO] = remote_nic_wol_load_info,
+	[NIC_OFFLOAD_PROBE] = remote_nic_offload_probe,
+	[NIC_OFFLOAD_SET] = remote_nic_offload_set,
+	[NIC_POLL_GET_MODE] = remote_nic_poll_get_mode,
+	[NIC_POLL_SET_MODE] = remote_nic_poll_set_mode,
+	[NIC_POLL_NOW] = remote_nic_poll_now
 };
 
@@ -1248,7 +2540,6 @@
  *
  */
-remote_iface_t remote_nic_iface = {
-	.method_count = sizeof(remote_nic_iface_ops) /
-	    sizeof(remote_iface_func_ptr_t),
+const remote_iface_t remote_nic_iface = {
+	.method_count = ARRAY_SIZE(remote_nic_iface_ops),
 	.methods = remote_nic_iface_ops
 };
Index: uspace/lib/drv/generic/remote_pci.c
===================================================================
--- uspace/lib/drv/generic/remote_pci.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_pci.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -36,7 +36,91 @@
 #include <async.h>
 #include <errno.h>
+#include <macros.h>
 
 #include "pci_dev_iface.h"
 #include "ddf/driver.h"
+
+typedef enum {
+	IPC_M_CONFIG_SPACE_READ_8,
+	IPC_M_CONFIG_SPACE_READ_16,
+	IPC_M_CONFIG_SPACE_READ_32,
+
+	IPC_M_CONFIG_SPACE_WRITE_8,
+	IPC_M_CONFIG_SPACE_WRITE_16,
+	IPC_M_CONFIG_SPACE_WRITE_32
+} pci_dev_iface_funcs_t;
+
+int pci_config_space_read_8(async_sess_t *sess, uint32_t address, uint8_t *val)
+{
+	sysarg_t res = 0;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
+	    IPC_M_CONFIG_SPACE_READ_8, address, &res);
+	async_exchange_end(exch);
+	
+	*val = (uint8_t) res;
+	return rc;
+}
+
+int pci_config_space_read_16(async_sess_t *sess, uint32_t address,
+    uint16_t *val)
+{
+	sysarg_t res = 0;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
+	    IPC_M_CONFIG_SPACE_READ_16, address, &res);
+	async_exchange_end(exch);
+	
+	*val = (uint16_t) res;
+	return rc;
+}
+
+int pci_config_space_read_32(async_sess_t *sess, uint32_t address,
+    uint32_t *val)
+{
+	sysarg_t res = 0;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
+	    IPC_M_CONFIG_SPACE_READ_32, address, &res);
+	async_exchange_end(exch);
+	
+	*val = (uint32_t) res;
+	return rc;
+}
+
+int pci_config_space_write_8(async_sess_t *sess, uint32_t address, uint8_t val)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
+	    IPC_M_CONFIG_SPACE_WRITE_8, address, val);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+int pci_config_space_write_16(async_sess_t *sess, uint32_t address,
+    uint16_t val)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
+	    IPC_M_CONFIG_SPACE_WRITE_16, address, val);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+int pci_config_space_write_32(async_sess_t *sess, uint32_t address,
+    uint32_t val)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
+	    IPC_M_CONFIG_SPACE_WRITE_32, address, val);
+	async_exchange_end(exch);
+	
+	return rc;
+}
 
 static void remote_config_space_read_8(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
@@ -49,19 +133,18 @@
 
 /** Remote USB interface operations. */
-static remote_iface_func_ptr_t remote_pci_iface_ops [] = {
-	remote_config_space_read_8,
-	remote_config_space_read_16,
-	remote_config_space_read_32,
-
-	remote_config_space_write_8,
-	remote_config_space_write_16,
-	remote_config_space_write_32
+static const remote_iface_func_ptr_t remote_pci_iface_ops [] = {
+	[IPC_M_CONFIG_SPACE_READ_8] = remote_config_space_read_8,
+	[IPC_M_CONFIG_SPACE_READ_16] = remote_config_space_read_16,
+	[IPC_M_CONFIG_SPACE_READ_32] = remote_config_space_read_32,
+
+	[IPC_M_CONFIG_SPACE_WRITE_8] = remote_config_space_write_8,
+	[IPC_M_CONFIG_SPACE_WRITE_16] = remote_config_space_write_16,
+	[IPC_M_CONFIG_SPACE_WRITE_32] = remote_config_space_write_32
 };
 
 /** Remote USB interface structure.
  */
-remote_iface_t remote_pci_iface = {
-	.method_count = sizeof(remote_pci_iface_ops) /
-	    sizeof(remote_pci_iface_ops[0]),
+const remote_iface_t remote_pci_iface = {
+	.method_count = ARRAY_SIZE(remote_pci_iface_ops),
 	.methods = remote_pci_iface_ops
 };
Index: uspace/lib/drv/generic/remote_pio_window.c
===================================================================
--- uspace/lib/drv/generic/remote_pio_window.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_pio_window.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -35,4 +35,5 @@
 #include <async.h>
 #include <errno.h>
+#include <macros.h>
 
 #include "ops/pio_window.h"
@@ -42,11 +43,10 @@
     ipc_call_t *);
 
-static remote_iface_func_ptr_t remote_pio_window_iface_ops [] = {
+static const remote_iface_func_ptr_t remote_pio_window_iface_ops [] = {
 	[PIO_WINDOW_GET] = &remote_pio_window_get
 };
 
-remote_iface_t remote_pio_window_iface = {
-	.method_count = sizeof(remote_pio_window_iface_ops) /
-	    sizeof(remote_iface_func_ptr_t),
+const remote_iface_t remote_pio_window_iface = {
+	.method_count = ARRAY_SIZE(remote_pio_window_iface_ops),
 	.methods = remote_pio_window_iface_ops
 };
Index: uspace/lib/drv/generic/remote_usb.c
===================================================================
--- uspace/lib/drv/generic/remote_usb.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_usb.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -36,4 +36,5 @@
 #include <async.h>
 #include <errno.h>
+#include <macros.h>
 
 #include "usb_iface.h"
@@ -107,5 +108,5 @@
 
 /** Remote USB interface operations. */
-static remote_iface_func_ptr_t remote_usb_iface_ops [] = {
+static const remote_iface_func_ptr_t remote_usb_iface_ops [] = {
 	[IPC_M_USB_GET_MY_ADDRESS] = remote_usb_get_my_address,
 	[IPC_M_USB_GET_MY_INTERFACE] = remote_usb_get_my_interface,
@@ -115,7 +116,6 @@
 /** Remote USB interface structure.
  */
-remote_iface_t remote_usb_iface = {
-	.method_count = sizeof(remote_usb_iface_ops) /
-	    sizeof(remote_usb_iface_ops[0]),
+const remote_iface_t remote_usb_iface = {
+	.method_count = ARRAY_SIZE(remote_usb_iface_ops),
 	.methods = remote_usb_iface_ops
 };
Index: uspace/lib/drv/generic/remote_usbhc.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhc.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_usbhc.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -37,4 +37,5 @@
 #include <errno.h>
 #include <assert.h>
+#include <macros.h>
 
 #include "usbhc_iface.h"
@@ -334,5 +335,5 @@
 
 /** Remote USB host controller interface operations. */
-static remote_iface_func_ptr_t remote_usbhc_iface_ops[] = {
+static const remote_iface_func_ptr_t remote_usbhc_iface_ops[] = {
 	[IPC_M_USBHC_REQUEST_ADDRESS] = remote_usbhc_request_address,
 	[IPC_M_USBHC_RELEASE_ADDRESS] = remote_usbhc_release_address,
@@ -349,7 +350,6 @@
 /** Remote USB host controller interface structure.
  */
-remote_iface_t remote_usbhc_iface = {
-	.method_count = sizeof(remote_usbhc_iface_ops) /
-	    sizeof(remote_usbhc_iface_ops[0]),
+const remote_iface_t remote_usbhc_iface = {
+	.method_count = ARRAY_SIZE(remote_usbhc_iface_ops),
 	.methods = remote_usbhc_iface_ops
 };
Index: uspace/lib/drv/generic/remote_usbhid.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhid.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_usbhid.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -37,7 +37,249 @@
 #include <assert.h>
 #include <stdio.h>
+#include <macros.h>
 
 #include "usbhid_iface.h"
 #include "ddf/driver.h"
+
+/** IPC methods for USB HID device interface. */
+typedef enum {
+	/** Get number of events reported in single burst.
+	 * Parameters: none
+	 * Answer:
+	 * - Size of one report in bytes.
+	 */
+	IPC_M_USBHID_GET_EVENT_LENGTH,
+	/** Get single event from the HID device.
+	 * The word single refers to set of individual events that were
+	 * available at particular point in time.
+	 * Parameters:
+	 * - flags
+	 * The call is followed by data read expecting two concatenated
+	 * arrays.
+	 * Answer:
+	 * - EOK - events returned
+	 * - EAGAIN - no event ready (only in non-blocking mode)
+	 *
+	 * It is okay if the client requests less data. Extra data must
+	 * be truncated by the driver.
+	 *
+	 * @todo Change this comment.
+	 */
+	IPC_M_USBHID_GET_EVENT,
+	
+	/** Get the size of the report descriptor from the HID device.
+	 *
+	 * Parameters:
+	 * - none
+	 * Answer:
+	 * - EOK - method is implemented (expected always)
+	 * Parameters of the answer:
+	 * - Size of the report in bytes.
+	 */
+	IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH,
+	
+	/** Get the report descriptor from the HID device.
+	 *
+	 * Parameters:
+	 * - none
+	 * The call is followed by data read expecting the descriptor itself.
+	 * Answer:
+	 * - EOK - report descriptor returned.
+	 */
+	IPC_M_USBHID_GET_REPORT_DESCRIPTOR
+} usbhid_iface_funcs_t;
+
+/** Ask for event array length.
+ *
+ * @param dev_sess Session to DDF device providing USB HID interface.
+ *
+ * @return Number of usages returned or negative error code.
+ *
+ */
+int usbhid_dev_get_event_length(async_sess_t *dev_sess, size_t *size)
+{
+	if (!dev_sess)
+		return EINVAL;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	sysarg_t len;
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(USBHID_DEV_IFACE),
+	    IPC_M_USBHID_GET_EVENT_LENGTH, &len);
+	
+	async_exchange_end(exch);
+	
+	if (rc == EOK) {
+		if (size != NULL)
+			*size = (size_t) len;
+	}
+	
+	return rc;
+}
+
+/** Request for next event from HID device.
+ *
+ * @param[in]  dev_sess    Session to DDF device providing USB HID interface.
+ * @param[out] usage_pages Where to store usage pages.
+ * @param[out] usages      Where to store usages (actual data).
+ * @param[in]  usage_count Length of @p usage_pages and @p usages buffer
+ *                         (in items, not bytes).
+ * @param[out] actual_usage_count Number of usages actually returned by the
+ *                                device driver.
+ * @param[in] flags        Flags (see USBHID_IFACE_FLAG_*).
+ *
+ * @return Error code.
+ *
+ */
+int usbhid_dev_get_event(async_sess_t *dev_sess, uint8_t *buf,
+    size_t size, size_t *actual_size, int *event_nr, unsigned int flags)
+{
+	if (!dev_sess)
+		return EINVAL;
+	
+	if (buf == NULL)
+		return ENOMEM;
+	
+	if (size == 0)
+		return EINVAL;
+	
+	size_t buffer_size =  size;
+	uint8_t *buffer = malloc(buffer_size);
+	if (buffer == NULL)
+		return ENOMEM;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	ipc_call_t opening_request_call;
+	aid_t opening_request = async_send_2(exch,
+	    DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_EVENT,
+	    flags, &opening_request_call);
+	
+	if (opening_request == 0) {
+		async_exchange_end(exch);
+		free(buffer);
+		return ENOMEM;
+	}
+	
+	ipc_call_t data_request_call;
+	aid_t data_request = async_data_read(exch, buffer, buffer_size,
+	    &data_request_call);
+	
+	async_exchange_end(exch);
+	
+	if (data_request == 0) {
+		async_forget(opening_request);
+		free(buffer);
+		return ENOMEM;
+	}
+	
+	sysarg_t data_request_rc;
+	sysarg_t opening_request_rc;
+	async_wait_for(data_request, &data_request_rc);
+	async_wait_for(opening_request, &opening_request_rc);
+	
+	if (data_request_rc != EOK) {
+		/* Prefer return code of the opening request. */
+		if (opening_request_rc != EOK)
+			return (int) opening_request_rc;
+		else
+			return (int) data_request_rc;
+	}
+	
+	if (opening_request_rc != EOK)
+		return (int) opening_request_rc;
+	
+	size_t act_size = IPC_GET_ARG2(data_request_call);
+	
+	/* Copy the individual items. */
+	memcpy(buf, buffer, act_size);
+	
+	if (actual_size != NULL)
+		*actual_size = act_size;
+	
+	if (event_nr != NULL)
+		*event_nr = IPC_GET_ARG1(opening_request_call);
+	
+	return EOK;
+}
+
+int usbhid_dev_get_report_descriptor_length(async_sess_t *dev_sess,
+    size_t *size)
+{
+	if (!dev_sess)
+		return EINVAL;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	sysarg_t arg_size;
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(USBHID_DEV_IFACE),
+	    IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH, &arg_size);
+	
+	async_exchange_end(exch);
+	
+	if (rc == EOK) {
+		if (size != NULL)
+			*size = (size_t) arg_size;
+	}
+	
+	return rc;
+}
+
+int usbhid_dev_get_report_descriptor(async_sess_t *dev_sess, uint8_t *buf,
+    size_t size, size_t *actual_size)
+{
+	if (!dev_sess)
+		return EINVAL;
+	
+	if (buf == NULL)
+		return ENOMEM;
+	
+	if (size == 0)
+		return EINVAL;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	aid_t opening_request = async_send_1(exch,
+	    DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_REPORT_DESCRIPTOR,
+	    NULL);
+	if (opening_request == 0) {
+		async_exchange_end(exch);
+		return ENOMEM;
+	}
+	
+	ipc_call_t data_request_call;
+	aid_t data_request = async_data_read(exch, buf, size,
+	    &data_request_call);
+	
+	async_exchange_end(exch);
+	
+	if (data_request == 0) {
+		async_forget(opening_request);
+		return ENOMEM;
+	}
+	
+	sysarg_t data_request_rc;
+	sysarg_t opening_request_rc;
+	async_wait_for(data_request, &data_request_rc);
+	async_wait_for(opening_request, &opening_request_rc);
+	
+	if (data_request_rc != EOK) {
+		/* Prefer return code of the opening request. */
+		if (opening_request_rc != EOK)
+			return (int) opening_request_rc;
+		else
+			return (int) data_request_rc;
+	}
+	
+	if (opening_request_rc != EOK)
+		return (int) opening_request_rc;
+	
+	size_t act_size = IPC_GET_ARG2(data_request_call);
+	
+	if (actual_size != NULL)
+		*actual_size = act_size;
+	
+	return EOK;
+}
 
 static void remote_usbhid_get_event_length(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
@@ -48,16 +290,16 @@
 
 /** Remote USB HID interface operations. */
-static remote_iface_func_ptr_t remote_usbhid_iface_ops [] = {
-	remote_usbhid_get_event_length,
-	remote_usbhid_get_event,
-	remote_usbhid_get_report_descriptor_length,
-	remote_usbhid_get_report_descriptor
+static const remote_iface_func_ptr_t remote_usbhid_iface_ops [] = {
+	[IPC_M_USBHID_GET_EVENT_LENGTH] = remote_usbhid_get_event_length,
+	[IPC_M_USBHID_GET_EVENT] = remote_usbhid_get_event,
+	[IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH] =
+	    remote_usbhid_get_report_descriptor_length,
+	[IPC_M_USBHID_GET_REPORT_DESCRIPTOR] = remote_usbhid_get_report_descriptor
 };
 
 /** Remote USB HID interface structure.
  */
-remote_iface_t remote_usbhid_iface = {
-	.method_count = sizeof(remote_usbhid_iface_ops) /
-	    sizeof(remote_usbhid_iface_ops[0]),
+const remote_iface_t remote_usbhid_iface = {
+	.method_count = ARRAY_SIZE(remote_usbhid_iface_ops),
 	.methods = remote_usbhid_iface_ops
 };
Index: uspace/lib/drv/include/ahci_iface.h
===================================================================
--- uspace/lib/drv/include/ahci_iface.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/include/ahci_iface.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -41,4 +41,12 @@
 #include <async.h>
 
+extern async_sess_t* ahci_get_sess(devman_handle_t, char **);
+
+extern int ahci_get_sata_device_name(async_sess_t *, size_t, char *);
+extern int ahci_get_num_blocks(async_sess_t *, uint64_t *);
+extern int ahci_get_block_size(async_sess_t *, size_t *);
+extern int ahci_read_blocks(async_sess_t *, uint64_t, size_t, void *);
+extern int ahci_write_blocks(async_sess_t *, uint64_t, size_t, void *);
+
 /** AHCI device communication interface. */
 typedef struct {
Index: uspace/lib/drv/include/battery_iface.h
===================================================================
--- uspace/lib/drv/include/battery_iface.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/include/battery_iface.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,55 @@
+/*
+ * 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_BATTERY_IFACE_H_
+#define LIBDRV_BATTERY_IFACE_H_
+
+#include <async.h>
+
+typedef enum {
+	BATTERY_OK,
+	BATTERY_LOW,
+	BATTERY_NOT_PRESENT,
+} battery_status_t;
+
+typedef enum {
+	BATTERY_STATUS_GET = 0,
+	BATTERY_CHARGE_LEVEL_GET,
+} battery_dev_method_t;
+
+extern int battery_status_get(async_sess_t *, battery_status_t *);
+extern int battery_charge_level_get(async_sess_t *, int *);
+
+#endif
+
Index: uspace/lib/drv/include/char_dev_iface.h
===================================================================
--- uspace/lib/drv/include/char_dev_iface.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/include/char_dev_iface.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_CHAR_DEV_IFACE_H_
+#define LIBDRV_CHAR_DEV_IFACE_H_
+
+#include <async.h>
+
+typedef enum {
+	CHAR_DEV_READ = 0,
+	CHAR_DEV_WRITE
+} char_dev_method_t;
+
+extern ssize_t char_dev_read(async_sess_t *, void *, size_t);
+extern ssize_t char_dev_write(async_sess_t *, void *, size_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/drv/include/ddf/driver.h
===================================================================
--- uspace/lib/drv/include/ddf/driver.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/include/ddf/driver.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -108,5 +108,5 @@
 	const char *name;
 	/** Generic device driver operations */
-	driver_ops_t *driver_ops;
+	const driver_ops_t *driver_ops;
 } driver_t;
 
@@ -116,5 +116,5 @@
 #endif
 
-extern int ddf_driver_main(driver_t *);
+extern int ddf_driver_main(const driver_t *);
 
 extern void *ddf_dev_data_alloc(ddf_dev_t *, size_t);
Index: uspace/lib/drv/include/ddf/interrupt.h
===================================================================
--- uspace/lib/drv/include/ddf/interrupt.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/include/ddf/interrupt.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -67,5 +67,5 @@
 extern void interrupt_init(void);
 extern int register_interrupt_handler(ddf_dev_t *, int, interrupt_handler_t *,
-    irq_code_t *);
+    const irq_code_t *);
 extern int unregister_interrupt_handler(ddf_dev_t *, int);
 
Index: uspace/lib/drv/include/dev_iface.h
===================================================================
--- uspace/lib/drv/include/dev_iface.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/include/dev_iface.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -55,14 +55,14 @@
 
 typedef struct {
-	size_t method_count;
-	remote_iface_func_ptr_t *methods;
+	const size_t method_count;
+	const remote_iface_func_ptr_t *methods;
 } remote_iface_t;
 
 typedef struct {
-	remote_iface_t *ifaces[DEV_IFACE_COUNT];
+	const remote_iface_t *ifaces[DEV_IFACE_COUNT];
 } iface_dipatch_table_t;
 
-extern remote_iface_t *get_remote_iface(int);
-extern remote_iface_func_ptr_t get_remote_method(remote_iface_t *, sysarg_t);
+extern const remote_iface_t *get_remote_iface(int);
+extern remote_iface_func_ptr_t get_remote_method(const remote_iface_t *, sysarg_t);
 
 
Index: uspace/lib/drv/include/graph_iface.h
===================================================================
--- uspace/lib/drv/include/graph_iface.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/include/graph_iface.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011 Petr Koupy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_DEVICE_GRAPH_DEV_H_
+#define LIBC_DEVICE_GRAPH_DEV_H_
+
+#include <async.h>
+
+extern int graph_dev_connect(async_sess_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/drv/include/nic_iface.h
===================================================================
--- uspace/lib/drv/include/nic_iface.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/drv/include/nic_iface.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2010 Radim Vansa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ /** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_NIC_IFACE_H_
+#define LIBDRV_NIC_IFACE_H_
+
+#include <async.h>
+#include <nic/nic.h>
+#include <ipc/common.h>
+
+
+typedef enum {
+	NIC_EV_ADDR_CHANGED = IPC_FIRST_USER_METHOD,
+	NIC_EV_RECEIVED,
+	NIC_EV_DEVICE_STATE
+} nic_event_t;
+
+extern int nic_send_frame(async_sess_t *, void *, size_t);
+extern int nic_callback_create(async_sess_t *, async_client_conn_t, void *);
+extern int nic_get_state(async_sess_t *, nic_device_state_t *);
+extern int nic_set_state(async_sess_t *, nic_device_state_t);
+extern int nic_get_address(async_sess_t *, nic_address_t *);
+extern int nic_set_address(async_sess_t *, const nic_address_t *);
+extern int nic_get_stats(async_sess_t *, nic_device_stats_t *);
+extern int nic_get_device_info(async_sess_t *, nic_device_info_t *);
+extern int nic_get_cable_state(async_sess_t *, nic_cable_state_t *);
+
+extern int nic_get_operation_mode(async_sess_t *, int *, nic_channel_mode_t *,
+    nic_role_t *);
+extern int nic_set_operation_mode(async_sess_t *, int, nic_channel_mode_t,
+    nic_role_t);
+extern int nic_autoneg_enable(async_sess_t *, uint32_t);
+extern int nic_autoneg_disable(async_sess_t *);
+extern int nic_autoneg_probe(async_sess_t *, uint32_t *, uint32_t *,
+    nic_result_t *, nic_result_t *);
+extern int nic_autoneg_restart(async_sess_t *);
+extern int nic_get_pause(async_sess_t *, nic_result_t *, nic_result_t *,
+    uint16_t *);
+extern int nic_set_pause(async_sess_t *, int, int, uint16_t);
+
+extern int nic_unicast_get_mode(async_sess_t *, nic_unicast_mode_t *, size_t,
+    nic_address_t *, size_t *);
+extern int nic_unicast_set_mode(async_sess_t *, nic_unicast_mode_t,
+    const nic_address_t *, size_t);
+extern int nic_multicast_get_mode(async_sess_t *, nic_multicast_mode_t *,
+    size_t, nic_address_t *, size_t *);
+extern int nic_multicast_set_mode(async_sess_t *, nic_multicast_mode_t,
+    const nic_address_t *, size_t);
+extern int nic_broadcast_get_mode(async_sess_t *, nic_broadcast_mode_t *);
+extern int nic_broadcast_set_mode(async_sess_t *, nic_broadcast_mode_t);
+extern int nic_defective_get_mode(async_sess_t *, uint32_t *);
+extern int nic_defective_set_mode(async_sess_t *, uint32_t);
+extern int nic_blocked_sources_get(async_sess_t *, size_t, nic_address_t *,
+    size_t *);
+extern int nic_blocked_sources_set(async_sess_t *, const nic_address_t *,
+    size_t);
+
+extern int nic_vlan_get_mask(async_sess_t *, nic_vlan_mask_t *);
+extern int nic_vlan_set_mask(async_sess_t *, const nic_vlan_mask_t *);
+extern int nic_vlan_set_tag(async_sess_t *, uint16_t, bool, bool);
+
+extern int nic_wol_virtue_add(async_sess_t *, nic_wv_type_t, const void *,
+    size_t, nic_wv_id_t *);
+extern int nic_wol_virtue_remove(async_sess_t *, nic_wv_id_t);
+extern int nic_wol_virtue_probe(async_sess_t *, nic_wv_id_t, nic_wv_type_t *,
+    size_t, void *, size_t *);
+extern int nic_wol_virtue_list(async_sess_t *, nic_wv_type_t, size_t,
+    nic_wv_id_t *, size_t *);
+extern int nic_wol_virtue_get_caps(async_sess_t *, nic_wv_type_t, int *);
+extern int nic_wol_load_info(async_sess_t *, nic_wv_type_t *, size_t, uint8_t *,
+    size_t *);
+
+extern int nic_offload_probe(async_sess_t *, uint32_t *, uint32_t *);
+extern int nic_offload_set(async_sess_t *, uint32_t, uint32_t);
+
+extern int nic_poll_get_mode(async_sess_t *, nic_poll_mode_t *,
+    struct timeval *);
+extern int nic_poll_set_mode(async_sess_t *, nic_poll_mode_t,
+    const struct timeval *);
+extern int nic_poll_now(async_sess_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/drv/include/ops/battery_dev.h
===================================================================
--- uspace/lib/drv/include/ops/battery_dev.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/include/ops/battery_dev.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -37,5 +37,5 @@
 
 #include "../ddf/driver.h"
-#include "device/battery_dev.h"
+#include "battery_iface.h"
 
 typedef struct {
Index: uspace/lib/drv/include/pci_dev_iface.h
===================================================================
--- uspace/lib/drv/include/pci_dev_iface.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/include/pci_dev_iface.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -40,13 +40,13 @@
 #include "ddf/driver.h"
 
-typedef enum {
-	IPC_M_CONFIG_SPACE_READ_8,
-	IPC_M_CONFIG_SPACE_READ_16,
-	IPC_M_CONFIG_SPACE_READ_32,
+#define PCI_DEVICE_ID  0x02
 
-	IPC_M_CONFIG_SPACE_WRITE_8,
-	IPC_M_CONFIG_SPACE_WRITE_16,
-	IPC_M_CONFIG_SPACE_WRITE_32
-} pci_dev_iface_funcs_t;
+extern int pci_config_space_read_8(async_sess_t *, uint32_t, uint8_t *);
+extern int pci_config_space_read_16(async_sess_t *, uint32_t, uint16_t *);
+extern int pci_config_space_read_32(async_sess_t *, uint32_t, uint32_t *);
+
+extern int pci_config_space_write_8(async_sess_t *, uint32_t, uint8_t);
+extern int pci_config_space_write_16(async_sess_t *, uint32_t, uint16_t);
+extern int pci_config_space_write_32(async_sess_t *, uint32_t, uint32_t);
 
 /** PCI device communication interface. */
Index: uspace/lib/drv/include/remote_ahci.h
===================================================================
--- uspace/lib/drv/include/remote_ahci.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2012 Petr Jerman
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_AHCI_H_
-#define LIBDRV_REMOTE_AHCI_H_
-
-extern remote_iface_t remote_ahci_iface;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/lib/drv/include/remote_audio_mixer.h
===================================================================
--- uspace/lib/drv/include/remote_audio_mixer.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,45 +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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_AUDIO_MIXER_H_
-#define LIBDRV_REMOTE_AUDIO_MIXER_H_
-
-extern remote_iface_t remote_audio_mixer_iface;
-
-#endif
-
-/**
- * @}
- */
-
Index: uspace/lib/drv/include/remote_audio_pcm.h
===================================================================
--- uspace/lib/drv/include/remote_audio_pcm.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_AUDIO_PCM_H_
-#define LIBDRV_REMOTE_AUDIO_PCM_H_
-
-extern remote_iface_t remote_audio_pcm_iface;
-
-#endif
-
-/**
- * @}
- */
-
Index: uspace/lib/drv/include/remote_battery_dev.h
===================================================================
--- uspace/lib/drv/include/remote_battery_dev.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/*
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_BATTERY_DEV_H_
-#define LIBDRV_REMOTE_BATTERY_DEV_H_
-
-extern remote_iface_t remote_battery_dev_iface;
-
-#endif
-
-/**
- * @}
- */
-
Index: uspace/lib/drv/include/remote_char_dev.h
===================================================================
--- uspace/lib/drv/include/remote_char_dev.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2010 Lenka Trochtova
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_CHAR_DEV_H_
-#define LIBDRV_REMOTE_CHAR_DEV_H_
-
-extern remote_iface_t remote_char_dev_iface;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/lib/drv/include/remote_clock_dev.h
===================================================================
--- uspace/lib/drv/include/remote_clock_dev.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/*
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_CLOCK_DEV_H_
-#define LIBDRV_REMOTE_CLOCK_DEV_H_
-
-extern remote_iface_t remote_clock_dev_iface;
-
-#endif
-
-/**
- * @}
- */
-
Index: uspace/lib/drv/include/remote_graph_dev.h
===================================================================
--- uspace/lib/drv/include/remote_graph_dev.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2011 Petr Koupy
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_GRAPH_DEV_H_
-#define LIBDRV_REMOTE_GRAPH_DEV_H_
-
-extern remote_iface_t remote_graph_dev_iface;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/lib/drv/include/remote_hw_res.h
===================================================================
--- uspace/lib/drv/include/remote_hw_res.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2010 Lenka Trochtova
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_HW_RES_H_
-#define LIBDRV_REMOTE_HW_RES_H_
-
-extern remote_iface_t remote_hw_res_iface;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/lib/drv/include/remote_nic.h
===================================================================
--- uspace/lib/drv/include/remote_nic.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2011 Radim Vansa
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_NIC_H_
-#define LIBDRV_REMOTE_NIC_H_
-
-extern remote_iface_t remote_nic_iface;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/lib/drv/include/remote_pci.h
===================================================================
--- uspace/lib/drv/include/remote_pci.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,45 +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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_PCI_H_
-#define LIBDRV_REMOTE_PCI_H_
-
-extern remote_iface_t remote_pci_iface;
-
-#endif
-
-/**
- * @}
- */
-
Index: uspace/lib/drv/include/remote_pio_window.h
===================================================================
--- uspace/lib/drv/include/remote_pio_window.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2013 Jakub Jermar 
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_PIO_WINDOW_H_
-#define LIBDRV_REMOTE_PIO_WINDOW_H_
-
-extern remote_iface_t remote_pio_window_iface;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/lib/drv/include/remote_usb.h
===================================================================
--- uspace/lib/drv/include/remote_usb.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_USB_H_
-#define LIBDRV_REMOTE_USB_H_
-
-extern remote_iface_t remote_usb_iface;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/lib/drv/include/remote_usbhc.h
===================================================================
--- uspace/lib/drv/include/remote_usbhc.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_USBHC_H_
-#define LIBDRV_REMOTE_USBHC_H_
-
-extern remote_iface_t remote_usbhc_iface;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/lib/drv/include/remote_usbhid.h
===================================================================
--- uspace/lib/drv/include/remote_usbhid.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_USBHID_H_
-#define LIBDRV_REMOTE_USBHID_H_
-
-extern remote_iface_t remote_usbhid_iface;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/lib/drv/include/usbhid_iface.h
===================================================================
--- uspace/lib/drv/include/usbhid_iface.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/include/usbhid_iface.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -40,54 +40,10 @@
 #include <usb/usb.h>
 
-/** IPC methods for USB HID device interface. */
-typedef enum {
-	/** Get number of events reported in single burst.
-	 * Parameters: none
-	 * Answer:
-	 * - Size of one report in bytes.
-	 */
-	IPC_M_USBHID_GET_EVENT_LENGTH,
-	/** Get single event from the HID device.
-	 * The word single refers to set of individual events that were
-	 * available at particular point in time.
-	 * Parameters:
-	 * - flags
-	 * The call is followed by data read expecting two concatenated
-	 * arrays.
-	 * Answer:
-	 * - EOK - events returned
-	 * - EAGAIN - no event ready (only in non-blocking mode)
-	 *
-	 * It is okay if the client requests less data. Extra data must
-	 * be truncated by the driver.
-	 *
-	 * @todo Change this comment.
-	 */
-	IPC_M_USBHID_GET_EVENT,
-	
-	/** Get the size of the report descriptor from the HID device.
-	 *
-	 * Parameters:
-	 * - none
-	 * Answer:
-	 * - EOK - method is implemented (expected always)
-	 * Parameters of the answer:
-	 * - Size of the report in bytes.
-	 */
-	IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH,
-	
-	/** Get the report descriptor from the HID device.
-	 *
-	 * Parameters:
-	 * - none
-	 * The call is followed by data read expecting the descriptor itself.
-	 * Answer:
-	 * - EOK - report descriptor returned.
-	 */
-	IPC_M_USBHID_GET_REPORT_DESCRIPTOR
-} usbhid_iface_funcs_t;
-
-/** USB HID interface flag - return immediately if no data are available. */
-#define USBHID_IFACE_FLAG_NON_BLOCKING (1 << 0)
+extern int usbhid_dev_get_event_length(async_sess_t *, size_t *);
+extern int usbhid_dev_get_event(async_sess_t *, uint8_t *, size_t, size_t *,
+    int *, unsigned int);
+extern int usbhid_dev_get_report_descriptor_length(async_sess_t *, size_t *);
+extern int usbhid_dev_get_report_descriptor(async_sess_t *, uint8_t *, size_t,
+    size_t *);
 
 /** USB HID device communication interface. */
Index: uspace/lib/gpt/Makefile
===================================================================
--- uspace/lib/gpt/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/gpt/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2011 Dominik Taborsky
+# 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 = ../..
+EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX) -I$(LIBMBR_PREFIX)
+LIBRARY = libgpt
+
+SOURCES = \
+	libgpt.c \
+	global.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/gpt/global.c
===================================================================
--- uspace/lib/gpt/global.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/gpt/global.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2011-2013 Dominik Taborsky
+ * 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 libgpt
+ * @{
+ */
+/** @file
+ */
+
+#include "libgpt.h"
+
+/** GPT header signature ("EFI PART" in ASCII) */
+const uint8_t efi_signature[8] = {
+	0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54
+};
+
+const uint8_t revision[4] = {
+	00, 00, 01, 00
+};
+
+const partition_type_t gpt_ptypes[] = {
+	{ "unused entry",                 "00000000" "0000" "0000" "0000000000000000" }, /* 0 */
+	{ "HelenOS System",               "3dc61fa0" "cf7a" "3ad8" "ac57615029d81a6b" }, /* "HelenOS System" encoded as RFC 4122 UUID, version 3 (MD5 name-based) */
+	{ "MBR partition scheme",         "024dee41" "33e7" "11d3" "9d690008c781f39f" },
+	{ "EFI System",                   "c12a7328" "f81f" "11d2" "ba4b00a0c93ec93b" },
+	{ "BIOS Boot",                    "21686148" "6449" "6e6f" "744e656564454649" },
+	{ "Windows Reserved",             "e3c9e316" "0b5c" "4db8" "817df92df00215ae" },
+	{ "Windows Basic data",           "ebd0a0a2" "b9e5" "4433" "87c068b6b72699c7" },
+	{ "Windows LDM metadata",         "5808c8aa" "7e8f" "42e0" "85d2e1e90434cfb3" },
+	{ "Windows LDM data",             "af9b60a0" "1431" "4f62" "bc683311714a69ad" },
+	{ "Windows Recovery Environment", "de94bba4" "06d1" "4d40" "a16abfd50179d6ac" },
+	{ "Windows IBM GPFS",             "37affc90" "ef7d" "4e96" "91c32d7ae055b174" }, /* 10 */
+	{ "Windows Cluster metadata",     "db97dba9" "0840" "4bae" "97f0ffb9a327c7e1" },
+	{ "HP-UX Data",                   "75894c1e" "3aeb" "11d3" "b7c17b03a0000000" },
+	{ "HP-UX Service",                "e2a1e728" "32e3" "11d6" "a6827b03a0000000" },
+	{ "Linux filesystem data",        "0fc63daf" "8483" "4772" "8e793d69d8477de4" },
+	{ "Linux RAID",                   "a19d880f" "05fc" "4d3b" "a006743f0f84911e" },
+	{ "Linux Swap",                   "0657fd6d" "a4ab" "43c4" "84e50933c84b4f4f" },
+	{ "Linux LVM",                    "e6d6d379" "f507" "44c2" "a23c238f2a3df928" },
+	{ "Linux filesystem data",        "933ac7e1" "2eb4" "4f13" "b8440e14e2aef915" },
+	{ "Linux Reserved",               "8da63339" "0007" "60c0" "c436083ac8230908" },
+	{ "FreeBSD Boot",                 "83bd6b9d" "7f41" "11dc" "be0b001560b84f0f" }, /* 20 */
+	{ "FreeBSD Data",                 "516e7cb4" "6ecf" "11d6" "8ff800022d09712b" },
+	{ "FreeBSD Swap",                 "516e7cb5" "6ecf" "11d6" "8ff800022d09712b" },
+	{ "FreeBSD UFS",                  "516e7cb6" "6ecf" "11d6" "8ff800022d09712b" },
+	{ "FreeBSD Vinum VM",             "516e7cb8" "6ecf" "11d6" "8ff800022d09712b" },
+	{ "FreeBSD ZFS",                  "516e7cba" "6ecf" "11d6" "8ff800022d09712b" },
+	{ "Mac OS X HFS+",                "48465300" "0000" "11aa" "aa1100306543ecac" },
+	{ "Mac OS X UFS",                 "55465300" "0000" "11aa" "aa1100306543ecac" },
+	{ "Mac OS X ZFS",                 "6a898cc3" "1dd2" "11b2" "99a6080020736631" },
+	{ "Mac OS X RAID",                "52414944" "0000" "11aa" "aa1100306543ecac" },
+	{ "Mac OS X RAID, offline",       "52414944" "5f4f" "11aa" "aa1100306543ecac" }, /* 30 */
+	{ "Mac OS X Boot",                "426f6f74" "0000" "11aa" "aa1100306543ecac" },
+	{ "Mac OS X Label",               "4c616265" "6c00" "11aa" "aa1100306543ecac" },
+	{ "Mac OS X TV Recovery",         "5265636f" "7665" "11aa" "aa1100306543ecac" },
+	{ "Mac OS X Core Storage",        "53746f72" "6167" "11aa" "aa1100306543ecac" },
+	{ "Solaris Boot",                 "6a82cb45" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Root",                 "6a85cf4d" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Swap",                 "6a87c46f" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Backup",               "6a8b642b" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris /usr",                 "6a898cc3" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris /var",                 "6a8ef2e9" "1dd2" "11b2" "99a6080020736631" }, /* 40 */
+	{ "Solaris /home",                "6a90ba39" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Alternate sector",     "6a9283a5" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Reserved",             "6a945a3b" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Reserved",             "6a9630d1" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Reserved",             "6a980767" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Reserved",             "6a96237f" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Reserved",             "6a8d2ac7" "1dd2" "11b2" "99a6080020736631" },
+	{ "NetBSD Swap",                  "49f48d32" "b10e" "11dc" "b99b0019d1879648" },
+	{ "NetBSD FFS",                   "49f48d5a" "b10e" "11dc" "b99b0019d1879648" },
+	{ "NetBSD LFS",                   "49f48d82" "b10e" "11dc" "b99b0019d1879648" }, /* 50 */
+	{ "NetBSD RAID",                  "49f48daa" "b10e" "11dc" "b99b0019d1879648" },
+	{ "NetBSD Concatenated",          "2db519c4" "b10f" "11dc" "b99b0019d1879648" },
+	{ "NetBSD Encrypted",             "2db519ec" "b10f" "11dc" "b99b0019d1879648" },
+	{ "ChromeOS ChromeOS kernel",     "fe3a2a5d" "4f32" "41a7" "b725accc3285a309" },
+	{ "ChromeOS rootfs",              "3cb8e202" "3b7e" "47dd" "8a3c7ff2a13cfcec" },
+	{ "ChromeOS future use",          "2e0a753d" "9e48" "43b0" "8337b15192cb1b5e" },
+	{ "MidnightBSD Boot",             "85d5e45e" "237c" "11e1" "b4b3e89a8f7fc3a7" },
+	{ "MidnightBSD Data",             "85d5e45a" "237c" "11e1" "b4b3e89a8f7fc3a7" },
+	{ "MidnightBSD Swap",             "85d5e45b" "237c" "11e1" "b4b3e89a8f7fc3a7" },
+	{ "MidnightBSD UFS",              "0394ef8b" "237e" "11e1" "b4b3e89a8f7fc3a7" }, /* 60 */
+	{ "MidnightBSD Vinum VM",         "85d5e45c" "237c" "11e1" "b4b3e89a8f7fc3a7" },
+	{ "MidnightBSD ZFS",              "85d5e45d" "237c" "11e1" "b4b3e89a8f7fc3a7" },
+	{ "unknown entry",                NULL } /* Keep this as the last entry */
+};
Index: uspace/lib/gpt/gpt.h
===================================================================
--- uspace/lib/gpt/gpt.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/gpt/gpt.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * Copyright (c) 2011-2013 Dominik Taborsky
+ * 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 libgpt
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBGPT_GPT_H_
+#define LIBGPT_GPT_H_
+
+typedef enum {
+	AT_REQ_PART = 0,
+	AT_NO_BLOCK_IO,
+	AT_LEGACY_BOOT,
+	AT_UNDEFINED,
+	AT_SPECIFIC = 48
+} gpt_attr_t;
+
+/** GPT header */
+typedef struct {
+	uint8_t efi_signature[8];
+	uint8_t revision[4];
+	uint32_t header_size;
+	uint32_t header_crc32;
+	uint32_t reserved;
+	uint64_t current_lba;
+	uint64_t alternate_lba;
+	uint64_t first_usable_lba;
+	uint64_t last_usable_lba;
+	uint8_t disk_guid[16];
+	uint64_t entry_lba;
+	uint32_t fillries;
+	uint32_t entry_size;
+	uint32_t pe_array_crc32;
+} __attribute__((packed)) gpt_header_t;
+
+/** GPT partition entry */
+typedef struct {
+	uint8_t part_type[16];
+	uint8_t part_id[16];
+	uint64_t start_lba;
+	uint64_t end_lba;
+	uint64_t attributes;
+	uint8_t part_name[72];
+} __attribute__((packed)) gpt_entry_t;
+
+#endif
Index: uspace/lib/gpt/libgpt.c
===================================================================
--- uspace/lib/gpt/libgpt.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/gpt/libgpt.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,853 @@
+/*
+ * Copyright (c) 2011-2013 Dominik Taborsky
+ * 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 libgpt
+ * @{
+ */
+/** @file
+ */
+
+/* TODO:
+ * The implementation currently supports fixed size partition entries only.
+ * The specification requires otherwise, though.
+ */
+
+#include <ipc/bd.h>
+#include <async.h>
+#include <stdio.h>
+#include <block.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <byteorder.h>
+#include <adt/checksum.h>
+#include <mem.h>
+#include <sys/typefmt.h>
+#include <mbr.h>
+#include <align.h>
+#include "libgpt.h"
+
+static int load_and_check_header(service_id_t, aoff64_t, size_t, gpt_header_t *);
+static gpt_partitions_t *alloc_part_array(uint32_t);
+static int extend_part_array(gpt_partitions_t *);
+static int reduce_part_array(gpt_partitions_t *);
+static uint8_t get_byte(const char *);
+static bool check_overlap(gpt_part_t *, gpt_part_t *);
+static bool check_encaps(gpt_part_t *, uint64_t, uint64_t);
+
+/** Allocate a GPT label */
+gpt_label_t *gpt_alloc_label(void)
+{
+	gpt_label_t *label = malloc(sizeof(gpt_label_t));
+	if (label == NULL)
+		return NULL;
+	
+	label->parts = gpt_alloc_partitions();
+	if (label->parts == NULL) {
+		free(label);
+		return NULL;
+	}
+	
+	label->gpt = NULL;
+	label->device = 0;
+	
+	return label;
+}
+
+/** Free a GPT label */
+void gpt_free_label(gpt_label_t *label)
+{
+	if (label->gpt != NULL)
+		gpt_free_gpt(label->gpt);
+	
+	if (label->parts != NULL)
+		gpt_free_partitions(label->parts);
+	
+	free(label);
+}
+
+/** Allocate a GPT header */
+gpt_t *gpt_alloc_header(size_t size)
+{
+	gpt_t *gpt = malloc(sizeof(gpt_t));
+	if (gpt == NULL)
+		return NULL;
+	
+	/*
+	 * We might need only sizeof(gpt_header_t), but we should follow
+	 * specs and have zeroes through all the rest of the block
+	 */
+	size_t final_size = max(size, sizeof(gpt_header_t));
+	gpt->header = malloc(final_size);
+	if (gpt->header == NULL) {
+		free(gpt);
+		return NULL;
+	}
+	
+	memset(gpt->header, 0, final_size);
+	memcpy(gpt->header->efi_signature, efi_signature, 8);
+	memcpy(gpt->header->revision, revision, 4);
+	gpt->header->header_size = host2uint32_t_le(final_size);
+	gpt->header->entry_lba = host2uint64_t_le((uint64_t) 2);
+	gpt->header->entry_size = host2uint32_t_le(sizeof(gpt_entry_t));
+	
+	return gpt;
+}
+
+/** Free a GPT header */
+void gpt_free_gpt(gpt_t *gpt)
+{
+	free(gpt->header);
+	free(gpt);
+}
+
+/** Read GPT from a device
+ *
+ * @param label      Label to read.
+ * @param dev_handle Device to read GPT from.
+ *
+ * @return EOK on success, error code on error.
+ *
+ */
+int gpt_read_header(gpt_label_t *label, service_id_t dev_handle)
+{
+	int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
+	if (rc != EOK)
+		return rc;
+	
+	size_t block_size;
+	rc = block_get_bsize(dev_handle, &block_size);
+	if (rc != EOK)
+		goto end;
+	
+	if (label->gpt == NULL) {
+		label->gpt = gpt_alloc_header(block_size);
+		if (label->gpt == NULL) {
+			rc = ENOMEM;
+			goto end;
+		}
+	}
+	
+	rc = load_and_check_header(dev_handle, GPT_HDR_BA, block_size,
+	    label->gpt->header);
+	if ((rc == EBADCHECKSUM) || (rc == EINVAL)) {
+		aoff64_t blocks;
+		rc = block_get_nblocks(dev_handle, &blocks);
+		if (rc != EOK) {
+			gpt_free_gpt(label->gpt);
+			goto end;
+		}
+		
+		rc = load_and_check_header(dev_handle, blocks - 1, block_size,
+		    label->gpt->header);
+		if ((rc == EBADCHECKSUM) || (rc == EINVAL)) {
+			gpt_free_gpt(label->gpt);
+			goto end;
+		}
+	}
+	
+	label->device = dev_handle;
+	rc = EOK;
+	
+end:
+	block_fini(dev_handle);
+	return rc;
+}
+
+/** Write GPT header to device
+ *
+ * @param label        Label to be written.
+ * @param dev_handle   Device to write the GPT to.
+ *
+ * @return EOK on success, libblock error code otherwise.
+ *
+ */
+int gpt_write_header(gpt_label_t *label, service_id_t dev_handle)
+{
+	/* The comm_size argument (the last one) is ignored */
+	int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 4096);
+	if ((rc != EOK) && (rc != EEXIST))
+		return rc;
+	
+	size_t block_size;
+	rc = block_get_bsize(dev_handle, &block_size);
+	if (rc != EOK)
+		goto end;
+	
+	aoff64_t blocks;
+	rc = block_get_nblocks(dev_handle, &blocks);
+	if (rc != EOK)
+		goto end;
+	
+	gpt_set_random_uuid(label->gpt->header->disk_guid);
+	
+	/* Prepare the backup header */
+	label->gpt->header->alternate_lba = label->gpt->header->current_lba;
+	label->gpt->header->current_lba = host2uint64_t_le(blocks - 1);
+	
+	uint64_t lba = label->gpt->header->entry_lba;
+	label->gpt->header->entry_lba = host2uint64_t_le(blocks -
+	    (uint32_t_le2host(label->gpt->header->fillries) *
+	    sizeof(gpt_entry_t)) / block_size - 1);
+	
+	label->gpt->header->header_crc32 = 0;
+	label->gpt->header->header_crc32 =
+	    host2uint32_t_le(compute_crc32((uint8_t *) label->gpt->header,
+	    uint32_t_le2host(label->gpt->header->header_size)));
+	
+	/* Write to backup GPT header location */
+	rc = block_write_direct(dev_handle, blocks - 1, GPT_HDR_BS,
+	    label->gpt->header);
+	if (rc != EOK)
+		goto end;
+	
+	/* Prepare the main header */
+	label->gpt->header->entry_lba = lba;
+	
+	lba = label->gpt->header->alternate_lba;
+	label->gpt->header->alternate_lba = label->gpt->header->current_lba;
+	label->gpt->header->current_lba = lba;
+	
+	label->gpt->header->header_crc32 = 0;
+	label->gpt->header->header_crc32 =
+	    host2uint32_t_le(compute_crc32((uint8_t *) label->gpt->header,
+	    uint32_t_le2host(label->gpt->header->header_size)));
+	
+	/* Write to main GPT header location */
+	rc = block_write_direct(dev_handle, GPT_HDR_BA, GPT_HDR_BS,
+	    label->gpt->header);
+	if (rc != EOK)
+		goto end;
+	
+	/* Write Protective MBR */
+	br_block_t mbr;
+	memset(&mbr, 0, 512);
+	
+	memset(mbr.pte[0].first_chs, 1, 3);
+	mbr.pte[0].ptype = 0xEE;
+	memset(mbr.pte[0].last_chs, 0xff, 3);
+	mbr.pte[0].first_lba = host2uint32_t_le(1);
+	mbr.pte[0].length = 0xffffffff;
+	mbr.signature = host2uint16_t_le(BR_SIGNATURE);
+	
+	rc = block_write_direct(dev_handle, 0, 1, &mbr);
+	
+end:
+	block_fini(dev_handle);
+	return rc;
+}
+
+/** Alloc partition array */
+gpt_partitions_t *gpt_alloc_partitions(void)
+{
+	return alloc_part_array(GPT_MIN_PART_NUM);
+}
+
+/** Parse partitions from GPT
+ *
+ * @param label GPT label to be parsed.
+ *
+ * @return EOK on success, error code otherwise.
+ *
+ */
+int gpt_read_partitions(gpt_label_t *label)
+{
+	uint32_t fillries = uint32_t_le2host(label->gpt->header->fillries);
+	uint32_t ent_size = uint32_t_le2host(label->gpt->header->entry_size);
+	uint64_t ent_lba = uint64_t_le2host(label->gpt->header->entry_lba);
+	
+	if (label->parts == NULL) {
+		label->parts = alloc_part_array(fillries);
+		if (label->parts == NULL)
+			return ENOMEM;
+	}
+	
+	int rc = block_init(EXCHANGE_SERIALIZE, label->device,
+	    sizeof(gpt_entry_t));
+	if (rc != EOK) {
+		gpt_free_partitions(label->parts);
+		label->parts = NULL;
+		goto end;
+	}
+	
+	size_t block_size;
+	rc = block_get_bsize(label->device, &block_size);
+	if (rc != EOK) {
+		gpt_free_partitions(label->parts);
+		label->parts = NULL;
+		goto end;
+	}
+	
+	aoff64_t pos = ent_lba * block_size;
+	
+	for (uint32_t i = 0; i < fillries; i++) {
+		rc = block_read_bytes_direct(label->device, pos, sizeof(gpt_entry_t),
+		    label->parts->part_array + i);
+		pos += ent_size;
+		
+		if (rc != EOK) {
+			gpt_free_partitions(label->parts);
+			label->parts = NULL;
+			goto end;
+		}
+	}
+	
+	uint32_t crc = compute_crc32((uint8_t *) label->parts->part_array,
+	    fillries * ent_size);
+	
+	if (uint32_t_le2host(label->gpt->header->pe_array_crc32) != crc) {
+		rc = EBADCHECKSUM;
+		gpt_free_partitions(label->parts);
+		label->parts = NULL;
+		goto end;
+	}
+	
+	rc = EOK;
+	
+end:
+	block_fini(label->device);
+	return rc;
+}
+
+/** Write GPT and partitions to device
+ *
+ * Note: Also writes the header.
+ *
+ * @param label      Label to write.
+ * @param dev_handle Device to write the data to.
+ *
+ * @return EOK on succes, error code otherwise
+ *
+ */
+int gpt_write_partitions(gpt_label_t *label, service_id_t dev_handle)
+{
+	/* comm_size of 4096 is ignored */
+	int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 4096);
+	if ((rc != EOK) && (rc != EEXIST))
+		return rc;
+	
+	size_t block_size;
+	rc = block_get_bsize(dev_handle, &block_size);
+	if (rc != EOK)
+		goto fail;
+	
+	aoff64_t blocks;
+	rc = block_get_nblocks(dev_handle, &blocks);
+	if (rc != EOK)
+		goto fail;
+	
+	if (label->gpt == NULL)
+		label->gpt = gpt_alloc_header(block_size);
+	
+	uint32_t entry_size =
+	    uint32_t_le2host(label->gpt->header->entry_size);
+	size_t fillries = (label->parts->fill > GPT_MIN_PART_NUM) ?
+	    label->parts->fill : GPT_MIN_PART_NUM;
+	
+	if (entry_size != sizeof(gpt_entry_t))
+		return ENOTSUP;
+	
+	label->gpt->header->fillries = host2uint32_t_le(fillries);
+	
+	uint64_t arr_blocks = (fillries * sizeof(gpt_entry_t)) / block_size;
+	
+	/* Include Protective MBR */
+	uint64_t gpt_space = arr_blocks + GPT_HDR_BS + 1;
+	
+	label->gpt->header->first_usable_lba = host2uint64_t_le(gpt_space);
+	label->gpt->header->last_usable_lba =
+	    host2uint64_t_le(blocks - gpt_space - 1);
+	
+	/* Perform checks */
+	gpt_part_foreach (label, p) {
+		if (gpt_get_part_type(p) == GPT_PTE_UNUSED)
+			continue;
+		
+		if (!check_encaps(p, blocks, gpt_space)) {
+			rc = ERANGE;
+			goto fail;
+		}
+		
+		gpt_part_foreach (label, q) {
+			if (p == q)
+				continue;
+			
+			if (gpt_get_part_type(p) != GPT_PTE_UNUSED) {
+				if (check_overlap(p, q)) {
+					rc = ERANGE;
+					goto fail;
+				}
+			}
+		}
+	}
+	
+	label->gpt->header->pe_array_crc32 =
+	    host2uint32_t_le(compute_crc32((uint8_t *) label->parts->part_array,
+	    fillries * entry_size));
+	
+	/* Write to backup GPT partition array location */
+	rc = block_write_direct(dev_handle, blocks - arr_blocks - 1,
+	    arr_blocks, label->parts->part_array);
+	if (rc != EOK)
+		goto fail;
+	
+	/* Write to main GPT partition array location */
+	rc = block_write_direct(dev_handle,
+	    uint64_t_le2host(label->gpt->header->entry_lba),
+	    arr_blocks, label->parts->part_array);
+	if (rc != EOK)
+		goto fail;
+	
+	return gpt_write_header(label, dev_handle);
+	
+fail:
+	block_fini(dev_handle);
+	return rc;
+}
+
+/** Allocate a new partition
+ *
+ * Note: Use either gpt_alloc_partition() or gpt_get_partition().
+ * This returns a memory block (zero-filled) and needs gpt_add_partition()
+ * to be called to insert it into a partition array.
+ * Requires you to call gpt_free_partition afterwards.
+ *
+ * @return Pointer to the new partition or NULL.
+ *
+ */
+gpt_part_t *gpt_alloc_partition(void)
+{
+	gpt_part_t *partition = malloc(sizeof(gpt_part_t));
+	if (partition == NULL)
+		return NULL;
+	
+	memset(partition, 0, sizeof(gpt_part_t));
+	
+	return partition;
+}
+
+/** Allocate a new partition already inside the label
+ *
+ * Note: Use either gpt_alloc_partition() or gpt_get_partition().
+ * This one returns a pointer to the first empty structure already
+ * inside the array, so don't call gpt_add_partition() afterwards.
+ * This is the one you will usually want.
+ *
+ * @param label Label to carry new partition.
+ *
+ * @return Pointer to the new partition or NULL.
+ *
+ */
+gpt_part_t *gpt_get_partition(gpt_label_t *label)
+{
+	gpt_part_t *partition;
+	
+	/* Find the first empty entry */
+	do {
+		if (label->parts->fill == label->parts->arr_size) {
+			if (extend_part_array(label->parts) == -1)
+				return NULL;
+		}
+		
+		partition = label->parts->part_array + label->parts->fill++;
+	} while (gpt_get_part_type(partition) != GPT_PTE_UNUSED);
+	
+	return partition;
+}
+
+/** Get partition already inside the label
+ *
+ * Note: For new partitions use either gpt_alloc_partition() or
+ * gpt_get_partition() unless you want a partition at a specific place.
+ * This returns a pointer to a structure already inside the array,
+ * so don't call gpt_add_partition() afterwards.
+ * This function is handy when you want to change already existing
+ * partition or to simply write somewhere in the middle. This works only
+ * for indexes smaller than either 128 or the actual number of filled
+ * entries.
+ *
+ * @param label Label to carrying the partition.
+ * @param idx   Index of the partition.
+ *
+ * @return Pointer to the partition or NULL when out of range.
+ *
+ */
+gpt_part_t *gpt_get_partition_at(gpt_label_t *label, size_t idx)
+{
+	if ((idx >= GPT_MIN_PART_NUM) && (idx >= label->parts->fill))
+		return NULL;
+	
+	return label->parts->part_array + idx;
+}
+
+/** Copy partition into partition array
+ *
+ * Note: For use with gpt_alloc_partition() only. You will get
+ * duplicates with gpt_get_partition().
+ * Note: Does not call gpt_free_partition()!
+ *
+ * @param parts     Target label
+ * @param partition Source partition to copy
+ *
+ * @return EOK on succes, error code otherwise
+ *
+ */
+int gpt_add_partition(gpt_label_t *label, gpt_part_t *partition)
+{
+	/* Find the first empty entry */
+	
+	gpt_part_t *part;
+	
+	do {
+		if (label->parts->fill == label->parts->arr_size) {
+			if (extend_part_array(label->parts) == -1)
+				return ENOMEM;
+		}
+		
+		part = label->parts->part_array + label->parts->fill++;
+	} while (gpt_get_part_type(part) != GPT_PTE_UNUSED);
+	
+	memcpy(part, partition, sizeof(gpt_entry_t));
+	return EOK;
+}
+
+/** Remove partition from array
+ *
+ * Note: Even if it fails, the partition still gets removed. Only
+ * reducing the array failed.
+ *
+ * @param label Label to remove from
+ * @param idx   Index of the partition to remove
+ *
+ * @return EOK on success, ENOMEM on array reduction failure
+ *
+ */
+int gpt_remove_partition(gpt_label_t *label, size_t idx)
+{
+	if (idx >= label->parts->arr_size)
+		return EINVAL;
+	
+	/*
+	 * FIXME:
+	 * If we allow blank spots, we break the array. If we have more than
+	 * 128 partitions in the array and then remove something from
+	 * the first 128 partitions, we would forget to write the last one.
+	 */
+	
+	memset(label->parts->part_array + idx, 0, sizeof(gpt_entry_t));
+	
+	if (label->parts->fill > idx)
+		label->parts->fill = idx;
+	
+	gpt_part_t *partition;
+	
+	if ((label->parts->fill > GPT_MIN_PART_NUM) &&
+	    (label->parts->fill < (label->parts->arr_size / 2) -
+	    GPT_IGNORE_FILL_NUM)) {
+		for (partition = gpt_get_partition_at(label, label->parts->arr_size / 2);
+		     partition < label->parts->part_array + label->parts->arr_size;
+		     partition++) {
+			if (gpt_get_part_type(partition) != GPT_PTE_UNUSED)
+				return EOK;
+		}
+		
+		if (reduce_part_array(label->parts) == ENOMEM)
+			return ENOMEM;
+	}
+	
+	return EOK;
+}
+
+/** Free partition list
+ *
+ * @param parts Partition list to be freed
+ *
+ */
+void gpt_free_partitions(gpt_partitions_t *parts)
+{
+	free(parts->part_array);
+	free(parts);
+}
+
+/** Get partition type */
+size_t gpt_get_part_type(gpt_part_t *partition)
+{
+	size_t i;
+	
+	for (i = 0; gpt_ptypes[i].guid != NULL; i++) {
+		if ((partition->part_type[3] == get_byte(gpt_ptypes[i].guid + 0)) &&
+		    (partition->part_type[2] == get_byte(gpt_ptypes[i].guid + 2)) &&
+		    (partition->part_type[1] == get_byte(gpt_ptypes[i].guid + 4)) &&
+		    (partition->part_type[0] == get_byte(gpt_ptypes[i].guid + 6)) &&
+		    (partition->part_type[5] == get_byte(gpt_ptypes[i].guid + 8)) &&
+		    (partition->part_type[4] == get_byte(gpt_ptypes[i].guid + 10)) &&
+		    (partition->part_type[7] == get_byte(gpt_ptypes[i].guid + 12)) &&
+		    (partition->part_type[6] == get_byte(gpt_ptypes[i].guid + 14)) &&
+		    (partition->part_type[8] == get_byte(gpt_ptypes[i].guid + 16)) &&
+		    (partition->part_type[9] == get_byte(gpt_ptypes[i].guid + 18)) &&
+		    (partition->part_type[10] == get_byte(gpt_ptypes[i].guid + 20)) &&
+		    (partition->part_type[11] == get_byte(gpt_ptypes[i].guid + 22)) &&
+		    (partition->part_type[12] == get_byte(gpt_ptypes[i].guid + 24)) &&
+		    (partition->part_type[13] == get_byte(gpt_ptypes[i].guid + 26)) &&
+		    (partition->part_type[14] == get_byte(gpt_ptypes[i].guid + 28)) &&
+		    (partition->part_type[15] == get_byte(gpt_ptypes[i].guid + 30)))
+			return i;
+	}
+	
+	return i;
+}
+
+/** Set partition type */
+void gpt_set_part_type(gpt_part_t *partition, size_t type)
+{
+	/* Beware: first 3 blocks are byteswapped! */
+	partition->part_type[3] = get_byte(gpt_ptypes[type].guid + 0);
+	partition->part_type[2] = get_byte(gpt_ptypes[type].guid + 2);
+	partition->part_type[1] = get_byte(gpt_ptypes[type].guid + 4);
+	partition->part_type[0] = get_byte(gpt_ptypes[type].guid + 6);
+	
+	partition->part_type[5] = get_byte(gpt_ptypes[type].guid + 8);
+	partition->part_type[4] = get_byte(gpt_ptypes[type].guid + 10);
+	
+	partition->part_type[7] = get_byte(gpt_ptypes[type].guid + 12);
+	partition->part_type[6] = get_byte(gpt_ptypes[type].guid + 14);
+	
+	partition->part_type[8] = get_byte(gpt_ptypes[type].guid + 16);
+	partition->part_type[9] = get_byte(gpt_ptypes[type].guid + 18);
+	partition->part_type[10] = get_byte(gpt_ptypes[type].guid + 20);
+	partition->part_type[11] = get_byte(gpt_ptypes[type].guid + 22);
+	partition->part_type[12] = get_byte(gpt_ptypes[type].guid + 24);
+	partition->part_type[13] = get_byte(gpt_ptypes[type].guid + 26);
+	partition->part_type[14] = get_byte(gpt_ptypes[type].guid + 28);
+	partition->part_type[15] = get_byte(gpt_ptypes[type].guid + 30);
+}
+
+/** Get partition starting LBA */
+uint64_t gpt_get_start_lba(gpt_part_t *partition)
+{
+	return uint64_t_le2host(partition->start_lba);
+}
+
+/** Set partition starting LBA */
+void gpt_set_start_lba(gpt_part_t *partition, uint64_t start)
+{
+	partition->start_lba = host2uint64_t_le(start);
+}
+
+/** Get partition ending LBA */
+uint64_t gpt_get_end_lba(gpt_part_t *partition)
+{
+	return uint64_t_le2host(partition->end_lba);
+}
+
+/** Set partition ending LBA */
+void gpt_set_end_lba(gpt_part_t *partition, uint64_t end)
+{
+	partition->end_lba = host2uint64_t_le(end);
+}
+
+/** Get partition name */
+unsigned char * gpt_get_part_name(gpt_part_t *partition)
+{
+	return partition->part_name;
+}
+
+/** Copy partition name */
+void gpt_set_part_name(gpt_part_t *partition, char *name, size_t length)
+{
+	if (length >= 72)
+		length = 71;
+	
+	memcpy(partition->part_name, name, length);
+	partition->part_name[length] = '\0';
+}
+
+/** Get partition attribute */
+bool gpt_get_flag(gpt_part_t *partition, gpt_attr_t flag)
+{
+	return (partition->attributes & (((uint64_t) 1) << flag)) ? 1 : 0;
+}
+
+/** Set partition attribute */
+void gpt_set_flag(gpt_part_t *partition, gpt_attr_t flag, bool value)
+{
+	uint64_t attr = partition->attributes;
+	
+	if (value)
+		attr = attr | (((uint64_t) 1) << flag);
+	else
+		attr = attr ^ (attr & (((uint64_t) 1) << flag));
+	
+	partition->attributes = attr;
+}
+
+/** Generate a new pseudo-random UUID
+ *
+ * FIXME: This UUID generator is not compliant with RFC 4122.
+ *
+ */
+void gpt_set_random_uuid(uint8_t *uuid)
+{
+	srandom((unsigned int) (size_t) uuid);
+	
+	for (size_t i = 0; i < 16; i++)
+		uuid[i] = random();
+}
+
+/** Get next aligned address */
+uint64_t gpt_get_next_aligned(uint64_t addr, unsigned int alignment)
+{
+	return ALIGN_UP(addr + 1, alignment);
+}
+
+static int load_and_check_header(service_id_t dev_handle, aoff64_t addr,
+    size_t block_size, gpt_header_t *header)
+{
+	int rc = block_read_direct(dev_handle, addr, GPT_HDR_BS, header);
+	if (rc != EOK)
+		return rc;
+	
+	/* Check the EFI signature */
+	for (unsigned int i = 0; i < 8; i++) {
+		if (header->efi_signature[i] != efi_signature[i])
+			return EINVAL;
+	}
+	
+	/* Check the CRC32 of the header */
+	uint32_t crc = header->header_crc32;
+	header->header_crc32 = 0;
+	
+	if (crc != compute_crc32((uint8_t *) header, header->header_size))
+		return EBADCHECKSUM;
+	else
+		header->header_crc32 = crc;
+	
+	/* Check for zeroes in the rest of the block */
+	for (size_t i = sizeof(gpt_header_t); i < block_size; i++) {
+		if (((uint8_t *) header)[i] != 0)
+			return EINVAL;
+	}
+	
+	return EOK;
+}
+
+static gpt_partitions_t *alloc_part_array(uint32_t num)
+{
+	gpt_partitions_t *res = malloc(sizeof(gpt_partitions_t));
+	if (res == NULL)
+		return NULL;
+	
+	uint32_t size = num > GPT_BASE_PART_NUM ? num : GPT_BASE_PART_NUM;
+	res->part_array = malloc(size * sizeof(gpt_entry_t));
+	if (res->part_array == NULL) {
+		free(res);
+		return NULL;
+	}
+	
+	memset(res->part_array, 0, size * sizeof(gpt_entry_t));
+	
+	res->fill = 0;
+	res->arr_size = num;
+	
+	return res;
+}
+
+static int extend_part_array(gpt_partitions_t *partition)
+{
+	size_t nsize = partition->arr_size * 2;
+	gpt_entry_t *entry = malloc(nsize * sizeof(gpt_entry_t));
+	if (entry == NULL)
+		return ENOMEM;
+	
+	memcpy(entry, partition->part_array, partition->fill *
+	    sizeof(gpt_entry_t));
+	free(partition->part_array);
+	
+	partition->part_array = entry;
+	partition->arr_size = nsize;
+	
+	return EOK;
+}
+
+static int reduce_part_array(gpt_partitions_t *partition)
+{
+	if (partition->arr_size > GPT_MIN_PART_NUM) {
+		unsigned int nsize = partition->arr_size / 2;
+		nsize = nsize > GPT_MIN_PART_NUM ? nsize : GPT_MIN_PART_NUM;
+		
+		gpt_entry_t *entry = malloc(nsize * sizeof(gpt_entry_t));
+		if (entry == NULL)
+			return ENOMEM;
+		
+		memcpy(entry, partition->part_array,
+		    partition->fill < nsize ? partition->fill : nsize);
+		free(partition->part_array);
+		
+		partition->part_array = entry;
+		partition->arr_size = nsize;
+	}
+	
+	return EOK;
+}
+
+/* Parse a byte from a string in hexadecimal */
+static uint8_t get_byte(const char *c)
+{
+	uint8_t val = 0;
+	char hex[3] = {*c, *(c + 1), 0};
+	
+	str_uint8_t(hex, NULL, 16, false, &val);
+	return val;
+}
+
+static bool check_overlap(gpt_part_t *part1, gpt_part_t *part2)
+{
+	if ((gpt_get_start_lba(part1) < gpt_get_start_lba(part2)) &&
+	    (gpt_get_end_lba(part1) < gpt_get_start_lba(part2)))
+		return false;
+	
+	if ((gpt_get_start_lba(part1) > gpt_get_start_lba(part2)) &&
+	    (gpt_get_end_lba(part2) < gpt_get_start_lba(part1)))
+		return false;
+	
+	return true;
+}
+
+static bool check_encaps(gpt_part_t *part, uint64_t blocks,
+    uint64_t first_lba)
+{
+	/*
+	 * We allow "<=" in the second expression because it lacks
+	 * MBR so it is smaller by 1 block.
+	 */
+	if ((gpt_get_start_lba(part) >= first_lba) &&
+	    (gpt_get_end_lba(part) <= blocks - first_lba))
+		return true;
+	
+	return false;
+}
Index: uspace/lib/gpt/libgpt.h
===================================================================
--- uspace/lib/gpt/libgpt.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/gpt/libgpt.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * Copyright (c) 2011-2013 Dominik Taborsky
+ * 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 libgpt
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBGPT_LIBGPT_H_
+#define LIBGPT_LIBGPT_H_
+
+#include <loc.h>
+#include <sys/types.h>
+#include "gpt.h"
+
+/** Block address of GPT header. */
+#define GPT_HDR_BA  1
+
+/** Block size of GPT header. */
+#define GPT_HDR_BS  1
+
+/** Minimum number of GPT partition entries */
+#define GPT_MIN_PART_NUM  128
+
+/** Basic number of GPT partition entries */
+#define GPT_BASE_PART_NUM  (GPT_MIN_PART_NUM)
+
+/** How much fill we ignore before resizing partition array */
+#define GPT_IGNORE_FILL_NUM  10
+
+/** Unused partition entry */
+#define GPT_PTE_UNUSED  0
+
+/** Raw GPT header.
+ *
+ * Uses more bytes than sizeof(gpt_header_t).
+ */
+typedef struct {
+	gpt_header_t *header;
+} gpt_t;
+
+typedef gpt_entry_t gpt_part_t;
+
+typedef struct {
+	/** Number of entries */
+	size_t fill;
+	
+	/** Size of the array */
+	size_t arr_size;
+	
+	/** Resizable partition array */
+	gpt_part_t *part_array;
+} gpt_partitions_t;
+
+typedef struct {
+	gpt_t *gpt;
+	gpt_partitions_t *parts;
+	service_id_t device;
+} gpt_label_t;
+
+typedef struct {
+	const char *desc;
+	const char *guid;
+} partition_type_t;
+
+/** GPT header signature ("EFI PART" in ASCII) */
+extern const uint8_t efi_signature[8];
+extern const uint8_t revision[4];
+
+extern const partition_type_t gpt_ptypes[];
+
+extern gpt_label_t *gpt_alloc_label(void);
+extern void gpt_free_label(gpt_label_t *);
+
+extern gpt_t *gpt_alloc_header(size_t);
+extern int gpt_read_header(gpt_label_t *, service_id_t);
+extern int gpt_write_header(gpt_label_t *, service_id_t);
+
+extern gpt_partitions_t *gpt_alloc_partitions(void);
+extern int gpt_read_partitions(gpt_label_t *);
+extern int gpt_write_partitions(gpt_label_t *, service_id_t);
+extern gpt_part_t *gpt_alloc_partition(void);
+extern gpt_part_t *gpt_get_partition(gpt_label_t *);
+extern gpt_part_t *gpt_get_partition_at(gpt_label_t *, size_t);
+extern int gpt_add_partition(gpt_label_t *, gpt_part_t *);
+extern int gpt_remove_partition(gpt_label_t *, size_t);
+
+extern size_t gpt_get_part_type(gpt_part_t *);
+extern void gpt_set_part_type(gpt_part_t *, size_t);
+extern void gpt_set_start_lba(gpt_part_t *, uint64_t);
+extern uint64_t gpt_get_start_lba(gpt_part_t *);
+extern void gpt_set_end_lba(gpt_part_t *, uint64_t);
+extern uint64_t gpt_get_end_lba(gpt_part_t *);
+extern unsigned char *gpt_get_part_name(gpt_part_t *);
+extern void gpt_set_part_name(gpt_part_t *, char *, size_t);
+extern bool gpt_get_flag(gpt_part_t *, gpt_attr_t);
+extern void gpt_set_flag(gpt_part_t *, gpt_attr_t, bool);
+
+extern void gpt_set_random_uuid(uint8_t *);
+extern uint64_t gpt_get_next_aligned(uint64_t, unsigned int);
+
+
+#define gpt_part_foreach(label, iterator) \
+	for (gpt_part_t *iterator = (label)->parts->part_array; \
+	    iterator < (label)->parts->part_array + (label)->parts->arr_size; \
+	    iterator++)
+
+extern void gpt_free_gpt(gpt_t *);
+extern void gpt_free_partitions(gpt_partitions_t *);
+
+#endif
Index: uspace/lib/gui/Makefile
===================================================================
--- uspace/lib/gui/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -34,4 +34,5 @@
 
 SOURCES = \
+	common.c \
 	button.c \
 	canvas.c \
Index: uspace/lib/gui/button.c
===================================================================
--- uspace/lib/gui/button.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/button.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -36,45 +36,57 @@
 #include <str.h>
 #include <malloc.h>
-
 #include <drawctx.h>
 #include <surface.h>
-
+#include "common.h"
 #include "window.h"
 #include "button.h"
 
-static void paint_internal(widget_t *w)
-{
-	button_t *btn = (button_t *) w;
-
+static pixel_t color_highlight = PIXEL(255, 255, 255, 255);
+static pixel_t color_shadow = PIXEL(255, 85, 85, 85);
+
+static void paint_internal(widget_t *widget)
+{
+	button_t *btn = (button_t *) widget;
+	
 	surface_t *surface = window_claim(btn->widget.window);
-	if (!surface) {
+	if (!surface)
 		window_yield(btn->widget.window);
+	
+	source_t source;
+	source_init(&source);
+	
+	drawctx_t drawctx;
+	drawctx_init(&drawctx, surface);
+	
+	drawctx_set_source(&drawctx, &btn->background);
+	drawctx_transfer(&drawctx, widget->hpos, widget->vpos,
+	    widget->width, widget->height);
+	
+	if ((widget->width >= 8) && (widget->height >= 8)) {
+		drawctx_set_source(&drawctx, &source);
+		draw_bevel(&drawctx, &source, widget->hpos + 3, widget->vpos + 3,
+		    widget->width - 6, widget->height - 6, color_highlight,
+		    color_shadow);
+		
+		drawctx_set_source(&drawctx, &btn->foreground);
+		drawctx_transfer(&drawctx, widget->hpos + 4, widget->vpos + 4,
+		    widget->width - 8, widget->height - 8);
 	}
-
-	drawctx_t drawctx;
-
-	drawctx_init(&drawctx, surface);
-	drawctx_set_source(&drawctx, &btn->foreground);
-	drawctx_transfer(&drawctx, w->hpos, w->vpos, w->width, w->height);
-
-	if (w->width >= 6 && w->height >= 6) {
-		drawctx_set_source(&drawctx, &btn->background);
-		drawctx_transfer(&drawctx,
-		    w->hpos + 3, w->vpos + 3, w->width - 6, w->height - 6);
-	}
-
+	
 	sysarg_t cpt_width;
 	sysarg_t cpt_height;
 	font_get_box(&btn->font, btn->caption, &cpt_width, &cpt_height);
-	if (w->width >= cpt_width && w->height >= cpt_height) {
-		drawctx_set_source(&drawctx, &btn->foreground);
+	
+	if ((widget->width >= cpt_width) && (widget->height >= cpt_height)) {
+		sysarg_t x = ((widget->width - cpt_width) / 2) + widget->hpos;
+		sysarg_t y = ((widget->height - cpt_height) / 2) + widget->vpos;
+		
+		drawctx_set_source(&drawctx, &btn->text);
 		drawctx_set_font(&drawctx, &btn->font);
-		sysarg_t x = ((w->width - cpt_width) / 2) + w->hpos;
-		sysarg_t y = ((w->height - cpt_height) / 2) + w->vpos;
-		if (btn->caption) {
+		
+		if (btn->caption)
 			drawctx_print(&drawctx, btn->caption, x, y);
-		}
 	}
-
+	
 	window_yield(btn->widget.window);
 }
@@ -90,7 +102,6 @@
 {
 	button_t *btn = (button_t *) widget;
-
+	
 	deinit_button(btn);
-	
 	free(btn);
 }
@@ -117,7 +128,7 @@
 {
 	button_t *btn = (button_t *) widget;
-	if (event.key == KC_ENTER && event.type == KEY_PRESS) {
+	
+	if (event.key == KC_ENTER && event.type == KEY_PRESS)
 		sig_send(&btn->clicked, NULL);
-	}
 }
 
@@ -126,18 +137,17 @@
 	button_t *btn = (button_t *) widget;
 	widget->window->focus = widget;
-
+	
 	// TODO make the click logic more robust (mouse grabbing, mouse moves)
 	if (event.btn_num == 1) {
-		if (event.type == POS_RELEASE) {
+		if (event.type == POS_RELEASE)
 			sig_send(&btn->clicked, NULL);
-		}
 	}
 }
 
-bool init_button(button_t *btn, widget_t *parent,
-    const char *caption, uint16_t points, pixel_t background, pixel_t foreground)
+bool init_button(button_t *btn, widget_t *parent, const char *caption,
+    uint16_t points, pixel_t background, pixel_t foreground, pixel_t text)
 {
 	widget_init(&btn->widget, parent);
-
+	
 	btn->widget.destroy = button_destroy;
 	btn->widget.reconfigure = button_reconfigure;
@@ -146,42 +156,45 @@
 	btn->widget.handle_keyboard_event = button_handle_keyboard_event;
 	btn->widget.handle_position_event = button_handle_position_event;
-
+	
 	source_init(&btn->background);
 	source_set_color(&btn->background, background);
+	
 	source_init(&btn->foreground);
 	source_set_color(&btn->foreground, foreground);
-
-	if (caption == NULL) {
+	
+	source_init(&btn->text);
+	source_set_color(&btn->text, text);
+	
+	if (caption == NULL)
 		btn->caption = NULL;
-	} else {
+	else
 		btn->caption = str_dup(caption);
-	}
+	
 	font_init(&btn->font, FONT_DECODER_EMBEDDED, NULL, points);
-
+	
 	sysarg_t cpt_width;
 	sysarg_t cpt_height;
 	font_get_box(&btn->font, btn->caption, &cpt_width, &cpt_height);
-	btn->widget.width_min = cpt_width + 8;
-	btn->widget.height_min = cpt_height + 8;
-	btn->widget.width_ideal = cpt_width + 28;
-	btn->widget.height_ideal = cpt_height + 8;
-
+	btn->widget.width_min = cpt_width + 10;
+	btn->widget.height_min = cpt_height + 10;
+	btn->widget.width_ideal = cpt_width + 30;
+	btn->widget.height_ideal = cpt_height + 10;
+	
 	return true;
 }
 
-button_t *create_button(widget_t *parent,
-    const char *caption, uint16_t points, pixel_t background, pixel_t foreground)
+button_t *create_button(widget_t *parent, const char *caption, uint16_t points,
+    pixel_t background, pixel_t foreground, pixel_t text)
 {
 	button_t *btn = (button_t *) malloc(sizeof(button_t));
-	if (!btn) {
+	if (!btn)
 		return NULL;
-	}
-
-	if (init_button(btn, parent, caption, points, background, foreground)) {
+	
+	if (init_button(btn, parent, caption, points, background, foreground,
+	    text))
 		return btn;
-	} else {
-		free(btn);
-		return NULL;
-	}
+	
+	free(btn);
+	return NULL;
 }
 
Index: uspace/lib/gui/button.h
===================================================================
--- uspace/lib/gui/button.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/button.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -50,4 +50,5 @@
 	source_t background;
 	source_t foreground;
+	source_t text;
 	char *caption;
 	font_t font;
@@ -55,6 +56,8 @@
 } button_t;
 
-extern bool init_button(button_t *, widget_t *, const char *, uint16_t, pixel_t, pixel_t);
-extern button_t *create_button(widget_t *, const char *, uint16_t, pixel_t, pixel_t);
+extern bool init_button(button_t *, widget_t *, const char *, uint16_t, pixel_t,
+    pixel_t, pixel_t);
+extern button_t *create_button(widget_t *, const char *, uint16_t, pixel_t,
+    pixel_t, pixel_t);
 extern void deinit_button(button_t *);
 
Index: uspace/lib/gui/canvas.c
===================================================================
--- uspace/lib/gui/canvas.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/canvas.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -112,5 +112,12 @@
 static void canvas_handle_position_event(widget_t *widget, pos_event_t event)
 {
-	/* No-op */
+	canvas_t *canvas = (canvas_t *) widget;
+	pos_event_t tevent;
+	
+	tevent = event;
+	tevent.hpos -= widget->hpos;
+	tevent.vpos -= widget->vpos;
+	
+	sig_send(&canvas->position_event, &tevent);
 }
 
Index: uspace/lib/gui/canvas.h
===================================================================
--- uspace/lib/gui/canvas.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/canvas.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -50,4 +50,5 @@
 	surface_t *surface;
 	signal_t keyboard_event;
+	signal_t position_event;
 } canvas_t;
 
Index: uspace/lib/gui/common.c
===================================================================
--- uspace/lib/gui/common.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/gui/common.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+/** @addtogroup gui
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <sys/types.h>
+#include <drawctx.h>
+#include "common.h"
+
+#define CROSS_WIDTH   14
+#define CROSS_HEIGHT  14
+
+static uint8_t cross_texture[] = {
+	0x00, 0x00, 0x02, 0x08, 0x04, 0x04, 0x08, 0x02, 0x10, 0x01, 0xa0, 0x00,
+	0x40, 0x00, 0xa0, 0x00, 0x10, 0x01, 0x08, 0x02, 0x04, 0x04, 0x02, 0x08,
+	0x01, 0x10, 0x00, 0x00
+};
+
+static uint8_t cross_mask[] = {
+	0x00, 0x00, 0x02, 0x18, 0x06, 0x0c, 0x0c, 0x06, 0x18, 0x03, 0xb0, 0x01,
+	0xe0, 0x00, 0xe0, 0x00, 0xb0, 0x01, 0x18, 0x03, 0x0c, 0x06, 0x06, 0x0c,
+	0x03, 0x18, 0x00, 0x00
+};
+
+void draw_icon_cross(surface_t *surface, sysarg_t hpos, sysarg_t vpos,
+    pixel_t highlight, pixel_t shadow)
+{
+	for (unsigned int y = 0; y < CROSS_HEIGHT; y++) {
+		for (unsigned int x = 0; x < CROSS_WIDTH; x++) {
+			size_t offset = y * ((CROSS_WIDTH - 1) / 8 + 1) + x / 8;
+			bool visible = cross_mask[offset] & (1 << (x % 8));
+			pixel_t pixel = (cross_texture[offset] & (1 << (x % 8))) ?
+			    highlight : shadow;
+			
+			if (visible)
+				surface_put_pixel(surface, hpos + x, vpos + y, pixel);
+		}
+	}
+}
+
+void draw_bevel(drawctx_t *drawctx, source_t *source, sysarg_t hpos,
+    sysarg_t vpos, sysarg_t width, sysarg_t height, pixel_t highlight,
+    pixel_t shadow)
+{
+	source_set_color(source, highlight);
+	drawctx_transfer(drawctx, hpos, vpos, width - 1, 1);
+	drawctx_transfer(drawctx, hpos, vpos + 1, 1, height - 2);
+	
+	source_set_color(source, shadow);
+	drawctx_transfer(drawctx, hpos, vpos + height - 1, width, 1);
+	drawctx_transfer(drawctx, hpos + width - 1, vpos, 1, height);
+}
+
+/** @}
+ */
Index: uspace/lib/gui/common.h
===================================================================
--- uspace/lib/gui/common.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/gui/common.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+/** @addtogroup gui
+ * @{
+ */
+/**
+ * @file
+ */
+
+#ifndef GUI_COMMON_H_
+#define GUI_COMMON_H_
+
+#include <sys/types.h>
+#include <drawctx.h>
+
+extern void draw_icon_cross(surface_t *, sysarg_t, sysarg_t, pixel_t, pixel_t);
+extern void draw_bevel(drawctx_t *, source_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, pixel_t, pixel_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/gui/connection.c
===================================================================
--- uspace/lib/gui/connection.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/connection.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -210,7 +210,7 @@
 			link_initialize(&event->link);
 			event->type = ET_SIGNAL_EVENT;
-			event->data.sig.object = (sysarg_t) cur->widget;
-			event->data.sig.slot = (sysarg_t) cur->slot;
-			event->data.sig.argument = (sysarg_t) data_copy;
+			event->data.signal.object = (sysarg_t) cur->widget;
+			event->data.signal.slot = (sysarg_t) cur->slot;
+			event->data.signal.argument = (sysarg_t) data_copy;
 			prodcons_produce(&cur->widget->window->events, &event->link);
 		} else {
Index: uspace/lib/gui/label.c
===================================================================
--- uspace/lib/gui/label.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/label.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -36,39 +36,39 @@
 #include <str.h>
 #include <malloc.h>
-
 #include <drawctx.h>
 #include <surface.h>
-
 #include "window.h"
 #include "label.h"
 
-static void paint_internal(widget_t *w)
+static void paint_internal(widget_t *widget)
 {
-	label_t *lbl = (label_t *) w;
+	label_t *lbl = (label_t *) widget;
 
 	surface_t *surface = window_claim(lbl->widget.window);
-	if (!surface) {
+	if (!surface)
 		window_yield(lbl->widget.window);
-	}
-
+	
 	drawctx_t drawctx;
-
 	drawctx_init(&drawctx, surface);
+	
 	drawctx_set_source(&drawctx, &lbl->background);
-	drawctx_transfer(&drawctx, w->hpos, w->vpos, w->width, w->height);
-
+	drawctx_transfer(&drawctx, widget->hpos, widget->vpos, widget->width,
+	    widget->height);
+	
 	sysarg_t cpt_width;
 	sysarg_t cpt_height;
 	font_get_box(&lbl->font, lbl->caption, &cpt_width, &cpt_height);
-	if (w->width >= cpt_width && w->height >= cpt_height) {
-		drawctx_set_source(&drawctx, &lbl->foreground);
+	
+	if ((widget->width >= cpt_width) && (widget->height >= cpt_height)) {
+		sysarg_t x = ((widget->width - cpt_width) / 2) + widget->hpos;
+		sysarg_t y = ((widget->height - cpt_height) / 2) + widget->vpos;
+		
+		drawctx_set_source(&drawctx, &lbl->text);
 		drawctx_set_font(&drawctx, &lbl->font);
-		sysarg_t x = ((w->width - cpt_width) / 2) + w->hpos;
-		sysarg_t y = ((w->height - cpt_height) / 2) + w->vpos;
-		if (lbl->caption) {
+		
+		if (lbl->caption)
 			drawctx_print(&drawctx, lbl->caption, x, y);
-		}
 	}
-
+	
 	window_yield(lbl->widget.window);
 }
@@ -78,15 +78,17 @@
 	if (data != NULL) {
 		label_t *lbl = (label_t *) widget;
+		
 		const char *new_caption = (const char *) data;
 		lbl->caption = str_dup(new_caption);
-
+		
 		sysarg_t cpt_width;
 		sysarg_t cpt_height;
 		font_get_box(&lbl->font, lbl->caption, &cpt_width, &cpt_height);
+		
 		lbl->widget.width_min = cpt_width + 4;
 		lbl->widget.height_min = cpt_height + 4;
 		lbl->widget.width_ideal = lbl->widget.width_min;
 		lbl->widget.height_ideal = lbl->widget.height_min;
-
+		
 		window_refresh(lbl->widget.window);
 	}
@@ -103,7 +105,6 @@
 {
 	label_t *lbl = (label_t *) widget;
-
+	
 	deinit_label(lbl);
-	
 	free(lbl);
 }
@@ -137,9 +138,9 @@
 }
 
-bool init_label(label_t *lbl, widget_t *parent,
-    const char *caption, uint16_t points, pixel_t background, pixel_t foreground)
+bool init_label(label_t *lbl, widget_t *parent, const char *caption,
+    uint16_t points, pixel_t background, pixel_t text)
 {
 	widget_init(&lbl->widget, parent);
-
+	
 	lbl->widget.destroy = label_destroy;
 	lbl->widget.reconfigure = label_reconfigure;
@@ -148,47 +149,46 @@
 	lbl->widget.handle_keyboard_event = label_handle_keyboard_event;
 	lbl->widget.handle_position_event = label_handle_position_event;
-
+	
 	source_init(&lbl->background);
 	source_set_color(&lbl->background, background);
-	source_init(&lbl->foreground);
-	source_set_color(&lbl->foreground, foreground);
-
-	if (caption == NULL) {
+	
+	source_init(&lbl->text);
+	source_set_color(&lbl->text, text);
+	
+	if (caption == NULL)
 		lbl->caption = NULL;
-	} else {
+	else
 		lbl->caption = str_dup(caption);
-	}
+	
 	font_init(&lbl->font, FONT_DECODER_EMBEDDED, NULL, points);
-
+	
 	sysarg_t cpt_width;
 	sysarg_t cpt_height;
 	font_get_box(&lbl->font, lbl->caption, &cpt_width, &cpt_height);
+	
 	lbl->widget.width_min = cpt_width + 4;
 	lbl->widget.height_min = cpt_height + 4;
 	lbl->widget.width_ideal = lbl->widget.width_min;
 	lbl->widget.height_ideal = lbl->widget.height_min;
-
+	
 	lbl->rewrite = on_rewrite;
-
+	
 	return true;
 }
 
-label_t *create_label(widget_t *parent,
-    const char *caption, uint16_t points, pixel_t background, pixel_t foreground)
+label_t *create_label(widget_t *parent, const char *caption, uint16_t points,
+    pixel_t background, pixel_t text)
 {
 	label_t *lbl = (label_t *) malloc(sizeof(label_t));
-	if (!lbl) {
+	if (!lbl)
 		return NULL;
-	}
-
-	if (init_label(lbl, parent, caption, points, background, foreground)) {
+	
+	if (init_label(lbl, parent, caption, points, background, text))
 		return lbl;
-	} else {
-		free(lbl);
-		return NULL;
-	}
+	
+	free(lbl);
+	return NULL;
 }
 
 /** @}
  */
-
Index: uspace/lib/gui/label.h
===================================================================
--- uspace/lib/gui/label.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/label.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -49,5 +49,5 @@
 	widget_t widget;
 	source_t background;
-	source_t foreground;
+	source_t text;
 	char *caption;
 	font_t font;
@@ -55,6 +55,8 @@
 } label_t;
 
-extern bool init_label(label_t *, widget_t *, const char *, uint16_t, pixel_t, pixel_t);
-extern label_t *create_label(widget_t *, const char *, uint16_t, pixel_t, pixel_t);
+extern bool init_label(label_t *, widget_t *, const char *, uint16_t, pixel_t,
+    pixel_t);
+extern label_t *create_label(widget_t *, const char *, uint16_t, pixel_t,
+    pixel_t);
 extern void deinit_label(label_t *);
 
Index: uspace/lib/gui/window.c
===================================================================
--- uspace/lib/gui/window.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/window.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -56,75 +56,133 @@
 #include <surface.h>
 
+#include "common.h"
 #include "connection.h"
 #include "widget.h"
 #include "window.h"
 
-static sysarg_t border_thickness = 5;
+static sysarg_t border_thickness = 4;
+static sysarg_t bevel_thickness = 1;
 static sysarg_t header_height = 20;
 static sysarg_t header_min_width = 40;
-static sysarg_t close_width = 20;
-
-static pixel_t border_color = PIXEL(255, 0, 0, 0);
-static pixel_t header_bg_focus_color = PIXEL(255, 88, 106, 196);
-static pixel_t header_fg_focus_color = PIXEL(255, 255, 255, 255);
-static pixel_t header_bg_unfocus_color = PIXEL(255, 12, 57, 92);
-static pixel_t header_fg_unfocus_color = PIXEL(255, 255, 255, 255);
-
-static void paint_internal(widget_t *w)
-{
-	surface_t *surface = window_claim(w->window);
-	if (!surface) {
-		window_yield(w->window);
-	}
-
+static sysarg_t close_thickness = 20;
+
+static pixel_t color_highlight = PIXEL(255, 255, 255, 255);
+static pixel_t color_shadow = PIXEL(255, 85, 85, 85);
+static pixel_t color_surface = PIXEL(255, 186, 186, 186);
+
+static pixel_t color_header_focus_highlight = PIXEL(255, 120, 145, 255);
+static pixel_t color_header_focus_shadow = PIXEL(255, 40, 48, 89);
+static pixel_t color_header_focus_surface = PIXEL(255, 88, 106, 196);
+
+static pixel_t color_header_unfocus_highlight = PIXEL(255, 16, 78, 126);
+static pixel_t color_header_unfocus_shadow = PIXEL(255, 5, 26, 42);
+static pixel_t color_header_unfocus_surface = PIXEL(255, 12, 57, 92);
+
+static pixel_t color_caption_focus = PIXEL(255, 255, 255, 255);
+static pixel_t color_caption_unfocus = PIXEL(255, 207, 207, 207);
+
+static void paint_internal(widget_t *widget)
+{
+	surface_t *surface = window_claim(widget->window);
+	if (!surface)
+		window_yield(widget->window);
+	
 	source_t source;
-	font_t font;
+	source_init(&source);
+	
 	drawctx_t drawctx;
-
-	source_init(&source);
-	font_init(&font, FONT_DECODER_EMBEDDED, NULL, 16);
 	drawctx_init(&drawctx, surface);
 	drawctx_set_source(&drawctx, &source);
+	
+	/* Window border outer bevel */
+	
+	draw_bevel(&drawctx, &source, widget->vpos, widget->hpos,
+	    widget->width, widget->height, color_highlight, color_shadow);
+	
+	/* Window border surface */
+	
+	source_set_color(&source, color_surface);
+	drawctx_transfer(&drawctx, widget->hpos + 1, widget->vpos + 1,
+	    widget->width - 2, 2);
+	drawctx_transfer(&drawctx, widget->hpos + 1, widget->vpos + 1,
+	    2, widget->height - 2);
+	drawctx_transfer(&drawctx, widget->hpos + 1,
+	    widget->vpos + widget->height - 3, widget->width - 2, 2);
+	drawctx_transfer(&drawctx, widget->hpos + widget->width - 3,
+	    widget->vpos + 1, 2, widget->height - 4);
+	
+	/* Window border inner bevel */
+	
+	draw_bevel(&drawctx, &source, widget->hpos + 3, widget->vpos + 3,
+	    widget->width - 6, widget->height - 6, color_shadow,
+	    color_highlight);
+	
+	/* Header bevel */
+	
+	sysarg_t header_hpos = widget->hpos + border_thickness;
+	sysarg_t header_vpos = widget->vpos + border_thickness;
+	sysarg_t header_width = widget->width - 2 * border_thickness -
+	    close_thickness;
+	
+	draw_bevel(&drawctx, &source, header_hpos, header_vpos,
+	    header_width, header_height, widget->window->is_focused ?
+	    color_header_focus_highlight : color_header_unfocus_highlight,
+	    widget->window->is_focused ?
+	    color_header_focus_shadow : color_header_unfocus_shadow);
+	
+	/* Header surface */
+	
+	source_set_color(&source, widget->window->is_focused ?
+	    color_header_focus_surface : color_header_unfocus_surface);
+	drawctx_transfer(&drawctx, header_hpos + 1, header_vpos + 1,
+	    header_width - 2, header_height - 2);
+	
+	/* Close button bevel */
+	
+	sysarg_t close_hpos = widget->hpos + widget->width -
+	    border_thickness - close_thickness;
+	sysarg_t close_vpos = widget->vpos + border_thickness;
+	
+	draw_bevel(&drawctx, &source, close_hpos, close_vpos,
+	    close_thickness, close_thickness, color_highlight, color_shadow);
+	
+	/* Close button surface */
+	
+	source_set_color(&source, color_surface);
+	drawctx_transfer(&drawctx, close_hpos + 1, close_vpos + 1,
+	    close_thickness - 2, close_thickness - 2);
+	
+	/* Close button icon */
+	
+	draw_icon_cross(surface, close_hpos + 3, close_vpos + 3,
+	    color_highlight, color_shadow);
+	
+	/* Window caption */
+	
+	font_t font;
+	font_init(&font, FONT_DECODER_EMBEDDED, NULL, 16);
+	
 	drawctx_set_font(&drawctx, &font);
-
-	source_set_color(&source, border_color);
-	drawctx_transfer(&drawctx, w->hpos, w->vpos, border_thickness, w->height);
-	drawctx_transfer(&drawctx, w->hpos + w->width - border_thickness,
-	    w->vpos, border_thickness, w->height);
-	drawctx_transfer(&drawctx, w->hpos, w->vpos, w->width, border_thickness);
-	drawctx_transfer(&drawctx, w->hpos,
-	    w->vpos + w->height - border_thickness, w->width, border_thickness);
-
-	source_set_color(&source, 
-	    w->window->is_focused ? header_bg_focus_color : header_bg_unfocus_color);
-	drawctx_transfer(&drawctx,
-	    w->hpos + border_thickness, w->vpos + border_thickness,
-		w->width - 2 * border_thickness, header_height);
-
+	source_set_color(&source, widget->window->is_focused ?
+	    color_caption_focus : color_caption_unfocus);
+	
 	sysarg_t cpt_width;
 	sysarg_t cpt_height;
-	font_get_box(&font, w->window->caption, &cpt_width, &cpt_height);
-	sysarg_t cls_width;
-	sysarg_t cls_height;
-	char cls_pict[] = "x";
-	font_get_box(&font, cls_pict, &cls_width, &cls_height);
-	source_set_color(&source, 
-	    w->window->is_focused ? header_fg_focus_color : header_fg_unfocus_color);
-	sysarg_t cls_x = ((close_width - cls_width) / 2) + w->hpos + w->width -
-	    border_thickness - close_width;
-	sysarg_t cls_y = ((header_height - cls_height) / 2) + w->vpos + border_thickness;
-	drawctx_print(&drawctx, cls_pict, cls_x, cls_y);
-
-	bool draw_title = (w->width >= 2 * border_thickness + close_width + cpt_width);
+	font_get_box(&font, widget->window->caption, &cpt_width, &cpt_height);
+	
+	bool draw_title =
+	    (widget->width >= 2 * border_thickness + 2 * bevel_thickness +
+	    close_thickness + cpt_width);
 	if (draw_title) {
-		sysarg_t cpt_x = ((w->width - cpt_width) / 2) + w->hpos;
-		sysarg_t cpt_y = ((header_height - cpt_height) / 2) + w->vpos + border_thickness;
-		if (w->window->caption) {
-			drawctx_print(&drawctx, w->window->caption, cpt_x, cpt_y);
-		}
-	}
-
+		sysarg_t cpt_x = ((widget->width - cpt_width) / 2) + widget->hpos;
+		sysarg_t cpt_y = ((header_height - cpt_height) / 2) +
+		    widget->vpos + border_thickness;
+		
+		if (widget->window->caption)
+			drawctx_print(&drawctx, widget->window->caption, cpt_x, cpt_y);
+	}
+	
 	font_release(&font);
-	window_yield(w->window);
+	window_yield(widget->window);
 }
 
@@ -138,5 +196,5 @@
 	if (widget->window->is_decorated) {
 		list_foreach(widget->children, link, widget_t, child) {
-			child->rearrange(child, 
+			child->rearrange(child,
 			    widget->hpos + border_thickness,
 			    widget->vpos + border_thickness + header_height,
@@ -211,5 +269,6 @@
 		    (event.vpos >= border_thickness) &&
 		    (event.vpos < border_thickness + header_height);
-		bool close = header && (event.hpos >= width - border_thickness - close_width);
+		bool close = (header) &&
+		    (event.hpos >= width - border_thickness - close_thickness);
 
 		if (top && left && allowed_button) {
@@ -292,5 +351,5 @@
 }
 
-static void handle_signal_event(window_t *win, sig_event_t event)
+static void handle_signal_event(window_t *win, signal_event_t event)
 {
 	widget_t *widget = (widget_t *) event.object;
@@ -303,58 +362,56 @@
 }
 
-static void handle_resize(window_t *win, sysarg_t width, sysarg_t height)
-{
-	int rc;
-	surface_t *old_surface;
-	surface_t *new_surface;
-
+static void handle_resize(window_t *win, sysarg_t offset_x, sysarg_t offset_y,
+    sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags)
+{
 	if (width < 2 * border_thickness + header_min_width) {
 		win_damage(win->osess, 0, 0, 0, 0);
 		return;
 	}
-
+	
 	if (height < 2 * border_thickness + header_height) {
 		win_damage(win->osess, 0, 0, 0, 0);
 		return;
 	}
-
+	
 	/* Allocate resources for new surface. */
-	new_surface = surface_create(width, height, NULL, SURFACE_FLAG_SHARED);
-	if (!new_surface) {
+	surface_t *new_surface = surface_create(width, height, NULL,
+	    SURFACE_FLAG_SHARED);
+	if (!new_surface)
 		return;
-	}
-
+	
 	/* Switch new and old surface. */
 	fibril_mutex_lock(&win->guard);
-	old_surface = win->surface;
+	surface_t *old_surface = win->surface;
 	win->surface = new_surface;
 	fibril_mutex_unlock(&win->guard);
-
-	/* Let all widgets in the tree alter their position and size. Widgets might
-	 * also paint themselves onto the new surface. */
+	
+	/*
+	 * Let all widgets in the tree alter their position and size.
+	 * Widgets might also paint themselves onto the new surface.
+	 */
 	win->root.rearrange(&win->root, 0, 0, width, height);
-
+	
 	fibril_mutex_lock(&win->guard);
 	surface_reset_damaged_region(win->surface);
 	fibril_mutex_unlock(&win->guard);
-
+	
 	/* Inform compositor about new surface. */
-	rc = win_resize(win->osess,
-		width, height, surface_direct_access(new_surface));
-
+	int rc = win_resize(win->osess, offset_x, offset_y, width, height,
+	    placement_flags, surface_direct_access(new_surface));
+	
 	if (rc != EOK) {
 		/* Rollback to old surface. Reverse all changes. */
-
+		
 		sysarg_t old_width = 0;
 		sysarg_t old_height = 0;
-		if (old_surface) {
+		if (old_surface)
 			surface_get_resolution(old_surface, &old_width, &old_height);
-		}
-
+		
 		fibril_mutex_lock(&win->guard);
 		new_surface = win->surface;
 		win->surface = old_surface;
 		fibril_mutex_unlock(&win->guard);
-
+		
 		win->root.rearrange(&win->root, 0, 0, old_width, old_height);
 		
@@ -364,12 +421,10 @@
 			fibril_mutex_unlock(&win->guard);
 		}
-
+		
 		surface_destroy(new_surface);
-		return;
-	}
-
-	/* Finally deallocate old surface. */
-	if (old_surface) {
-		surface_destroy(old_surface);
+	} else {
+		/* Deallocate old surface. */
+		if (old_surface)
+			surface_destroy(old_surface);
 	}
 }
@@ -453,8 +508,10 @@
 			break;
 		case ET_SIGNAL_EVENT:
-			handle_signal_event(win, event->data.sig);
+			handle_signal_event(win, event->data.signal);
 			break;
 		case ET_WINDOW_RESIZE:
-			handle_resize(win, event->data.rsz.width, event->data.rsz.height);
+			handle_resize(win, event->data.resize.offset_x,
+			    event->data.resize.offset_y, event->data.resize.width,
+			    event->data.resize.height, event->data.resize.placement_flags);
 			break;
 		case ET_WINDOW_FOCUS:
@@ -530,13 +587,10 @@
 
 window_t *window_open(const char *winreg, bool is_main, bool is_decorated,
-    const char *caption, sysarg_t x_offset, sysarg_t y_offset)
-{
-	int rc;
-
+    const char *caption)
+{
 	window_t *win = (window_t *) malloc(sizeof(window_t));
-	if (!win) {
+	if (!win)
 		return NULL;
-	}
-
+	
 	win->is_main = is_main;
 	win->is_decorated = is_decorated;
@@ -544,4 +598,5 @@
 	prodcons_initialize(&win->events);
 	fibril_mutex_initialize(&win->guard);
+	
 	widget_init(&win->root, NULL);
 	win->root.window = win;
@@ -555,24 +610,22 @@
 	win->focus = NULL;
 	win->surface = NULL;
-
+	
 	service_id_t reg_dsid;
-	async_sess_t *reg_sess;
-
-	rc = loc_service_get_id(winreg, &reg_dsid, 0);
+	int rc = loc_service_get_id(winreg, &reg_dsid, 0);
 	if (rc != EOK) {
 		free(win);
 		return NULL;
 	}
-
-	reg_sess = loc_service_connect(EXCHANGE_SERIALIZE, reg_dsid, 0);
+	
+	async_sess_t *reg_sess = loc_service_connect(EXCHANGE_SERIALIZE,
+	    reg_dsid, 0);
 	if (reg_sess == NULL) {
 		free(win);
 		return NULL;
 	}
-
+	
 	service_id_t in_dsid;
 	service_id_t out_dsid;
-	
-	rc = win_register(reg_sess, &in_dsid, &out_dsid, x_offset, y_offset);
+	rc = win_register(reg_sess, &in_dsid, &out_dsid);
 	async_hangup(reg_sess);
 	if (rc != EOK) {
@@ -580,5 +633,5 @@
 		return NULL;
 	}
-
+	
 	win->osess = loc_service_connect(EXCHANGE_SERIALIZE, out_dsid, 0);
 	if (win->osess == NULL) {
@@ -586,5 +639,5 @@
 		return NULL;
 	}
-
+	
 	win->isess = loc_service_connect(EXCHANGE_SERIALIZE, in_dsid, 0);
 	if (win->isess == NULL) {
@@ -593,15 +646,15 @@
 		return NULL;
 	}
-
-	if (caption == NULL) {
+	
+	if (caption == NULL)
 		win->caption = NULL;
-	} else {
+	else
 		win->caption = str_dup(caption);
-	}
-
+	
 	return win;
 }
 
-void window_resize(window_t *win, sysarg_t width, sysarg_t height)
+void window_resize(window_t *win, sysarg_t offset_x, sysarg_t offset_y,
+    sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags)
 {
 	window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
@@ -609,6 +662,9 @@
 		link_initialize(&event->link);
 		event->type = ET_WINDOW_RESIZE;
-		event->data.rsz.width = width;
-		event->data.rsz.height = height;
+		event->data.resize.offset_x = offset_x;
+		event->data.resize.offset_y = offset_y;
+		event->data.resize.width = width;
+		event->data.resize.height = height;
+		event->data.resize.placement_flags = placement_flags;
 		prodcons_produce(&win->events, &event->link);
 	}
Index: uspace/lib/gui/window.h
===================================================================
--- uspace/lib/gui/window.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/window.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -66,6 +66,5 @@
  * If the window is declared as main, its closure causes termination of the
  * whole application. Note that opened window does not have any surface yet. */
-extern window_t *window_open(const char *, bool, bool, const char *, sysarg_t,
-    sysarg_t);
+extern window_t *window_open(const char *, bool, bool, const char *);
 
 /**
@@ -74,5 +73,6 @@
  * and to paint themselves on the new surface (top-bottom order). Should be
  * called also after opening new window to obtain surface. */
-extern void window_resize(window_t *, sysarg_t, sysarg_t);
+extern void window_resize(window_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
+    window_placement_flags_t);
 
 /**
Index: uspace/lib/math/Makefile
===================================================================
--- uspace/lib/math/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/math/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2013 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.
+#
+
+USPACE_PREFIX = ../..
+LIBRARY = libmath
+
+SOURCES = \
+	src/dummy.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/math/src/dummy.c
===================================================================
--- uspace/lib/math/src/dummy.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/math/src/dummy.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2011 Petr Koupy
+ * Copyright (c) 2013 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 libmath
+ * @{
+ */
+/** @file Mathematical operations (dummy implementation).
+ */
+#include <math.h>
+#include <stdio.h>
+
+#define WARN_NOT_IMPLEMENTED() \
+	do { \
+		static int __not_implemented_counter = 0; \
+		if (__not_implemented_counter == 0) { \
+			fprintf(stderr, "Warning: using dummy implementation of %s().\n", \
+				__func__); \
+		} \
+		__not_implemented_counter++; \
+	} while (0)
+
+double ldexp(double x, int exp)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double frexp(double num, int *exp)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double cos(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double cosh(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double acos(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double acosh(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double pow(double x, double y)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double floor(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double ceil(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double fabs(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double modf(double x, double *iptr)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double fmod(double x, double y)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double log(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double log10(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+
+double atan2(double y, double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double sin(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double sinh(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double asin(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double asinh(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double tan(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double tanh(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double atan(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double atanh(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+
+double exp(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double expm1(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double sqrt(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double copysign(double x, double y)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+
+/** @}
+ */
Index: uspace/lib/mbr/Makefile
===================================================================
--- uspace/lib/mbr/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/mbr/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2011 Dominik Taborsky
+# 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 = ../..
+EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX)
+LIBRARY = libmbr
+
+SOURCES = \
+	libmbr.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/mbr/libmbr.c
===================================================================
--- uspace/lib/mbr/libmbr.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/mbr/libmbr.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,852 @@
+/*
+ * Copyright (c) 2011-2013 Dominik Taborsky
+ * 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 LIBMBR_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 libmbr
+ * @{
+ */
+/** @file MBR extraxtion library
+ */
+
+#include <async.h>
+#include <assert.h>
+#include <block.h>
+#include <byteorder.h>
+#include <errno.h>
+#include <ipc/bd.h>
+#include <mem.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <str_error.h>
+#include <align.h>
+#include "libmbr.h"
+
+static br_block_t *alloc_br(void);
+static int decode_part(pt_entry_t *, mbr_part_t *, uint32_t);
+static int decode_logical(mbr_label_t *, mbr_part_t *);
+static void encode_part(mbr_part_t *, pt_entry_t *, uint32_t, bool);
+static bool check_overlap(mbr_part_t *, mbr_part_t *);
+static bool check_encaps(mbr_part_t *, mbr_part_t *);
+static bool check_preceeds(mbr_part_t *, mbr_part_t *);
+static mbr_err_val mbr_add_primary(mbr_label_t *, mbr_part_t *);
+static mbr_err_val mbr_add_logical(mbr_label_t *, mbr_part_t *);
+
+/** Allocate and initialize mbr_label_t structure */
+mbr_label_t *mbr_alloc_label(void)
+{
+	mbr_label_t *label = malloc(sizeof(mbr_label_t));
+	if (label == NULL)
+		return NULL;
+	
+	label->mbr = NULL;
+	label->parts = NULL;
+	label->device = 0;
+	
+	return label;
+}
+
+void mbr_set_device(mbr_label_t *label, service_id_t dev_handle)
+{
+	label->device = dev_handle;
+}
+
+/** Free mbr_label_t structure */
+void mbr_free_label(mbr_label_t *label)
+{
+	if (label->mbr != NULL)
+		mbr_free_mbr(label->mbr);
+	
+	if (label->parts != NULL)
+		mbr_free_partitions(label->parts);
+	
+	free(label);
+}
+
+/** Allocate memory for mbr_t */
+mbr_t *mbr_alloc_mbr(void)
+{
+	return malloc(sizeof(mbr_t));
+}
+
+/** Read MBR from specific device
+ *
+ * @param label      Label to be read.
+ * @param dev_handle Device to read MBR from.
+ *
+ * @return EOK on success, error code on error.
+ *
+ */
+int mbr_read_mbr(mbr_label_t *label, service_id_t dev_handle)
+{	
+	if (label->mbr == NULL) {
+		label->mbr = mbr_alloc_mbr();
+		if (label->mbr == NULL)
+			return ENOMEM;
+	}
+	
+	int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
+	if (rc != EOK)
+		return rc;
+	
+	rc = block_read_direct(dev_handle, 0, 1, &label->mbr->raw_data);
+	block_fini(dev_handle);
+	if (rc != EOK)
+		return rc;
+	
+	label->device = dev_handle;
+	
+	return EOK;
+}
+
+/** Write MBR to specific device
+ *
+ * @param label      Label to be written.
+ * @param dev_handle Device to write MBR to.
+ *
+ * @return EOK on success, error code on error.
+ *
+ */
+int mbr_write_mbr(mbr_label_t *label, service_id_t dev_handle)
+{
+	int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
+	if (rc != EOK)
+		return rc;
+	
+	rc = block_write_direct(dev_handle, 0, 1, &label->mbr->raw_data);
+	block_fini(dev_handle);
+	
+	return rc;
+}
+
+/** Decide whether this is an actual MBR or a Protective MBR for GPT
+ *
+ * @param label Label to decide upon.
+ *
+ * @return True if MBR.
+ * @return False if Protective MBR for GPT.
+ *
+ */
+int mbr_is_mbr(mbr_label_t *label)
+{
+	return (label->mbr->raw_data.pte[0].ptype != PT_GPT);
+}
+
+/** Parse partitions from MBR (freeing previous partitions if any)
+ *
+ * It is assumed that mbr_read_mbr() was called before.
+ *
+ * @param label Label to be parsed.
+ *
+ * @return EOK on success, error code on error.
+ *
+ */
+int mbr_read_partitions(mbr_label_t *label)
+{
+	if ((label == NULL) || (label->mbr == NULL))
+		return EINVAL;
+	
+	if (label->parts != NULL)
+		mbr_free_partitions(label->parts);
+	
+	label->parts = mbr_alloc_partitions();
+	if (label->parts == NULL)
+		return ENOMEM;
+	
+	mbr_part_t *extended = NULL;
+	
+	/* Generate the primary partitions */
+	for (unsigned int i = 0; i < N_PRIMARY; i++) {
+		if (label->mbr->raw_data.pte[i].ptype == PT_UNUSED)
+			continue;
+		
+		mbr_part_t *partition = mbr_alloc_partition();
+		if (partition == NULL) {
+			mbr_free_partitions(label->parts);
+			return ENOMEM;
+		}
+		
+		int is_extended =
+		    decode_part(&label->mbr->raw_data.pte[i], partition, 0);
+		
+		mbr_set_flag(partition, ST_LOGIC, false);
+		
+		int rc = mbr_add_partition(label, partition);
+		if (rc != ERR_OK) {
+			mbr_free_partitions(label->parts);
+			return EINVAL;
+		}
+		
+		if (is_extended) {
+			extended = partition;
+			label->parts->l_extended = &partition->link;
+		}
+	}
+	
+	/* Fill in the primary partitions and generate logical ones (if any) */
+	return decode_logical(label, extended);
+}
+
+/** Write MBR and partitions to device
+ *
+ * @param label      Label to write.
+ * @param dev_handle Device to write the data to.
+ *
+ * @return EOK on success, specific error code otherwise.
+ *
+ */
+int mbr_write_partitions(mbr_label_t *label, service_id_t dev_handle)
+{
+	if (label->parts == NULL)
+		return EOK;
+	
+	if (label->mbr == NULL)
+		label->mbr = mbr_alloc_mbr();
+	
+	int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
+	if (rc != EOK)
+		return rc;
+	
+	mbr_part_t *partition = NULL;
+	mbr_part_t *extended = NULL;
+	
+	if (label->parts->l_extended != NULL)
+		extended = list_get_instance(label->parts->l_extended,
+		    mbr_part_t, link);
+	
+	link_t *link = label->parts->list.head.next;
+	
+	/* Encode primary partitions */
+	for (unsigned int i = 0; i < N_PRIMARY; i++) {
+		partition = list_get_instance(link, mbr_part_t, link);
+		
+		encode_part(partition, &label->mbr->raw_data.pte[i], 0, false);
+		link = link->next;
+	}
+	
+	/* Write MBR */
+	rc = block_write_direct(dev_handle, 0, 1, &label->mbr->raw_data);
+	if ((rc != EOK) || (extended == NULL))
+		goto end;
+	
+	uint32_t base = extended->start_addr;
+	mbr_part_t *prev_partition;
+	
+	/* Encode and write first logical partition */
+	if (link != &label->parts->list.head) {
+		partition = list_get_instance(link, mbr_part_t, link);
+		
+		partition->ebr_addr = base;
+		encode_part(partition, &partition->ebr->pte[0], base, false);
+		link = link->next;
+	} else {
+		/*
+		 * If there was an extended partition but no logical partitions,
+		 * we should overwrite the space where the first logical
+		 * partitions's EBR would have been. There might be some
+		 * garbage from the past.
+		 */
+		
+		br_block_t *br = alloc_br();
+		rc = block_write_direct(dev_handle, base, 1, br);
+		if (rc != EOK)
+			goto end;
+		
+		free(br);
+		goto end;
+	}
+	
+	prev_partition = partition;
+	
+	/*
+	 * Check EBR addresses: The code saves previous EBR
+	 * placements from other software. But if our user
+	 * modifies the logical partition chain, we have to
+	 * fix those placements if needed.
+	 */
+	
+	link_t *link_ebr = link;
+	link_t *link_iter;
+	
+	mbr_part_t tmp_partition;
+	tmp_partition.length = 1;
+	
+	while (link_ebr != &label->parts->list.head) {
+		partition = list_get_instance(link_ebr, mbr_part_t, link);
+		
+		tmp_partition.start_addr = partition->ebr_addr;
+		
+		link_iter = link;
+		while (link_iter != &label->parts->list.head) {
+			/*
+			 * Check whether EBR address makes sense. If not, we take
+			 * a guess.  So far this is simple, we just take the first
+			 * preceeding sector. FDisk always reserves at least 2048
+			 * sectors (1 MiB), so it can have the EBR aligned as well
+			 * as the partition itself. Parted reserves minimum one
+			 * sector, like we do.
+			 *
+			 * Note that we know there is at least one sector free from
+			 * previous checks. Also note that the user can set ebr_addr
+			 * to their liking (if it is valid).
+			 */
+			
+			if ((partition->ebr_addr < base) ||
+			    (partition->ebr_addr >= base + extended->length) ||
+			    (check_overlap(&tmp_partition,
+			    list_get_instance(link_iter, mbr_part_t, link)))) {
+				partition->ebr_addr = partition->start_addr - 1;
+				break;
+			}
+			
+			link_iter = link_iter->next;
+		}
+		
+		link_ebr = link_ebr->next;
+	}
+	
+	/* Encode and write logical partitions */
+	while (link != &label->parts->list.head) {
+		partition = list_get_instance(link, mbr_part_t, link);
+		
+		encode_part(partition, &partition->ebr->pte[0],
+		    partition->ebr_addr, false);
+		encode_part(partition, &prev_partition->ebr->pte[1],
+		    base, true);
+		
+		rc = block_write_direct(dev_handle, prev_partition->ebr_addr, 1,
+		    prev_partition->ebr);
+		if (rc != EOK)
+			goto end;
+		
+		prev_partition = partition;
+		link = link->next;
+	}
+	
+	/* Write the last EBR */
+	encode_part(NULL, &prev_partition->ebr->pte[1], 0, false);
+	rc = block_write_direct(dev_handle, prev_partition->ebr_addr,
+	    1, prev_partition->ebr);
+	
+end:
+	block_fini(dev_handle);
+	return rc;
+}
+
+/** Partition constructor */
+mbr_part_t *mbr_alloc_partition(void)
+{
+	mbr_part_t *partition = malloc(sizeof(mbr_part_t));
+	if (partition == NULL)
+		return NULL;
+	
+	link_initialize(&partition->link);
+	partition->ebr = NULL;
+	partition->type = PT_UNUSED;
+	partition->status = 0;
+	partition->start_addr = 0;
+	partition->length = 0;
+	partition->ebr_addr = 0;
+	
+	return partition;
+}
+
+/** Partitions constructor */
+mbr_partitions_t *mbr_alloc_partitions(void)
+{
+	mbr_partitions_t *parts = malloc(sizeof(mbr_partitions_t));
+	if (parts == NULL)
+		return NULL;
+	
+	list_initialize(&parts->list);
+	parts->n_primary = 0;
+	parts->n_logical = 0;
+	parts->l_extended = NULL;
+	
+	/* Add blank primary partitions */
+	for (unsigned int i = 0; i < N_PRIMARY; ++i) {
+		mbr_part_t *part = mbr_alloc_partition();
+		if (part == NULL) {
+			mbr_free_partitions(parts);
+			return NULL;
+		}
+		
+		list_append(&part->link, &parts->list);
+	}
+	
+	return parts;
+}
+
+/** Add partition
+ *
+ * Perform checks, sort the list.
+ *
+ * @param label Label to add to.
+ * @param part  Partition to add.
+ *
+ * @return ERR_OK on success, other MBR_ERR_VAL otherwise
+ *
+ */
+mbr_err_val mbr_add_partition(mbr_label_t *label, mbr_part_t *part)
+{
+	int rc = block_init(EXCHANGE_ATOMIC, label->device, 512);
+	if ((rc != EOK) && (rc != EEXIST))
+		return ERR_LIBBLOCK;
+	
+	aoff64_t nblocks;
+	int ret = block_get_nblocks(label->device, &nblocks);
+	
+	if (rc != EEXIST)
+		block_fini(label->device);
+	
+	if (ret != EOK)
+		return ERR_LIBBLOCK;
+	
+	if ((aoff64_t) part->start_addr + part->length > nblocks)
+		return ERR_OUT_BOUNDS;
+	
+	if (label->parts == NULL) {
+		label->parts = mbr_alloc_partitions();
+		if (label->parts == NULL)
+			// FIXME! merge mbr_err_val into errno.h
+			return ENOMEM;
+	}
+	
+	if (mbr_get_flag(part, ST_LOGIC))
+		return mbr_add_logical(label, part);
+	else
+		return mbr_add_primary(label, part);
+}
+
+/** Remove partition
+ *
+ * Remove partition (indexed from zero). When removing the extended
+ * partition, all logical partitions get removed as well.
+ *
+ * @param label Label to remove from.
+ * @param idx   Index of the partition to remove.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the index is invalid.
+ *
+ */
+int mbr_remove_partition(mbr_label_t *label, size_t idx)
+{
+	link_t *link = list_nth(&label->parts->list, idx);
+	if (link == NULL)
+		return EINVAL;
+	
+	/*
+	 * If removing the extended partition, remove all
+	 * logical partitions as well.
+	 */
+	if (link == label->parts->l_extended) {
+		label->parts->l_extended = NULL;
+		
+		link_t *iterator = link->next;
+		link_t *next;
+		
+		while (iterator != &label->parts->list.head) {
+			next = iterator->next;
+			mbr_part_t *partition =
+			    list_get_instance(iterator, mbr_part_t, link);
+			
+			if (mbr_get_flag(partition, ST_LOGIC)) {
+				list_remove(iterator);
+				label->parts->n_logical--;
+				mbr_free_partition(partition);
+			}
+			
+			iterator = next;
+		}
+	}
+	
+	/* Remove the partition itself */
+	mbr_part_t *partition =
+	    list_get_instance(link, mbr_part_t, link);
+	
+	if (mbr_get_flag(partition, ST_LOGIC)) {
+		label->parts->n_logical--;
+		list_remove(link);
+		mbr_free_partition(partition);
+	} else {
+		/*
+		 * Cannot remove a primary partition without
+		 * breaking the ordering. Just zero it.
+		 */
+		label->parts->n_primary--;
+		partition->type = 0;
+		partition->status = 0;
+		partition->start_addr = 0;
+		partition->length = 0;
+		partition->ebr_addr = 0;
+	}
+	
+	return EOK;
+}
+
+/** Partition destructor */
+void mbr_free_partition(mbr_part_t *partition)
+{
+	if (partition->ebr != NULL)
+		free(partition->ebr);
+	
+	free(partition);
+}
+
+/** Check for flag */
+int mbr_get_flag(mbr_part_t *partition, mbr_flags_t flag)
+{
+	return (partition->status & (1 << flag));
+}
+
+/** Set a specific status flag */
+void mbr_set_flag(mbr_part_t *partition, mbr_flags_t flag, bool set)
+{
+	if (set)
+		partition->status |= 1 << flag;
+	else
+		partition->status &= ~((uint16_t) (1 << flag));
+}
+
+/** Get next aligned address */
+uint32_t mbr_get_next_aligned(uint32_t addr, unsigned int alignment)
+{
+	return ALIGN_UP(addr + 1, alignment);
+}
+
+list_t *mbr_get_list(mbr_label_t *label)
+{
+	if (label->parts != NULL)
+		return &label->parts->list;
+	else
+		return NULL;
+}
+
+mbr_part_t *mbr_get_first_partition(mbr_label_t *label)
+{
+	list_t *list = mbr_get_list(label);
+	if ((list != NULL) && (!list_empty(list)))
+		return list_get_instance(list->head.next, mbr_part_t, link);
+	else
+		return NULL;
+}
+
+mbr_part_t *mbr_get_next_partition(mbr_label_t *label, mbr_part_t *partition)
+{
+	list_t *list = mbr_get_list(label);
+	if ((list != NULL) && (&partition->link != list_last(list)))
+		return list_get_instance(partition->link.next, mbr_part_t, link);
+	else
+		return NULL;
+}
+
+void mbr_free_mbr(mbr_t *mbr)
+{
+	free(mbr);
+}
+
+/** Free partition list
+ *
+ * @param parts Partition list to be freed
+ *
+ */
+void mbr_free_partitions(mbr_partitions_t *parts)
+{
+	list_foreach_safe(parts->list, cur_link, next) {
+		mbr_part_t *partition = list_get_instance(cur_link, mbr_part_t, link);
+		list_remove(cur_link);
+		mbr_free_partition(partition);
+	}
+	
+	free(parts);
+}
+
+static br_block_t *alloc_br(void)
+{
+	br_block_t *br = malloc(sizeof(br_block_t));
+	if (br == NULL)
+		return NULL;
+	
+	memset(br, 0, 512);
+	br->signature = host2uint16_t_le(BR_SIGNATURE);
+	
+	return br;
+}
+
+/** Decode partition entry */
+static int decode_part(pt_entry_t *src, mbr_part_t *partition, uint32_t base)
+{
+	partition->type = src->ptype;
+	partition->status = (partition->status & 0xff00) | (uint16_t) src->status;
+	partition->start_addr = uint32_t_le2host(src->first_lba) + base;
+	partition->length = uint32_t_le2host(src->length);
+	
+	return (src->ptype == PT_EXTENDED);
+}
+
+/** Parse logical partitions */
+static int decode_logical(mbr_label_t *label, mbr_part_t *extended)
+{
+	if (extended == NULL)
+		return EOK;
+	
+	br_block_t *ebr = alloc_br();
+	if (ebr == NULL)
+		return ENOMEM;
+	
+	uint32_t base = extended->start_addr;
+	uint32_t addr = base;
+	
+	int rc = block_init(EXCHANGE_ATOMIC, label->device, 512);
+	if (rc != EOK)
+		goto end;
+	
+	rc = block_read_direct(label->device, addr, 1, ebr);
+	if (rc != EOK)
+		goto end;
+	
+	if (uint16_t_le2host(ebr->signature) != BR_SIGNATURE) {
+		rc = EINVAL;
+		goto end;
+	}
+	
+	if (ebr->pte[0].ptype == PT_UNUSED) {
+		rc = EOK;
+		goto end;
+	}
+	
+	mbr_part_t *partition = mbr_alloc_partition();
+	if (partition == NULL) {
+		rc = ENOMEM;
+		goto end;
+	}
+	
+	decode_part(&ebr->pte[0], partition, base);
+	mbr_set_flag(partition, ST_LOGIC, true);
+	partition->ebr = ebr;
+	partition->ebr_addr = addr;
+	
+	rc = mbr_add_partition(label, partition);
+	if (rc != ERR_OK)
+		goto end;
+	
+	addr = uint32_t_le2host(ebr->pte[1].first_lba) + base;
+	
+	while (ebr->pte[1].ptype != PT_UNUSED) {
+		rc = block_read_direct(label->device, addr, 1, ebr);
+		if (rc != EOK)
+			goto end;
+		
+		if (uint16_t_le2host(ebr->signature) != BR_SIGNATURE) {
+			rc = EINVAL;
+			goto end;
+		}
+		
+		mbr_part_t *partition = mbr_alloc_partition();
+		if (partition == NULL) {
+			rc = ENOMEM;
+			goto end;
+		}
+		
+		decode_part(&ebr->pte[0], partition, addr);
+		mbr_set_flag(partition, ST_LOGIC, true);
+		partition->ebr = ebr;
+		partition->ebr_addr = addr;
+		
+		rc = mbr_add_partition(label, partition);
+		if (rc != ERR_OK)
+			goto end;
+		
+		addr = uint32_t_le2host(ebr->pte[1].first_lba) + base;
+	}
+	
+	rc = EOK;
+	
+end:
+	// FIXME possible memory leaks
+	block_fini(label->device);
+	
+	return rc;
+}
+
+/** Encode partition entry */
+static void encode_part(mbr_part_t *src, pt_entry_t *entry, uint32_t base,
+    bool ebr)
+{
+	if (src != NULL) {
+		entry->status = (uint8_t) src->status & 0xff;
+		
+		/* Ignore CHS */
+		entry->first_chs[0] = 0xfe;
+		entry->first_chs[1] = 0xff;
+		entry->first_chs[2] = 0xff;
+		entry->last_chs[0] = 0xfe;
+		entry->last_chs[1] = 0xff;
+		entry->last_chs[2] = 0xff;
+		
+		if (ebr) {
+			/* Encode reference to EBR */
+			entry->ptype = PT_EXTENDED_LBA;
+			entry->first_lba = host2uint32_t_le(src->ebr_addr - base);
+			entry->length = host2uint32_t_le(src->length + src->start_addr -
+			    src->ebr_addr);
+		} else {
+			/* Encode reference to partition */
+			entry->ptype = src->type;
+			entry->first_lba = host2uint32_t_le(src->start_addr - base);
+			entry->length = host2uint32_t_le(src->length);
+		}
+		
+		if (entry->ptype == PT_UNUSED)
+			memset(entry, 0, sizeof(pt_entry_t));
+	} else
+		memset(entry, 0, sizeof(pt_entry_t));
+}
+
+/** Check whether two partitions overlap */
+static bool check_overlap(mbr_part_t *part1, mbr_part_t *part2)
+{
+	if ((part1->start_addr < part2->start_addr) &&
+	    (part1->start_addr + part1->length <= part2->start_addr))
+		return false;
+	
+	if ((part1->start_addr > part2->start_addr) &&
+	    (part2->start_addr + part2->length <= part1->start_addr))
+		return false;
+	
+	return true;
+}
+
+/** Check whether one partition encapsulates the other */
+static bool check_encaps(mbr_part_t *inner, mbr_part_t *outer)
+{
+	if ((inner->start_addr <= outer->start_addr) ||
+	    (outer->start_addr + outer->length <= inner->start_addr))
+		return false;
+	
+	if (outer->start_addr + outer->length < inner->start_addr + inner->length)
+		return false;
+	
+	return true;
+}
+
+/** Check whether one partition preceeds the other */
+static bool check_preceeds(mbr_part_t *preceeder, mbr_part_t *precedee)
+{
+	return preceeder->start_addr < precedee->start_addr;
+}
+
+mbr_err_val mbr_add_primary(mbr_label_t *label, mbr_part_t *part)
+{
+	if (label->parts->n_primary == 4)
+		return ERR_PRIMARY_FULL;
+	
+	/* Check if partition makes space for MBR itself */
+	if (part->start_addr == 0)
+		return ERR_OUT_BOUNDS;
+	
+	/* If it is an extended partition, is there any other one? */
+	if (((part->type == PT_EXTENDED) || (part->type == PT_EXTENDED_LBA)) &&
+	    (label->parts->l_extended != NULL))
+		return ERR_EXTENDED_PRESENT;
+	
+	/* Find a place and add it */
+	mbr_part_t *iter;
+	mbr_part_t *empty = NULL;
+	mbr_part_foreach(label, iter) {
+		if (iter->type == PT_UNUSED) {
+			if (empty == NULL)
+				empty = iter;
+		} else if (check_overlap(part, iter))
+			return ERR_OVERLAP;
+	}
+	
+	list_insert_after(&part->link, &empty->link);
+	list_remove(&empty->link);
+	free(empty);
+	
+	label->parts->n_primary++;
+	
+	if ((part->type == PT_EXTENDED) || (part->type == PT_EXTENDED_LBA))
+		label->parts->l_extended = &part->link;
+	
+	return EOK;
+}
+
+mbr_err_val mbr_add_logical(mbr_label_t *label, mbr_part_t *part)
+{
+	/* Is there any extended partition? */
+	if (label->parts->l_extended == NULL)
+		return ERR_NO_EXTENDED;
+	
+	/* Is the logical partition inside the extended partition? */
+	mbr_part_t *extended = list_get_instance(label->parts->l_extended, mbr_part_t, link);
+	if (!check_encaps(part, extended))
+		return ERR_OUT_BOUNDS;
+	
+	/* Find a place for the new partition in a sorted linked list */
+	bool first_logical = true;
+	mbr_part_t *iter;
+	mbr_part_foreach (label, iter) {
+		if (mbr_get_flag(iter, ST_LOGIC)) {
+			if (check_overlap(part, iter))
+				return ERR_OVERLAP;
+			
+			if (check_preceeds(iter, part)) {
+				/* Check if there is at least one sector of space preceeding */
+				if ((iter->start_addr + iter->length) >= part->start_addr - 1)
+					return ERR_NO_EBR;
+			} else if (first_logical) {
+				/*
+				 * First logical partition's EBR is before every other
+				 * logical partition. Thus we do not check if this partition
+				 * leaves enough space for it.
+				 */
+				first_logical = false;
+			} else {
+				/*
+				 * Check if there is at least one sector of space following
+				 * (for following partitions's EBR).
+				 */
+				if ((part->start_addr + part->length) >= iter->start_addr - 1)
+					return ERR_NO_EBR;
+			}
+		}
+	}
+	
+	/* Allocate EBR if it is not already there */
+	if (part->ebr == NULL) {
+		part->ebr = alloc_br();
+		if (part->ebr == NULL)
+			return ERR_NOMEM;
+	}
+	
+	list_append(&part->link, &label->parts->list);
+	label->parts->n_logical++;
+	
+	return EOK;
+}
Index: uspace/lib/mbr/libmbr.h
===================================================================
--- uspace/lib/mbr/libmbr.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/mbr/libmbr.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * Copyright (c) 2011-2013 Dominik Taborsky
+ * 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 libmbr
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBMBR_LIBMBR_H_
+#define LIBMBR_LIBMBR_H_
+
+#include <sys/types.h>
+#include "mbr.h"
+
+/*
+ * WARNING: When changing both header and partitions, write first header,
+ * then partitions. The MBR headers' raw_data is not updated to follow
+ * partition changes.
+ *
+ * NOTE: Writing partitions writes the complete header as well.
+ */
+
+typedef enum {
+	/** Other flags unknown - saving previous state */
+	/** Bootability */
+	ST_BOOT = 7,
+	/** Logical partition, 0 = primary, 1 = logical*/
+	ST_LOGIC = 8
+} mbr_flags_t;
+
+typedef enum {
+	/** No error */
+	ERR_OK = 0,
+	/** All primary partitions already present */
+	ERR_PRIMARY_FULL,
+	/** Extended partition already present */
+	ERR_EXTENDED_PRESENT,
+	/** No extended partition present */
+	ERR_NO_EXTENDED,
+	/** Partition overlapping */
+	ERR_OVERLAP,
+	/** Partition out of bounds */
+	ERR_OUT_BOUNDS,
+	/** No space left for EBR */
+	ERR_NO_EBR,
+	/** Out of memory */
+	ERR_NOMEM,
+	/** Libblock error */
+	ERR_LIBBLOCK,
+} mbr_err_val;
+
+/** MBR header */
+typedef struct {
+	/** Raw access to data */
+	br_block_t raw_data;
+} mbr_t;
+
+/** Partition */
+typedef struct mbr_part {
+	/** The link in the doubly-linked list */
+	link_t link;
+	/** Partition type */
+	uint8_t type;
+	/** Flags */
+	uint16_t status;
+	/** Address of first block */
+	uint32_t start_addr;
+	/** Number of blocks */
+	uint32_t length;
+	/** Points to Extended Boot Record of logical partition */
+	br_block_t *ebr;
+	/** EBR address */
+	uint32_t ebr_addr;
+} mbr_part_t;
+
+/** Partition list structure */
+typedef struct mbr_parts {
+	/** Number of primary partitions */
+	unsigned char n_primary;
+	/** Index to the extended partition in the array */
+	link_t *l_extended;
+	/** Number of logical partitions */
+	unsigned int n_logical;
+	/** Logical partition linked list */
+	list_t list;
+} mbr_partitions_t;
+
+/** Both header and partition list */
+typedef struct mbr_label {
+	/** MBR header */
+	mbr_t *mbr;
+	/** Partition list */
+	mbr_partitions_t * parts;
+	/** Device where the data are from (or for) */
+	service_id_t device;
+} mbr_label_t;
+
+#define mbr_part_foreach(label, iterator) \
+	for (iterator = list_get_instance((label)->parts->list.head.next, mbr_part_t, link); \
+	    iterator != list_get_instance(&((label)->parts->list.head), mbr_part_t, link); \
+	    iterator = list_get_instance(iterator->link.next, mbr_part_t, link))
+
+extern mbr_label_t *mbr_alloc_label(void);
+
+extern void mbr_set_device(mbr_label_t *, service_id_t);
+extern mbr_t *mbr_alloc_mbr(void);
+extern int mbr_read_mbr(mbr_label_t *, service_id_t);
+extern int mbr_write_mbr(mbr_label_t *, service_id_t);
+extern int mbr_is_mbr(mbr_label_t *);
+
+extern int mbr_read_partitions(mbr_label_t *);
+extern int mbr_write_partitions(mbr_label_t *, service_id_t);
+extern mbr_part_t *mbr_alloc_partition(void);
+extern mbr_partitions_t *mbr_alloc_partitions(void);
+extern mbr_err_val mbr_add_partition(mbr_label_t *, mbr_part_t *);
+extern int mbr_remove_partition(mbr_label_t *, size_t);
+extern int mbr_get_flag(mbr_part_t *, mbr_flags_t);
+extern void mbr_set_flag(mbr_part_t *, mbr_flags_t, bool);
+extern uint32_t mbr_get_next_aligned(uint32_t, unsigned int);
+extern list_t *mbr_get_list(mbr_label_t *);
+extern mbr_part_t *mbr_get_first_partition(mbr_label_t *);
+extern mbr_part_t *mbr_get_next_partition(mbr_label_t *, mbr_part_t *);
+
+extern void mbr_free_label(mbr_label_t *);
+extern void mbr_free_mbr(mbr_t *);
+extern void mbr_free_partition(mbr_part_t *);
+extern void mbr_free_partitions(mbr_partitions_t *);
+
+#endif
Index: uspace/lib/mbr/mbr.h
===================================================================
--- uspace/lib/mbr/mbr.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/mbr/mbr.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * Copyright (c) 2011-2013 Dominik Taborsky
+ * 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 libmbr
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBMBR_MBR_H_
+#define LIBMBR_MBR_H_
+
+#include <sys/types.h>
+
+enum {
+	/** Number of primary partition records */
+	N_PRIMARY = 4,
+	
+	/** Boot record signature */
+	BR_SIGNATURE = 0xAA55
+};
+
+enum {
+	/** Non-bootable */
+	B_INACTIVE = 0x00,
+	/** Bootable */
+	B_ACTIVE = 0x80,
+	/** Anything else means invalid */
+};
+
+enum {
+	/** Unused partition entry */
+	PT_UNUSED = 0x00,
+	/** Extended partition */
+	PT_EXTENDED = 0x05,
+	/** Extended partition with LBA */
+	PT_EXTENDED_LBA = 0x0F,
+	/** GPT Protective partition */
+	PT_GPT = 0xEE,
+};
+
+/** Structure of a partition table entry */
+typedef struct {
+	uint8_t status;
+	/** CHS of fist block in partition */
+	uint8_t first_chs[3];
+	/** Partition type */
+	uint8_t ptype;
+	/** CHS of last block in partition */
+	uint8_t last_chs[3];
+	/** LBA of first block in partition */
+	uint32_t first_lba;
+	/** Number of blocks in partition */
+	uint32_t length;
+} __attribute__((packed)) pt_entry_t;
+
+/** Structure of a boot-record block */
+typedef struct {
+	/** Area for boot code */
+	uint8_t code_area[440];
+	/** Optional media ID */
+	uint32_t media_id;
+	/** Padding */
+	uint16_t pad0;
+	/** Partition table entries */
+	pt_entry_t pte[N_PRIMARY];
+	/** Boot record block signature (@c BR_SIGNATURE) */
+	uint16_t signature;
+} __attribute__((packed)) br_block_t;
+
+#endif
+
Index: uspace/lib/nic/Makefile
===================================================================
--- uspace/lib/nic/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/nic/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -30,4 +30,5 @@
 LIBRARY = libnic
 EXTRA_CFLAGS += -DLIBNIC_INTERNAL -Iinclude -I$(LIBDRV_PREFIX)/include
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
 
 SOURCES = \
Index: uspace/lib/nic/src/nic_ev.c
===================================================================
--- uspace/lib/nic/src/nic_ev.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/nic/src/nic_ev.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -37,5 +37,5 @@
 
 #include <async.h>
-#include <device/nic.h>
+#include <nic_iface.h>
 #include <errno.h>
 #include "nic_ev.h"
Index: uspace/lib/posix/Makefile
===================================================================
--- uspace/lib/posix/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/posix/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -60,5 +60,4 @@
 	source/getopt.c \
 	source/locale.c \
-	source/math.c \
 	source/pthread/condvar.c \
 	source/pthread/keys.c \
Index: uspace/lib/posix/include/posix/float.h
===================================================================
--- uspace/lib/posix/include/posix/float.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/posix/include/posix/float.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -59,4 +59,6 @@
 	#undef DBL_EPSILON
 	#define DBL_EPSILON __DBL_EPSILON__
+	#undef LDBL_EPSILON
+	#define LDBL_EPSILON __LDBL_EPSILON__
 	#undef FLT_RADIX
 	#define FLT_RADIX __FLT_RADIX__
@@ -69,4 +71,8 @@
 	#undef FLT_MANT_DIG
 	#define FLT_MANT_DIG __FLT_MANT_DIG__
+	#undef LDBL_MIN
+	#define LDBL_MIN __LDBL_MIN__
+	#undef LDBL_MAX
+	#define LDBL_MAX __LDBL_MAX__
 	#undef LDBL_MANT_DIG 
 	#define LDBL_MANT_DIG __LDBL_MANT_DIG__
Index: uspace/lib/posix/include/posix/math.h
===================================================================
--- uspace/lib/posix/include/posix/math.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/posix/include/posix/math.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -36,27 +36,5 @@
 #define POSIX_MATH_H_
 
-#ifndef __POSIX_DEF__
-#define __POSIX_DEF__(x) x
-#endif
-
-#ifdef __GNUC__
-	#define HUGE_VAL (__builtin_huge_val())
-#endif
-
-/* Normalization Functions */
-extern double __POSIX_DEF__(ldexp)(double x, int exp);
-extern double __POSIX_DEF__(frexp)(double num, int *exp);
-
-double __POSIX_DEF__(fabs)(double x);
-double __POSIX_DEF__(floor)(double x);
-double __POSIX_DEF__(modf)(double x, double *iptr);
-double __POSIX_DEF__(fmod)(double x, double y);
-double __POSIX_DEF__(pow)(double x, double y);
-double __POSIX_DEF__(exp)(double x);
-double __POSIX_DEF__(sqrt)(double x);
-double __POSIX_DEF__(log)(double x);
-double __POSIX_DEF__(sin)(double x);
-double __POSIX_DEF__(cos)(double x);
-double __POSIX_DEF__(atan2)(double y, double x);
+#include "libc/math.h"
 
 #endif /* POSIX_MATH_H_ */
Index: uspace/lib/posix/include/posix/setjmp.h
===================================================================
--- uspace/lib/posix/include/posix/setjmp.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/posix/include/posix/setjmp.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013 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 libposix
+ * @{
+ */
+
+/*
+ * Just a pass-through to libc setjmp.
+ */
+#include "libc/setjmp.h"
+
+/** @}
+ */
Index: uspace/lib/posix/include/posix/stdlib.h
===================================================================
--- uspace/lib/posix/include/posix/stdlib.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/posix/include/posix/stdlib.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -56,5 +56,5 @@
 #define _Exit exit
 extern int __POSIX_DEF__(atexit)(void (*func)(void));
-extern void exit(int status);
+extern void exit(int status) __attribute__((noreturn));
 extern void abort(void) __attribute__((noreturn));
 
Index: uspace/lib/posix/source/math.c
===================================================================
--- uspace/lib/posix/source/math.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,204 +1,0 @@
-/*
- * Copyright (c) 2011 Petr Koupy
- * 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 libposix
- * @{
- */
-/** @file Mathematical operations.
- */
-
-#define LIBPOSIX_INTERNAL
-#define __POSIX_DEF__(x) posix_##x
-
-#include "internal/common.h"
-#include "posix/math.h"
-
-/**
- * 
- * @param x
- * @param exp
- * @return
- */
-double posix_ldexp(double x, int exp)
-{
-	// TODO: low priority, just a compile-time dependency of binutils
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param num
- * @param exp
- * @return
- */
-double posix_frexp(double num, int *exp)
-{
-	// TODO: low priority, just a compile-time dependency of binutils
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @return
- */
-double posix_cos(double x)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @param y
- * @return
- */
-double posix_pow(double x, double y)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @return
- */
-double posix_floor(double x)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @return
- */
-double posix_fabs(double x)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @param iptr
- * @return
- */
-double posix_modf(double x, double *iptr)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @param y
- * @return
- */
-double posix_fmod(double x, double y)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @return
- */
-double posix_log(double x)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @param y
- * @return
- */
-double posix_atan2(double y, double x)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @return
- */
-double posix_sin(double x)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @return
- */
-double posix_exp(double x)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @return
- */
-double posix_sqrt(double x)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/** @}
- */
Index: uspace/lib/softfloat/softfloat.c
===================================================================
--- uspace/lib/softfloat/softfloat.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/softfloat/softfloat.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -1265,4 +1265,15 @@
 }
 
+float __aeabi_d2f(double a)
+{
+	return __truncdfsf2(a);
+}
+
+double __aeabi_f2d(float a)
+{
+	return __extendsfdf2(a);
+}
+
+
 float __aeabi_i2f(int i)
 {
@@ -1285,4 +1296,19 @@
 }
 
+double __aeabi_l2d(long long i)
+{
+	return __floattidf(i);
+}
+
+float __aeabi_l2f(long long i)
+{
+	return __floattisf(i);
+}
+
+float __aeabi_ul2f(unsigned long long u)
+{
+	return __floatuntisf(u);
+}
+
 int __aeabi_f2iz(float a)
 {
@@ -1305,4 +1331,9 @@
 }
 
+long long __aeabi_d2lz(double a)
+{
+	return __fixdfti(a);
+}
+
 int __aeabi_fcmpge(float a, float b)
 {
@@ -1339,4 +1370,10 @@
 	return __ltdf2(a, b);
 }
+
+int __aeabi_dcmple(double a, double b)
+{
+	return __ledf2(a, b);
+}
+
 
 int __aeabi_dcmpeq(double a, double b)
Index: uspace/lib/softfloat/softfloat.h
===================================================================
--- uspace/lib/softfloat/softfloat.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/softfloat/softfloat.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -204,9 +204,15 @@
 
 /* ARM EABI */
+extern float __aeabi_d2f(double);
+extern double __aeabi_f2d(float);
 extern float __aeabi_i2f(int);
 extern float __aeabi_ui2f(int);
 extern double __aeabi_i2d(int);
 extern double __aeabi_ui2d(unsigned int);
+extern double __aeabi_l2d(long long);
+extern float __aeabi_l2f(long long);
+extern float __aeabi_ul2f(unsigned long long);
 extern unsigned int __aeabi_d2uiz(double);
+extern long long __aeabi_d2lz(double);
 
 extern int __aeabi_f2iz(float);
@@ -222,4 +228,5 @@
 extern int __aeabi_dcmpgt(double, double);
 extern int __aeabi_dcmplt(double, double);
+extern int __aeabi_dcmple(double, double);
 extern int __aeabi_dcmpeq(double, double);
 
Index: uspace/lib/softint/Makefile
===================================================================
--- uspace/lib/softint/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/softint/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -35,4 +35,5 @@
 
 SOURCES = \
+	generic/bits.c \
 	generic/comparison.c \
 	generic/division.c \
Index: uspace/lib/softint/generic/bits.c
===================================================================
--- uspace/lib/softint/generic/bits.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/softint/generic/bits.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2013 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 softint
+ * @{
+ */
+
+#include <bits.h>
+
+/** Compute number of trailing 0-bits in a number. */
+int __ctzdi2(long a)
+{
+	unsigned int bits = 0;
+	while (((a >> bits) & 1) == 0) {
+		bits++;
+		if (bits >= sizeof(a) * 8) {
+			break;
+		}
+	}
+
+	return bits;
+}
+
+/** Compute number of trailing 0-bits in a number. */
+int __ctzsi2(int a)
+{
+	unsigned int bits = 0;
+	while (((a >> bits) & 1) == 0) {
+		bits++;
+		if (bits >= sizeof(a) * 8) {
+			break;
+		}
+	}
+
+	return bits;
+}
+
+/** Compute number of leading 0-bits in a number. */
+int __clzdi2(long a)
+{
+	int index = sizeof(a) * 8 - 1;
+	int bits = 0;
+	while (index >= 0) {
+		if (((a >> index) & 1) == 0) {
+			bits++;
+		} else {
+			break;
+		}
+		index--;
+	}
+
+	return bits;
+}
+
+/** Compute index of the first 1-bit in a number increased by one.
+ *
+ * If the number is zero, zero is returned.
+ */
+int __ffsdi2(long a) {
+	if (a == 0) {
+		return 0;
+	}
+
+	return 1 + __ctzdi2(a);
+}
+
+/** Compute number of set bits in a number. */
+int __popcountsi2(int a)
+{
+	int bits = 0;
+	for (unsigned int i = 0; i < sizeof(a) * 8; i++)	 {
+		if (((a >> i) & 1) != 0) {
+			bits++;
+		}
+	}
+	return bits;									
+}
+
+/** Compute number of set bits in a number. */
+int __popcountdi2(long a)
+{
+	int bits = 0;
+	for (unsigned int i = 0; i < sizeof(a) * 8; i++)	 {
+		if (((a >> i) & 1) != 0) {
+			bits++;
+		}
+	}
+	return bits;									
+}
+
+/** @}
+ */
Index: uspace/lib/softint/generic/shift.c
===================================================================
--- uspace/lib/softint/generic/shift.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/softint/generic/shift.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -123,4 +123,9 @@
 }
 
+long long __aeabi_llsl(long long val, int shift)
+{
+	return __ashldi3(val, shift);
+}
+
 /** @}
  */
Index: uspace/lib/softint/include/bits.h
===================================================================
--- uspace/lib/softint/include/bits.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/lib/softint/include/bits.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013 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 softint
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __SOFTINT_BITS_H_
+#define __SOFTINT_BITS_H_
+
+extern int __ctzdi2(long);
+extern int __ctzsi2(int);
+extern int __clzdi2(long);
+extern int __ffsdi2(long);
+extern int __popcountsi2(int);
+extern int __popcountdi2(long);
+
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/softint/include/shift.h
===================================================================
--- uspace/lib/softint/include/shift.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/softint/include/shift.h	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -46,4 +46,8 @@
 extern long long __lshrdi3(long long, int);
 
+
+/* ARM EABI */
+extern long long __aeabi_llsl(long long, int);
+
 #endif
 
Index: uspace/lib/usbhid/Makefile
===================================================================
--- uspace/lib/usbhid/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/usbhid/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -37,5 +37,4 @@
 SOURCES = \
 	src/hiddescriptor.c \
-	src/hidiface.c \
 	src/hidparser.c \
 	src/hidpath.c \
Index: uspace/lib/usbhid/include/usb/hid/iface.h
===================================================================
--- uspace/lib/usbhid/include/usb/hid/iface.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,51 +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 libusbhid
- * @{
- */
-/** @file
- * Client functions for accessing USB HID interface.
- */
-#ifndef LIBUSBHID_CLASSES_HID_IFACE_H_
-#define LIBUSBHID_CLASSES_HID_IFACE_H_
-
-#include <sys/types.h>
-#include <async.h>
-
-extern int usbhid_dev_get_event_length(async_sess_t *, size_t *);
-extern int usbhid_dev_get_event(async_sess_t *, uint8_t *, size_t, size_t *,
-    int *, unsigned int);
-extern int usbhid_dev_get_report_descriptor_length(async_sess_t *, size_t *);
-extern int usbhid_dev_get_report_descriptor(async_sess_t *, uint8_t *, size_t,
-    size_t *);
-
-#endif
-/**
- * @}
- */
Index: uspace/lib/usbhid/src/hidiface.c
===================================================================
--- uspace/lib/usbhid/src/hidiface.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,239 +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 libusbhid
- * @{
- */
-/** @file
- * Client functions for accessing USB HID interface (implementation).
- */
-
-#include <dev_iface.h>
-#include <usbhid_iface.h>
-#include <usb/hid/iface.h>
-#include <errno.h>
-#include <str_error.h>
-#include <async.h>
-#include <assert.h>
-
-/** Ask for event array length.
- *
- * @param dev_sess Session to DDF device providing USB HID interface.
- *
- * @return Number of usages returned or negative error code.
- *
- */
-int usbhid_dev_get_event_length(async_sess_t *dev_sess, size_t *size)
-{
-	if (!dev_sess)
-		return EINVAL;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	sysarg_t len;
-	int rc = async_req_1_1(exch, DEV_IFACE_ID(USBHID_DEV_IFACE),
-	    IPC_M_USBHID_GET_EVENT_LENGTH, &len);
-	
-	async_exchange_end(exch);
-	
-	if (rc == EOK) {
-		if (size != NULL)
-			*size = (size_t) len;
-	}
-	
-	return rc;
-}
-
-/** Request for next event from HID device.
- *
- * @param[in]  dev_sess    Session to DDF device providing USB HID interface.
- * @param[out] usage_pages Where to store usage pages.
- * @param[out] usages      Where to store usages (actual data).
- * @param[in]  usage_count Length of @p usage_pages and @p usages buffer
- *                         (in items, not bytes).
- * @param[out] actual_usage_count Number of usages actually returned by the
- *                                device driver.
- * @param[in] flags        Flags (see USBHID_IFACE_FLAG_*).
- *
- * @return Error code.
- *
- */
-int usbhid_dev_get_event(async_sess_t *dev_sess, uint8_t *buf,
-    size_t size, size_t *actual_size, int *event_nr, unsigned int flags)
-{
-	if (!dev_sess)
-		return EINVAL;
-	
-	if (buf == NULL)
-		return ENOMEM;
-	
-	if (size == 0)
-		return EINVAL;
-	
-	size_t buffer_size =  size;
-	uint8_t *buffer = malloc(buffer_size);
-	if (buffer == NULL)
-		return ENOMEM;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	ipc_call_t opening_request_call;
-	aid_t opening_request = async_send_2(exch,
-	    DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_EVENT,
-	    flags, &opening_request_call);
-	
-	if (opening_request == 0) {
-		async_exchange_end(exch);
-		free(buffer);
-		return ENOMEM;
-	}
-	
-	ipc_call_t data_request_call;
-	aid_t data_request = async_data_read(exch, buffer, buffer_size,
-	    &data_request_call);
-	
-	async_exchange_end(exch);
-	
-	if (data_request == 0) {
-		async_forget(opening_request);
-		free(buffer);
-		return ENOMEM;
-	}
-	
-	sysarg_t data_request_rc;
-	sysarg_t opening_request_rc;
-	async_wait_for(data_request, &data_request_rc);
-	async_wait_for(opening_request, &opening_request_rc);
-	
-	if (data_request_rc != EOK) {
-		/* Prefer return code of the opening request. */
-		if (opening_request_rc != EOK)
-			return (int) opening_request_rc;
-		else
-			return (int) data_request_rc;
-	}
-	
-	if (opening_request_rc != EOK)
-		return (int) opening_request_rc;
-	
-	size_t act_size = IPC_GET_ARG2(data_request_call);
-	
-	/* Copy the individual items. */
-	memcpy(buf, buffer, act_size);
-	
-	if (actual_size != NULL)
-		*actual_size = act_size;
-	
-	if (event_nr != NULL)
-		*event_nr = IPC_GET_ARG1(opening_request_call);
-	
-	return EOK;
-}
-
-int usbhid_dev_get_report_descriptor_length(async_sess_t *dev_sess,
-    size_t *size)
-{
-	if (!dev_sess)
-		return EINVAL;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	sysarg_t arg_size;
-	int rc = async_req_1_1(exch, DEV_IFACE_ID(USBHID_DEV_IFACE),
-	    IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH, &arg_size);
-	
-	async_exchange_end(exch);
-	
-	if (rc == EOK) {
-		if (size != NULL)
-			*size = (size_t) arg_size;
-	}
-	
-	return rc;
-}
-
-int usbhid_dev_get_report_descriptor(async_sess_t *dev_sess, uint8_t *buf,
-    size_t size, size_t *actual_size)
-{
-	if (!dev_sess)
-		return EINVAL;
-	
-	if (buf == NULL)
-		return ENOMEM;
-	
-	if (size == 0)
-		return EINVAL;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	aid_t opening_request = async_send_1(exch,
-	    DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_REPORT_DESCRIPTOR,
-	    NULL);
-	if (opening_request == 0) {
-		async_exchange_end(exch);
-		return ENOMEM;
-	}
-	
-	ipc_call_t data_request_call;
-	aid_t data_request = async_data_read(exch, buf, size,
-	    &data_request_call);
-	
-	async_exchange_end(exch);
-	
-	if (data_request == 0) {
-		async_forget(opening_request);
-		return ENOMEM;
-	}
-	
-	sysarg_t data_request_rc;
-	sysarg_t opening_request_rc;
-	async_wait_for(data_request, &data_request_rc);
-	async_wait_for(opening_request, &opening_request_rc);
-	
-	if (data_request_rc != EOK) {
-		/* Prefer return code of the opening request. */
-		if (opening_request_rc != EOK)
-			return (int) opening_request_rc;
-		else
-			return (int) data_request_rc;
-	}
-	
-	if (opening_request_rc != EOK)
-		return (int) opening_request_rc;
-	
-	size_t act_size = IPC_GET_ARG2(data_request_call);
-	
-	if (actual_size != NULL)
-		*actual_size = act_size;
-	
-	return EOK;
-}
-
-/**
- * @}
- */
Index: uspace/srv/bd/sata_bd/Makefile
===================================================================
--- uspace/srv/bd/sata_bd/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/bd/sata_bd/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -29,4 +29,6 @@
 USPACE_PREFIX = ../../..
 BINARY = sata_bd
+EXTRA_CFLAGS = -I$(LIBDRV_PREFIX)/include
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
 
 SOURCES = \
Index: uspace/srv/bd/sata_bd/sata_bd.c
===================================================================
--- uspace/srv/bd/sata_bd/sata_bd.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/bd/sata_bd/sata_bd.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -39,4 +39,5 @@
 #include <sys/types.h>
 #include <bd_srv.h>
+#include <devman.h>
 #include <errno.h>
 #include <stdio.h>
@@ -45,5 +46,5 @@
 #include <macros.h>
 
-#include <device/ahci.h>
+#include <ahci_iface.h>
 #include "sata_bd.h"
 
Index: uspace/srv/hid/compositor/Makefile
===================================================================
--- uspace/srv/hid/compositor/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/hid/compositor/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -28,21 +28,19 @@
 
 USPACE_PREFIX = ../../..
-LIBS = $(LIBDRAW_PREFIX)/libdraw.a $(LIBSOFTREND_PREFIX)/libsoftrend.a \
-	$(LIBSOFTFLOAT_PREFIX)/libsoftfloat.a
-EXTRA_CFLAGS += -I$(LIBDRAW_PREFIX) -I$(LIBSOFTREND_PREFIX)
+LIBS = \
+	$(LIBDRAW_PREFIX)/libdraw.a \
+	$(LIBSOFTREND_PREFIX)/libsoftrend.a \
+	$(LIBSOFTFLOAT_PREFIX)/libsoftfloat.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+
+EXTRA_CFLAGS += \
+	-I$(LIBDRAW_PREFIX) \
+	-I$(LIBSOFTREND_PREFIX) \
+	-I$(LIBDRV_PREFIX)/include
+
 BINARY = compositor
 
 SOURCES = \
-	compositor.c \
-	images.c
-
-IMAGES = \
-	gfx/nameic.tga
-
-PRE_DEPEND = images.c images.h
-EXTRA_CLEAN = images.c images.h
+	compositor.c
 
 include $(USPACE_PREFIX)/Makefile.common
-
-images.c images.h: $(IMAGES)
-	$(ROOT_PATH)/tools/mkarray.py images COMPOSITOR_IMAGES $^
Index: uspace/srv/hid/compositor/compositor.c
===================================================================
--- uspace/srv/hid/compositor/compositor.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/hid/compositor/compositor.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -58,5 +58,5 @@
 
 #include <event.h>
-#include <device/graph_dev.h>
+#include <graph_iface.h>
 #include <io/keycode.h>
 #include <io/mode.h>
@@ -72,5 +72,4 @@
 #include <codec/tga.h>
 
-#include "images.h"
 #include "compositor.h"
 
@@ -162,5 +161,4 @@
 static void input_disconnect(void);
 
-
 static pointer_t *input_pointer(input_t *input)
 {
@@ -168,11 +166,10 @@
 }
 
-static pointer_t *pointer_create()
+static pointer_t *pointer_create(void)
 {
 	pointer_t *p = (pointer_t *) malloc(sizeof(pointer_t));
-	if (!p) {
+	if (!p)
 		return NULL;
-	}
-
+	
 	link_initialize(&p->link);
 	p->pos.x = coord_origin;
@@ -186,5 +183,5 @@
 	p->state = 0;
 	cursor_init(&p->cursor, CURSOR_DECODER_EMBEDDED, NULL);
-
+	
 	/* Ghost window for transformation animation. */
 	transform_identity(&p->ghost.transform);
@@ -199,5 +196,5 @@
 	p->accum_ghost.x = 0;
 	p->accum_ghost.y = 0;
-
+	
 	return p;
 }
@@ -211,19 +208,17 @@
 }
 
-static window_t *window_create(sysarg_t x_offset, sysarg_t y_offset)
+static window_t *window_create(void)
 {
 	window_t *win = (window_t *) malloc(sizeof(window_t));
-	if (!win) {
+	if (!win)
 		return NULL;
-	}
-
+	
 	link_initialize(&win->link);
 	atomic_set(&win->ref_cnt, 0);
 	prodcons_initialize(&win->queue);
 	transform_identity(&win->transform);
-	transform_translate(&win->transform, 
-	    coord_origin + x_offset, coord_origin + y_offset);
-	win->dx = coord_origin + x_offset;
-	win->dy = coord_origin + y_offset;
+	transform_translate(&win->transform, coord_origin, coord_origin);
+	win->dx = coord_origin;
+	win->dy = coord_origin;
 	win->fx = 1;
 	win->fy = 1;
@@ -231,5 +226,5 @@
 	win->opacity = 255;
 	win->surface = NULL;
-
+	
 	return win;
 }
@@ -294,16 +289,19 @@
     sysarg_t *x_out, sysarg_t *y_out, sysarg_t *w_out, sysarg_t *h_out)
 {
-	if (w_in > 0 && h_in > 0) {
+	if ((w_in > 0) && (h_in > 0)) {
 		sysarg_t x[4];
 		sysarg_t y[4];
+		
 		comp_coord_from_client(x_in, y_in, win_trans, &x[0], &y[0]);
 		comp_coord_from_client(x_in + w_in - 1, y_in, win_trans, &x[1], &y[1]);
 		comp_coord_from_client(x_in + w_in - 1, y_in + h_in - 1, win_trans, &x[2], &y[2]);
 		comp_coord_from_client(x_in, y_in + h_in - 1, win_trans, &x[3], &y[3]);
+		
 		(*x_out) = x[0];
 		(*y_out) = y[0];
 		(*w_out) = x[0];
 		(*h_out) = y[0];
-		for (int i = 1; i < 4; ++i) {
+		
+		for (unsigned int i = 1; i < 4; ++i) {
 			(*x_out) = (x[i] < (*x_out)) ? x[i] : (*x_out);
 			(*y_out) = (y[i] < (*y_out)) ? y[i] : (*y_out);
@@ -311,4 +309,5 @@
 			(*h_out) = (y[i] > (*h_out)) ? y[i] : (*h_out);
 		}
+		
 		(*w_out) = (*w_out) - (*x_out) + 1;
 		(*h_out) = (*h_out) - (*y_out) + 1;
@@ -321,13 +320,13 @@
 }
 
-static void comp_restrict_pointers(void)
+static void comp_update_viewport_bound_rect(void)
 {
 	fibril_mutex_lock(&viewport_list_mtx);
-
+	
 	sysarg_t x_res = coord_origin;
 	sysarg_t y_res = coord_origin;
 	sysarg_t w_res = 0;
 	sysarg_t h_res = 0;
-
+	
 	if (!list_empty(&viewport_list)) {
 		viewport_t *vp = (viewport_t *) list_first(&viewport_list);
@@ -336,23 +335,27 @@
 		surface_get_resolution(vp->surface, &w_res, &h_res);
 	}
-
+	
 	list_foreach(viewport_list, link, viewport_t, vp) {
 		sysarg_t w_vp, h_vp;
 		surface_get_resolution(vp->surface, &w_vp, &h_vp);
-		rectangle_union(
-		    x_res, y_res, w_res, h_res,
+		rectangle_union(x_res, y_res, w_res, h_res,
 		    vp->pos.x, vp->pos.y, w_vp, h_vp,
 		    &x_res, &y_res, &w_res, &h_res);
 	}
-
+	
 	viewport_bound_rect.x = x_res;
 	viewport_bound_rect.y = y_res;
 	viewport_bound_rect.w = w_res;
 	viewport_bound_rect.h = h_res;
-
+	
 	fibril_mutex_unlock(&viewport_list_mtx);
-
+}
+
+static void comp_restrict_pointers(void)
+{
+	comp_update_viewport_bound_rect();
+	
 	fibril_mutex_lock(&pointer_list_mtx);
-
+	
 	list_foreach(pointer_list, link, pointer_t, ptr) {
 		ptr->pos.x = ptr->pos.x > viewport_bound_rect.x ? ptr->pos.x : viewport_bound_rect.x;
@@ -363,5 +366,5 @@
 		    ptr->pos.y : viewport_bound_rect.y + viewport_bound_rect.h;
 	}
-
+	
 	fibril_mutex_unlock(&pointer_list_mtx);
 }
@@ -642,12 +645,39 @@
 }
 
+static void comp_recalc_transform(window_t *win)
+{
+	transform_t translate;
+	transform_identity(&translate);
+	transform_translate(&translate, win->dx, win->dy);
+	
+	transform_t scale;
+	transform_identity(&scale);
+	if ((win->fx != 1) || (win->fy != 1))
+		transform_scale(&scale, win->fx, win->fy);
+	
+	transform_t rotate;
+	transform_identity(&rotate);
+	if (win->angle != 0)
+		transform_rotate(&rotate, win->angle);
+	
+	transform_t transform;
+	transform_t temp;
+	transform_identity(&transform);
+	temp = transform;
+	transform_multiply(&transform, &temp, &translate);
+	temp = transform;
+	transform_multiply(&transform, &temp, &rotate);
+	temp = transform;
+	transform_multiply(&transform, &temp, &scale);
+	
+	win->transform = transform;
+}
+
 static void comp_window_resize(window_t *win, ipc_callid_t iid, ipc_call_t *icall)
 {
-	int rc;
-
 	ipc_callid_t callid;
 	size_t size;
 	unsigned int flags;
-
+	
 	/* Start sharing resized window with client. */
 	if (!async_share_out_receive(&callid, &size, &flags)) {
@@ -655,15 +685,15 @@
 		return;
 	}
+	
 	void *new_cell_storage;
-	rc = async_share_out_finalize(callid, &new_cell_storage);
+	int rc = async_share_out_finalize(callid, &new_cell_storage);
 	if ((rc != EOK) || (new_cell_storage == AS_MAP_FAILED)) {
 		async_answer_0(iid, ENOMEM);
 		return;
 	}
-
+	
 	/* Create new surface for the resized window. */
-	surface_t *new_surface = surface_create(
-	    IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall),
-	    new_cell_storage, SURFACE_FLAG_SHARED);
+	surface_t *new_surface = surface_create(IPC_GET_ARG3(*icall),
+	    IPC_GET_ARG4(*icall), new_cell_storage, SURFACE_FLAG_SHARED);
 	if (!new_surface) {
 		as_area_destroy(new_cell_storage);
@@ -671,30 +701,88 @@
 		return;
 	}
-
+	
+	sysarg_t offset_x = IPC_GET_ARG1(*icall);
+	sysarg_t offset_y = IPC_GET_ARG2(*icall);
+	window_placement_flags_t placement_flags =
+	    (window_placement_flags_t) IPC_GET_ARG5(*icall);
+	
+	comp_update_viewport_bound_rect();
+	
 	/* Switch new surface with old surface and calculate damage. */
 	fibril_mutex_lock(&window_list_mtx);
-
+	
 	sysarg_t old_width = 0;
 	sysarg_t old_height = 0;
+	
 	if (win->surface) {
 		surface_get_resolution(win->surface, &old_width, &old_height);
 		surface_destroy(win->surface);
 	}
-
+	
 	win->surface = new_surface;
-
+	
 	sysarg_t new_width = 0;
 	sysarg_t new_height = 0;
 	surface_get_resolution(win->surface, &new_width, &new_height);
-
-	sysarg_t x, y;
-	sysarg_t width = old_width > new_width ? old_width : new_width;
-	sysarg_t height = old_height > new_height ? old_height : new_height;
-	comp_coord_bounding_rect(0, 0, width, height, win->transform, &x, &y, &width, &height);
-
+	
+	if (placement_flags & WINDOW_PLACEMENT_CENTER_X)
+		win->dx = viewport_bound_rect.x + viewport_bound_rect.w / 2 -
+		    new_width / 2;
+	
+	if (placement_flags & WINDOW_PLACEMENT_CENTER_Y)
+		win->dy = viewport_bound_rect.y + viewport_bound_rect.h / 2 -
+		    new_height / 2;
+	
+	if (placement_flags & WINDOW_PLACEMENT_LEFT)
+		win->dx = viewport_bound_rect.x;
+	
+	if (placement_flags & WINDOW_PLACEMENT_TOP)
+		win->dy = viewport_bound_rect.y;
+	
+	if (placement_flags & WINDOW_PLACEMENT_RIGHT)
+		win->dx = viewport_bound_rect.x + viewport_bound_rect.w -
+		    new_width;
+	
+	if (placement_flags & WINDOW_PLACEMENT_BOTTOM)
+		win->dy = viewport_bound_rect.y + viewport_bound_rect.h -
+		    new_height;
+	
+	if (placement_flags & WINDOW_PLACEMENT_ABSOLUTE_X)
+		win->dx = coord_origin + offset_x;
+	
+	if (placement_flags & WINDOW_PLACEMENT_ABSOLUTE_Y)
+		win->dy = coord_origin + offset_y;
+	
+	/* Transform the window and calculate damage. */
+	sysarg_t x1;
+	sysarg_t y1;
+	sysarg_t width1;
+	sysarg_t height1;
+	
+	comp_coord_bounding_rect(0, 0, old_width, old_height, win->transform,
+	    &x1, &y1, &width1, &height1);
+	
+	comp_recalc_transform(win);
+	
+	sysarg_t x2;
+	sysarg_t y2;
+	sysarg_t width2;
+	sysarg_t height2;
+	
+	comp_coord_bounding_rect(0, 0, new_width, new_height, win->transform,
+	    &x2, &y2, &width2, &height2);
+	
+	sysarg_t x;
+	sysarg_t y;
+	sysarg_t width;
+	sysarg_t height;
+	
+	rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2,
+	    &x, &y, &width, &height);
+	
 	fibril_mutex_unlock(&window_list_mtx);
-
+	
 	comp_damage(x, y, width, height);
-
+	
 	async_answer_0(iid, EOK);
 }
@@ -703,5 +791,5 @@
 {
 	fibril_mutex_lock(&window_list_mtx);
-
+	
 	list_foreach(window_list, link, window_t, window) {
 		if (window == target) {
@@ -711,5 +799,5 @@
 		}
 	}
-
+	
 	fibril_mutex_unlock(&window_list_mtx);
 	free(event);
@@ -719,10 +807,11 @@
 {
 	fibril_mutex_lock(&window_list_mtx);
+	
 	window_t *win = (window_t *) list_first(&window_list);
-	if (win) {
+	if (win)
 		prodcons_produce(&win->queue, &event->link);
-	} else {
+	else
 		free(event);
-	}
+	
 	fibril_mutex_unlock(&window_list_mtx);
 }
@@ -801,5 +890,5 @@
 			fibril_mutex_lock(&window_list_mtx);
 
-			window_t *win = window_create(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
+			window_t *win = window_create();
 			if (!win) {
 				async_answer_2(callid, ENOMEM, 0, 0);
@@ -1173,36 +1262,4 @@
 }
 
-static void comp_recalc_transform(window_t *win)
-{
-	transform_t translate;
-	transform_identity(&translate);
-	transform_translate(&translate, win->dx, win->dy);
-
-	transform_t scale;
-	transform_identity(&scale);
-	if (win->fx != 1 || win->fy != 1) {
-		transform_scale(&scale, win->fx, win->fy);
-	}
-
-	transform_t rotate;
-	transform_identity(&rotate);
-	if (win->angle != 0) {
-		transform_rotate(&rotate, win->angle);
-	}
-
-	transform_t transform;
-	transform_t temp;
-	transform_identity(&transform);
-	temp = transform;
-	transform_multiply(&transform, &temp, &translate);
-	temp = transform;
-	transform_multiply(&transform, &temp, &rotate);
-	temp = transform;
-	transform_multiply(&transform, &temp, &scale);
-	
-
-	win->transform = transform;
-}
-
 static void comp_window_animate(pointer_t *pointer, window_t *win,
     sysarg_t *dmg_x, sysarg_t *dmg_y, sysarg_t *dmg_width, sysarg_t *dmg_height)
@@ -1226,26 +1283,27 @@
 		double cx = 0;
 		double cy = 0;
-		if (pointer->grab_flags & GF_MOVE_X) {
+		
+		if (pointer->grab_flags & GF_MOVE_X)
 			cx = 1;
-		}
-		if (pointer->grab_flags & GF_MOVE_Y) {
+		
+		if (pointer->grab_flags & GF_MOVE_Y)
 			cy = 1;
-		}
-
-		if ((scale || resize) && (win->angle != 0)) {
+		
+		if (((scale) || (resize)) && (win->angle != 0)) {
 			transform_t rotate;
 			transform_identity(&rotate);
+			
 			transform_rotate(&rotate, win->angle);
 			transform_apply_linear(&rotate, &cx, &cy);
 		}
 		
-		cx = (cx < 0) ? (-1 * cx) : cx; 
+		cx = (cx < 0) ? (-1 * cx) : cx;
 		cy = (cy < 0) ? (-1 * cy) : cy;
-
+		
 		win->dx += (cx * dx);
 		win->dy += (cy * dy);
 	}
 
-	if (scale || resize) {
+	if ((scale) || (resize)) {
 		double _dx = dx;
 		double _dy = dy;
@@ -1263,5 +1321,6 @@
 			if (fx > 0) {
 #if ANIMATE_WINDOW_TRANSFORMS == 0
-				if (scale) win->fx *= fx;
+				if (scale)
+					win->fx *= fx;
 #endif
 #if ANIMATE_WINDOW_TRANSFORMS == 1
@@ -1444,24 +1503,29 @@
 {
 	pointer_t *pointer = input_pointer(input);
-
+	
+	comp_update_viewport_bound_rect();
+	
 	/* Update pointer position. */
 	fibril_mutex_lock(&pointer_list_mtx);
+	
 	desktop_point_t old_pos = pointer->pos;
+	
 	sysarg_t cursor_width;
 	sysarg_t cursor_height;
-	surface_get_resolution(pointer->cursor.states[pointer->state], 
+	surface_get_resolution(pointer->cursor.states[pointer->state],
 	     &cursor_width, &cursor_height);
-	if (pointer->pos.x + dx < viewport_bound_rect.x) {
+	
+	if (pointer->pos.x + dx < viewport_bound_rect.x)
 		dx = -1 * (pointer->pos.x - viewport_bound_rect.x);
-	}
-	if (pointer->pos.y + dy < viewport_bound_rect.y) {
+	
+	if (pointer->pos.y + dy < viewport_bound_rect.y)
 		dy = -1 * (pointer->pos.y - viewport_bound_rect.y);
-	}
-	if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w) {
+	
+	if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w)
 		dx = (viewport_bound_rect.x + viewport_bound_rect.w - pointer->pos.x);
-	}
-	if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h) {
+	
+	if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h)
 		dy = (viewport_bound_rect.y + viewport_bound_rect.h - pointer->pos.y);
-	}
+	
 	pointer->pos.x += dx;
 	pointer->pos.y += dy;
@@ -1469,5 +1533,5 @@
 	comp_damage(old_pos.x, old_pos.y, cursor_width, cursor_height);
 	comp_damage(old_pos.x + dx, old_pos.y + dy, cursor_width, cursor_height);
-
+	
 	fibril_mutex_lock(&window_list_mtx);
 	fibril_mutex_lock(&pointer_list_mtx);
@@ -1630,5 +1694,5 @@
 
 #if ANIMATE_WINDOW_TRANSFORMS == 0
-		sysarg_t pre_x = 0; 
+		sysarg_t pre_x = 0;
 		sysarg_t pre_y = 0;
 		sysarg_t pre_width = 0;
@@ -1662,21 +1726,25 @@
 				link_initialize(&event_top->link);
 				event_top->type = ET_WINDOW_RESIZE;
-
+				
+				event_top->data.resize.offset_x = 0;
+				event_top->data.resize.offset_y = 0;
+				
 				int dx = (int) (((double) width) * (scale_back_x - 1.0));
 				int dy = (int) (((double) height) * (scale_back_y - 1.0));
-
-				if (pointer->grab_flags & GF_RESIZE_X) {
-					event_top->data.rsz.width =
-						((((int) width) + dx) >= 0) ? (width + dx) : 0;
-				} else {
-					event_top->data.rsz.width = width;
-				}
-
-				if (pointer->grab_flags & GF_RESIZE_Y) {
-					event_top->data.rsz.height =
-						((((int) height) + dy) >= 0) ? (height + dy) : 0;
-				} else {
-					event_top->data.rsz.height = height;
-				}
+				
+				if (pointer->grab_flags & GF_RESIZE_X)
+					event_top->data.resize.width =
+					    ((((int) width) + dx) >= 0) ? (width + dx) : 0;
+				else
+					event_top->data.resize.width = width;
+				
+				if (pointer->grab_flags & GF_RESIZE_Y)
+					event_top->data.resize.height =
+					    ((((int) height) + dy) >= 0) ? (height + dy) : 0;
+				else
+					event_top->data.resize.height = height;
+				
+				event_top->data.resize.placement_flags =
+				    WINDOW_PLACEMENT_ANY;
 			}
 
@@ -1746,9 +1814,8 @@
 	    key == KC_O || key == KC_P);
 	bool kconsole_switch = (mods & KM_ALT) && (key == KC_M);
-	bool compositor_test = (mods & KM_ALT) && (key == KC_H);
 
 	bool filter = (type == KEY_RELEASE) && (win_transform || win_resize ||
 	    win_opacity || win_close || win_switch || viewport_move ||
-	    viewport_change || kconsole_switch || compositor_test);
+	    viewport_change || kconsole_switch);
 
 	if (filter) {
@@ -1816,34 +1883,39 @@
 				return ENOMEM;
 			}
-
+			
 			sysarg_t width, height;
 			surface_get_resolution(win->surface, &width, &height);
-
+			
 			link_initialize(&event->link);
 			event->type = ET_WINDOW_RESIZE;
-
+			
+			event->data.resize.offset_x = 0;
+			event->data.resize.offset_y = 0;
+			
 			switch (key) {
 			case KC_T:
-				event->data.rsz.width = width;
-				event->data.rsz.height = (height >= 20) ? height - 20 : 0;
+				event->data.resize.width = width;
+				event->data.resize.height = (height >= 20) ? height - 20 : 0;
 				break;
 			case KC_G:
-				event->data.rsz.width = width;
-				event->data.rsz.height = height + 20;
+				event->data.resize.width = width;
+				event->data.resize.height = height + 20;
 				break;
 			case KC_B:
-				event->data.rsz.width = (width >= 20) ? width - 20 : 0;;
-				event->data.rsz.height = height;
+				event->data.resize.width = (width >= 20) ? width - 20 : 0;;
+				event->data.resize.height = height;
 				break;
 			case KC_N:
-				event->data.rsz.width = width + 20;
-				event->data.rsz.height = height;
+				event->data.resize.width = width + 20;
+				event->data.resize.height = height;
 				break;
 			default:
-				event->data.rsz.width = 0;
-				event->data.rsz.height = 0;
-				break;
-			}
-
+				event->data.resize.width = 0;
+				event->data.resize.height = 0;
+				break;
+			}
+			
+			event->data.resize.placement_flags = WINDOW_PLACEMENT_ANY;
+			
 			fibril_mutex_unlock(&window_list_mtx);
 			comp_post_event_top(event);
@@ -2014,33 +2086,4 @@
 	} else if (kconsole_switch) {
 		__SYSCALL0(SYS_DEBUG_ACTIVATE_CONSOLE);
-	} else if (compositor_test) {
-		fibril_mutex_lock(&window_list_mtx);
-
-		window_t *red_win = window_create(0, 0);
-		red_win->surface = surface_create(250, 150, NULL, 0);
-		pixel_t red_pix = PIXEL(255, 240, 0, 0);
-		for (sysarg_t y = 0; y <  150; ++y) {
-			for (sysarg_t x = 0; x < 250; ++x) {
-				surface_put_pixel(red_win->surface, x, y, red_pix);
-			}
-		}
-		list_prepend(&red_win->link, &window_list);
-
-		window_t *blue_win = window_create(0, 0);
-		blue_win->surface = surface_create(200, 100, NULL, 0);
-		pixel_t blue_pix = PIXEL(255, 0, 0, 240);
-		for (sysarg_t y = 0; y <  100; ++y) {
-			for (sysarg_t x = 0; x < 200; ++x) {
-				surface_put_pixel(blue_win->surface, x, y, blue_pix);
-			}
-		}
-		list_prepend(&blue_win->link, &window_list);
-		
-		window_t *nameic_win = window_create(0, 0);
-		nameic_win->surface = decode_tga((void *) nameic_tga, nameic_tga_size, 0);
-		list_prepend(&nameic_win->link, &window_list);
-
-		fibril_mutex_unlock(&window_list_mtx);
-		comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
 	} else {
 		window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
Index: uspace/srv/hid/isdv4_tablet/Makefile
===================================================================
--- uspace/srv/hid/isdv4_tablet/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/hid/isdv4_tablet/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -28,6 +28,6 @@
 
 USPACE_PREFIX = ../../..
-#LIBS = 
-#EXTRA_CFLAGS = 
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS = -I$(LIBDRV_PREFIX)/include
 BINARY = isdv4_tablet
 
Index: uspace/srv/hid/isdv4_tablet/isdv4.c
===================================================================
--- uspace/srv/hid/isdv4_tablet/isdv4.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/hid/isdv4_tablet/isdv4.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -27,5 +27,5 @@
  */
 
-#include <device/char_dev.h>
+#include <char_dev_iface.h>
 #include <errno.h>
 #include <stdlib.h>
Index: uspace/srv/hid/isdv4_tablet/main.c
===================================================================
--- uspace/srv/hid/isdv4_tablet/main.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/hid/isdv4_tablet/main.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -27,5 +27,5 @@
  */
 
-#include <device/char_dev.h>
+#include <char_dev_iface.h>
 #include <errno.h>
 #include <ipc/serial_ctl.h>
Index: uspace/srv/klog/Makefile
===================================================================
--- uspace/srv/klog/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/srv/klog/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+USPACE_PREFIX = ../..
+BINARY = klog
+
+SOURCES = \
+	klog.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/klog/klog.c
===================================================================
--- uspace/srv/klog/klog.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
+++ uspace/srv/klog/klog.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * Copyright (c) 2013 Martin Sucha
+ * 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 klog KLog
+ * @brief HelenOS KLog
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <async.h>
+#include <as.h>
+#include <ddi.h>
+#include <event.h>
+#include <errno.h>
+#include <str_error.h>
+#include <io/klog.h>
+#include <sysinfo.h>
+#include <malloc.h>
+#include <fibril_synch.h>
+#include <adt/list.h>
+#include <adt/prodcons.h>
+#include <io/log.h>
+#include <io/logctl.h>
+
+#define NAME       "klog"
+
+typedef struct {
+	size_t entry_len;
+	uint32_t serial;
+	uint32_t facility;
+	uint32_t level;
+	char message[0];
+	
+} __attribute__((__packed__)) log_entry_t;
+
+/* Producer/consumer buffers */
+typedef struct {
+	link_t link;
+	size_t size;
+	log_entry_t *data;
+} item_t;
+
+static prodcons_t pc;
+
+/* Pointer to buffer where kernel stores new entries */
+#define BUFFER_SIZE PAGE_SIZE
+static void *buffer;
+
+/* Notification mutex */
+static FIBRIL_MUTEX_INITIALIZE(mtx);
+
+static log_t kernel_ctx;
+static const char *facility_name[] = {
+	"other",
+	"uspace",
+	"arch"
+};
+
+#define facility_len (sizeof(facility_name) / sizeof(const char *))
+static log_t facility_ctx[facility_len];
+
+/** Klog producer
+ *
+ * Copies the log entries to a producer/consumer queue.
+ *
+ * @param length Number of characters to copy.
+ * @param data   Pointer to the kernel klog buffer.
+ *
+ */
+static void producer()
+{
+	int read = klog_read(buffer, BUFFER_SIZE);
+	
+	if (read < 0) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "klog_read failed, rc = %d",
+		    read);
+		return;
+	}
+	
+	size_t len = read;
+	size_t offset = 0;
+	while (offset < len) {
+		size_t entry_len = *((size_t *) (buffer + offset));
+		
+		if (offset + entry_len > len || entry_len < sizeof(log_entry_t))
+			break;
+		
+		log_entry_t *buf = malloc(entry_len + 1);
+		if (buf == NULL)
+			break;
+		
+		item_t *item = malloc(sizeof(item_t));
+		if (item == NULL) {
+			free(buf);
+			break;
+		}
+		
+		memcpy(buf, buffer + offset, entry_len);
+		*((uint8_t *) buf + entry_len) = 0;
+		link_initialize(&item->link);
+		item->size = entry_len;
+		item->data = buf;
+		prodcons_produce(&pc, &item->link);
+		
+		offset += entry_len;
+	}
+}
+
+/** Klog consumer
+ *
+ * Waits in an infinite loop for the log data created by
+ * the producer and logs them to the logger.
+ *
+ * @param data Unused.
+ *
+ * @return Always EOK (unreachable).
+ *
+ */
+static int consumer(void *data)
+{
+	
+	while (true) {
+		link_t *link = prodcons_consume(&pc);
+		item_t *item = list_get_instance(link, item_t, link);
+		
+		if (item->size < sizeof(log_entry_t)) {
+			free(item->data);
+			free(item);
+			continue;
+		}
+		
+		if (item->data->facility == LF_USPACE) {
+			/* Avoid reposting messages */
+			free(item->data);
+			free(item);
+			continue;
+		}
+		
+		log_t ctx = kernel_ctx;
+		if (item->data->facility < facility_len) {
+			ctx = facility_ctx[item->data->facility];
+		}
+		
+		log_level_t lvl = item->data->level;
+		if (lvl > LVL_LIMIT)
+			lvl = LVL_NOTE;
+		
+		log_msg(ctx, lvl, "%s", item->data->message);
+		
+		free(item->data);
+		free(item);
+	}
+	
+	return EOK;
+}
+
+/** Kernel notification handler
+ *
+ * Receives kernel klog notifications.
+ *
+ * @param callid IPC call ID
+ * @param call   IPC call structure
+ * @param arg    Local argument
+ *
+ */
+static void notification_received(ipc_callid_t callid, ipc_call_t *call)
+{
+	/*
+	 * Make sure we process only a single notification
+	 * at any time to limit the chance of the consumer
+	 * starving.
+	 */
+	
+	fibril_mutex_lock(&mtx);
+	
+	producer();
+	
+	event_unmask(EVENT_KLOG);
+	fibril_mutex_unlock(&mtx);
+}
+
+int main(int argc, char *argv[])
+{
+	int rc = log_init(NAME);
+	if (rc != EOK) {
+		fprintf(stderr, "%s: Unable to initialize log\n", NAME);
+		return rc;
+	}
+	
+	kernel_ctx = log_create("kernel", LOG_NO_PARENT);
+	for (unsigned int i = 0; i < facility_len; i++) {
+		facility_ctx[i] = log_create(facility_name[i], kernel_ctx);
+	}
+	
+	buffer = malloc(BUFFER_SIZE);
+	if (buffer == NULL) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Unable to allocate buffer");
+		return 1;
+	}
+	
+	prodcons_initialize(&pc);
+	async_set_interrupt_received(notification_received);
+	rc = event_subscribe(EVENT_KLOG, 0);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR,
+		    "Unable to register klog notifications");
+		return rc;
+	}
+	
+	fid_t fid = fibril_create(consumer, NULL);
+	if (!fid) {
+		log_msg(LOG_DEFAULT, LVL_ERROR,
+		    "Unable to create consumer fibril");
+		return ENOMEM;
+	}
+	
+	fibril_add_ready(fid);
+	event_unmask(EVENT_KLOG);
+	
+	fibril_mutex_lock(&mtx);
+	producer();
+	fibril_mutex_unlock(&mtx);
+	
+	task_retval(0);
+	async_manager();
+	
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/srv/logger/writer.c
===================================================================
--- uspace/srv/logger/writer.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/logger/writer.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -40,4 +40,5 @@
 #include <io/log.h>
 #include <io/logctl.h>
+#include <io/klog.h>
 #include <ns.h>
 #include <async.h>
@@ -79,5 +80,5 @@
 	}
 
-	printf("[%s] %s: %s\n",
+	KLOG_PRINTF(level, "[%s] %s: %s\n",
 	    log->full_name, log_level_str(level),
 	    (const char *) message);
Index: uspace/srv/net/ethip/Makefile
===================================================================
--- uspace/srv/net/ethip/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/net/ethip/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -29,4 +29,6 @@
 USPACE_PREFIX = ../../..
 BINARY = ethip
+EXTRA_CFLAGS = -I$(LIBDRV_PREFIX)/include
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
 
 SOURCES = \
Index: uspace/srv/net/ethip/ethip_nic.c
===================================================================
--- uspace/srv/net/ethip/ethip_nic.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/net/ethip/ethip_nic.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -43,5 +43,5 @@
 #include <io/log.h>
 #include <loc.h>
-#include <device/nic.h>
+#include <nic_iface.h>
 #include <stdlib.h>
 #include <mem.h>
Index: uspace/srv/net/slip/Makefile
===================================================================
--- uspace/srv/net/slip/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/net/slip/Makefile	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -29,5 +29,6 @@
 USPACE_PREFIX = ../../..
 BINARY = slip
-
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS = -I$(LIBDRV_PREFIX)/include
 SOURCES = \
 	slip.c
Index: uspace/srv/net/slip/slip.c
===================================================================
--- uspace/srv/net/slip/slip.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/net/slip/slip.c	(revision dbb29de402aedf0e136e946bd4ad53cc6beecc25)
@@ -40,5 +40,5 @@
 #include <inet/addr.h>
 #include <inet/iplink_srv.h>
-#include <device/char_dev.h>
+#include <char_dev_iface.h>
 #include <io/log.h>
 #include <errno.h>
