Index: uspace/lib/c/generic/ns.c
===================================================================
--- uspace/lib/c/generic/ns.c	(revision 8d6bcc8c1ce0a3da902a68975c2b18e4c75d582a)
+++ uspace/lib/c/generic/ns.c	(revision 7b616e23c349fc3f8cb4c5132825f4f5ef12c96a)
@@ -40,25 +40,49 @@
 #include "private/ns.h"
 
+/*
+ * XXX ns does not know about session_ns, so we create an extra session for
+ * actual communicaton
+ */
+static async_sess_t *sess_ns = NULL;
+
 int service_register(service_t service)
 {
-	async_exch_t *exch = async_exchange_begin(session_ns);
+	sysarg_t retval;
+	ipc_call_t answer;
+	
+	async_sess_t *sess = ns_session_get();
+	if (sess == NULL)
+		return EIO;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	aid_t req = async_send_1(exch, NS_REGISTER, service, &answer);
 	int rc = async_connect_to_me(exch, 0, service, 0);
+	
 	async_exchange_end(exch);
 	
+	if (rc != EOK) {
+		async_forget(req);
+		return rc;
+	}
+	
+	async_wait_for(req, &retval);
 	return rc;
 }
 
-
 async_sess_t *service_connect(service_t service, iface_t iface, sysarg_t arg3)
 {
-	async_exch_t *exch = async_exchange_begin(session_ns);
-	if (!exch)
+	async_sess_t *sess = ns_session_get();
+	if (sess == NULL)
 		return NULL;
 	
-	async_sess_t *sess =
+	async_exch_t *exch = async_exchange_begin(sess);
+	if (exch == NULL)
+		return NULL;
+	
+	async_sess_t *csess =
 	    async_connect_me_to_iface(exch, iface, service, arg3);
 	async_exchange_end(exch);
 	
-	if (!sess)
+	if (csess == NULL)
 		return NULL;
 	
@@ -68,7 +92,7 @@
 	 * first argument for non-initial connections.
 	 */
-	async_sess_args_set(sess, iface, arg3, 0);
+	async_sess_args_set(csess, iface, arg3, 0);
 	
-	return sess;
+	return csess;
 }
 
@@ -76,10 +100,14 @@
     sysarg_t arg3)
 {
-	async_exch_t *exch = async_exchange_begin(session_ns);
-	async_sess_t *sess =
+	async_sess_t *sess = ns_session_get();
+	if (sess == NULL)
+		return NULL;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	async_sess_t *csess =
 	    async_connect_me_to_blocking_iface(exch, iface, service, arg3);
 	async_exchange_end(exch);
 	
-	if (!sess)
+	if (csess == NULL)
 		return NULL;
 	
@@ -89,7 +117,7 @@
 	 * first argument for non-initial connections.
 	 */
-	async_sess_args_set(sess, iface, arg3, 0);
+	async_sess_args_set(csess, iface, arg3, 0);
 	
-	return sess;
+	return csess;
 }
 
