Index: uspace/lib/c/generic/async.c
===================================================================
--- uspace/lib/c/generic/async.c	(revision 22cf42d96305c1472aead44ed289906f0f0b0f13)
+++ uspace/lib/c/generic/async.c	(revision d1e196f782180ef828064caefc47c1fa0ed2111c)
@@ -98,4 +98,5 @@
 #include <ipc/ipc.h>
 #include <async.h>
+#include "private/async.h"
 #undef LIBC_ASYNC_C_
 
@@ -112,5 +113,5 @@
 #include <mem.h>
 #include <stdlib.h>
-#include "private/async.h"
+#include <macros.h>
 
 #define CLIENT_HASH_TABLE_BUCKETS  32
@@ -138,5 +139,5 @@
 	link_t link;
 	
-	sysarg_t in_task_hash;
+	task_id_t in_task_id;
 	atomic_t refcnt;
 	void *data;
@@ -150,6 +151,6 @@
 	link_t link;
 	
-	/** Incoming client task hash. */
-	sysarg_t in_task_hash;
+	/** Incoming client task ID. */
+	task_id_t in_task_id;
 	
 	/** Incoming phone hash. */
@@ -283,8 +284,10 @@
 {
 	assert(key);
+	assert(keys == 2);
 	assert(item);
 	
 	client_t *client = hash_table_get_instance(item, client_t, link);
-	return (key[0] == client->in_task_hash);
+	return (key[0] == LOWER32(client->in_task_id) &&
+	    (key[1] == UPPER32(client->in_task_id)));
 }
 
@@ -574,11 +577,14 @@
 }
 
