Index: uspace/lib/c/generic/async/client.c
===================================================================
--- uspace/lib/c/generic/async/client.c	(revision 9c16c36bce125d0c1aaadb77800494de3f54faa5)
+++ uspace/lib/c/generic/async/client.c	(revision 95faa4dec13caf69ef6b5a19e578aecba68ea63a)
@@ -1349,5 +1349,12 @@
     sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
 {
+	assert(call);
 	memset(call, 0, sizeof(*call));
+	list_initialize(&call->fragments);
+
+	if (!sess) {
+		call->rc = ENOENT;
+		return;
+	}
 
 	call->exch = async_exchange_begin(sess);
@@ -1503,9 +1510,11 @@
 	data->finalizer = finalizer;
 
-	if (!call->exch)
-		call->rc = ENOENT;
-
 	if (call->rc)
 		return;
+
+	if (!call->exch) {
+		call->rc = ENOENT;
+		return;
+	}
 
 	data->msgid = async_send_fast(call->exch, imethod,
@@ -1606,4 +1615,10 @@
 }
 
+void async_call_connect_to_me(async_call_t *call, async_call_data_t *data,
+	sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
+{
+	async_call_method(call, data, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, 0);
+}
+
 // TODO: connect me to, connect to me, vfs handle, etc.
 
Index: uspace/lib/c/generic/devman.c
===================================================================
--- uspace/lib/c/generic/devman.c	(revision 9c16c36bce125d0c1aaadb77800494de3f54faa5)
+++ uspace/lib/c/generic/devman.c	(revision 95faa4dec13caf69ef6b5a19e578aecba68ea63a)
@@ -69,12 +69,5 @@
 }
 
-/** Start an async exchange on the devman session (blocking).
- *
- * @param iface Device manager interface to choose
- *
- * @return New exchange.
- *
- */
-async_exch_t *devman_exchange_begin_blocking(iface_t iface)
+static async_sess_t *devman_session_blocking(iface_t iface)
 {
 	switch (iface) {
@@ -97,5 +90,5 @@
 		    &devman_driver_sess);
 
-		return async_exchange_begin(devman_driver_block_sess);
+		return devman_driver_block_sess;
 	case INTERFACE_DDF_CLIENT:
 		fibril_mutex_lock(&devman_client_block_mutex);
@@ -116,5 +109,5 @@
 		    &devman_client_sess);
 
-		return async_exchange_begin(devman_client_block_sess);
+		return devman_client_block_sess;
 	default:
 		return NULL;
@@ -122,5 +115,5 @@
 }
 
-/** Start an async exchange on the devman session.
+/** Start an async exchange on the devman session (blocking).
  *
  * @param iface Device manager interface to choose
@@ -129,5 +122,13 @@
  *
  */