@@ -97,5 +125,9 @@
 int ns_ping(void)
 {
-	async_exch_t *exch = async_exchange_begin(session_ns);
+	async_sess_t *sess = ns_session_get();
+	if (sess == NULL)
+		return EIO;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
 	int rc = async_req_0_0(exch, NS_PING);
 	async_exchange_end(exch);
@@ -106,5 +138,10 @@
 int ns_intro(task_id_t id)
 {
-	async_exch_t *exch = async_exchange_begin(session_ns);
+	async_exch_t *exch;
+	async_sess_t *sess = ns_session_get();
+	if (sess == NULL)
+		return EIO;
+	
+	exch = async_exchange_begin(sess);
 	int rc = async_req_2_0(exch, NS_ID_INTRO, LOWER32(id), UPPER32(id));
 	async_exchange_end(exch);
@@ -113,4 +150,19 @@
 }
 
+async_sess_t *ns_session_get(void)
+{
+	async_exch_t *exch;
+	
+	if (sess_ns == NULL) {
+		exch = async_exchange_begin(session_ns);
+		sess_ns = async_connect_me_to_iface(exch, 0, 0, 0);
+		async_exchange_end(exch);
+		if (sess_ns == NULL)
+			return NULL;
+	}
+	
+	return sess_ns;
+}
+
 /** @}
  */
Index: uspace/lib/c/generic/task.c
===================================================================
--- uspace/lib/c/generic/task.c	(revision 8d6bcc8c1ce0a3da902a68975c2b18e4c75d582a)
+++ uspace/lib/c/generic/task.c	(revision 7b616e23c349fc3f8cb4c5132825f4f5ef12c96a)
@@ -44,4 +44,5 @@
 #include <async.h>
 #include <errno.h>
+#include <ns.h>
 #include <malloc.h>
 #include <libc.h>
@@ -324,5 +325,9 @@
 int task_setup_wait(task_id_t id, task_wait_t *wait)
 {
-	async_exch_t *exch = async_exchange_begin(session_ns);
+	async_sess_t *sess_ns = ns_session_get();
+	if (sess_ns == NULL)
+		return EIO;
+
+	async_exch_t *exch = async_exchange_begin(sess_ns);
 	wait->aid = async_send_2(exch, NS_TASK_WAIT, LOWER32(id), UPPER32(id),
 	    &wait->result);
@@ -401,5 +406,9 @@
 int task_retval(int val)
 {
-	async_exch_t *exch = async_exchange_begin(session_ns);
+	async_sess_t *sess_ns = ns_session_get();
+	if (sess_ns == NULL)
+		return EIO;
+
+	async_exch_t *exch = async_exchange_begin(sess_ns);
 	int rc = (int) async_req_1_0(exch, NS_RETVAL, val);
 	async_exchange_end(exch);
Index: uspace/lib/c/include/ipc/ns.h
===================================================================
--- uspace/lib/c/include/ipc/ns.h	(revision 8d6bcc8c1ce0a3da902a68975c2b18e4c75d582a)
+++ uspace/lib/c/include/ipc/ns.h	(revision 7b616e23c349fc3f8cb4c5132825f4f5ef12c96a)
@@ -40,4 +40,5 @@
 typedef enum {
 	NS_PING = IPC_FIRST_USER_METHOD,
+	NS_REGISTER,
 	NS_TASK_WAIT,
 	NS_ID_INTRO,
Index: uspace/lib/c/include/ns.h
===================================================================
--- uspace/lib/c/include/ns.h	(revision 8d6bcc8c1ce0a3da902a68975c2b18e4c75d582a)
+++ uspace/lib/c/include/ns.h	(revision 7b616e23c349fc3f8cb4c5132825f4f5ef12c96a)
@@ -46,4 +46,5 @@
 extern int ns_ping(void);
 extern int ns_intro(task_id_t);
+extern async_sess_t *ns_session_get(void);
 
 #endif
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision 8d6bcc8c1ce0a3da902a68975c2b18e4c75d582a)
+++ uspace/lib/drv/generic/driver.c	(revision 7b616e23c349fc3f8cb4c5132825f4f5ef12c96a)
@@ -943,11 +943,15 @@
 	int rc = async_create_port(INTERFACE_DDF_DRIVER, driver_connection_driver,
 	    NULL, &port);
-	if (rc != EOK)
+	if (rc != EOK) {
+		printf("Error: Failed to create driver port.\n");
 		return rc;
+	}
 	
 	rc = async_create_port(INTERFACE_DDF_DEVMAN, driver_connection_devman,
 	    NULL, &port);
-	if (rc != EOK)
+	if (rc != EOK) {
+		printf("Error: Failed to create devman port.\n");
 		return rc;
+	}
 	
 	async_set_fallback_port_handler(driver_connection_client, NULL);
@@ -964,6 +968,8 @@
 	/* Return success from the task since server has started. */
 	rc = task_retval(0);
-	if (rc != EOK)
+	if (rc != EOK) {
+		printf("Error: Failed returning task value.\n");
 		return rc;
+	}
 	
 	async_manager();
Index: uspace/srv/ns/clonable.c
===================================================================
--- uspace/srv/ns/clonable.c	(revision 8d6bcc8c1ce0a3da902a68975c2b18e4c75d582a)
+++ uspace/srv/ns/clonable.c	(revision 7b616e23c349fc3f8cb4c5132825f4f5ef12c96a)
@@ -31,5 +31,5 @@
  */
 
-#include <ipc/ipc.h>
+#include <async.h>
 #include <ipc/services.h>
 #include <adt/list.h>
@@ -81,5 +81,5 @@
 		/* There was no pending connection request. */
 		printf("%s: Unexpected clonable server.\n", NAME);
-		ipc_answer_0(callid, EBUSY);
+		async_answer_0(callid, EBUSY);
 		return;
 	}
@@ -91,11 +91,17 @@
 	assert(csr->service == SERVICE_LOADER);
 	
-	ipc_answer_0(callid, EOK);
+	async_answer_0(callid, EOK);
 	
-	ipc_forward_fast(csr->callid, phone, csr->iface, csr->arg3, 0,
+	async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
+	if (sess == NULL)
+		async_answer_0(callid, EIO);
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	async_forward_fast(csr->callid, exch, csr->iface, csr->arg3, 0,
 	    IPC_FF_NONE);
+	async_exchange_end(exch);
 	
 	free(csr);
-	ipc_hangup(phone);
+	async_hangup(sess);
 }
 
@@ -117,5 +123,5 @@
 	cs_req_t *csr = malloc(sizeof(cs_req_t));
 	if (csr == NULL) {
-		ipc_answer_0(callid, ENOMEM);
+		async_answer_0(callid, ENOMEM);
 		return;
 	}
@@ -126,5 +132,5 @@
 	if (rc < 0) {
 		free(csr);
-		ipc_answer_0(callid, rc);
+		async_answer_0(callid, rc);
 		return;
 	}
Index: uspace/srv/ns/ns.c
===================================================================
--- uspace/srv/ns/ns.c	(revision 8d6bcc8c1ce0a3da902a68975c2b18e4c75d582a)
+++ uspace/srv/ns/ns.c	(revision 7b616e23c349fc3f8cb4c5132825f4f5ef12c96a)
@@ -36,5 +36,6 @@
  */
 
-#include <ipc/ipc.h>
+#include <abi/ipc/methods.h>
+#include <async.h>
 #include <ipc/ns.h>
 #include <ipc/services.h>
@@ -47,4 +48,82 @@
 #include "clonable.h"
 #include "task.h"
+
+static void ns_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	ipc_call_t call;
+	ipc_callid_t callid;
+	iface_t iface;
+	service_t service;
+
+	iface = IPC_GET_ARG1(*icall);
+	service = IPC_GET_ARG2(*icall);
+	if (service != 0) {
+		/*
+		 * Client requests to be connected to a service.
+		 */
+		if (service_clonable(service)) {
+			connect_to_clonable(service, iface, icall, iid);
+		} else {
+			connect_to_service(service, iface, icall, iid);
+		}
+		return;
+	}
+	
+	async_answer_0(iid, EOK);
+
+	while (true) {
+		process_pending_conn();
+		
+		callid = async_get_call(&call);
+		if (!IPC_GET_IMETHOD(call))
+			break;
+		
+		task_id_t id;
+		sysarg_t retval;
+		
+		service_t service;
+		sysarg_t phone;
+		
+		switch (IPC_GET_IMETHOD(call)) {
+		case NS_REGISTER:
+			service = IPC_GET_ARG1(call);
+			phone = IPC_GET_ARG5(call);
+			
+			/*
+			 * Server requests service registration.
+			 */
+			if (service_clonable(service)) {
+				register_clonable(service, phone, &call, callid);
+				continue;
+			} else {
+				retval = register_service(service, phone, &call);
+			}
+			
+			break;
+		case NS_PING:
+			retval = EOK;
+			break;
+		case NS_TASK_WAIT:
+			id = (task_id_t)
+			    MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
+			wait_for_task(id, &call, callid);
+			continue;
+		case NS_ID_INTRO:
+			retval = ns_task_id_intro(&call);
+			break;
+		case NS_RETVAL:
+			retval = ns_task_retval(&call);
+			break;
+		default:
+			printf("ns: method not supported\n");
+			retval = ENOTSUP;
+			break;
+		}
+		
+		async_answer_0(callid, retval);
+	}
+
+	(void) ns_task_disconnect(&call);
+}
 
 int main(int argc, char **argv)
@@ -64,74 +143,8 @@
 		return rc;
 	
+	async_set_fallback_port_handler(ns_connection, NULL);
+	
 	printf("%s: Accepting connections\n", NAME);
-	
-	while (true) {
-		process_pending_conn();
-		
-		ipc_call_t call;
-		ipc_callid_t callid = ipc_wait_for_call(&call);
-		
-		task_id_t id;
-		sysarg_t retval;
-		
-		iface_t iface;
-		service_t service;
-		sysarg_t phone;
-		
-		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			retval = ns_task_disconnect(&call);
-			break;
-		case IPC_M_CONNECT_TO_ME:
-			service = IPC_GET_ARG2(call);
-			phone = IPC_GET_ARG5(call);
-			
-			/*
-			 * Server requests service registration.
-			 */
-			if (service_clonable(service)) {
-				register_clonable(service, phone, &call, callid);
-				continue;
-			} else
-				retval = register_service(service, phone, &call);
-			
-			break;
-		case IPC_M_CONNECT_ME_TO:
-			iface = IPC_GET_ARG1(call);
-			service = IPC_GET_ARG2(call);
-			
-			/*
-			 * Client requests to be connected to a service.
-			 */
-			if (service_clonable(service)) {
-				connect_to_clonable(service, iface, &call, callid);
-				continue;
-			} else {
-				connect_to_service(service, iface, &call, callid);
-				continue;
-			}
-			break;
-		case NS_PING:
-			retval = EOK;
-			break;
-		case NS_TASK_WAIT:
-			id = (task_id_t)
-			    MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
-			wait_for_task(id, &call, callid);
-			continue;
-		case NS_ID_INTRO:
-			retval = ns_task_id_intro(&call);
-			break;
-		case NS_RETVAL:
-			retval = ns_task_retval(&call);
-			break;
-		default:
-			retval = ENOENT;
-			break;
-		}
-		
-		if (!(callid & IPC_CALLID_NOTIFICATION))
-			ipc_answer_0(callid, retval);
-	}
+	async_manager();
 	
 	/* Not reached */
