Index: uspace/lib/block/libblock.c
===================================================================
--- uspace/lib/block/libblock.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/block/libblock.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -60,5 +60,5 @@
 static FIBRIL_MUTEX_INITIALIZE(dcl_lock);
 /** Device connection list head. */
-static LIST_INITIALIZE(dcl_head);
+static LIST_INITIALIZE(dcl);
 
 #define CACHE_BUCKETS_LOG2  10
@@ -72,5 +72,5 @@
 	unsigned blocks_cached;   /**< Number of cached blocks. */
 	hash_table_t block_hash;
-	link_t free_head;
+	list_t free_list;
 	enum cache_mode mode;
 } cache_t;
@@ -97,9 +97,7 @@
 static devcon_t *devcon_search(devmap_handle_t devmap_handle)
 {
-	link_t *cur;
-	
 	fibril_mutex_lock(&dcl_lock);
 	
-	for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
+	list_foreach(dcl, cur) {
 		devcon_t *devcon = list_get_instance(cur, devcon_t, link);
 		if (devcon->devmap_handle == devmap_handle) {
@@ -116,5 +114,4 @@
     size_t bsize, void *comm_area, size_t comm_size)
 {
-	link_t *cur;
 	devcon_t *devcon;
 	
@@ -138,5 +135,5 @@
 	
 	fibril_mutex_lock(&dcl_lock);
-	for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
+	list_foreach(dcl, cur) {
 		devcon_t *d = list_get_instance(cur, devcon_t, link);
 		if (d->devmap_handle == devmap_handle) {
@@ -146,5 +143,5 @@
 		}
 	}
-	list_append(&devcon->link, &dcl_head);
+	list_append(&devcon->link, &dcl);
 	fibril_mutex_unlock(&dcl_lock);
 	return EOK;
@@ -294,5 +291,5 @@
 	
 	fibril_mutex_initialize(&cache->lock);
-	list_initialize(&cache->free_head);
+	list_initialize(&cache->free_list);
 	cache->lblock_size = size;
 	cache->block_count = blocks;
@@ -335,6 +332,6 @@
 	 * bother with the cache and block locks because we are single-threaded.
 	 */
-	while (!list_empty(&cache->free_head)) {
-		block_t *b = list_get_instance(cache->free_head.next,
+	while (!list_empty(&cache->free_list)) {
+		block_t *b = list_get_instance(list_first(&cache->free_list),
 		    block_t, free_link);
 
@@ -367,5 +364,5 @@
 	if (cache->blocks_cached < CACHE_LO_WATERMARK)
 		return true;
-	if (!list_empty(&cache->free_head))
+	if (!list_empty(&cache->free_list))
 		return false;
 	return true;
@@ -456,10 +453,10 @@
 			unsigned long temp_key;
 recycle:
-			if (list_empty(&cache->free_head)) {
+			if (list_empty(&cache->free_list)) {
 				fibril_mutex_unlock(&cache->lock);
 				rc = ENOMEM;
 				goto out;
 			}
-			l = cache->free_head.next;
+			l = list_first(&cache->free_list);
 			b = list_get_instance(l, block_t, free_link);
 
@@ -476,5 +473,5 @@
 				 */
 				list_remove(&b->free_link);
-				list_append(&b->free_link, &cache->free_head);
+				list_append(&b->free_link, &cache->free_list);
 				fibril_mutex_unlock(&cache->lock);
 				fibril_mutex_lock(&devcon->comm_area_lock);
@@ -668,5 +665,5 @@
 			goto retry;
 		}
-		list_append(&block->free_link, &cache->free_head);
+		list_append(&block->free_link, &cache->free_list);
 	}
 	fibril_mutex_unlock(&block->lock);
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/Makefile	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -68,5 +68,4 @@
 	generic/clipboard.c \
 	generic/devmap.c \
-	generic/devmap_obsolete.c \
 	generic/devman.c \
 	generic/devman_obsolete.c \
Index: uspace/lib/c/generic/adt/hash_table.c
===================================================================
--- uspace/lib/c/generic/adt/hash_table.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/generic/adt/hash_table.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -61,9 +61,9 @@
 	assert(max_keys > 0);
 	
-	h->entry = malloc(m * sizeof(link_t));
+	h->entry = malloc(m * sizeof(list_t));
 	if (!h->entry)
 		return false;
 	
-	memset((void *) h->entry, 0,  m * sizeof(link_t));
+	memset((void *) h->entry, 0,  m * sizeof(list_t));
 	
 	hash_count_t i;
@@ -123,7 +123,5 @@
 	assert(chain < h->entries);
 	
-	link_t *cur;
-	for (cur = h->entry[chain].next; cur != &h->entry[chain];
-	    cur = cur->next) {
+	list_foreach(h->entry[chain], cur) {
 		if (h->op->compare(key, h->max_keys, cur)) {
 			/*
@@ -153,7 +151,7 @@
 	assert(keys <= h->max_keys);
 	
-	link_t *cur;
-	
 	if (keys == h->max_keys) {
+		link_t *cur;
+		
 		/*
 		 * All keys are known, hash_table_find() can be used to find the
@@ -176,5 +174,7 @@
 	hash_index_t chain;
 	for (chain = 0; chain < h->entries; chain++) {
-		for (cur = h->entry[chain].next; cur != &h->entry[chain];
+		link_t *cur;
+		
+		for (cur = h->entry[chain].head.next; cur != &h->entry[chain].head;
 		    cur = cur->next) {
 			if (h->op->compare(key, keys, cur)) {
@@ -203,9 +203,7 @@
 {
 	hash_index_t bucket;
-	link_t *cur;
 	
 	for (bucket = 0; bucket < h->entries; bucket++) {
-		for (cur = h->entry[bucket].next; cur != &h->entry[bucket];
-		    cur = cur->next) {
+		list_foreach(h->entry[bucket], cur) {
 			f(cur, arg);
 		}
Index: uspace/lib/c/generic/adt/list.c
===================================================================
--- uspace/lib/c/generic/adt/list.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/generic/adt/list.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -30,29 +30,35 @@
  * @{
  */
-/** @file
+
+/**
+ * @file
+ * @brief	Functions completing doubly linked circular list implementaion.
+ *
+ * This file contains some of the functions implementing doubly linked circular lists.
+ * However, this ADT is mostly implemented in @ref list.h.
  */
 
 #include <adt/list.h>
-
+#include <bool.h>
 
 /** Check for membership
  *
- * Check whether link is contained in the list head.
- * The membership is defined as pointer equivalence.
+ * Check whether link is contained in a list.
+ * Membership is defined as pointer equivalence.
  *
- * @param link Item to look for.
- * @param head List to look in.
+ * @param link	Item to look for.
+ * @param list	List to look in.
  *
  * @return true if link is contained in head, false otherwise.
  *
  */
-int list_member(const link_t *link, const link_t *head)
+int list_member(const link_t *link, const list_t *list)
 {
-	int found = 0;
-	link_t *hlp = head->next;
+	bool found = false;
+	link_t *hlp = list->head.next;
 	
-	while (hlp != head) {
+	while (hlp != &list->head) {
 		if (hlp == link) {
-			found = 1;
+			found = true;
 			break;
 		}
@@ -63,27 +69,25 @@
 }
 
-
 /** Concatenate two lists
  *
- * Concatenate lists head1 and head2, producing a single
- * list head1 containing items from both (in head1, head2
- * order) and empty list head2.
+ * Concatenate lists @a list1 and @a list2, producing a single
+ * list @a list1 containing items from both (in @a list1, @a list2
+ * order) and empty list @a list2.
  *
- * @param head1 First list and concatenated output
- * @param head2 Second list and empty output.
+ * @param list1		First list and concatenated output
+ * @param list2 	Second list and empty output.
  *
  */
-void list_concat(link_t *head1, link_t *head2)
+void list_concat(list_t *list1, list_t *list2)
 {
-	if (list_empty(head2))
+	if (list_empty(list2))
 		return;
-	
-	head2->next->prev = head1->prev;
-	head2->prev->next = head1;
-	head1->prev->next = head2->next;
-	head1->prev = head2->prev;
-	list_initialize(head2);
+
+	list2->head.next->prev = list1->head.prev;
+	list2->head.prev->next = &list1->head;
+	list1->head.prev->next = list2->head.next;
+	list1->head.prev = list2->head.prev;
+	list_initialize(list2);
 }
-
 
 /** Count list items
@@ -91,17 +95,13 @@
  * Return the number of items in the list.
  *
- * @param link List to count.
- *
- * @return Number of items in the list.
- *
+ * @param list		List to count.
+ * @return		Number of items in the list.
  */
-unsigned int list_count(const link_t *link)
+unsigned int list_count(const list_t *list)
 {
 	unsigned int count = 0;
-	link_t *hlp = link->next;
 	
-	while (hlp != link) {
+	list_foreach(*list, link) {
 		count++;
-		hlp = hlp->next;
 	}
 	
Index: uspace/lib/c/generic/adt/prodcons.c
===================================================================
--- uspace/lib/c/generic/adt/prodcons.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/generic/adt/prodcons.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -61,5 +61,5 @@
 		fibril_condvar_wait(&pc->cv, &pc->mtx);
 	
-	link_t *head = pc->list.next;
+	link_t *head = list_first(&pc->list);
 	list_remove(head);
 	
Index: uspace/lib/c/generic/async.c
===================================================================
--- uspace/lib/c/generic/async.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/generic/async.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -160,5 +160,5 @@
 	
 	/** Messages that should be delivered to this fibril. */
-	link_t msg_queue;
+	list_t msg_queue;
 	
 	/** Identification of the opening call. */
@@ -166,4 +166,6 @@
 	/** Call data of the opening call. */
 	ipc_call_t call;
+	/** Local argument or NULL if none. */
+	void *carg;
 	
 	/** Identification of the closing call. */
@@ -171,5 +173,5 @@
 	
 	/** Fibril function that will be used to handle the connection. */
-	void (*cfibril)(ipc_callid_t, ipc_call_t *);
+	async_client_conn_t cfibril;
 } connection_t;
 
@@ -213,7 +215,9 @@
  * @param callid Hash of the incoming call.
  * @param call   Data of the incoming call.
- *
- */
-static void default_client_connection(ipc_callid_t callid, ipc_call_t *call)
+ * @param arg    Local argument
+ *
+ */
+static void default_client_connection(ipc_callid_t callid, ipc_call_t *call,
+    void *arg)
 {
 	ipc_answer_0(callid, ENOENT);
@@ -226,4 +230,5 @@
  * @param callid Hash of the incoming call.
  * @param call   Data of the incoming call.
+ * @param arg    Local argument.
  *
  */
@@ -233,5 +238,5 @@
 
 static async_client_conn_t client_connection = default_client_connection;
-static async_client_conn_t interrupt_received = default_interrupt_received;
+static async_interrupt_handler_t interrupt_received = default_interrupt_received;
 
 /** Setter for client_connection function pointer.
@@ -250,5 +255,5 @@
  *             notification fibril.
  */
-void async_set_interrupt_received(async_client_conn_t intr)
+void async_set_interrupt_received(async_interrupt_handler_t intr)
 {
 	interrupt_received = intr;
@@ -356,6 +361,6 @@
 	wd->to_event.inlist = true;
 	
-	link_t *tmp = timeout_list.next;
-	while (tmp != &timeout_list) {
+	link_t *tmp = timeout_list.head.next;
+	while (tmp != &timeout_list.head) {
 		awaiter_t *cur
 		    = list_get_instance(tmp, awaiter_t, to_event.link);
@@ -367,5 +372,5 @@
 	}
 	
-	list_append(&wd->to_event.link, tmp);
+	list_insert_before(&wd->to_event.link, tmp);
 }
 
@@ -564,5 +569,5 @@
 	}
 	
-	msg_t *msg = list_get_instance(conn->msg_queue.next, msg_t, link);
+	msg_t *msg = list_get_instance(list_first(&conn->msg_queue), msg_t, link);
 	list_remove(&msg->link);
 	
@@ -633,5 +638,5 @@
 	 */
 	fibril_connection->cfibril(fibril_connection->callid,
-	    &fibril_connection->call);
+	    &fibril_connection->call, fibril_connection->carg);
 	
 	/*
@@ -670,6 +675,6 @@
 	while (!list_empty(&fibril_connection->msg_queue)) {
 		msg_t *msg =
-		    list_get_instance(fibril_connection->msg_queue.next, msg_t,
-		    link);
+		    list_get_instance(list_first(&fibril_connection->msg_queue),
+		    msg_t, link);
 		
 		list_remove(&msg->link);
@@ -704,4 +709,5 @@
  * @param cfibril       Fibril function that should be called upon opening the
  *                      connection.
+ * @param carg          Extra argument to pass to the connection fibril
  *
  * @return New fibril id or NULL on failure.
@@ -710,5 +716,5 @@
 fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash,
     ipc_callid_t callid, ipc_call_t *call,
-    async_client_conn_t cfibril)
+    async_client_conn_t cfibril, void *carg)
 {
 	connection_t *conn = malloc(sizeof(*conn));
@@ -725,4 +731,5 @@
 	conn->callid = callid;
 	conn->close_callid = 0;
+	conn->carg = carg;
 	
 	if (call)
@@ -779,5 +786,5 @@
 		/* Open new connection with fibril, etc. */
 		async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call),
-		    callid, call, client_connection);
+		    callid, call, client_connection, NULL);
 		return;
 	}
@@ -799,6 +806,6 @@
 	futex_down(&async_futex);
 	
-	link_t *cur = timeout_list.next;
-	while (cur != &timeout_list) {
+	link_t *cur = list_first(&timeout_list);
+	while (cur != NULL) {
 		awaiter_t *waiter =
 		    list_get_instance(cur, awaiter_t, to_event.link);
@@ -806,6 +813,4 @@
 		if (tv_gt(&waiter->to_event.expires, &tv))
 			break;
-		
-		cur = cur->next;
 		
 		list_remove(&waiter->to_event.link);
@@ -821,4 +826,6 @@
 			fibril_add_ready(waiter->fid);
 		}
+		
+		cur = list_first(&timeout_list);
 	}
 	
@@ -847,6 +854,6 @@
 		suseconds_t timeout;
 		if (!list_empty(&timeout_list)) {
-			awaiter_t *waiter = list_get_instance(timeout_list.next,
-			    awaiter_t, to_event.link);
+			awaiter_t *waiter = list_get_instance(
+			    list_first(&timeout_list), awaiter_t, to_event.link);
 			
 			struct timeval tv;
@@ -1414,5 +1421,5 @@
  */
 int async_connect_to_me(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2,
-    sysarg_t arg3, async_client_conn_t client_receiver)
+    sysarg_t arg3, async_client_conn_t client_receiver, void *carg)
 {
 	if (exch == NULL)
@@ -1428,5 +1435,5 @@
 	if (client_receiver != NULL)
 		async_new_connection(task_hash, phone_hash, 0, NULL,
-		    client_receiver);
+		    client_receiver, carg);
 	
 	return EOK;
@@ -1724,5 +1731,7 @@
 		 */
 		exch = (async_exch_t *)
-		    list_get_instance(sess->exch_list.next, async_exch_t, sess_link);
+		    list_get_instance(list_first(&sess->exch_list),
+		    async_exch_t, sess_link);
+		
 		list_remove(&exch->sess_link);
 		list_remove(&exch->global_link);
@@ -1736,6 +1745,6 @@
 			exch = (async_exch_t *) malloc(sizeof(async_exch_t));
 			if (exch != NULL) {
-				list_initialize(&exch->sess_link);
-				list_initialize(&exch->global_link);
+				link_initialize(&exch->sess_link);
+				link_initialize(&exch->global_link);
 				exch->sess = sess;
 				exch->phone = sess->phone;
@@ -1754,6 +1763,6 @@
 				exch = (async_exch_t *) malloc(sizeof(async_exch_t));
 				if (exch != NULL) {
-					list_initialize(&exch->sess_link);
-					list_initialize(&exch->global_link);
+					link_initialize(&exch->sess_link);
+					link_initialize(&exch->global_link);
 					exch->sess = sess;
 					exch->phone = phone;
@@ -1767,6 +1776,7 @@
 				 */
 				exch = (async_exch_t *)
-				    list_get_instance(inactive_exch_list.next, async_exch_t,
-				    global_link);
+				    list_get_instance(list_first(&inactive_exch_list),
+				    async_exch_t, global_link);
+				
 				list_remove(&exch->sess_link);
 				list_remove(&exch->global_link);
@@ -1808,4 +1818,6 @@
 	async_sess_t *sess = exch->sess;
 	
+	atomic_dec(&sess->refcnt);
+	
 	if (sess->mgmt == EXCHANGE_SERIALIZE)
 		fibril_mutex_unlock(&sess->mutex);
Index: uspace/lib/c/generic/async_obsolete.c
===================================================================
--- uspace/lib/c/generic/async_obsolete.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/generic/async_obsolete.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -166,14 +166,4 @@
 }
 
-void async_obsolete_serialize_start(void)
-{
-	fibril_inc_sercount();
-}
-
-void async_obsolete_serialize_end(void)
-{
-	fibril_dec_sercount();
-}
-
 /** Wrapper for IPC_M_DATA_WRITE calls using the async framework.
  *
@@ -240,5 +230,5 @@
  */
 int async_obsolete_connect_to_me(int phone, sysarg_t arg1, sysarg_t arg2,
-    sysarg_t arg3, async_client_conn_t client_receiver)
+    sysarg_t arg3, async_client_conn_t client_receiver, void *carg)
 {
 	sysarg_t task_hash;
@@ -251,5 +241,5 @@
 	if (client_receiver != NULL)
 		async_new_connection(task_hash, phone_hash, 0, NULL,
-		    client_receiver);
+		    client_receiver, carg);
 	
 	return EOK;
Index: uspace/lib/c/generic/devman.c
===================================================================
--- uspace/lib/c/generic/devman.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/generic/devman.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -35,4 +35,5 @@
  */
 
+#include <adt/list.h>
 #include <str.h>
 #include <ipc/services.h>
@@ -194,5 +195,5 @@
 	
 	exch = devman_exchange_begin(DEVMAN_DRIVER);
-	async_connect_to_me(exch, 0, 0, 0, NULL);
+	async_connect_to_me(exch, 0, 0, 0, NULL, NULL);
 	devman_exchange_end(exch);
 	
@@ -231,8 +232,7 @@
 	}
 	
-	link_t *link = match_ids->ids.next;
 	match_id_t *match_id = NULL;
 	
-	while (link != &match_ids->ids) {
+	list_foreach(match_ids->ids, link) {
 		match_id = list_get_instance(link, match_id_t, link);
 		
@@ -255,6 +255,4 @@
 			return retval;
 		}
-		
-		link = link->next;
 	}
 	
Index: uspace/lib/c/generic/devmap.c
===================================================================
--- uspace/lib/c/generic/devmap.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/generic/devmap.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -187,5 +187,5 @@
 	
 	exch = devmap_exchange_begin(DEVMAP_DRIVER);
-	async_connect_to_me(exch, 0, 0, 0, NULL);
+	async_connect_to_me(exch, 0, 0, 0, NULL, NULL);
 	devmap_exchange_end(exch);
 	
Index: uspace/lib/c/generic/devmap_obsolete.c
===================================================================
--- uspace/lib/c/generic/devmap_obsolete.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ 	(revision )
@@ -1,114 +1,0 @@
-/*
- * Copyright (c) 2007 Josef Cejka
- * Copyright (c) 2009 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <str.h>
-#include <ipc/services.h>
-#include <ns.h>
-#include <ns_obsolete.h>
-#include <ipc/devmap.h>
-#include <devmap_obsolete.h>
-#include <async.h>
-#include <async_obsolete.h>
-#include <errno.h>
-#include <malloc.h>
-#include <bool.h>
-
-static int devmap_phone_driver = -1;
-static int devmap_phone_client = -1;
-
-/** Get phone to device mapper task. */
-int devmap_obsolete_get_phone(devmap_interface_t iface, unsigned int flags)
-{
-	switch (iface) {
-	case DEVMAP_DRIVER:
-		if (devmap_phone_driver >= 0)
-			return devmap_phone_driver;
-		
-		if (flags & IPC_FLAG_BLOCKING)
-			devmap_phone_driver = service_obsolete_connect_blocking(SERVICE_DEVMAP,
-			    DEVMAP_DRIVER, 0);
-		else
-			devmap_phone_driver = service_obsolete_connect(SERVICE_DEVMAP,
-			    DEVMAP_DRIVER, 0);
-		
-		return devmap_phone_driver;
-	case DEVMAP_CLIENT:
-		if (devmap_phone_client >= 0)
-			return devmap_phone_client;
-		
-		if (flags & IPC_FLAG_BLOCKING)
-			devmap_phone_client = service_obsolete_connect_blocking(SERVICE_DEVMAP,
-			    DEVMAP_CLIENT, 0);
-		else
-			devmap_phone_client = service_obsolete_connect(SERVICE_DEVMAP,
-			    DEVMAP_CLIENT, 0);
-		
-		return devmap_phone_client;
-	default:
-		return -1;
-	}
-}
-
-void devmap_obsolete_hangup_phone(devmap_interface_t iface)
-{
-	switch (iface) {
-	case DEVMAP_DRIVER:
-		if (devmap_phone_driver >= 0) {
-			async_obsolete_hangup(devmap_phone_driver);
-			devmap_phone_driver = -1;
-		}
-		break;
-	case DEVMAP_CLIENT:
-		if (devmap_phone_client >= 0) {
-			async_obsolete_hangup(devmap_phone_client);
-			devmap_phone_client = -1;
-		}
-		break;
-	default:
-		break;
-	}
-}
-
-int devmap_obsolete_device_connect(devmap_handle_t handle, unsigned int flags)
-{
-	int phone;
-	
-	if (flags & IPC_FLAG_BLOCKING) {
-		phone = service_obsolete_connect_blocking(SERVICE_DEVMAP,
-		    DEVMAP_CONNECT_TO_DEVICE, handle);
-	} else {
-		phone = service_obsolete_connect(SERVICE_DEVMAP,
-		    DEVMAP_CONNECT_TO_DEVICE, handle);
-	}
-	
-	return phone;
-}
-
-/** @}
- */
Index: uspace/lib/c/generic/fibril.c
===================================================================
--- uspace/lib/c/generic/fibril.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/generic/fibril.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -222,5 +222,6 @@
 	fibril_t *dstf;
 	if ((stype == FIBRIL_TO_MANAGER) || (stype == FIBRIL_FROM_DEAD)) {
-		dstf = list_get_instance(manager_list.next, fibril_t, link);
+		dstf = list_get_instance(list_first(&manager_list), fibril_t,
+		    link);
 		if (serialization_count && stype == FIBRIL_TO_MANAGER) {
 			serialized_threads++;
@@ -233,10 +234,10 @@
 	} else {
 		if (!list_empty(&serialized_list)) {
-			dstf = list_get_instance(serialized_list.next, fibril_t,
-			    link);
+			dstf = list_get_instance(list_first(&serialized_list),
+			    fibril_t, link);
 			serialized_threads--;
 		} else {
-			dstf = list_get_instance(ready_list.next, fibril_t,
-			    link);
+			dstf = list_get_instance(list_first(&ready_list),
+			    fibril_t, link);
 		}
 	}
@@ -326,5 +327,5 @@
 	
 	if (!list_empty(&manager_list))
-		list_remove(manager_list.next);
+		list_remove(list_first(&manager_list));
 	
 	futex_up(&fibril_futex);
Index: uspace/lib/c/generic/fibril_synch.c
===================================================================
--- uspace/lib/c/generic/fibril_synch.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/generic/fibril_synch.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -148,6 +148,6 @@
 		fibril_t *f;
 	
-		assert(!list_empty(&fm->waiters));
-		tmp = fm->waiters.next;
+		tmp = list_first(&fm->waiters);
+		assert(tmp != NULL);
 		wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
 		wdp->active = true;
@@ -279,5 +279,5 @@
 	
 	while (!list_empty(&frw->waiters)) {
-		link_t *tmp = frw->waiters.next;
+		link_t *tmp = list_first(&frw->waiters);
 		awaiter_t *wdp;
 		fibril_t *f;
@@ -422,5 +422,5 @@
 	futex_down(&async_futex);
 	while (!list_empty(&fcv->waiters)) {
-		tmp = fcv->waiters.next;
+		tmp = list_first(&fcv->waiters);
 		wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
 		list_remove(&wdp->wu_event.link);
Index: uspace/lib/c/generic/io/io.c
===================================================================
--- uspace/lib/c/generic/io/io.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/generic/io/io.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -127,10 +127,7 @@
 void __stdio_done(void)
 {
-	link_t *link = files.next;
-	
-	while (link != &files) {
-		FILE *file = list_get_instance(link, FILE, link);
+	while (!list_empty(&files)) {
+		FILE *file = list_get_instance(list_first(&files), FILE, link);
 		fclose(file);
-		link = files.next;
 	}
 }
Index: uspace/lib/c/generic/ipc.c
===================================================================
--- uspace/lib/c/generic/ipc.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/generic/ipc.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -458,5 +458,5 @@
 	while (!list_empty(&queued_calls)) {
 		async_call_t *call =
-		    list_get_instance(queued_calls.next, async_call_t, list);
+		    list_get_instance(list_first(&queued_calls), async_call_t, list);
 		ipc_callid_t callid =
 		    ipc_call_async_internal(call->u.msg.phoneid, &call->u.msg.data);
@@ -511,5 +511,5 @@
 	
 	link_t *item;
-	for (item = dispatched_calls.next; item != &dispatched_calls;
+	for (item = dispatched_calls.head.next; item != &dispatched_calls.head;
 	    item = item->next) {
 		async_call_t *call =
Index: uspace/lib/c/generic/net/icmp_common.c
===================================================================
--- uspace/lib/c/generic/net/icmp_common.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/generic/net/icmp_common.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -45,14 +45,10 @@
 /** Connect to the ICMP module.
  *
- * @param[in] timeout Connection timeout in microseconds, zero
- *                    for no timeout.
- *
  * @return ICMP module phone on success.
- * @return ETIMEOUT if the connection timeouted.
  *
  */
-int icmp_connect_module(suseconds_t timeout)
+int icmp_connect_module(void)
 {
-	return connect_to_service_timeout(SERVICE_ICMP, timeout);
+	return connect_to_service(SERVICE_ICMP);
 }
 
Index: uspace/lib/c/generic/net/modules.c
===================================================================
--- uspace/lib/c/generic/net/modules.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/generic/net/modules.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -114,32 +114,10 @@
     async_client_conn_t client_receiver)
 {
-	return bind_service_timeout(need, arg1, arg2, arg3, client_receiver, 0);
-}
-
-/** Create bidirectional connection with the needed module service and registers
- * the message receiver.
- *
- * @param[in] need	The needed module service.
- * @param[in] arg1	The first parameter.
- * @param[in] arg2	The second parameter.
- * @param[in] arg3	The third parameter.
- * @param[in] client_receiver The message receiver.
- * @param[in] timeout	The connection timeout in microseconds. No timeout if
- * 			set to zero (0).
- *
- * @return		The phone of the needed service.
- * @return		ETIMEOUT if the connection timeouted.
- * @return		Other error codes as defined for the ipc_connect_to_me()
- *			function.
- *
- */
-int bind_service_timeout(services_t need, sysarg_t arg1, sysarg_t arg2,
-    sysarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout)
-{
 	/* Connect to the needed service */
-	int phone = connect_to_service_timeout(need, timeout);
+	int phone = connect_to_service(need);
 	if (phone >= 0) {
 		/* Request the bidirectional connection */
-		int rc = async_obsolete_connect_to_me(phone, arg1, arg2, arg3, client_receiver);
+		int rc = async_obsolete_connect_to_me(phone, arg1, arg2, arg3,
+		    client_receiver, NULL);
 		if (rc != EOK) {
 			async_obsolete_hangup(phone);
@@ -158,37 +136,5 @@
 int connect_to_service(services_t need)
 {
-	return connect_to_service_timeout(need, 0);
-}
-
-/** Connects to the needed module.
- *
- *  @param[in] need	The needed module service.
- *  @param[in] timeout	The connection timeout in microseconds. No timeout if
- *			set to zero (0).
- *  @return		The phone of the needed service.
- *  @return		ETIMEOUT if the connection timeouted.
- */
-int connect_to_service_timeout(services_t need, suseconds_t timeout)
-{
-	int phone;
-
-	/* If no timeout is set */
-	if (timeout <= 0)
-		return service_obsolete_connect_blocking(need, 0, 0);
-	
-	while (true) {
-		phone = service_obsolete_connect(need, 0, 0);
-		if ((phone >= 0) || (phone != ENOENT))
-			return phone;
-
-		/* Abort if no time is left */
-		if (timeout <= 0)
-			return ETIMEOUT;
-
-		/* Wait the minimum of the module wait time and the timeout */
-		usleep((timeout <= MODULE_WAIT_TIME) ?
-		    timeout : MODULE_WAIT_TIME);
-		timeout -= MODULE_WAIT_TIME;
-	}
+	return service_obsolete_connect_blocking(need, 0, 0);
 }
 
Index: uspace/lib/c/generic/net/socket_client.c
===================================================================
--- uspace/lib/c/generic/net/socket_client.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/generic/net/socket_client.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -65,7 +65,4 @@
 #define SOCKET_MAX_ACCEPTED_SIZE	0
 
-/** Default timeout for connections in microseconds. */
-#define SOCKET_CONNECT_TIMEOUT	(1 * 1000 * 1000)
-
 /**
  * Maximum number of random attempts to find a new socket identifier before
@@ -203,6 +200,7 @@
  * @param[in] iid	The initial message identifier.
  * @param[in] icall	The initial message call structure.
- */
-static void socket_connection(ipc_callid_t iid, ipc_call_t * icall)
+ * @param[in] arg	Local argument.
+ */
+static void socket_connection(ipc_callid_t iid, ipc_call_t * icall, void *arg)
 {
 	ipc_callid_t callid;
@@ -288,12 +286,11 @@
  * @return		The TCP module phone.
  * @return		Other error codes as defined for the
- *			bind_service_timeout() function.
+ *			bind_service() function.
  */
 static int socket_get_tcp_phone(void)
 {
 	if (socket_globals.tcp_phone < 0) {
-		socket_globals.tcp_phone = bind_service_timeout(SERVICE_TCP,
-		    0, 0, SERVICE_TCP, socket_connection,
-		    SOCKET_CONNECT_TIMEOUT);
+		socket_globals.tcp_phone = bind_service(SERVICE_TCP,
+		    0, 0, SERVICE_TCP, socket_connection);
 	}
 
@@ -307,12 +304,11 @@
  * @return		The UDP module phone.
  * @return		Other error codes as defined for the
- *			bind_service_timeout() function.
+ *			bind_service() function.
  */
 static int socket_get_udp_phone(void)
 {
 	if (socket_globals.udp_phone < 0) {
-		socket_globals.udp_phone = bind_service_timeout(SERVICE_UDP,
-		    0, 0, SERVICE_UDP, socket_connection,
-		    SOCKET_CONNECT_TIMEOUT);
+		socket_globals.udp_phone = bind_service(SERVICE_UDP,
+		    0, 0, SERVICE_UDP, socket_connection);
 	}
 
@@ -396,5 +392,5 @@
  * @return		Other error codes as defined for the NET_SOCKET message.
  * @return		Other error codes as defined for the
- *			bind_service_timeout() function.
+ *			bind_service() function.
  */
 int socket(int domain, int type, int protocol)
Index: uspace/lib/c/generic/ns.c
===================================================================
--- uspace/lib/c/generic/ns.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/generic/ns.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -42,5 +42,5 @@
 {
 	async_exch_t *exch = async_exchange_begin(session_ns);
-	int rc = async_connect_to_me(exch, service, 0, 0, NULL);
+	int rc = async_connect_to_me(exch, service, 0, 0, NULL, NULL);
 	async_exchange_end(exch);
 	
Index: uspace/lib/c/generic/str.c
===================================================================
--- uspace/lib/c/generic/str.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/generic/str.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -540,4 +540,7 @@
 
 	dstr_size = str_size(dest);
+	if (dstr_size >= size)
+		return;
+	
 	str_cpy(dest + dstr_size, size - dstr_size, src);
 }
Index: uspace/lib/c/generic/task.c
===================================================================
--- uspace/lib/c/generic/task.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/generic/task.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -101,30 +101,4 @@
 int task_spawnv(task_id_t *id, const char *path, const char *const args[])
 {
-	/* Connect to a program loader. */
-	loader_t *ldr = loader_connect();
-	if (ldr == NULL)
-		return EREFUSED;
-	
-	/* Get task ID. */
-	task_id_t task_id;
-	int rc = loader_get_task_id(ldr, &task_id);
-	if (rc != EOK)
-		goto error;
-	
-	/* Send spawner's current working directory. */
-	rc = loader_set_cwd(ldr);
-	if (rc != EOK)
-		goto error;
-	
-	/* Send program pathname. */
-	rc = loader_set_pathname(ldr, path);
-	if (rc != EOK)
-		goto error;
-	
-	/* Send arguments. */
-	rc = loader_set_args(ldr, args);
-	if (rc != EOK)
-		goto error;
-	
 	/* Send default files */
 	fdi_node_t *files[4];
@@ -150,4 +124,51 @@
 	files[3] = NULL;
 	
+	return task_spawnvf(id, path, args, files);
+}
+
+/** Create a new task by running an executable from the filesystem.
+ *
+ * This is really just a convenience wrapper over the more complicated
+ * loader API. Arguments are passed as a null-terminated array of strings.
+ * Files are passed as null-terminated array of pointers to fdi_node_t.
+ *
+ * @param id    If not NULL, the ID of the task is stored here on success.
+ * @param path  Pathname of the binary to execute.
+ * @param argv  Command-line arguments.
+ * @param files Standard files to use.
+ *
+ * @return Zero on success or negative error code.
+ *
+ */
+int task_spawnvf(task_id_t *id, const char *path, const char *const args[],
+    fdi_node_t *const files[])
+{
+	/* Connect to a program loader. */
+	loader_t *ldr = loader_connect();
+	if (ldr == NULL)
+		return EREFUSED;
+	
+	/* Get task ID. */
+	task_id_t task_id;
+	int rc = loader_get_task_id(ldr, &task_id);
+	if (rc != EOK)
+		goto error;
+	
+	/* Send spawner's current working directory. */
+	rc = loader_set_cwd(ldr);
+	if (rc != EOK)
+		goto error;
+	
+	/* Send program pathname. */
+	rc = loader_set_pathname(ldr, path);
+	if (rc != EOK)
+		goto error;
+	
+	/* Send arguments. */
+	rc = loader_set_args(ldr, args);
+	if (rc != EOK)
+		goto error;
+	
+	/* Send files */
 	rc = loader_set_files(ldr, files);
 	if (rc != EOK)
Index: uspace/lib/c/include/adt/hash_table.h
===================================================================
--- uspace/lib/c/include/adt/hash_table.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/include/adt/hash_table.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -75,5 +75,5 @@
 /** Hash table structure. */
 typedef struct {
-	link_t *entry;
+	list_t *entry;
 	hash_count_t entries;
 	hash_count_t max_keys;
Index: uspace/lib/c/include/adt/list.h
===================================================================
--- uspace/lib/c/include/adt/list.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/include/adt/list.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2001-2004 Jakub Jermar
+ * Copyright (c) 2011 Jiri Svoboda
  * All rights reserved.
  *
@@ -36,7 +37,8 @@
 #define LIBC_LIST_H_
 
+#include <assert.h>
 #include <unistd.h>
 
-/** Doubly linked list head and link type. */
+/** Doubly linked list link. */
 typedef struct link {
 	struct link *prev;  /**< Pointer to the previous item in the list. */
@@ -44,4 +46,9 @@
 } link_t;
 
+/** Doubly linked list. */
+typedef struct list {
+	link_t head;  /**< List head. Does not have any data. */
+} list_t;
+
 /** Declare and initialize statically allocated list.
  *
@@ -50,7 +57,9 @@
  */
 #define LIST_INITIALIZE(name) \
-	link_t name = { \
-		.prev = &name, \
-		.next = &name \
+	list_t name = { \
+		.head = { \
+			.prev = &(name).head, \
+			.next = &(name).head \
+		} \
 	}
 
@@ -59,6 +68,9 @@
 
 #define list_foreach(list, iterator) \
-	for (link_t *iterator = (list).next; \
-	    iterator != &(list); iterator = iterator->next)
+	for (link_t *iterator = (list).head.next; \
+	    iterator != &(list).head; iterator = iterator->next)
+
+#define assert_link_not_used(link) \
+	assert((link)->prev == NULL && (link)->next == NULL)
 
 /** Initialize doubly-linked circular list link
@@ -79,11 +91,33 @@
  * Initialize doubly-linked circular list.
  *
- * @param list Pointer to link_t structure representing the list.
- *
- */
-static inline void list_initialize(link_t *list)
-{
-	list->prev = list;
-	list->next = list;
+ * @param list Pointer to list_t structure.
+ *
+ */
+static inline void list_initialize(list_t *list)
+{
+	list->head.prev = &list->head;
+	list->head.next = &list->head;
+}
+
+/** Insert item before another item in doubly-linked circular list.
+ *
+ */
+static inline void list_insert_before(link_t *lnew, link_t *lold)
+{
+	lnew->next = lold;
+	lnew->prev = lold->prev;
+	lold->prev->next = lnew;
+	lold->prev = lnew;
+}
+
+/** Insert item after another item in doubly-linked circular list.
+ *
+ */
+static inline void list_insert_after(link_t *lnew, link_t *lold)
+{
+	lnew->prev = lold;
+	lnew->next = lold->next;
+	lold->next->prev = lnew;
+	lold->next = lnew;
 }
 
@@ -93,13 +127,10 @@
  *
  * @param link Pointer to link_t structure to be added.
- * @param list Pointer to link_t structure representing the list.
- *
- */
-static inline void list_prepend(link_t *link, link_t *list)
-{
-	link->next = list->next;
-	link->prev = list;
-	list->next->prev = link;
-	list->next = link;
+ * @param list Pointer to list_t structure.
+ *
+ */
+static inline void list_prepend(link_t *link, list_t *list)
+{
+	list_insert_after(link, &list->head);
 }
 
@@ -109,29 +140,10 @@
  *
  * @param link Pointer to link_t structure to be added.
- * @param list Pointer to link_t structure representing the list.
- *
- */
-static inline void list_append(link_t *link, link_t *list)
-{
-	link->prev = list->prev;
-	link->next = list;
-	list->prev->next = link;
-	list->prev = link;
-}
-
-/** Insert item before another item in doubly-linked circular list.
- *
- */
-static inline void list_insert_before(link_t *link, link_t *list)
-{
-	list_append(link, list);
-}
-
-/** Insert item after another item in doubly-linked circular list.
- *
- */
-static inline void list_insert_after(link_t *link, link_t *list)
-{
-	list_prepend(list, link);
+ * @param list Pointer to list_t structure.
+ *
+ */
+static inline void list_append(link_t *link, list_t *list)
+{
+	list_insert_before(link, &list->head);
 }
 
@@ -155,15 +167,15 @@
  * Query emptiness of doubly-linked circular list.
  *
- * @param list Pointer to link_t structure representing the list.
- *
- */
-static inline int list_empty(link_t *list)
-{
-	return (list->next == list);
-}
-
-/** Get head item of a list.
- *
- * @param list Pointer to link_t structure representing the list.
+ * @param list Pointer to lins_t structure.
+ *
+ */
+static inline int list_empty(list_t *list)
+{
+	return (list->head.next == &list->head);
+}
+
+/** Get first item in list.
+ *
+ * @param list Pointer to list_t structure.
  *
  * @return Head item of the list.
@@ -171,7 +183,20 @@
  *
  */
-static inline link_t *list_head(link_t *list)
-{
-	return ((list->next == list) ? NULL : list->next);
+static inline link_t *list_first(list_t *list)
+{
+	return ((list->head.next == &list->head) ? NULL : list->head.next);
+}
+
+/** Get last item in list.
+ *
+ * @param list Pointer to list_t structure.
+ *
+ * @return Head item of the list.
+ * @return NULL if the list is empty.
+ *
+ */
+static inline link_t *list_last(list_t *list)
+{
+	return ((list->head.prev == &list->head) ? NULL : list->head.prev);
 }
 
@@ -230,5 +255,5 @@
 }
 
-/** Get n-th item of a list.
+/** Get n-th item in a list.
  *
  * @param list Pointer to link_t structure representing the list.
@@ -239,5 +264,5 @@
  *
  */
-static inline link_t *list_nth(link_t *list, unsigned int n)
+static inline link_t *list_nth(list_t *list, unsigned int n)
 {
 	unsigned int cnt = 0;
@@ -253,7 +278,7 @@
 }
 
-extern int list_member(const link_t *, const link_t *);
-extern void list_concat(link_t *, link_t *);
-extern unsigned int list_count(const link_t *);
+extern int list_member(const link_t *, const list_t *);
+extern void list_concat(list_t *, list_t *);
+extern unsigned int list_count(const list_t *);
 
 #endif
Index: uspace/lib/c/include/adt/prodcons.h
===================================================================
--- uspace/lib/c/include/adt/prodcons.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/include/adt/prodcons.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -42,5 +42,5 @@
 	fibril_mutex_t mtx;
 	fibril_condvar_t cv;
-	link_t list;
+	list_t list;
 } prodcons_t;
 
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/include/async.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -53,5 +53,16 @@
 typedef void (*async_client_data_dtor_t)(void *);
 
-typedef void (*async_client_conn_t)(ipc_callid_t, ipc_call_t *);
+/** Client connection handler
+ *
+ * @param callid ID of incoming call or 0 if connection initiated from
+ *               inside using async_connect_to_me()
+ * @param call   Incoming call or 0 if connection initiated from inside
+ * @param arg    Local argument passed from async_new_connection() or
+ *               async_connect_to_me()
+ */
+typedef void (*async_client_conn_t)(ipc_callid_t, ipc_call_t *, void *);
+
+/** Interrupt handler */
+typedef void (*async_interrupt_handler_t)(ipc_callid_t, ipc_call_t *);
 
 /** Exchange management style
@@ -88,5 +99,5 @@
 typedef struct {
 	/** List of inactive exchanges */
-	link_t exch_list;
+	list_t exch_list;
 	
 	/** Exchange management style */
@@ -166,5 +177,5 @@
 
 extern fid_t async_new_connection(sysarg_t, sysarg_t, ipc_callid_t,
-    ipc_call_t *, async_client_conn_t);
+    ipc_call_t *, async_client_conn_t, void *);
 
 extern void async_usleep(suseconds_t);
@@ -177,5 +188,5 @@
 
 extern void async_set_client_connection(async_client_conn_t);
-extern void async_set_interrupt_received(async_client_conn_t);
+extern void async_set_interrupt_received(async_interrupt_handler_t);
 
 /*
@@ -351,5 +362,5 @@
 
 extern int async_connect_to_me(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
-    async_client_conn_t);
+    async_client_conn_t, void *);
 
 extern int async_hangup(async_sess_t *);
Index: uspace/lib/c/include/async_obsolete.h
===================================================================
--- uspace/lib/c/include/async_obsolete.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/include/async_obsolete.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -40,7 +40,4 @@
 #define LIBC_ASYNC_OBSOLETE_H_
 
-extern void async_obsolete_serialize_start(void);
-extern void async_obsolete_serialize_end(void);
-
 #define async_obsolete_send_0(phoneid, method, dataptr) \
 	async_obsolete_send_fast((phoneid), (method), 0, 0, 0, 0, (dataptr))
@@ -198,5 +195,5 @@
 
 extern int async_obsolete_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t,
-    async_client_conn_t);
+    async_client_conn_t, void *);
 extern int async_obsolete_connect_me_to(int, sysarg_t, sysarg_t, sysarg_t);
 extern int async_obsolete_connect_me_to_blocking(int, sysarg_t, sysarg_t, sysarg_t);
Index: uspace/lib/c/include/devmap_obsolete.h
===================================================================
--- uspace/lib/c/include/devmap_obsolete.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ 	(revision )
@@ -1,50 +1,0 @@
-/*
- * Copyright (c) 2009 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_DEVMAP_OBSOLETE_H_
-#define LIBC_DEVMAP_OBSOLETE_H_
-
-#include <ipc/devmap.h>
-#include <async.h>
-#include <bool.h>
-
-extern int devmap_obsolete_get_phone(devmap_interface_t, unsigned int);
-extern void devmap_obsolete_hangup_phone(devmap_interface_t iface);
-
-extern int devmap_obsolete_device_connect(devmap_handle_t, unsigned int);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/fibril_synch.h
===================================================================
--- uspace/lib/c/include/fibril_synch.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/include/fibril_synch.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -45,5 +45,5 @@
 	fibril_owner_info_t oi;  /**< Keep this the first thing. */
 	int counter;
-	link_t waiters;
+	list_t waiters;
 } fibril_mutex_t;
 
@@ -55,6 +55,8 @@
 		.counter = 1, \
 		.waiters = { \
-			.prev = &name.waiters, \
-			.next = &name.waiters, \
+			.head = { \
+				.prev = &(name).waiters.head, \
+				.next = &(name).waiters.head, \
+			} \
 		} \
 	}
@@ -67,5 +69,5 @@
 	unsigned writers;
 	unsigned readers;
-	link_t waiters;
+	list_t waiters;
 } fibril_rwlock_t;
 
@@ -78,6 +80,8 @@
 		.writers = 0, \
 		.waiters = { \
-			.prev = &name.waiters, \
-			.next = &name.waiters, \
+			.head = { \
+				.prev = &(name).waiters.head, \
+				.next = &(name).waiters.head, \
+			} \
 		} \
 	}
@@ -87,5 +91,5 @@
 
 typedef struct {
-	link_t waiters;
+	list_t waiters;
 } fibril_condvar_t;
 
@@ -93,6 +97,8 @@
 	{ \
 		.waiters = { \
-			.next = &name.waiters, \
-			.prev = &name.waiters, \
+			.head = { \
+				.next = &(name).waiters.head, \
+				.prev = &(name).waiters.head, \
+			} \
 		} \
 	}
Index: uspace/lib/c/include/ipc/clipboard.h
===================================================================
--- uspace/lib/c/include/ipc/clipboard.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/include/ipc/clipboard.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -36,4 +36,6 @@
 #define LIBC_IPC_CLIPBOARD_H_
 
+#include <ipc/common.h>
+
 typedef enum {
 	CLIPBOARD_PUT_DATA = IPC_FIRST_USER_METHOD,
Index: uspace/lib/c/include/ipc/devman.h
===================================================================
--- uspace/lib/c/include/ipc/devman.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/include/ipc/devman.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -72,5 +72,5 @@
  */
 typedef struct match_id_list {
-	link_t ids;
+	list_t ids;
 } match_id_list_t;
 
@@ -95,11 +95,11 @@
 {
 	match_id_t *mid = NULL;
-	link_t *link = ids->ids.next;
+	link_t *link = ids->ids.head.next;
 	
-	while (link != &ids->ids) {
+	while (link != &ids->ids.head) {
 		mid = list_get_instance(link, match_id_t,link);
 		if (mid->score < id->score) {
 			break;
-		}	
+		}
 		link = link->next;
 	}
@@ -118,10 +118,10 @@
 	match_id_t *id;
 	
-	while(!list_empty(&ids->ids)) {
-		link = ids->ids.next;
-		list_remove(link);		
+	while (!list_empty(&ids->ids)) {
+		link = list_first(&ids->ids);
+		list_remove(link);
 		id = list_get_instance(link, match_id_t, link);
-		delete_match_id(id);		
-	}	
+		delete_match_id(id);
+	}
 }
 
Index: uspace/lib/c/include/ipc/input.h
===================================================================
--- uspace/lib/c/include/ipc/input.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
+++ uspace/lib/c/include/ipc/input.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -0,0 +1,55 @@
+/*
+ * 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 libcipc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_IPC_INPUT_H_
+#define LIBC_IPC_INPUT_H_
+
+#include <ipc/common.h>
+
+typedef enum {
+	INPUT_YIELD = IPC_FIRST_USER_METHOD,
+	INPUT_RECLAIM
+} input_request_t;
+
+typedef enum {
+	INPUT_EVENT_KEY = IPC_FIRST_USER_METHOD,
+	INPUT_EVENT_MOVE,
+	INPUT_EVENT_BUTTON
+} input_notif_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/c/include/ipc/kbd.h
===================================================================
--- uspace/lib/c/include/ipc/kbd.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ 	(revision )
@@ -1,56 +1,0 @@
-/*
- * Copyright (c) 2009 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 kbdgen generic
- * @brief HelenOS generic uspace keyboard handler.
- * @ingroup kbd
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_IPC_KBD_H_
-#define LIBC_IPC_KBD_H_
-
-#include <ipc/common.h>
-#include <ipc/dev_iface.h>
-
-typedef enum {
-	KBD_YIELD = DEV_FIRST_CUSTOM_METHOD,
-	KBD_RECLAIM
-} kbd_request_t;
-
-typedef enum {
-	KBD_EVENT = IPC_FIRST_USER_METHOD
-} kbd_notif_t;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/lib/c/include/ipc/kbdev.h
===================================================================
--- uspace/lib/c/include/ipc/kbdev.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
+++ uspace/lib/c/include/ipc/kbdev.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -0,0 +1,55 @@
+/*
+ * 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 libcipc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_IPC_KBDEV_H_
+#define LIBC_IPC_KBDEV_H_
+
+#include <ipc/common.h>
+#include <ipc/dev_iface.h>
+
+typedef enum {
+	KBDEV_YIELD = DEV_FIRST_CUSTOM_METHOD,
+	KBDEV_RECLAIM,
+	KBDEV_SET_IND
+} kbdev_request_t;
+
+typedef enum {
+	KBDEV_EVENT = IPC_FIRST_USER_METHOD
+} kbdev_notif_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/c/include/ipc/mouse.h
===================================================================
--- uspace/lib/c/include/ipc/mouse.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ 	(revision )
@@ -1,50 +1,0 @@
-/*
- * Copyright (c) 2009 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 mouse
- * @brief
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_IPC_MOUSE_H_
-#define LIBC_IPC_MOUSE_H_
-
-#include <ipc/common.h>
-
-typedef enum {
-	MEVENT_BUTTON = IPC_FIRST_USER_METHOD,
-	MEVENT_MOVE
-} mouse_notif_t;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/lib/c/include/ipc/mouseev.h
===================================================================
--- uspace/lib/c/include/ipc/mouseev.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
+++ uspace/lib/c/include/ipc/mouseev.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2009 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 mouse
+ * @brief
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_IPC_MOUSEEV_H_
+#define LIBC_IPC_MOUSEEV_H_
+
+#include <ipc/common.h>
+#include <ipc/dev_iface.h>
+
+typedef enum {
+	MOUSEEV_YIELD = DEV_FIRST_CUSTOM_METHOD,
+	MOUSEEV_RECLAIM
+} mouseev_request_t;
+
+typedef enum {
+	MOUSEEV_MOVE_EVENT = IPC_FIRST_USER_METHOD,
+	MOUSEEV_BUTTON_EVENT
+} mouseev_notif_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/c/include/ipc/services.h
===================================================================
--- uspace/lib/c/include/ipc/services.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/include/ipc/services.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -41,7 +41,5 @@
 	SERVICE_NONE = 0,
 	SERVICE_LOAD,
-	SERVICE_PCI,
 	SERVICE_VIDEO,
-	SERVICE_CONSOLE,
 	SERVICE_VFS,
 	SERVICE_DEVMAP,
@@ -56,9 +54,7 @@
 	SERVICE_IP,
 	SERVICE_ARP,
-	SERVICE_RARP,
 	SERVICE_ICMP,
 	SERVICE_UDP,
-	SERVICE_TCP,
-	SERVICE_SOCKET
+	SERVICE_TCP
 } services_t;
 
Index: uspace/lib/c/include/net/icmp_common.h
===================================================================
--- uspace/lib/c/include/net/icmp_common.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/include/net/icmp_common.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -41,8 +41,5 @@
 #include <sys/time.h>
 
-/** Default timeout for incoming connections in microseconds (1 sec). */
-#define ICMP_CONNECT_TIMEOUT  1000000
-
-extern int icmp_connect_module(suseconds_t);
+extern int icmp_connect_module(void);
 
 #endif
Index: uspace/lib/c/include/net/modules.h
===================================================================
--- uspace/lib/c/include/net/modules.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/include/net/modules.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -58,8 +58,5 @@
 extern int bind_service(services_t, sysarg_t, sysarg_t, sysarg_t,
     async_client_conn_t);
-extern int bind_service_timeout(services_t, sysarg_t, sysarg_t, sysarg_t,
-    async_client_conn_t, suseconds_t);
 extern int connect_to_service(services_t);
-extern int connect_to_service_timeout(services_t, suseconds_t);
 extern int data_reply(void *, size_t);
 extern void refresh_answer(ipc_call_t *, size_t *);
Index: uspace/lib/c/include/task.h
===================================================================
--- uspace/lib/c/include/task.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/c/include/task.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -37,4 +37,5 @@
 
 #include <sys/types.h>
+#include <vfs/vfs.h>
 
 typedef uint64_t task_id_t;
@@ -51,4 +52,6 @@
 extern task_id_t task_spawn(const char *, const char *const[], int *);
 extern int task_spawnv(task_id_t *, const char *path, const char *const []);
+extern int task_spawnvf(task_id_t *, const char *path, const char *const [],
+    fdi_node_t *const []);
 extern int task_spawnl(task_id_t *, const char *path, ...);
 
Index: uspace/lib/drv/Makefile
===================================================================
--- uspace/lib/drv/Makefile	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/drv/Makefile	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -36,4 +36,5 @@
 	generic/dev_iface.c \
 	generic/log.c \
+	generic/logbuf.c \
 	generic/remote_hw_res.c \
 	generic/remote_char_dev.c \
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/drv/generic/driver.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -139,10 +139,9 @@
 find_interrupt_context_by_id(interrupt_context_list_t *list, int id)
 {
+	interrupt_context_t *ctx;
+	
 	fibril_mutex_lock(&list->mutex);
 	
-	link_t *link = list->contexts.next;
-	interrupt_context_t *ctx;
-	
-	while (link != &list->contexts) {
+	list_foreach(list->contexts, link) {
 		ctx = list_get_instance(link, interrupt_context_t, link);
 		if (ctx->id == id) {
@@ -150,5 +149,4 @@
 			return ctx;
 		}
-		link = link->next;
 	}
 	
@@ -160,10 +158,9 @@
 find_interrupt_context(interrupt_context_list_t *list, ddf_dev_t *dev, int irq)
 {
+	interrupt_context_t *ctx;
+	
 	fibril_mutex_lock(&list->mutex);
 	
-	link_t *link = list->contexts.next;
-	interrupt_context_t *ctx;
-	
-	while (link != &list->contexts) {
+	list_foreach(list->contexts, link) {
 		ctx = list_get_instance(link, interrupt_context_t, link);
 		if (ctx->irq == irq && ctx->dev == dev) {
@@ -171,5 +168,4 @@
 			return ctx;
 		}
-		link = link->next;
 	}
 	
@@ -231,12 +227,11 @@
 }
 
-static ddf_fun_t *driver_get_function(link_t *functions, devman_handle_t handle)
+static ddf_fun_t *driver_get_function(list_t *functions, devman_handle_t handle)
 {
 	ddf_fun_t *fun = NULL;
 	
 	fibril_mutex_lock(&functions_mutex);
-	link_t *link = functions->next;
-	
-	while (link != functions) {
+	
+	list_foreach(*functions, link) {
 		fun = list_get_instance(link, ddf_fun_t, link);
 		if (fun->handle == handle) {
@@ -244,6 +239,4 @@
 			return fun;
 		}
-		
-		link = link->next;
 	}
 	
@@ -361,5 +354,5 @@
 			if (default_handler != NULL) {
 				(*default_handler)(fun, callid, &call);
-				break;
+				continue;
 			}
 			
@@ -372,5 +365,5 @@
 			    driver->name, iface_idx);
 			async_answer_0(callid, ENOTSUP);
-			break;
+			continue;
 		}
 		
@@ -384,5 +377,5 @@
 			    "with id %d.\n", handle, iface_idx);
 			async_answer_0(callid, ENOTSUP);
-			break;
+			continue;
 		}
 		
@@ -403,5 +396,5 @@
 			    "invalid interface method.", driver->name);
 			async_answer_0(callid, ENOTSUP);
-			break;
+			continue;
 		}
 		
@@ -413,5 +406,4 @@
 		 */
 		(*iface_method_ptr)(fun, ops, callid, &call);
-		break;
 	}
 }
@@ -428,5 +420,5 @@
 
 /** Function for handling connections to device driver. */
-static void driver_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void driver_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	/* Select interface */
Index: uspace/lib/drv/generic/logbuf.c
===================================================================
--- uspace/lib/drv/generic/logbuf.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
+++ uspace/lib/drv/generic/logbuf.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -0,0 +1,202 @@
+/*
+ * 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
+ * @{
+ */
+
+#include <libarch/common.h>
+#include <stdio.h>
+#include <ddf/log.h>
+#include <assert.h>
+
+/** Formatting string for printing number of not-printed items. */
+#define REMAINDER_STR_FMT " (%zu)..."
+/** Expected max size of the remainder string.
+ * String + terminator + number width (enough for 4GB).*/
+#define REMAINDER_STR_LEN (5 + 1 + 10)
+
+/** Groups size. */
+#define BUFFER_DUMP_GROUP_SIZE 4
+
+/** Space between two items. */
+#define SPACE_NORMAL " "
+/** Space between two groups. */
+#define SPACE_GROUP "  "
+
+/** Dump one item into given buffer.
+ *
+ * @param buffer Data buffer.
+ * @param item_size Size of the item (1, 2, 4).
+ * @param index Index into the @p buffer (respecting @p item_size).
+ * @param dump Where to store the dump.
+ * @param dump_size Size of @p dump size.
+ * @return Number of characters printed (see snprintf).
+ */
+static int dump_one_item(const void *buffer, size_t item_size, size_t index,
+    char *dump, size_t dump_size)
+{
+	/* Determine space before the number. */
+	const char *space_before;
+	if (index == 0) {
+		space_before = "";
+	} else if ((index % BUFFER_DUMP_GROUP_SIZE) == 0) {
+		space_before = SPACE_GROUP;
+	} else {
+		space_before = SPACE_NORMAL;
+	}
+
+	/* Let buf point to the item to be printed. */
+	const uint8_t *buf = (const uint8_t *) buffer;
+	buf += index * item_size;
+
+/* Formats the dump with space before, takes care of type casting (ugly). */
+#define _FORMAT(digits, bits) \
+	snprintf(dump, dump_size, "%s%0" #digits PRIx##bits, \
+	    space_before, ((uint##bits##_t *)buf)[0]);
+
+	switch (item_size) {
+	case 4:
+		return _FORMAT(8, 32);
+	case 2:
+		return _FORMAT(4, 16);
+	default:
+		return _FORMAT(2, 8);
+	}
+#undef _FORMAT
+}
+
+/** Count number of characters needed for dumping buffer of given size.
+ *
+ * @param item_size Item size in bytes.
+ * @param items Number of items to print.
+ * @return Number of characters the full dump would occupy.
+ */
+static size_t count_dump_length(size_t item_size, size_t items)
+{
+	size_t group_space_count = items / BUFFER_DUMP_GROUP_SIZE - 1;
+	size_t normal_space_count = items - 1 - group_space_count;
+
+	size_t dump_itself = item_size * 2 * items;
+	size_t group_spaces = str_size(SPACE_GROUP) * group_space_count;
+	size_t normal_spaces = str_size(SPACE_NORMAL) * normal_space_count;
+
+	return dump_itself + group_spaces + normal_spaces;
+}
+
+
+/** Dumps data buffer to a string in hexadecimal format.
+ *
+ * Setting @p items_to_print to zero would dump the whole buffer together
+ * with information how many items were omitted. Otherwise, no information
+ * about omitted items is printed.
+ *
+ * @param dump Where to store the dumped buffer.
+ * @param dump_size Size of @p dump in bytes.
+ * @param buffer Data buffer to be dumped.
+ * @param item_size Size of items in the @p buffer in bytes (1,2,4 allowed).
+ * @param items Number of items in the @p buffer.
+ * @param items_to_print How many items to actually print.
+ */
+void ddf_dump_buffer(char *dump, size_t dump_size,
+    const void *buffer, size_t item_size, size_t items, size_t items_to_print)
+{
+	if ((dump_size == 0) || (dump == NULL)) {
+		return;
+	}
+	/* We need space for one byte at least. */
+	if (dump_size < 3) {
+		str_cpy(dump, dump_size, "...");
+		return;
+	}
+
+	/* Special cases first. */
+	if (buffer == NULL) {
+		str_cpy(dump, dump_size, "(null)");
+		return;
+	}
+	if (items == 0) {
+		str_cpy(dump, dump_size, "(empty)");
+	}
+
+	if (items_to_print > items) {
+		items_to_print = items;
+	}
+
+	bool print_remainder = items_to_print == 0;
+
+	/* How many available bytes we do have. */
+	size_t dump_size_remaining = dump_size - 1;
+
+	if (print_remainder) {
+		/* Can't do much when user supplied small buffer. */
+		if (dump_size_remaining < REMAINDER_STR_LEN) {
+			print_remainder = false;
+		} else {
+			size_t needed_size = count_dump_length(item_size, items);
+			if (needed_size > dump_size_remaining) {
+				dump_size_remaining -= REMAINDER_STR_LEN;
+			} else {
+				print_remainder = false;
+			}
+		}
+		items_to_print = items;
+	}
+
+	str_cpy(dump, dump_size, "");
+
+	size_t index = 0;
+	while (index < items) {
+		char current_item[32];
+		int printed = dump_one_item(buffer, item_size, index,
+		    current_item, 32);
+		assert(printed >= 0);
+
+		if ((size_t) printed > dump_size_remaining) {
+			break;
+		}
+
+		str_append(dump, dump_size, current_item);
+
+		dump_size_remaining -= printed;
+		index++;
+
+		if (index >= items_to_print) {
+			break;
+		}
+	}
+
+	if (print_remainder && (index < items)) {
+		size_t s = str_size(dump);
+		snprintf(dump + s, dump_size - s ,REMAINDER_STR_FMT,
+		    items - index);
+	}
+}
+
+/** @}
+ */
Index: uspace/lib/drv/include/ddf/interrupt.h
===================================================================
--- uspace/lib/drv/include/ddf/interrupt.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/drv/include/ddf/interrupt.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -60,5 +60,5 @@
 typedef struct interrupt_context_list {
 	int curr_id;
-	link_t contexts;
+	list_t contexts;
 	fibril_mutex_t mutex;
 } interrupt_context_list_t;
Index: uspace/lib/drv/include/ddf/log.h
===================================================================
--- uspace/lib/drv/include/ddf/log.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/drv/include/ddf/log.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -39,4 +39,7 @@
 extern void ddf_msg(log_level_t, const char *, ...);
 
+extern void ddf_dump_buffer(char *, size_t, const void *, size_t, size_t,
+    size_t);
+
 #endif
 
Index: uspace/lib/fs/libfs.c
===================================================================
--- uspace/lib/fs/libfs.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/fs/libfs.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -106,5 +106,5 @@
 	 * Ask VFS for callback connection.
 	 */
-	async_connect_to_me(exch, 0, 0, 0, conn);
+	async_connect_to_me(exch, 0, 0, 0, conn, NULL);
 	
 	/*
Index: uspace/lib/net/il/il_skel.c
===================================================================
--- uspace/lib/net/il/il_skel.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/net/il/il_skel.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -51,5 +51,6 @@
  *
  */
-static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg)
 {
 	/*
@@ -117,5 +118,5 @@
 		goto out;
 	
-	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL);
+	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL, NULL);
 	if (rc != EOK)
 		goto out;
Index: uspace/lib/net/netif/netif_skel.c
===================================================================
--- uspace/lib/net/netif/netif_skel.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/net/netif/netif_skel.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -365,5 +365,6 @@
  *
  */
-static void netif_client_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void netif_client_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg)
 {
 	/*
Index: uspace/lib/net/nil/nil_skel.c
===================================================================
--- uspace/lib/net/nil/nil_skel.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/net/nil/nil_skel.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -51,5 +51,6 @@
  *
  */
-static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg)
 {
 	/*
@@ -117,5 +118,5 @@
 		goto out;
 	
-	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL);
+	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL, NULL);
 	if (rc != EOK)
 		goto out;
Index: uspace/lib/net/tl/tl_skel.c
===================================================================
--- uspace/lib/net/tl/tl_skel.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/net/tl/tl_skel.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -47,9 +47,11 @@
 /** Default thread for new connections.
  *
- * @param[in] iid   The initial message identifier.
- * @param[in] icall The initial message call structure.
+ * @param[in] iid  	The initial message identifier.
+ * @param[in] icall	The initial message call structure.
+ * @param[in] arg	Local argument.
  *
  */
-static void tl_client_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void tl_client_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg)
 {
 	/*
@@ -119,5 +121,5 @@
 		goto out;
 	
-	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL);
+	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL, NULL);
 	if (rc != EOK)
 		goto out;
Index: uspace/lib/usb/include/usb/usb.h
===================================================================
--- uspace/lib/usb/include/usb/usb.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/usb/include/usb/usb.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -69,4 +69,6 @@
 	USB_DIRECTION_BOTH
 } usb_direction_t;
+
+const char *usb_str_direction(usb_direction_t);
 
 /** USB speeds. */
Index: uspace/lib/usb/src/debug.c
===================================================================
--- uspace/lib/usb/src/debug.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/usb/src/debug.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -38,4 +38,5 @@
 #include <stdlib.h>
 #include <stdio.h>
+#include <ddf/log.h>
 #include <usb/debug.h>
 
@@ -67,4 +68,7 @@
 		if (rc > 0) {
 			log_stream = fopen(fname, "w");
+			if (log_stream != NULL)
+				setvbuf(log_stream, NULL, _IOFBF, BUFSIZ);
+			
 			free(fname);
 		}
@@ -193,66 +197,7 @@
 	bzero(buffer_dump[buffer_dump_index], BUFFER_DUMP_LEN);
 
-	if (buffer == NULL) {
-		return "(null)";
-	}
-	if (size == 0) {
-		return "(empty)";
-	}
-	if ((dumped_size == 0) || (dumped_size > size)) {
-		dumped_size = size;
-	}
-
-	/* How many bytes are available in the output buffer. */
-	size_t buffer_remaining_size = BUFFER_DUMP_LEN - 1 - REMAINDER_STR_LEN;
-	char *it = buffer_dump[buffer_dump_index];
-
-	size_t index = 0;
-
-	while (index < size) {
-		/* Determine space before the number. */
-		const char *space_before;
-		if (index == 0) {
-			space_before = "";
-		} else if ((index % BUFFER_DUMP_GROUP_SIZE) == 0) {
-			space_before = "  ";
-		} else {
-			space_before = " ";
-		}
-
-		/*
-		 * Add the byte as a hexadecimal number plus the space.
-		 * We do it into temporary buffer to ensure that always
-		 * the whole byte is printed.
-		 */
-		int val = buffer[index];
-		char current_byte[16];
-		int printed = snprintf(current_byte, 16,
-		    "%s%02x", space_before, val);
-		if (printed < 0) {
-			break;
-		}
-
-		if ((size_t) printed > buffer_remaining_size) {
-			break;
-		}
-
-		/* We can safely add 1, because space for end 0 is reserved. */
-		str_append(it, buffer_remaining_size + 1, current_byte);
-
-		buffer_remaining_size -= printed;
-		/* Point at the terminator 0. */
-		it += printed;
-		index++;
-
-		if (index >= dumped_size) {
-			break;
-		}
-	}
-
-	/* Add how many bytes were not printed. */
-	if (index < size) {
-		snprintf(it, REMAINDER_STR_LEN,
-		    REMAINDER_STR_FMT, size - index);
-	}
+	/* Do the actual dump. */
+	ddf_dump_buffer(buffer_dump[buffer_dump_index], BUFFER_DUMP_LEN,
+	    buffer, 1, size, dumped_size);
 
 	/* Next time, use the other buffer. */
Index: uspace/lib/usb/src/hc.c
===================================================================
--- uspace/lib/usb/src/hc.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/usb/src/hc.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -98,5 +98,5 @@
 		return EBUSY;
 	
-	async_sess_t *sess = devman_device_connect(EXCHANGE_SERIALIZE,
+	async_sess_t *sess = devman_device_connect(EXCHANGE_ATOMIC,
 	    connection->hc_handle, 0);
 	if (!sess)
@@ -177,5 +177,5 @@
 {
 	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev_handle,
+	    devman_parent_device_connect(EXCHANGE_ATOMIC, dev_handle,
 	    IPC_FLAG_BLOCKING);
 	if (!parent_sess)
@@ -241,5 +241,5 @@
 {
 	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device_handle,
+	    devman_parent_device_connect(EXCHANGE_ATOMIC, device_handle,
 	    IPC_FLAG_BLOCKING);
 	if (!parent_sess)
Index: uspace/lib/usb/src/usb.c
===================================================================
--- uspace/lib/usb/src/usb.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/usb/src/usb.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -58,4 +58,10 @@
 };
 
+static const char *str_direction[] = {
+	"in",
+	"out",
+	"both"
+};
+
 /** String representation for USB transfer type.
  *
@@ -84,4 +90,17 @@
 }
 
+/** String representation of USB direction.
+ *
+ * @param d The direction.
+ * @return Direction as a string (in English).
+ */
+const char *usb_str_direction(usb_direction_t d)
+{
+	if (d >= ARR_SIZE(str_direction)) {
+		return "invalid";
+	}
+	return str_direction[d];
+}
+
 /** String representation of USB speed.
  *
Index: uspace/lib/usbdev/src/pipes.c
===================================================================
--- uspace/lib/usbdev/src/pipes.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/usbdev/src/pipes.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -81,5 +81,5 @@
 {
 	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
+	    devman_parent_device_connect(EXCHANGE_ATOMIC, device->handle,
 	    IPC_FLAG_BLOCKING);
 	if (!parent_sess)
@@ -122,5 +122,5 @@
 	
 	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
+	    devman_parent_device_connect(EXCHANGE_ATOMIC, dev->handle,
 	    IPC_FLAG_BLOCKING);
 	if (!parent_sess)
Index: uspace/lib/usbhid/include/usb/hid/hiddescriptor.h
===================================================================
--- uspace/lib/usbhid/include/usb/hid/hiddescriptor.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/usbhid/include/usb/hid/hiddescriptor.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -74,9 +74,9 @@
 		usb_hid_report_path_t *usage_path);
 
-void usb_hid_descriptor_print_list(link_t *head);
+void usb_hid_descriptor_print_list(list_t *list);
 
 void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item);
 
-void usb_hid_free_report_list(link_t *head);
+void usb_hid_free_report_list(list_t *list);
 
 usb_hid_report_item_t *usb_hid_report_item_clone(
Index: uspace/lib/usbhid/include/usb/hid/hidpath.h
===================================================================
--- uspace/lib/usbhid/include/usb/hid/hidpath.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/usbhid/include/usb/hid/hidpath.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -88,6 +88,6 @@
 	uint8_t flags;
 
-	/** Linked list structure*/
-	link_t link;
+	/** Link to usb_hid_report_path_t.items list */
+	link_t rpath_items_link;
 } usb_hid_report_usage_path_t;
 
@@ -98,17 +98,16 @@
  * */
 typedef struct {
-	/** Length of usage path */	
-	int depth;	
+	/** Length of usage path */
+	int depth;
 
 	/** Report id. Zero is reserved and means that report id is not used.
 	 * */
 	uint8_t report_id;
-	
-	/** Linked list structure. */	
-	link_t link; /* list */
 
-	/** Head of the list of usage path items. */
-	link_t head;
+	/** Link to usb_hid_report_path_t.collection_paths list. */
+	link_t cpath_link;
 
+	/** List of usage path items. */
+	list_t items;	/* of usb_hid_report_usage_path_t */
 } usb_hid_report_path_t;
 
Index: uspace/lib/usbhid/include/usb/hid/hidtypes.h
===================================================================
--- uspace/lib/usbhid/include/usb/hid/hidtypes.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/usbhid/include/usb/hid/hidtypes.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -95,9 +95,9 @@
 	int report_count;
 
-	/** Head of linked list of description of reports. */
-	link_t reports;
-
-	/** Head of linked list of all used usage/collection paths. */
-	link_t collection_paths;
+	/** List of description of reports. */
+	list_t reports; /* of usb_hid_report_description_t */
+
+	/** List of all used usage/collection paths. */
+	list_t collection_paths;
 
 	/** Length of list of usage paths. */
@@ -129,9 +129,9 @@
 	size_t item_length;
 	
-	/** Linked list of report items in report */
-	link_t report_items;
-
-	/** Linked list of descriptions. */
-	link_t link;
+	/** List of report items in report */
+	list_t report_items;
+
+	/** Link to usb_hid_report_t.reports list. */
+	link_t reports_link;
 } usb_hid_report_description_t;
 /*---------------------------------------------------------------------------*/
@@ -198,6 +198,6 @@
 	int32_t value;
 
-	/** List to another report items */
-	link_t link;
+	/** Link to usb_hid_report_description_t.report_items list */
+	link_t ritems_link;
 } usb_hid_report_field_t;
 
Index: uspace/lib/usbhid/src/hiddescriptor.c
===================================================================
--- uspace/lib/usbhid/src/hiddescriptor.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/usbhid/src/hiddescriptor.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -88,8 +88,8 @@
  * @retval NULL If some error occurs
  */
-usb_hid_report_path_t *usb_hid_report_path_try_insert(
-		usb_hid_report_t *report, usb_hid_report_path_t *cmp_path) {
-	
-	link_t *path_it = report->collection_paths.prev->next;
+usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t *report,
+    usb_hid_report_path_t *cmp_path)
+{
+	link_t *path_it = report->collection_paths.head.next;
 	usb_hid_report_path_t *path = NULL;
 	
@@ -98,20 +98,20 @@
 	}
 	
-	while(path_it != &report->collection_paths) {
+	while(path_it != &report->collection_paths.head) {
 		path = list_get_instance(path_it, usb_hid_report_path_t,
-				link);
+				cpath_link);
 		
 		if(usb_hid_report_compare_usage_path(path, cmp_path,
 					USB_HID_PATH_COMPARE_STRICT) == EOK){
 			break;
-		}			
+		}
 		path_it = path_it->next;
 	}
-	if(path_it == &report->collection_paths) {
+	if(path_it == &report->collection_paths.head) {
 		path = usb_hid_report_path_clone(cmp_path);
 		if(path == NULL) {
 			return NULL;
 		}
-		list_append(&path->link, &report->collection_paths);					
+		list_append(&path->cpath_link, &report->collection_paths);
 		report->collection_paths_count++;
 
@@ -120,5 +120,5 @@
 	else {
 		return list_get_instance(path_it, usb_hid_report_path_t,
-				link); 
+				cpath_link); 
 	}
 }
@@ -192,5 +192,5 @@
 
 		memset(field, 0, sizeof(usb_hid_report_field_t));
-		list_initialize(&field->link);
+		link_initialize(&field->ritems_link);
 
 		/* fill the attributes */		
@@ -291,13 +291,13 @@
 			}
 
-			list_initialize (&report_des->link);
+			link_initialize (&report_des->reports_link);
 			list_initialize (&report_des->report_items);
 
-			list_append(&report_des->link, &report->reports);
+			list_append(&report_des->reports_link, &report->reports);
 			report->report_count++;
 		}
 
 		/* append this field to the end of founded report list */
-		list_append (&field->link, &report_des->report_items);
+		list_append(&field->ritems_link, &report_des->report_items);
 		
 		/* update the sizes */
@@ -333,10 +333,9 @@
 	}
 
-	link_t *report_it = report->reports.next;
 	usb_hid_report_description_t *report_des = NULL;
 	
-	while(report_it != &report->reports) {
+	list_foreach(report->reports, report_it) {
 		report_des = list_get_instance(report_it,
-				usb_hid_report_description_t, link);
+				usb_hid_report_description_t, reports_link);
 
 		// if report id not set, return the first of the type
@@ -345,6 +344,4 @@
 			return report_des;
 		}
-		
-		report_it = report_it->next;
 	}
 
@@ -377,7 +374,9 @@
 	size_t offset_output=0;
 	size_t offset_feature=0;
-
-	link_t stack;
-	list_initialize(&stack);	
+	
+	link_t *item_link;
+
+	list_t stack;
+	list_initialize(&stack);
 
 	/* parser structure initialization*/
@@ -391,5 +390,5 @@
 	}
 	memset(report_item, 0, sizeof(usb_hid_report_item_t));
-	list_initialize(&(report_item->link));	
+	link_initialize(&(report_item->link));
 
 	/* usage path context initialization */
@@ -493,17 +492,18 @@
 			case USB_HID_REPORT_TAG_POP:
 				// restore current state from stack
-				if(list_empty (&stack)) {
+				item_link = list_first(&stack);
+				if (item_link == NULL) {
 					return EINVAL;
 				}
 				free(report_item);
-						
-				report_item = list_get_instance(stack.next, 
+				
+				report_item = list_get_instance(item_link,
 				    usb_hid_report_item_t, link);
-					
+				
 				usb_hid_report_usage_path_t *tmp_usage_path;
 				tmp_usage_path = list_get_instance(
-				    report_item->usage_path->link.prev, 
-				    usb_hid_report_usage_path_t, link);
-					
+				    report_item->usage_path->cpath_link.prev,
+				    usb_hid_report_usage_path_t, rpath_items_link);
+				
 				usb_hid_report_set_last_item(usage_path, 
 				    USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page);
@@ -513,6 +513,5 @@
 
 				usb_hid_report_path_free(report_item->usage_path);
-				list_initialize(&report_item->usage_path->link);
-				list_remove (stack.next);
+				list_remove (item_link);
 					
 				break;
@@ -610,7 +609,7 @@
 
 		/* store collection atributes */
-		path_item = list_get_instance(usage_path->head.prev, 
-			usb_hid_report_usage_path_t, link);
-		path_item->flags = *data;	
+		path_item = list_get_instance(list_first(&usage_path->items),
+			usb_hid_report_usage_path_t, rpath_items_link);
+		path_item->flags = *data;
 			
 		/* set last item */
@@ -901,35 +900,32 @@
  * @return void
  */
-void usb_hid_descriptor_print_list(link_t *head)
+void usb_hid_descriptor_print_list(list_t *list)
 {
 	usb_hid_report_field_t *report_item;
-	link_t *item;
-
-
-	if(head == NULL || list_empty(head)) {
+
+	if(list == NULL || list_empty(list)) {
 	    usb_log_debug("\tempty\n");
 	    return;
 	}
-        
-	for(item = head->next; item != head; item = item->next) {
-                
-		report_item = list_get_instance(item, usb_hid_report_field_t, 
-				link);
+
+        list_foreach(*list, item) {
+		report_item = list_get_instance(item, usb_hid_report_field_t,
+				ritems_link);
 
 		usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
 		usb_log_debug("\t\tSIZE: %zu\n", report_item->size);
-		usb_log_debug("\t\tLOGMIN: %d\n", 
+		usb_log_debug("\t\tLOGMIN: %d\n",
 			report_item->logical_minimum);
-		usb_log_debug("\t\tLOGMAX: %d\n", 
-			report_item->logical_maximum);		
-		usb_log_debug("\t\tPHYMIN: %d\n", 
-			report_item->physical_minimum);		
-		usb_log_debug("\t\tPHYMAX: %d\n", 
-			report_item->physical_maximum);				
-		usb_log_debug("\t\ttUSAGEMIN: %X\n", 
+		usb_log_debug("\t\tLOGMAX: %d\n",
+			report_item->logical_maximum);
+		usb_log_debug("\t\tPHYMIN: %d\n",
+			report_item->physical_minimum);
+		usb_log_debug("\t\tPHYMAX: %d\n",
+			report_item->physical_maximum);
+		usb_log_debug("\t\ttUSAGEMIN: %X\n",
 			report_item->usage_minimum);
 		usb_log_debug("\t\tUSAGEMAX: %X\n",
 			       report_item->usage_maximum);
-		usb_log_debug("\t\tUSAGES COUNT: %zu\n", 
+		usb_log_debug("\t\tUSAGES COUNT: %zu\n",
 			report_item->usages_count);
 
@@ -937,8 +933,8 @@
 		usb_log_debug("\t\ttUSAGE: %X\n", report_item->usage);
 		usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page);
-		
+
 		usb_hid_print_usage_path(report_item->collection_path);
 
-		usb_log_debug("\n");		
+		usb_log_debug("\n");
 
 	}
@@ -959,22 +955,19 @@
 	}
 
-	link_t *report_it = report->reports.next;
 	usb_hid_report_description_t *report_des;
 
-	while(report_it != &report->reports) {
-		report_des = list_get_instance(report_it, 
-			usb_hid_report_description_t, link);
+	list_foreach(report->reports, report_it) {
+		report_des = list_get_instance(report_it,
+			usb_hid_report_description_t, reports_link);
 		usb_log_debug("Report ID: %d\n", report_des->report_id);
 		usb_log_debug("\tType: %d\n", report_des->type);
-		usb_log_debug("\tLength: %zu\n", report_des->bit_length);		
+		usb_log_debug("\tLength: %zu\n", report_des->bit_length);
 		usb_log_debug("\tB Size: %zu\n",
-			usb_hid_report_byte_size(report, 
-				report_des->report_id, 
+			usb_hid_report_byte_size(report,
+				report_des->report_id,
 				report_des->type));
-		usb_log_debug("\tItems: %zu\n", report_des->item_length);		
+		usb_log_debug("\tItems: %zu\n", report_des->item_length);
 
 		usb_hid_descriptor_print_list(&report_des->report_items);
-
-		report_it = report_it->next;
 	}
 }
@@ -984,25 +977,25 @@
  * Releases whole linked list of report items
  *
- * @param head Head of list of report descriptor items (usb_hid_report_item_t)
+ * @param list List of report descriptor items (usb_hid_report_item_t)
  * @return void
  */
-void usb_hid_free_report_list(link_t *head)
+void usb_hid_free_report_list(list_t *list)
 {
-	return; 
-	
-	usb_hid_report_item_t *report_item;
+	return; /* XXX What's this? */
+	
+/*	usb_hid_report_item_t *report_item;
 	link_t *next;
 	
-	if(head == NULL || list_empty(head)) {		
+	if(list == NULL || list_empty(list)) {
 	    return;
 	}
 	
-	next = head->next;
-	while(next != head) {
-	
-	    report_item = list_get_instance(next, usb_hid_report_item_t, link);
+	next = list->head.next;
+	while (next != &list->head) {
+		report_item = list_get_instance(next, usb_hid_report_item_t,
+		    rpath_items_link);
 
 		while(!list_empty(&report_item->usage_path->link)) {
-		    usb_hid_report_remove_last_item(report_item->usage_path);
+			usb_hid_report_remove_last_item(report_item->usage_path);
 		}
 
@@ -1014,5 +1007,5 @@
 	
 	return;
-	
+	*/
 }
 /*---------------------------------------------------------------------------*/
@@ -1030,10 +1023,13 @@
 
 	// free collection paths
+	link_t *path_link;
 	usb_hid_report_path_t *path;
 	while(!list_empty(&report->collection_paths)) {
-		path = list_get_instance(report->collection_paths.next, 
-				usb_hid_report_path_t, link);
-
-		usb_hid_report_path_free(path);		
+		path_link = list_first(&report->collection_paths);
+		path = list_get_instance(path_link,
+		    usb_hid_report_path_t, cpath_link);
+
+		list_remove(path_link);
+		usb_hid_report_path_free(path);
 	}
 	
@@ -1042,15 +1038,15 @@
 	usb_hid_report_field_t *field;
 	while(!list_empty(&report->reports)) {
-		report_des = list_get_instance(report->reports.next, 
-				usb_hid_report_description_t, link);
-
-		list_remove(&report_des->link);
+		report_des = list_get_instance(list_first(&report->reports),
+				usb_hid_report_description_t, reports_link);
+
+		list_remove(&report_des->reports_link);
 		
 		while(!list_empty(&report_des->report_items)) {
 			field = list_get_instance(
-				report_des->report_items.next, 
-				usb_hid_report_field_t, link);
-
-			list_remove(&field->link);
+			    list_first(&report_des->report_items),
+			    usb_hid_report_field_t, ritems_link);
+
+			list_remove(&field->ritems_link);
 
 			free(field);
Index: uspace/lib/usbhid/src/hidparser.c
===================================================================
--- uspace/lib/usbhid/src/hidparser.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/usbhid/src/hidparser.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -135,5 +135,4 @@
 	size_t size, uint8_t *report_id)
 {
-	link_t *list_item;
 	usb_hid_report_field_t *item;
 
@@ -161,9 +160,7 @@
 
 	/* read data */
-	list_item = report_des->report_items.next;	   
-	while(list_item != &(report_des->report_items)) {
-
+	list_foreach(report_des->report_items, list_item) {
 		item = list_get_instance(list_item, usb_hid_report_field_t, 
-				link);
+				ritems_link);
 
 		if(USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) == 0) {
@@ -200,5 +197,4 @@
 			}			
 		}
-		list_item = list_item->next;
 	}
 	
@@ -310,16 +306,14 @@
 	}
 
-	link_t *report_it = report->reports.next;
 	usb_hid_report_description_t *report_des = NULL;
-	while(report_it != &report->reports) {
-		report_des = list_get_instance(report_it, 
-			usb_hid_report_description_t, link);
+
+	list_foreach(report->reports, report_it) {
+		report_des = list_get_instance(report_it,
+			usb_hid_report_description_t, reports_link);
 		
-		if((report_des->report_id == report_id) && 
+		if((report_des->report_id == report_id) &&
 			(report_des->type == USB_HID_REPORT_TYPE_OUTPUT)){
 			break;
 		}
-
-		report_it = report_it->next;
 	}
 
@@ -362,5 +356,4 @@
 	uint8_t report_id, uint8_t *buffer, size_t size)
 {
-	link_t *item;	
 	int32_t value=0;
 	int offset;
@@ -384,8 +377,9 @@
 	}
 
-	usb_hid_report_field_t *report_item;	
-	item = report_des->report_items.next;	
-	while(item != &report_des->report_items) {
-		report_item = list_get_instance(item, usb_hid_report_field_t, link);
+	usb_hid_report_field_t *report_item;
+
+	list_foreach(report_des->report_items, item) {
+		report_item = list_get_instance(item, usb_hid_report_field_t,
+		    ritems_link);
 
 		value = usb_hid_translate_data_reverse(report_item, 
@@ -449,6 +443,4 @@
 		// reset value
 		report_item->value = 0;
-		
-		item = item->next;
 	}
 	
@@ -550,13 +542,13 @@
 
 	if(field == NULL){
-		field_it = report_des->report_items.next;
-	}
-	else {
-		field_it = field->link.next;
-	}
-
-	while(field_it != &report_des->report_items) {
+		field_it = report_des->report_items.head.next;
+	}
+	else {
+		field_it = field->ritems_link.next;
+	}
+
+	while(field_it != &report_des->report_items.head) {
 		field = list_get_instance(field_it, usb_hid_report_field_t, 
-			link);
+			ritems_link);
 
 		if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {
@@ -611,14 +603,14 @@
 		}
 		else {
-			report_it = report_des->link.next;
+			report_it = report_des->reports_link.next;
 		}	
 	}
 	else {
-		report_it = report->reports.next;
-	}
-
-	while(report_it != &report->reports) {
+		report_it = report->reports.head.next;
+	}
+
+	while(report_it != &report->reports.head) {
 		report_des = list_get_instance(report_it, 
-			usb_hid_report_description_t, link);
+			usb_hid_report_description_t, reports_link);
 
 		if(report_des->type == type){
Index: uspace/lib/usbhid/src/hidpath.c
===================================================================
--- uspace/lib/usbhid/src/hidpath.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/usbhid/src/hidpath.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -81,5 +81,5 @@
 		return ENOMEM;
 	}
-	list_initialize(&item->link);
+	link_initialize(&item->rpath_items_link);
 
 	item->usage = usage;
@@ -87,5 +87,5 @@
 	item->flags = 0;
 	
-	list_append (&item->link, &usage_path->head);
+	list_append (&item->rpath_items_link, &usage_path->items);
 	usage_path->depth++;
 	return EOK;
@@ -100,10 +100,12 @@
 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path)
 {
+	link_t *item_link;
 	usb_hid_report_usage_path_t *item;
 	
-	if(!list_empty(&usage_path->head)){
-		item = list_get_instance(usage_path->head.prev, 
-		                         usb_hid_report_usage_path_t, link);		
-		list_remove(usage_path->head.prev);
+	if(!list_empty(&usage_path->items)){
+		item_link = list_last(&usage_path->items);
+		item = list_get_instance(item_link,
+		    usb_hid_report_usage_path_t, rpath_items_link);
+		list_remove(item_link);
 		usage_path->depth--;
 		free(item);
@@ -122,7 +124,7 @@
 	usb_hid_report_usage_path_t *item;
 	
-	if(!list_empty(&usage_path->head)){	
-		item = list_get_instance(usage_path->head.prev, 
-			usb_hid_report_usage_path_t, link);
+	if(!list_empty(&usage_path->items)){
+		item = list_get_instance(list_last(&usage_path->items),
+			usb_hid_report_usage_path_t, rpath_items_link);
 
 		memset(item, 0, sizeof(usb_hid_report_usage_path_t));
@@ -145,7 +147,7 @@
 	usb_hid_report_usage_path_t *item;
 	
-	if(!list_empty(&usage_path->head)){	
-		item = list_get_instance(usage_path->head.prev, 
-		                         usb_hid_report_usage_path_t, link);
+	if(!list_empty(&usage_path->items)){
+		item = list_get_instance(list_last(&usage_path->items),
+		     usb_hid_report_usage_path_t, rpath_items_link);
 
 		switch(tag) {
@@ -173,16 +175,13 @@
 	usb_log_debug("\tLENGTH: %d\n", path->depth);
 
-	link_t *item = path->head.next;
 	usb_hid_report_usage_path_t *path_item;
-	while(item != &path->head) {
-
-		path_item = list_get_instance(item, usb_hid_report_usage_path_t, 
-			link);
+
+	list_foreach(path->items, item) {
+		path_item = list_get_instance(item, usb_hid_report_usage_path_t,
+			rpath_items_link);
 
 		usb_log_debug("\tUSAGE_PAGE: %X\n", path_item->usage_page);
 		usb_log_debug("\tUSAGE: %X\n", path_item->usage);
-		usb_log_debug("\tFLAGS: %d\n", path_item->flags);		
-		
-       	item = item->next;
+		usb_log_debug("\tFLAGS: %d\n", path_item->flags);
 	}
 }
@@ -233,14 +232,13 @@
 		}
 
-		report_link = report_path->head.next;
-		path_link = path->head.next;
-		path_item = list_get_instance(path_link, 
-			usb_hid_report_usage_path_t, link);
-
-		while(report_link != &report_path->head) {
-			report_item = list_get_instance(report_link, 
-				usb_hid_report_usage_path_t, link);
+		path_link = list_first(&path->items);
+		path_item = list_get_instance(path_link,
+			usb_hid_report_usage_path_t, rpath_items_link);
+
+		list_foreach(report_path->items, report_link) {
+			report_item = list_get_instance(report_link,
+				usb_hid_report_usage_path_t, rpath_items_link);
 				
-			if(USB_HID_SAME_USAGE_PAGE(report_item->usage_page, 
+			if(USB_HID_SAME_USAGE_PAGE(report_item->usage_page,
 				path_item->usage_page)){
 					
@@ -257,6 +255,4 @@
 				}
 			}
-
-			report_link = report_link->next;
 		}
 
@@ -273,15 +269,15 @@
 	case USB_HID_PATH_COMPARE_BEGIN:
 	
-		report_link = report_path->head.next;
-		path_link = path->head.next;
+		report_link = report_path->items.head.next;
+		path_link = path->items.head.next;
 			
-		while((report_link != &report_path->head) && 
-		      (path_link != &path->head)) {
+		while((report_link != &report_path->items.head) && 
+		      (path_link != &path->items.head)) {
 					  
 			report_item = list_get_instance(report_link, 
-				usb_hid_report_usage_path_t, link);
+				usb_hid_report_usage_path_t, rpath_items_link);
 					  
 			path_item = list_get_instance(path_link,
-       				usb_hid_report_usage_path_t, link);
+       				usb_hid_report_usage_path_t, rpath_items_link);
 
 			if(!USB_HID_SAME_USAGE_PAGE(report_item->usage_page, 
@@ -297,10 +293,10 @@
 			}
 			
-				}
+		}
 
 		if((((flags & USB_HID_PATH_COMPARE_BEGIN) != 0) && 
-			(path_link == &path->head)) || 
-		   ((report_link == &report_path->head) && 
-			(path_link == &path->head))) {
+			(path_link == &path->items.head)) || 
+		   ((report_link == &report_path->items.head) && 
+			(path_link == &path->items.head))) {
 				
 			return EOK;
@@ -314,19 +310,19 @@
 	case USB_HID_PATH_COMPARE_END:
 
-		report_link = report_path->head.prev;
-		path_link = path->head.prev;
-
-		if(list_empty(&path->head)){
+		report_link = report_path->items.head.prev;
+		path_link = path->items.head.prev;
+
+		if(list_empty(&path->items)){
 			return EOK;
 		}
 			
-		while((report_link != &report_path->head) && 
-		      (path_link != &path->head)) {
+		while((report_link != &report_path->items.head) && 
+		      (path_link != &path->items.head)) {
 						  
-			report_item = list_get_instance(report_link, 
-				usb_hid_report_usage_path_t, link);
+			report_item = list_get_instance(report_link,
+				usb_hid_report_usage_path_t, rpath_items_link);
 
 			path_item = list_get_instance(path_link, 
-				usb_hid_report_usage_path_t, link);		
+				usb_hid_report_usage_path_t, rpath_items_link);
 						  
 			if(!USB_HID_SAME_USAGE_PAGE(report_item->usage_page, 
@@ -343,5 +339,5 @@
 		}
 
-		if(path_link == &path->head) {
+		if(path_link == &path->items.head) {
 			return EOK;
 		}
@@ -373,6 +369,6 @@
 		path->depth = 0;
 		path->report_id = 0;
-		list_initialize(&path->link);
-		list_initialize(&path->head);
+		link_initialize(&path->cpath_link);
+		list_initialize(&path->items);
 		return path;
 	}
@@ -388,9 +384,9 @@
 void usb_hid_report_path_free(usb_hid_report_path_t *path)
 {
-	while(!list_empty(&path->head)){
+	while(!list_empty(&path->items)){
 		usb_hid_report_remove_last_item(path);
 	}
 
-	list_remove(&path->link);
+	assert_link_not_used(&path->cpath_link);
 	free(path);
 }
@@ -406,5 +402,4 @@
 	usb_hid_report_path_t *usage_path)
 {
-	link_t *path_link;
 	usb_hid_report_usage_path_t *path_item;
 	usb_hid_report_usage_path_t *new_path_item;
@@ -417,12 +412,11 @@
 	new_usage_path->report_id = usage_path->report_id;
 	
-	if(list_empty(&usage_path->head)){
+	if(list_empty(&usage_path->items)){
 		return new_usage_path;
 	}
 
-	path_link = usage_path->head.next;
-	while(path_link != &usage_path->head) {
-		path_item = list_get_instance(path_link, 
-			usb_hid_report_usage_path_t, link);
+	list_foreach(usage_path->items, path_link) {
+		path_item = list_get_instance(path_link,
+			usb_hid_report_usage_path_t, rpath_items_link);
 
 		new_path_item = malloc(sizeof(usb_hid_report_usage_path_t));
@@ -431,13 +425,12 @@
 		}
 		
-		list_initialize (&new_path_item->link);		
+		link_initialize(&new_path_item->rpath_items_link);
 		new_path_item->usage_page = path_item->usage_page;
 		new_path_item->usage = path_item->usage;		
 		new_path_item->flags = path_item->flags;		
 		
-		list_append(&new_path_item->link, &new_usage_path->head);
+		list_append(&new_path_item->rpath_items_link,
+		    &new_usage_path->items);
 		new_usage_path->depth++;
-
-		path_link = path_link->next;
 	}
 
Index: uspace/lib/usbhid/src/hidreq.c
===================================================================
--- uspace/lib/usbhid/src/hidreq.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/usbhid/src/hidreq.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -82,5 +82,5 @@
 	value |= (type << 8);
 
-	usb_log_debug("Sending Set_Report request to the device.\n");
+	usb_log_debug("Sending Set Report request to the device.\n");
 	
 	rc = usb_control_request_set(ctrl_pipe, 
@@ -89,6 +89,6 @@
 
 	if (rc != EOK) {
-		usb_log_warning("Error sending output report to the keyboard: "
-		    "%s.\n", str_error(rc));
+		usb_log_warning("Error sending Set Report request to the "
+		    "device: %s.\n", str_error(rc));
 		return rc;
 	}
@@ -129,5 +129,5 @@
 	int rc;
 
-	usb_log_debug("Sending Set_Protocol request to the device ("
+	usb_log_debug("Sending Set Protocol request to the device ("
 	    "protocol: %d, iface: %d).\n", protocol, iface_no);
 	
@@ -137,6 +137,6 @@
 
 	if (rc != EOK) {
-		usb_log_warning("Error sending output report to the keyboard: "
-		    "%s.\n", str_error(rc));
+		usb_log_warning("Error sending Set Protocol request to the "
+		    "device: %s.\n", str_error(rc));
 		return rc;
 	}
@@ -177,5 +177,5 @@
 	int rc;
 
-	usb_log_debug("Sending Set_Idle request to the device ("
+	usb_log_debug("Sending Set Idle request to the device ("
 	    "duration: %u, iface: %d).\n", duration, iface_no);
 	
@@ -187,5 +187,5 @@
 
 	if (rc != EOK) {
-		usb_log_warning("Error sending output report to the keyboard: "
+		usb_log_warning("Error sending Set Idle request to the device: "
 		    "%s.\n", str_error(rc));
 		return rc;
@@ -235,5 +235,5 @@
 	value |= (type << 8);
 	
-	usb_log_debug("Sending Get_Report request to the device.\n");
+	usb_log_debug("Sending Get Report request to the device.\n");
 	
 	rc = usb_control_request_get(ctrl_pipe, 
@@ -243,5 +243,5 @@
 
 	if (rc != EOK) {
-		usb_log_warning("Error sending output report to the keyboard: "
+		usb_log_warning("Error sending Get Report request to the device: "
 		    "%s.\n", str_error(rc));
 		return rc;
@@ -283,5 +283,5 @@
 	int rc;	
 
-	usb_log_debug("Sending Get_Protocol request to the device ("
+	usb_log_debug("Sending Get Protocol request to the device ("
 	    "iface: %d).\n", iface_no);
 	
@@ -294,6 +294,6 @@
 
 	if (rc != EOK) {
-		usb_log_warning("Error sending output report to the keyboard: "
-		    "%s.\n", str_error(rc));
+		usb_log_warning("Error sending Get Protocol request to the "
+		    "device: %s.\n", str_error(rc));
 		return rc;
 	}
@@ -344,5 +344,5 @@
 	int rc;
 
-	usb_log_debug("Sending Get_Idle request to the device ("
+	usb_log_debug("Sending Get Idle request to the device ("
 	    "iface: %d).\n", iface_no);
 	
@@ -357,5 +357,5 @@
 
 	if (rc != EOK) {
-		usb_log_warning("Error sending output report to the keyboard: "
+		usb_log_warning("Error sending Get Idle request to the device: "
 		    "%s.\n", str_error(rc));
 		return rc;
Index: uspace/lib/usbhost/include/usb/host/batch.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/batch.h	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/usbhost/include/usb/host/batch.h	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -61,4 +61,18 @@
 };
 
+/** Printf formatting string for dumping usb_transfer_batch_t. */
+#define USB_TRANSFER_BATCH_FMT "[%d:%d %s %s-%s %zuB/%zu]"
+
+/** Printf arguments for dumping usb_transfer_batch_t.
+ * @param batch USB transfer batch to be dumped.
+ */
+#define USB_TRANSFER_BATCH_ARGS(batch) \
+	(batch).ep->address, (batch).ep->endpoint, \
+	usb_str_speed((batch).ep->speed), \
+	usb_str_transfer_type_short((batch).ep->transfer_type), \
+	usb_str_direction((batch).ep->direction), \
+	(batch).buffer_size, (batch).ep->max_packet_size
+
+
 void usb_transfer_batch_init(
     usb_transfer_batch_t *instance,
Index: uspace/lib/usbhost/src/batch.c
===================================================================
--- uspace/lib/usbhost/src/batch.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/usbhost/src/batch.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -128,10 +128,7 @@
 	memcpy(instance->buffer, instance->data_buffer, instance->buffer_size);
 
-	usb_log_debug("Batch(%p) done (T%d.%d, %s %s in, %zuB): %s (%d).\n",
-	    instance, instance->ep->address, instance->ep->endpoint,
-	    usb_str_speed(instance->ep->speed),
-	    usb_str_transfer_type_short(instance->ep->transfer_type),
-	    instance->transfered_size, str_error(instance->error),
-	    instance->error);
+	usb_log_debug("Batch %p " USB_TRANSFER_BATCH_FMT " completed (%zuB): %s.\n",
+	    instance, USB_TRANSFER_BATCH_ARGS(*instance),
+	    instance->transfered_size, str_error(instance->error));
 
 	instance->callback_in(instance->fun, instance->error,
@@ -148,9 +145,7 @@
 	assert(instance->callback_out);
 
-	usb_log_debug("Batch(%p) done (T%d.%d, %s %s out): %s (%d).\n",
-	    instance, instance->ep->address, instance->ep->endpoint,
-	    usb_str_speed(instance->ep->speed),
-	    usb_str_transfer_type_short(instance->ep->transfer_type),
-	    str_error(instance->error), instance->error);
+	usb_log_debug("Batch %p " USB_TRANSFER_BATCH_FMT " completed: %s.\n",
+	    instance, USB_TRANSFER_BATCH_ARGS(*instance),
+	    str_error(instance->error));
 
 	instance->callback_out(instance->fun,
@@ -165,5 +160,6 @@
 {
 	assert(instance);
-	usb_log_debug("Batch(%p) disposing.\n", instance);
+	usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " disposing.\n",
+	    instance, USB_TRANSFER_BATCH_ARGS(*instance));
 	if (instance->private_data) {
 		assert(instance->private_data_dtor);
Index: uspace/lib/usbvirt/src/device.c
===================================================================
--- uspace/lib/usbvirt/src/device.c	(revision 72ec8ccd9c72ce673d1e624f564b852de69bcc40)
+++ uspace/lib/usbvirt/src/device.c	(revision f1fae414fd9fd1d6dafa676d0cd3e128d33393dd)
@@ -49,8 +49,9 @@
 /** Main IPC call handling from virtual host controller.
  *
- * @param iid Caller identification.
- * @param icall Initial incoming call.
+ * @param iid   Caller identification
+ * @param icall Initial incoming call
+ * @param arg   Local argument
  */
-static void callback_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void callback_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	assert(DEV != NULL);
@@ -99,5 +100,5 @@
 	
 	async_exch_t *exch = async_exchange_begin(hcd_sess);
-	rc = async_connect_to_me(exch, 0, 0, 0, callback_connection);
+	rc = async_connect_to_me(exch, 0, 0, 0, callback_connection, NULL);
 	async_exchange_end(exch);
 	