-async_exch_t *devman_exchange_begin(iface_t iface)
+async_exch_t *devman_exchange_begin_blocking(iface_t iface)
+{
+	async_sess_t *sess = devman_session_blocking(iface);
+	if (!sess)
+		return NULL;
+	return async_exchange_begin(sess);
+}
+
+static async_sess_t *devman_session(iface_t iface)
 {
 	switch (iface) {
@@ -145,5 +146,5 @@
 			return NULL;
 
-		return async_exchange_begin(devman_driver_sess);
+		return devman_driver_sess;
 	case INTERFACE_DDF_CLIENT:
 		fibril_mutex_lock(&devman_client_mutex);
@@ -159,5 +160,5 @@
 			return NULL;
 
-		return async_exchange_begin(devman_client_sess);
+		return devman_client_sess;
 	default:
 		return NULL;
@@ -165,4 +166,19 @@
 }
 
+/** Start an async exchange on the devman session.
+ *
+ * @param iface Device manager interface to choose
+ *
+ * @return New exchange.
+ *
+ */
+async_exch_t *devman_exchange_begin(iface_t iface)
+{
+	async_sess_t *sess = devman_session(iface);
+	if (!sess)
+		return NULL;
+	return async_exchange_begin(sess);
+}
+
 /** Finish an async exchange on the devman session.
  *
@@ -178,23 +194,14 @@
 errno_t devman_driver_register(const char *name)
 {
-	async_exch_t *exch = devman_exchange_begin_blocking(INTERFACE_DDF_DRIVER);
-
-	ipc_call_t answer;
-	aid_t req = async_send_2(exch, DEVMAN_DRIVER_REGISTER, 0, 0, &answer);
-	errno_t retval = async_data_write_start(exch, name, str_size(name));
-
-	devman_exchange_end(exch);
-
-	if (retval != EOK) {
-		async_forget(req);
-		return retval;
-	}
-
-	exch = devman_exchange_begin(INTERFACE_DDF_DRIVER);
-	async_connect_to_me(exch, 0, 0, 0);
-	devman_exchange_end(exch);
-
-	async_wait_for(req, &retval);
-	return retval;
+	async_sess_t *sess = devman_session_blocking(INTERFACE_DDF_DRIVER);
+
+	async_call_t call;
+	async_call_data_t write, connect;
+
+	async_call_begin(&call, sess, DEVMAN_DRIVER_REGISTER, 0, 0, 0, 0);
+	async_call_write(&call, &write, name, str_size(name), NULL);
+	async_call_connect_to_me(&call, &connect, 0, 0, 0);
+
+	return async_call_finish(&call);
 }
 
@@ -217,49 +224,38 @@
 {
 	unsigned long match_count = list_count(&match_ids->ids);
-	async_exch_t *exch = devman_exchange_begin_blocking(INTERFACE_DDF_DRIVER);
-
-	ipc_call_t answer;
-	aid_t req = async_send_3(exch, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype,
-	    devh, match_count, &answer);
-	errno_t retval = async_data_write_start(exch, name, str_size(name));
-	if (retval != EOK) {
-		devman_exchange_end(exch);
-		async_forget(req);
-		return retval;
-	}
+
+	async_sess_t *sess = devman_session_blocking(INTERFACE_DDF_DRIVER);
+
+	async_call_t call;
+	async_call_data_t write1, method_n, write_n;
+
+	async_call_begin(&call, sess, DEVMAN_ADD_FUNCTION,
+	    (sysarg_t) ftype, devh, match_count, 0);
+
+	async_call_write(&call, &write1, name, str_size(name), NULL);
 
 	list_foreach(match_ids->ids, link, match_id_t, match_id) {
-		ipc_call_t answer2;
-		aid_t req2 = async_send_1(exch, DEVMAN_ADD_MATCH_ID,
-		    match_id->score, &answer2);
-		retval = async_data_write_start(exch, match_id->id,
-		    str_size(match_id->id));
-		if (retval != EOK) {
-			devman_exchange_end(exch);
-			async_forget(req2);
-			async_forget(req);
-			return retval;
+		async_call_method(&call, &method_n, DEVMAN_ADD_MATCH_ID,
+		    match_id->score, 0, 0, 0);
+
+		async_call_write(&call, &write_n,
+		    match_id->id, str_size(match_id->id), NULL);
+
+		/* Wait so that we can recycle `method_n` and `write_n`. */
+		(void) async_call_wait(&call);
+	}
+
+	errno_t rc = async_call_finish(&call);
+
+	if (funh) {
+		if (rc == EOK) {
+			*funh = (devman_handle_t)
+			    IPC_GET_ARG1(call.initial.answer);
+		} else {
+			*funh = -1;
 		}
-
-		async_wait_for(req2, &retval);
-		if (retval != EOK) {
-			devman_exchange_end(exch);
-			async_forget(req);
-			return retval;
-		}
-	}
-
-	devman_exchange_end(exch);
-
-	async_wait_for(req, &retval);
-	if (retval == EOK) {
-		if (funh != NULL)
-			*funh = (int) IPC_GET_ARG1(answer);
-	} else {
-		if (funh != NULL)
-			*funh = -1;
-	}
-
-	return retval;
+	}
+
+	return rc;
 }
 
@@ -267,21 +263,12 @@
     const char *cat_name)
 {
-	async_exch_t *exch = devman_exchange_begin_blocking(INTERFACE_DDF_DRIVER);
-
-	ipc_call_t answer;
-	aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CATEGORY,
-	    devman_handle, &answer);
-	errno_t retval = async_data_write_start(exch, cat_name,
-	    str_size(cat_name));
-
-	devman_exchange_end(exch);
-
-	if (retval != EOK) {
-		async_forget(req);
-		return retval;
-	}
-
-	async_wait_for(req, &retval);
-	return retval;
+	async_sess_t *sess = devman_session_blocking(INTERFACE_DDF_DRIVER);
+
+	async_call_t call;
+	async_call_data_t write;
+
+	async_call_begin(&call, sess, DEVMAN_ADD_DEVICE_TO_CATEGORY, devman_handle, 0, 0, 0);
+	async_call_write(&call, &write, cat_name, str_size(cat_name), NULL);
+	return async_call_finish(&call);
 }
 