Index: uspace/srv/ns/service.c
===================================================================
--- uspace/srv/ns/service.c	(revision 8d6bcc8c1ce0a3da902a68975c2b18e4c75d582a)
+++ uspace/srv/ns/service.c	(revision 7b616e23c349fc3f8cb4c5132825f4f5ef12c96a)
@@ -31,7 +31,7 @@
  */
 
-#include <ipc/ipc.h>
 #include <adt/hash_table.h>
 #include <assert.h>
+#include <async.h>
 #include <errno.h>
 #include <stdio.h>
@@ -47,9 +47,6 @@
 	service_t service;
 	
-	/** Phone registered with the interface */
-	sysarg_t phone;
-	
-	/** Incoming phone hash */
-	sysarg_t in_phone_hash;
+	/** Session to the service */
+	async_sess_t *sess;
 } hashed_service_t;
 
@@ -121,6 +118,8 @@
 		
 		hashed_service_t *hashed_service = hash_table_get_inst(link, hashed_service_t, link);
-		(void) ipc_forward_fast(pending->callid, hashed_service->phone,
-		    pending->iface, pending->arg3, 0, IPC_FF_NONE);
+		async_exch_t *exch = async_exchange_begin(hashed_service->sess);
+		async_forward_fast(pending->callid, exch, pending->iface,
+		    pending->arg3, 0, IPC_FF_NONE);
+		async_exchange_end(exch);
 		
 		list_remove(&pending->link);