-static client_t *async_client_get(sysarg_t client_hash, bool create)
-{
-	unsigned long key = client_hash;
+static client_t *async_client_get(task_id_t client_id, bool create)
+{
+	unsigned long key[2] = {
+		LOWER32(client_id),
+		UPPER32(client_id),
+	};
 	client_t *client = NULL;
 
 	futex_down(&async_futex);
-	link_t *lnk = hash_table_find(&client_hash_table, &key);
+	link_t *lnk = hash_table_find(&client_hash_table, key);
 	if (lnk) {
 		client = hash_table_get_instance(lnk, client_t, link);
@@ -587,9 +593,9 @@
 		client = malloc(sizeof(client_t));
 		if (client) {
-			client->in_task_hash = client_hash;
+			client->in_task_id = client_id;
 			client->data = async_client_data_create();
 		
 			atomic_set(&client->refcnt, 1);
-			hash_table_insert(&client_hash_table, &key, &client->link);
+			hash_table_insert(&client_hash_table, key, &client->link);
 		}
 	}
@@ -602,10 +608,13 @@
 {
 	bool destroy;
-	unsigned long key = client->in_task_hash;
+	unsigned long key[2] = {
+		LOWER32(client->in_task_id),
+		UPPER32(client->in_task_id)
+	};
 	
 	futex_down(&async_futex);
 	
 	if (atomic_predec(&client->refcnt) == 0) {
-		hash_table_remove(&client_hash_table, &key, 1);
+		hash_table_remove(&client_hash_table, key, 2);
 		destroy = true;
 	} else
@@ -628,7 +637,7 @@
 }
 
-void *async_get_client_data_by_hash(sysarg_t client_hash)
-{
-	client_t *client = async_client_get(client_hash, false);
+void *async_get_client_data_by_id(task_id_t client_id)
+{
+	client_t *client = async_client_get(client_id, false);
 	if (!client)
 		return NULL;
@@ -641,7 +650,7 @@
 }
 
-void async_put_client_data_by_hash(sysarg_t client_hash)
-{
-	client_t *client = async_client_get(client_hash, false);
+void async_put_client_data_by_id(task_id_t client_id)
+{
+	client_t *client = async_client_get(client_id, false);
 
 	assert(client);
@@ -680,5 +689,5 @@
 	 */
 
-	client_t *client = async_client_get(fibril_connection->in_task_hash, true);
+	client_t *client = async_client_get(fibril_connection->in_task_id, true);
 	if (!client) {
 		ipc_answer_0(fibril_connection->callid, ENOMEM);
@@ -737,5 +746,5 @@
  * particular fibrils.
  *
- * @param in_task_hash  Identification of the incoming connection.
+ * @param in_task_id    Identification of the incoming connection.
  * @param in_phone_hash Identification of the incoming connection.
  * @param callid        Hash of the opening IPC_M_CONNECT_ME_TO call.
@@ -751,5 +760,5 @@
  *
  */
-fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash,
+fid_t async_new_connection(task_id_t in_task_id, sysarg_t in_phone_hash,
     ipc_callid_t callid, ipc_call_t *call,
     async_client_conn_t cfibril, void *carg)
@@ -763,5 +772,5 @@
 	}
 	
-	conn->in_task_hash = in_task_hash;
+	conn->in_task_id = in_task_id;
 	conn->in_phone_hash = in_phone_hash;
 	list_initialize(&conn->msg_queue);
@@ -822,5 +831,5 @@
 	case IPC_M_CONNECT_ME_TO:
 		/* Open new connection with fibril, etc. */
-		async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call),
+		async_new_connection(call->in_task_id, IPC_GET_ARG5(*call),
 		    callid, call, client_connection, NULL);
 		return;
@@ -970,5 +979,5 @@
 {
 	if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS,
-	    1, &client_hash_table_ops))
+	    2, &client_hash_table_ops))
 		abort();
 	
@@ -986,4 +995,7 @@
 	session_ns->arg2 = 0;
 	session_ns->arg3 = 0;
+	
+	fibril_mutex_initialize(&session_ns->remote_state_mtx);
+	session_ns->remote_state_data = NULL;
 	
 	list_initialize(&session_ns->exch_list);
@@ -1463,13 +1475,19 @@
 		return ENOENT;
 	
-	sysarg_t task_hash;
 	sysarg_t phone_hash;
-	int rc = async_req_3_5(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
-	    NULL, NULL, NULL, &task_hash, &phone_hash);
+	sysarg_t rc;
+
+	aid_t req;
+	ipc_call_t answer;
+	req = async_send_3(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
+	    &answer);
+	async_wait_for(req, &rc);
 	if (rc != EOK)
-		return rc;
-	
+		return (int) rc;
+
+	phone_hash = IPC_GET_ARG5(answer);
+
 	if (client_receiver != NULL)
-		async_new_connection(task_hash, phone_hash, 0, NULL,
+		async_new_connection(answer.in_task_id, phone_hash, 0, NULL,
 		    client_receiver, carg);
 	
@@ -1546,4 +1564,7 @@
 	sess->arg3 = 0;
 	
+	fibril_mutex_initialize(&sess->remote_state_mtx);
+	sess->remote_state_data = NULL;
+	
 	list_initialize(&sess->exch_list);
 	fibril_mutex_initialize(&sess->mutex);
@@ -1627,4 +1648,7 @@
 	sess->arg3 = arg3;
 	
+	fibril_mutex_initialize(&sess->remote_state_mtx);
+	sess->remote_state_data = NULL;
+	
 	list_initialize(&sess->exch_list);
 	fibril_mutex_initialize(&sess->mutex);
@@ -1632,4 +1656,22 @@
 	
 	return sess;
+}
+
+/** Set arguments for new connections.
+ *
+ * FIXME This is an ugly hack to work around the problem that parallel
+ * exchanges are implemented using parallel connections. When we create
+ * a callback session, the framework does not know arguments for the new
+ * connections.
+ *
+ * The proper solution seems to be to implement parallel exchanges using
+ * tagging.
+ */
+void async_sess_args_set(async_sess_t *sess, sysarg_t arg1, sysarg_t arg2,
+    sysarg_t arg3)
+{
+	sess->arg1 = arg1;
+	sess->arg2 = arg2;
+	sess->arg3 = arg3;
 }
 
@@ -1677,4 +1719,7 @@
 	sess->arg3 = arg3;
 	
+	fibril_mutex_initialize(&sess->remote_state_mtx);
+	sess->remote_state_data = NULL;
+	
 	list_initialize(&sess->exch_list);
 	fibril_mutex_initialize(&sess->mutex);
@@ -1707,4 +1752,7 @@
 	sess->arg2 = 0;
 	sess->arg3 = 0;
+	
+	fibril_mutex_initialize(&sess->remote_state_mtx);
+	sess->remote_state_data = NULL;
 	
 	list_initialize(&sess->exch_list);
@@ -2371,4 +2419,7 @@
 	sess->arg3 = 0;
 	
+	fibril_mutex_initialize(&sess->remote_state_mtx);
+	sess->remote_state_data = NULL;
+	
 	list_initialize(&sess->exch_list);
 	fibril_mutex_initialize(&sess->mutex);
@@ -2417,4 +2468,7 @@
 	sess->arg3 = 0;
 	
+	fibril_mutex_initialize(&sess->remote_state_mtx);
+	sess->remote_state_data = NULL;
+	
 	list_initialize(&sess->exch_list);
 	fibril_mutex_initialize(&sess->mutex);
@@ -2458,4 +2512,7 @@
 	sess->arg2 = 0;
 	sess->arg3 = 0;
+	
+	fibril_mutex_initialize(&sess->remote_state_mtx);
+	sess->remote_state_data = NULL;
 	
 	list_initialize(&sess->exch_list);
@@ -2499,4 +2556,74 @@
 }
 
