Index: uspace/lib/c/generic/devman.c
===================================================================
--- uspace/lib/c/generic/devman.c	(revision 93ad49a84b4c98526fa998394274bbd6c68b4f7d)
+++ uspace/lib/c/generic/devman.c	(revision 422722e64b724fdbff99b610f05f336291dc1b6b)
@@ -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);
 		
Index: uspace/lib/c/generic/ns.c
===================================================================
--- uspace/lib/c/generic/ns.c	(revision 93ad49a84b4c98526fa998394274bbd6c68b4f7d)
+++ uspace/lib/c/generic/ns.c	(revision 422722e64b724fdbff99b610f05f336291dc1b6b)
@@ -74,4 +74,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;
 }
Index: uspace/srv/devman/devman.h
===================================================================
--- uspace/srv/devman/devman.h	(revision 93ad49a84b4c98526fa998394274bbd6c68b4f7d)
+++ uspace/srv/devman/devman.h	(revision 422722e64b724fdbff99b610f05f336291dc1b6b)
@@ -63,4 +63,9 @@
 typedef struct fun_node fun_node_t;
 
+typedef struct {
+	fibril_mutex_t mutex;
+	struct driver *driver;
+} client_t;
+
 typedef enum {
 	/** Driver has not been started. */
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision 93ad49a84b4c98526fa998394274bbd6c68b4f7d)
+++ uspace/srv/devman/main.c	(revision 422722e64b724fdbff99b610f05f336291dc1b6b)
@@ -65,25 +65,18 @@
 static dev_tree_t device_tree;
 
+static int init_running_drv(void *drv);
+
 /** Register running driver. */
-static driver_t *devman_driver_register(void)
-{
-	ipc_call_t icall;
-	ipc_callid_t iid;
+static driver_t *devman_driver_register(ipc_callid_t callid, ipc_call_t *call)
+{
 	driver_t *driver = NULL;
+	char *drv_name = NULL;
 
 	log_msg(LVL_DEBUG, "devman_driver_register");
-	
-	iid = async_get_call(&icall);
-	if (IPC_GET_IMETHOD(icall) != DEVMAN_DRIVER_REGISTER) {
-		async_answer_0(iid, EREFUSED);
-		return NULL;
-	}
-	
-	char *drv_name = NULL;
 	
 	/* Get driver name. */
 	int rc = async_data_write_accept((void **) &drv_name, true, 0, 0, 0, 0);
 	if (rc != EOK) {
-		async_answer_0(iid, rc);
+		async_answer_0(callid, rc);
 		return NULL;
 	}
@@ -98,5 +91,5 @@
 		free(drv_name);
 		drv_name = NULL;
-		async_answer_0(iid, ENOENT);
+		async_answer_0(callid, ENOENT);
 		return NULL;
 	}
@@ -112,5 +105,5 @@
 		    driver->name);
 		fibril_mutex_unlock(&driver->driver_mutex);
-		async_answer_0(iid, EEXISTS);
+		async_answer_0(callid, EEXISTS);
 		return NULL;
 	}
@@ -134,12 +127,12 @@
 	log_msg(LVL_DEBUG, "Creating connection to the `%s' driver.",
 	    driver->name);
-	driver->sess = async_callback_receive(EXCHANGE_SERIALIZE);
+	driver->sess = async_callback_receive(EXCHANGE_PARALLEL);
 	if (!driver->sess) {
 		fibril_mutex_unlock(&driver->driver_mutex);
-		async_answer_0(iid, ENOTSUP);
+		async_answer_0(callid, ENOTSUP);
 		return NULL;
 	}
-	
-	fibril_mutex_unlock(&driver->driver_mutex);
+	/* FIXME: Work around problem with callback sessions */
+	async_sess_args_set(driver->sess, DRIVER_DEVMAN, 0, 0);
 	
 	log_msg(LVL_NOTE,
@@ -147,6 +140,22 @@
 	    driver->name);
 	