@@ -151,9 +150,9 @@
 	
 	hashed_service->service = service;
-	hashed_service->phone = phone;
-	hashed_service->in_phone_hash = call->in_phone_hash;
+	hashed_service->sess = async_callback_receive(EXCHANGE_SERIALIZE);
+	if (hashed_service->sess == NULL)
+		return EIO;
 	
 	hash_table_insert(&service_hash_table, &hashed_service->link);
-	
 	return EOK;
 }
@@ -202,11 +201,11 @@
 	
 	hashed_service_t *hashed_service = hash_table_get_inst(link, hashed_service_t, link);
-	(void) ipc_forward_fast(callid, hashed_service->phone, iface, arg3,
-	    0, IPC_FF_NONE);
+	async_exch_t *exch = async_exchange_begin(hashed_service->sess);
+	async_forward_fast(callid, exch, iface, arg3, 0, IPC_FF_NONE);
+	async_exchange_end(exch);
 	return;
 	
 out:
-	if (!(callid & IPC_CALLID_NOTIFICATION))
-		ipc_answer_0(callid, retval);
+	async_answer_0(callid, retval);
 }
 
Index: uspace/srv/ns/task.c
===================================================================
--- uspace/srv/ns/task.c	(revision 8d6bcc8c1ce0a3da902a68975c2b18e4c75d582a)
+++ uspace/srv/ns/task.c	(revision 7b616e23c349fc3f8cb4c5132825f4f5ef12c96a)
@@ -32,6 +32,6 @@
  */
 