+/** Lock and get session remote state
+ *
+ * Lock and get the local replica of the remote state
+ * in stateful sessions. The call should be paired
+ * with async_remote_state_release*().
+ *
+ * @param[in] sess Stateful session.
+ *
+ * @return Local replica of the remote state.
+ *
+ */
+void *async_remote_state_acquire(async_sess_t *sess)
+{
+	fibril_mutex_lock(&sess->remote_state_mtx);
+	return sess->remote_state_data;
+}
+
+/** Update the session remote state
+ *
+ * Update the local replica of the remote state
+ * in stateful sessions. The remote state must
+ * be already locked.
+ *
+ * @param[in] sess  Stateful session.
+ * @param[in] state New local replica of the remote state.
+ *
+ */
+void async_remote_state_update(async_sess_t *sess, void *state)
+{
+	assert(fibril_mutex_is_locked(&sess->remote_state_mtx));
+	sess->remote_state_data = state;
+}
+
+/** Release the session remote state
+ *
+ * Unlock the local replica of the remote state
+ * in stateful sessions.
+ *
+ * @param[in] sess Stateful session.
+ *
+ */
+void async_remote_state_release(async_sess_t *sess)
+{
+	assert(fibril_mutex_is_locked(&sess->remote_state_mtx));
+	
+	fibril_mutex_unlock(&sess->remote_state_mtx);
+}
+
+/** Release the session remote state and end an exchange
+ *
+ * Unlock the local replica of the remote state
+ * in stateful sessions. This is convenience function
+ * which gets the session pointer from the exchange
+ * and also ends the exchange.
+ *
+ * @param[in] exch Stateful session's exchange.
+ *
+ */
+void async_remote_state_release_exchange(async_exch_t *exch)
+{
+	if (exch == NULL)
+		return;
+	
+	async_sess_t *sess = exch->sess;
+	assert(fibril_mutex_is_locked(&sess->remote_state_mtx));
+	
+	async_exchange_end(exch);
+	fibril_mutex_unlock(&sess->remote_state_mtx);
+}
+
 /** @}
  */
Index: uspace/lib/c/generic/async_obsolete.c
===================================================================
--- uspace/lib/c/generic/async_obsolete.c	(revision 22cf42d96305c1472aead44ed289906f0f0b0f13)
+++ uspace/lib/c/generic/async_obsolete.c	(revision d1e196f782180ef828064caefc47c1fa0ed2111c)
@@ -38,4 +38,5 @@
 #include <async.h>
 #include <async_obsolete.h>
+#include "private/async.h"
 #undef LIBC_ASYNC_C_
 #undef LIBC_ASYNC_OBSOLETE_C_
@@ -44,5 +45,4 @@
 #include <malloc.h>
 #include <errno.h>