@@ -309,36 +296,27 @@
 errno_t devman_remove_function(devman_handle_t funh)
 {
-	async_exch_t *exch;
-	errno_t retval;
-
-	exch = devman_exchange_begin_blocking(INTERFACE_DDF_DRIVER);
-	retval = async_req_1_0(exch, DEVMAN_REMOVE_FUNCTION, (sysarg_t) funh);
-	devman_exchange_end(exch);
-
-	return retval;
+	async_sess_t *sess = devman_session_blocking(INTERFACE_DDF_DRIVER);
+
+	async_call_t call;
+	async_call_begin(&call, sess, DEVMAN_REMOVE_FUNCTION, funh, 0, 0, 0);
+	return async_call_finish(&call);
 }
 
 errno_t devman_drv_fun_online(devman_handle_t funh)
 {
-	async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_DRIVER);
-	if (exch == NULL)
-		return ENOMEM;
-
-	errno_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_ONLINE, funh);
-
-	devman_exchange_end(exch);
-	return retval;
+	async_sess_t *sess = devman_session_blocking(INTERFACE_DDF_DRIVER);
+
+	async_call_t call;
+	async_call_begin(&call, sess, DEVMAN_DRV_FUN_ONLINE, funh, 0, 0, 0);
+	return async_call_finish(&call);
 }
 
 errno_t devman_drv_fun_offline(devman_handle_t funh)
 {
-	async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_DRIVER);
-	if (exch == NULL)
-		return ENOMEM;
-
-	errno_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_OFFLINE, funh);
-
-	devman_exchange_end(exch);
-	return retval;
+	async_sess_t *sess = devman_session_blocking(INTERFACE_DDF_DRIVER);
+
+	async_call_t call;
+	async_call_begin(&call, sess, DEVMAN_DRV_FUN_OFFLINE, funh, 0, 0, 0);
+	return async_call_finish(&call);
 }
 
@@ -361,40 +339,28 @@
     unsigned int flags)
 {
-	async_exch_t *exch;
+	async_sess_t *sess;
+	async_call_t call;
+	async_call_data_t write;
 
 	if (flags & IPC_FLAG_BLOCKING)
-		exch = devman_exchange_begin_blocking(INTERFACE_DDF_CLIENT);
-	else {
-		exch = devman_exchange_begin(INTERFACE_DDF_CLIENT);
-		if (exch == NULL)
-			return ENOMEM;
-	}
-
-	ipc_call_t answer;
-	aid_t req = async_send_2(exch, DEVMAN_DEVICE_GET_HANDLE, flags, 0,
-	    &answer);
-	errno_t retval = async_data_write_start(exch, pathname,
-	    str_size(pathname));
-
-	devman_exchange_end(exch);
-
-	if (retval != EOK) {
-		async_forget(req);
-		return retval;
-	}
-
-	async_wait_for(req, &retval);
-
-	if (retval != EOK) {
+		sess = devman_session_blocking(INTERFACE_DDF_CLIENT);
+	else
+		sess = devman_session(INTERFACE_DDF_CLIENT);
+
+	async_call_begin(&call, sess, DEVMAN_DEVICE_GET_HANDLE, flags, 0, 0, 0);
+	async_call_write(&call, &write, pathname, str_size(pathname), NULL);
+	errno_t rc = async_call_finish(&call);
+
+	if (rc != EOK) {
 		if (handle != NULL)
 			*handle = (devman_handle_t) -1;
 
-		return retval;
+		return rc;
 	}
 
 	if (handle != NULL)
-		*handle = (devman_handle_t) IPC_GET_ARG1(answer);
-
-	return retval;
+		*handle = (devman_handle_t) IPC_GET_ARG1(call.initial.answer);
+
+	return EOK;
 }
 
@@ -402,36 +368,21 @@
     sysarg_t arg2, sysarg_t *r1, char *buf, size_t buf_size)
 {
-	async_exch_t *exch;
-	ipc_call_t dreply;
+	async_call_t call;
+	async_call_data_t read;
 	size_t act_size;
-	errno_t dretval;
-
-	exch = devman_exchange_begin_blocking(INTERFACE_DDF_CLIENT);
-
-	ipc_call_t answer;
-	aid_t req = async_send_2(exch, method, arg1, arg2, &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_forget(req);
-		return dretval;
-	}
-
-	errno_t retval;
-	async_wait_for(req, &retval);
-
-	if (retval != EOK) {
-		return retval;
-	}
+
+	async_sess_t *sess = devman_session_blocking(INTERFACE_DDF_CLIENT);
+
+	async_call_begin(&call, sess, method, arg1, arg2, 0, 0);
+	async_call_read(&call, &read, buf, buf_size - 1, &act_size);
+	errno_t rc = async_call_finish(&call);
+	if (rc != EOK)
+		return rc;
 
 	if (r1 != NULL)
-		*r1 = IPC_GET_ARG1(answer);
-	act_size = IPC_GET_ARG2(dreply);
+		*r1 = IPC_GET_ARG1(call.initial.answer);
+
 	assert(act_size <= buf_size - 1);
 	buf[act_size] = '\0';
-
 	return EOK;
 }