-#include <ipc/ipc.h>
 #include <adt/hash_table.h>
+#include <async.h>
 #include <stdbool.h>
 #include <errno.h>
@@ -182,10 +182,7 @@
 			continue;
 		
-		if (!(pr->callid & IPC_CALLID_NOTIFICATION)) {
-			texit = ht->have_rval ? TASK_EXIT_NORMAL :
-			    TASK_EXIT_UNEXPECTED;
-			ipc_answer_2(pr->callid, EOK, texit,
-			    ht->retval);
-		}
+		texit = ht->have_rval ? TASK_EXIT_NORMAL :
+		    TASK_EXIT_UNEXPECTED;
+		async_answer_2(pr->callid, EOK, texit, ht->retval);
 		
 		list_remove(&pr->link);
@@ -203,5 +200,5 @@
 	if (ht == NULL) {
 		/* No such task exists. */
-		ipc_answer_0(callid, ENOENT);
+		async_answer_0(callid, ENOENT);
 		return;
 	}
@@ -210,5 +207,5 @@
 		task_exit_t texit = ht->have_rval ? TASK_EXIT_NORMAL :
 		    TASK_EXIT_UNEXPECTED;
-		ipc_answer_2(callid, EOK, texit, ht->retval);
+		async_answer_2(callid, EOK, texit, ht->retval);
 		return;
 	}
@@ -218,6 +215,5 @@
 	    (pending_wait_t *) malloc(sizeof(pending_wait_t));
 	if (!pr) {
-		if (!(callid & IPC_CALLID_NOTIFICATION))
-			ipc_answer_0(callid, ENOMEM);
+		async_answer_0(callid, ENOMEM);
 		return;
 	}
@@ -282,4 +278,24 @@
 int ns_task_retval(ipc_call_t *call)
 {
+	task_id_t id = call->in_task_id;
+	
+	ht_link_t *link = hash_table_find(&task_hash_table, &id);
+	hashed_task_t *ht = (link != NULL) ?
+	    hash_table_get_inst(link, hashed_task_t, link) : NULL;
+	
+	if ((ht == NULL) || (ht->finished))
+		return EINVAL;
+	
+	ht->finished = true;
+	ht->have_rval = true;
+	ht->retval = IPC_GET_ARG1(*call);
+	
+	process_pending_wait();
+	
+	return EOK;
+}
+
+int ns_task_disconnect(ipc_call_t *call)
+{
 	task_id_t id;
 	int rc = get_id_by_phone(call->in_phone_hash, &id);
@@ -287,27 +303,4 @@
 		return rc;
 	
-	ht_link_t *link = hash_table_find(&task_hash_table, &id);
-	hashed_task_t *ht = (link != NULL) ?
-	    hash_table_get_inst(link, hashed_task_t, link) : NULL;
-	
-	if ((ht == NULL) || (ht->finished))
-		return EINVAL;
-	
-	ht->finished = true;
-	ht->have_rval = true;
-	ht->retval = IPC_GET_ARG1(*call);
-	
-	process_pending_wait();
-	
-	return EOK;
-}
-
-int ns_task_disconnect(ipc_call_t *call)
-{
-	task_id_t id;
-	int rc = get_id_by_phone(call->in_phone_hash, &id);
-	if (rc != EOK)
-		return rc;
-	
 	/* Delete from phone-to-id map. */
 	hash_table_remove(&phone_to_id, &call->in_phone_hash);