-#include "private/async.h"
 
 /** Send message and return id of the sent message.
Index: uspace/lib/c/generic/devman.c
===================================================================
--- uspace/lib/c/generic/devman.c	(revision 22cf42d96305c1472aead44ed289906f0f0b0f13)
+++ uspace/lib/c/generic/devman.c	(revision d1e196f782180ef828064caefc47c1fa0ed2111c)
@@ -1,5 +1,5 @@
 /*
  * Copyright (c) 2007 Josef Cejka
- * Copyright (c) 2009 Jiri Svoboda
+ * Copyright (c) 2011 Jiri Svoboda
  * Copyright (c) 2010 Lenka Trochtova
  * All rights reserved.
@@ -89,5 +89,5 @@
 			if (devman_driver_block_sess == NULL)
 				devman_driver_block_sess =
-				    service_connect_blocking(EXCHANGE_SERIALIZE,
+				    service_connect_blocking(EXCHANGE_PARALLEL,
 				    SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
 		}
@@ -138,5 +138,5 @@
 		if (devman_driver_sess == NULL)
 			devman_driver_sess =
-			    service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAN,
+			    service_connect(EXCHANGE_PARALLEL, SERVICE_DEVMAN,
 			    DEVMAN_DRIVER, 0);
 		
@@ -195,5 +195,5 @@
 	
 	exch = devman_exchange_begin(DEVMAN_DRIVER);
-	async_connect_to_me(exch, 0, 0, 0, NULL, NULL);
+	async_connect_to_me(exch, 0, 0, 0, conn, NULL);
 	devman_exchange_end(exch);
 	
@@ -342,5 +342,5 @@
 }
 
-int devman_device_get_handle(const char *pathname, devman_handle_t *handle,
+int devman_fun_get_handle(const char *pathname, devman_handle_t *handle,
     unsigned int flags)
 {
@@ -383,5 +383,132 @@
 }
 
-int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
+static int devman_get_str_internal(sysarg_t method, sysarg_t arg1, char *buf,
+    size_t buf_size)
+{
+	async_exch_t *exch;
+	ipc_call_t dreply;
+	size_t act_size;
+	sysarg_t dretval;
+	
+	exch = devman_exchange_begin_blocking(LOC_PORT_CONSUMER);
+	
+	ipc_call_t answer;
+	aid_t req = async_send_1(exch, method, arg1, &answer);
+	aid_t dreq = async_data_read(exch, buf, buf_size - 1, &dreply);
+	async_wait_for(dreq, &dretval);
+	
+	devman_exchange_end(exch);
+	
+	if (dretval != EOK) {
+		async_wait_for(req, NULL);
+		return dretval;
+	}
+	
+	sysarg_t retval;
+	async_wait_for(req, &retval);
+	
+	if (retval != EOK)
+		return retval;
+	
+	act_size = IPC_GET_ARG2(dreply);
+	assert(act_size <= buf_size - 1);
+	buf[act_size] = '\0';
+	
+	return EOK;
+}
+
+int devman_fun_get_path(devman_handle_t handle, char *buf, size_t buf_size)
+{
+	return devman_get_str_internal(DEVMAN_FUN_GET_PATH, handle, buf,
+	    buf_size);
+}
+
+int devman_fun_get_name(devman_handle_t handle, char *buf, size_t buf_size)
+{
+	return devman_get_str_internal(DEVMAN_FUN_GET_NAME, handle, buf,
+	    buf_size);
+}
+
+static int devman_get_handles_once(sysarg_t method, sysarg_t arg1,
+    devman_handle_t *handle_buf, size_t buf_size, size_t *act_size)
+{
+	async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
+
+	ipc_call_t answer;
+	aid_t req = async_send_1(exch, method, arg1, &answer);
+	int rc = async_data_read_start(exch, handle_buf, buf_size);
+	
+	devman_exchange_end(exch);
+	
+	if (rc != EOK) {
+		async_wait_for(req, NULL);
+		return rc;
+	}
+	
+	sysarg_t retval;
+	async_wait_for(req, &retval);
+	
+	if (retval != EOK) {
+		return retval;
+	}
+	
+	*act_size = IPC_GET_ARG1(answer);
+	return EOK;
+}
+
+/** Get list of handles.
+ *
+ * Returns an allocated array of handles.
+ *
+ * @param method	IPC method
+ * @param arg1		IPC argument 1
+ * @param data		Place to store pointer to array of handles
+ * @param count		Place to store number of handles
+ * @return 		EOK on success or negative error code
+ */
+static int devman_get_handles_internal(sysarg_t method, sysarg_t arg1,
+    devman_handle_t **data, size_t *count)
+{
+	devman_handle_t *handles;
+	size_t act_size;
+	size_t alloc_size;
+	int rc;
+
+	*data = NULL;
+	act_size = 0;	/* silence warning */
+
+	rc = devman_get_handles_once(method, arg1, NULL, 0,
+	    &act_size);
+	if (rc != EOK)
+		return rc;
+
+	alloc_size = act_size;
+	handles = malloc(alloc_size);
+	if (handles == NULL)
+		return ENOMEM;
+
+	while (true) {
+		rc = devman_get_handles_once(method, arg1, handles, alloc_size,
+		    &act_size);
+		if (rc != EOK)
+			return rc;
+
+		if (act_size <= alloc_size)
+			break;
+
+		alloc_size *= 2;
+		free(handles);
+
+		handles = malloc(alloc_size);
+		if (handles == NULL)
+			return ENOMEM;
+	}
+
+	*count = act_size / sizeof(devman_handle_t);
+	*data = handles;
+	return EOK;
+}
+
+int devman_fun_get_child(devman_handle_t funh, devman_handle_t *devh)
 {
 	async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
@@ -389,45 +516,16 @@
 		return ENOMEM;
 	
-	ipc_call_t answer;
-	aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_DEVICE_PATH,
-	    handle, &answer);
-	
-	ipc_call_t data_request_call;
-	aid_t data_request = async_data_read(exch, path, path_size,
-	    &data_request_call);
-	
-	devman_exchange_end(exch);
-	
-	if (data_request == 0) {
-		async_wait_for(req, NULL);
-		return ENOMEM;
-	}
-	
-	sysarg_t data_request_rc;
-	async_wait_for(data_request, &data_request_rc);
-	
-	sysarg_t opening_request_rc;
-	async_wait_for(req, &opening_request_rc);
-	
-	if (data_request_rc != EOK) {
-		/* Prefer the return code of the opening request. */
-		if (opening_request_rc != EOK)
-			return (int) opening_request_rc;
-		else
-			return (int) data_request_rc;
-	}
-	
-	if (opening_request_rc != EOK)
-		return (int) opening_request_rc;
-	
-	/* To be on the safe-side. */
-	path[path_size - 1] = 0;
-	size_t transferred_size = IPC_GET_ARG2(data_request_call);
-	if (transferred_size >= path_size)
-		return ELIMIT;
-	
-	/* Terminate the string (trailing 0 not send over IPC). */
-	path[transferred_size] = 0;
-	return EOK;
+	sysarg_t retval = async_req_1_1(exch, DEVMAN_FUN_GET_CHILD,
+	    funh, devh);
+	
+	devman_exchange_end(exch);
+	return (int) retval;
+}
+
+int devman_dev_get_functions(devman_handle_t devh, devman_handle_t **funcs,
+    size_t *count)
+{
+	return devman_get_handles_internal(DEVMAN_DEV_GET_FUNCTIONS,
+	    devh, funcs, count);
 }
 