-	async_answer_0(iid, EOK);
-	
+	/*
+	 * Initialize the driver as running (e.g. pass assigned devices to it)
+	 * in a separate fibril; the separate fibril is used to enable the
+	 * driver to use devman service during the driver's initialization.
+	 */
+	fid_t fid = fibril_create(init_running_drv, driver);
+	if (fid == 0) {
+		log_msg(LVL_ERROR, "Failed to create initialization fibril " \
+		    "for driver `%s'.", driver->name);
+		fibril_mutex_unlock(&driver->driver_mutex);
+		async_answer_0(callid, ENOMEM);
+		return NULL;
+	}
+	
+	fibril_add_ready(fid);
+	fibril_mutex_unlock(&driver->driver_mutex);
+	
+	async_answer_0(callid, EOK);
 	return driver;
 }
@@ -429,23 +438,15 @@
 static void devman_connection_driver(ipc_callid_t iid, ipc_call_t *icall)
 {
+	client_t *client;
+	driver_t *driver;
+	
 	/* Accept the connection. */
 	async_answer_0(iid, EOK);
 	
-	driver_t *driver = devman_driver_register();
-	if (driver == NULL)
-		return;
-	
-	/*
-	 * Initialize the driver as running (e.g. pass assigned devices to it)
-	 * in a separate fibril; the separate fibril is used to enable the
-	 * driver to use devman service during the driver's initialization.
-	 */
-	fid_t fid = fibril_create(init_running_drv, driver);
-	if (fid == 0) {
-		log_msg(LVL_ERROR, "Failed to create initialization fibril " \
-		    "for driver `%s'.", driver->name);
-		return;
-	}
-	fibril_add_ready(fid);
+	client = async_get_client_data();
+	if (client == NULL) {
+		log_msg(LVL_ERROR, "Failed to allocate client data.");
+		return;
+	}
 	
 	while (true) {
@@ -456,5 +457,26 @@
 			break;
 		
+		if (IPC_GET_IMETHOD(call) != DEVMAN_DRIVER_REGISTER) {
+			fibril_mutex_lock(&client->mutex);
+			driver = client->driver;
+			fibril_mutex_unlock(&client->mutex);
+			if (driver == NULL) {
+				/* First call must be to DEVMAN_DRIVER_REGISTER */
+				async_answer_0(callid, ENOTSUP);
+				continue;
+			}
+		}
+		
 		switch (IPC_GET_IMETHOD(call)) {
+		case DEVMAN_DRIVER_REGISTER:
+			fibril_mutex_lock(&client->mutex);
+			if (client->driver != NULL) {
+				fibril_mutex_unlock(&client->mutex);
+				async_answer_0(callid, EINVAL);
+				continue;
+			}
+			client->driver = devman_driver_register(callid, &call);
+			fibril_mutex_unlock(&client->mutex);
+			break;
 		case DEVMAN_ADD_FUNCTION:
 			devman_add_function(callid, &call);
@@ -814,5 +836,5 @@
 static void devman_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
-	/* Select interface. */
+	/* Select port. */
 	switch ((sysarg_t) (IPC_GET_ARG1(*icall))) {
 	case DEVMAN_DRIVER:
@@ -840,4 +862,21 @@
 }
 
+static void *devman_client_data_create(void)
+{
+	client_t *client;
+	
+	client = calloc(1, sizeof(client_t));
+	if (client == NULL)
+		return NULL;
+	
+	fibril_mutex_initialize(&client->mutex);
+	return client;
+}
+
+static void devman_client_data_destroy(void *data)
+{
+	free(data);
+}
+
 /** Initialize device manager internal structures. */
 static bool devman_init(void)
@@ -886,5 +925,7 @@
 	}
 	
-	/* Set a handler of incomming connections. */
+	/* Set handlers for incoming connections. */
+	async_set_client_data_constructor(devman_client_data_create);
+	async_set_client_data_destructor(devman_client_data_destroy);
 	async_set_client_connection(devman_connection);
 