@@ -472,24 +423,18 @@
 errno_t devman_fun_online(devman_handle_t funh)
 {
-	async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_CLIENT);
-	if (exch == NULL)
-		return ENOMEM;
-
-	errno_t retval = async_req_1_0(exch, DEVMAN_FUN_ONLINE, funh);
-
-	devman_exchange_end(exch);
-	return retval;
+	async_sess_t *sess = devman_session(INTERFACE_DDF_CLIENT);
+
+	async_call_t call;
+	async_call_begin(&call, sess, DEVMAN_FUN_ONLINE, funh, 0, 0, 0);
+	return async_call_finish(&call);
 }
 
 errno_t devman_fun_offline(devman_handle_t funh)
 {
-	async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_CLIENT);
-	if (exch == NULL)
-		return ENOMEM;
-
-	errno_t retval = async_req_1_0(exch, DEVMAN_FUN_OFFLINE, funh);
-
-	devman_exchange_end(exch);
-	return retval;
+	async_sess_t *sess = devman_session(INTERFACE_DDF_CLIENT);
+
+	async_call_t call;
+	async_call_begin(&call, sess, DEVMAN_FUN_OFFLINE, funh, 0, 0, 0);
+	return async_call_finish(&call);
 }
 
@@ -497,25 +442,16 @@
     devman_handle_t *handle_buf, size_t buf_size, size_t *act_size)
 {
-	async_exch_t *exch = devman_exchange_begin_blocking(INTERFACE_DDF_CLIENT);
-
-	ipc_call_t answer;
-	aid_t req = async_send_1(exch, method, arg1, &answer);
-	errno_t rc = async_data_read_start(exch, handle_buf, buf_size);
-
-	devman_exchange_end(exch);
-
-	if (rc != EOK) {
-		async_forget(req);
-		return rc;
-	}
-
-	errno_t retval;
-	async_wait_for(req, &retval);
-
-	if (retval != EOK) {
-		return retval;
-	}
-
-	*act_size = IPC_GET_ARG1(answer);
+	async_sess_t *sess = devman_session_blocking(INTERFACE_DDF_CLIENT);
+
+	async_call_t call;
+	async_call_data_t read;
+
+	async_call_begin(&call, sess, method, arg1, 0, 0, 0);
+	async_call_read(&call, &read, handle_buf, buf_size, NULL);
+	errno_t rc = async_call_finish(&call);
+	if (rc != EOK)
+		return rc;
+
+	*act_size = IPC_GET_ARG1(call.initial.answer);
 	return EOK;
 }
@@ -576,13 +512,14 @@
 errno_t devman_fun_get_child(devman_handle_t funh, devman_handle_t *devh)
 {
-	async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_CLIENT);
-	if (exch == NULL)
-		return ENOMEM;
-
-	errno_t retval = async_req_1_1(exch, DEVMAN_FUN_GET_CHILD,
-	    funh, devh);
-
-	devman_exchange_end(exch);
-	return retval;
+	async_sess_t *sess = devman_session(INTERFACE_DDF_CLIENT);
+
+	async_call_t call;
+	async_call_begin(&call, sess, DEVMAN_FUN_GET_CHILD, funh, 0, 0, 0);
+	errno_t rc = async_call_finish(&call);
+	if (rc != EOK)
+		return rc;
+
+	*devh = (devman_handle_t) IPC_GET_ARG1(call.initial.answer);
+	return EOK;
 }
 
@@ -596,13 +533,14 @@
 errno_t devman_dev_get_parent(devman_handle_t devh, devman_handle_t *funh)
 {
-	async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_CLIENT);
-	if (exch == NULL)
-		return ENOMEM;
-
-	errno_t retval = async_req_1_1(exch, DEVMAN_DEV_GET_PARENT,
-	    devh, funh);
-
-	devman_exchange_end(exch);
-	return retval;
+	async_sess_t *sess = devman_session(INTERFACE_DDF_CLIENT);
+
+	async_call_t call;
+	async_call_begin(&call, sess, DEVMAN_DEV_GET_PARENT, devh, 0, 0, 0);
+	errno_t rc = async_call_finish(&call);
+	if (rc != EOK)
+		return rc;
+
+	*funh = (devman_handle_t) IPC_GET_ARG1(call.initial.answer);
+	return EOK;
 }
 
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision 9c16c36bce125d0c1aaadb77800494de3f54faa5)
+++ uspace/lib/c/include/async.h	(revision 95faa4dec13caf69ef6b5a19e578aecba68ea63a)
@@ -550,4 +550,7 @@
     void *, unsigned int);
 
+extern void async_call_connect_to_me(async_call_t *, async_call_data_t *,
+    sysarg_t, sysarg_t, sysarg_t);
+
 // TODO: connect me to, connect to me, vfs handle, etc.
 