Index: uspace/lib/c/generic/io/printf_core.c
===================================================================
--- uspace/lib/c/generic/io/printf_core.c	(revision 22cf42d96305c1472aead44ed289906f0f0b0f13)
+++ uspace/lib/c/generic/io/printf_core.c	(revision d1e196f782180ef828064caefc47c1fa0ed2111c)
@@ -206,5 +206,5 @@
 	}
 	
-	return (int) (counter + 1);
+	return (int) (counter);
 }
 
@@ -244,5 +244,5 @@
 	}
 	
-	return (int) (counter + 1);
+	return (int) (counter);
 }
 
Index: uspace/lib/c/generic/ipc.c
===================================================================
--- uspace/lib/c/generic/ipc.c	(revision 22cf42d96305c1472aead44ed289906f0f0b0f13)
+++ uspace/lib/c/generic/ipc.c	(revision d1e196f782180ef828064caefc47c1fa0ed2111c)
@@ -47,4 +47,5 @@
 #include <futex.h>
 #include <fibril.h>
+#include <macros.h>
 
 /**
@@ -611,5 +612,5 @@
 /** Request callback connection.
  *
- * The @a taskhash and @a phonehash identifiers returned
+ * The @a task_id and @a phonehash identifiers returned
  * by the kernel can be used for connection tracking.
  *
@@ -618,5 +619,5 @@
  * @param arg2      User defined argument.
  * @param arg3      User defined argument.
- * @param taskhash  Opaque identifier of the client task.
+ * @param task_id   Identifier of the client task.
  * @param phonehash Opaque identifier of the phone that will
  *                  be used for incoming calls.
@@ -626,8 +627,14 @@
  */
 int ipc_connect_to_me(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
-    sysarg_t *taskhash, sysarg_t *phonehash)
-{
-	return ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_TO_ME, arg1, arg2,
-	    arg3, NULL, NULL, NULL, taskhash, phonehash);
+    task_id_t *task_id, sysarg_t *phonehash)
+{
+	ipc_call_t data;
+	int rc = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid,
+	    IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, (sysarg_t) &data);
+	if (rc == EOK) {
+		*task_id = data.in_task_id;
+		*phonehash = IPC_GET_ARG5(data);
+	}	
+	return rc;
 }
 
Index: uspace/lib/c/generic/loader.c
===================================================================
--- uspace/lib/c/generic/loader.c	(revision 22cf42d96305c1472aead44ed289906f0f0b0f13)
+++ uspace/lib/c/generic/loader.c	(revision d1e196f782180ef828064caefc47c1fa0ed2111c)
@@ -263,6 +263,5 @@
 	
 	int i;
-	for (i = 0; files[i]; i++)
-		;
+	for (i = 0; files[i]; i++);
 
 	ipc_call_t answer;
Index: uspace/lib/c/generic/loc.c
===================================================================
--- uspace/lib/c/generic/loc.c	(revision 22cf42d96305c1472aead44ed289906f0f0b0f13)
+++ uspace/lib/c/generic/loc.c	(revision d1e196f782180ef828064caefc47c1fa0ed2111c)
@@ -315,6 +315,6 @@
 /** Register new service.
  *
- * @param fqsn	Fully qualified service name
- * @param sid	Output: ID of new service
+ * @param fqsn Fully qualified service name
+ * @param sid  Output: ID of new service
  *
  */
Index: uspace/lib/c/generic/ns.c
===================================================================
--- uspace/lib/c/generic/ns.c	(revision 22cf42d96305c1472aead44ed289906f0f0b0f13)
+++ uspace/lib/c/generic/ns.c	(revision d1e196f782180ef828064caefc47c1fa0ed2111c)
@@ -56,4 +56,11 @@
 	async_exchange_end(exch);
 	
+	/*
+	 * FIXME Ugly hack to work around limitation of implementing
+	 * parallel exchanges using multiple connections. Shift out
+	 * first argument for non-initial connections.
+	 */
+	async_sess_args_set(sess, arg2, arg3, 0);
+	
 	return sess;
 }
@@ -66,4 +73,11 @@
 	    async_connect_me_to_blocking(mgmt, exch, service, arg2, arg3);
 	async_exchange_end(exch);
+	
+	/*
+	 * FIXME Ugly hack to work around limitation of implementing
+	 * parallel exchanges using multiple connections. Shift out
+	 * first argument for non-initial connections.
+	 */
+	async_sess_args_set(sess, arg2, arg3, 0);
 	
 	return sess;
Index: uspace/lib/c/generic/private/async.h
===================================================================
--- uspace/lib/c/generic/private/async.h	(revision 22cf42d96305c1472aead44ed289906f0f0b0f13)
+++ uspace/lib/c/generic/private/async.h	(revision d1e196f782180ef828064caefc47c1fa0ed2111c)
@@ -36,9 +36,58 @@
 #define LIBC_PRIVATE_ASYNC_H_
 
-#include <ipc/common.h>
+#include <async.h>
 #include <adt/list.h>
 #include <fibril.h>
+#include <fibril_synch.h>
 #include <sys/time.h>
 #include <bool.h>
+
+/** Session data */
+struct _async_sess {
+	/** List of inactive exchanges */
+	list_t exch_list;
+	
+	/** Exchange management style */
+	exch_mgmt_t mgmt;
+	
+	/** Session identification */
+	int phone;
+	
+	/** First clone connection argument */
+	sysarg_t arg1;
+	
+	/** Second clone connection argument */
+	sysarg_t arg2;
+	
+	/** Third clone connection argument */
+	sysarg_t arg3;
+	
+	/** Exchange mutex */
+	fibril_mutex_t mutex;
+	
+	/** Number of opened exchanges */
+	atomic_t refcnt;
+	
+	/** Mutex for stateful connections */
+	fibril_mutex_t remote_state_mtx;
+	
+	/** Data for stateful connections */
+	void *remote_state_data;
+};
+
+/** Exchange data */
+struct _async_exch {
+	/** Link into list of inactive exchanges */
+	link_t sess_link;
+	
+	/** Link into global list of inactive exchanges */
+	link_t global_link;
+	
+	/** Session pointer */
+	async_sess_t *sess;
+	
+	/** Exchange identification */
+	int phone;
+};
 
 /** Structures of this type are used to track the timeout events. */
