Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/Makefile.common	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -133,4 +133,5 @@
 	endif
 endif
+
 # Build static whenever we use libusb because that library uses 
 # thread local variables
Index: uspace/app/bdsh/cmds/modules/bdd/bdd.c
===================================================================
--- uspace/app/bdsh/cmds/modules/bdd/bdd.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/bdsh/cmds/modules/bdd/bdd.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -102,5 +102,5 @@
 	}
 
-	rc = block_init(handle, 2048);
+	rc = block_init(EXCHANGE_SERIALIZE, handle, 2048);
 	if (rc != EOK)  {
 		printf("%s: Error initializing libblock.\n", cmdname);
Index: uspace/app/bdsh/cmds/modules/cat/cat.c
===================================================================
--- uspace/app/bdsh/cmds/modules/cat/cat.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/bdsh/cmds/modules/cat/cat.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -64,4 +64,6 @@
 static sysarg_t console_rows = 0;
 static bool should_quit = false;
+
+static console_ctrl_t *console = NULL;
 
 static struct option const long_options[] = {
@@ -102,18 +104,20 @@
 static void waitprompt()
 {
-	console_set_pos(fphone(stdout), 0, console_rows-1);
-	console_set_color(fphone(stdout), COLOR_BLUE, COLOR_WHITE, 0);
+	console_set_pos(console, 0, console_rows-1);
+	console_set_color(console, COLOR_BLUE, COLOR_WHITE, 0);
+	
 	printf("ENTER/SPACE/PAGE DOWN - next page, "
 	       "ESC/Q - quit, C - continue unpaged");
 	fflush(stdout);
-	console_set_style(fphone(stdout), STYLE_NORMAL);
+	
+	console_set_style(console, STYLE_NORMAL);
 }
 
 static void waitkey()
 {
-	console_event_t ev;
+	kbd_event_t ev;
 	
 	while (true) {
-		if (!console_get_event(fphone(stdin), &ev)) {
+		if (!console_get_kbd_event(console, &ev)) {
 			return;
 		}
@@ -138,7 +142,7 @@
 static void newpage()
 {
-	console_clear(fphone(stdout));
+	console_clear(console);
 	chars_remaining = console_cols;
-	lines_remaining = console_rows-1;
+	lines_remaining = console_rows - 1;
 }
 
@@ -238,4 +242,5 @@
 	console_rows = 0;
 	should_quit = false;
+	console = console_init(stdin, stdout);
 
 	argc = cli_count_args(argv);
@@ -280,5 +285,5 @@
 	
 	if (more) {
-		rc = console_get_size(fphone(stdout), &cols, &rows);
+		rc = console_get_size(console, &cols, &rows);
 		if (rc != EOK) {
 			printf("%s - cannot get console size\n", cmdname);
Index: uspace/app/bdsh/cmds/modules/kcon/kcon.c
===================================================================
--- uspace/app/bdsh/cmds/modules/kcon/kcon.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/bdsh/cmds/modules/kcon/kcon.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -32,5 +32,4 @@
 #include <stdlib.h>
 #include <io/console.h>
-#include <vfs/vfs.h>
 #include "config.h"
 #include "util.h"
@@ -42,13 +41,12 @@
 static const char *cmdname = "kcon";
 
-/* Dispays help for kcon in various levels */
+/* Display help for kcon in various levels */
 void help_cmd_kcon(unsigned int level)
 {
 	printf("`kcon' switches to the kernel debug console.\n");
-
-	if (level != HELP_SHORT) {
-		printf("Usage:  %s\n", cmdname);
-	}
-
+	
+	if (level != HELP_SHORT)
+		printf("Usage: %s\n", cmdname);
+	
 	return;
 }
@@ -57,17 +55,15 @@
 int cmd_kcon(char **argv)
 {
-	unsigned int argc;
-
-	argc = cli_count_args(argv);
-
+	unsigned int argc = cli_count_args(argv);
+	
 	if (argc != 1) {
 		printf("%s - incorrect number of arguments. Try `%s --help'\n",
-			cmdname, cmdname);
+		    cmdname, cmdname);
 		return CMD_FAILURE;
 	}
-
-	console_kcon_enable(fphone(stdout));
-
-	return CMD_SUCCESS;
+	
+	if (console_kcon())
+		return CMD_SUCCESS;
+	else
+		return CMD_FAILURE;
 }
-
Index: uspace/app/bdsh/input.c
===================================================================
--- uspace/app/bdsh/input.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/bdsh/input.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -110,10 +110,10 @@
 	char *str;
 	int rc;
-
-	fflush(stdout);
-	console_set_style(fphone(stdout), STYLE_EMPHASIS);
+	
+	console_flush(tinput->console);
+	console_set_style(tinput->console, STYLE_EMPHASIS);
 	printf("%s", usr->prompt);
-	fflush(stdout);
-	console_set_style(fphone(stdout), STYLE_NORMAL);
+	console_flush(tinput->console);
+	console_set_style(tinput->console, STYLE_NORMAL);
 
 	rc = tinput_read(tinput, &str);
Index: uspace/app/blkdump/blkdump.c
===================================================================
--- uspace/app/blkdump/blkdump.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/blkdump/blkdump.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -134,5 +134,5 @@
 	}
 
-	rc = block_init(handle, 2048);
+	rc = block_init(EXCHANGE_SERIALIZE, handle, 2048);
 	if (rc != EOK)  {
 		printf(NAME ": Error initializing libblock.\n");
Index: uspace/app/edit/edit.c
===================================================================
--- uspace/app/edit/edit.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/edit/edit.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -94,5 +94,5 @@
 } doc_t;
 
-static int con;
+static console_ctrl_t *con;
 static doc_t doc;
 static bool done;
@@ -115,7 +115,7 @@
 static void cursor_setvis(bool visible);
 
-static void key_handle_unmod(console_event_t const *ev);
-static void key_handle_ctrl(console_event_t const *ev);
-static void key_handle_shift(console_event_t const *ev);
+static void key_handle_unmod(kbd_event_t const *ev);
+static void key_handle_ctrl(kbd_event_t const *ev);
+static void key_handle_shift(kbd_event_t const *ev);
 static void key_handle_movement(unsigned int key, bool shift);
 
@@ -158,5 +158,5 @@
 int main(int argc, char *argv[])
 {
-	console_event_t ev;
+	kbd_event_t ev;
 	coord_t coord;
 	bool new_file;
@@ -164,5 +164,5 @@
 	spt_t pt;
 
-	con = fphone(stdout);
+	con = console_init(stdin, stdout);
 	console_clear(con);
 
@@ -219,5 +219,5 @@
 
 	while (!done) {
-		console_get_event(con, &ev);
+		console_get_kbd_event(con, &ev);
 		pane.rflags = 0;
 
@@ -277,5 +277,5 @@
 
 /** Handle key without modifier. */
-static void key_handle_unmod(console_event_t const *ev)
+static void key_handle_unmod(kbd_event_t const *ev)
 {
 	switch (ev->key) {
@@ -320,5 +320,5 @@
 
 /** Handle Shift-key combination. */
-static void key_handle_shift(console_event_t const *ev)
+static void key_handle_shift(kbd_event_t const *ev)
 {
 	switch (ev->key) {
@@ -344,5 +344,5 @@
 
 /** Handle Ctrl-key combination. */
-static void key_handle_ctrl(console_event_t const *ev)
+static void key_handle_ctrl(kbd_event_t const *ev)
 {
 	switch (ev->key) {
@@ -497,5 +497,5 @@
 static char *filename_prompt(char const *prompt, char const *init_value)
 {
-	console_event_t ev;
+	kbd_event_t ev;
 	char *str;
 	wchar_t buffer[INFNAME_MAX_LEN + 1];
@@ -517,5 +517,5 @@
 
 	while (!done) {
-		console_get_event(con, &ev);
+		console_get_kbd_event(con, &ev);
 
 		if (ev.type == KEY_PRESS) {
@@ -531,5 +531,5 @@
 					if (nc > 0) {
 						putchar('\b');
-						fflush(stdout);
+						console_flush(con);
 						--nc;
 					}
@@ -541,5 +541,5 @@
 					if (ev.c >= 32 && nc < max_len) {
 						putchar(ev.c);
-						fflush(stdout);
+						console_flush(con);
 						buffer[nc++] = ev.c;
 					}
@@ -689,5 +689,5 @@
 		for (j = 0; j < scr_columns; ++j)
 			putchar(' ');
-		fflush(stdout);
+		console_flush(con);
 	}
 
@@ -757,7 +757,7 @@
 		if (coord_cmp(&csel_start, &rbc) <= 0 &&
 		    coord_cmp(&rbc, &csel_end) < 0) {
-			fflush(stdout);
+			console_flush(con);
 			console_set_style(con, STYLE_SELECTED);
-			fflush(stdout);
+			console_flush(con);
 		}
 
@@ -768,13 +768,13 @@
 		while (pos < size) {
 			if ((csel_start.row == rbc.row) && (csel_start.column == s_column)) {
-				fflush(stdout);
+				console_flush(con);
 				console_set_style(con, STYLE_SELECTED);
-				fflush(stdout);
+				console_flush(con);
 			}
 	
 			if ((csel_end.row == rbc.row) && (csel_end.column == s_column)) {
-				fflush(stdout);
+				console_flush(con);
 				console_set_style(con, STYLE_NORMAL);
-				fflush(stdout);
+				console_flush(con);
 			}
 	
@@ -794,7 +794,7 @@
 
 		if ((csel_end.row == rbc.row) && (csel_end.column == s_column)) {
-			fflush(stdout);
+			console_flush(con);
 			console_set_style(con, STYLE_NORMAL);
-			fflush(stdout);
+			console_flush(con);
 		}
 
@@ -808,5 +808,5 @@
 		for (j = 0; j < fill; ++j)
 			putchar(' ');
-		fflush(stdout);
+		console_flush(con);
 		console_set_style(con, STYLE_NORMAL);
 	}
@@ -833,5 +833,5 @@
 	int pos = scr_columns - 1 - n;
 	printf("%*s", pos, "");
-	fflush(stdout);
+	console_flush(con);
 	console_set_style(con, STYLE_NORMAL);
 
@@ -1158,5 +1158,5 @@
 	int pos = -(scr_columns - 3);
 	printf(" %*s ", pos, str);
-	fflush(stdout);
+	console_flush(con);
 	console_set_style(con, STYLE_NORMAL);
 
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/init/init.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -176,24 +176,19 @@
 static void console(const char *dev)
 {
-	char hid_in[DEVMAP_NAME_MAXLEN];
-	int rc;
-	
-	snprintf(hid_in, DEVMAP_NAME_MAXLEN, "%s/%s", DEVFS_MOUNT_POINT, dev);
-	
-	printf("%s: Spawning %s %s\n", NAME, SRV_CONSOLE, hid_in);
+	printf("%s: Spawning %s %s\n", NAME, SRV_CONSOLE, dev);
 	
 	/* Wait for the input device to be ready */
 	devmap_handle_t handle;
-	rc = devmap_device_get_handle(dev, &handle, IPC_FLAG_BLOCKING);
-	if (rc != EOK) {
-		printf("%s: Error waiting on %s (%s)\n", NAME, hid_in,
-		    str_error(rc));
-		return;
-	}
-	
-	rc = task_spawnl(NULL, SRV_CONSOLE, SRV_CONSOLE, hid_in, NULL);
+	int rc = devmap_device_get_handle(dev, &handle, IPC_FLAG_BLOCKING);
+	if (rc != EOK) {
+		printf("%s: Error waiting on %s (%s)\n", NAME, dev,
+		    str_error(rc));
+		return;
+	}
+	
+	rc = task_spawnl(NULL, SRV_CONSOLE, SRV_CONSOLE, dev, NULL);
 	if (rc != EOK) {
 		printf("%s: Error spawning %s %s (%s)\n", NAME, SRV_CONSOLE,
-		    hid_in, str_error(rc));
+		    dev, str_error(rc));
 	}
 }
Index: uspace/app/mkbd/main.c
===================================================================
--- uspace/app/mkbd/main.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/mkbd/main.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -45,6 +45,4 @@
 #include <devmap.h>
 #include <usb/dev/hub.h>
-//#include <usb/host.h>
-//#include <usb/driver.h>
 #include <usb/hid/iface.h>
 #include <usb/dev/pipes.h>
@@ -58,12 +56,12 @@
 #define NAME "mkbd"
 
-static int dev_phone = -1;
-
-static int initialize_report_parser(int dev_phone, usb_hid_report_t **report)
-{
-	*report = (usb_hid_report_t *)malloc(sizeof(usb_hid_report_t));
-	if (*report == NULL) {
-		return ENOMEM;
-	}
+static async_sess_t *dev_sess = NULL;
+
+static int initialize_report_parser(async_sess_t *dev_sess,
+    usb_hid_report_t **report)
+{
+	*report = (usb_hid_report_t *) malloc(sizeof(usb_hid_report_t));
+	if (*report == NULL)
+		return ENOMEM;
 	
 	int rc = usb_hid_report_init(*report);
@@ -71,16 +69,14 @@
 		usb_hid_free_report(*report);
 		*report = NULL;
-		//printf("usb_hid_report_init() failed.\n");
-		return rc;
-	}
-	
-	// get the report descriptor length from the device
+		return rc;
+	}
+	
+	/* Get the report descriptor length from the device */
 	size_t report_desc_size;
-	rc = usbhid_dev_get_report_descriptor_length(
-	    dev_phone, &report_desc_size);
-	if (rc != EOK) {
-		usb_hid_free_report(*report);
-		*report = NULL;
-		//printf("usbhid_dev_get_report_descriptor_length() failed.\n");
+	rc = usbhid_dev_get_report_descriptor_length(dev_sess,
+	    &report_desc_size);
+	if (rc != EOK) {
+		usb_hid_free_report(*report);
+		*report = NULL;
 		return rc;
 	}
@@ -89,9 +85,9 @@
 		usb_hid_free_report(*report);
 		*report = NULL;
-		//printf("usbhid_dev_get_report_descriptor_length() returned 0.\n");
-		return EINVAL;	// TODO: other error code?
-	}
-	
-	uint8_t *desc = (uint8_t *)malloc(report_desc_size);
+		// TODO: other error code?
+		return EINVAL;
+	}
+	
+	uint8_t *desc = (uint8_t *) malloc(report_desc_size);
 	if (desc == NULL) {
 		usb_hid_free_report(*report);
@@ -100,7 +96,7 @@
 	}
 	
-	// get the report descriptor from the device
+	/* Get the report descriptor from the device */
 	size_t actual_size;
-	rc = usbhid_dev_get_report_descriptor(dev_phone, desc, report_desc_size,
+	rc = usbhid_dev_get_report_descriptor(dev_sess, desc, report_desc_size,
 	    &actual_size);
 	if (rc != EOK) {
@@ -108,5 +104,4 @@
 		*report = NULL;
 		free(desc);
-		//printf("usbhid_dev_get_report_descriptor() failed.\n");
 		return rc;
 	}
@@ -116,10 +111,9 @@
 		*report = NULL;
 		free(desc);
-//		printf("usbhid_dev_get_report_descriptor() returned wrong size:"
-//		    " %zu, expected: %zu.\n", actual_size, report_desc_size);
-		return EINVAL;	// TODO: other error code?
-	}
-	
-	// initialize the report parser
+		// TODO: other error code?
+		return EINVAL;
+	}
+	
+	/* Initialize the report parser */
 	
 	rc = usb_hid_parse_report_descriptor(*report, desc, report_desc_size);
@@ -128,5 +122,4 @@
 	if (rc != EOK) {
 		free(desc);
-//		printf("usb_hid_parse_report_descriptor() failed.\n");
 		return rc;
 	}
@@ -140,17 +133,8 @@
 	assert(report != NULL);
 	
-//	printf("Calling usb_hid_parse_report() with size %zu and "
-//	    "buffer: \n", size);
-//	for (size_t i = 0; i < size; ++i) {
-//		printf(" %X ", buffer[i]);
-//	}
-//	printf("\n");
-	
 	uint8_t report_id;
 	int rc = usb_hid_parse_report(report, buffer, size, &report_id);
-	if (rc != EOK) {
-//		printf("Error parsing report: %s\n", str_error(rc));
+	if (rc != EOK)
 		return;
-	}
 	
 	usb_hid_report_path_t *path = usb_hid_report_path();
@@ -164,13 +148,9 @@
 
 	usb_hid_report_field_t *field = usb_hid_report_get_sibling(
-	    report, NULL, path, USB_HID_PATH_COMPARE_END 
-	    | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
+	    report, NULL, path, USB_HID_PATH_COMPARE_END
+	    | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
 	    USB_HID_REPORT_TYPE_INPUT);
 	
-//	printf("Field: %p\n", field);
-	
 	while (field != NULL) {
-//		printf("Field usage: %u, field value: %d\n", field->usage, 
-//		    field->value);
 		if (field->value != 0) {
 			const char *key_str = 
@@ -183,5 +163,4 @@
 		    | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
 		    USB_HID_REPORT_TYPE_INPUT);
-//		printf("Next field: %p\n", field);
 	}
 	
@@ -194,9 +173,7 @@
 {
 #define _INDENT "      "
-
-       printf(NAME ": Print out what multimedia keys were pressed.\n\n");
-       printf("Usage: %s device\n", app_name);
-       printf(_INDENT "The device is a devman path to the device.\n");
-
+	printf(NAME ": Print out what multimedia keys were pressed.\n\n");
+	printf("Usage: %s device\n", app_name);
+	printf(_INDENT "The device is a devman path to the device.\n");
 #undef _OPTION
 #undef _INDENT
@@ -223,13 +200,13 @@
 	}
 	
-	rc = devman_device_connect(dev_handle, 0);
-	if (rc < 0) {
+	async_sess_t *sess = devman_device_connect(EXCHANGE_SERIALIZE,
+	    dev_handle, 0);
+	if (!sess) {
 		printf(NAME ": failed to connect to the device (handle %"
-		       PRIun "): %s.\n", dev_handle, str_error(rc));
-		return rc;
-	}
-	
-	dev_phone = rc;
-//	printf("Got phone to the device: %d\n", dev_phone);
+		       PRIun "): %s.\n", dev_handle, str_error(errno));
+		return errno;
+	}
+	
+	dev_sess = sess;
 	
 	char path[MAX_PATH_LENGTH];
@@ -243,5 +220,5 @@
 	
 	usb_hid_report_t *report = NULL;
-	rc = initialize_report_parser(dev_phone, &report);
+	rc = initialize_report_parser(dev_sess, &report);
 	if (rc != EOK) {
 		printf("Failed to initialize report parser: %s\n",
@@ -253,5 +230,5 @@
 	
 	size_t size;
-	rc = usbhid_dev_get_event_length(dev_phone, &size);
+	rc = usbhid_dev_get_event_length(dev_sess, &size);
 	if (rc != EOK) {
 		printf("Failed to get event length: %s.\n", str_error(rc));
@@ -259,25 +236,19 @@
 	}
 	
-//	printf("Event length: %zu\n", size);
 	uint8_t *event = (uint8_t *)malloc(size);
 	if (event == NULL) {
-		// hangup phone?
-		return ENOMEM;
-	}
-	
-//	printf("Event length: %zu\n", size);
+		// TODO: hangup phone?
+		return ENOMEM;
+	}
 	
 	size_t actual_size;
 	int event_nr;
 	
-	while (1) {
-		// get event from the driver
-//		printf("Getting event from the driver.\n");
-		
+	while (true) {
 		/** @todo Try blocking call. */
-		rc = usbhid_dev_get_event(dev_phone, event, size, &actual_size, 
+		rc = usbhid_dev_get_event(dev_sess, event, size, &actual_size, 
 		    &event_nr, 0);
 		if (rc != EOK) {
-			// hangup phone?
+			// TODO: hangup phone?
 			printf("Error in getting event from the HID driver:"
 			    "%s.\n", str_error(rc));
@@ -285,9 +256,4 @@
 		}
 		
-//		printf("Got buffer: %p, size: %zu, max size: %zu\n", event, 
-//		    actual_size, size);
-		
-//		printf("Event number: %d, my actual event: %d\n", event_nr, 
-//		    act_event);
 		if (event_nr > act_event) {
 			print_key(event, size, report);
@@ -301,5 +267,4 @@
 }
 
-
 /** @}
  */
Index: uspace/app/mkfat/mkfat.c
===================================================================
--- uspace/app/mkfat/mkfat.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/mkfat/mkfat.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -144,5 +144,5 @@
 	}
 
-	rc = block_init(handle, 2048);
+	rc = block_init(EXCHANGE_SERIALIZE, handle, 2048);
 	if (rc != EOK)  {
 		printf(NAME ": Error initializing libblock.\n");
Index: uspace/app/ping/ping.c
===================================================================
--- uspace/app/ping/ping.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/ping/ping.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -36,4 +36,5 @@
 
 #include <async.h>
+#include <async_obsolete.h>
 #include <stdio.h>
 #include <str.h>
@@ -355,5 +356,5 @@
 			    str_error(ret));
 			
-			async_hangup(icmp_phone);
+			async_obsolete_hangup(icmp_phone);
 			return ret;
 		}
@@ -370,5 +371,5 @@
 			    str_error(ret));
 			
-			async_hangup(icmp_phone);
+			async_obsolete_hangup(icmp_phone);
 			return ret;
 		}
@@ -390,5 +391,5 @@
 	}
 	
-	async_hangup(icmp_phone);
+	async_obsolete_hangup(icmp_phone);
 	
 	return 0;
Index: uspace/app/taskdump/elf_core.c
===================================================================
--- uspace/app/taskdump/elf_core.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/taskdump/elf_core.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -62,7 +62,7 @@
 #include "include/elf_core.h"
 
-static off64_t align_foff_up(off64_t foff, uintptr_t vaddr, size_t page_size);
-static int write_all(int fd, void *data, size_t len);
-static int write_mem_area(int fd, as_area_info_t *area, int phoneid);
+static off64_t align_foff_up(off64_t, uintptr_t, size_t);
+static int write_all(int, void *, size_t);
+static int write_mem_area(int, as_area_info_t *, async_sess_t *);
 
 #define BUFFER_SIZE 0x1000
@@ -71,13 +71,17 @@
 /** Save ELF core file.
  *
- * @param file_name	Name of file to save to.
- * @param ainfo		Array of @a n memory area info structures.
- * @param n		Number of memory areas.
- * @param phoneid	Debugging phone.
- *
- * @return		EOK on sucess, ENOENT if file cannot be created,
- *			ENOMEM on out of memory, EIO on write error.
- */
-int elf_core_save(const char *file_name, as_area_info_t *ainfo, unsigned int n, int phoneid)
+ * @param file_name Name of file to save to.
+ * @param ainfo     Array of @a n memory area info structures.
+ * @param n         Number of memory areas.
+ * @param sess      Debugging session.
+ *
+ * @return EOK on sucess.
+ * @return ENOENT if file cannot be created.
+ * @return ENOMEM on out of memory.
+ * @return EIO on write error.
+ *
+ */
+int elf_core_save(const char *file_name, as_area_info_t *ainfo, unsigned int n,
+    async_sess_t *sess)
 {
 	elf_header_t elf_hdr;
@@ -189,5 +193,5 @@
 			return EIO;
 		}
-		if (write_mem_area(fd, &ainfo[i], phoneid) != EOK) {
+		if (write_mem_area(fd, &ainfo[i], sess) != EOK) {
 			printf("Failed writing memory data.\n");
 			free(p_hdr);
@@ -215,11 +219,12 @@
 /** Write memory area from application to core file.
  *
- * @param fd		File to write to.
- * @param area		Memory area info structure.
- * @param phoneid	Debugging phone.
- *
- * @return		EOK on success, EIO on failure.
- */
-static int write_mem_area(int fd, as_area_info_t *area, int phoneid)
+ * @param fd   File to write to.
+ * @param area Memory area info structure.
+ * @param sess Debugging session.
+ *
+ * @return EOK on success, EIO on failure.
+ *
+ */
+static int write_mem_area(int fd, as_area_info_t *area, async_sess_t *sess)
 {
 	size_t to_copy;
@@ -233,5 +238,5 @@
 	while (total < area->size) {
 		to_copy = min(area->size - total, BUFFER_SIZE);
-		rc = udebug_mem_read(phoneid, buffer, addr, to_copy);
+		rc = udebug_mem_read(sess, buffer, addr, to_copy);
 		if (rc < 0) {
 			printf("Failed reading task memory.\n");
Index: uspace/app/taskdump/include/elf_core.h
===================================================================
--- uspace/app/taskdump/include/elf_core.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/taskdump/include/elf_core.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -36,5 +36,8 @@
 #define ELF_CORE_H_
 
-int elf_core_save(const char *file_name, as_area_info_t *ainfo, unsigned int n, int phoneid);
+#include <async.h>
+
+extern int elf_core_save(const char *, as_area_info_t *, unsigned int,
+    async_sess_t *);
 
 #endif
Index: uspace/app/taskdump/taskdump.c
===================================================================
--- uspace/app/taskdump/taskdump.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/taskdump/taskdump.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -54,5 +54,5 @@
 #define LINE_BYTES 16
 
-static int phoneid;
+static async_sess_t *sess;
 static task_id_t task_id;
 static bool write_core_file;
@@ -104,6 +104,6 @@
 		printf("Failed dumping address space areas.\n");
 
-	udebug_end(phoneid);
-	async_hangup(phoneid);
+	udebug_end(sess);
+	async_hangup(sess);
 
 	return 0;
@@ -112,30 +112,27 @@
 static int connect_task(task_id_t task_id)
 {
-	int rc;
-
-	rc = async_connect_kbox(task_id);
-
-	if (rc == ENOTSUP) {
-		printf("You do not have userspace debugging support "
-		    "compiled in the kernel.\n");
-		printf("Compile kernel with 'Support for userspace debuggers' "
-		    "(CONFIG_UDEBUG) enabled.\n");
-		return rc;
-	}
-
-	if (rc < 0) {
+	async_sess_t *ksess = async_connect_kbox(task_id);
+	
+	if (!ksess) {
+		if (errno == ENOTSUP) {
+			printf("You do not have userspace debugging support "
+			    "compiled in the kernel.\n");
+			printf("Compile kernel with 'Support for userspace debuggers' "
+			    "(CONFIG_UDEBUG) enabled.\n");
+			return errno;
+		}
+		
 		printf("Error connecting\n");
-		printf("async_connect_kbox(%" PRIu64 ") -> %d ", task_id, rc);
-		return rc;
-	}
-
-	phoneid = rc;
-
-	rc = udebug_begin(phoneid);
+		printf("async_connect_kbox(%" PRIu64 ") -> %d ", task_id, errno);
+		return errno;
+	}
+	
+	int rc = udebug_begin(ksess);
 	if (rc < 0) {
 		printf("udebug_begin() -> %d\n", rc);
 		return rc;
 	}
-
+	
+	sess = ksess;
 	return 0;
 }
@@ -213,5 +210,5 @@
 
 	/* TODO: See why NULL does not work. */
-	rc = udebug_thread_read(phoneid, &dummy_buf, 0, &copied, &needed);
+	rc = udebug_thread_read(sess, &dummy_buf, 0, &copied, &needed);
 	if (rc < 0) {
 		printf("udebug_thread_read() -> %d\n", rc);
@@ -227,5 +224,5 @@
 	thash_buf = malloc(buf_size);
 
-	rc = udebug_thread_read(phoneid, thash_buf, buf_size, &copied, &needed);
+	rc = udebug_thread_read(sess, thash_buf, buf_size, &copied, &needed);
 	if (rc < 0) {
 		printf("udebug_thread_read() -> %d\n", rc);
@@ -262,5 +259,5 @@
 	int rc;
 
-	rc = udebug_areas_read(phoneid, &dummy_buf, 0, &copied, &needed);
+	rc = udebug_areas_read(sess, &dummy_buf, 0, &copied, &needed);
 	if (rc < 0) {
 		printf("udebug_areas_read() -> %d\n", rc);
@@ -271,5 +268,5 @@
 	ainfo_buf = malloc(buf_size);
 
-	rc = udebug_areas_read(phoneid, ainfo_buf, buf_size, &copied, &needed);
+	rc = udebug_areas_read(sess, ainfo_buf, buf_size, &copied, &needed);
 	if (rc < 0) {
 		printf("udebug_areas_read() -> %d\n", rc);
@@ -296,5 +293,5 @@
 	if (write_core_file) {
 		printf("Writing core file '%s'\n", core_file_name);
-		rc = elf_core_save(core_file_name, ainfo_buf, n_areas, phoneid);
+		rc = elf_core_save(core_file_name, ainfo_buf, n_areas, sess);
 		if (rc != EOK) {
 			printf("Failed writing core file.\n");
@@ -316,5 +313,5 @@
 	int rc;
 
-	rc = udebug_regs_read(phoneid, thash, &istate);
+	rc = udebug_regs_read(sess, thash, &istate);
 	if (rc < 0) {
 		printf("Failed reading registers (%d).\n", rc);
@@ -359,5 +356,5 @@
 	(void) arg;
 
-	rc = udebug_mem_read(phoneid, &data, addr, sizeof(data));
+	rc = udebug_mem_read(sess, &data, addr, sizeof(data));
 	if (rc < 0) {
 		printf("Warning: udebug_mem_read() failed.\n");
@@ -430,5 +427,5 @@
 	int rc;
 
-	rc = udebug_name_read(phoneid, &dummy_buf, 0, &copied, &needed);
+	rc = udebug_name_read(sess, &dummy_buf, 0, &copied, &needed);
 	if (rc < 0)
 		return NULL;
@@ -436,5 +433,5 @@
 	name_size = needed;
 	name = malloc(name_size + 1);
-	rc = udebug_name_read(phoneid, name, name_size, &copied, &needed);
+	rc = udebug_name_read(sess, name, name_size, &copied, &needed);
 	if (rc < 0) {
 		free(name);
Index: uspace/app/tester/console/console1.c
===================================================================
--- uspace/app/tester/console/console1.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/tester/console/console1.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -50,19 +50,21 @@
 {
 	if (!test_quiet) {
+		console_ctrl_t *console = console_init(stdin, stdout);
+		
 		printf("Style test: ");
-		fflush(stdout);
-		console_set_style(fphone(stdout), STYLE_NORMAL);
+		console_flush(console);
+		console_set_style(console, STYLE_NORMAL);
 		printf(" normal ");
-		fflush(stdout);
-		console_set_style(fphone(stdout), STYLE_EMPHASIS);
+		console_flush(console);
+		console_set_style(console, STYLE_EMPHASIS);
 		printf(" emphasized ");
-		fflush(stdout);
-		console_set_style(fphone(stdout), STYLE_INVERTED);
+		console_flush(console);
+		console_set_style(console, STYLE_INVERTED);
 		printf(" inverted ");
-		fflush(stdout);
-		console_set_style(fphone(stdout), STYLE_SELECTED);
+		console_flush(console);
+		console_set_style(console, STYLE_SELECTED);
 		printf(" selected ");
-		fflush(stdout);
-		console_set_style(fphone(stdout), STYLE_NORMAL);
+		console_flush(console);
+		console_set_style(console, STYLE_NORMAL);
 		printf("\n");
 		
@@ -73,11 +75,11 @@
 		for (j = 0; j < 2; j++) {
 			for (i = COLOR_BLACK; i <= COLOR_WHITE; i++) {
-				fflush(stdout);
-				console_set_color(fphone(stdout), i, COLOR_WHITE,
+				console_flush(console);
+				console_set_color(console, i, COLOR_WHITE,
 				    j ? CATTR_BRIGHT : 0);
 				printf(" %s ", color_name[i]);
 			}
-			fflush(stdout);
-			console_set_style(fphone(stdout), STYLE_NORMAL);
+			console_flush(console);
+			console_set_style(console, STYLE_NORMAL);
 			putchar('\n');
 		}
@@ -86,11 +88,11 @@
 		for (j = 0; j < 2; j++) {
 			for (i = COLOR_BLACK; i <= COLOR_WHITE; i++) {
-				fflush(stdout);
-				console_set_color(fphone(stdout), COLOR_WHITE, i,
+				console_flush(console);
+				console_set_color(console, COLOR_WHITE, i,
 				    j ? CATTR_BRIGHT : 0);
 				printf(" %s ", color_name[i]);
 			}
-			fflush(stdout);
-			console_set_style(fphone(stdout), STYLE_NORMAL);
+			console_flush(console);
+			console_set_style(console, STYLE_NORMAL);
 			putchar('\n');
 		}
@@ -99,28 +101,28 @@
 		
 		for (i = 0; i < 255; i += 16) {
-			fflush(stdout);
-			console_set_rgb_color(fphone(stdout), (255 - i) << 16, i << 16);
+			console_flush(console);
+			console_set_rgb_color(console, (255 - i) << 16, i << 16);
 			putchar('X');
 		}
-		fflush(stdout);
-		console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
+		console_flush(console);
+		console_set_color(console, COLOR_BLACK, COLOR_WHITE, 0);
 		putchar('\n');
 		
 		for (i = 0; i < 255; i += 16) {
-			fflush(stdout);
-			console_set_rgb_color(fphone(stdout), (255 - i) << 8, i << 8);
+			console_flush(console);
+			console_set_rgb_color(console, (255 - i) << 8, i << 8);
 			putchar('X');
 		}
-		fflush(stdout);
-		console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
+		console_flush(console);
+		console_set_color(console, COLOR_BLACK, COLOR_WHITE, 0);
 		putchar('\n');
 		
 		for (i = 0; i < 255; i += 16) {
-			fflush(stdout);
-			console_set_rgb_color(fphone(stdout), 255 - i, i);
+			console_flush(console);
+			console_set_rgb_color(console, 255 - i, i);
 			putchar('X');
 		}
-		fflush(stdout);
-		console_set_style(fphone(stdout), STYLE_NORMAL);
+		console_flush(console);
+		console_set_style(console, STYLE_NORMAL);
 		putchar('\n');
 	}
Index: uspace/app/tester/devs/devman2.c
===================================================================
--- uspace/app/tester/devs/devman2.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/tester/devs/devman2.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -42,5 +42,7 @@
 #include <devman.h>
 #include <str.h>
+#include <async.h>
 #include <vfs/vfs.h>
+#include <vfs/vfs_sess.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -68,13 +70,13 @@
 			continue;
 		}
-		int phone = fd_phone(fd);
+		async_sess_t *sess = fd_session(EXCHANGE_SERIALIZE, fd);
 		close(fd);
-		if (phone < 0) {
-			TPRINTF("Failed opening phone: %s.\n", str_error(phone));
-			rc = phone;
+		if (sess == NULL) {
+			TPRINTF("Failed opening phone: %s.\n", str_error(errno));
+			rc = errno;
 			err_msg = "Failed opening file descriptor phone";
 			continue;
 		}
-		async_hangup(phone);
+		async_hangup(sess);
 		TPRINTF("Path `%s' okay.\n", path);
 		free(path);
@@ -83,8 +85,7 @@
 	}
 	
-	if (path != NULL) {
+	if (path != NULL)
 		free(path);
-	}
-
+	
 	return err_msg;
 }
Index: uspace/app/tester/hw/misc/virtchar1.c
===================================================================
--- uspace/app/tester/hw/misc/virtchar1.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/tester/hw/misc/virtchar1.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -43,4 +43,5 @@
 #include <str.h>
 #include <vfs/vfs.h>
+#include <vfs/vfs_sess.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -66,17 +67,17 @@
 	TPRINTF("   ...file handle %d\n", fd);
 
-	TPRINTF(" Asking for phone...\n");
-	int phone = fd_phone(fd);
-	if (phone < 0) {
+	TPRINTF(" Asking for session...\n");
+	async_sess_t *sess = fd_session(EXCHANGE_SERIALIZE, fd);
+	if (!sess) {
 		close(fd);
-		TPRINTF("   ...error: %s\n", str_error(phone));
-		return "Failed to get phone to device";
+		TPRINTF("   ...error: %s\n", str_error(errno));
+		return "Failed to get session to device";
 	}
-	TPRINTF("   ...phone is %d\n", phone);
+	TPRINTF("   ...session is %p\n", sess);
 	
 	TPRINTF(" Will try to read...\n");
 	size_t i;
 	char buffer[BUFFER_SIZE];
-	char_dev_read(phone, buffer, BUFFER_SIZE);
+	char_dev_read(sess, buffer, BUFFER_SIZE);
 	TPRINTF(" ...verifying that we read zeroes only...\n");
 	for (i = 0; i < BUFFER_SIZE; i++) {
@@ -88,6 +89,6 @@
 	
 	/* Clean-up. */
-	TPRINTF(" Closing phones and file descriptors\n");
-	async_hangup(phone);
+	TPRINTF(" Closing session and file descriptor\n");
+	async_hangup(sess);
 	close(fd);
 	
Index: uspace/app/tester/hw/serial/serial1.c
===================================================================
--- uspace/app/tester/hw/serial/serial1.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/tester/hw/serial/serial1.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -71,22 +71,18 @@
 		}
 	
-	int res = devman_get_phone(DEVMAN_CLIENT, IPC_FLAG_BLOCKING);
-	
 	devman_handle_t handle;
-	res = devman_device_get_handle("/hw/pci0/00:01.0/com1/a", &handle,
+	int res = devman_device_get_handle("/hw/pci0/00:01.0/com1/a", &handle,
 	    IPC_FLAG_BLOCKING);
 	if (res != EOK)
 		return "Could not get serial device handle";
 	
-	int phone = devman_device_connect(handle, IPC_FLAG_BLOCKING);
-	if (phone < 0) {
-		devman_hangup_phone(DEVMAN_CLIENT);
+	async_sess_t *sess = devman_device_connect(EXCHANGE_SERIALIZE, handle,
+	    IPC_FLAG_BLOCKING);
+	if (!sess)
 		return "Unable to connect to serial device";
-	}
 	
 	char *buf = (char *) malloc(cnt + 1);
 	if (buf == NULL) {
-		async_hangup(phone);
-		devman_hangup_phone(DEVMAN_CLIENT);
+		async_hangup(sess);
 		return "Failed to allocate input buffer";
 	}
@@ -97,19 +93,23 @@
 	sysarg_t old_word_size;
 	
-	res = async_req_0_4(phone, SERIAL_GET_COM_PROPS, &old_baud,
+	async_exch_t *exch = async_exchange_begin(sess);
+	res = async_req_0_4(exch, SERIAL_GET_COM_PROPS, &old_baud,
 	    &old_par, &old_word_size, &old_stop);
+	async_exchange_end(exch);
+	
 	if (res != EOK) {
 		free(buf);
-		async_hangup(phone);
-		devman_hangup_phone(DEVMAN_CLIENT);
+		async_hangup(sess);
 		return "Failed to get old serial communication parameters";
 	}
 	
-	res = async_req_4_0(phone, SERIAL_SET_COM_PROPS, 1200,
+	exch = async_exchange_begin(sess);
+	res = async_req_4_0(exch, SERIAL_SET_COM_PROPS, 1200,
 	    SERIAL_NO_PARITY, 8, 1);
+	async_exchange_end(exch);
+	
 	if (EOK != res) {
 		free(buf);
-		async_hangup(phone);
-		devman_hangup_phone(DEVMAN_CLIENT);
+		async_hangup(sess);
 		return "Failed to set serial communication parameters";
 	}
@@ -120,21 +120,25 @@
 	size_t total = 0;
 	while (total < cnt) {
-		ssize_t read = char_dev_read(phone, buf, cnt - total);
+		ssize_t read = char_dev_read(sess, buf, cnt - total);
 		
 		if (read < 0) {
-			async_req_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
+			exch = async_exchange_begin(sess);
+			async_req_4_0(exch, SERIAL_SET_COM_PROPS, old_baud,
 			    old_par, old_word_size, old_stop);
+			async_exchange_end(exch);
+			
 			free(buf);
-			async_hangup(phone);
-			devman_hangup_phone(DEVMAN_CLIENT);
+			async_hangup(sess);
 			return "Failed read from serial device";
 		}
 		
 		if ((size_t) read > cnt - total) {
-			async_req_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
+			exch = async_exchange_begin(sess);
+			async_req_4_0(exch, SERIAL_SET_COM_PROPS, old_baud,
 			    old_par, old_word_size, old_stop);
+			async_exchange_end(exch);
+			
 			free(buf);
-			async_hangup(phone);
-			devman_hangup_phone(DEVMAN_CLIENT);
+			async_hangup(sess);
 			return "Read more data than expected";
 		}
@@ -151,21 +155,25 @@
 			 * direction of data transfer.
 			 */
-			ssize_t written = char_dev_write(phone, buf, read);
+			ssize_t written = char_dev_write(sess, buf, read);
 			
 			if (written < 0) {
-				async_req_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
+				exch = async_exchange_begin(sess);
+				async_req_4_0(exch, SERIAL_SET_COM_PROPS, old_baud,
 				    old_par, old_word_size, old_stop);
+				async_exchange_end(exch);
+				
 				free(buf);
-				async_hangup(phone);
-				devman_hangup_phone(DEVMAN_CLIENT);
+				async_hangup(sess);
 				return "Failed write to serial device";
 			}
 			
 			if (written != read) {
-				async_req_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
+				exch = async_exchange_begin(sess);
+				async_req_4_0(exch, SERIAL_SET_COM_PROPS, old_baud,
 				    old_par, old_word_size, old_stop);
+				async_exchange_end(exch);
+				
 				free(buf);
-				async_hangup(phone);
-				devman_hangup_phone(DEVMAN_CLIENT);
+				async_hangup(sess);
 				return "Written less data than read from serial device";
 			}
@@ -180,11 +188,13 @@
 	
 	size_t eot_size = str_size(EOT);
-	ssize_t written = char_dev_write(phone, (void *) EOT, eot_size);
-	
-	async_req_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
+	ssize_t written = char_dev_write(sess, (void *) EOT, eot_size);
+	
+	exch = async_exchange_begin(sess);
+	async_req_4_0(exch, SERIAL_SET_COM_PROPS, old_baud,
 	    old_par, old_word_size, old_stop);
+	async_exchange_end(exch);
+	
 	free(buf);
-	async_hangup(phone);
-	devman_hangup_phone(DEVMAN_CLIENT);
+	async_hangup(sess);
 	
 	if (written < 0)
Index: uspace/app/tester/ipc/ping_pong.c
===================================================================
--- uspace/app/tester/ipc/ping_pong.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/tester/ipc/ping_pong.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -30,5 +30,5 @@
 #include <stdlib.h>
 #include <sys/time.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <async.h>
 #include <errno.h>
@@ -61,5 +61,5 @@
 		size_t i;
 		for (i = 0; i < COUNT_GRANULARITY; i++) {
-			int retval = async_req_0_0(PHONE_NS, NS_PING);
+			int retval = ns_ping();
 			
 			if (retval != EOK) {
Index: uspace/app/tetris/Makefile
===================================================================
--- uspace/app/tetris/Makefile	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/tetris/Makefile	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -34,5 +34,4 @@
 	shapes.c \
 	scores.c \
-	input.c \
 	tetris.c \
 	screen.c
Index: uspace/app/tetris/input.c
===================================================================
--- uspace/app/tetris/input.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ 	(revision )
@@ -1,197 +1,0 @@
-/*	$OpenBSD: input.c,v 1.12 2005/04/13 02:33:08 deraadt Exp $	*/
-/*    $NetBSD: input.c,v 1.3 1996/02/06 22:47:33 jtc Exp $    */
-
-/*-
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek and Darren F. Provine.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- *	@(#)input.c	8.1 (Berkeley) 5/31/93
- */
-
-/** @addtogroup tetris
- * @{
- */
-/** @file
- */
-
-/*
- * Tetris input.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <stdio.h>
-
-#include <errno.h>
-#include <unistd.h>
-#include <str.h>
-
-#include "input.h"
-#include "tetris.h"
-
-#include <async.h>
-#include <vfs/vfs.h>
-#include <io/console.h>
-#include <ipc/console.h>
-
-/* return true iff the given timeval is positive */
-#define	TV_POS(tv) \
-	((tv)->tv_sec > 0 || ((tv)->tv_sec == 0 && (tv)->tv_usec > 0))
-
-/* subtract timeval `sub' from `res' */
-#define	TV_SUB(res, sub) \
-	(res)->tv_sec -= (sub)->tv_sec; \
-	(res)->tv_usec -= (sub)->tv_usec; \
-	if ((res)->tv_usec < 0) { \
-		(res)->tv_usec += 1000000; \
-		(res)->tv_sec--; \
-	}
-
-/* We will use a hack here - if lastchar is non-zero, it is
- * the last character read. We will somehow simulate the select
- * semantics.
- */
-static aid_t getchar_inprog = 0;
-static char lastchar = '\0';
-
-/*
- * Do a `read wait': select for reading from stdin, with timeout *tvp.
- * On return, modify *tvp to reflect the amount of time spent waiting.
- * It will be positive only if input appeared before the time ran out;
- * otherwise it will be zero or perhaps negative.
- *
- * If tvp is nil, wait forever, but return if select is interrupted.
- *
- * Return 0 => no input, 1 => can read() from stdin
- *
- */
-int rwait(struct timeval *tvp)
-{
-	struct timeval starttv, endtv, *s;
-	static ipc_call_t charcall;
-	sysarg_t rc;
-	
-	/*
-	 * Someday, select() will do this for us.
-	 * Just in case that day is now, and no one has
-	 * changed this, we use a temporary.
-	 */
-	if (tvp) {
-		(void) gettimeofday(&starttv, NULL);
-		endtv = *tvp;
-		s = &endtv;
-	} else
-		s = NULL;
-	
-	if (!lastchar) {
-again:
-		if (!getchar_inprog) {
-			getchar_inprog = async_send_0(fphone(stdin),
-			    CONSOLE_GET_EVENT, &charcall);
-		}
-		
-		if (!s)
-			async_wait_for(getchar_inprog, &rc);
-		else if (async_wait_timeout(getchar_inprog, &rc, s->tv_usec) == ETIMEOUT) {
-			tvp->tv_sec = 0;
-			tvp->tv_usec = 0;
-			return (0);
-		}
-		
-		getchar_inprog = 0;
-		if (rc)
-			stop("end of file, help");
-		
-		if (IPC_GET_ARG1(charcall) == KEY_RELEASE)
-			goto again;
-		
-		lastchar = IPC_GET_ARG4(charcall);
-	}
-	
-	if (tvp) {
-		/* since there is input, we may not have timed out */
-		(void) gettimeofday(&endtv, NULL);
-		TV_SUB(&endtv, &starttv);
-		TV_SUB(tvp, &endtv);  /* adjust *tvp by elapsed time */
-	}
-	
-	return 1;
-}
-
-/*
- * `sleep' for the current turn time (using select).
- * Eat any input that might be available.
- */
-void tsleep(void)
-{
-	struct timeval tv;
-	
-	tv.tv_sec = 0;
-	tv.tv_usec = fallrate;
-	while (TV_POS(&tv))
-		if (rwait(&tv)) {
-			lastchar = '\0';
-		} else
-			break;
-}
-
-/*
- * getchar with timeout.
- */
-int tgetchar(void)
-{
-	static struct timeval timeleft;
-	char c;
-	
-	/*
-	 * Reset timeleft to fallrate whenever it is not positive.
-	 * In any case, wait to see if there is any input.  If so,
-	 * take it, and update timeleft so that the next call to
-	 * tgetchar() will not wait as long.  If there is no input,
-	 * make timeleft zero or negative, and return -1.
-	 *
-	 * Most of the hard work is done by rwait().
-	 */
-	if (!TV_POS(&timeleft)) {
-		faster();  /* go faster */
-		timeleft.tv_sec = 0;
-		timeleft.tv_usec = fallrate;
-	}
-	
-	if (!rwait(&timeleft))
-		return -1;
-	
-	c = lastchar;
-	lastchar = '\0';
-	return ((int) (unsigned char) c);
-}
-
-/** @}
- */
Index: uspace/app/tetris/input.h
===================================================================
--- uspace/app/tetris/input.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*	$OpenBSD: input.h,v 1.5 2003/06/03 03:01:41 millert Exp $	*/
-/*	$NetBSD: input.h,v 1.2 1995/04/22 07:42:36 cgd Exp $	*/
-
-/*-
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek and Darren F. Provine.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- *	@(#)input.h	8.1 (Berkeley) 5/31/93
- */
-
-/** @addtogroup tetris
- * @{
- */
-/** @file
- */
-
-extern int rwait(struct timeval *);
-extern int tgetchar(void);
-extern void tsleep(void);
-
-/** @}
- */
Index: uspace/app/tetris/scores.c
===================================================================
--- uspace/app/tetris/scores.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/tetris/scores.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -1,37 +1,45 @@
-/*	$OpenBSD: scores.c,v 1.11 2006/04/20 03:25:36 ray Exp $	*/
-/*	$NetBSD: scores.c,v 1.2 1995/04/22 07:42:38 cgd Exp $	*/
-
-/*-
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek and Darren F. Provine.
+/*
+ * Copyright (c) 2011 Martin Decky
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- *	@(#)scores.c	8.1 (Berkeley) 5/31/93
+ *
+ * - 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.
+ */
+
+/** Attributations
+ *
+ * scores.c 8.1 (Berkeley) 5/31/93
+ * NetBSD: scores.c,v 1.2 1995/04/22 07:42:38 cgd
+ * OpenBSD: scores.c,v 1.11 2006/04/20 03:25:36 ray
+ *
+ * Based upon BSD Tetris
+ *
+ * Copyright (c) 1992, 1993
+ *      The Regents of the University of California.
+ *      Distributed under BSD license.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
  */
 
@@ -60,5 +68,4 @@
 #include <err.h>
 #include <time.h>
-
 #include "screen.h"
 #include "tetris.h"
@@ -118,5 +125,5 @@
 	int j;
 	size_t off;
-	console_event_t ev;
+	kbd_event_t ev;
 	
 	clear_screen();
@@ -133,6 +140,6 @@
 	
 	while (1) {
-		fflush(stdout);
-		if (!console_get_event(fphone(stdin), &ev))
+		console_flush(console);
+		if (!console_get_kbd_event(console, &ev))
 			exit(1);
 		
Index: uspace/app/tetris/scores.h
===================================================================
--- uspace/app/tetris/scores.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/tetris/scores.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -1,37 +1,45 @@
-/*	$OpenBSD: scores.h,v 1.5 2003/06/03 03:01:41 millert Exp $	*/
-/*	$NetBSD: scores.h,v 1.2 1995/04/22 07:42:40 cgd Exp $	*/
+/*
+ * Copyright (c) 2011 Martin Decky
+ * 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.
+ */
 
-/*-
+/** Attributations
+ *
+ * scores.h 8.1 (Berkeley) 5/31/93
+ * NetBSD: scores.h,v 1.2 1995/04/22 07:42:40 cgd
+ * OpenBSD: scores.h,v 1.5 2003/06/03 03:01:41 millert
+ *
+ * Based upon BSD Tetris
+ *
  * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
+ *      The Regents of the University of California.
+ *      Distributed under BSD license.
  *
  * This code is derived from software contributed to Berkeley by
  * Chris Torek and Darren F. Provine.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- *	@(#)scores.h	8.1 (Berkeley) 5/31/93
  */
 
@@ -41,5 +49,4 @@
 /** @file
  */
-
 
 /*
Index: uspace/app/tetris/screen.c
===================================================================
--- uspace/app/tetris/screen.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/tetris/screen.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -1,37 +1,45 @@
-/*	$OpenBSD: screen.c,v 1.13 2006/04/20 03:25:36 ray Exp $	*/
-/*	$NetBSD: screen.c,v 1.4 1995/04/29 01:11:36 mycroft Exp $	*/
-
-/*-
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek and Darren F. Provine.
+/*
+ * Copyright (c) 2011 Martin Decky
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- *	@(#)screen.c	8.1 (Berkeley) 5/31/93
+ *
+ * - 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.
+ */
+
+/** Attributations
+ *
+ * screen.c 8.1 (Berkeley) 5/31/93
+ * NetBSD: screen.c,v 1.4 1995/04/29 01:11:36 mycroft
+ * OpenBSD: screen.c,v 1.13 2006/04/20 03:25:36 ray
+ *
+ * Based upon BSD Tetris
+ *
+ * Copyright (c) 1992, 1993
+ *      The Regents of the University of California.
+ *      Distributed under BSD license.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
  */
 
@@ -69,4 +77,8 @@
 static const struct shape *lastshape;
 
+static suseconds_t timeleft = 0;
+
+console_ctrl_t *console;
+
 
 /*
@@ -82,6 +94,6 @@
 static void start_standout(uint32_t color)
 {
-	fflush(stdout);
-	console_set_rgb_color(fphone(stdout), 0xffffff,
+	console_flush(console);
+	console_set_rgb_color(console, 0xffffff,
 	    use_color ? color : 0x000000);
 }
@@ -89,11 +101,11 @@
 static void resume_normal(void)
 {
-	fflush(stdout);
-	console_set_style(fphone(stdout), STYLE_NORMAL);
+	console_flush(console);
+	console_set_style(console, STYLE_NORMAL);
 }
 
 void clear_screen(void)
 {
-	console_clear(fphone(stdout));
+	console_clear(console);
 	moveto(0, 0);
 }
@@ -105,5 +117,5 @@
 {
 	resume_normal();
-	console_clear(fphone(stdout));
+	console_clear(console);
 	curscore = -1;
 	memset(curscreen, 0, sizeof(curscreen));
@@ -115,5 +127,5 @@
 void scr_init(void)
 {
-	console_cursor_visibility(fphone(stdout), 0);
+	console_cursor_visibility(console, 0);
 	resume_normal();
 	scr_clear();
@@ -122,6 +134,6 @@
 void moveto(sysarg_t r, sysarg_t c)
 {
-	fflush(stdout);
-	console_set_pos(fphone(stdout), c, r);
+	console_flush(console);
+	console_set_pos(console, c, r);
 }
 
@@ -130,5 +142,5 @@
 static int get_display_size(winsize_t *ws)
 {
-	return console_get_size(fphone(stdout), &ws->ws_col, &ws->ws_row);
+	return console_get_size(console, &ws->ws_col, &ws->ws_row);
 }
 
@@ -136,5 +148,5 @@
 {
 	sysarg_t ccap;
-	int rc = console_get_color_cap(fphone(stdout), &ccap);
+	int rc = console_get_color_cap(console, &ccap);
 	
 	if (rc != 0)
@@ -179,5 +191,5 @@
 void scr_end(void)
 {
-	console_cursor_visibility(fphone(stdout), 1);
+	console_cursor_visibility(console, 1);
 }
 
@@ -302,5 +314,5 @@
 		resume_normal();
 	
-	fflush(stdout);
+	console_flush(console);
 }
 
@@ -322,4 +334,80 @@
 }
 
+/** Sleep for the current turn time
+ *
+ * Eat any input that might be available.
+ *
+ */
+void tsleep(void)
+{
+	suseconds_t timeout = fallrate;
+	
+	while (timeout > 0) {
+		kbd_event_t event;
+		
+		if (!console_get_kbd_event_timeout(console, &event, &timeout))
+			break;
+	}
+}
+
+/** Get char with timeout
+ *
+ */
+int tgetchar(void)
+{
+	/*
+	 * Reset timeleft to fallrate whenever it is not positive
+	 * and increase speed.
+	 */
+	
+	if (timeleft <= 0) {
+		faster();
+		timeleft = fallrate;
+	}
+	
+	/*
+	 * Wait to see if there is any input. If so, take it and
+	 * update timeleft so that the next call to tgetchar()
+	 * will not wait as long. If there is no input,
+	 * make timeleft zero and return -1.
+	 */
+	
+	wchar_t c = 0;
+	
+	while (c == 0) {
+		kbd_event_t event;
+		
+		if (!console_get_kbd_event_timeout(console, &event, &timeleft)) {
+			timeleft = 0;
+			return -1;
+		}
+		
+		if (event.type == KEY_PRESS)
+			c = event.c;
+	}
+	
+	return (int) c;
+}
+
+/** Get char without timeout
+ *
+ */
+int twait(void)
+{
+	wchar_t c = 0;
+	
+	while (c == 0) {
+		kbd_event_t event;
+		
+		if (!console_get_kbd_event(console, &event))
+			return -1;
+		
+		if (event.type == KEY_PRESS)
+			c = event.c;
+	}
+	
+	return (int) c;
+}
+
 /** @}
  */
Index: uspace/app/tetris/screen.h
===================================================================
--- uspace/app/tetris/screen.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/tetris/screen.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -1,37 +1,45 @@
-/*	$OpenBSD: screen.h,v 1.5 2003/06/03 03:01:41 millert Exp $	*/
-/*	$NetBSD: screen.h,v 1.2 1995/04/22 07:42:42 cgd Exp $	*/
+/*
+ * Copyright (c) 2011 Martin Decky
+ * 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.
+ */
 
-/*-
+/** Attributations
+ *
+ * screen.h 8.1 (Berkeley) 5/31/93
+ * NetBSD: screen.h,v 1.2 1995/04/22 07:42:42 cgd
+ * OpenBSD: screen.h,v 1.5 2003/06/03 03:01:41 millert
+ *
+ * Based upon BSD Tetris
+ *
  * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
+ *      The Regents of the University of California.
+ *      Distributed under BSD license.
  *
  * This code is derived from software contributed to Berkeley by
  * Chris Torek and Darren F. Provine.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- *	@(#)screen.h	8.1 (Berkeley) 5/31/93
  */
 
@@ -48,4 +56,5 @@
 
 #include <sys/types.h>
+#include <io/console.h>
 #include <async.h>
 #include <bool.h>
@@ -56,4 +65,5 @@
 } winsize_t;
 
+extern console_ctrl_t *console;
 extern winsize_t winsize;
 
@@ -61,5 +71,4 @@
 extern void clear_screen(void);
 
-/* just calls putchar; for tputs */
 extern int put(int);
 extern void scr_clear(void);
@@ -70,4 +79,8 @@
 extern void scr_update(void);
 
+extern void tsleep(void);
+extern int tgetchar(void);
+extern int twait(void);
+
 /** @}
  */
Index: uspace/app/tetris/shapes.c
===================================================================
--- uspace/app/tetris/shapes.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/tetris/shapes.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -1,37 +1,45 @@
-/*	$OpenBSD: shapes.c,v 1.8 2004/07/10 07:26:24 deraadt Exp $	*/
-/*	$NetBSD: shapes.c,v 1.2 1995/04/22 07:42:44 cgd Exp $	*/
+/*
+ * Copyright (c) 2011 Martin Decky
+ * 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.
+ */
 
-/*-
+/** Attributations
+ *
+ * shapes.c 8.1 (Berkeley) 5/31/93
+ * NetBSD: shapes.c,v 1.2 1995/04/22 07:42:44 cgd
+ * OpenBSD: shapes.c,v 1.8 2004/07/10 07:26:24 deraadt
+ *
+ * Based upon BSD Tetris
+ *
  * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
+ *      The Regents of the University of California.
+ *      Distributed under BSD license.
  *
  * This code is derived from software contributed to Berkeley by
  * Chris Torek and Darren F. Provine.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- *	@(#)shapes.c	8.1 (Berkeley) 5/31/93
  */
 
Index: uspace/app/tetris/tetris.c
===================================================================
--- uspace/app/tetris/tetris.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/tetris/tetris.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -1,37 +1,45 @@
-/*	$OpenBSD: tetris.c,v 1.21 2006/04/20 03:24:12 ray Exp $	*/
-/*	$NetBSD: tetris.c,v 1.2 1995/04/22 07:42:47 cgd Exp $	*/
-
-/*-
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek and Darren F. Provine.
+/*
+ * Copyright (c) 2011 Martin Decky
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- *	@(#)tetris.c	8.1 (Berkeley) 5/31/93
+ *
+ * - 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.
+ */
+
+/** Attributations
+ *
+ * tetris.c 8.1 (Berkeley) 5/31/93
+ * NetBSD: tetris.c,v 1.2 1995/04/22 07:42:47 cgd
+ * OpenBSD: tetris.c,v 1.21 2006/04/20 03:24:12 ray
+ *
+ * Based upon BSD Tetris
+ *
+ * Copyright (c) 1992, 1993
+ *      The Regents of the University of California.
+ *      Distributed under BSD license.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
  */
 
@@ -56,6 +64,4 @@
 #include <unistd.h>
 #include <getopt.h>
-
-#include "input.h"
 #include "scores.h"
 #include "screen.h"
@@ -245,8 +251,10 @@
 	int ch;
 	
+	console = console_init(stdin, stdout);
+	
 	keys = "jkl pq";
 	
 	classic = 0;
-	showpreview = 1; 
+	showpreview = 1;
 	
 	while ((ch = getopt(argc, argv, "ck:ps")) != -1)
@@ -371,6 +379,6 @@
 					scr_msg(key_msg, 0);
 					scr_msg(msg, 1);
-					(void) fflush(stdout);
-				} while (rwait((struct timeval *) NULL) == -1);
+					console_flush(console);
+				} while (!twait());
 				
 				scr_msg(msg, 0);
Index: uspace/app/tetris/tetris.h
===================================================================
--- uspace/app/tetris/tetris.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/tetris/tetris.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -1,37 +1,45 @@
-/*	$OpenBSD: tetris.h,v 1.9 2003/06/03 03:01:41 millert Exp $	*/
-/*	$NetBSD: tetris.h,v 1.2 1995/04/22 07:42:48 cgd Exp $	*/
+/*
+ * Copyright (c) 2011 Martin Decky
+ * 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.
+ */
 
-/*-
+/** Attributations
+ *
+ * tetris.h 8.1 (Berkeley) 5/31/93
+ * NetBSD: tetris.h,v 1.2 1995/04/22 07:42:48 cgd
+ * OpenBSD: tetris.h,v 1.9 2003/06/03 03:01:41 millert
+ *
+ * Based upon BSD Tetris
+ *
  * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
+ *      The Regents of the University of California.
+ *      Distributed under BSD license.
  *
  * This code is derived from software contributed to Berkeley by
  * Chris Torek and Darren F. Provine.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- *	@(#)tetris.h	8.1 (Berkeley) 5/31/93
  */
 
Index: uspace/app/top/Makefile
===================================================================
--- uspace/app/top/Makefile	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/top/Makefile	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -33,6 +33,5 @@
 SOURCES = \
 	top.c \
-	screen.c \
-	input.c
+	screen.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/top/input.c
===================================================================
--- uspace/app/top/input.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ 	(revision )
@@ -1,200 +1,0 @@
-/*	$OpenBSD: input.c,v 1.12 2005/04/13 02:33:08 deraadt Exp $	*/
-/*    $NetBSD: input.c,v 1.3 1996/02/06 22:47:33 jtc Exp $    */
-
-/*-
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek and Darren F. Provine.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- *	@(#)input.c	8.1 (Berkeley) 5/31/93
- */
-
-/** @addtogroup top
- * @{
- */
-/** @file
- */
-
-/*
- * Top input.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <stdio.h>
-
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <str.h>
-
-#include "input.h"
-
-#include <async.h>
-#include <vfs/vfs.h>
-#include <io/console.h>
-#include <ipc/console.h>
-
-#define USEC_COUNT 1000000
-
-/* return true iff the given timeval is positive */
-#define	TV_POS(tv) \
-	((tv)->tv_sec > 0 || ((tv)->tv_sec == 0 && (tv)->tv_usec > 0))
-
-/* subtract timeval `sub' from `res' */
-#define	TV_SUB(res, sub) \
-	(res)->tv_sec -= (sub)->tv_sec; \
-	(res)->tv_usec -= (sub)->tv_usec; \
-	if ((res)->tv_usec < 0) { \
-		(res)->tv_usec += 1000000; \
-		(res)->tv_sec--; \
-	}
-
-/* We will use a hack here - if lastchar is non-zero, it is
- * the last character read. We will somehow simulate the select
- * semantics.
- */
-static aid_t getchar_inprog = 0;
-static char lastchar = '\0';
-
-/*
- * Do a `read wait': select for reading from stdin, with timeout *tvp.
- * On return, modify *tvp to reflect the amount of time spent waiting.
- * It will be positive only if input appeared before the time ran out;
- * otherwise it will be zero or perhaps negative.
- *
- * If tvp is nil, wait forever, but return if select is interrupted.
- *
- * Return 0 => no input, 1 => can read() from stdin
- *
- */
-int rwait(struct timeval *tvp)
-{
-	struct timeval starttv, endtv, *s;
-	static ipc_call_t charcall;
-	sysarg_t rc;
-	
-	/*
-	 * Someday, select() will do this for us.
-	 * Just in case that day is now, and no one has
-	 * changed this, we use a temporary.
-	 */
-	if (tvp) {
-		(void) gettimeofday(&starttv, NULL);
-		endtv = *tvp;
-		s = &endtv;
-	} else
-		s = NULL;
-	
-	if (!lastchar) {
-again:
-		if (!getchar_inprog) {
-			getchar_inprog = async_send_0(fphone(stdin),
-			    CONSOLE_GET_EVENT, &charcall);
-		}
-		
-		if (!s)
-			async_wait_for(getchar_inprog, &rc);
-		else if (async_wait_timeout(getchar_inprog, &rc, s->tv_usec) == ETIMEOUT) {
-			tvp->tv_sec = 0;
-			tvp->tv_usec = 0;
-			return (0);
-		}
-		
-		getchar_inprog = 0;
-		if (rc) {
-			printf("End of file, bug?\n");
-			exit(1);
-		}
-		
-		if (IPC_GET_ARG1(charcall) == KEY_RELEASE)
-			goto again;
-		
-		lastchar = IPC_GET_ARG4(charcall);
-	}
-	
-	if (tvp) {
-		/* since there is input, we may not have timed out */
-		(void) gettimeofday(&endtv, NULL);
-		TV_SUB(&endtv, &starttv);
-		TV_SUB(tvp, &endtv);  /* adjust *tvp by elapsed time */
-	}
-	
-	return 1;
-}
-
-/*
- * `sleep' for the current turn time (using select).
- * Eat any input that might be available.
- */
-void tsleep(unsigned int sec)
-{
-	struct timeval tv;
-	
-	tv.tv_sec = 0;
-	tv.tv_usec = sec * USEC_COUNT;
-	while (TV_POS(&tv))
-		if (rwait(&tv)) {
-			lastchar = '\0';
-		} else
-			break;
-}
-
-/*
- * getchar with timeout.
- */
-int tgetchar(unsigned int sec)
-{
-	static struct timeval timeleft;
-	char c;
-	
-	/*
-	 * Reset timeleft to USEC_COUNT whenever it is not positive.
-	 * In any case, wait to see if there is any input.  If so,
-	 * take it, and update timeleft so that the next call to
-	 * tgetchar() will not wait as long.  If there is no input,
-	 * make timeleft zero or negative, and return -1.
-	 *
-	 * Most of the hard work is done by rwait().
-	 */
-	if (!TV_POS(&timeleft)) {
-		timeleft.tv_sec = 0;
-		timeleft.tv_usec = sec * USEC_COUNT;
-	}
-	
-	if (!rwait(&timeleft))
-		return -1;
-	
-	c = lastchar;
-	lastchar = '\0';
-	return ((int) (unsigned char) c);
-}
-
-/** @}
- */
Index: uspace/app/top/input.h
===================================================================
--- uspace/app/top/input.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ 	(revision )
@@ -1,56 +1,0 @@
-/*	$OpenBSD: input.h,v 1.5 2003/06/03 03:01:41 millert Exp $	*/
-/*	$NetBSD: input.h,v 1.2 1995/04/22 07:42:36 cgd Exp $	*/
-
-/*-
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek and Darren F. Provine.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- *	@(#)input.h	8.1 (Berkeley) 5/31/93
- */
-
-/** @addtogroup top
- * @{
- */
-/** @file
- */
-
-#ifndef TOP_INPUT_
-#define TOP_INPUT_
-
-#include <sys/time.h>
-
-extern int rwait(struct timeval *);
-extern int tgetchar(unsigned int sec);
-extern void tsleep(unsigned int sec);
-
-#endif
-
-/** @}
- */
Index: uspace/app/top/screen.c
===================================================================
--- uspace/app/top/screen.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/top/screen.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -46,35 +46,40 @@
 #include "top.h"
 
+#define USEC_COUNT  1000000
+
 static sysarg_t warn_col = 0;
 static sysarg_t warn_row = 0;
+static suseconds_t timeleft = 0;
+
+console_ctrl_t *console;
 
 static void screen_style_normal(void)
 {
-	fflush(stdout);
-	console_set_style(fphone(stdout), STYLE_NORMAL);
+	console_flush(console);
+	console_set_style(console, STYLE_NORMAL);
 }
 
 static void screen_style_inverted(void)
 {
-	fflush(stdout);
-	console_set_style(fphone(stdout), STYLE_INVERTED);
+	console_flush(console);
+	console_set_style(console, STYLE_INVERTED);
 }
 
 static void screen_moveto(sysarg_t col, sysarg_t row)
 {
-	fflush(stdout);
-	console_set_pos(fphone(stdout), col, row);
+	console_flush(console);
+	console_set_pos(console, col, row);
 }
 
 static void screen_get_pos(sysarg_t *col, sysarg_t *row)
 {
-	fflush(stdout);
-	console_get_pos(fphone(stdout), col, row);
+	console_flush(console);
+	console_get_pos(console, col, row);
 }
 
 static void screen_get_size(sysarg_t *col, sysarg_t *row)
 {
-	fflush(stdout);
-	console_get_size(fphone(stdout), col, row);
+	console_flush(console);
+	console_get_size(console, col, row);
 }
 
@@ -84,6 +89,6 @@
 	
 	if (clear) {
-		fflush(stdout);
-		console_clear(fphone(stdout));
+		console_flush(console);
+		console_clear(console);
 	}
 	
@@ -111,6 +116,8 @@
 void screen_init(void)
 {
-	fflush(stdout);
-	console_cursor_visibility(fphone(stdout), false);
+	console = console_init(stdin, stdout);
+	
+	console_flush(console);
+	console_cursor_visibility(console, false);
 	
 	screen_restart(true);
@@ -121,6 +128,6 @@
 	screen_restart(true);
 	
-	fflush(stdout);
-	console_cursor_visibility(fphone(stdout), true);
+	console_flush(console);
+	console_cursor_visibility(console, true);
 }
 
@@ -508,5 +515,5 @@
 	}
 	
-	fflush(stdout);
+	console_flush(console);
 }
 
@@ -521,5 +528,41 @@
 	
 	screen_newline();
-	fflush(stdout);
+	console_flush(console);
+}
+
+/** Get char with timeout
+ *
+ */
+int tgetchar(unsigned int sec)
+{
+	/*
+	 * Reset timeleft whenever it is not positive.
+	 */
+	
+	if (timeleft <= 0)
+		timeleft = sec * USEC_COUNT;
+	
+	/*
+	 * Wait to see if there is any input. If so, take it and
+	 * update timeleft so that the next call to tgetchar()
+	 * will not wait as long. If there is no input,
+	 * make timeleft zero and return -1.
+	 */
+	
+	wchar_t c = 0;
+	
+	while (c == 0) {
+		kbd_event_t event;
+		
+		if (!console_get_kbd_event_timeout(console, &event, &timeleft)) {
+			timeleft = 0;
+			return -1;
+		}
+		
+		if (event.type == KEY_PRESS)
+			c = event.c;
+	}
+	
+	return (int) c;
 }
 
Index: uspace/app/top/screen.h
===================================================================
--- uspace/app/top/screen.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/top/screen.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -35,5 +35,8 @@
 #define TOP_SCREEN_H_
 
+#include <io/console.h>
 #include "top.h"
+
+extern console_ctrl_t *console;
 
 extern void screen_init(void);
@@ -42,4 +45,6 @@
 extern void print_warning(const char *, ...);
 
+extern int tgetchar(unsigned int);
+
 #endif
 
Index: uspace/app/top/top.c
===================================================================
--- uspace/app/top/top.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/top/top.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -46,5 +46,4 @@
 #include <sort.h>
 #include "screen.h"
-#include "input.h"
 #include "top.h"
 
Index: uspace/app/trace/ipc_desc.c
===================================================================
--- uspace/app/trace/ipc_desc.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/trace/ipc_desc.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -33,5 +33,6 @@
  */
 
-#include <ipc/common.h>
+#include <kernel/ipc/ipc.h>
+#include <kernel/ipc/ipc_methods.h>
 #include <stdlib.h>
 #include "ipc_desc.h"
@@ -39,16 +40,14 @@
 ipc_m_desc_t ipc_methods[] = {
 	/* System methods */
-	{ IPC_M_CONNECT_TO_ME,	"CONNECT_TO_ME" },
-	{ IPC_M_CONNECT_ME_TO,	"CONNECT_ME_TO" },
-	{ IPC_M_PHONE_HUNGUP,	"PHONE_HUNGUP" },
-	{ IPC_M_SHARE_OUT,	"SHARE_OUT" },
-	{ IPC_M_SHARE_IN,	"SHARE_IN" },
-	{ IPC_M_DATA_WRITE,	"DATA_WRITE" },
-	{ IPC_M_DATA_READ,	"DATA_READ" },
-	{ IPC_M_DEBUG_ALL,	"DEBUG_ALL" },
-
-	/* Well-known methods */
-	{ IPC_M_PING,		"PING" },
-
+	{ IPC_M_PHONE_HUNGUP,  "PHONE_HUNGUP" },
+	{ IPC_M_CONNECT_ME,    "CONNECT_ME" },
+	{ IPC_M_CONNECT_ME_TO, "CONNECT_ME_TO" },
+	{ IPC_M_CONNECT_TO_ME, "CONNECT_TO_ME" },
+	{ IPC_M_SHARE_OUT,     "SHARE_OUT" },
+	{ IPC_M_SHARE_IN,      "SHARE_IN" },
+	{ IPC_M_DATA_WRITE,    "DATA_WRITE" },
+	{ IPC_M_DATA_READ,     "DATA_READ" },
+	{ IPC_M_DEBUG,         "DEBUG" },
+	
 	/* Terminating entry */
 	{ 0, NULL }
Index: uspace/app/trace/ipcp.c
===================================================================
--- uspace/app/trace/ipcp.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/trace/ipcp.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -37,5 +37,5 @@
 #include <adt/hash_table.h>
 #include <sys/typefmt.h>
-
+#include <kernel/ipc/ipc_methods.h>
 #include "ipc_desc.h"
 #include "proto.h"
@@ -268,17 +268,15 @@
 	proto_t *proto;
 	int cphone;
-
+	
 	sysarg_t *resp;
 	oper_t *oper;
 	int i;
-
-//	printf("parse_answer\n");
-
+	
 	phone = pcall->phone_hash;
 	method = IPC_GET_IMETHOD(pcall->question);
 	retval = IPC_GET_RETVAL(*answer);
-
+	
 	resp = answer->args;
-
+	
 	if ((display_mask & DM_IPC) != 0) {
 		printf("Response to %p: retval=%" PRIdn ", args = (%" PRIun ", "
@@ -288,11 +286,12 @@
 		    IPC_GET_ARG4(*answer), IPC_GET_ARG5(*answer));
 	}
-
+	
 	if ((display_mask & DM_USER) != 0) {
 		oper = pcall->oper;
-
-		if (oper != NULL && (oper->rv_type != V_VOID || oper->respc > 0)) {
+		
+		if ((oper != NULL) &&
+		    ((oper->rv_type != V_VOID) || (oper->respc > 0))) {
 			printf("->");
-
+			
 			if (oper->rv_type != V_VOID) {
 				putchar(' ');
@@ -304,25 +303,29 @@
 				putchar('(');
 				for (i = 1; i <= oper->respc; ++i) {
-					if (i > 1) printf(", ");
+					if (i > 1)
+						printf(", ");
 					val_print(resp[i], oper->resp_type[i - 1]);
 				}
 				putchar(')');
 			}
-
+			
 			putchar('\n');
 		}
 	}
-
-	if (phone == 0 && method == IPC_M_CONNECT_ME_TO && retval == 0) {
+	
+	if ((phone == PHONE_NS) && (method == IPC_M_CONNECT_ME_TO) &&
+	    (retval == 0)) {
 		/* Connected to a service (through NS) */
 		service = IPC_GET_ARG1(pcall->question);
 		proto = proto_get_by_srv(service);
-		if (proto == NULL) proto = proto_unknown;
-
+		if (proto == NULL)
+			proto = proto_unknown;
+		
 		cphone = IPC_GET_ARG5(*answer);
 		if ((display_mask & DM_SYSTEM) != 0) {
 			printf("Registering connection (phone %d, protocol: %s)\n", cphone,
-		    		proto->name);
-		}
+		    proto->name);
+		}
+		
 		ipcp_connection_set(cphone, 0, proto);
 	}
@@ -334,7 +337,5 @@
 	pending_call_t *pcall;
 	unsigned long key[1];
-
-//	printf("ipcp_call_in()\n");
-
+	
 	if ((hash & IPC_CALLID_ANSWERED) == 0 && hash != IPCP_CALLID_SYNC) {
 		/* Not a response */
@@ -344,11 +345,12 @@
 		return;
 	}
-
+	
 	hash = hash & ~IPC_CALLID_ANSWERED;
 	key[0] = hash;
-
+	
 	item = hash_table_find(&pending_calls, key);
-	if (item == NULL) return; // No matching question found
-
+	if (item == NULL)
+		return; /* No matching question found */
+	
 	/*
 	 * Response matched to question.
@@ -357,5 +359,5 @@
 	pcall = hash_table_get_instance(item, pending_call_t, link);
 	hash_table_remove(&pending_calls, key, 1);
-
+	
 	parse_answer(hash, pcall, call);
 	free(pcall);
Index: uspace/app/trace/syscalls.c
===================================================================
--- uspace/app/trace/syscalls.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/trace/syscalls.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -40,4 +40,5 @@
     [SYS_KLOG] ={ "klog",				3,	V_INT_ERRNO },
     [SYS_TLS_SET] = { "tls_set",			1,	V_ERRNO },
+
     [SYS_THREAD_CREATE] = { "thread_create",		3,	V_ERRNO },
     [SYS_THREAD_EXIT] = { "thread_exit",		1,	V_ERRNO },
Index: uspace/app/trace/trace.c
===================================================================
--- uspace/app/trace/trace.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/app/trace/trace.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -72,5 +72,5 @@
 ipc_call_t thread_ipc_req[THBUF_SIZE];
 
-int phoneid;
+async_sess_t *sess;
 bool abort_trace;
 
@@ -81,5 +81,5 @@
 
 static bool cev_valid;
-static console_event_t cev;
+static kbd_event_t cev;
 
 void thread_trace_start(uintptr_t thread_hash);
@@ -146,36 +146,33 @@
 static int connect_task(task_id_t task_id)
 {
-	int rc;
-
-	rc = async_connect_kbox(task_id);
-
-	if (rc == ENOTSUP) {
-		printf("You do not have userspace debugging support "
-		    "compiled in the kernel.\n");
-		printf("Compile kernel with 'Support for userspace debuggers' "
-		    "(CONFIG_UDEBUG) enabled.\n");
-		return rc;
-	}
-
-	if (rc < 0) {
+	async_sess_t *ksess = async_connect_kbox(task_id);
+	
+	if (!ksess) {
+		if (errno == ENOTSUP) {
+			printf("You do not have userspace debugging support "
+			    "compiled in the kernel.\n");
+			printf("Compile kernel with 'Support for userspace debuggers' "
+			    "(CONFIG_UDEBUG) enabled.\n");
+			return errno;
+		}
+		
 		printf("Error connecting\n");
-		printf("ipc_connect_task(%" PRIu64 ") -> %d ", task_id, rc);
-		return rc;
-	}
-
-	phoneid = rc;
-
-	rc = udebug_begin(phoneid);
+		printf("ipc_connect_task(%" PRIu64 ") -> %d ", task_id, errno);
+		return errno;
+	}
+	
+	int rc = udebug_begin(ksess);
 	if (rc < 0) {
 		printf("udebug_begin() -> %d\n", rc);
 		return rc;
 	}
-
-	rc = udebug_set_evmask(phoneid, UDEBUG_EM_ALL);
+	
+	rc = udebug_set_evmask(ksess, UDEBUG_EM_ALL);
 	if (rc < 0) {
 		printf("udebug_set_evmask(0x%x) -> %d\n ", UDEBUG_EM_ALL, rc);
 		return rc;
 	}
-
+	
+	sess = ksess;
 	return 0;
 }
@@ -188,5 +185,5 @@
 	int i;
 
-	rc = udebug_thread_read(phoneid, thread_hash_buf,
+	rc = udebug_thread_read(sess, thread_hash_buf,
 		THBUF_SIZE*sizeof(unsigned), &tb_copied, &tb_needed);
 	if (rc < 0) {
@@ -314,5 +311,5 @@
 
 	memset(&call, 0, sizeof(call));
-	rc = udebug_mem_read(phoneid, &call.args, sc_args[1], sizeof(call.args));
+	rc = udebug_mem_read(sess, &call.args, sc_args[1], sizeof(call.args));
 
 	if (rc >= 0) {
@@ -325,8 +322,7 @@
 	ipc_call_t question, reply;
 	int rc;
-	int phoneidx;
-
-//	printf("sc_ipc_call_sync_fast()\n");
-	phoneidx = sc_args[0];
+	int phoneid;
+
+	phoneid = sc_args[0];
 
 	IPC_SET_IMETHOD(question, sc_args[1]);
@@ -337,14 +333,10 @@
 	IPC_SET_ARG5(question, 0);
 
-//	printf("memset\n");
 	memset(&reply, 0, sizeof(reply));
-//	printf("udebug_mem_read(phone=%d, buffer_ptr=%u, src_addr=%d, n=%d\n",
-//		phoneid, &reply.args, sc_args[5], sizeof(reply.args));
-	rc = udebug_mem_read(phoneid, &reply.args, sc_args[5], sizeof(reply.args));
-//	printf("dmr->%d\n", rc);
-	if (rc < 0) return;
-
-//	printf("call ipc_call_sync\n");
-	ipcp_call_sync(phoneidx, &question, &reply);
+	rc = udebug_mem_read(sess, &reply.args, sc_args[5], sizeof(reply.args));
+	if (rc < 0)
+		return;
+	
+	ipcp_call_sync(phoneid, &question, &reply);
 }
 
@@ -355,5 +347,5 @@
 
 	memset(&question, 0, sizeof(question));
-	rc = udebug_mem_read(phoneid, &question.args, sc_args[1],
+	rc = udebug_mem_read(sess, &question.args, sc_args[1],
 	    sizeof(question.args));
 
@@ -372,5 +364,5 @@
 
 	memset(&reply, 0, sizeof(reply));
-	rc = udebug_mem_read(phoneid, &reply.args, sc_args[2],
+	rc = udebug_mem_read(sess, &reply.args, sc_args[2],
 	    sizeof(reply.args));
 
@@ -391,11 +383,8 @@
 
 	memset(&call, 0, sizeof(call));
-	rc = udebug_mem_read(phoneid, &call, sc_args[0], sizeof(call));
-//	printf("udebug_mem_read(phone %d, dest %d, app-mem src %d, size %d -> %d\n",
-//		phoneid, (int)&call, sc_args[0], sizeof(call), rc);
-
-	if (rc >= 0) {
+	rc = udebug_mem_read(sess, &call, sc_args[0], sizeof(call));
+	
+	if (rc >= 0)
 		ipcp_call_in(&call, sc_rc);
-	}
 }
 
@@ -407,13 +396,8 @@
 
 	/* Read syscall arguments */
-	rc = udebug_args_read(phoneid, thread_hash, sc_args);
-
-	async_serialize_start();
-
-//	printf("[%d] ", thread_id);
+	rc = udebug_args_read(sess, thread_hash, sc_args);
 
 	if (rc < 0) {
 		printf("error\n");
-		async_serialize_end();
 		return;
 	}
@@ -432,6 +416,4 @@
 		break;
 	}
-
-	async_serialize_end();
 }
 
@@ -444,7 +426,5 @@
 
 	/* Read syscall arguments */
-	rc = udebug_args_read(phoneid, thread_hash, sc_args);
-
-	async_serialize_start();
+	rc = udebug_args_read(sess, thread_hash, sc_args);
 
 //	printf("[%d] ", thread_id);
@@ -452,5 +432,4 @@
 	if (rc < 0) {
 		printf("error\n");
-		async_serialize_end();
 		return;
 	}
@@ -481,14 +460,9 @@
 		break;
 	}
-
-	async_serialize_end();
 }
 
 static void event_thread_b(uintptr_t hash)
 {
-	async_serialize_start();
 	printf("New thread, hash %p\n", (void *) hash);
-	async_serialize_end();
-
 	thread_trace_start(hash);
 }
@@ -527,5 +501,5 @@
 
 		/* Run thread until an event occurs */
-		rc = udebug_go(phoneid, thread_hash,
+		rc = udebug_go(sess, thread_hash,
 		    &ev_type, &val0, &val1);
 
@@ -656,5 +630,7 @@
 {
 	(void) arg;
-
+	
+	console_ctrl_t *console = console_init(stdin, stdout);
+	
 	while (true) {
 		fibril_mutex_lock(&state_lock);
@@ -662,12 +638,12 @@
 			fibril_condvar_wait(&state_cv, &state_lock);
 		fibril_mutex_unlock(&state_lock);
-
-		if (!console_get_event(fphone(stdin), &cev))
+		
+		if (!console_get_kbd_event(console, &cev))
 			return -1;
-
+		
 		fibril_mutex_lock(&state_lock);
 		cev_valid = true;
 		fibril_condvar_broadcast(&state_cv);
-		fibril_mutex_unlock(&state_lock);		
+		fibril_mutex_unlock(&state_lock);
 	}
 }
@@ -675,5 +651,5 @@
 static void trace_task(task_id_t task_id)
 {
-	console_event_t ev;
+	kbd_event_t ev;
 	bool done;
 	int i;
@@ -727,5 +703,5 @@
 		case KC_P:
 			printf("Pause...\n");
-			rc = udebug_stop(phoneid, thash);
+			rc = udebug_stop(sess, thash);
 			if (rc != EOK)
 				printf("Error: stop -> %d\n", rc);
@@ -743,6 +719,6 @@
 	printf("\nTerminate debugging session...\n");
 	abort_trace = true;
-	udebug_end(phoneid);
-	async_hangup(phoneid);
+	udebug_end(sess);
+	async_hangup(sess);
 
 	ipcp_cleanup();
Index: uspace/doc/doxygroups.h
===================================================================
--- uspace/doc/doxygroups.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/doc/doxygroups.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -150,5 +150,5 @@
 	 * @endcond
 	 */
-
+	
 /**
  * @defgroup emul Emulation Libraries
Index: uspace/drv/ehci_hcd/pci.c
===================================================================
--- uspace/drv/ehci_hcd/pci.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/ehci_hcd/pci.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -26,4 +26,5 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 /**
  * @addtogroup drvusbehci
@@ -34,4 +35,5 @@
  * PCI related functions needed by the EHCI driver.
  */
+
 #include <errno.h>
 #include <str_error.h>
@@ -72,56 +74,76 @@
 #define PCI_READ(size) \
 do { \
-	const int parent_phone = \
-	    devman_parent_device_connect(dev->handle, IPC_FLAG_BLOCKING);\
-	if (parent_phone < 0) {\
-		return parent_phone; \
-	} \
-	sysarg_t add = (sysarg_t)address; \
+	async_sess_t *parent_sess = \
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle, \
+	    IPC_FLAG_BLOCKING); \
+	if (!parent_sess) \
+		return ENOMEM; \
+	\
+	sysarg_t add = (sysarg_t) address; \
 	sysarg_t val; \
+	\
+	async_exch_t *exch = async_exchange_begin(parent_sess); \
+	\
 	const int ret = \
-	    async_req_2_1(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE), \
+	    async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE), \
 	        IPC_M_CONFIG_SPACE_READ_##size, add, &val); \
+	\
+	async_exchange_end(exch); \
+	async_hangup(parent_sess); \
+	\
 	assert(value); \
+	\
 	*value = val; \
-	async_hangup(parent_phone); \
+	return ret; \
+} while (0)
+
+static int pci_read32(const ddf_dev_t *dev, int address, uint32_t *value)
+{
+	PCI_READ(32);
+}
+
+static int pci_read16(const ddf_dev_t *dev, int address, uint16_t *value)
+{
+	PCI_READ(16);
+}
+
+static int pci_read8(const ddf_dev_t *dev, int address, uint8_t *value)
+{
+	PCI_READ(8);
+}
+
+#define PCI_WRITE(size) \
+do { \
+	async_sess_t *parent_sess = \
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle, \
+	    IPC_FLAG_BLOCKING); \
+	if (!parent_sess) \
+		return ENOMEM; \
+	\
+	sysarg_t add = (sysarg_t) address; \
+	sysarg_t val = value; \
+	\
+	async_exch_t *exch = async_exchange_begin(parent_sess); \
+	\
+	const int ret = \
+	    async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE), \
+	        IPC_M_CONFIG_SPACE_WRITE_##size, add, val); \
+	\
+	async_exchange_end(exch); \
+	async_hangup(parent_sess); \
+	\
 	return ret; \
 } while(0)
 
-static int pci_read32(const ddf_dev_t *dev, int address, uint32_t *value)
-{
-	PCI_READ(32);
-}
-static int pci_read16(const ddf_dev_t *dev, int address, uint16_t *value)
-{
-	PCI_READ(16);
-}
-static int pci_read8(const ddf_dev_t *dev, int address, uint8_t *value)
-{
-	PCI_READ(8);
-}
-#define PCI_WRITE(size) \
-do { \
-	const int parent_phone = \
-	    devman_parent_device_connect(dev->handle, IPC_FLAG_BLOCKING);\
-	if (parent_phone < 0) {\
-		return parent_phone; \
-	} \
-	sysarg_t add = (sysarg_t)address; \
-	sysarg_t val = value; \
-	const int ret = \
-	    async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE), \
-	        IPC_M_CONFIG_SPACE_WRITE_##size, add, val); \
-	async_hangup(parent_phone); \
-	return ret; \
-} while(0)
-
 static int pci_write32(const ddf_dev_t *dev, int address, uint32_t value)
 {
 	PCI_WRITE(32);
 }
+
 static int pci_write16(const ddf_dev_t *dev, int address, uint16_t value)
 {
 	PCI_WRITE(16);
 }
+
 static int pci_write8(const ddf_dev_t *dev, int address, uint8_t value)
 {
@@ -141,32 +163,29 @@
 {
 	assert(dev != NULL);
-
-	const int parent_phone =
-	    devman_parent_device_connect(dev->handle, IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return parent_phone;
-	}
-
-	int rc;
-
+	
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
+	    IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+	
 	hw_resource_list_t hw_resources;
-	rc = hw_res_get_resource_list(parent_phone, &hw_resources);
+	int rc = hw_res_get_resource_list(parent_sess, &hw_resources);
 	if (rc != EOK) {
-		async_hangup(parent_phone);
+		async_hangup(parent_sess);
 		return rc;
 	}
-
+	
 	uintptr_t mem_address = 0;
 	size_t mem_size = 0;
 	bool mem_found = false;
-
+	
 	int irq = 0;
 	bool irq_found = false;
-
+	
 	size_t i;
 	for (i = 0; i < hw_resources.count; i++) {
 		hw_resource_t *res = &hw_resources.resources[i];
-		switch (res->type)
-		{
+		switch (res->type) {
 		case INTERRUPT:
 			irq = res->res.interrupt.irq;
@@ -174,5 +193,4 @@
 			usb_log_debug2("Found interrupt: %d.\n", irq);
 			break;
-
 		case MEM_RANGE:
 			if (res->res.mem_range.address != 0
@@ -183,10 +201,10 @@
 				    mem_address, mem_size);
 				mem_found = true;
-				}
+			}
 		default:
 			break;
 		}
 	}
-
+	
 	if (mem_found && irq_found) {
 		*mem_reg_address = mem_address;
@@ -197,6 +215,6 @@
 		rc = ENOENT;
 	}
-
-	async_hangup(parent_phone);
+	
+	async_hangup(parent_sess);
 	return rc;
 }
@@ -209,11 +227,13 @@
 int pci_enable_interrupts(const ddf_dev_t *device)
 {
-	const int parent_phone =
-	    devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return parent_phone;
-	}
-	const bool enabled = hw_res_enable_interrupt(parent_phone);
-	async_hangup(parent_phone);
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
+	    IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+	
+	const bool enabled = hw_res_enable_interrupt(parent_sess);
+	async_hangup(parent_sess);
+	
 	return enabled ? EOK : EIO;
 }
@@ -366,10 +386,6 @@
 #undef CHECK_RET_RETURN
 }
-/*----------------------------------------------------------------------------*/
+
 /**
  * @}
  */
-
-/**
- * @}
- */
Index: uspace/drv/ns8250/ns8250.c
===================================================================
--- uspace/drv/ns8250/ns8250.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/ns8250/ns8250.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -263,7 +263,7 @@
 static void ns8250_dev_cleanup(ns8250_t *ns)
 {
-	if (ns->dev->parent_phone > 0) {
-		async_hangup(ns->dev->parent_phone);
-		ns->dev->parent_phone = 0;
+	if (ns->dev->parent_sess) {
+		async_hangup(ns->dev->parent_sess);
+		ns->dev->parent_sess = NULL;
 	}
 }
@@ -337,15 +337,15 @@
 	
 	/* Connect to the parent's driver. */
-	ns->dev->parent_phone = devman_parent_device_connect(ns->dev->handle,
-	    IPC_FLAG_BLOCKING);
-	if (ns->dev->parent_phone < 0) {
+	ns->dev->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE,
+	    ns->dev->handle, IPC_FLAG_BLOCKING);
+	if (!ns->dev->parent_sess) {
 		ddf_msg(LVL_ERROR, "Failed to connect to parent driver of "
 		    "device %s.", ns->dev->name);
-		ret = ns->dev->parent_phone;
+		ret = ENOENT;
 		goto failed;
 	}
 	
 	/* Get hw resources. */
-	ret = hw_res_get_resource_list(ns->dev->parent_phone, &hw_resources);
+	ret = hw_res_get_resource_list(ns->dev->parent_sess, &hw_resources);
 	if (ret != EOK) {
 		ddf_msg(LVL_ERROR, "Failed to get HW resources for device "
Index: uspace/drv/ohci/pci.c
===================================================================
--- uspace/drv/ohci/pci.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/ohci/pci.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -26,4 +26,5 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 /**
  * @addtogroup drvusbohci
@@ -34,4 +35,5 @@
  * PCI related functions needed by the OHCI driver.
  */
+
 #include <errno.h>
 #include <assert.h>
@@ -63,31 +65,28 @@
 	assert(irq_no);
 
-	int parent_phone = devman_parent_device_connect(dev->handle,
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
 	    IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return parent_phone;
-	}
-
-	int rc;
-
+	if (!parent_sess)
+		return ENOMEM;
+	
 	hw_resource_list_t hw_resources;
-	rc = hw_res_get_resource_list(parent_phone, &hw_resources);
+	int rc = hw_res_get_resource_list(parent_sess, &hw_resources);
 	if (rc != EOK) {
-		async_hangup(parent_phone);
+		async_hangup(parent_sess);
 		return rc;
 	}
-
+	
 	uintptr_t mem_address = 0;
 	size_t mem_size = 0;
 	bool mem_found = false;
-
+	
 	int irq = 0;
 	bool irq_found = false;
-
+	
 	size_t i;
 	for (i = 0; i < hw_resources.count; i++) {
 		hw_resource_t *res = &hw_resources.resources[i];
-		switch (res->type)
-		{
+		switch (res->type) {
 		case INTERRUPT:
 			irq = res->res.interrupt.irq;
@@ -95,5 +94,4 @@
 			usb_log_debug2("Found interrupt: %d.\n", irq);
 			break;
-
 		case MEM_RANGE:
 			if (res->res.mem_range.address != 0
@@ -104,10 +102,10 @@
 				    (void *) mem_address, mem_size);
 				mem_found = true;
-				}
+			}
 		default:
 			break;
 		}
 	}
-
+	
 	if (mem_found && irq_found) {
 		*mem_reg_address = mem_address;
@@ -115,13 +113,12 @@
 		*irq_no = irq;
 		rc = EOK;
-	} else {
+	} else
 		rc = ENOENT;
-	}
-
-	async_hangup(parent_phone);
+	
+	async_hangup(parent_sess);
 	return rc;
 }
-/*----------------------------------------------------------------------------*/
-/** Calls the PCI driver with a request to enable interrupts
+
+/** Call the PCI driver with a request to enable interrupts
  *
  * @param[in] device Device asking for interrupts
@@ -130,16 +127,15 @@
 int pci_enable_interrupts(ddf_dev_t *device)
 {
-	int parent_phone =
-	    devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return parent_phone;
-	}
-	bool enabled = hw_res_enable_interrupt(parent_phone);
-	async_hangup(parent_phone);
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
+	    IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+	
+	bool enabled = hw_res_enable_interrupt(parent_sess);
+	async_hangup(parent_sess);
+	
 	return enabled ? EOK : EIO;
 }
-/**
- * @}
- */
 
 /**
Index: uspace/drv/pciintel/pci.c
===================================================================
--- uspace/drv/pciintel/pci.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/pciintel/pci.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -53,5 +53,5 @@
 #include <ipc/dev_iface.h>
 #include <ipc/irc.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <ipc/services.h>
 #include <sysinfo.h>
@@ -92,19 +92,19 @@
 	assert(fnode);
 	pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data;
-
+	
 	sysarg_t apic;
 	sysarg_t i8259;
-
-	int irc_phone = ENOTSUP;
-
+	
+	async_sess_t *irc_sess = NULL;
+	
 	if (((sysinfo_get_value("apic", &apic) == EOK) && (apic))
 	    || ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259))) {
-		irc_phone = service_connect_blocking(SERVICE_IRC, 0, 0);
-	}
-
-	if (irc_phone < 0) {
+		irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
+		    SERVICE_IRC, 0, 0);
+	}
+	
+	if (!irc_sess)
 		return false;
-	}
-
+	
 	size_t i = 0;
 	hw_resource_list_t *res = &dev_data->hw_resources;
@@ -112,19 +112,23 @@
 		if (res->resources[i].type == INTERRUPT) {
 			const int irq = res->resources[i].res.interrupt.irq;
+			
+			async_exch_t *exch = async_exchange_begin(irc_sess);
 			const int rc =
-			    async_req_1_0(irc_phone, IRC_ENABLE_INTERRUPT, irq);
+			    async_req_1_0(exch, IRC_ENABLE_INTERRUPT, irq);
+			async_exchange_end(exch);
+			
 			if (rc != EOK) {
-				async_hangup(irc_phone);
+				async_hangup(irc_sess);
 				return false;
 			}
 		}
 	}
-
-	async_hangup(irc_phone);
+	
+	async_hangup(irc_sess);
 	return true;
 }
 
-static int pci_config_space_write_32(
-    ddf_fun_t *fun, uint32_t address, uint32_t data)
+static int pci_config_space_write_32(ddf_fun_t *fun, uint32_t address,
+    uint32_t data)
 {
 	if (address > 252)
@@ -576,5 +580,5 @@
 	
 	ddf_msg(LVL_DEBUG, "pci_add_device");
-	dnode->parent_phone = -1;
+	dnode->parent_sess = NULL;
 	
 	bus = pci_bus_new();
@@ -587,10 +591,10 @@
 	dnode->driver_data = bus;
 	
-	dnode->parent_phone = devman_parent_device_connect(dnode->handle,
-	    IPC_FLAG_BLOCKING);
-	if (dnode->parent_phone < 0) {
+	dnode->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE,
+	    dnode->handle, IPC_FLAG_BLOCKING);
+	if (!dnode->parent_sess) {
 		ddf_msg(LVL_ERROR, "pci_add_device failed to connect to the "
-		    "parent's driver.");
-		rc = dnode->parent_phone;
+		    "parent driver.");
+		rc = ENOENT;
 		goto fail;
 	}
@@ -598,5 +602,5 @@
 	hw_resource_list_t hw_resources;
 	
-	rc = hw_res_get_resource_list(dnode->parent_phone, &hw_resources);
+	rc = hw_res_get_resource_list(dnode->parent_sess, &hw_resources);
 	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "pci_add_device failed to get hw resources "
@@ -651,11 +655,14 @@
 	if (bus != NULL)
 		pci_bus_delete(bus);
-	if (dnode->parent_phone >= 0)
-		async_hangup(dnode->parent_phone);
+	
+	if (dnode->parent_sess)
+		async_hangup(dnode->parent_sess);
+	
 	if (got_res)
 		hw_res_clean_resource_list(&hw_resources);
+	
 	if (ctl != NULL)
 		ddf_fun_destroy(ctl);
-
+	
 	return rc;
 }
Index: uspace/drv/uhci_hcd/pci.c
===================================================================
--- uspace/drv/uhci_hcd/pci.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/uhci_hcd/pci.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -26,4 +26,5 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 /**
  * @addtogroup drvusbuhcihc
@@ -34,4 +35,5 @@
  * PCI related functions needed by the UHCI driver.
  */
+
 #include <errno.h>
 #include <assert.h>
@@ -59,30 +61,29 @@
 	assert(io_reg_size);
 	assert(irq_no);
-
-	int parent_phone =
-	    devman_parent_device_connect(dev->handle, IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return parent_phone;
-	}
-
+	
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
+	    IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+	
 	hw_resource_list_t hw_resources;
-	int rc = hw_res_get_resource_list(parent_phone, &hw_resources);
+	int rc = hw_res_get_resource_list(parent_sess, &hw_resources);
 	if (rc != EOK) {
-		async_hangup(parent_phone);
+		async_hangup(parent_sess);
 		return rc;
 	}
-
+	
 	uintptr_t io_address = 0;
 	size_t io_size = 0;
 	bool io_found = false;
-
+	
 	int irq = 0;
 	bool irq_found = false;
-
+	
 	size_t i;
 	for (i = 0; i < hw_resources.count; i++) {
 		const hw_resource_t *res = &hw_resources.resources[i];
-		switch (res->type)
-		{
+		switch (res->type) {
 		case INTERRUPT:
 			irq = res->res.interrupt.irq;
@@ -90,5 +91,4 @@
 			usb_log_debug2("Found interrupt: %d.\n", irq);
 			break;
-
 		case IO_RANGE:
 			io_address = res->res.io_range.address;
@@ -98,21 +98,21 @@
 			io_found = true;
 			break;
-
 		default:
 			break;
 		}
 	}
-	async_hangup(parent_phone);
-
+	
+	async_hangup(parent_sess);
+	
 	if (!io_found || !irq_found)
 		return ENOENT;
-
+	
 	*io_reg_address = io_address;
 	*io_reg_size = io_size;
 	*irq_no = irq;
-
+	
 	return EOK;
 }
-/*----------------------------------------------------------------------------*/
+
 /** Call the PCI driver with a request to enable interrupts
  *
@@ -122,14 +122,16 @@
 int pci_enable_interrupts(const ddf_dev_t *device)
 {
-	const int parent_phone =
-	    devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return parent_phone;
-	}
-	const bool enabled = hw_res_enable_interrupt(parent_phone);
-	async_hangup(parent_phone);
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
+	    IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+	
+	const bool enabled = hw_res_enable_interrupt(parent_sess);
+	async_hangup(parent_sess);
+	
 	return enabled ? EOK : EIO;
 }
-/*----------------------------------------------------------------------------*/
+
 /** Call the PCI driver with a request to clear legacy support register
  *
@@ -140,25 +142,26 @@
 {
 	assert(device);
-	const int parent_phone =
-	    devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return parent_phone;
-	}
-
+	
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
+	    IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+	
 	/* See UHCI design guide for these values p.45,
 	 * write all WC bits in USB legacy register */
 	const sysarg_t address = 0xc0;
 	const sysarg_t value = 0xaf00;
-
-	const int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
+	
+	async_exch_t *exch = async_exchange_begin(parent_sess);
+	
+	const int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
 	    IPC_M_CONFIG_SPACE_WRITE_16, address, value);
-	async_hangup(parent_phone);
-
+	
+	async_exchange_end(exch);
+	async_hangup(parent_sess);
+	
 	return rc;
 }
-/*----------------------------------------------------------------------------*/
-/**
- * @}
- */
 
 /**
Index: uspace/drv/uhci_rhd/main.c
===================================================================
--- uspace/drv/uhci_rhd/main.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/uhci_rhd/main.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -26,4 +26,5 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 /** @addtogroup drvusbuhcirh
  * @{
@@ -32,4 +33,5 @@
  * @brief UHCI root hub initialization routines
  */
+
 #include <ddf/driver.h>
 #include <devman.h>
@@ -48,16 +50,16 @@
 static int hc_get_my_registers(const ddf_dev_t *dev,
     uintptr_t *io_reg_address, size_t *io_reg_size);
-/*----------------------------------------------------------------------------*/
+
 static int uhci_rh_add_device(ddf_dev_t *device);
-/*----------------------------------------------------------------------------*/
+
 static driver_ops_t uhci_rh_driver_ops = {
 	.add_device = uhci_rh_add_device,
 };
-/*----------------------------------------------------------------------------*/
+
 static driver_t uhci_rh_driver = {
 	.name = NAME,
 	.driver_ops = &uhci_rh_driver_ops
 };
-/*----------------------------------------------------------------------------*/
+
 /** Initialize global driver structures (NONE).
  *
@@ -74,5 +76,5 @@
 	return ddf_driver_main(&uhci_rh_driver);
 }
-/*----------------------------------------------------------------------------*/
+
 /** Initialize a new ddf driver instance of UHCI root hub.
  *
@@ -122,5 +124,5 @@
 	return EOK;
 }
-/*----------------------------------------------------------------------------*/
+
 /** Get address of I/O registers.
  *
@@ -134,22 +136,22 @@
 {
 	assert(dev);
-
-	const int parent_phone = devman_parent_device_connect(dev->handle,
+	
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
 	    IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return parent_phone;
-	}
-
+	if (!parent_sess)
+		return ENOMEM;
+	
 	hw_resource_list_t hw_resources;
-	const int ret = hw_res_get_resource_list(parent_phone, &hw_resources);
+	const int ret = hw_res_get_resource_list(parent_sess, &hw_resources);
 	if (ret != EOK) {
-		async_hangup(parent_phone);
+		async_hangup(parent_sess);
 		return ret;
 	}
-
+	
 	uintptr_t io_address = 0;
 	size_t io_size = 0;
 	bool io_found = false;
-
+	
 	size_t i = 0;
 	for (; i < hw_resources.count; i++) {
@@ -160,18 +162,20 @@
 			io_found = true;
 		}
+	
 	}
-	async_hangup(parent_phone);
-
-	if (!io_found) {
+	async_hangup(parent_sess);
+	
+	if (!io_found)
 		return ENOENT;
-	}
-	if (io_reg_address != NULL) {
+	
+	if (io_reg_address != NULL)
 		*io_reg_address = io_address;
-	}
-	if (io_reg_size != NULL) {
+	
+	if (io_reg_size != NULL)
 		*io_reg_size = io_size;
-	}
+	
 	return EOK;
 }
+
 /**
  * @}
Index: uspace/drv/usbhid/kbd/kbddev.c
===================================================================
--- uspace/drv/usbhid/kbd/kbddev.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/usbhid/kbd/kbddev.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -42,4 +42,5 @@
 #include <ipc/kbd.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <fibril.h>
 #include <fibril_synch.h>
@@ -67,4 +68,7 @@
 
 #include "../usbhid.h"
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 /*----------------------------------------------------------------------------*/
@@ -307,5 +311,5 @@
     unsigned int key)
 {
-	console_event_t ev;
+	kbd_event_t ev;
 	unsigned mod_mask;
 
@@ -399,5 +403,5 @@
 	}
 	
-	async_msg_4(kbd_dev->console_phone, KBD_EVENT, ev.type, ev.key, 
+	async_obsolete_msg_4(kbd_dev->console_phone, KBD_EVENT, ev.type, ev.key, 
 	    ev.mods, ev.c);
 }
@@ -892,5 +896,5 @@
 	
 	// hangup phone to the console
-	async_hangup((*kbd_dev)->console_phone);
+	async_obsolete_hangup((*kbd_dev)->console_phone);
 	
 	if ((*kbd_dev)->repeat_mtx != NULL) {
Index: uspace/drv/usbhid/layout.h
===================================================================
--- uspace/drv/usbhid/layout.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/usbhid/layout.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -44,5 +44,5 @@
 typedef struct {
 	void (*reset)(void);
-	wchar_t (*parse_ev)(console_event_t *);
+	wchar_t (*parse_ev)(kbd_event_t *);
 } layout_op_t;
 
Index: uspace/drv/usbhid/mouse/mousedev.c
===================================================================
--- uspace/drv/usbhid/mouse/mousedev.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/usbhid/mouse/mousedev.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -41,4 +41,6 @@
 #include <usb/hid/usages/core.h>
 #include <errno.h>
+#include <async.h>
+#include <async_obsolete.h>
 #include <str_error.h>
 #include <ipc/mouse.h>
@@ -50,4 +52,7 @@
 #include "mousedev.h"
 #include "../usbhid.h"
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 #define NAME "mouse"
@@ -181,9 +186,9 @@
 	// hangup phone to the console
 	if ((*mouse_dev)->mouse_phone >= 0) {
-		async_hangup((*mouse_dev)->mouse_phone);
+		async_obsolete_hangup((*mouse_dev)->mouse_phone);
 	}
 	
 	if ((*mouse_dev)->wheel_phone >= 0) {
-		async_hangup((*mouse_dev)->wheel_phone);
+		async_obsolete_hangup((*mouse_dev)->wheel_phone);
 	}
 	
@@ -196,5 +201,5 @@
 static void usb_mouse_send_wheel(const usb_mouse_t *mouse_dev, int wheel)
 {
-	console_event_t ev;
+	kbd_event_t ev;
 	
 	ev.type = KEY_PRESS;
@@ -214,8 +219,8 @@
 	for (i = 0; i < count * 3; ++i) {
 		usb_log_debug2("Sending key %d to the console\n", ev.key);
-		async_msg_4(mouse_dev->wheel_phone, KBD_EVENT, ev.type, 
+		async_obsolete_msg_4(mouse_dev->wheel_phone, KBD_EVENT, ev.type, 
 		    ev.key, ev.mods, ev.c);
 		// send key release right away
-		async_msg_4(mouse_dev->wheel_phone, KBD_EVENT, KEY_RELEASE, 
+		async_obsolete_msg_4(mouse_dev->wheel_phone, KBD_EVENT, KEY_RELEASE, 
 		    ev.key, ev.mods, ev.c);
 	}
@@ -303,5 +308,5 @@
 	
 	if ((shift_x != 0) || (shift_y != 0)) {
-		async_req_2_0(mouse_dev->mouse_phone,
+		async_obsolete_req_2_0(mouse_dev->mouse_phone,
 		    MEVENT_MOVE, shift_x, shift_y);
 	}
@@ -353,5 +358,5 @@
 		if (mouse_dev->buttons[field->usage - field->usage_minimum] == 0
 		    && field->value != 0) {
-			async_req_2_0(mouse_dev->mouse_phone,
+			async_obsolete_req_2_0(mouse_dev->mouse_phone,
 			    MEVENT_BUTTON, field->usage, 1);
 			mouse_dev->buttons[field->usage - field->usage_minimum]
@@ -360,5 +365,5 @@
 		    mouse_dev->buttons[field->usage - field->usage_minimum] != 0
 		    && field->value == 0) {
-		       async_req_2_0(mouse_dev->mouse_phone,
+		       async_obsolete_req_2_0(mouse_dev->mouse_phone,
 			   MEVENT_BUTTON, field->usage, 0);
 		       mouse_dev->buttons[field->usage - field->usage_minimum]
Index: uspace/drv/usbhid/multimedia/multimedia.c
===================================================================
--- uspace/drv/usbhid/multimedia/multimedia.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/usbhid/multimedia/multimedia.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -46,8 +46,13 @@
 
 #include <errno.h>
+#include <async.h>
+#include <async_obsolete.h>
 #include <str_error.h>
 
 #include <ipc/kbd.h>
 #include <io/console.h>
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 #define NAME "multimedia-keys"
@@ -143,5 +148,5 @@
 	assert(multim_dev != NULL);
 	
-	console_event_t ev;
+	kbd_event_t ev;
 	
 	ev.type = type;
@@ -157,5 +162,5 @@
 	}
 	
-	async_msg_4(multim_dev->console_phone, KBD_EVENT, ev.type, ev.key, 
+	async_obsolete_msg_4(multim_dev->console_phone, KBD_EVENT, ev.type, ev.key, 
 	    ev.mods, ev.c);
 }
@@ -170,5 +175,5 @@
 	
 	// hangup phone to the console
-	async_hangup((*multim_dev)->console_phone);
+	async_obsolete_hangup((*multim_dev)->console_phone);
 
 	free(*multim_dev);
Index: uspace/drv/usbmouse/init.c
===================================================================
--- uspace/drv/usbmouse/init.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/usbmouse/init.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -34,4 +34,5 @@
  * Initialization routines for USB mouse driver.
  */
+
 #include "mouse.h"
 #include <usb/debug.h>
@@ -41,4 +42,7 @@
 #include <usb/hid/request.h>
 #include <errno.h>
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 /** Mouse polling endpoint description for boot protocol subclass. */
Index: uspace/drv/usbmouse/mouse.c
===================================================================
--- uspace/drv/usbmouse/mouse.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/usbmouse/mouse.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -34,9 +34,12 @@
  * Actual handling of USB mouse protocol.
  */
-#include "mouse.h"
+
 #include <usb/debug.h>
 #include <errno.h>
 #include <str_error.h>
 #include <ipc/mouse.h>
+#include <async.h>
+#include <async_obsolete.h>
+#include "mouse.h"
 
 /** Mouse polling callback.
@@ -81,5 +84,5 @@
 		if ((shift_x != 0) || (shift_y != 0)) {
 			/* FIXME: guessed for QEMU */
-			async_req_2_0(mouse->console_phone,
+			async_obsolete_req_2_0(mouse->console_phone,
 			    MEVENT_MOVE,
 			    - shift_x / 10,  - shift_y / 10);
@@ -87,7 +90,7 @@
 		if (butt) {
 			/* FIXME: proper button clicking. */
-			async_req_2_0(mouse->console_phone,
+			async_obsolete_req_2_0(mouse->console_phone,
 			    MEVENT_BUTTON, 1, 1);
-			async_req_2_0(mouse->console_phone,
+			async_obsolete_req_2_0(mouse->console_phone,
 			    MEVENT_BUTTON, 1, 0);
 		}
@@ -115,5 +118,5 @@
 	usb_mouse_t *mouse = (usb_mouse_t *) arg;
 
-	async_hangup(mouse->console_phone);
+	async_obsolete_hangup(mouse->console_phone);
 	mouse->console_phone = -1;
 
Index: uspace/drv/vhc/conndev.c
===================================================================
--- uspace/drv/vhc/conndev.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/vhc/conndev.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -38,4 +38,5 @@
 #include <ddf/driver.h>
 #include <usbvirt/ipc.h>
+#include <async.h>
 #include "conn.h"
 
@@ -44,40 +45,45 @@
 static fibril_local char plugged_device_name[PLUGGED_DEVICE_NAME_MAXLEN + 1] = "<unknown>";
 
+#if 0
 /** Receive device name.
  *
  * @warning Errors are silently ignored.
  *
- * @param phone Phone to the virtual device.
+ * @param sess Session to the virtual device.
+ *
  */
-static void receive_device_name(int phone)
+static void receive_device_name(async_sess_t *sess)
 {
-	aid_t opening_request = async_send_0(phone, IPC_M_USBVIRT_GET_NAME, NULL);
+	async_exch_t *exch = async_exchange_begin(sess);
+	
+	aid_t opening_request = async_send_0(exch, IPC_M_USBVIRT_GET_NAME, NULL);
 	if (opening_request == 0) {
+		async_exchange_end(exch);
 		return;
 	}
-
-
+	
 	ipc_call_t data_request_call;
-	aid_t data_request = async_data_read(phone,
-	     plugged_device_name, PLUGGED_DEVICE_NAME_MAXLEN,
-	     &data_request_call);
-
+	aid_t data_request = async_data_read(exch, plugged_device_name,
+	     PLUGGED_DEVICE_NAME_MAXLEN, &data_request_call);
+	
+	async_exchange_end(exch);
+	
 	if (data_request == 0) {
 		async_wait_for(opening_request, NULL);
 		return;
 	}
-
+	
 	sysarg_t data_request_rc;
 	sysarg_t opening_request_rc;
 	async_wait_for(data_request, &data_request_rc);
 	async_wait_for(opening_request, &opening_request_rc);
-
-	if ((data_request_rc != EOK) || (opening_request_rc != EOK)) {
+	
+	if ((data_request_rc != EOK) || (opening_request_rc != EOK))
 		return;
-	}
-
+	
 	size_t len = IPC_GET_ARG2(data_request_call);
 	plugged_device_name[len] = 0;
 }
+#endif
 
 /** Default handler for IPC methods not handled by DDF.
@@ -90,4 +96,10 @@
     ipc_callid_t icallid, ipc_call_t *icall)
 {
+// FIXME:
+// This code needs to be refactored since the async
+// framework does not support automatic callback connections
+// yet.
+
+#if 0
 	vhc_data_t *vhc = fun->dev->driver_data;
 	sysarg_t method = IPC_GET_IMETHOD(*icall);
@@ -112,4 +124,5 @@
 		return;
 	}
+#endif
 
 	async_answer_0(icallid, EINVAL);
Index: uspace/drv/vhc/devconn.c
===================================================================
--- uspace/drv/vhc/devconn.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/vhc/devconn.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -1,2 +1,30 @@
+/*
+ * 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.
+ */
+
 #include <errno.h>
 #include "vhcd.h"
@@ -11,5 +39,5 @@
 	}
 	dev->address = 0;
-	dev->dev_phone = -1;
+	dev->dev_sess = NULL;
 	dev->dev_local = NULL;
 	dev->plugged = true;
@@ -22,5 +50,5 @@
 
 static int vhc_virtdev_plug_generic(vhc_data_t *vhc,
-    int phone, usbvirt_device_t *virtdev,
+    async_sess_t *sess, usbvirt_device_t *virtdev,
     uintptr_t *handle, bool connect)
 {
@@ -30,5 +58,5 @@
 	}
 
-	dev->dev_phone = phone;
+	dev->dev_sess = sess;
 	dev->dev_local = virtdev;
 
@@ -56,17 +84,17 @@
 }
 
-int vhc_virtdev_plug(vhc_data_t *vhc, int phone, uintptr_t *handle)
+int vhc_virtdev_plug(vhc_data_t *vhc, async_sess_t *sess, uintptr_t *handle)
 {
-	return vhc_virtdev_plug_generic(vhc, phone, NULL, handle, true);
+	return vhc_virtdev_plug_generic(vhc, sess, NULL, handle, true);
 }
 
 int vhc_virtdev_plug_local(vhc_data_t *vhc, usbvirt_device_t *dev, uintptr_t *handle)
 {
-	return vhc_virtdev_plug_generic(vhc, -1, dev, handle, true);
+	return vhc_virtdev_plug_generic(vhc, NULL, dev, handle, true);
 }
 
 int vhc_virtdev_plug_hub(vhc_data_t *vhc, usbvirt_device_t *dev, uintptr_t *handle)
 {
-	return vhc_virtdev_plug_generic(vhc, -1, dev, handle, false);
+	return vhc_virtdev_plug_generic(vhc, NULL, dev, handle, false);
 }
 
Index: uspace/drv/vhc/hub.c
===================================================================
--- uspace/drv/vhc/hub.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/vhc/hub.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -33,7 +33,9 @@
  * @brief Virtual USB hub.
  */
+
 #include <usb/classes/classes.h>
 #include <usbvirt/device.h>
 #include <errno.h>
+#include <async.h>
 #include <str_error.h>
 #include <stdlib.h>
@@ -44,5 +46,4 @@
 
 #include "hub.h"
-//#include "hub/virthub.h"
 #include "vhcd.h"
 #include "conn.h"
@@ -97,9 +98,9 @@
 	 * Wait until parent device is properly initialized.
 	 */
-	int phone;
+	async_sess_t *sess;
 	do {
-		phone = devman_device_connect(hc_dev->handle, 0);
-	} while (phone < 0);
-	async_hangup(phone);
+		sess = devman_device_connect(EXCHANGE_SERIALIZE, hc_dev->handle, 0);
+	} while (!sess);
+	async_hangup(sess);
 
 	int rc;
@@ -129,5 +130,4 @@
 	return 0;
 }
-	
 
 /**
Index: uspace/drv/vhc/hub.h
===================================================================
--- uspace/drv/vhc/hub.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/vhc/hub.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -33,4 +33,5 @@
  * @brief Virtual USB hub.
  */
+
 #ifndef VHCD_HUB_H_
 #define VHCD_HUB_H_
Index: uspace/drv/vhc/main.c
===================================================================
--- uspace/drv/vhc/main.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/vhc/main.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -29,5 +29,5 @@
 /** @addtogroup drvusbvhc
  * @{
- */ 
+ */
 /** @file
  * Virtual host controller.
Index: uspace/drv/vhc/transfer.c
===================================================================
--- uspace/drv/vhc/transfer.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/vhc/transfer.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -1,2 +1,30 @@
+/*
+ * 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.
+ */
+
 #include <errno.h>
 #include <str_error.h>
@@ -123,5 +151,5 @@
 
 static int process_transfer_remote(vhc_transfer_t *transfer,
-    int phone, size_t *actual_data_size)
+    async_sess_t *sess, size_t *actual_data_size)
 {
 	int rc;
@@ -129,17 +157,17 @@
 	if (transfer->transfer_type == USB_TRANSFER_CONTROL) {
 		if (transfer->direction == USB_DIRECTION_IN) {
-			rc = usbvirt_ipc_send_control_read(phone,
-			    transfer->setup_buffer, transfer->setup_buffer_size,
-			    transfer->data_buffer, transfer->data_buffer_size,
-			    actual_data_size);
-		} else {
-			assert(transfer->direction == USB_DIRECTION_OUT);
-			rc = usbvirt_ipc_send_control_write(phone,
-			    transfer->setup_buffer, transfer->setup_buffer_size,
-			    transfer->data_buffer, transfer->data_buffer_size);
-		}
-	} else {
-		if (transfer->direction == USB_DIRECTION_IN) {
-			rc = usbvirt_ipc_send_data_in(phone, transfer->endpoint,
+			rc = usbvirt_ipc_send_control_read(sess,
+			    transfer->setup_buffer, transfer->setup_buffer_size,
+			    transfer->data_buffer, transfer->data_buffer_size,
+			    actual_data_size);
+		} else {
+			assert(transfer->direction == USB_DIRECTION_OUT);
+			rc = usbvirt_ipc_send_control_write(sess,
+			    transfer->setup_buffer, transfer->setup_buffer_size,
+			    transfer->data_buffer, transfer->data_buffer_size);
+		}
+	} else {
+		if (transfer->direction == USB_DIRECTION_IN) {
+			rc = usbvirt_ipc_send_data_in(sess, transfer->endpoint,
 			    transfer->transfer_type,
 			    transfer->data_buffer, transfer->data_buffer_size,
@@ -147,5 +175,5 @@
 		} else {
 			assert(transfer->direction == USB_DIRECTION_OUT);
-			rc = usbvirt_ipc_send_data_out(phone, transfer->endpoint,
+			rc = usbvirt_ipc_send_data_out(sess, transfer->endpoint,
 			    transfer->transfer_type,
 			    transfer->data_buffer, transfer->data_buffer_size);
@@ -206,6 +234,6 @@
 		int rc = EOK;
 		size_t data_transfer_size = 0;
-		if (dev->dev_phone > 0) {
-			rc = process_transfer_remote(transfer, dev->dev_phone,
+		if (dev->dev_sess) {
+			rc = process_transfer_remote(transfer, dev->dev_sess,
 			    &data_transfer_size);
 		} else if (dev->dev_local != NULL) {
Index: uspace/drv/vhc/vhcd.h
===================================================================
--- uspace/drv/vhc/vhcd.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/drv/vhc/vhcd.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -41,4 +41,5 @@
 #include <usb/host/device_keeper.h>
 #include <usbhc_iface.h>
+#include <async.h>
 
 #define NAME "vhc"
@@ -46,5 +47,5 @@
 typedef struct {
 	link_t link;
-	int dev_phone;
+	async_sess_t *dev_sess;
 	usbvirt_device_t *dev_local;
 	bool plugged;
@@ -82,5 +83,5 @@
 vhc_transfer_t *vhc_transfer_create(usb_address_t, usb_endpoint_t,
     usb_direction_t, usb_transfer_type_t, ddf_fun_t *, void *);
-int vhc_virtdev_plug(vhc_data_t *, int, uintptr_t *);
+int vhc_virtdev_plug(vhc_data_t *, async_sess_t *, uintptr_t *);
 int vhc_virtdev_plug_local(vhc_data_t *, usbvirt_device_t *, uintptr_t *);
 int vhc_virtdev_plug_hub(vhc_data_t *, usbvirt_device_t *, uintptr_t *);
Index: uspace/lib/block/libblock.c
===================================================================
--- uspace/lib/block/libblock.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/block/libblock.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -62,13 +62,13 @@
 static LIST_INITIALIZE(dcl_head);
 
-#define CACHE_BUCKETS_LOG2		10
-#define CACHE_BUCKETS			(1 << CACHE_BUCKETS_LOG2)
+#define CACHE_BUCKETS_LOG2  10
+#define CACHE_BUCKETS       (1 << CACHE_BUCKETS_LOG2)
 
 typedef struct {
 	fibril_mutex_t lock;
-	size_t lblock_size;		/**< Logical block size. */
-	unsigned blocks_cluster;	/**< Physical blocks per block_t */
-	unsigned block_count;		/**< Total number of blocks. */
-	unsigned blocks_cached;		/**< Number of cached blocks. */
+	size_t lblock_size;       /**< Logical block size. */
+	unsigned blocks_cluster;  /**< Physical blocks per block_t */
+	unsigned block_count;     /**< Total number of blocks. */
+	unsigned blocks_cached;   /**< Number of cached blocks. */
 	hash_table_t block_hash;
 	link_t free_head;
@@ -79,5 +79,5 @@
 	link_t link;
 	devmap_handle_t devmap_handle;
-	int dev_phone;
+	async_sess_t *sess;
 	fibril_mutex_t comm_area_lock;
 	void *comm_area;
@@ -85,19 +85,20 @@
 	void *bb_buf;
 	aoff64_t bb_addr;
-	size_t pblock_size;		/**< Physical block size. */
+	size_t pblock_size;  /**< Physical block size. */
 	cache_t *cache;
 } devcon_t;
 
-static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt);
-static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt);
-static int get_block_size(int dev_phone, size_t *bsize);
-static int get_num_blocks(int dev_phone, aoff64_t *nblocks);
-static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba);
+static int read_blocks(devcon_t *, aoff64_t, size_t);
+static int write_blocks(devcon_t *, aoff64_t, size_t);
+static int get_block_size(async_sess_t *, size_t *);
+static int get_num_blocks(async_sess_t *, aoff64_t *);
+static aoff64_t ba_ltop(devcon_t *, aoff64_t);
 
 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) {
 		devcon_t *devcon = list_get_instance(cur, devcon_t, link);
@@ -107,17 +108,18 @@
 		}
 	}
+	
 	fibril_mutex_unlock(&dcl_lock);
 	return NULL;
 }
 
-static int devcon_add(devmap_handle_t devmap_handle, int dev_phone, size_t bsize,
-    void *comm_area, size_t comm_size)
+static int devcon_add(devmap_handle_t devmap_handle, async_sess_t *sess,
+    size_t bsize, void *comm_area, size_t comm_size)
 {
 	link_t *cur;
 	devcon_t *devcon;
-
+	
 	if (comm_size < bsize)
 		return EINVAL;
-
+	
 	devcon = malloc(sizeof(devcon_t));
 	if (!devcon)
@@ -126,5 +128,5 @@
 	link_initialize(&devcon->link);
 	devcon->devmap_handle = devmap_handle;
-	devcon->dev_phone = dev_phone;
+	devcon->sess = sess;
 	fibril_mutex_initialize(&devcon->comm_area_lock);
 	devcon->comm_area = comm_area;
@@ -134,5 +136,5 @@
 	devcon->pblock_size = bsize;
 	devcon->cache = NULL;
-
+	
 	fibril_mutex_lock(&dcl_lock);
 	for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
@@ -156,44 +158,46 @@
 }
 
-int block_init(devmap_handle_t devmap_handle, size_t comm_size)
-{
-	int rc;
-	int dev_phone;
-	void *comm_area;
-	size_t bsize;
-
-	comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE,
+int block_init(exch_mgmt_t mgmt, devmap_handle_t devmap_handle,
+    size_t comm_size)
+{
+	void *comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE,
 	    MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
-	if (!comm_area) {
+	if (!comm_area)
 		return ENOMEM;
-	}
-
-	dev_phone = devmap_device_connect(devmap_handle, IPC_FLAG_BLOCKING);
-	if (dev_phone < 0) {
+	
+	async_sess_t *sess = devmap_device_connect(mgmt, devmap_handle,
+	    IPC_FLAG_BLOCKING);
+	if (!sess) {
 		munmap(comm_area, comm_size);
-		return dev_phone;
-	}
-
-	rc = async_share_out_start(dev_phone, comm_area,
+		return ENOENT;
+	}
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_share_out_start(exch, comm_area,
 	    AS_AREA_READ | AS_AREA_WRITE);
-	if (rc != EOK) {
-	    	munmap(comm_area, comm_size);
-		async_hangup(dev_phone);
-		return rc;
-	}
-
-	if (get_block_size(dev_phone, &bsize) != EOK) {
-		munmap(comm_area, comm_size);
-		async_hangup(dev_phone);
-		return rc;
-	}
-	
-	rc = devcon_add(devmap_handle, dev_phone, bsize, comm_area, comm_size);
+	async_exchange_end(exch);
+	
 	if (rc != EOK) {
 		munmap(comm_area, comm_size);
-		async_hangup(dev_phone);
+		async_hangup(sess);
 		return rc;
 	}
-
+	
+	size_t bsize;
+	rc = get_block_size(sess, &bsize);
+	
+	if (rc != EOK) {
+		munmap(comm_area, comm_size);
+		async_hangup(sess);
+		return rc;
+	}
+	
+	rc = devcon_add(devmap_handle, sess, bsize, comm_area, comm_size);
+	if (rc != EOK) {
+		munmap(comm_area, comm_size);
+		async_hangup(sess);
+		return rc;
+	}
+	
 	return EOK;
 }
@@ -206,14 +210,14 @@
 	if (devcon->cache)
 		(void) block_cache_fini(devmap_handle);
-
+	
 	devcon_remove(devcon);
-
+	
 	if (devcon->bb_buf)
 		free(devcon->bb_buf);
-
+	
 	munmap(devcon->comm_area, devcon->comm_size);
-	async_hangup(devcon->dev_phone);
-
-	free(devcon);	
+	async_hangup(devcon->sess);
+	
+	free(devcon);
 }
 
@@ -808,5 +812,5 @@
 	assert(devcon);
 	
-	return get_block_size(devcon->dev_phone, bsize);
+	return get_block_size(devcon->sess, bsize);
 }
 
@@ -820,10 +824,8 @@
 int block_get_nblocks(devmap_handle_t devmap_handle, aoff64_t *nblocks)
 {
-	devcon_t *devcon;
-
-	devcon = devcon_search(devmap_handle);
-	assert(devcon);
-	
-	return get_num_blocks(devcon->dev_phone, nblocks);
+	devcon_t *devcon = devcon_search(devmap_handle);
+	assert(devcon);
+	
+	return get_num_blocks(devcon->sess, nblocks);
 }
 
@@ -891,9 +893,11 @@
 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
 {
-	int rc;
-
-	assert(devcon);
-	rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba),
+	assert(devcon);
+	
+	async_exch_t *exch = async_exchange_begin(devcon->sess);
+	int rc = async_req_3_0(exch, BD_READ_BLOCKS, LOWER32(ba),
 	    UPPER32(ba), cnt);
+	async_exchange_end(exch);
+	
 	if (rc != EOK) {
 		printf("Error %d reading %zu blocks starting at block %" PRIuOFF64
@@ -904,4 +908,5 @@
 #endif
 	}
+	
 	return rc;
 }
@@ -918,9 +923,11 @@
 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
 {
-	int rc;
-
-	assert(devcon);
-	rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba),
+	assert(devcon);
+	
+	async_exch_t *exch = async_exchange_begin(devcon->sess);
+	int rc = async_req_3_0(exch, BD_WRITE_BLOCKS, LOWER32(ba),
 	    UPPER32(ba), cnt);
+	async_exchange_end(exch);
+	
 	if (rc != EOK) {
 		printf("Error %d writing %zu blocks starting at block %" PRIuOFF64
@@ -930,31 +937,36 @@
 #endif
 	}
+	
 	return rc;
 }
 
 /** Get block size used by the device. */
-static int get_block_size(int dev_phone, size_t *bsize)
+static int get_block_size(async_sess_t *sess, size_t *bsize)
 {
 	sysarg_t bs;
-	int rc;
-
-	rc = async_req_0_1(dev_phone, BD_GET_BLOCK_SIZE, &bs);
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_0_1(exch, BD_GET_BLOCK_SIZE, &bs);
+	async_exchange_end(exch);
+	
 	if (rc == EOK)
 		*bsize = (size_t) bs;
-
+	
 	return rc;
 }
 
 /** Get total number of blocks on block device. */
-static int get_num_blocks(int dev_phone, aoff64_t *nblocks)
-{
-	sysarg_t nb_l, nb_h;
-	int rc;
-
-	rc = async_req_0_2(dev_phone, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);
-	if (rc == EOK) {
+static int get_num_blocks(async_sess_t *sess, aoff64_t *nblocks)
+{
+	sysarg_t nb_l;
+	sysarg_t nb_h;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_0_2(exch, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);
+	async_exchange_end(exch);
+	
+	if (rc == EOK)
 		*nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h);
-	}
-
+	
 	return rc;
 }
Index: uspace/lib/block/libblock.h
===================================================================
--- uspace/lib/block/libblock.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/block/libblock.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -40,4 +40,5 @@
 
 #include <stdint.h>
+#include <async.h>
 #include "../../srv/vfs/vfs.h"
 #include <fibril_synch.h>
@@ -96,5 +97,5 @@
 };
 
-extern int block_init(devmap_handle_t, size_t);
+extern int block_init(exch_mgmt_t, devmap_handle_t, size_t);
 extern void block_fini(devmap_handle_t);
 
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/Makefile	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -68,5 +68,7 @@
 	generic/clipboard.c \
 	generic/devmap.c \
+	generic/devmap_obsolete.c \
 	generic/devman.c \
+	generic/devman_obsolete.c \
 	generic/device/hw_res.c \
 	generic/device/char_dev.c \
@@ -96,10 +98,11 @@
 	generic/io/console.c \
 	generic/io/screenbuffer.c \
-	generic/ipc/ns.c \
 	generic/malloc.c \
 	generic/sysinfo.c \
 	generic/ipc.c \
+	generic/ns.c \
+	generic/ns_obsolete.c \
 	generic/async.c \
-	generic/async_sess.c \
+	generic/async_obsolete.c \
 	generic/loader.c \
 	generic/getopt.c \
@@ -129,5 +132,5 @@
 	generic/assert.c
 
-ifeq ($(CONFIG_RTLD), y)
+ifeq ($(CONFIG_RTLD),y)
 	GENERIC_SOURCES += \
 		generic/dlfcn.c \
Index: uspace/lib/c/generic/adt/measured_strings.c
===================================================================
--- uspace/lib/c/generic/adt/measured_strings.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/adt/measured_strings.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -42,4 +42,5 @@
 #include <errno.h>
 #include <async.h>
+#include <async_obsolete.h>
 
 /** Creates a new measured string bundled with a copy of the given string
@@ -326,5 +327,5 @@
 		return ENOMEM;
 
-	rc = async_data_read_start(phone, lengths,
+	rc = async_obsolete_data_read_start(phone, lengths,
 	    sizeof(size_t) * (count + 1));
 	if (rc != EOK) {
@@ -351,5 +352,5 @@
 		(*strings)[index].length = lengths[index];
 		if (lengths[index] > 0) {
-			rc = async_data_read_start(phone, next, lengths[index]);
+			rc = async_obsolete_data_read_start(phone, next, lengths[index]);
 			if (rc != EOK) {
 			    	free(lengths);
@@ -399,5 +400,5 @@
 		return ENOMEM;
 
-	rc = async_data_write_start(phone, lengths,
+	rc = async_obsolete_data_write_start(phone, lengths,
 	    sizeof(size_t) * (count + 1));
 	if (rc != EOK) {
@@ -410,5 +411,5 @@
 	for (index = 0; index < count; index++) {
 		if (strings[index].length > 0) {
-			rc = async_data_write_start(phone, strings[index].value,
+			rc = async_obsolete_data_write_start(phone, strings[index].value,
 			    strings[index].length);
 			if (rc != EOK)
Index: uspace/lib/c/generic/async.c
===================================================================
--- uspace/lib/c/generic/async.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/async.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -40,6 +40,7 @@
  * programming.
  *
- * You should be able to write very simple multithreaded programs, the async
- * framework will automatically take care of most synchronization problems.
+ * You should be able to write very simple multithreaded programs. The async
+ * framework will automatically take care of most of the synchronization
+ * problems.
  *
  * Example of use (pseudo C):
@@ -53,7 +54,14 @@
  *   int fibril1(void *arg)
  *   {
- *     conn = async_connect_me_to();
- *     c1 = async_send(conn);
- *     c2 = async_send(conn);
+ *     conn = async_connect_me_to(...);
+ *
+ *     exch = async_exchange_begin(conn);
+ *     c1 = async_send(exch);
+ *     async_exchange_end(exch);
+ *
+ *     exch = async_exchange_begin(conn);
+ *     c2 = async_send(exch);
+ *     async_exchange_end(exch);
+ *
  *     async_wait_for(c1);
  *     async_wait_for(c2);
@@ -94,5 +102,4 @@
 #include <futex.h>
 #include <fibril.h>
-#include <stdio.h>
 #include <adt/hash_table.h>
 #include <adt/list.h>
@@ -102,8 +109,13 @@
 #include <arch/barrier.h>
 #include <bool.h>
+#include <malloc.h>
+#include <mem.h>
 #include <stdlib.h>
-#include <malloc.h>
 #include "private/async.h"
 
+#define CLIENT_HASH_TABLE_BUCKETS  32
+#define CONN_HASH_TABLE_BUCKETS    32
+
+/** Async framework global futex */
 atomic_t async_futex = FUTEX_INITIALIZER;
 
@@ -111,33 +123,25 @@
 atomic_t threads_in_ipc_wait = { 0 };
 
-typedef struct {
-	awaiter_t wdata;
-	
-	/** If reply was received. */
-	bool done;
-	
-	/** Pointer to where the answer data is stored. */
-	ipc_call_t *dataptr;
-	
-	sysarg_t retval;
-} amsg_t;
-
-/**
- * Structures of this type are used to group information about
- * a call and about a message queue link.
- */
+/** Naming service session */
+async_sess_t *session_ns;
+
+/** Call data */
 typedef struct {
 	link_t link;
+	
 	ipc_callid_t callid;
 	ipc_call_t call;
 } msg_t;
 
+/* Client connection data */
 typedef struct {
+	link_t link;
+	
 	sysarg_t in_task_hash;
-	link_t link;
-	int refcnt;
+	atomic_t refcnt;
 	void *data;
 } client_t;
 
+/* Server connection data */
 typedef struct {
 	awaiter_t wdata;
@@ -148,4 +152,5 @@
 	/** Incoming client task hash. */
 	sysarg_t in_task_hash;
+	
 	/** Incoming phone hash. */
 	sysarg_t in_phone_hash;
@@ -170,5 +175,5 @@
 
 /** Identifier of the incoming connection handled by the current fibril. */
-static fibril_local connection_t *FIBRIL_connection;
+static fibril_local connection_t *fibril_connection;
 
 static void *default_client_data_constructor(void)
@@ -196,8 +201,8 @@
 }
 
-void *async_client_data_get(void)
-{
-	assert(FIBRIL_connection);
-	return FIBRIL_connection->client->data;
+void *async_get_client_data(void)
+{
+	assert(fibril_connection);
+	return fibril_connection->client->data;
 }
 
@@ -215,9 +220,4 @@
 }
 
-/**
- * Pointer to a fibril function that will be used to handle connections.
- */
-static async_client_conn_t client_connection = default_client_connection;
-
 /** Default fibril function that gets called to handle interrupt notifications.
  *
@@ -232,9 +232,41 @@
 }
 
-/**
- * Pointer to a fibril function that will be used to handle interrupt
- * notifications.
- */
+static async_client_conn_t client_connection = default_client_connection;
 static async_client_conn_t interrupt_received = default_interrupt_received;
+
+/** Setter for client_connection function pointer.
+ *
+ * @param conn Function that will implement a new connection fibril.
+ *
+ */
+void async_set_client_connection(async_client_conn_t conn)
+{
+	client_connection = conn;
+}
+
+/** Setter for interrupt_received function pointer.
+ *
+ * @param intr Function that will implement a new interrupt
+ *             notification fibril.
+ */
+void async_set_interrupt_received(async_client_conn_t intr)
+{
+	interrupt_received = intr;
+}
+
+/** Mutex protecting inactive_exch_list and avail_phone_cv.
+ *
+ */
+static FIBRIL_MUTEX_INITIALIZE(async_sess_mutex);
+
+/** List of all currently inactive exchanges.
+ *
+ */
+static LIST_INITIALIZE(inactive_exch_list);
+
+/** Condition variable to wait for a phone to become available.
+ *
+ */
+static FIBRIL_CONDVAR_INITIALIZE(avail_phone_cv);
 
 static hash_table_t client_hash_table;
@@ -242,10 +274,8 @@
 static LIST_INITIALIZE(timeout_list);
 
-#define CLIENT_HASH_TABLE_BUCKETS  32
-#define CONN_HASH_TABLE_BUCKETS    32
-
 static hash_index_t client_hash(unsigned long key[])
 {
 	assert(key);
+	
 	return (((key[0]) >> 4) % CLIENT_HASH_TABLE_BUCKETS);
 }
@@ -253,4 +283,7 @@
 static int client_compare(unsigned long key[], hash_count_t keys, link_t *item)
 {
+	assert(key);
+	assert(item);
+	
 	client_t *client = hash_table_get_instance(item, client_t, link);
 	return (key[0] == client->in_task_hash);
@@ -278,4 +311,5 @@
 {
 	assert(key);
+	
 	return (((key[0]) >> 4) % CONN_HASH_TABLE_BUCKETS);
 }
@@ -292,4 +326,7 @@
 static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item)
 {
+	assert(key);
+	assert(item);
+	
 	connection_t *conn = hash_table_get_instance(item, connection_t, link);
 	return (key[0] == conn->in_phone_hash);
@@ -314,4 +351,6 @@
 void async_insert_timeout(awaiter_t *wd)
 {
+	assert(wd);
+	
 	wd->to_event.occurred = false;
 	wd->to_event.inlist = true;
@@ -346,4 +385,6 @@
 static bool route_call(ipc_callid_t callid, ipc_call_t *call)
 {
+	assert(call);
+	
 	futex_down(&async_futex);
 	
@@ -400,4 +441,6 @@
 static int notification_fibril(void *arg)
 {
+	assert(arg);
+	
 	msg_t *msg = (msg_t *) arg;
 	interrupt_received(msg->callid, &msg->call);
@@ -420,4 +463,6 @@
 static bool process_notification(ipc_callid_t callid, ipc_call_t *call)
 {
+	assert(call);
+	
 	futex_down(&async_futex);
 	
@@ -458,13 +503,14 @@
 ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs)
 {
-	assert(FIBRIL_connection);
+	assert(call);
+	assert(fibril_connection);
 	
 	/* Why doing this?
-	 * GCC 4.1.0 coughs on FIBRIL_connection-> dereference.
+	 * GCC 4.1.0 coughs on fibril_connection-> dereference.
 	 * GCC 4.1.1 happilly puts the rdhwr instruction in delay slot.
 	 *           I would never expect to find so many errors in
 	 *           a compiler.
 	 */
-	connection_t *conn = FIBRIL_connection;
+	connection_t *conn = fibril_connection;
 	
 	futex_down(&async_futex);
@@ -541,8 +587,10 @@
 static int connection_fibril(void *arg)
 {
+	assert(arg);
+	
 	/*
 	 * Setup fibril-local connection pointer.
 	 */
-	FIBRIL_connection = (connection_t *) arg;
+	fibril_connection = (connection_t *) arg;
 	
 	futex_down(&async_futex);
@@ -554,5 +602,5 @@
 	 */
 	
-	unsigned long key = FIBRIL_connection->in_task_hash;
+	unsigned long key = fibril_connection->in_task_hash;
 	link_t *lnk = hash_table_find(&client_hash_table, &key);
 	
@@ -561,20 +609,17 @@
 	if (lnk) {
 		client = hash_table_get_instance(lnk, client_t, link);
-		client->refcnt++;
+		atomic_inc(&client->refcnt);
 	} else {
 		client = malloc(sizeof(client_t));
 		if (!client) {
-			ipc_answer_0(FIBRIL_connection->callid, ENOMEM);
+			ipc_answer_0(fibril_connection->callid, ENOMEM);
 			futex_up(&async_futex);
 			return 0;
 		}
 		
-		client->in_task_hash = FIBRIL_connection->in_task_hash;
-		
-		async_serialize_start();
+		client->in_task_hash = fibril_connection->in_task_hash;
 		client->data = async_client_data_create();
-		async_serialize_end();
-		
-		client->refcnt = 1;
+		
+		atomic_set(&client->refcnt, 1);
 		hash_table_insert(&client_hash_table, &key, &client->link);
 	}
@@ -582,11 +627,11 @@
 	futex_up(&async_futex);
 	
-	FIBRIL_connection->client = client;
+	fibril_connection->client = client;
 	
 	/*
 	 * Call the connection handler function.
 	 */
-	FIBRIL_connection->cfibril(FIBRIL_connection->callid,
-	    &FIBRIL_connection->call);
+	fibril_connection->cfibril(fibril_connection->callid,
+	    &fibril_connection->call);
 	
 	/*
@@ -597,5 +642,5 @@
 	futex_down(&async_futex);
 	
-	if (--client->refcnt == 0) {
+	if (atomic_predec(&client->refcnt) == 0) {
 		hash_table_remove(&client_hash_table, &key, 1);
 		destroy = true;
@@ -616,5 +661,5 @@
 	 */
 	futex_down(&async_futex);
-	key = FIBRIL_connection->in_phone_hash;
+	key = fibril_connection->in_phone_hash;
 	hash_table_remove(&conn_hash_table, &key, 1);
 	futex_up(&async_futex);
@@ -623,7 +668,7 @@
 	 * Answer all remaining messages with EHANGUP.
 	 */
-	while (!list_empty(&FIBRIL_connection->msg_queue)) {
+	while (!list_empty(&fibril_connection->msg_queue)) {
 		msg_t *msg =
-		    list_get_instance(FIBRIL_connection->msg_queue.next, msg_t,
+		    list_get_instance(fibril_connection->msg_queue.next, msg_t,
 		    link);
 		
@@ -637,8 +682,8 @@
 	 * i.e. IPC_M_PHONE_HUNGUP.
 	 */
-	if (FIBRIL_connection->close_callid)
-		ipc_answer_0(FIBRIL_connection->close_callid, EOK);
-	
-	free(FIBRIL_connection);
+	if (fibril_connection->close_callid)
+		ipc_answer_0(fibril_connection->close_callid, EOK);
+	
+	free(fibril_connection);
 	return 0;
 }
@@ -646,5 +691,5 @@
 /** Create a new fibril for a new connection.
  *
- * Create new fibril for connection, fill in connection structures and inserts
+ * Create new fibril for connection, fill in connection structures and insert
  * it into the hash table, so that later we can easily do routing of messages to
  * particular fibrils.
@@ -665,5 +710,5 @@
 fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash,
     ipc_callid_t callid, ipc_call_t *call,
-    void (*cfibril)(ipc_callid_t, ipc_call_t *))
+    async_client_conn_t cfibril)
 {
 	connection_t *conn = malloc(sizeof(*conn));
@@ -721,4 +766,6 @@
 static void handle_call(ipc_callid_t callid, ipc_call_t *call)
 {
+	assert(call);
+	
 	/* Unrouted call - take some default action */
 	if ((callid & IPC_CALLID_NOTIFICATION)) {
@@ -878,11 +925,25 @@
 void __async_init(void)
 {
-	if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 1,
-	    &client_hash_table_ops))
+	if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS,
+	    1, &client_hash_table_ops))
 		abort();
 	
-	if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS, 1,
-	    &conn_hash_table_ops))
+	if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS,
+	    1, &conn_hash_table_ops))
 		abort();
+	
+	session_ns = (async_sess_t *) malloc(sizeof(async_sess_t));
+	if (session_ns == NULL)
+		abort();
+	
+	session_ns->mgmt = EXCHANGE_ATOMIC;
+	session_ns->phone = PHONE_NS;
+	session_ns->arg1 = 0;
+	session_ns->arg2 = 0;
+	session_ns->arg3 = 0;
+	
+	list_initialize(&session_ns->exch_list);
+	fibril_mutex_initialize(&session_ns->mutex);
+	atomic_set(&session_ns->refcnt, 0);
 }
 
@@ -899,6 +960,8 @@
  *
  */
-static void reply_received(void *arg, int retval, ipc_call_t *data)
-{
+void reply_received(void *arg, int retval, ipc_call_t *data)
+{
+	assert(arg);
+	
 	futex_down(&async_futex);
 	
@@ -930,6 +993,6 @@
  * completion.
  *
- * @param phoneid Handle of the phone that will be used for the send.
- * @param method  Service-defined method.
+ * @param exch    Exchange for sending the message.
+ * @param imethod Service-defined interface and method.
  * @param arg1    Service-defined payload argument.
  * @param arg2    Service-defined payload argument.
@@ -942,10 +1005,12 @@
  *
  */
-aid_t async_send_fast(int phoneid, sysarg_t method, sysarg_t arg1,
+aid_t async_send_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
 {
+	if (exch == NULL)
+		return 0;
+	
 	amsg_t *msg = malloc(sizeof(amsg_t));
-	
-	if (!msg)
+	if (msg == NULL)
 		return 0;
 	
@@ -961,5 +1026,5 @@
 	msg->wdata.active = true;
 	
-	ipc_call_async_4(phoneid, method, arg1, arg2, arg3, arg4, msg,
+	ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4, msg,
 	    reply_received, true);
 	
@@ -972,6 +1037,6 @@
  * completion.
  *
- * @param phoneid Handle of the phone that will be used for the send.
- * @param method  Service-defined method.
+ * @param exch    Exchange for sending the message.
+ * @param imethod Service-defined interface and method.
  * @param arg1    Service-defined payload argument.
  * @param arg2    Service-defined payload argument.
@@ -985,11 +1050,14 @@
  *
  */
-aid_t async_send_slow(int phoneid, sysarg_t method, sysarg_t arg1,
+aid_t async_send_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
     ipc_call_t *dataptr)
 {
+	if (exch == NULL)
+		return 0;
+	
 	amsg_t *msg = malloc(sizeof(amsg_t));
 	
-	if (!msg)
+	if (msg == NULL)
 		return 0;
 	
@@ -1005,6 +1073,6 @@
 	msg->wdata.active = true;
 	
-	ipc_call_async_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, msg,
-	    reply_received, true);
+	ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4, arg5,
+	    msg, reply_received, true);
 	
 	return (aid_t) msg;
@@ -1020,4 +1088,6 @@
 void async_wait_for(aid_t amsgid, sysarg_t *retval)
 {
+	assert(amsgid);
+	
 	amsg_t *msg = (amsg_t *) amsgid;
 	
@@ -1056,4 +1126,6 @@
 int async_wait_timeout(aid_t amsgid, sysarg_t *retval, suseconds_t timeout)
 {
+	assert(amsgid);
+	
 	amsg_t *msg = (amsg_t *) amsgid;
 	
@@ -1124,24 +1196,4 @@
 }
 
-/** Setter for client_connection function pointer.
- *
- * @param conn Function that will implement a new connection fibril.
- *
- */
-void async_set_client_connection(async_client_conn_t conn)
-{
-	client_connection = conn;
-}
-
-/** Setter for interrupt_received function pointer.
- *
- * @param intr Function that will implement a new interrupt
- *             notification fibril.
- */
-void async_set_interrupt_received(async_client_conn_t intr)
-{
-	interrupt_received = intr;
-}
-
 /** Pseudo-synchronous message sending - fast version.
  *
@@ -1151,6 +1203,6 @@
  * transferring more arguments, see the slower async_req_slow().
  *
- * @param phoneid Hash of the phone through which to make the call.
- * @param method  Method of the call.
+ * @param exch    Exchange for sending the message.
+ * @param imethod Interface and method of the call.
  * @param arg1    Service-defined payload argument.
  * @param arg2    Service-defined payload argument.
@@ -1166,14 +1218,17 @@
  *
  */
-sysarg_t async_req_fast(int phoneid, sysarg_t method, sysarg_t arg1,
+sysarg_t async_req_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2,
     sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
 {
+	if (exch == NULL)
+		return ENOENT;
+	
 	ipc_call_t result;
-	aid_t eid = async_send_4(phoneid, method, arg1, arg2, arg3, arg4,
+	aid_t aid = async_send_4(exch, imethod, arg1, arg2, arg3, arg4,
 	    &result);
 	
 	sysarg_t rc;
-	async_wait_for(eid, &rc);
+	async_wait_for(aid, &rc);
 	
 	if (r1)
@@ -1199,6 +1254,6 @@
  * Send message asynchronously and return only after the reply arrives.
  *
- * @param phoneid Hash of the phone through which to make the call.
- * @param method  Method of the call.
+ * @param exch    Exchange for sending the message.
+ * @param imethod Interface and method of the call.
  * @param arg1    Service-defined payload argument.
  * @param arg2    Service-defined payload argument.
@@ -1215,14 +1270,17 @@
  *
  */
-sysarg_t async_req_slow(int phoneid, sysarg_t method, sysarg_t arg1,
+sysarg_t async_req_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1,
     sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
 {
+	if (exch == NULL)
+		return ENOENT;
+	
 	ipc_call_t result;
-	aid_t eid = async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5,
+	aid_t aid = async_send_5(exch, imethod, arg1, arg2, arg3, arg4, arg5,
 	    &result);
 	
 	sysarg_t rc;
-	async_wait_for(eid, &rc);
+	async_wait_for(aid, &rc);
 	
 	if (r1)
@@ -1244,37 +1302,46 @@
 }
 
-void async_msg_0(int phone, sysarg_t imethod)
-{
-	ipc_call_async_0(phone, imethod, NULL, NULL, true);
-}
-
-void async_msg_1(int phone, sysarg_t imethod, sysarg_t arg1)
-{
-	ipc_call_async_1(phone, imethod, arg1, NULL, NULL, true);
-}
-
-void async_msg_2(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2)
-{
-	ipc_call_async_2(phone, imethod, arg1, arg2, NULL, NULL, true);
-}
-
-void async_msg_3(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
-    sysarg_t arg3)
-{
-	ipc_call_async_3(phone, imethod, arg1, arg2, arg3, NULL, NULL, true);
-}
-
-void async_msg_4(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
-    sysarg_t arg3, sysarg_t arg4)
-{
-	ipc_call_async_4(phone, imethod, arg1, arg2, arg3, arg4, NULL, NULL,
-	    true);
-}
-
-void async_msg_5(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
-    sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
-{
-	ipc_call_async_5(phone, imethod, arg1, arg2, arg3, arg4, arg5, NULL,
-	    NULL, true);
+void async_msg_0(async_exch_t *exch, sysarg_t imethod)
+{
+	if (exch != NULL)
+		ipc_call_async_0(exch->phone, imethod, NULL, NULL, true);
+}
+
+void async_msg_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1)
+{
+	if (exch != NULL)
+		ipc_call_async_1(exch->phone, imethod, arg1, NULL, NULL, true);
+}
+
+void async_msg_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+    sysarg_t arg2)
+{
+	if (exch != NULL)
+		ipc_call_async_2(exch->phone, imethod, arg1, arg2, NULL, NULL,
+		    true);
+}
+
+void async_msg_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+    sysarg_t arg2, sysarg_t arg3)
+{
+	if (exch != NULL)
+		ipc_call_async_3(exch->phone, imethod, arg1, arg2, arg3, NULL,
+		    NULL, true);
+}
+
+void async_msg_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
+{
+	if (exch != NULL)
+		ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4,
+		    NULL, NULL, true);
+}
+
+void async_msg_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
+{
+	if (exch != NULL)
+		ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4,
+		    arg5, NULL, NULL, true);
 }
 
@@ -1313,16 +1380,22 @@
 }
 
-int async_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod,
-    sysarg_t arg1, sysarg_t arg2, unsigned int mode)
-{
-	return ipc_forward_fast(callid, phoneid, imethod, arg1, arg2, mode);
-}
-
-int async_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod,
-    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
-    unsigned int mode)
-{
-	return ipc_forward_slow(callid, phoneid, imethod, arg1, arg2, arg3, arg4,
-	    arg5, mode);
+int async_forward_fast(ipc_callid_t callid, async_exch_t *exch,
+    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, unsigned int mode)
+{
+	if (exch == NULL)
+		return ENOENT;
+	
+	return ipc_forward_fast(callid, exch->phone, imethod, arg1, arg2, mode);
+}
+
+int async_forward_slow(ipc_callid_t callid, async_exch_t *exch,
+    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
+    sysarg_t arg4, sysarg_t arg5, unsigned int mode)
+{
+	if (exch == NULL)
+		return ENOENT;
+	
+	return ipc_forward_slow(callid, exch->phone, imethod, arg1, arg2, arg3,
+	    arg4, arg5, mode);
 }
 
@@ -1331,5 +1404,5 @@
  * Ask through phone for a new connection to some service.
  *
- * @param phone           Phone handle used for contacting the other side.
+ * @param exch            Exchange for sending the message.
  * @param arg1            User defined argument.
  * @param arg2            User defined argument.
@@ -1337,13 +1410,16 @@
  * @param client_receiver Connection handing routine.
  *
- * @return New phone handle on success or a negative error code.
- *
- */
-int async_connect_to_me(int phone, sysarg_t arg1, sysarg_t arg2,
+ * @return Zero on success or a negative error code.
+ *
+ */
+int async_connect_to_me(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2,
     sysarg_t arg3, async_client_conn_t client_receiver)
 {
+	if (exch == NULL)
+		return ENOENT;
+	
 	sysarg_t task_hash;
 	sysarg_t phone_hash;
-	int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
+	int rc = async_req_3_5(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
 	    NULL, NULL, NULL, &task_hash, &phone_hash);
 	if (rc != EOK)
@@ -1357,27 +1433,159 @@
 }
 
-/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
- *
- * Ask through phone for a new connection to some service.
- *
- * @param phone Phone handle used for contacting the other side.
- * @param arg1  User defined argument.
- * @param arg2  User defined argument.
- * @param arg3  User defined argument.
- *
- * @return New phone handle on success or a negative error code.
- *
- */
-int async_connect_me_to(int phone, sysarg_t arg1, sysarg_t arg2,
-    sysarg_t arg3)
-{
-	sysarg_t newphid;
-	int rc = async_req_3_5(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
-	    NULL, NULL, NULL, NULL, &newphid);
+/** Wrapper for making IPC_M_CONNECT_ME calls using the async framework.
+ *
+ * Ask through for a cloned connection to some service.
+ *
+ * @param mgmt Exchange management style.
+ * @param exch Exchange for sending the message.
+ *
+ * @return New session on success or NULL on error.
+ *
+ */
+async_sess_t *async_connect_me(exch_mgmt_t mgmt, async_exch_t *exch)
+{
+	if (exch == NULL) {
+		errno = ENOENT;
+		return NULL;
+	}
+	
+	async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
+	if (sess == NULL) {
+		errno = ENOMEM;
+		return NULL;
+	}
+	
+	ipc_call_t result;
+	
+	amsg_t *msg = malloc(sizeof(amsg_t));
+	if (msg == NULL) {
+		free(sess);
+		errno = ENOMEM;
+		return NULL;
+	}
+	
+	msg->done = false;
+	msg->dataptr = &result;
+	
+	msg->wdata.to_event.inlist = false;
+	
+	/*
+	 * We may sleep in the next method,
+	 * but it will use its own means
+	 */
+	msg->wdata.active = true;
+	
+	ipc_call_async_0(exch->phone, IPC_M_CONNECT_ME, msg,
+	    reply_received, true);
+	
+	sysarg_t rc;
+	async_wait_for((aid_t) msg, &rc);
+	
+	if (rc != EOK) {
+		errno = rc;
+		free(sess);
+		return NULL;
+	}
+	
+	int phone = (int) IPC_GET_ARG5(result);
+	
+	if (phone < 0) {
+		errno = phone;
+		free(sess);
+		return NULL;
+	}
+	
+	sess->mgmt = mgmt;
+	sess->phone = phone;
+	sess->arg1 = 0;
+	sess->arg2 = 0;
+	sess->arg3 = 0;
+	
+	list_initialize(&sess->exch_list);
+	fibril_mutex_initialize(&sess->mutex);
+	atomic_set(&sess->refcnt, 0);
+	
+	return sess;
+}
+
+static int async_connect_me_to_internal(int phone, sysarg_t arg1, sysarg_t arg2,
+    sysarg_t arg3, sysarg_t arg4)
+{
+	ipc_call_t result;
+	
+	amsg_t *msg = malloc(sizeof(amsg_t));
+	if (msg == NULL)
+		return ENOENT;
+	
+	msg->done = false;
+	msg->dataptr = &result;
+	
+	msg->wdata.to_event.inlist = false;
+	
+	/*
+	 * We may sleep in the next method,
+	 * but it will use its own means
+	 */
+	msg->wdata.active = true;
+	
+	ipc_call_async_4(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, arg4,
+	    msg, reply_received, true);
+	
+	sysarg_t rc;
+	async_wait_for((aid_t) msg, &rc);
 	
 	if (rc != EOK)
 		return rc;
 	
-	return newphid;
+	return (int) IPC_GET_ARG5(result);
+}
+
+/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
+ *
+ * Ask through for a new connection to some service.
+ *
+ * @param mgmt Exchange management style.
+ * @param exch Exchange for sending the message.
+ * @param arg1 User defined argument.
+ * @param arg2 User defined argument.
+ * @param arg3 User defined argument.
+ *
+ * @return New session on success or NULL on error.
+ *
+ */
+async_sess_t *async_connect_me_to(exch_mgmt_t mgmt, async_exch_t *exch,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
+{
+	if (exch == NULL) {
+		errno = ENOENT;
+		return NULL;
+	}
+	
+	async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
+	if (sess == NULL) {
+		errno = ENOMEM;
+		return NULL;
+	}
+	
+	int phone = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3,
+	    0);
+	
+	if (phone < 0) {
+		errno = phone;
+		free(sess);
+		return NULL;
+	}
+	
+	sess->mgmt = mgmt;
+	sess->phone = phone;
+	sess->arg1 = arg1;
+	sess->arg2 = arg2;
+	sess->arg3 = arg3;
+	
+	list_initialize(&sess->exch_list);
+	fibril_mutex_initialize(&sess->mutex);
+	atomic_set(&sess->refcnt, 0);
+	
+	return sess;
 }
 
@@ -1387,23 +1595,47 @@
  * success.
  *
- * @param phoneid Phone handle used for contacting the other side.
- * @param arg1    User defined argument.
- * @param arg2    User defined argument.
- * @param arg3    User defined argument.
- *
- * @return New phone handle on success or a negative error code.
- *
- */
-int async_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
-    sysarg_t arg3)
-{
-	sysarg_t newphid;
-	int rc = async_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
-	    IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
-	
-	if (rc != EOK)
-		return rc;
-	
-	return newphid;
+ * @param mgmt Exchange management style.
+ * @param exch Exchange for sending the message.
+ * @param arg1 User defined argument.
+ * @param arg2 User defined argument.
+ * @param arg3 User defined argument.
+ *
+ * @return New session on success or NULL on error.
+ *
+ */
+async_sess_t *async_connect_me_to_blocking(exch_mgmt_t mgmt, async_exch_t *exch,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
+{
+	if (exch == NULL) {
+		errno = ENOENT;
+		return NULL;
+	}
+	
+	async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
+	if (sess == NULL) {
+		errno = ENOMEM;
+		return NULL;
+	}
+	
+	int phone = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3,
+	    IPC_FLAG_BLOCKING);
+	
+	if (phone < 0) {
+		errno = phone;
+		free(sess);
+		return NULL;
+	}
+	
+	sess->mgmt = mgmt;
+	sess->phone = phone;
+	sess->arg1 = arg1;
+	sess->arg2 = arg2;
+	sess->arg3 = arg3;
+	
+	list_initialize(&sess->exch_list);
+	fibril_mutex_initialize(&sess->mutex);
+	atomic_set(&sess->refcnt, 0);
+	
+	return sess;
 }
 
@@ -1411,19 +1643,56 @@
  *
  */
-int async_connect_kbox(task_id_t id)
-{
-	return ipc_connect_kbox(id);
+async_sess_t *async_connect_kbox(task_id_t id)
+{
+	async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
+	if (sess == NULL) {
+		errno = ENOMEM;
+		return NULL;
+	}
+	
+	int phone = ipc_connect_kbox(id);
+	if (phone < 0) {
+		errno = phone;
+		free(sess);
+		return NULL;
+	}
+	
+	sess->mgmt = EXCHANGE_ATOMIC;
+	sess->phone = phone;
+	sess->arg1 = 0;
+	sess->arg2 = 0;
+	sess->arg3 = 0;
+	
+	list_initialize(&sess->exch_list);
+	fibril_mutex_initialize(&sess->mutex);
+	atomic_set(&sess->refcnt, 0);
+	
+	return sess;
+}
+
+static int async_hangup_internal(int phone)
+{
+	return ipc_hangup(phone);
 }
 
 /** Wrapper for ipc_hangup.
  *
- * @param phone Phone handle to hung up.
+ * @param sess Session to hung up.
  *
  * @return Zero on success or a negative error code.
  *
  */
-int async_hangup(int phone)
-{
-	return ipc_hangup(phone);
+int async_hangup(async_sess_t *sess)
+{
+	assert(sess);
+	
+	if (atomic_get(&sess->refcnt) > 0)
+		return EBUSY;
+	
+	int rc = async_hangup_internal(sess->phone);
+	if (rc == EOK)
+		free(sess);
+	
+	return rc;
 }
 
@@ -1434,20 +1703,140 @@
 }
 
+/** Start new exchange in a session.
+ *
+ * @param session Session.
+ *
+ * @return New exchange or NULL on error.
+ *
+ */
+async_exch_t *async_exchange_begin(async_sess_t *sess)
+{
+	if (sess == NULL)
+		return NULL;
+	
+	async_exch_t *exch;
+	
+	fibril_mutex_lock(&async_sess_mutex);
+	
+	if (!list_empty(&sess->exch_list)) {
+		/*
+		 * There are inactive exchanges in the session.
+		 */
+		exch = (async_exch_t *)
+		    list_get_instance(sess->exch_list.next, async_exch_t, sess_link);
+		list_remove(&exch->sess_link);
+		list_remove(&exch->global_link);
+	} else {
+		/*
+		 * There are no available exchanges in the session.
+		 */
+		
+		if ((sess->mgmt == EXCHANGE_ATOMIC) ||
+		    (sess->mgmt == EXCHANGE_SERIALIZE)) {
+			exch = (async_exch_t *) malloc(sizeof(async_exch_t));
+			if (exch != NULL) {
+				list_initialize(&exch->sess_link);
+				list_initialize(&exch->global_link);
+				exch->sess = sess;
+				exch->phone = sess->phone;
+			}
+		} else {  /* EXCHANGE_PARALLEL */
+			/*
+			 * Make a one-time attempt to connect a new data phone.
+			 */
+			
+			int phone;
+			
+retry:
+			phone = async_connect_me_to_internal(sess->phone, sess->arg1,
+			    sess->arg2, sess->arg3, 0);
+			if (phone >= 0) {
+				exch = (async_exch_t *) malloc(sizeof(async_exch_t));
+				if (exch != NULL) {
+					list_initialize(&exch->sess_link);
+					list_initialize(&exch->global_link);
+					exch->sess = sess;
+					exch->phone = phone;
+				} else
+					async_hangup_internal(phone);
+			} else if (!list_empty(&inactive_exch_list)) {
+				/*
+				 * We did not manage to connect a new phone. But we
+				 * can try to close some of the currently inactive
+				 * connections in other sessions and try again.
+				 */
+				exch = (async_exch_t *)
+				    list_get_instance(inactive_exch_list.next, async_exch_t,
+				    global_link);
+				list_remove(&exch->sess_link);
+				list_remove(&exch->global_link);
+				async_hangup_internal(exch->phone);
+				free(exch);
+				goto retry;
+			} else {
+				/*
+				 * Wait for a phone to become available.
+				 */
+				fibril_condvar_wait(&avail_phone_cv, &async_sess_mutex);
+				goto retry;
+			}
+		}
+	}
+	
+	fibril_mutex_unlock(&async_sess_mutex);
+	
+	if (exch != NULL) {
+		atomic_inc(&sess->refcnt);
+		
+		if (sess->mgmt == EXCHANGE_SERIALIZE)
+			fibril_mutex_lock(&sess->mutex);
+	}
+	
+	return exch;
+}
+
+/** Finish an exchange.
+ *
+ * @param exch Exchange to finish.
+ *
+ */
+void async_exchange_end(async_exch_t *exch)
+{
+	if (exch == NULL)
+		return;
+	
+	async_sess_t *sess = exch->sess;
+	
+	if (sess->mgmt == EXCHANGE_SERIALIZE)
+		fibril_mutex_unlock(&sess->mutex);
+	
+	fibril_mutex_lock(&async_sess_mutex);
+	
+	list_append(&exch->sess_link, &sess->exch_list);
+	list_append(&exch->global_link, &inactive_exch_list);
+	fibril_condvar_signal(&avail_phone_cv);
+	
+	fibril_mutex_unlock(&async_sess_mutex);
+}
+
 /** Wrapper for IPC_M_SHARE_IN calls using the async framework.
  *
- * @param phoneid Phone that will be used to contact the receiving side.
- * @param dst     Destination address space area base.
- * @param size    Size of the destination address space area.
- * @param arg     User defined argument.
- * @param flags   Storage for the received flags. Can be NULL.
+ * @param exch  Exchange for sending the message.
+ * @param dst   Destination address space area base.
+ * @param size  Size of the destination address space area.
+ * @param arg   User defined argument.
+ * @param flags Storage for the received flags. Can be NULL.
  *
  * @return Zero on success or a negative error code from errno.h.
  *
  */
-int async_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg,
-    unsigned int *flags)
-{
+int async_share_in_start(async_exch_t *exch, void *dst, size_t size,
+    sysarg_t arg, unsigned int *flags)
+{
+	if (exch == NULL)
+		return ENOENT;
+	
 	sysarg_t tmp_flags;
-	int res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,
+	int res = async_req_3_2(exch, IPC_M_SHARE_IN, (sysarg_t) dst,
 	    (sysarg_t) size, arg, NULL, &tmp_flags);
 	
@@ -1507,14 +1896,17 @@
 /** Wrapper for IPC_M_SHARE_OUT calls using the async framework.
  *
- * @param phoneid Phone that will be used to contact the receiving side.
- * @param src     Source address space area base address.
- * @param flags   Flags to be used for sharing. Bits can be only cleared.
+ * @param exch  Exchange for sending the message.
+ * @param src   Source address space area base address.
+ * @param flags Flags to be used for sharing. Bits can be only cleared.
  *
  * @return Zero on success or a negative error code from errno.h.
  *
  */
-int async_share_out_start(int phoneid, void *src, unsigned int flags)
-{
-	return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
+int async_share_out_start(async_exch_t *exch, void *src, unsigned int flags)
+{
+	if (exch == NULL)
+		return ENOENT;
+	
+	return async_req_3_0(exch, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
 	    (sysarg_t) flags);
 }
@@ -1571,13 +1963,16 @@
 /** Start IPC_M_DATA_READ using the async framework.
  *
- * @param phoneid Phone that will be used to contact the receiving side.
- * @param dst Address of the beginning of the destination buffer.
- * @param size Size of the destination buffer (in bytes).
+ * @param exch    Exchange for sending the message.
+ * @param dst     Address of the beginning of the destination buffer.
+ * @param size    Size of the destination buffer (in bytes).
  * @param dataptr Storage of call data (arg 2 holds actual data size).
+ *
  * @return Hash of the sent message or 0 on error.
- */
-aid_t async_data_read(int phoneid, void *dst, size_t size, ipc_call_t *dataptr)
-{
-	return async_send_2(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,
+ *
+ */
+aid_t async_data_read(async_exch_t *exch, void *dst, size_t size,
+    ipc_call_t *dataptr)
+{
+	return async_send_2(exch, IPC_M_DATA_READ, (sysarg_t) dst,
 	    (sysarg_t) size, dataptr);
 }
@@ -1585,17 +1980,18 @@
 /** Wrapper for IPC_M_DATA_READ calls using the async framework.
  *
- * @param phoneid Phone that will be used to contact the receiving side.
- * @param dst     Address of the beginning of the destination buffer.
- * @param size    Size of the destination buffer.
- * @param flags   Flags to control the data transfer.
+ * @param exch Exchange for sending the message.
+ * @param dst  Address of the beginning of the destination buffer.
+ * @param size Size of the destination buffer.
  *
  * @return Zero on success or a negative error code from errno.h.
  *
  */
-int
-async_data_read_start_generic(int phoneid, void *dst, size_t size, int flags)
-{
-	return async_req_3_0(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,
-	    (sysarg_t) size, (sysarg_t) flags);
+int async_data_read_start(async_exch_t *exch, void *dst, size_t size)
+{
+	if (exch == NULL)
+		return ENOENT;
+	
+	return async_req_2_0(exch, IPC_M_DATA_READ, (sysarg_t) dst,
+	    (sysarg_t) size);
 }
 
@@ -1652,7 +2048,11 @@
  *
  */
-int async_data_read_forward_fast(int phoneid, sysarg_t method, sysarg_t arg1,
-    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
-{
+int async_data_read_forward_fast(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
+    ipc_call_t *dataptr)
+{
+	if (exch == NULL)
+		return ENOENT;
+	
 	ipc_callid_t callid;
 	if (!async_data_read_receive(&callid, NULL)) {
@@ -1661,5 +2061,5 @@
 	}
 	
-	aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
+	aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4,
 	    dataptr);
 	if (msg == 0) {
@@ -1668,5 +2068,5 @@
 	}
 	
-	int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
+	int retval = ipc_forward_fast(callid, exch->phone, 0, 0, 0,
 	    IPC_FF_ROUTE_FROM_ME);
 	if (retval != EOK) {
@@ -1684,18 +2084,18 @@
 /** Wrapper for IPC_M_DATA_WRITE calls using the async framework.
  *
- * @param phoneid Phone that will be used to contact the receiving side.
- * @param src     Address of the beginning of the source buffer.
- * @param size    Size of the source buffer.
- * @param flags   Flags to control the data transfer.
+ * @param exch Exchange for sending the message.
+ * @param src  Address of the beginning of the source buffer.
+ * @param size Size of the source buffer.
  *
  * @return Zero on success or a negative error code from errno.h.
  *
  */
-int
-async_data_write_start_generic(int phoneid, const void *src, size_t size,
-    int flags)
-{
-	return async_req_3_0(phoneid, IPC_M_DATA_WRITE, (sysarg_t) src,
-	    (sysarg_t) size, (sysarg_t) flags);
+int async_data_write_start(async_exch_t *exch, const void *src, size_t size)
+{
+	if (exch == NULL)
+		return ENOENT;
+	
+	return async_req_2_0(exch, IPC_M_DATA_WRITE, (sysarg_t) src,
+	    (sysarg_t) size);
 }
 
@@ -1773,4 +2173,6 @@
     size_t *received)
 {
+	assert(data);
+	
 	ipc_callid_t callid;
 	size_t size;
@@ -1840,7 +2242,11 @@
  *
  */
-int async_data_write_forward_fast(int phoneid, sysarg_t method, sysarg_t arg1,
-    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
-{
+int async_data_write_forward_fast(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
+    ipc_call_t *dataptr)
+{
+	if (exch == NULL)
+		return ENOENT;
+	
 	ipc_callid_t callid;
 	if (!async_data_write_receive(&callid, NULL)) {
@@ -1849,5 +2255,5 @@
 	}
 	
-	aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
+	aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4,
 	    dataptr);
 	if (msg == 0) {
@@ -1856,5 +2262,5 @@
 	}
 	
-	int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
+	int retval = ipc_forward_fast(callid, exch->phone, 0, 0, 0,
 	    IPC_FF_ROUTE_FROM_ME);
 	if (retval != EOK) {
@@ -1870,4 +2276,105 @@
 }
 
+/** Wrapper for sending an exchange over different exchange for cloning
+ *
+ * @param exch       Exchange to be used for sending.
+ * @param clone_exch Exchange to be cloned.
+ *
+ */
+int async_exchange_clone(async_exch_t *exch, async_exch_t *clone_exch)
+{
+	return async_req_1_0(exch, IPC_M_CONNECTION_CLONE, clone_exch->phone);
+}
+
+/** Wrapper for receiving the IPC_M_CONNECTION_CLONE calls.
+ *
+ * If the current call is IPC_M_CONNECTION_CLONE then a new
+ * async session is created for the accepted phone.
+ *
+ * @param mgmt Exchange management style.
+ *
+ * @return New async session or NULL on failure.
+ *
+ */
+async_sess_t *async_clone_receive(exch_mgmt_t mgmt)
+{
+	/* Accept the phone */
+	ipc_call_t call;
+	ipc_callid_t callid = async_get_call(&call);
+	int phone = (int) IPC_GET_ARG1(call);
+	
+	if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECTION_CLONE) ||
+	    (phone < 0)) {
+		async_answer_0(callid, EINVAL);
+		return NULL;
+	}
+	
+	async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
+	if (sess == NULL) {
+		async_answer_0(callid, ENOMEM);
+		return NULL;
+	}
+	
+	sess->mgmt = mgmt;
+	sess->phone = phone;
+	sess->arg1 = 0;
+	sess->arg2 = 0;
+	sess->arg3 = 0;
+	
+	list_initialize(&sess->exch_list);
+	fibril_mutex_initialize(&sess->mutex);
+	atomic_set(&sess->refcnt, 0);
+	
+	/* Acknowledge the cloned phone */
+	async_answer_0(callid, EOK);
+	
+	return sess;
+}
+
+/** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls.
+ *
+ * If the current call is IPC_M_CONNECT_TO_ME then a new
+ * async session is created for the accepted phone.
+ *
+ * @param mgmt Exchange management style.
+ *
+ * @return New async session or NULL on failure.
+ *
+ */
+async_sess_t *async_callback_receive(exch_mgmt_t mgmt)
+{
+	/* Accept the phone */
+	ipc_call_t call;
+	ipc_callid_t callid = async_get_call(&call);
+	int phone = (int) IPC_GET_ARG5(call);
+	
+	if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) ||
+	    (phone < 0)) {
+		async_answer_0(callid, EINVAL);
+		return NULL;
+	}
+	
+	async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
+	if (sess == NULL) {
+		async_answer_0(callid, ENOMEM);
+		return NULL;
+	}
+	
+	sess->mgmt = mgmt;
+	sess->phone = phone;
+	sess->arg1 = 0;
+	sess->arg2 = 0;
+	sess->arg3 = 0;
+	
+	list_initialize(&sess->exch_list);
+	fibril_mutex_initialize(&sess->mutex);
+	atomic_set(&sess->refcnt, 0);
+	
+	/* Acknowledge the connected phone */
+	async_answer_0(callid, EOK);
+	
+	return sess;
+}
+
 /** @}
  */
Index: uspace/lib/c/generic/async_obsolete.c
===================================================================
--- uspace/lib/c/generic/async_obsolete.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
+++ uspace/lib/c/generic/async_obsolete.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -0,0 +1,460 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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
+ */
+
+#define LIBC_ASYNC_C_
+#define LIBC_ASYNC_OBSOLETE_C_
+#include <ipc/ipc.h>
+#include <async.h>
+#include <async_obsolete.h>
+#undef LIBC_ASYNC_C_
+#undef LIBC_ASYNC_OBSOLETE_C_
+
+#include <fibril.h>
+#include <malloc.h>
+#include <errno.h>
+#include "private/async.h"
+
+/** Send message and return id of the sent message.
+ *
+ * The return value can be used as input for async_wait() to wait for
+ * completion.
+ *
+ * @param phoneid Handle of the phone that will be used for the send.
+ * @param method  Service-defined method.
+ * @param arg1    Service-defined payload argument.
+ * @param arg2    Service-defined payload argument.
+ * @param arg3    Service-defined payload argument.
+ * @param arg4    Service-defined payload argument.
+ * @param dataptr If non-NULL, storage where the reply data will be
+ *                stored.
+ *
+ * @return Hash of the sent message or 0 on error.
+ *
+ */
+aid_t async_obsolete_send_fast(int phoneid, sysarg_t method, sysarg_t arg1,
+    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
+{
+	amsg_t *msg = malloc(sizeof(amsg_t));
+	
+	if (!msg)
+		return 0;
+	
+	msg->done = false;
+	msg->dataptr = dataptr;
+	
+	msg->wdata.to_event.inlist = false;
+	
+	/*
+	 * We may sleep in the next method,
+	 * but it will use its own means
+	 */
+	msg->wdata.active = true;
+	
+	ipc_call_async_4(phoneid, method, arg1, arg2, arg3, arg4, msg,
+	    reply_received, true);
+	
+	return (aid_t) msg;
+}
+
+/** Pseudo-synchronous message sending - fast version.
+ *
+ * Send message asynchronously and return only after the reply arrives.
+ *
+ * This function can only transfer 4 register payload arguments. For
+ * transferring more arguments, see the slower async_req_slow().
+ *
+ * @param phoneid Hash of the phone through which to make the call.
+ * @param method  Method of the call.
+ * @param arg1    Service-defined payload argument.
+ * @param arg2    Service-defined payload argument.
+ * @param arg3    Service-defined payload argument.
+ * @param arg4    Service-defined payload argument.
+ * @param r1      If non-NULL, storage for the 1st reply argument.
+ * @param r2      If non-NULL, storage for the 2nd reply argument.
+ * @param r3      If non-NULL, storage for the 3rd reply argument.
+ * @param r4      If non-NULL, storage for the 4th reply argument.
+ * @param r5      If non-NULL, storage for the 5th reply argument.
+ *
+ * @return Return code of the reply or a negative error code.
+ *
+ */
+sysarg_t async_obsolete_req_fast(int phoneid, sysarg_t method, sysarg_t arg1,
+    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2,
+    sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
+{
+	ipc_call_t result;
+	aid_t eid = async_obsolete_send_4(phoneid, method, arg1, arg2, arg3, arg4,
+	    &result);
+	
+	sysarg_t rc;
+	async_wait_for(eid, &rc);
+	
+	if (r1)
+		*r1 = IPC_GET_ARG1(result);
+	
+	if (r2)
+		*r2 = IPC_GET_ARG2(result);
+	
+	if (r3)
+		*r3 = IPC_GET_ARG3(result);
+	
+	if (r4)
+		*r4 = IPC_GET_ARG4(result);
+	
+	if (r5)
+		*r5 = IPC_GET_ARG5(result);
+	
+	return rc;
+}
+
+/** Wrapper for IPC_M_SHARE_OUT calls using the async framework.
+ *
+ * @param phoneid Phone that will be used to contact the receiving side.
+ * @param src     Source address space area base address.
+ * @param flags   Flags to be used for sharing. Bits can be only cleared.
+ *
+ * @return Zero on success or a negative error code from errno.h.
+ *
+ */
+int async_obsolete_share_out_start(int phoneid, void *src, unsigned int flags)
+{
+	return async_obsolete_req_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
+	    (sysarg_t) flags);
+}
+
+/** Wrapper for ipc_hangup.
+ *
+ * @param phone Phone handle to hung up.
+ *
+ * @return Zero on success or a negative error code.
+ *
+ */
+int async_obsolete_hangup(int phone)
+{
+	return ipc_hangup(phone);
+}
+
+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.
+ *
+ * @param phoneid Phone that will be used to contact the receiving side.
+ * @param src     Address of the beginning of the source buffer.
+ * @param size    Size of the source buffer.
+ * @param flags   Flags to control the data transfer.
+ *
+ * @return Zero on success or a negative error code from errno.h.
+ *
+ */
+int async_obsolete_data_write_start_generic(int phoneid, const void *src, size_t size,
+    int flags)
+{
+	return async_obsolete_req_3_0(phoneid, IPC_M_DATA_WRITE, (sysarg_t) src,
+	    (sysarg_t) size, (sysarg_t) flags);
+}
+
+/** Start IPC_M_DATA_READ using the async framework.
+ *
+ * @param phoneid Phone that will be used to contact the receiving side.
+ * @param dst     Address of the beginning of the destination buffer.
+ * @param size    Size of the destination buffer (in bytes).
+ * @param dataptr Storage of call data (arg 2 holds actual data size).
+ *
+ * @return Hash of the sent message or 0 on error.
+ *
+ */
+aid_t async_obsolete_data_read(int phone, void *dst, size_t size,
+    ipc_call_t *dataptr)
+{
+	return async_obsolete_send_2(phone, IPC_M_DATA_READ, (sysarg_t) dst,
+	    (sysarg_t) size, dataptr);
+}
+
+/** Wrapper for IPC_M_DATA_READ calls using the async framework.
+ *
+ * @param phoneid Phone that will be used to contact the receiving side.
+ * @param dst     Address of the beginning of the destination buffer.
+ * @param size    Size of the destination buffer.
+ * @param flags   Flags to control the data transfer.
+ *
+ * @return Zero on success or a negative error code from errno.h.
+ *
+ */
+int async_obsolete_data_read_start_generic(int phoneid, void *dst, size_t size, int flags)
+{
+	return async_obsolete_req_3_0(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,
+	    (sysarg_t) size, (sysarg_t) flags);
+}
+
+/** Wrapper for making IPC_M_CONNECT_TO_ME calls using the async framework.
+ *
+ * Ask through phone for a new connection to some service.
+ *
+ * @param phone           Phone handle used for contacting the other side.
+ * @param arg1            User defined argument.
+ * @param arg2            User defined argument.
+ * @param arg3            User defined argument.
+ * @param client_receiver Connection handing routine.
+ *
+ * @return New phone handle on success or a negative error code.
+ *
+ */
+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 task_hash;
+	sysarg_t phone_hash;
+	int rc = async_obsolete_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
+	    NULL, NULL, NULL, &task_hash, &phone_hash);
+	if (rc != EOK)
+		return rc;
+	
+	if (client_receiver != NULL)
+		async_new_connection(task_hash, phone_hash, 0, NULL,
+		    client_receiver);
+	
+	return EOK;
+}
+
+/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
+ *
+ * Ask through phone for a new connection to some service.
+ *
+ * @param phone Phone handle used for contacting the other side.
+ * @param arg1  User defined argument.
+ * @param arg2  User defined argument.
+ * @param arg3  User defined argument.
+ *
+ * @return New phone handle on success or a negative error code.
+ *
+ */
+int async_obsolete_connect_me_to(int phone, sysarg_t arg1, sysarg_t arg2,
+    sysarg_t arg3)
+{
+	sysarg_t newphid;
+	int rc = async_obsolete_req_3_5(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
+	    NULL, NULL, NULL, NULL, &newphid);
+	
+	if (rc != EOK)
+		return rc;
+	
+	return newphid;
+}
+
+/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
+ *
+ * Ask through phone for a new connection to some service and block until
+ * success.
+ *
+ * @param phoneid Phone handle used for contacting the other side.
+ * @param arg1    User defined argument.
+ * @param arg2    User defined argument.
+ * @param arg3    User defined argument.
+ *
+ * @return New phone handle on success or a negative error code.
+ *
+ */
+int async_obsolete_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
+    sysarg_t arg3)
+{
+	sysarg_t newphid;
+	int rc = async_obsolete_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
+	    IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
+	
+	if (rc != EOK)
+		return rc;
+	
+	return newphid;
+}
+
+/** Send message and return id of the sent message
+ *
+ * The return value can be used as input for async_wait() to wait for
+ * completion.
+ *
+ * @param phoneid Handle of the phone that will be used for the send.
+ * @param method  Service-defined method.
+ * @param arg1    Service-defined payload argument.
+ * @param arg2    Service-defined payload argument.
+ * @param arg3    Service-defined payload argument.
+ * @param arg4    Service-defined payload argument.
+ * @param arg5    Service-defined payload argument.
+ * @param dataptr If non-NULL, storage where the reply data will be
+ *                stored.
+ *
+ * @return Hash of the sent message or 0 on error.
+ *
+ */
+aid_t async_obsolete_send_slow(int phoneid, sysarg_t method, sysarg_t arg1,
+    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
+    ipc_call_t *dataptr)
+{
+	amsg_t *msg = malloc(sizeof(amsg_t));
+	
+	if (!msg)
+		return 0;
+	
+	msg->done = false;
+	msg->dataptr = dataptr;
+	
+	msg->wdata.to_event.inlist = false;
+	
+	/*
+	 * We may sleep in the next method,
+	 * but it will use its own means
+	 */
+	msg->wdata.active = true;
+	
+	ipc_call_async_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, msg,
+	    reply_received, true);
+	
+	return (aid_t) msg;
+}
+
+void async_obsolete_msg_0(int phone, sysarg_t imethod)
+{
+	ipc_call_async_0(phone, imethod, NULL, NULL, true);
+}
+
+void async_obsolete_msg_1(int phone, sysarg_t imethod, sysarg_t arg1)
+{
+	ipc_call_async_1(phone, imethod, arg1, NULL, NULL, true);
+}
+
+void async_obsolete_msg_2(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2)
+{
+	ipc_call_async_2(phone, imethod, arg1, arg2, NULL, NULL, true);
+}
+
+void async_obsolete_msg_3(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
+    sysarg_t arg3)
+{
+	ipc_call_async_3(phone, imethod, arg1, arg2, arg3, NULL, NULL, true);
+}
+
+void async_obsolete_msg_4(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
+    sysarg_t arg3, sysarg_t arg4)
+{
+	ipc_call_async_4(phone, imethod, arg1, arg2, arg3, arg4, NULL, NULL,
+	    true);
+}
+
+void async_obsolete_msg_5(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
+    sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
+{
+	ipc_call_async_5(phone, imethod, arg1, arg2, arg3, arg4, arg5, NULL,
+	    NULL, true);
+}
+
+/** Wrapper for IPC_M_SHARE_IN calls using the async framework.
+ *
+ * @param phoneid Phone that will be used to contact the receiving side.
+ * @param dst     Destination address space area base.
+ * @param size    Size of the destination address space area.
+ * @param arg     User defined argument.
+ * @param flags   Storage for the received flags. Can be NULL.
+ *
+ * @return Zero on success or a negative error code from errno.h.
+ *
+ */
+int async_obsolete_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg,
+    unsigned int *flags)
+{
+	sysarg_t tmp_flags;
+	int res = async_obsolete_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,
+	    (sysarg_t) size, arg, NULL, &tmp_flags);
+	
+	if (flags)
+		*flags = (unsigned int) tmp_flags;
+	
+	return res;
+}
+
+int async_obsolete_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, unsigned int mode)
+{
+	return ipc_forward_fast(callid, phoneid, imethod, arg1, arg2, mode);
+}
+
+int async_obsolete_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
+    unsigned int mode)
+{
+	return ipc_forward_slow(callid, phoneid, imethod, arg1, arg2, arg3, arg4,
+	    arg5, mode);
+}
+
+/** Wrapper for forwarding any data that is about to be received
+ *
+ */
+int async_obsolete_data_write_forward_fast(int phoneid, sysarg_t method, sysarg_t arg1,
+    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
+{
+	ipc_callid_t callid;
+	if (!async_data_write_receive(&callid, NULL)) {
+		ipc_answer_0(callid, EINVAL);
+		return EINVAL;
+	}
+	
+	aid_t msg = async_obsolete_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
+	    dataptr);
+	if (msg == 0) {
+		ipc_answer_0(callid, EINVAL);
+		return EINVAL;
+	}
+	
+	int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
+	    IPC_FF_ROUTE_FROM_ME);
+	if (retval != EOK) {
+		async_wait_for(msg, NULL);
+		ipc_answer_0(callid, retval);
+		return retval;
+	}
+	
+	sysarg_t rc;
+	async_wait_for(msg, &rc);
+	
+	return (int) rc;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/async_sess.c
===================================================================
--- uspace/lib/c/generic/async_sess.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ 	(revision )
@@ -1,309 +1,0 @@
-/*
- * Copyright (c) 2010 Jakub Jermar
- * 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
- */
-
-/**
- * This file implements simple session support for the async framework.
- *
- * By the term 'session', we mean a logical data path between a client and a
- * server over which the client can perform multiple concurrent exchanges.
- * Each exchange consists of one or more requests (IPC calls) which can
- * be potentially blocking.
- *
- * Clients and servers are naturally connected using IPC phones, thus an IPC
- * phone represents a session between a client and a server. In one
- * session, there can be many outstanding exchanges. In the current
- * implementation each concurrent exchanges takes place over a different
- * connection (there can be at most one active exchage per connection).
- *
- * Sessions make it useful for a client or client API to support concurrent
- * requests, independent of the actual implementation. Sessions provide
- * an abstract interface to concurrent IPC communication. This is especially
- * useful for client API stubs that aim to be reentrant (i.e. that allow
- * themselves to be called from different fibrils and threads concurrently).
- *
- * There are several possible implementations of sessions. This implementation
- * uses additional phones to represent sessions. Using phones both for the
- * session and also for its exchages/connections has several advantages:
- *
- * - to make a series of exchanges over a session, the client can continue to
- *   use the existing async framework APIs
- * - the server supports sessions by the virtue of spawning a new connection
- *   fibril, just as it does for every new connection even without sessions
- * - the implementation is pretty straightforward; a very naive implementation
- *   would be to make each exchage using a fresh phone (that is what we
- *   have done in the past); a slightly better approach would be to cache
- *   connections so that they can be reused by a later exchange within
- *   the same session (that is what this implementation does)
- *
- * The main disadvantages of using phones to represent sessions are:
- *
- * - if there are too many exchanges (even cached ones), the task may hit its
- *   limit on the maximum number of connected phones, which could prevent the
- *   task from making new IPC connections to other tasks
- * - if there are too many IPC connections already, it may be impossible to
- *   create an exchange by connecting a new phone thanks to the task's limit on
- *   the maximum number of connected phones
- *
- * These problems can be alleviated by increasing the limit on the maximum
- * number of connected phones to some reasonable value and by limiting the number
- * of cached connections to some fraction of this limit.
- *
- * The cache itself has a mechanism to close some number of unused phones if a
- * new phone cannot be connected, but the outer world currently does not have a
- * way to ask the phone cache to shrink.
- *
- * To minimize the confusion stemming from the fact that we use phones for two
- * things (the session itself and also one for each data connection), this file
- * makes the distinction by using the term 'session phone' for the former and
- * 'data phone' for the latter. Under the hood, all phones remain equal,
- * of course.
- *
- * There is a small inefficiency in that the cache repeatedly allocates and
- * deallocates the conn_node_t structures when in fact it could keep the
- * allocated structures around and reuse them later. But such a solution would
- * be effectively implementing a poor man's slab allocator while it would be
- * better to have the slab allocator ported to uspace so that everyone could
- * benefit from it.
- */
-
-#include <async_sess.h>
-#include <fibril_synch.h>
-#include <adt/list.h>
-#include <adt/hash_table.h>
-#include <malloc.h>
-#include <errno.h>
-#include <assert.h>
-#include <async.h>
-#include "private/async_sess.h"
-
-/** An inactive open connection. */
-typedef struct {
-	link_t sess_link;	/**< Link for the session list of inactive connections. */
-	link_t global_link;	/**< Link for the global list of inactive connections. */
-	int data_phone;		/**< Connected data phone. */
-} conn_node_t;
-
-/**
- * Mutex protecting the inactive_conn_head list, the session list and the
- * avail_phone condition variable.
- */
-static fibril_mutex_t async_sess_mutex;
-
-/**
- * List of all currently inactive connections.
- */
-static LIST_INITIALIZE(inactive_conn_head);
-
-/**
- * List of all open sessions.
- */
-static LIST_INITIALIZE(session_list_head);
-
-/**
- * Condition variable used to wait for a phone to become available.
- */
-static FIBRIL_CONDVAR_INITIALIZE(avail_phone_cv);
-
-/** Initialize the async_sess subsystem.
- *
- * Needs to be called prior to any other interface in this file.
- *
- */
-void __async_sess_init(void)
-{
-	fibril_mutex_initialize(&async_sess_mutex);
-	list_initialize(&inactive_conn_head);
-	list_initialize(&session_list_head);
-}
-
-/** Create a session.
- *
- * Session is a logical datapath from a client task to a server task.
- * One session can accomodate multiple concurrent exchanges. Here
- * @a phone is a phone connected to the desired server task.
- *
- * This function always succeeds.
- *
- * @param sess	Session structure provided by caller, will be filled in.
- * @param phone	Phone connected to the desired server task.
- * @param arg1	Value to pass as first argument upon creating a new
- *		connection. Typical use is to identify a resource within
- *		the server that the caller wants to access (port ID,
- *		interface ID, device ID, etc.).
- */
-void async_session_create(async_sess_t *sess, int phone, sysarg_t arg1)
-{
-	sess->sess_phone = phone;
-	sess->connect_arg1 = arg1;
-	list_initialize(&sess->conn_head);
-	
-	/* Add to list of sessions. */
-	fibril_mutex_lock(&async_sess_mutex);
-	list_append(&sess->sess_link, &session_list_head);
-	fibril_mutex_unlock(&async_sess_mutex);
-}
-
-/** Destroy a session.
- *
- * Dismantle session structure @a sess and release any resources (connections)
- * held by the session.
- *
- * @param sess	Session to destroy.
- */
-void async_session_destroy(async_sess_t *sess)
-{
-	conn_node_t *conn;
-
-	/* Remove from list of sessions. */
-	fibril_mutex_lock(&async_sess_mutex);
-	list_remove(&sess->sess_link);
-	fibril_mutex_unlock(&async_sess_mutex);
-
-	/* We did not connect the phone so we do not hang it up either. */
-	sess->sess_phone = -1;
-
-	/* Tear down all data connections. */
-	while (!list_empty(&sess->conn_head)) {
-		conn = list_get_instance(sess->conn_head.next, conn_node_t,
-		    sess_link);
-
-		list_remove(&conn->sess_link);
-		list_remove(&conn->global_link);
-		
-		async_hangup(conn->data_phone);
-		free(conn);
-	}
-	
-	fibril_condvar_broadcast(&avail_phone_cv);
-}
-
-static void conn_node_initialize(conn_node_t *conn)
-{
-	link_initialize(&conn->sess_link);
-	link_initialize(&conn->global_link);
-	conn->data_phone = -1;
-}
-
-/** Start new exchange in a session.
- *
- * @param sess_phone	Session.
- * @return		Phone representing the new exchange or a negative error
- *			code.
- */
-int async_exchange_begin(async_sess_t *sess)
-{
-	conn_node_t *conn;
-	int data_phone;
-
-	fibril_mutex_lock(&async_sess_mutex);
-
-	if (!list_empty(&sess->conn_head)) {
-		/*
-		 * There are inactive connections in the session.
-		 */
-		conn = list_get_instance(sess->conn_head.next, conn_node_t,
-		    sess_link);
-		list_remove(&conn->sess_link);
-		list_remove(&conn->global_link);
-		
-		data_phone = conn->data_phone;
-		free(conn);
-	} else {
-		/*
-		 * There are no available connections in the session.
-		 * Make a one-time attempt to connect a new data phone.
-		 */
-retry:
-		data_phone = async_connect_me_to(sess->sess_phone,
-		    sess->connect_arg1, 0, 0);
-		if (data_phone >= 0) {
-			/* success, do nothing */
-		} else if (!list_empty(&inactive_conn_head)) {
-			/*
-			 * We did not manage to connect a new phone. But we can
-			 * try to close some of the currently inactive
-			 * connections in other sessions and try again.
-			 */
-			conn = list_get_instance(inactive_conn_head.next,
-			    conn_node_t, global_link);
-			list_remove(&conn->global_link);
-			list_remove(&conn->sess_link);
-			data_phone = conn->data_phone;
-			free(conn);
-			async_hangup(data_phone);
-			goto retry;
-		} else {
-			/*
-			 * Wait for a phone to become available.
-			 */
-			fibril_condvar_wait(&avail_phone_cv, &async_sess_mutex);
-			goto retry;
-		}
-	}
-
-	fibril_mutex_unlock(&async_sess_mutex);
-	return data_phone;
-}
-
-/** Finish an exchange.
- *
- * @param sess		Session.
- * @param data_phone	Phone representing the exchange within the session.
- */
-void async_exchange_end(async_sess_t *sess, int data_phone)
-{
-	conn_node_t *conn;
-
-	fibril_mutex_lock(&async_sess_mutex);
-	fibril_condvar_signal(&avail_phone_cv);
-	conn = (conn_node_t *) malloc(sizeof(conn_node_t));
-	if (!conn) {
-		/*
-		 * Being unable to remember the connected data phone here
-		 * means that we simply hang up.
-		 */
-		async_hangup(data_phone);
-		fibril_mutex_unlock(&async_sess_mutex);
-		return;
-	}
-
-	conn_node_initialize(conn);
-	conn->data_phone = data_phone;
-	list_append(&conn->sess_link, &sess->conn_head);
-	list_append(&conn->global_link, &inactive_conn_head);
-	fibril_mutex_unlock(&async_sess_mutex);
-}
-
-/** @}
- */
Index: uspace/lib/c/generic/clipboard.c
===================================================================
--- uspace/lib/c/generic/clipboard.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/clipboard.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -39,7 +39,8 @@
 
 #include <clipboard.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <ipc/services.h>
 #include <ipc/clipboard.h>
+#include <fibril_synch.h>
 #include <async.h>
 #include <str.h>
@@ -47,13 +48,33 @@
 #include <malloc.h>
 
-static int clip_phone = -1;
-
-/** Connect to clipboard server
- *
- */
-static void clip_connect(void)
-{
-	while (clip_phone < 0)
-		clip_phone = service_connect_blocking(SERVICE_CLIPBOARD, 0, 0);
+static FIBRIL_MUTEX_INITIALIZE(clip_mutex);
+static async_sess_t *clip_sess = NULL;
+
+/** Start an async exchange on the clipboard session.
+ *
+ * @return New exchange.
+ *
+ */
+static async_exch_t *clip_exchange_begin(void)
+{
+	fibril_mutex_lock(&clip_mutex);
+	
+	while (clip_sess == NULL)
+		clip_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
+		    SERVICE_CLIPBOARD, 0, 0);
+	
+	fibril_mutex_unlock(&clip_mutex);
+	
+	return async_exchange_begin(clip_sess);
+}
+
+/** Finish an async exchange on the clipboard session.
+ *
+ * @param exch Exchange to be finished.
+ *
+ */
+static void clip_exchange_end(async_exch_t *exch)
+{
+	async_exchange_end(exch);
 }
 
@@ -73,22 +94,20 @@
 	
 	if (size == 0) {
-		async_serialize_start();
-		clip_connect();
-		
-		sysarg_t rc = async_req_1_0(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_NONE);
-		
-		async_serialize_end();
+		async_exch_t *exch = clip_exchange_begin();
+		sysarg_t rc = async_req_1_0(exch, CLIPBOARD_PUT_DATA,
+		    CLIPBOARD_TAG_NONE);
+		clip_exchange_end(exch);
 		
 		return (int) rc;
 	} else {
-		async_serialize_start();
-		clip_connect();
-		
-		aid_t req = async_send_1(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA, NULL);
-		sysarg_t rc = async_data_write_start(clip_phone, (void *) str, size);
+		async_exch_t *exch = clip_exchange_begin();
+		aid_t req = async_send_1(exch, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA,
+		    NULL);
+		sysarg_t rc = async_data_write_start(exch, (void *) str, size);
+		clip_exchange_end(exch);
+		
 		if (rc != EOK) {
 			sysarg_t rc_orig;
 			async_wait_for(req, &rc_orig);
-			async_serialize_end();
 			if (rc_orig == EOK)
 				return (int) rc;
@@ -98,5 +117,4 @@
 		
 		async_wait_for(req, &rc);
-		async_serialize_end();
 		
 		return (int) rc;
@@ -117,12 +135,11 @@
 	/* Loop until clipboard read succesful */
 	while (true) {
-		async_serialize_start();
-		clip_connect();
+		async_exch_t *exch = clip_exchange_begin();
 		
 		sysarg_t size;
 		sysarg_t tag;
-		sysarg_t rc = async_req_0_2(clip_phone, CLIPBOARD_CONTENT, &size, &tag);
-		
-		async_serialize_end();
+		sysarg_t rc = async_req_0_2(exch, CLIPBOARD_CONTENT, &size, &tag);
+		
+		clip_exchange_end(exch);
 		
 		if (rc != EOK)
@@ -145,8 +162,9 @@
 				return ENOMEM;
 			
-			async_serialize_start();
-			
-			aid_t req = async_send_1(clip_phone, CLIPBOARD_GET_DATA, tag, NULL);
-			rc = async_data_read_start(clip_phone, (void *) sbuf, size);
+			exch = clip_exchange_begin();
+			aid_t req = async_send_1(exch, CLIPBOARD_GET_DATA, tag, NULL);
+			rc = async_data_read_start(exch, (void *) sbuf, size);
+			clip_exchange_end(exch);
+			
 			if ((int) rc == EOVERFLOW) {
 				/*
@@ -154,5 +172,4 @@
 				 * the last call of CLIPBOARD_CONTENT
 				 */
-				async_serialize_end();
 				break;
 			}
@@ -161,5 +178,4 @@
 				sysarg_t rc_orig;
 				async_wait_for(req, &rc_orig);
-				async_serialize_end();
 				if (rc_orig == EOK)
 					return (int) rc;
@@ -169,5 +185,4 @@
 			
 			async_wait_for(req, &rc);
-			async_serialize_end();
 			
 			if (rc == EOK) {
Index: uspace/lib/c/generic/device/char_dev.c
===================================================================
--- uspace/lib/c/generic/device/char_dev.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/device/char_dev.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -45,35 +45,37 @@
  * using its character interface.
  *
- * @param dev_phone	Phone to the device.
- * @param buf		Buffer for the data read from or written to the device.
- * @param size		Maximum size of data (in bytes) to be read or written.
- * @param read		Read from the device if true, write to it otherwise.
+ * @param sess Session to the device.
+ * @param buf  Buffer for the data read from or written to the device.
+ * @param size Maximum size of data (in bytes) to be read or written.
+ * @param read Read from the device if true, write to it otherwise.
  *
- * @return		Non-negative number of bytes actually read from or
- *			written to the device on success, negative error number
- *			otherwise.
+ * @return Non-negative number of bytes actually read from or
+ *         written to the device on success, negative error number
+ *         otherwise.
+ *
  */
-static ssize_t char_dev_rw(int dev_phone, void *buf, size_t size, bool read)
+static ssize_t char_dev_rw(async_sess_t *sess, void *buf, size_t size, bool read)
 {
-	async_serialize_start();
-	
 	ipc_call_t answer;
 	aid_t req;
 	int ret;
 	
+	async_exch_t *exch = async_exchange_begin(sess);
+	
 	if (read) {
-		req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE),
+		req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE),
 		    CHAR_DEV_READ, &answer);
-		ret = async_data_read_start(dev_phone, buf, size);
+		ret = async_data_read_start(exch, buf, size);
 	} else {
-		req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE),
+		req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE),
 		    CHAR_DEV_WRITE, &answer);
-		ret = async_data_write_start(dev_phone, buf, size);
+		ret = async_data_write_start(exch, buf, size);
 	}
+	
+	async_exchange_end(exch);
 	
 	sysarg_t rc;
 	if (ret != EOK) {
 		async_wait_for(req, &rc);
-		async_serialize_end();
 		if (rc == EOK)
 			return (ssize_t) ret;
@@ -83,5 +85,4 @@
 	
 	async_wait_for(req, &rc);
-	async_serialize_end();
 	
 	ret = (int) rc;
@@ -94,29 +95,31 @@
 /** Read from character device.
  *
- * @param dev_phone	Phone to the device.
- * @param buf		Output buffer for the data read from the device.
- * @param size		Maximum size (in bytes) of the data to be read.
+ * @param sess Session to the device.
+ * @param buf  Output buffer for the data read from the device.
+ * @param size Maximum size (in bytes) of the data to be read.
  *
- * @return		Non-negative number of bytes actually read from the
- *			device on success, negative error number otherwise.
+ * @return Non-negative number of bytes actually read from the
+ *         device on success, negative error number otherwise.
+ *
  */
-ssize_t char_dev_read(int dev_phone, void *buf, size_t size)
+ssize_t char_dev_read(async_sess_t *sess, void *buf, size_t size)
 {
-	return char_dev_rw(dev_phone, buf, size, true);
+	return char_dev_rw(sess, buf, size, true);
 }
 
 /** Write to character device.
  *
- * @param dev_phone	Phone to the device.
- * @param buf		Input buffer containg the data to be written to the
- *			device.
- * @param size		Maximum size (in bytes) of the data to be written.
+ * @param sess Session to the device.
+ * @param buf  Input buffer containg the data to be written to the
+ *             device.
+ * @param size Maximum size (in bytes) of the data to be written.
  *
- * @return		Non-negative number of bytes actually written to the
- *			device on success, negative error number otherwise.
+ * @return Non-negative number of bytes actually written to the
+ *         device on success, negative error number otherwise.
+ *
  */
-ssize_t char_dev_write(int dev_phone, void *buf, size_t size)
+ssize_t char_dev_write(async_sess_t *sess, void *buf, size_t size)
 {
-	return char_dev_rw(dev_phone, buf, size, false);
+	return char_dev_rw(sess, buf, size, false);
 }
 
Index: uspace/lib/c/generic/device/hw_res.c
===================================================================
--- uspace/lib/c/generic/device/hw_res.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/device/hw_res.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -38,36 +38,48 @@
 #include <malloc.h>
 
-int hw_res_get_resource_list(int dev_phone, hw_resource_list_t *hw_resources)
+int hw_res_get_resource_list(async_sess_t *sess,
+    hw_resource_list_t *hw_resources)
 {
 	sysarg_t count = 0;
-
-	int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(HW_RES_DEV_IFACE),
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE),
 	    HW_RES_GET_RESOURCE_LIST, &count);
-
-	hw_resources->count = count;
-	if (rc != EOK)
+	
+	if (rc != EOK) {
+		async_exchange_end(exch);
 		return rc;
+	}
 	
 	size_t size = count * sizeof(hw_resource_t);
-	hw_resources->resources = (hw_resource_t *)malloc(size);
-	if (!hw_resources->resources)
+	hw_resource_t *resources = (hw_resource_t *) malloc(size);
+	if (resources == NULL) {
+		// FIXME: This is protocol violation
+		async_exchange_end(exch);
 		return ENOMEM;
+	}
 	
-	rc = async_data_read_start(dev_phone, hw_resources->resources, size);
+	rc = async_data_read_start(exch, resources, size);
+	async_exchange_end(exch);
+	
 	if (rc != EOK) {
-		free(hw_resources->resources);
-		hw_resources->resources = NULL;
+		free(resources);
 		return rc;
 	}
+	
+	hw_resources->resources = resources;
+	hw_resources->count = count;
 	
 	return EOK;
 }
 
-bool hw_res_enable_interrupt(int dev_phone)
+bool hw_res_enable_interrupt(async_sess_t *sess)
 {
-	int rc = async_req_1_0(dev_phone, DEV_IFACE_ID(HW_RES_DEV_IFACE),
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_1_0(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE),
 	    HW_RES_ENABLE_INTERRUPT);
-
-	return rc == EOK;
+	async_exchange_end(exch);
+	
+	return (rc == EOK);
 }
 
Index: uspace/lib/c/generic/devman.c
===================================================================
--- uspace/lib/c/generic/devman.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/devman.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -36,59 +36,141 @@
 
 #include <str.h>
-#include <stdio.h>
 #include <ipc/services.h>
+#include <ns.h>
 #include <ipc/devman.h>
 #include <devman.h>
+#include <fibril_synch.h>
 #include <async.h>
-#include <fibril_synch.h>
 #include <errno.h>
 #include <malloc.h>
 #include <bool.h>
-#include <adt/list.h>
-
-static int devman_phone_driver = -1;
-static int devman_phone_client = -1;
-
-static FIBRIL_MUTEX_INITIALIZE(devman_phone_mutex);
-
-int devman_get_phone(devman_interface_t iface, unsigned int flags)
+
+static FIBRIL_MUTEX_INITIALIZE(devman_driver_block_mutex);
+static FIBRIL_MUTEX_INITIALIZE(devman_client_block_mutex);
+
+static FIBRIL_MUTEX_INITIALIZE(devman_driver_mutex);
+static FIBRIL_MUTEX_INITIALIZE(devman_client_mutex);
+
+static async_sess_t *devman_driver_block_sess = NULL;
+static async_sess_t *devman_client_block_sess = NULL;
+
+static async_sess_t *devman_driver_sess = NULL;
+static async_sess_t *devman_client_sess = NULL;
+
+static void clone_session(fibril_mutex_t *mtx, async_sess_t *src,
+    async_sess_t **dst)
+{
+	fibril_mutex_lock(mtx);
+	
+	if ((*dst == NULL) && (src != NULL))
+		*dst = src;
+	
+	fibril_mutex_unlock(mtx);
+}
+
+/** 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(devman_interface_t iface)
 {
 	switch (iface) {
 	case DEVMAN_DRIVER:
-		fibril_mutex_lock(&devman_phone_mutex);
-		if (devman_phone_driver >= 0) {
-			fibril_mutex_unlock(&devman_phone_mutex);
-			return devman_phone_driver;
+		fibril_mutex_lock(&devman_driver_block_mutex);
+		
+		while (devman_driver_block_sess == NULL) {
+			clone_session(&devman_driver_mutex, devman_driver_sess,
+			    &devman_driver_block_sess);
+			
+			if (devman_driver_block_sess == NULL)
+				devman_driver_block_sess =
+				    service_connect_blocking(EXCHANGE_SERIALIZE,
+				    SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
 		}
 		
-		if (flags & IPC_FLAG_BLOCKING)
-			devman_phone_driver = async_connect_me_to_blocking(
-			    PHONE_NS, SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
-		else
-			devman_phone_driver = async_connect_me_to(PHONE_NS,
-			    SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
-		
-		fibril_mutex_unlock(&devman_phone_mutex);
-		return devman_phone_driver;
+		fibril_mutex_unlock(&devman_driver_block_mutex);
+		
+		clone_session(&devman_driver_mutex, devman_driver_block_sess,
+		    &devman_driver_sess);
+		
+		return async_exchange_begin(devman_driver_block_sess);
 	case DEVMAN_CLIENT:
-		fibril_mutex_lock(&devman_phone_mutex);
-		if (devman_phone_client >= 0) {
-			fibril_mutex_unlock(&devman_phone_mutex);
-			return devman_phone_client;
+		fibril_mutex_lock(&devman_client_block_mutex);
+		
+		while (devman_client_block_sess == NULL) {
+			clone_session(&devman_client_mutex, devman_client_sess,
+			    &devman_client_block_sess);
+			
+			if (devman_client_block_sess == NULL)
+				devman_client_block_sess =
+				    service_connect_blocking(EXCHANGE_SERIALIZE,
+				    SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
 		}
 		
-		if (flags & IPC_FLAG_BLOCKING) {
-			devman_phone_client = async_connect_me_to_blocking(
-			    PHONE_NS, SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
-		} else {
-			devman_phone_client = async_connect_me_to(PHONE_NS,
-			    SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
-		}
-		
-		fibril_mutex_unlock(&devman_phone_mutex);
-		return devman_phone_client;
+		fibril_mutex_unlock(&devman_client_block_mutex);
+		
+		clone_session(&devman_client_mutex, devman_client_block_sess,
+		    &devman_client_sess);
+		
+		return async_exchange_begin(devman_client_block_sess);
 	default:
-		return -1;
-	}
+		return NULL;
+	}
+}
+
+/** Start an async exchange on the devman session.
+ *
+ * @param iface Device manager interface to choose
+ *
+ * @return New exchange.
+ *
+ */
+async_exch_t *devman_exchange_begin(devman_interface_t iface)
+{
+	switch (iface) {
+	case DEVMAN_DRIVER:
+		fibril_mutex_lock(&devman_driver_mutex);
+		
+		if (devman_driver_sess == NULL)
+			devman_driver_sess =
+			    service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAN,
+			    DEVMAN_DRIVER, 0);
+		
+		fibril_mutex_unlock(&devman_driver_mutex);
+		
+		if (devman_driver_sess == NULL)
+			return NULL;
+		
+		return async_exchange_begin(devman_driver_sess);
+	case DEVMAN_CLIENT:
+		fibril_mutex_lock(&devman_client_mutex);
+		
+		if (devman_client_sess == NULL)
+			devman_client_sess =
+			    service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAN,
+			    DEVMAN_CLIENT, 0);
+		
+		fibril_mutex_unlock(&devman_client_mutex);
+		
+		if (devman_client_sess == NULL)
+			return NULL;
+		
+		return async_exchange_begin(devman_client_sess);
+	default:
+		return NULL;
+	}
+}
+
+/** Finish an async exchange on the devman session.
+ *
+ * @param exch Exchange to be finished.
+ *
+ */
+void devman_exchange_end(async_exch_t *exch)
+{
+	async_exchange_end(exch);
 }
 
@@ -96,120 +178,98 @@
 int devman_driver_register(const char *name, async_client_conn_t conn)
 {
-	int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
-	
-	if (phone < 0)
-		return phone;
-	
-	async_serialize_start();
-	
-	ipc_call_t answer;
-	aid_t req = async_send_2(phone, DEVMAN_DRIVER_REGISTER, 0, 0, &answer);
-	
-	sysarg_t retval = async_data_write_start(phone, name, str_size(name));
-	if (retval != EOK) {
-		async_wait_for(req, NULL);
-		async_serialize_end();
-		return -1;
+	async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
+	
+	ipc_call_t answer;
+	aid_t req = async_send_2(exch, DEVMAN_DRIVER_REGISTER, 0, 0, &answer);
+	sysarg_t retval = async_data_write_start(exch, name, str_size(name));
+	
+	devman_exchange_end(exch);
+	
+	if (retval != EOK) {
+		async_wait_for(req, NULL);
+		return retval;
 	}
 	
 	async_set_client_connection(conn);
 	
-	async_connect_to_me(phone, 0, 0, 0, NULL);
+	exch = devman_exchange_begin(DEVMAN_DRIVER);
+	async_connect_to_me(exch, 0, 0, 0, NULL);
+	devman_exchange_end(exch);
+	
 	async_wait_for(req, &retval);
-	
-	async_serialize_end();
-	
 	return retval;
 }
 
-static int devman_send_match_id(int phone, match_id_t *match_id)
-{
-	ipc_call_t answer;
-
-	aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score,
-	    &answer);
-	int retval = async_data_write_start(phone, match_id->id,
-	    str_size(match_id->id));
-
-	async_wait_for(req, NULL);
-	return retval;
-}
-
-
-static int devman_send_match_ids(int phone, match_id_list_t *match_ids)
-{
+/** Add function to a device.
+ *
+ * Request devman to add a new function to the specified device owned by
+ * this driver task.
+ *
+ * @param name      Name of the new function
+ * @param ftype     Function type, fun_inner or fun_exposed
+ * @param match_ids Match IDs (should be empty for fun_exposed)
+ * @param devh      Devman handle of the device
+ * @param funh      Place to store handle of the new function
+ *
+ * @return EOK on success or negative error code.
+ *
+ */
+int devman_add_function(const char *name, fun_type_t ftype,
+    match_id_list_t *match_ids, devman_handle_t devh, devman_handle_t *funh)
+{
+	int match_count = list_count(&match_ids->ids);
+	async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
+	
+	ipc_call_t answer;
+	aid_t req = async_send_3(exch, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype,
+	    devh, match_count, &answer);
+	sysarg_t retval = async_data_write_start(exch, name, str_size(name));
+	if (retval != EOK) {
+		devman_exchange_end(exch);
+		async_wait_for(req, NULL);
+		return retval;
+	}
+	
+	async_wait_for(req, &retval);
+	if (retval != EOK) {
+		devman_exchange_end(exch);
+		
+		if (funh != NULL)
+			*funh = -1;
+		
+		return retval;
+	}
+	
+	if (funh != NULL)
+		*funh = (int) IPC_GET_ARG1(answer);
+	
 	link_t *link = match_ids->ids.next;
 	match_id_t *match_id = NULL;
-	int ret = EOK;
-
+	
 	while (link != &match_ids->ids) {
-		match_id = list_get_instance(link, match_id_t, link); 
-		ret = devman_send_match_id(phone, match_id);
-		if (ret != EOK) {
-			return ret;
+		match_id = list_get_instance(link, match_id_t, link);
+		
+		ipc_call_t answer;
+		aid_t req = async_send_1(exch, DEVMAN_ADD_MATCH_ID,
+		    match_id->score, &answer);
+		retval = async_data_write_start(exch, match_id->id,
+		    str_size(match_id->id));
+		if (retval != EOK) {
+			devman_exchange_end(exch);
+			async_wait_for(req, NULL);
+			return retval;
 		}
-
+		
+		async_wait_for(req, &retval);
+		if (retval != EOK) {
+			devman_exchange_end(exch);
+			return retval;
+		}
+		
 		link = link->next;
 	}
-
-	return ret;
-}
-
-/** Add function to a device.
- *
- * Request devman to add a new function to the specified device owned by
- * this driver task.
- *
- * @param name		Name of the new function
- * @param ftype		Function type, fun_inner or fun_exposed
- * @param match_ids	Match IDs (should be empty for fun_exposed)
- * @param devh		Devman handle of the device
- * @param funh		Place to store handle of the new function
- *
- * @return		EOK on success or negative error code.
- */
-int devman_add_function(const char *name, fun_type_t ftype,
-    match_id_list_t *match_ids, devman_handle_t devh, devman_handle_t *funh)
-{
-	int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
-	int fun_handle;
-	
-	if (phone < 0)
-		return phone;
-	
-	async_serialize_start();
-	
-	int match_count = list_count(&match_ids->ids);
-	ipc_call_t answer;
-
-	aid_t req = async_send_3(phone, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype,
-	    devh, match_count, &answer);
-
-	sysarg_t retval = async_data_write_start(phone, name, str_size(name));
-	if (retval != EOK) {
-		async_wait_for(req, NULL);
-		async_serialize_end();
-		return retval;
-	}
-	
-	int match_ids_rc = devman_send_match_ids(phone, match_ids);
-	
-	async_wait_for(req, &retval);
-	
-	async_serialize_end();
-	
-	/* Prefer the answer to DEVMAN_ADD_FUNCTION in case of errors. */
-	if ((match_ids_rc != EOK) && (retval == EOK)) {
-		retval = match_ids_rc;
-	}
-
-	if (retval == EOK)
-		fun_handle = (int) IPC_GET_ARG1(answer);
-	else
-		fun_handle = -1;
-	
-	*funh = fun_handle;
-
-	return retval;
+	
+	devman_exchange_end(exch);
+	return EOK;
 }
 
@@ -217,76 +277,51 @@
     const char *class_name)
 {
-	int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
-	
-	if (phone < 0)
-		return phone;
-	
-	async_serialize_start();
-	ipc_call_t answer;
-	aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS,
+	async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
+	
+	ipc_call_t answer;
+	aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CLASS,
 	    devman_handle, &answer);
-	
-	sysarg_t retval = async_data_write_start(phone, class_name,
+	sysarg_t retval = async_data_write_start(exch, class_name,
 	    str_size(class_name));
-	if (retval != EOK) {
-		async_wait_for(req, NULL);
-		async_serialize_end();
+	
+	devman_exchange_end(exch);
+	
+	if (retval != EOK) {
+		async_wait_for(req, NULL);
 		return retval;
 	}
 	
 	async_wait_for(req, &retval);
-	async_serialize_end();
-	
 	return retval;
 }
 
-void devman_hangup_phone(devman_interface_t iface)
-{
-	switch (iface) {
-	case DEVMAN_DRIVER:
-		if (devman_phone_driver >= 0) {
-			async_hangup(devman_phone_driver);
-			devman_phone_driver = -1;
-		}
-		break;
-	case DEVMAN_CLIENT:
-		if (devman_phone_client >= 0) {
-			async_hangup(devman_phone_client);
-			devman_phone_client = -1;
-		}
-		break;
-	default:
-		break;
-	}
-}
-
-int devman_device_connect(devman_handle_t handle, unsigned int flags)
-{
-	int phone;
-	
-	if (flags & IPC_FLAG_BLOCKING) {
-		phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,
-		    DEVMAN_CONNECT_TO_DEVICE, handle);
-	} else {
-		phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
-		    DEVMAN_CONNECT_TO_DEVICE, handle);
-	}
-	
-	return phone;
-}
-
-int devman_parent_device_connect(devman_handle_t handle, unsigned int flags)
-{
-	int phone;
-	
-	if (flags & IPC_FLAG_BLOCKING) {
-		phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,
-		    DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
-	} else {
-		phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
-		    DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
-	}
-	
-	return phone;
+async_sess_t *devman_device_connect(exch_mgmt_t mgmt, devman_handle_t handle,
+    unsigned int flags)
+{
+	async_sess_t *sess;
+	
+	if (flags & IPC_FLAG_BLOCKING)
+		sess = service_connect_blocking(mgmt, SERVICE_DEVMAN,
+			    DEVMAN_CONNECT_TO_DEVICE, handle);
+	else
+		sess = service_connect(mgmt, SERVICE_DEVMAN,
+			    DEVMAN_CONNECT_TO_DEVICE, handle);
+	
+	return sess;
+}
+
+async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt,
+    devman_handle_t handle, unsigned int flags)
+{
+	async_sess_t *sess;
+	
+	if (flags & IPC_FLAG_BLOCKING)
+		sess = service_connect_blocking(mgmt, SERVICE_DEVMAN,
+			    DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
+	else
+		sess = service_connect(mgmt, SERVICE_DEVMAN,
+			    DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
+	
+	return sess;
 }
 
@@ -294,30 +329,33 @@
     unsigned int flags)
 {
-	int phone = devman_get_phone(DEVMAN_CLIENT, flags);
-	
-	if (phone < 0)
-		return phone;
-	
-	async_serialize_start();
-	
-	ipc_call_t answer;
-	aid_t req = async_send_2(phone, DEVMAN_DEVICE_GET_HANDLE, flags, 0,
+	async_exch_t *exch;
+	
+	if (flags & IPC_FLAG_BLOCKING)
+		exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
+	else {
+		exch = devman_exchange_begin(DEVMAN_CLIENT);
+		if (exch == NULL)
+			return errno;
+	}
+	
+	ipc_call_t answer;
+	aid_t req = async_send_2(exch, DEVMAN_DEVICE_GET_HANDLE, flags, 0,
 	    &answer);
-	
-	sysarg_t retval = async_data_write_start(phone, pathname,
+	sysarg_t retval = async_data_write_start(exch, pathname,
 	    str_size(pathname));
-	if (retval != EOK) {
-		async_wait_for(req, NULL);
-		async_serialize_end();
+	
+	devman_exchange_end(exch);
+	
+	if (retval != EOK) {
+		async_wait_for(req, NULL);
 		return retval;
 	}
 	
 	async_wait_for(req, &retval);
-	
-	async_serialize_end();
 	
 	if (retval != EOK) {
 		if (handle != NULL)
 			*handle = (devman_handle_t) -1;
+		
 		return retval;
 	}
@@ -332,43 +370,48 @@
     const char *devname, devman_handle_t *handle, unsigned int flags)
 {
-	int phone = devman_get_phone(DEVMAN_CLIENT, flags);
-
-	if (phone < 0)
-		return phone;
-
-	async_serialize_start();
-
-	ipc_call_t answer;
-	aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
+	async_exch_t *exch;
+	
+	if (flags & IPC_FLAG_BLOCKING)
+		exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
+	else {
+		exch = devman_exchange_begin(DEVMAN_CLIENT);
+		if (exch == NULL)
+			return errno;
+	}
+	
+	ipc_call_t answer;
+	aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
 	    flags, &answer);
-
-	sysarg_t retval = async_data_write_start(phone, classname,
+	sysarg_t retval = async_data_write_start(exch, classname,
 	    str_size(classname));
-	if (retval != EOK) {
-		async_wait_for(req, NULL);
-		async_serialize_end();
-		return retval;
-	}
-	retval = async_data_write_start(phone, devname,
+	
+	if (retval != EOK) {
+		devman_exchange_end(exch);
+		async_wait_for(req, NULL);
+		return retval;
+	}
+	
+	retval = async_data_write_start(exch, devname,
 	    str_size(devname));
-	if (retval != EOK) {
-		async_wait_for(req, NULL);
-		async_serialize_end();
-		return retval;
-	}
-
+	
+	devman_exchange_end(exch);
+	
+	if (retval != EOK) {
+		async_wait_for(req, NULL);
+		return retval;
+	}
+	
 	async_wait_for(req, &retval);
-
-	async_serialize_end();
-
+	
 	if (retval != EOK) {
 		if (handle != NULL)
 			*handle = (devman_handle_t) -1;
-		return retval;
-	}
-
+		
+		return retval;
+	}
+	
 	if (handle != NULL)
 		*handle = (devman_handle_t) IPC_GET_ARG1(answer);
-
+	
 	return retval;
 }
@@ -376,59 +419,51 @@
 int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
 {
-	int phone = devman_get_phone(DEVMAN_CLIENT, 0);
-
-	if (phone < 0)
-		return phone;
-
-	async_serialize_start();
-
-	ipc_call_t answer;
-	aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_DEVICE_PATH,
+	async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
+	if (exch == NULL)
+		return errno;
+	
+	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(phone, path, path_size,
+	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);
-		async_serialize_end();
 		return ENOMEM;
 	}
-
+	
 	sysarg_t data_request_rc;
+	async_wait_for(data_request, &data_request_rc);
+	
 	sysarg_t opening_request_rc;
-	async_wait_for(data_request, &data_request_rc);
 	async_wait_for(req, &opening_request_rc);
-
-	async_serialize_end();
-
+	
 	if (data_request_rc != EOK) {
 		/* Prefer the return code of the opening request. */
-		if (opening_request_rc != EOK) {
+		if (opening_request_rc != EOK)
 			return (int) opening_request_rc;
-		} else {
+		else
 			return (int) data_request_rc;
-		}
-	}
-	if (opening_request_rc != EOK) {
+	}
+	
+	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) {
+	if (transferred_size >= path_size)
 		return ELIMIT;
-	}
-
+	
 	/* Terminate the string (trailing 0 not send over IPC). */
 	path[transferred_size] = 0;
-
 	return EOK;
 }
 
-
 /** @}
  */
Index: uspace/lib/c/generic/devman_obsolete.c
===================================================================
--- uspace/lib/c/generic/devman_obsolete.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
+++ uspace/lib/c/generic/devman_obsolete.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2007 Josef Cejka
+ * Copyright (c) 2009 Jiri Svoboda
+ * Copyright (c) 2010 Lenka Trochtova
+ * 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
+ */
+
+#include <str.h>
+#include <stdio.h>
+#include <ipc/services.h>
+#include <ipc/devman.h>
+#include <devman_obsolete.h>
+#include <async.h>
+#include <async_obsolete.h>
+#include <ns.h>
+#include <ns_obsolete.h>
+#include <fibril_synch.h>
+#include <errno.h>
+#include <malloc.h>
+#include <bool.h>
+#include <adt/list.h>
+
+static int devman_phone_driver = -1;
+static int devman_phone_client = -1;
+
+static FIBRIL_MUTEX_INITIALIZE(devman_phone_mutex);
+
+int devman_obsolete_get_phone(devman_interface_t iface, unsigned int flags)
+{
+	switch (iface) {
+	case DEVMAN_DRIVER:
+		fibril_mutex_lock(&devman_phone_mutex);
+		if (devman_phone_driver >= 0) {
+			fibril_mutex_unlock(&devman_phone_mutex);
+			return devman_phone_driver;
+		}
+		
+		if (flags & IPC_FLAG_BLOCKING)
+			devman_phone_driver = service_obsolete_connect_blocking(
+			    SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
+		else
+			devman_phone_driver = service_obsolete_connect(SERVICE_DEVMAN,
+			    DEVMAN_DRIVER, 0);
+		
+		fibril_mutex_unlock(&devman_phone_mutex);
+		return devman_phone_driver;
+	case DEVMAN_CLIENT:
+		fibril_mutex_lock(&devman_phone_mutex);
+		if (devman_phone_client >= 0) {
+			fibril_mutex_unlock(&devman_phone_mutex);
+			return devman_phone_client;
+		}
+		
+		if (flags & IPC_FLAG_BLOCKING) {
+			devman_phone_client = service_obsolete_connect_blocking(
+			    SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
+		} else {
+			devman_phone_client = service_obsolete_connect(SERVICE_DEVMAN,
+			    DEVMAN_CLIENT, 0);
+		}
+		
+		fibril_mutex_unlock(&devman_phone_mutex);
+		return devman_phone_client;
+	default:
+		return -1;
+	}
+}
+
+void devman_obsolete_hangup_phone(devman_interface_t iface)
+{
+	switch (iface) {
+	case DEVMAN_DRIVER:
+		if (devman_phone_driver >= 0) {
+			async_obsolete_hangup(devman_phone_driver);
+			devman_phone_driver = -1;
+		}
+		break;
+	case DEVMAN_CLIENT:
+		if (devman_phone_client >= 0) {
+			async_obsolete_hangup(devman_phone_client);
+			devman_phone_client = -1;
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+int devman_obsolete_device_connect(devman_handle_t handle, unsigned int flags)
+{
+	int phone;
+	
+	if (flags & IPC_FLAG_BLOCKING) {
+		phone = service_obsolete_connect_blocking(SERVICE_DEVMAN,
+		    DEVMAN_CONNECT_TO_DEVICE, handle);
+	} else {
+		phone = service_obsolete_connect(SERVICE_DEVMAN,
+		    DEVMAN_CONNECT_TO_DEVICE, handle);
+	}
+	
+	return phone;
+}
+
+int devman_obsolete_parent_device_connect(devman_handle_t handle, unsigned int flags)
+{
+	int phone;
+	
+	if (flags & IPC_FLAG_BLOCKING) {
+		phone = service_obsolete_connect_blocking(SERVICE_DEVMAN,
+		    DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
+	} else {
+		phone = service_obsolete_connect(SERVICE_DEVMAN,
+		    DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
+	}
+	
+	return phone;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/devmap.c
===================================================================
--- uspace/lib/c/generic/devmap.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/devmap.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -30,7 +30,8 @@
 #include <str.h>
 #include <ipc/services.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <ipc/devmap.h>
 #include <devmap.h>
+#include <fibril_synch.h>
 #include <async.h>
 #include <errno.h>
@@ -38,58 +39,131 @@
 #include <bool.h>
 
-static int devmap_phone_driver = -1;
-static int devmap_phone_client = -1;
-
-/** Get phone to device mapper task. */
-int devmap_get_phone(devmap_interface_t iface, unsigned int flags)
+static FIBRIL_MUTEX_INITIALIZE(devmap_driver_block_mutex);
+static FIBRIL_MUTEX_INITIALIZE(devmap_client_block_mutex);
+
+static FIBRIL_MUTEX_INITIALIZE(devmap_driver_mutex);
+static FIBRIL_MUTEX_INITIALIZE(devmap_client_mutex);
+
+static async_sess_t *devmap_driver_block_sess = NULL;
+static async_sess_t *devmap_client_block_sess = NULL;
+
+static async_sess_t *devmap_driver_sess = NULL;
+static async_sess_t *devmap_client_sess = NULL;
+
+static void clone_session(fibril_mutex_t *mtx, async_sess_t *src,
+    async_sess_t **dst)
+{
+	fibril_mutex_lock(mtx);
+	
+	if ((*dst == NULL) && (src != NULL))
+		*dst = src;
+	
+	fibril_mutex_unlock(mtx);
+}
+
+/** Start an async exchange on the devmap session (blocking).
+ *
+ * @param iface Device mapper interface to choose
+ *
+ * @return New exchange.
+ *
+ */
+async_exch_t *devmap_exchange_begin_blocking(devmap_interface_t iface)
 {
 	switch (iface) {
 	case DEVMAP_DRIVER:
-		if (devmap_phone_driver >= 0)
-			return devmap_phone_driver;
-		
-		if (flags & IPC_FLAG_BLOCKING)
-			devmap_phone_driver = service_connect_blocking(SERVICE_DEVMAP,
-			    DEVMAP_DRIVER, 0);
-		else
-			devmap_phone_driver = service_connect(SERVICE_DEVMAP,
-			    DEVMAP_DRIVER, 0);
-		
-		return devmap_phone_driver;
+		fibril_mutex_lock(&devmap_driver_block_mutex);
+		
+		while (devmap_driver_block_sess == NULL) {
+			clone_session(&devmap_driver_mutex, devmap_driver_sess,
+			    &devmap_driver_block_sess);
+			
+			if (devmap_driver_block_sess == NULL)
+				devmap_driver_block_sess =
+				    service_connect_blocking(EXCHANGE_SERIALIZE,
+				    SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
+		}
+		
+		fibril_mutex_unlock(&devmap_driver_block_mutex);
+		
+		clone_session(&devmap_driver_mutex, devmap_driver_block_sess,
+		    &devmap_driver_sess);
+		
+		return async_exchange_begin(devmap_driver_block_sess);
 	case DEVMAP_CLIENT:
-		if (devmap_phone_client >= 0)
-			return devmap_phone_client;
-		
-		if (flags & IPC_FLAG_BLOCKING)
-			devmap_phone_client = service_connect_blocking(SERVICE_DEVMAP,
-			    DEVMAP_CLIENT, 0);
-		else
-			devmap_phone_client = service_connect(SERVICE_DEVMAP,
-			    DEVMAP_CLIENT, 0);
-		
-		return devmap_phone_client;
+		fibril_mutex_lock(&devmap_client_block_mutex);
+		
+		while (devmap_client_block_sess == NULL) {
+			clone_session(&devmap_client_mutex, devmap_client_sess,
+			    &devmap_client_block_sess);
+			
+			if (devmap_client_block_sess == NULL)
+				devmap_client_block_sess =
+				    service_connect_blocking(EXCHANGE_SERIALIZE,
+				    SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
+		}
+		
+		fibril_mutex_unlock(&devmap_client_block_mutex);
+		
+		clone_session(&devmap_client_mutex, devmap_client_block_sess,
+		    &devmap_client_sess);
+		
+		return async_exchange_begin(devmap_client_block_sess);
 	default:
-		return -1;
-	}
-}
-
-void devmap_hangup_phone(devmap_interface_t iface)
+		return NULL;
+	}
+}
+
+/** Start an async exchange on the devmap session.
+ *
+ * @param iface Device mapper interface to choose
+ *
+ * @return New exchange.
+ *
+ */
+async_exch_t *devmap_exchange_begin(devmap_interface_t iface)
 {
 	switch (iface) {
 	case DEVMAP_DRIVER:
-		if (devmap_phone_driver >= 0) {
-			async_hangup(devmap_phone_driver);
-			devmap_phone_driver = -1;
-		}
-		break;
+		fibril_mutex_lock(&devmap_driver_mutex);
+		
+		if (devmap_driver_sess == NULL)
+			devmap_driver_sess =
+			    service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAP,
+			    DEVMAP_DRIVER, 0);
+		
+		fibril_mutex_unlock(&devmap_driver_mutex);
+		
+		if (devmap_driver_sess == NULL)
+			return NULL;
+		
+		return async_exchange_begin(devmap_driver_sess);
 	case DEVMAP_CLIENT:
-		if (devmap_phone_client >= 0) {
-			async_hangup(devmap_phone_client);
-			devmap_phone_client = -1;
-		}
-		break;
+		fibril_mutex_lock(&devmap_client_mutex);
+		
+		if (devmap_client_sess == NULL)
+			devmap_client_sess =
+			    service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAP,
+			    DEVMAP_CLIENT, 0);
+		
+		fibril_mutex_unlock(&devmap_client_mutex);
+		
+		if (devmap_client_sess == NULL)
+			return NULL;
+		
+		return async_exchange_begin(devmap_client_sess);
 	default:
-		break;
-	}
+		return NULL;
+	}
+}
+
+/** Finish an async exchange on the devmap session.
+ *
+ * @param exch Exchange to be finished.
+ *
+ */
+void devmap_exchange_end(async_exch_t *exch)
+{
+	async_exchange_end(exch);
 }
 
@@ -97,28 +171,24 @@
 int devmap_driver_register(const char *name, async_client_conn_t conn)
 {
-	int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
-	
-	if (phone < 0)
-		return phone;
-	
-	async_serialize_start();
+	async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_DRIVER);
 	
 	ipc_call_t answer;
-	aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
-	
-	sysarg_t retval = async_data_write_start(phone, name, str_size(name));
+	aid_t req = async_send_2(exch, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
+	sysarg_t retval = async_data_write_start(exch, name, str_size(name));
+	
+	devmap_exchange_end(exch);
+	
 	if (retval != EOK) {
 		async_wait_for(req, NULL);
-		async_serialize_end();
-		return -1;
+		return retval;
 	}
 	
 	async_set_client_connection(conn);
 	
-	async_connect_to_me(phone, 0, 0, 0, NULL);
+	exch = devmap_exchange_begin(DEVMAP_DRIVER);
+	async_connect_to_me(exch, 0, 0, 0, NULL);
+	devmap_exchange_end(exch);
+	
 	async_wait_for(req, &retval);
-	
-	async_serialize_end();
-	
 	return retval;
 }
@@ -129,10 +199,11 @@
  * If not 0, the first argument is the interface and the second argument
  * is the devmap handle of the device.
+ *
  * When the interface is zero (default), the first argument is directly
  * the handle (to ensure backward compatibility).
  *
- * @param fqdn Fully qualified device name.
- * @param[out] handle Handle to the created instance of device.
- * @param interface Interface when forwarding.
+ * @param      fqdn      Fully qualified device name.
+ * @param[out] handle    Handle to the created instance of device.
+ * @param      interface Interface when forwarding.
  *
  */
@@ -140,29 +211,24 @@
     devmap_handle_t *handle, sysarg_t interface)
 {
-	int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
-	
-	if (phone < 0)
-		return phone;
-	
-	async_serialize_start();
+	async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_DRIVER);
 	
 	ipc_call_t answer;
-	aid_t req = async_send_2(phone, DEVMAP_DEVICE_REGISTER, interface, 0,
+	aid_t req = async_send_2(exch, DEVMAP_DEVICE_REGISTER, interface, 0,
 	    &answer);
-	
-	sysarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
+	sysarg_t retval = async_data_write_start(exch, fqdn, str_size(fqdn));
+	
+	devmap_exchange_end(exch);
+	
 	if (retval != EOK) {
 		async_wait_for(req, NULL);
-		async_serialize_end();
 		return retval;
 	}
 	
 	async_wait_for(req, &retval);
-	
-	async_serialize_end();
 	
 	if (retval != EOK) {
 		if (handle != NULL)
 			*handle = -1;
+		
 		return retval;
 	}
@@ -176,6 +242,6 @@
 /** Register new device.
  *
- * @param fqdn      Fully qualified device name.
- * @param handle    Output: Handle to the created instance of device.
+ * @param fqdn   Fully qualified device name.
+ * @param handle Output: Handle to the created instance of device.
  *
  */
@@ -185,32 +251,35 @@
 }
 
-
-int devmap_device_get_handle(const char *fqdn, devmap_handle_t *handle, unsigned int flags)
-{
-	int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
-	
-	if (phone < 0)
-		return phone;
-	
-	async_serialize_start();
+int devmap_device_get_handle(const char *fqdn, devmap_handle_t *handle,
+    unsigned int flags)
+{
+	async_exch_t *exch;
+	
+	if (flags & IPC_FLAG_BLOCKING)
+		exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
+	else {
+		exch = devmap_exchange_begin(DEVMAP_CLIENT);
+		if (exch == NULL)
+			return errno;
+	}
 	
 	ipc_call_t answer;
-	aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
+	aid_t req = async_send_2(exch, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
 	    &answer);
-	
-	sysarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
+	sysarg_t retval = async_data_write_start(exch, fqdn, str_size(fqdn));
+	
+	devmap_exchange_end(exch);
+	
 	if (retval != EOK) {
 		async_wait_for(req, NULL);
-		async_serialize_end();
 		return retval;
 	}
 	
 	async_wait_for(req, &retval);
-	
-	async_serialize_end();
 	
 	if (retval != EOK) {
 		if (handle != NULL)
 			*handle = (devmap_handle_t) -1;
+		
 		return retval;
 	}
@@ -222,31 +291,35 @@
 }
 
-int devmap_namespace_get_handle(const char *name, devmap_handle_t *handle, unsigned int flags)
-{
-	int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
-	
-	if (phone < 0)
-		return phone;
-	
-	async_serialize_start();
+int devmap_namespace_get_handle(const char *name, devmap_handle_t *handle,
+    unsigned int flags)
+{
+	async_exch_t *exch;
+	
+	if (flags & IPC_FLAG_BLOCKING)
+		exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
+	else {
+		exch = devmap_exchange_begin(DEVMAP_CLIENT);
+		if (exch == NULL)
+			return errno;
+	}
 	
 	ipc_call_t answer;
-	aid_t req = async_send_2(phone, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0,
+	aid_t req = async_send_2(exch, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0,
 	    &answer);
-	
-	sysarg_t retval = async_data_write_start(phone, name, str_size(name));
+	sysarg_t retval = async_data_write_start(exch, name, str_size(name));
+	
+	devmap_exchange_end(exch);
+	
 	if (retval != EOK) {
 		async_wait_for(req, NULL);
-		async_serialize_end();
 		return retval;
 	}
 	
 	async_wait_for(req, &retval);
-	
-	async_serialize_end();
 	
 	if (retval != EOK) {
 		if (handle != NULL)
 			*handle = (devmap_handle_t) -1;
+		
 		return retval;
 	}
@@ -260,11 +333,11 @@
 devmap_handle_type_t devmap_handle_probe(devmap_handle_t handle)
 {
-	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
-	
-	if (phone < 0)
-		return phone;
+	async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
 	
 	sysarg_t type;
-	int retval = async_req_1_1(phone, DEVMAP_HANDLE_PROBE, handle, &type);
+	int retval = async_req_1_1(exch, DEVMAP_HANDLE_PROBE, handle, &type);
+	
+	devmap_exchange_end(exch);
+	
 	if (retval != EOK)
 		return DEV_HANDLE_NONE;
@@ -273,28 +346,28 @@
 }
 
-int devmap_device_connect(devmap_handle_t handle, unsigned int flags)
-{
-	int phone;
-	
-	if (flags & IPC_FLAG_BLOCKING) {
-		phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP,
+async_sess_t *devmap_device_connect(exch_mgmt_t mgmt, devmap_handle_t handle,
+    unsigned int flags)
+{
+	async_sess_t *sess;
+	
+	if (flags & IPC_FLAG_BLOCKING)
+		sess = service_connect_blocking(mgmt, SERVICE_DEVMAP,
 		    DEVMAP_CONNECT_TO_DEVICE, handle);
-	} else {
-		phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
+	else
+		sess = service_connect(mgmt, SERVICE_DEVMAP,
 		    DEVMAP_CONNECT_TO_DEVICE, handle);
-	}
-	
-	return phone;
+	
+	return sess;
 }
 
 int devmap_null_create(void)
 {
-	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
-	
-	if (phone < 0)
-		return -1;
+	async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
 	
 	sysarg_t null_id;
-	int retval = async_req_0_1(phone, DEVMAP_NULL_CREATE, &null_id);
+	int retval = async_req_0_1(exch, DEVMAP_NULL_CREATE, &null_id);
+	
+	devmap_exchange_end(exch);
+	
 	if (retval != EOK)
 		return -1;
@@ -305,16 +378,13 @@
 void devmap_null_destroy(int null_id)
 {
-	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
-	
-	if (phone < 0)
-		return;
-	
-	async_req_1_0(phone, DEVMAP_NULL_DESTROY, (sysarg_t) null_id);
-}
-
-static size_t devmap_count_namespaces_internal(int phone)
+	async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
+	async_req_1_0(exch, DEVMAP_NULL_DESTROY, (sysarg_t) null_id);
+	devmap_exchange_end(exch);
+}
+
+static size_t devmap_count_namespaces_internal(async_exch_t *exch)
 {
 	sysarg_t count;
-	int retval = async_req_0_1(phone, DEVMAP_GET_NAMESPACE_COUNT, &count);
+	int retval = async_req_0_1(exch, DEVMAP_GET_NAMESPACE_COUNT, &count);
 	if (retval != EOK)
 		return 0;
@@ -323,8 +393,10 @@
 }
 
-static size_t devmap_count_devices_internal(int phone, devmap_handle_t ns_handle)
+static size_t devmap_count_devices_internal(async_exch_t *exch,
+    devmap_handle_t ns_handle)
 {
 	sysarg_t count;
-	int retval = async_req_1_1(phone, DEVMAP_GET_DEVICE_COUNT, ns_handle, &count);
+	int retval = async_req_1_1(exch, DEVMAP_GET_DEVICE_COUNT, ns_handle,
+	    &count);
 	if (retval != EOK)
 		return 0;
@@ -335,32 +407,28 @@
 size_t devmap_count_namespaces(void)
 {
-	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
-	
-	if (phone < 0)
-		return 0;
-	
-	return devmap_count_namespaces_internal(phone);
+	async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
+	size_t size = devmap_count_namespaces_internal(exch);
+	devmap_exchange_end(exch);
+	
+	return size;
 }
 
 size_t devmap_count_devices(devmap_handle_t ns_handle)
 {
-	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
-	
-	if (phone < 0)
-		return 0;
-	
-	return devmap_count_devices_internal(phone, ns_handle);
+	async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
+	size_t size = devmap_count_devices_internal(exch, ns_handle);
+	devmap_exchange_end(exch);
+	
+	return size;
 }
 
 size_t devmap_get_namespaces(dev_desc_t **data)
 {
-	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
-	
-	if (phone < 0)
-		return 0;
-	
 	/* Loop until namespaces read succesful */
 	while (true) {
-		size_t count = devmap_count_namespaces_internal(phone);
+		async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
+		size_t count = devmap_count_namespaces_internal(exch);
+		devmap_exchange_end(exch);
+		
 		if (count == 0)
 			return 0;
@@ -370,10 +438,12 @@
 			return 0;
 		
-		async_serialize_start();
+		exch = devmap_exchange_begin(DEVMAP_CLIENT);
 		
 		ipc_call_t answer;
-		aid_t req = async_send_0(phone, DEVMAP_GET_NAMESPACES, &answer);
-		
-		int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t));
+		aid_t req = async_send_0(exch, DEVMAP_GET_NAMESPACES, &answer);
+		int rc = async_data_read_start(exch, devs, count * sizeof(dev_desc_t));
+		
+		devmap_exchange_end(exch);
+		
 		if (rc == EOVERFLOW) {
 			/*
@@ -381,5 +451,4 @@
 			 * the last call of DEVMAP_DEVICE_GET_NAMESPACE_COUNT
 			 */
-			async_serialize_end();
 			free(devs);
 			continue;
@@ -388,5 +457,4 @@
 		if (rc != EOK) {
 			async_wait_for(req, NULL);
-			async_serialize_end();
 			free(devs);
 			return 0;
@@ -395,5 +463,4 @@
 		sysarg_t retval;
 		async_wait_for(req, &retval);
-		async_serialize_end();
 		
 		if (retval != EOK)
@@ -407,12 +474,10 @@
 size_t devmap_get_devices(devmap_handle_t ns_handle, dev_desc_t **data)
 {
-	int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
-	
-	if (phone < 0)
-		return 0;
-	
-	/* Loop until namespaces read succesful */
+	/* Loop until devices read succesful */
 	while (true) {
-		size_t count = devmap_count_devices_internal(phone, ns_handle);
+		async_exch_t *exch = devmap_exchange_begin_blocking(DEVMAP_CLIENT);
+		size_t count = devmap_count_devices_internal(exch, ns_handle);
+		devmap_exchange_end(exch);
+		
 		if (count == 0)
 			return 0;
@@ -422,10 +487,12 @@
 			return 0;
 		
-		async_serialize_start();
+		exch = devmap_exchange_begin(DEVMAP_CLIENT);
 		
 		ipc_call_t answer;
-		aid_t req = async_send_1(phone, DEVMAP_GET_DEVICES, ns_handle, &answer);
-		
-		int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t));
+		aid_t req = async_send_1(exch, DEVMAP_GET_DEVICES, ns_handle, &answer);
+		int rc = async_data_read_start(exch, devs, count * sizeof(dev_desc_t));
+		
+		devmap_exchange_end(exch);
+		
 		if (rc == EOVERFLOW) {
 			/*
@@ -433,5 +500,4 @@
 			 * the last call of DEVMAP_DEVICE_GET_DEVICE_COUNT
 			 */
-			async_serialize_end();
 			free(devs);
 			continue;
@@ -440,5 +506,4 @@
 		if (rc != EOK) {
 			async_wait_for(req, NULL);
-			async_serialize_end();
 			free(devs);
 			return 0;
@@ -447,5 +512,4 @@
 		sysarg_t retval;
 		async_wait_for(req, &retval);
-		async_serialize_end();
 		
 		if (retval != EOK)
Index: uspace/lib/c/generic/devmap_obsolete.c
===================================================================
--- uspace/lib/c/generic/devmap_obsolete.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
+++ uspace/lib/c/generic/devmap_obsolete.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -0,0 +1,114 @@
+/*
+ * 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/io/console.c
===================================================================
--- uspace/lib/c/generic/io/console.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/io/console.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -37,73 +37,204 @@
 #include <libc.h>
 #include <async.h>
+#include <errno.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <vfs/vfs_sess.h>
 #include <io/console.h>
 #include <ipc/console.h>
 
-void console_clear(int phone)
-{
-	async_msg_0(phone, CONSOLE_CLEAR);
-}
-
-int console_get_size(int phone, sysarg_t *cols, sysarg_t *rows)
-{
-	return async_req_0_2(phone, CONSOLE_GET_SIZE, cols, rows);
-}
-
-void console_set_style(int phone, uint8_t style)
-{
-	async_msg_1(phone, CONSOLE_SET_STYLE, style);
-}
-
-void console_set_color(int phone, uint8_t fg_color, uint8_t bg_color,
+console_ctrl_t *console_init(FILE *ifile, FILE *ofile)
+{
+	console_ctrl_t *ctrl = malloc(sizeof(console_ctrl_t));
+	if (!ctrl)
+		return NULL;
+	
+	ctrl->input_sess = fsession(EXCHANGE_SERIALIZE, ifile);
+	if (!ctrl->input_sess) {
+		free(ctrl);
+		return NULL;
+	}
+	
+	ctrl->output_sess = fsession(EXCHANGE_SERIALIZE, ofile);
+	if (!ctrl->output_sess) {
+		free(ctrl);
+		return NULL;
+	}
+	
+	ctrl->input = ifile;
+	ctrl->output = ofile;
+	ctrl->input_aid = 0;
+	
+	return ctrl;
+}
+
+void console_done(console_ctrl_t *ctrl)
+{
+	free(ctrl);
+}
+
+bool console_kcon(void)
+{
+#if 0
+	return __SYSCALL0(SYS_DEBUG_ACTIVATE_CONSOLE);
+#endif
+	
+	return false;
+}
+
+void console_flush(console_ctrl_t *ctrl)
+{
+	fflush(ctrl->output);
+}
+
+void console_clear(console_ctrl_t *ctrl)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	async_msg_0(exch, CONSOLE_CLEAR);
+	async_exchange_end(exch);
+}
+
+int console_get_size(console_ctrl_t *ctrl, sysarg_t *cols, sysarg_t *rows)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	int rc = async_req_0_2(exch, CONSOLE_GET_SIZE, cols, rows);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+void console_set_style(console_ctrl_t *ctrl, uint8_t style)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	async_msg_1(exch, CONSOLE_SET_STYLE, style);
+	async_exchange_end(exch);
+}
+
+void console_set_color(console_ctrl_t *ctrl, uint8_t fg_color, uint8_t bg_color,
     uint8_t flags)
 {
-	async_msg_3(phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
-}
-
-void console_set_rgb_color(int phone, uint32_t fg_color, uint32_t bg_color)
-{
-	async_msg_2(phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
-}
-
-void console_cursor_visibility(int phone, bool show)
-{
-	async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, (show != false));
-}
-
-int console_get_color_cap(int phone, sysarg_t *ccap)
-{
-	return async_req_0_1(phone, CONSOLE_GET_COLOR_CAP, ccap);
-}
-
-void console_kcon_enable(int phone)
-{
-	async_msg_0(phone, CONSOLE_KCON_ENABLE);
-}
-
-int console_get_pos(int phone, sysarg_t *col, sysarg_t *row)
-{
-	return async_req_0_2(phone, CONSOLE_GET_POS, col, row);
-}
-
-void console_set_pos(int phone, sysarg_t col, sysarg_t row)
-{
-	async_msg_2(phone, CONSOLE_GOTO, col, row);
-}
-
-bool console_get_event(int phone, console_event_t *event)
-{
-	sysarg_t type;
-	sysarg_t key;
-	sysarg_t mods;
-	sysarg_t c;
-	
-	int rc = async_req_0_4(phone, CONSOLE_GET_EVENT, &type, &key, &mods, &c);
-	if (rc < 0)
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	async_msg_3(exch, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
+	async_exchange_end(exch);
+}
+
+void console_set_rgb_color(console_ctrl_t *ctrl, uint32_t fg_color,
+    uint32_t bg_color)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	async_msg_2(exch, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
+	async_exchange_end(exch);
+}
+
+void console_cursor_visibility(console_ctrl_t *ctrl, bool show)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	async_msg_1(exch, CONSOLE_CURSOR_VISIBILITY, (show != false));
+	async_exchange_end(exch);
+}
+
+int console_get_color_cap(console_ctrl_t *ctrl, sysarg_t *ccap)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	int rc = async_req_0_1(exch, CONSOLE_GET_COLOR_CAP, ccap);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+int console_get_pos(console_ctrl_t *ctrl, sysarg_t *col, sysarg_t *row)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	int rc = async_req_0_2(exch, CONSOLE_GET_POS, col, row);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+void console_set_pos(console_ctrl_t *ctrl, sysarg_t col, sysarg_t row)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	async_msg_2(exch, CONSOLE_GOTO, col, row);
+	async_exchange_end(exch);
+}
+
+bool console_get_kbd_event(console_ctrl_t *ctrl, kbd_event_t *event)
+{
+	if (ctrl->input_aid == 0) {
+		sysarg_t type;
+		sysarg_t key;
+		sysarg_t mods;
+		sysarg_t c;
+		
+		async_exch_t *exch = async_exchange_begin(ctrl->input_sess);
+		int rc = async_req_0_4(exch, CONSOLE_GET_EVENT, &type, &key, &mods, &c);
+		async_exchange_end(exch);
+		
+		if (rc != EOK) {
+			errno = rc;
+			return false;
+		}
+		
+		event->type = type;
+		event->key = key;
+		event->mods = mods;
+		event->c = c;
+	} else {
+		sysarg_t retval;
+		async_wait_for(ctrl->input_aid, &retval);
+		
+		ctrl->input_aid = 0;
+		
+		if (retval != EOK) {
+			errno = (int) retval;
+			return false;
+		}
+		
+		event->type = IPC_GET_ARG1(ctrl->input_call);
+		event->key = IPC_GET_ARG2(ctrl->input_call);
+		event->mods = IPC_GET_ARG3(ctrl->input_call);
+		event->c = IPC_GET_ARG4(ctrl->input_call);
+	}
+	
+	return true;
+}
+
+bool console_get_kbd_event_timeout(console_ctrl_t *ctrl, kbd_event_t *event,
+    suseconds_t *timeout)
+{
+	struct timeval t0;
+	gettimeofday(&t0, NULL);
+	
+	if (ctrl->input_aid == 0) {
+		async_exch_t *exch = async_exchange_begin(ctrl->input_sess);
+		ctrl->input_aid = async_send_0(exch, CONSOLE_GET_EVENT,
+		    &ctrl->input_call);
+		async_exchange_end(exch);
+	}
+	
+	sysarg_t retval;
+	int rc = async_wait_timeout(ctrl->input_aid, &retval, *timeout);
+	if (rc != EOK) {
+		*timeout = 0;
+		errno = rc;
 		return false;
-	
-	event->type = type;
-	event->key = key;
-	event->mods = mods;
-	event->c = c;
+	}
+	
+	ctrl->input_aid = 0;
+	
+	if (retval != EOK) {
+		errno = (int) retval;
+		return false;
+	}
+	
+	event->type = IPC_GET_ARG1(ctrl->input_call);
+	event->key = IPC_GET_ARG2(ctrl->input_call);
+	event->mods = IPC_GET_ARG3(ctrl->input_call);
+	event->c = IPC_GET_ARG4(ctrl->input_call);
+	
+	/* Update timeout */
+	struct timeval t1;
+	gettimeofday(&t1, NULL);
+	*timeout -= tv_sub(&t1, &t0);
 	
 	return true;
Index: uspace/lib/c/generic/io/io.c
===================================================================
--- uspace/lib/c/generic/io/io.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/io/io.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -44,7 +44,9 @@
 #include <io/klog.h>
 #include <vfs/vfs.h>
+#include <vfs/vfs_sess.h>
 #include <ipc/devmap.h>
 #include <adt/list.h>
 #include "../private/io.h"
+#include "../private/stdio.h"
 
 static void _ffillbuf(FILE *stream);
@@ -56,5 +58,5 @@
 	.eof = true,
 	.klog = false,
-	.phone = -1,
+	.sess = NULL,
 	.btype = _IONBF,
 	.buf = NULL,
@@ -70,5 +72,5 @@
 	.eof = false,
 	.klog = true,
-	.phone = -1,
+	.sess = NULL,
 	.btype = _IOLBF,
 	.buf = NULL,
@@ -84,5 +86,5 @@
 	.eof = false,
 	.klog = true,
-	.phone = -1,
+	.sess = NULL,
 	.btype = _IONBF,
 	.buf = NULL,
@@ -255,5 +257,5 @@
 	stream->eof = false;
 	stream->klog = false;
-	stream->phone = -1;
+	stream->sess = NULL;
 	stream->need_sync = false;
 	_setvbuf(stream);
@@ -277,5 +279,5 @@
 	stream->eof = false;
 	stream->klog = false;
-	stream->phone = -1;
+	stream->sess = NULL;
 	stream->need_sync = false;
 	_setvbuf(stream);
@@ -309,5 +311,5 @@
 	stream->eof = false;
 	stream->klog = false;
-	stream->phone = -1;
+	stream->sess = NULL;
 	stream->need_sync = false;
 	_setvbuf(stream);
@@ -324,6 +326,6 @@
 	fflush(stream);
 	
-	if (stream->phone >= 0)
-		async_hangup(stream->phone);
+	if (stream->sess != NULL)
+		async_hangup(stream->sess);
 	
 	if (stream->fd >= 0)
@@ -732,5 +734,5 @@
 	}
 	
-	if (stream->fd >= 0 && stream->need_sync) {
+	if ((stream->fd >= 0) && (stream->need_sync)) {
 		/**
 		 * Better than syncing always, but probably still not the
@@ -770,14 +772,14 @@
 }
 
-int fphone(FILE *stream)
+async_sess_t *fsession(exch_mgmt_t mgmt, FILE *stream)
 {
 	if (stream->fd >= 0) {
-		if (stream->phone < 0)
-			stream->phone = fd_phone(stream->fd);
-		
-		return stream->phone;
-	}
-	
-	return -1;
+		if (stream->sess == NULL)
+			stream->sess = fd_session(mgmt, stream->fd);
+		
+		return stream->sess;
+	}
+	
+	return NULL;
 }
 
Index: uspace/lib/c/generic/ipc.c
===================================================================
--- uspace/lib/c/generic/ipc.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/ipc.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -632,4 +632,22 @@
 }
 
+/** Request cloned connection.
+ *
+ * @param phoneid Phone handle used for contacting the other side.
+ *
+ * @return Cloned phone handle on success or a negative error code.
+ *
+ */
+int ipc_connect_me(int phoneid)
+{
+	sysarg_t newphid;
+	int res = ipc_call_sync_0_5(phoneid, IPC_M_CONNECT_ME, NULL, NULL,
+	    NULL, NULL, &newphid);
+	if (res)
+		return res;
+	
+	return newphid;
+}
+
 /** Request new connection.
  *
Index: uspace/lib/c/generic/ipc/ns.c
===================================================================
--- uspace/lib/c/generic/ipc/ns.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- * Copyright (c) 2011 Martin Decky
- * 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
- */
-
-#include <async.h>
-#include <ipc/ns.h>
-
-int service_register(sysarg_t service)
-{
-	return async_connect_to_me(PHONE_NS, service, 0, 0, NULL);
-}
-
-int service_connect(sysarg_t service, sysarg_t arg2, sysarg_t arg3)
-{
-	return async_connect_me_to(PHONE_NS, service, arg2, arg3);
-}
-
-int service_connect_blocking(sysarg_t service, sysarg_t arg2, sysarg_t arg3)
-{
-	return async_connect_me_to_blocking(PHONE_NS, service, arg2, arg3);
-}
-
-/** @}
- */
Index: uspace/lib/c/generic/libc.c
===================================================================
--- uspace/lib/c/generic/libc.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/libc.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -49,5 +49,4 @@
 #include "private/libc.h"
 #include "private/async.h"
-#include "private/async_sess.h"
 #include "private/malloc.h"
 #include "private/io.h"
@@ -64,5 +63,4 @@
 	__malloc_init();
 	__async_init();
-	__async_sess_init();
 	
 	fibril_t *fibril = fibril_setup();
Index: uspace/lib/c/generic/loader.c
===================================================================
--- uspace/lib/c/generic/loader.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/loader.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -35,5 +35,5 @@
 #include <ipc/loader.h>
 #include <ipc/services.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <libc.h>
 #include <task.h>
@@ -44,4 +44,5 @@
 #include <vfs/vfs.h>
 #include <loader/loader.h>
+#include "private/loader.h"
 
 /** Connect to a new program loader.
@@ -63,13 +64,16 @@
 loader_t *loader_connect(void)
 {
-	int phone_id = service_connect_blocking(SERVICE_LOAD, 0, 0);
-	if (phone_id < 0)
-		return NULL;
-	
 	loader_t *ldr = malloc(sizeof(loader_t));
 	if (ldr == NULL)
 		return NULL;
 	
-	ldr->phone_id = phone_id;
+	async_sess_t *sess =
+	    service_connect_blocking(EXCHANGE_SERIALIZE, SERVICE_LOAD, 0, 0);
+	if (sess == NULL) {
+		free(ldr);
+		return NULL;
+	}
+	
+	ldr->sess = sess;
 	return ldr;
 }
@@ -88,15 +92,19 @@
 {
 	/* Get task ID. */
-	ipc_call_t answer;
-	aid_t req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer);
-	int rc = async_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t));
-	if (rc != EOK) {
-		async_wait_for(req, NULL);
-		return rc;
-	}
-	
-	sysarg_t retval;
-	async_wait_for(req, &retval);
-	return (int) retval;
+	async_exch_t *exch = async_exchange_begin(ldr->sess);
+	
+	ipc_call_t answer;
+	aid_t req = async_send_0(exch, LOADER_GET_TASKID, &answer);
+	sysarg_t rc = async_data_read_start(exch, task_id, sizeof(task_id_t));
+	
+	async_exchange_end(exch);
+	
+	if (rc != EOK) {
+		async_wait_for(req, NULL);
+		return (int) rc;
+	}
+	
+	async_wait_for(req, &rc);
+	return (int) rc;
 }
 
@@ -112,26 +120,29 @@
 int loader_set_cwd(loader_t *ldr)
 {
-	char *cwd;
-	size_t len;
-
-	cwd = (char *) malloc(MAX_PATH_LEN + 1);
+	char *cwd = (char *) malloc(MAX_PATH_LEN + 1);
 	if (!cwd)
 		return ENOMEM;
+	
 	if (!getcwd(cwd, MAX_PATH_LEN + 1))
-		str_cpy(cwd, MAX_PATH_LEN + 1, "/"); 
-	len = str_length(cwd);
-	
-	ipc_call_t answer;
-	aid_t req = async_send_0(ldr->phone_id, LOADER_SET_CWD, &answer);
-	int rc = async_data_write_start(ldr->phone_id, cwd, len);
+		str_cpy(cwd, MAX_PATH_LEN + 1, "/");
+	
+	size_t len = str_length(cwd);
+	
+	async_exch_t *exch = async_exchange_begin(ldr->sess);
+	
+	ipc_call_t answer;
+	aid_t req = async_send_0(exch, LOADER_SET_CWD, &answer);
+	sysarg_t rc = async_data_write_start(exch, cwd, len);
+	
+	async_exchange_end(exch);
 	free(cwd);
-	if (rc != EOK) {
-		async_wait_for(req, NULL);
-		return rc;
-	}
-	
-	sysarg_t retval;
-	async_wait_for(req, &retval);
-	return (int) retval;
+	
+	if (rc != EOK) {
+		async_wait_for(req, NULL);
+		return (int) rc;
+	}
+	
+	async_wait_for(req, &rc);
+	return (int) rc;
 }
 
@@ -153,21 +164,23 @@
 	char *pa = absolutize(path, &pa_len);
 	if (!pa)
-		return 0;
+		return ENOMEM;
 	
 	/* Send program pathname */
-	ipc_call_t answer;
-	aid_t req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer);
-	int rc = async_data_write_start(ldr->phone_id, (void *) pa, pa_len);
-	if (rc != EOK) {
-		free(pa);
-		async_wait_for(req, NULL);
-		return rc;
-	}
-	
+	async_exch_t *exch = async_exchange_begin(ldr->sess);
+	
+	ipc_call_t answer;
+	aid_t req = async_send_0(exch, LOADER_SET_PATHNAME, &answer);
+	sysarg_t rc = async_data_write_start(exch, (void *) pa, pa_len);
+	
+	async_exchange_end(exch);
 	free(pa);
 	
-	sysarg_t retval;
-	async_wait_for(req, &retval);
-	return (int) retval;
+	if (rc != EOK) {
+		async_wait_for(req, NULL);
+		return (int) rc;
+	}
+	
+	async_wait_for(req, &rc);
+	return (int) rc;
 }
 
@@ -212,20 +225,21 @@
 	
 	/* Send serialized arguments to the loader */
-	ipc_call_t answer;
-	aid_t req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer);
-	sysarg_t rc = async_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size);
-	if (rc != EOK) {
-		async_wait_for(req, NULL);
-		return rc;
-	}
-	
-	async_wait_for(req, &rc);
-	if (rc != EOK)
-		return rc;
-	
-	/* Free temporary buffer */
+	async_exch_t *exch = async_exchange_begin(ldr->sess);
+	
+	ipc_call_t answer;
+	aid_t req = async_send_0(exch, LOADER_SET_ARGS, &answer);
+	sysarg_t rc = async_data_write_start(exch, (void *) arg_buf,
+	    buffer_size);
+	
+	async_exchange_end(exch);
 	free(arg_buf);
 	
-	return EOK;
+	if (rc != EOK) {
+		async_wait_for(req, NULL);
+		return (int) rc;
+	}
+	
+	async_wait_for(req, &rc);
+	return (int) rc;
 }
 
@@ -266,21 +280,21 @@
 	
 	/* Send serialized files to the loader */
-	ipc_call_t answer;
-	aid_t req = async_send_0(ldr->phone_id, LOADER_SET_FILES, &answer);
-	sysarg_t rc = async_data_write_start(ldr->phone_id, (void *) files_buf,
+	async_exch_t *exch = async_exchange_begin(ldr->sess);
+	
+	ipc_call_t answer;
+	aid_t req = async_send_0(exch, LOADER_SET_FILES, &answer);
+	sysarg_t rc = async_data_write_start(exch, (void *) files_buf,
 	    count * sizeof(fdi_node_t));
-	if (rc != EOK) {
-		async_wait_for(req, NULL);
-		return rc;
-	}
-	
-	async_wait_for(req, &rc);
-	if (rc != EOK)
-		return rc;
-	
-	/* Free temporary buffer */
+	
+	async_exchange_end(exch);
 	free(files_buf);
 	
-	return EOK;
+	if (rc != EOK) {
+		async_wait_for(req, NULL);
+		return (int) rc;
+	}
+	
+	async_wait_for(req, &rc);
+	return (int) rc;
 }
 
@@ -297,5 +311,9 @@
 int loader_load_program(loader_t *ldr)
 {
-	return (int) async_req_0_0(ldr->phone_id, LOADER_LOAD);
+	async_exch_t *exch = async_exchange_begin(ldr->sess);
+	int rc = async_req_0_0(exch, LOADER_LOAD);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
@@ -306,6 +324,6 @@
  * the task and its thread is stopped.
  *
- * After using this function, no further operations must be performed
- * on the loader structure. It should be de-allocated using free().
+ * After using this function, no further operations can be performed
+ * on the loader structure and it is deallocated.
  *
  * @param ldr Loader connection structure.
@@ -316,10 +334,14 @@
 int loader_run(loader_t *ldr)
 {
-	int rc = async_req_0_0(ldr->phone_id, LOADER_RUN);
+	async_exch_t *exch = async_exchange_begin(ldr->sess);
+	int rc = async_req_0_0(exch, LOADER_RUN);
+	async_exchange_end(exch);
+	
 	if (rc != EOK)
 		return rc;
 	
-	async_hangup(ldr->phone_id);
-	ldr->phone_id = 0;
+	async_hangup(ldr->sess);
+	free(ldr);
+	
 	return EOK;
 }
@@ -327,7 +349,7 @@
 /** Cancel the loader session.
  *
- * Tells the loader not to load any program and terminate.
- * After using this function, no further operations must be performed
- * on the loader structure. It should be de-allocated using free().
+ * Tell the loader not to load any program and terminate.
+ * After using this function, no further operations can be performed
+ * on the loader structure and it is deallocated.
  *
  * @param ldr Loader connection structure.
@@ -338,6 +360,6 @@
 void loader_abort(loader_t *ldr)
 {
-	async_hangup(ldr->phone_id);
-	ldr->phone_id = 0;
+	async_hangup(ldr->sess);
+	free(ldr);
 }
 
Index: uspace/lib/c/generic/net/icmp_api.c
===================================================================
--- uspace/lib/c/generic/net/icmp_api.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/net/icmp_api.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -42,4 +42,5 @@
 #include <net/ip_codes.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <sys/types.h>
 #include <sys/time.h>
@@ -83,9 +84,9 @@
 		return EINVAL;
 
-	message_id = async_send_5(icmp_phone, NET_ICMP_ECHO, size, timeout, ttl,
+	message_id = async_obsolete_send_5(icmp_phone, NET_ICMP_ECHO, size, timeout, ttl,
 	    tos, (sysarg_t) dont_fragment, NULL);
 
 	/* Send the address */
-	async_data_write_start(icmp_phone, addr, (size_t) addrlen);
+	async_obsolete_data_write_start(icmp_phone, addr, (size_t) addrlen);
 
 	async_wait_for(message_id, &result);
Index: uspace/lib/c/generic/net/modules.c
===================================================================
--- uspace/lib/c/generic/net/modules.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/net/modules.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -40,4 +40,5 @@
 
 #include <async.h>
+#include <async_obsolete.h>
 #include <malloc.h>
 #include <errno.h>
@@ -45,7 +46,9 @@
 #include <ipc/services.h>
 #include <net/modules.h>
+#include <ns.h>
+#include <ns_obsolete.h>
 
 /** The time between connect requests in microseconds. */
-#define MODULE_WAIT_TIME	(10 * 1000)
+#define MODULE_WAIT_TIME  (10 * 1000)
 
 /** Answer a call.
@@ -138,7 +141,7 @@
 	if (phone >= 0) {
 		/* Request the bidirectional connection */
-		int rc = async_connect_to_me(phone, arg1, arg2, arg3, client_receiver);
+		int rc = async_obsolete_connect_to_me(phone, arg1, arg2, arg3, client_receiver);
 		if (rc != EOK) {
-			async_hangup(phone);
+			async_obsolete_hangup(phone);
 			return rc;
 		}
@@ -172,8 +175,8 @@
 	/* If no timeout is set */
 	if (timeout <= 0)
-		return async_connect_me_to_blocking(PHONE_NS, need, 0, 0);
-
+		return service_obsolete_connect_blocking(need, 0, 0);
+	
 	while (true) {
-		phone = async_connect_me_to(PHONE_NS, need, 0, 0);
+		phone = service_obsolete_connect(need, 0, 0);
 		if ((phone >= 0) || (phone != ENOENT))
 			return phone;
Index: uspace/lib/c/generic/net/socket_client.c
===================================================================
--- uspace/lib/c/generic/net/socket_client.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/net/socket_client.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -39,4 +39,5 @@
 #include <assert.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <fibril_synch.h>
 #include <stdint.h>
@@ -472,5 +473,5 @@
 	}
 
-	rc = (int) async_req_3_3(phone, NET_SOCKET, socket_id, 0, service, NULL,
+	rc = (int) async_obsolete_req_3_3(phone, NET_SOCKET, socket_id, 0, service, NULL,
 	    &fragment_size, &header_size);
 	if (rc != EOK) {
@@ -493,5 +494,5 @@
 		dyn_fifo_destroy(&socket->accepted);
 		free(socket);
-		async_msg_3(phone, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0,
+		async_obsolete_msg_3(phone, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0,
 		    service);
 		return rc;
@@ -538,8 +539,8 @@
 
 	/* Request the message */
-	message_id = async_send_3(socket->phone, message,
+	message_id = async_obsolete_send_3(socket->phone, message,
 	    (sysarg_t) socket->socket_id, arg2, socket->service, NULL);
 	/* Send the address */
-	async_data_write_start(socket->phone, data, datalength);
+	async_obsolete_data_write_start(socket->phone, data, datalength);
 
 	fibril_rwlock_read_unlock(&socket_globals.lock);
@@ -598,5 +599,5 @@
 
 	/* Request listen backlog change */
-	result = (int) async_req_3_0(socket->phone, NET_SOCKET_LISTEN,
+	result = (int) async_obsolete_req_3_0(socket->phone, NET_SOCKET_LISTEN,
 	    (sysarg_t) socket->socket_id, (sysarg_t) backlog, socket->service);
 
@@ -681,10 +682,10 @@
 
 	/* Request accept */
-	message_id = async_send_5(socket->phone, NET_SOCKET_ACCEPT,
+	message_id = async_obsolete_send_5(socket->phone, NET_SOCKET_ACCEPT,
 	    (sysarg_t) socket->socket_id, 0, socket->service, 0,
 	    new_socket->socket_id, &answer);
 
 	/* Read address */
-	async_data_read_start(socket->phone, cliaddr, *addrlen);
+	async_obsolete_data_read_start(socket->phone, cliaddr, *addrlen);
 	fibril_rwlock_write_unlock(&socket_globals.lock);
 	async_wait_for(message_id, &ipc_result);
@@ -780,5 +781,5 @@
 
 	/* Request close */
-	rc = (int) async_req_3_0(socket->phone, NET_SOCKET_CLOSE,
+	rc = (int) async_obsolete_req_3_0(socket->phone, NET_SOCKET_CLOSE,
 	    (sysarg_t) socket->socket_id, 0, socket->service);
 	if (rc != EOK) {
@@ -853,5 +854,5 @@
 
 	/* Request send */
-	message_id = async_send_5(socket->phone, message,
+	message_id = async_obsolete_send_5(socket->phone, message,
 	    (sysarg_t) socket->socket_id,
 	    (fragments == 1 ? datalength : socket->data_fragment_size),
@@ -860,11 +861,11 @@
 	/* Send the address if given */
 	if (!toaddr ||
-	    (async_data_write_start(socket->phone, toaddr, addrlen) == EOK)) {
+	    (async_obsolete_data_write_start(socket->phone, toaddr, addrlen) == EOK)) {
 		if (fragments == 1) {
 			/* Send all if only one fragment */
-			async_data_write_start(socket->phone, data, datalength);
+			async_obsolete_data_write_start(socket->phone, data, datalength);
 		} else {
 			/* Send the first fragment */
-			async_data_write_start(socket->phone, data,
+			async_obsolete_data_write_start(socket->phone, data,
 			    socket->data_fragment_size - socket->header_size);
 			data = ((const uint8_t *) data) +
@@ -873,5 +874,5 @@
 			/* Send the middle fragments */
 			while (--fragments > 1) {
-				async_data_write_start(socket->phone, data,
+				async_obsolete_data_write_start(socket->phone, data,
 				    socket->data_fragment_size);
 				data = ((const uint8_t *) data) +
@@ -880,5 +881,5 @@
 
 			/* Send the last fragment */
-			async_data_write_start(socket->phone, data,
+			async_obsolete_data_write_start(socket->phone, data,
 			    (datalength + socket->header_size) %
 			    socket->data_fragment_size);
@@ -1038,5 +1039,5 @@
 
 		/* Request packet data */
-		message_id = async_send_4(socket->phone, message,
+		message_id = async_obsolete_send_4(socket->phone, message,
 		    (sysarg_t) socket->socket_id, 0, socket->service,
 		    (sysarg_t) flags, &answer);
@@ -1044,8 +1045,8 @@
 		/* Read the address if desired */
 		if(!fromaddr ||
-		    (async_data_read_start(socket->phone, fromaddr,
+		    (async_obsolete_data_read_start(socket->phone, fromaddr,
 		    *addrlen) == EOK)) {
 			/* Read the fragment lengths */
-			if (async_data_read_start(socket->phone, lengths,
+			if (async_obsolete_data_read_start(socket->phone, lengths,
 			    sizeof(int) * (fragments + 1)) == EOK) {
 				if (lengths[fragments] <= datalength) {
@@ -1054,5 +1055,5 @@
 					for (index = 0; index < fragments;
 					    ++index) {
-						async_data_read_start(
+						async_obsolete_data_read_start(
 						    socket->phone, data,
 						    lengths[index]);
@@ -1067,5 +1068,5 @@
 	} else { /* fragments == 1 */
 		/* Request packet data */
-		message_id = async_send_4(socket->phone, message,
+		message_id = async_obsolete_send_4(socket->phone, message,
 		    (sysarg_t) socket->socket_id, 0, socket->service,
 		    (sysarg_t) flags, &answer);
@@ -1073,8 +1074,8 @@
 		/* Read the address if desired */
 		if (!fromaddr ||
-		    (async_data_read_start(socket->phone, fromaddr,
+		    (async_obsolete_data_read_start(socket->phone, fromaddr,
 		        *addrlen) == EOK)) {
 			/* Read all if only one fragment */
-			async_data_read_start(socket->phone, data, datalength);
+			async_obsolete_data_read_start(socket->phone, data, datalength);
 		}
 	}
@@ -1190,13 +1191,13 @@
 
 	/* Request option value */
-	message_id = async_send_3(socket->phone, NET_SOCKET_GETSOCKOPT,
+	message_id = async_obsolete_send_3(socket->phone, NET_SOCKET_GETSOCKOPT,
 	    (sysarg_t) socket->socket_id, (sysarg_t) optname, socket->service,
 	    NULL);
 
 	/* Read the length */
-	if (async_data_read_start(socket->phone, optlen,
+	if (async_obsolete_data_read_start(socket->phone, optlen,
 	    sizeof(*optlen)) == EOK) {
 		/* Read the value */
-		async_data_read_start(socket->phone, value, *optlen);
+		async_obsolete_data_read_start(socket->phone, value, *optlen);
 	}
 
Index: uspace/lib/c/generic/ns.c
===================================================================
--- uspace/lib/c/generic/ns.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
+++ uspace/lib/c/generic/ns.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2011 Martin Decky
+ * 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
+ */
+
+#include <ns.h>
+#include <ipc/ns.h>
+#include <async.h>
+#include <macros.h>
+#include "private/ns.h"
+
+int service_register(sysarg_t service)
+{
+	async_exch_t *exch = async_exchange_begin(session_ns);
+	int rc = async_connect_to_me(exch, service, 0, 0, NULL);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+async_sess_t *service_connect(exch_mgmt_t mgmt, sysarg_t service, sysarg_t arg2,
+    sysarg_t arg3)
+{
+	async_exch_t *exch = async_exchange_begin(session_ns);
+	async_sess_t *sess =
+	    async_connect_me_to(mgmt, exch, service, arg2, arg3);
+	async_exchange_end(exch);
+	
+	return sess;
+}
+
+async_sess_t *service_connect_blocking(exch_mgmt_t mgmt, sysarg_t service,
+    sysarg_t arg2, sysarg_t arg3)
+{
+	async_exch_t *exch = async_exchange_begin(session_ns);
+	async_sess_t *sess =
+	    async_connect_me_to_blocking(mgmt, exch, service, arg2, arg3);
+	async_exchange_end(exch);
+	
+	return sess;
+}
+
+int ns_ping(void)
+{
+	async_exch_t *exch = async_exchange_begin(session_ns);
+	int rc = async_req_0_0(exch, NS_PING);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+int ns_intro(task_id_t id)
+{
+	async_exch_t *exch = async_exchange_begin(session_ns);
+	int rc = async_req_2_0(exch, NS_ID_INTRO, LOWER32(id), UPPER32(id));
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/ns_obsolete.c
===================================================================
--- uspace/lib/c/generic/ns_obsolete.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
+++ uspace/lib/c/generic/ns_obsolete.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2011 Martin Decky
+ * 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
+ */
+
+#include <async.h>
+#include <async_obsolete.h>
+#include <ns_obsolete.h>
+#include <kernel/ipc/ipc_methods.h>
+
+int service_obsolete_connect(sysarg_t service, sysarg_t arg2, sysarg_t arg3)
+{
+	return async_obsolete_connect_me_to(PHONE_NS, service, arg2, arg3);
+}
+
+int service_obsolete_connect_blocking(sysarg_t service, sysarg_t arg2, sysarg_t arg3)
+{
+	return async_obsolete_connect_me_to_blocking(PHONE_NS, service, arg2, arg3);
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/private/async.h
===================================================================
--- uspace/lib/c/generic/private/async.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/private/async.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -79,6 +79,20 @@
 } awaiter_t;
 
+/** Message data */
+typedef struct {
+	awaiter_t wdata;
+	
+	/** If reply was received. */
+	bool done;
+	
+	/** Pointer to where the answer data is stored. */
+	ipc_call_t *dataptr;
+	
+	sysarg_t retval;
+} amsg_t;
+
 extern void __async_init(void);
 extern void async_insert_timeout(awaiter_t *);
+extern void reply_received(void *, int, ipc_call_t *);
 
 #endif
Index: uspace/lib/c/generic/private/async_sess.h
===================================================================
--- uspace/lib/c/generic/private/async_sess.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ 	(revision )
@@ -1,43 +1,0 @@
-/*
- * Copyright (c) 2011 Martin Decky
- * 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_PRIVATE_ASYNC_SESS_H_
-#define LIBC_PRIVATE_ASYNC_SESS_H_
-
-extern void __async_sess_init(void);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/generic/private/loader.h
===================================================================
--- uspace/lib/c/generic/private/loader.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
+++ uspace/lib/c/generic/private/loader.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2011 Martin Decky
+ * 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_PRIVATE_LOADER_H_
+#define LIBC_PRIVATE_LOADER_H_
+
+#include <loader/loader.h>
+
+/** Abstraction of a loader connection */
+struct loader {
+	/** Session to the loader. */
+	async_sess_t *sess;
+};
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/generic/private/ns.h
===================================================================
--- uspace/lib/c/generic/private/ns.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
+++ uspace/lib/c/generic/private/ns.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011 Martin Decky
+ * 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_PRIVATE_NS_H_
+#define LIBC_PRIVATE_NS_H_
+
+#include <async.h>
+
+extern async_sess_t *session_ns;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/generic/private/stdio.h
===================================================================
--- uspace/lib/c/generic/private/stdio.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
+++ uspace/lib/c/generic/private/stdio.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2011 Martin Decky
+ * 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_PRIVATE_STDIO_H_
+#define LIBC_PRIVATE_STDIO_H_
+
+#include <adt/list.h>
+#include <stdio.h>
+#include <async.h>
+
+struct _IO_FILE {
+	/** Linked list pointer. */
+	link_t link;
+	
+	/** Underlying file descriptor. */
+	int fd;
+	
+	/** Error indicator. */
+	int error;
+	
+	/** End-of-file indicator. */
+	int eof;
+	
+	/** Klog indicator */
+	int klog;
+	
+	/** Session to the file provider */
+	async_sess_t *sess;
+	
+	/**
+	 * Non-zero if the stream needs sync on fflush(). XXX change
+	 * console semantics so that sync is not needed.
+	 */
+	int need_sync;
+	
+	/** Buffering type */
+	enum _buffer_type btype;
+	
+	/** Buffer */
+	uint8_t *buf;
+	
+	/** Buffer size */
+	size_t buf_size;
+	
+	/** Buffer state */
+	enum _buffer_state buf_state;
+	
+	/** Buffer I/O pointer */
+	uint8_t *buf_head;
+	
+	/** Points to end of occupied space when in read mode. */
+	uint8_t *buf_tail;
+};
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/generic/str_error.c
===================================================================
--- uspace/lib/c/generic/str_error.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/str_error.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -70,4 +70,5 @@
 	
 	/* Ad hoc descriptions of error codes interesting for USB. */
+	// FIXME: integrate these as first-class error values
 	switch (e) {
 		case EBADCHECKSUM:
Index: uspace/lib/c/generic/task.c
===================================================================
--- uspace/lib/c/generic/task.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/task.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -35,7 +35,4 @@
 
 #include <task.h>
-#include <libc.h>
-#include <stdlib.h>
-#include <errno.h>
 #include <loader/loader.h>
 #include <stdarg.h>
@@ -43,5 +40,10 @@
 #include <ipc/ns.h>
 #include <macros.h>
+#include <assert.h>
 #include <async.h>
+#include <errno.h>
+#include <malloc.h>
+#include <libc.h>
+#include "private/ns.h"
 
 task_id_t task_get_id(void)
@@ -68,4 +70,6 @@
 int task_set_name(const char *name)
 {
+	assert(name);
+	
 	return __SYSCALL2(SYS_TASK_SET_NAME, (sysarg_t) name, str_size(name));
 }
@@ -88,23 +92,21 @@
  * loader API. Arguments are passed as a null-terminated array of strings.
  *
- * @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.
- *
- * @return	Zero on success or negative error code.
+ * @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.
+ *
+ * @return Zero on success or negative error code.
+ *
  */
 int task_spawnv(task_id_t *id, const char *path, const char *const args[])
 {
-	loader_t *ldr;
-	task_id_t task_id;
-	int rc;
-
 	/* Connect to a program loader. */
-	ldr = loader_connect();
+	loader_t *ldr = loader_connect();
 	if (ldr == NULL)
 		return EREFUSED;
 	
 	/* Get task ID. */
-	rc = loader_get_task_id(ldr, &task_id);
+	task_id_t task_id;
+	int rc = loader_get_task_id(ldr, &task_id);
 	if (rc != EOK)
 		goto error;
@@ -163,6 +165,4 @@
 	
 	/* Success */
-	free(ldr);
-	
 	if (id != NULL)
 		*id = task_id;
@@ -182,19 +182,20 @@
  * loader API. Arguments are passed as a null-terminated list of arguments.
  *
- * @param id 	If not NULL, the ID of the task is stored here on success.
- * @param path	Pathname of the binary to execute.
- * @param ...	Command-line arguments.
- *
- * @return	Zero on success or negative error code.
+ * @param id   If not NULL, the ID of the task is stored here on success.
+ * @param path Pathname of the binary to execute.
+ * @param ...  Command-line arguments.
+ *
+ * @return Zero on success or negative error code.
+ *
  */
 int task_spawnl(task_id_t *task_id, const char *path, ...)
 {
+	/* Count the number of arguments. */
+	
 	va_list ap;
-	int rc, cnt;
 	const char *arg;
 	const char **arglist;
-
-	/* Count the number of arguments. */
-	cnt = 0;
+	int cnt = 0;
+	
 	va_start(ap, path);
 	do {
@@ -203,10 +204,10 @@
 	} while (arg != NULL);
 	va_end(ap);
-
+	
 	/* Allocate argument list. */
 	arglist = malloc(cnt * sizeof(const char *));
 	if (arglist == NULL)
 		return ENOMEM;
-
+	
 	/* Fill in arguments. */
 	cnt = 0;
@@ -217,8 +218,8 @@
 	} while (arg != NULL);
 	va_end(ap);
-
+	
 	/* Spawn task. */
-	rc = task_spawnv(task_id, path, arglist);
-
+	int rc = task_spawnv(task_id, path, arglist);
+	
 	/* Free argument list. */
 	free(arglist);
@@ -228,12 +229,16 @@
 int task_wait(task_id_t id, task_exit_t *texit, int *retval)
 {
+	assert(texit);
+	assert(retval);
+	
+	async_exch_t *exch = async_exchange_begin(session_ns);
 	sysarg_t te, rv;
-	int rc;
-
-	rc = (int) async_req_2_2(PHONE_NS, NS_TASK_WAIT, LOWER32(id),
+	int rc = (int) async_req_2_2(exch, NS_TASK_WAIT, LOWER32(id),
 	    UPPER32(id), &te, &rv);
+	async_exchange_end(exch);
+	
 	*texit = te;
 	*retval = rv;
-
+	
 	return rc;
 }
@@ -241,5 +246,9 @@
 int task_retval(int val)
 {
-	return (int) async_req_1_0(PHONE_NS, NS_RETVAL, val);
+	async_exch_t *exch = async_exchange_begin(session_ns);
+	int rc = (int) async_req_1_0(exch, NS_RETVAL, val);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
Index: uspace/lib/c/generic/udebug.c
===================================================================
--- uspace/lib/c/generic/udebug.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/udebug.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -35,102 +35,108 @@
 #include <udebug.h>
 #include <sys/types.h>
+#include <kernel/ipc/ipc_methods.h>
 #include <async.h>
 
-int udebug_begin(int phoneid)
+int udebug_begin(async_sess_t *sess)
 {
-	return async_req_1_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_BEGIN);
+	async_exch_t *exch = async_exchange_begin(sess);
+	return async_req_1_0(exch, IPC_M_DEBUG, UDEBUG_M_BEGIN);
 }
 
-int udebug_end(int phoneid)
+int udebug_end(async_sess_t *sess)
 {
-	return async_req_1_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_END);
+	async_exch_t *exch = async_exchange_begin(sess);
+	return async_req_1_0(exch, IPC_M_DEBUG, UDEBUG_M_END);
 }
 
-int udebug_set_evmask(int phoneid, udebug_evmask_t mask)
+int udebug_set_evmask(async_sess_t *sess, udebug_evmask_t mask)
 {
-	return async_req_2_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_SET_EVMASK,
-		mask);
+	async_exch_t *exch = async_exchange_begin(sess);
+	return async_req_2_0(exch, IPC_M_DEBUG, UDEBUG_M_SET_EVMASK, mask);
 }
 
-int udebug_thread_read(int phoneid, void *buffer, size_t n,
-	size_t *copied, size_t *needed)
+int udebug_thread_read(async_sess_t *sess, void *buffer, size_t n,
+    size_t *copied, size_t *needed)
 {
 	sysarg_t a_copied, a_needed;
-	int rc;
-
-	rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_THREAD_READ,
-		(sysarg_t)buffer, n, NULL, &a_copied, &a_needed);
-
-	*copied = (size_t)a_copied;
-	*needed = (size_t)a_needed;
-
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_THREAD_READ,
+	    (sysarg_t) buffer, n, NULL, &a_copied, &a_needed);
+	
+	*copied = (size_t) a_copied;
+	*needed = (size_t) a_needed;
+	
 	return rc;
 }
 
-int udebug_name_read(int phoneid, void *buffer, size_t n,
-	size_t *copied, size_t *needed)
+int udebug_name_read(async_sess_t *sess, void *buffer, size_t n,
+    size_t *copied, size_t *needed)
 {
 	sysarg_t a_copied, a_needed;
-	int rc;
-
-	rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_NAME_READ,
-		(sysarg_t)buffer, n, NULL, &a_copied, &a_needed);
-
-	*copied = (size_t)a_copied;
-	*needed = (size_t)a_needed;
-
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_NAME_READ,
+	    (sysarg_t) buffer, n, NULL, &a_copied, &a_needed);
+	
+	*copied = (size_t) a_copied;
+	*needed = (size_t) a_needed;
+	
 	return rc;
 }
 
-int udebug_areas_read(int phoneid, void *buffer, size_t n,
-	size_t *copied, size_t *needed)
+int udebug_areas_read(async_sess_t *sess, void *buffer, size_t n,
+    size_t *copied, size_t *needed)
 {
 	sysarg_t a_copied, a_needed;
-	int rc;
-
-	rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_AREAS_READ,
-		(sysarg_t)buffer, n, NULL, &a_copied, &a_needed);
-
-	*copied = (size_t)a_copied;
-	*needed = (size_t)a_needed;
-
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_AREAS_READ,
+	    (sysarg_t) buffer, n, NULL, &a_copied, &a_needed);
+	
+	*copied = (size_t) a_copied;
+	*needed = (size_t) a_needed;
+	
 	return rc;
 }
 
-int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n)
+int udebug_mem_read(async_sess_t *sess, void *buffer, uintptr_t addr, size_t n)
 {
-	return async_req_4_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_MEM_READ,
-	    (sysarg_t)buffer, addr, n);
+	async_exch_t *exch = async_exchange_begin(sess);
+	return async_req_4_0(exch, IPC_M_DEBUG, UDEBUG_M_MEM_READ,
+	    (sysarg_t) buffer, addr, n);
 }
 
-int udebug_args_read(int phoneid, thash_t tid, sysarg_t *buffer)
+int udebug_args_read(async_sess_t *sess, thash_t tid, sysarg_t *buffer)
 {
-	return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_ARGS_READ,
-	    tid, (sysarg_t)buffer);
+	async_exch_t *exch = async_exchange_begin(sess);
+	return async_req_3_0(exch, IPC_M_DEBUG, UDEBUG_M_ARGS_READ,
+	    tid, (sysarg_t) buffer);
 }
 
-int udebug_regs_read(int phoneid, thash_t tid, void *buffer)
+int udebug_regs_read(async_sess_t *sess, thash_t tid, void *buffer)
 {
-	return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_REGS_READ,
-	    tid, (sysarg_t)buffer);
+	async_exch_t *exch = async_exchange_begin(sess);
+	return async_req_3_0(exch, IPC_M_DEBUG, UDEBUG_M_REGS_READ,
+	    tid, (sysarg_t) buffer);
 }
 
-int udebug_go(int phoneid, thash_t tid, udebug_event_t *ev_type,
+int udebug_go(async_sess_t *sess, thash_t tid, udebug_event_t *ev_type,
     sysarg_t *val0, sysarg_t *val1)
 {
 	sysarg_t a_ev_type;
-	int rc;
-
-	rc =  async_req_2_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_GO,
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_2_3(exch, IPC_M_DEBUG, UDEBUG_M_GO,
 	    tid, &a_ev_type, val0, val1);
-
+	
 	*ev_type = a_ev_type;
 	return rc;
 }
 
-int udebug_stop(int phoneid, thash_t tid)
+int udebug_stop(async_sess_t *sess, thash_t tid)
 {
-	return async_req_2_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_STOP,
-	    tid);
+	async_exch_t *exch = async_exchange_begin(sess);
+	return async_req_2_0(exch, IPC_M_DEBUG, UDEBUG_M_STOP, tid);
 }
 
Index: uspace/lib/c/generic/vfs/vfs.c
===================================================================
--- uspace/lib/c/generic/vfs/vfs.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/generic/vfs/vfs.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -33,6 +33,7 @@
  */
 
+#include <vfs/canonify.h>
 #include <vfs/vfs.h>
-#include <vfs/canonify.h>
+#include <vfs/vfs_sess.h>
 #include <macros.h>
 #include <stdlib.h>
@@ -44,5 +45,5 @@
 #include <sys/types.h>
 #include <ipc/services.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <async.h>
 #include <fibril_synch.h>
@@ -54,8 +55,6 @@
 #include <ipc/devmap.h>
 
-static async_sess_t vfs_session;
-
-static FIBRIL_MUTEX_INITIALIZE(vfs_phone_mutex);
-static int vfs_phone = -1;
+static FIBRIL_MUTEX_INITIALIZE(vfs_mutex);
+static async_sess_t *vfs_sess = NULL;
 
 static FIBRIL_MUTEX_INITIALIZE(cwd_mutex);
@@ -65,9 +64,36 @@
 static size_t cwd_size = 0;
 
+/** Start an async exchange on the VFS session.
+ *
+ * @return New exchange.
+ *
+ */
+static async_exch_t *vfs_exchange_begin(void)
+{
+	fibril_mutex_lock(&vfs_mutex);
+	
+	while (vfs_sess == NULL)
+		vfs_sess = service_connect_blocking(EXCHANGE_PARALLEL, SERVICE_VFS,
+		    0, 0);
+	
+	fibril_mutex_unlock(&vfs_mutex);
+	
+	return async_exchange_begin(vfs_sess);
+}
+
+/** Finish an async exchange on the VFS session.
+ *
+ * @param exch Exchange to be finished.
+ *
+ */
+static void vfs_exchange_end(async_exch_t *exch)
+{
+	async_exchange_end(exch);
+}
+
 char *absolutize(const char *path, size_t *retlen)
 {
 	char *ncwd_path;
 	char *ncwd_path_nc;
-	size_t total_size; 
 
 	fibril_mutex_lock(&cwd_mutex);
@@ -78,16 +104,14 @@
 			return NULL;
 		}
-		total_size = cwd_size + 1 + size + 1;
-		ncwd_path_nc = malloc(total_size);
+		ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
 		if (!ncwd_path_nc) {
 			fibril_mutex_unlock(&cwd_mutex);
 			return NULL;
 		}
-		str_cpy(ncwd_path_nc, total_size, cwd_path);
+		str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);
 		ncwd_path_nc[cwd_size] = '/';
 		ncwd_path_nc[cwd_size + 1] = '\0';
 	} else {
-		total_size = size + 1;
-		ncwd_path_nc = malloc(total_size);
+		ncwd_path_nc = malloc(size + 1);
 		if (!ncwd_path_nc) {
 			fibril_mutex_unlock(&cwd_mutex);
@@ -96,5 +120,5 @@
 		ncwd_path_nc[0] = '\0';
 	}
-	str_append(ncwd_path_nc, total_size, path);
+	str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);
 	ncwd_path = canonify(ncwd_path_nc, retlen);
 	if (!ncwd_path) {
@@ -118,36 +142,4 @@
 }
 
-/** Connect to VFS service and create session. */
-static void vfs_connect(void)
-{
-	while (vfs_phone < 0)
-		vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
-	
-	async_session_create(&vfs_session, vfs_phone, 0);
-}
-
-/** Start an async exchange on the VFS session.
- *
- * @return		New phone to be used during the exchange.
- */
-static int vfs_exchange_begin(void)
-{
-	fibril_mutex_lock(&vfs_phone_mutex);
-	if (vfs_phone < 0)
-		vfs_connect();
-	fibril_mutex_unlock(&vfs_phone_mutex);
-
-	return async_exchange_begin(&vfs_session);
-}
-
-/** End an async exchange on the VFS session.
- *
- * @param phone		Phone used during the exchange.
- */
-static void vfs_exchange_end(int phone)
-{
-	async_exchange_end(&vfs_session, phone);
-}
-
 int mount(const char *fs_name, const char *mp, const char *fqdn,
     const char *opts, unsigned int flags)
@@ -186,11 +178,11 @@
 	}
 	
-	int vfs_phone = vfs_exchange_begin();
+	async_exch_t *exch = vfs_exchange_begin();
 
 	sysarg_t rc_orig;
-	aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL);
-	sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	aid_t req = async_send_2(exch, VFS_IN_MOUNT, devmap_handle, flags, NULL);
+	sysarg_t rc = async_data_write_start(exch, (void *) mpa, mpa_size);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(mpa);
 		async_wait_for(req, &rc_orig);
@@ -205,7 +197,7 @@
 	}
 	
-	rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	rc = async_data_write_start(exch, (void *) opts, str_size(opts));
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(mpa);
 		async_wait_for(req, &rc_orig);
@@ -220,7 +212,7 @@
 	}
 	
-	rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	rc = async_data_write_start(exch, (void *) fs_name, str_size(fs_name));
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(mpa);
 		async_wait_for(req, &rc_orig);
@@ -236,7 +228,7 @@
 	
 	/* Ask VFS whether it likes fs_name. */
-	rc = async_req_0_0(vfs_phone, IPC_M_PING);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	rc = async_req_0_0(exch, VFS_IN_PING);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(mpa);
 		async_wait_for(req, &rc_orig);
@@ -251,5 +243,5 @@
 	}
 	
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	free(mpa);
 	async_wait_for(req, &rc);
@@ -273,10 +265,10 @@
 		return ENOMEM;
 	
-	int vfs_phone = vfs_exchange_begin();
-	
-	req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
-	rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	async_exch_t *exch = vfs_exchange_begin();
+	
+	req = async_send_0(exch, VFS_IN_UNMOUNT, NULL);
+	rc = async_data_write_start(exch, (void *) mpa, mpa_size);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(mpa);
 		async_wait_for(req, &rc_orig);
@@ -288,5 +280,5 @@
 	
 
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	free(mpa);
 	async_wait_for(req, &rc);
@@ -297,12 +289,12 @@
 static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
 {
-	int vfs_phone = vfs_exchange_begin();
+	async_exch_t *exch = vfs_exchange_begin();
 	
 	ipc_call_t answer;
-	aid_t req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);
-	sysarg_t rc = async_data_write_start(vfs_phone, abs, abs_size);
-	
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	aid_t req = async_send_3(exch, VFS_IN_OPEN, lflag, oflag, 0, &answer);
+	sysarg_t rc = async_data_write_start(exch, abs, abs_size);
+	
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 
 		sysarg_t rc_orig;
@@ -315,5 +307,5 @@
 	}
 	
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	async_wait_for(req, &rc);
 	
@@ -339,11 +331,11 @@
 int open_node(fdi_node_t *node, int oflag)
 {
-	int vfs_phone = vfs_exchange_begin();
+	async_exch_t *exch = vfs_exchange_begin();
 	
 	ipc_call_t answer;
-	aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,
+	aid_t req = async_send_4(exch, VFS_IN_OPEN_NODE, node->fs_handle,
 	    node->devmap_handle, node->index, oflag, &answer);
 	
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 
 	sysarg_t rc;
@@ -360,11 +352,9 @@
 	sysarg_t rc;
 	
-	int vfs_phone = vfs_exchange_begin();
-	
-	rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
-	
-	vfs_exchange_end(vfs_phone);
-	
-	return (int)rc;
+	async_exch_t *exch = vfs_exchange_begin();
+	rc = async_req_1_0(exch, VFS_IN_CLOSE, fildes);
+	vfs_exchange_end(exch);
+	
+	return (int) rc;
 }
 
@@ -374,12 +364,11 @@
 	ipc_call_t answer;
 	aid_t req;
-
-	int vfs_phone = vfs_exchange_begin();
-	
-	req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
-	rc = async_data_read_start_generic(vfs_phone, (void *) buf, nbyte,
-	    IPC_XF_RESTRICT);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	
+	async_exch_t *exch = vfs_exchange_begin();
+	
+	req = async_send_1(exch, VFS_IN_READ, fildes, &answer);
+	rc = async_data_read_start(exch, (void *)buf, nbyte);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 
 		sysarg_t rc_orig;
@@ -391,5 +380,5 @@
 			return (ssize_t) rc_orig;
 	}
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	async_wait_for(req, &rc);
 	if (rc == EOK)
@@ -404,12 +393,11 @@
 	ipc_call_t answer;
 	aid_t req;
-
-	int vfs_phone = vfs_exchange_begin();
-	
-	req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
-	rc = async_data_write_start_generic(vfs_phone, (void *) buf, nbyte,
-	    IPC_XF_RESTRICT);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	
+	async_exch_t *exch = vfs_exchange_begin();
+	
+	req = async_send_1(exch, VFS_IN_WRITE, fildes, &answer);
+	rc = async_data_write_start(exch, (void *)buf, nbyte);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 
 		sysarg_t rc_orig;
@@ -421,5 +409,5 @@
 			return (ssize_t) rc_orig;
 	}
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	async_wait_for(req, &rc);
 	if (rc == EOK)
@@ -431,9 +419,7 @@
 int fsync(int fildes)
 {
-	int vfs_phone = vfs_exchange_begin();
-	
-	sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
-	
-	vfs_exchange_end(vfs_phone);
+	async_exch_t *exch = vfs_exchange_begin();
+	sysarg_t rc = async_req_1_0(exch, VFS_IN_SYNC, fildes);
+	vfs_exchange_end(exch);
 	
 	return (int) rc;
@@ -442,13 +428,13 @@
 off64_t lseek(int fildes, off64_t offset, int whence)
 {
-	int vfs_phone = vfs_exchange_begin();
+	async_exch_t *exch = vfs_exchange_begin();
 	
 	sysarg_t newoff_lo;
 	sysarg_t newoff_hi;
-	sysarg_t rc = async_req_4_2(vfs_phone, VFS_IN_SEEK, fildes,
+	sysarg_t rc = async_req_4_2(exch, VFS_IN_SEEK, fildes,
 	    LOWER32(offset), UPPER32(offset), whence,
 	    &newoff_lo, &newoff_hi);
 	
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	
 	if (rc != EOK)
@@ -462,9 +448,8 @@
 	sysarg_t rc;
 	
-	int vfs_phone = vfs_exchange_begin();
-	
-	rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
+	async_exch_t *exch = vfs_exchange_begin();
+	rc = async_req_3_0(exch, VFS_IN_TRUNCATE, fildes,
 	    LOWER32(length), UPPER32(length));
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	
 	return (int) rc;
@@ -475,11 +460,11 @@
 	sysarg_t rc;
 	aid_t req;
-
-	int vfs_phone = vfs_exchange_begin();
-	
-	req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
-	rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	
+	async_exch_t *exch = vfs_exchange_begin();
+	
+	req = async_send_1(exch, VFS_IN_FSTAT, fildes, NULL);
+	rc = async_data_read_start(exch, (void *) stat, sizeof(struct stat));
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 
 		sysarg_t rc_orig;
@@ -491,5 +476,5 @@
 			return (ssize_t) rc_orig;
 	}
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	async_wait_for(req, &rc);
 
@@ -508,10 +493,10 @@
 		return ENOMEM;
 	
-	int vfs_phone = vfs_exchange_begin();
-	
-	req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
-	rc = async_data_write_start(vfs_phone, pa, pa_size);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	async_exch_t *exch = vfs_exchange_begin();
+	
+	req = async_send_0(exch, VFS_IN_STAT, NULL);
+	rc = async_data_write_start(exch, pa, pa_size);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(pa);
 		async_wait_for(req, &rc_orig);
@@ -521,7 +506,7 @@
 			return (int) rc_orig;
 	}
-	rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	rc = async_data_read_start(exch, stat, sizeof(struct stat));
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(pa);
 		async_wait_for(req, &rc_orig);
@@ -531,5 +516,5 @@
 			return (int) rc_orig;
 	}
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	free(pa);
 	async_wait_for(req, &rc);
@@ -592,10 +577,10 @@
 		return ENOMEM;
 	
-	int vfs_phone = vfs_exchange_begin();
-	
-	req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
-	rc = async_data_write_start(vfs_phone, pa, pa_size);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	async_exch_t *exch = vfs_exchange_begin();
+	
+	req = async_send_1(exch, VFS_IN_MKDIR, mode, NULL);
+	rc = async_data_write_start(exch, pa, pa_size);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(pa);
 
@@ -608,5 +593,5 @@
 			return (int) rc_orig;
 	}
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	free(pa);
 	async_wait_for(req, &rc);
@@ -623,11 +608,11 @@
 	if (!pa)
 		return ENOMEM;
-
-	int vfs_phone = vfs_exchange_begin();
-	
-	req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
-	rc = async_data_write_start(vfs_phone, pa, pa_size);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	
+	async_exch_t *exch = vfs_exchange_begin();
+	
+	req = async_send_0(exch, VFS_IN_UNLINK, NULL);
+	rc = async_data_write_start(exch, pa, pa_size);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(pa);
 
@@ -640,5 +625,5 @@
 			return (int) rc_orig;
 	}
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	free(pa);
 	async_wait_for(req, &rc);
@@ -673,11 +658,11 @@
 		return ENOMEM;
 	}
-
-	int vfs_phone = vfs_exchange_begin();
-	
-	req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
-	rc = async_data_write_start(vfs_phone, olda, olda_size);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	
+	async_exch_t *exch = vfs_exchange_begin();
+	
+	req = async_send_0(exch, VFS_IN_RENAME, NULL);
+	rc = async_data_write_start(exch, olda, olda_size);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(olda);
 		free(newa);
@@ -688,7 +673,7 @@
 			return (int) rc_orig;
 	}
-	rc = async_data_write_start(vfs_phone, newa, newa_size);
-	if (rc != EOK) {
-		vfs_exchange_end(vfs_phone);
+	rc = async_data_write_start(exch, newa, newa_size);
+	if (rc != EOK) {
+		vfs_exchange_end(exch);
 		free(olda);
 		free(newa);
@@ -699,5 +684,5 @@
 			return (int) rc_orig;
 	}
-	vfs_exchange_end(vfs_phone);
+	vfs_exchange_end(exch);
 	free(olda);
 	free(newa);
@@ -755,16 +740,19 @@
 }
 
-int fd_phone(int fildes)
+async_sess_t *fd_session(exch_mgmt_t mgmt, int fildes)
 {
 	struct stat stat;
-	
 	int rc = fstat(fildes, &stat);
-	if (rc != 0)
-		return rc;
-	
-	if (!stat.device)
-		return -1;
-	
-	return devmap_device_connect(stat.device, 0);
+	if (rc != 0) {
+		errno = rc;
+		return NULL;
+	}
+	
+	if (!stat.device) {
+		errno = ENOENT;
+		return NULL;
+	}
+	
+	return devmap_device_connect(mgmt, stat.device, 0);
 }
 
@@ -772,7 +760,5 @@
 {
 	struct stat stat;
-	int rc;
-
-	rc = fstat(fildes, &stat);
+	int rc = fstat(fildes, &stat);
 	
 	if (rc == EOK) {
@@ -787,10 +773,10 @@
 int dup2(int oldfd, int newfd)
 {
-	int vfs_phone = vfs_exchange_begin();
+	async_exch_t *exch = vfs_exchange_begin();
 	
 	sysarg_t ret;
-	sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
-	
-	vfs_exchange_end(vfs_phone);
+	sysarg_t rc = async_req_2_1(exch, VFS_IN_DUP, oldfd, newfd, &ret);
+	
+	vfs_exchange_end(exch);
 	
 	if (rc == EOK)
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/include/async.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -41,6 +41,6 @@
 
 #include <ipc/common.h>
-#include <async_sess.h>
 #include <fibril.h>
+#include <fibril_synch.h>
 #include <sys/time.h>
 #include <atomic.h>
@@ -55,4 +55,76 @@
 typedef void (*async_client_conn_t)(ipc_callid_t, ipc_call_t *);
 
+/** Exchange management style
+ *
+ */
+typedef enum {
+	/** No explicit exchange management
+	 *
+	 * Suitable for protocols which use a single
+	 * IPC message per exchange only.
+	 *
+	 */
+	EXCHANGE_ATOMIC = 0,
+	
+	/** Exchange management via phone cloning
+	 *
+	 * Suitable for servers which support client
+	 * data tracking by task hashes and do not
+	 * mind cloned phones.
+	 *
+	 */
+	EXCHANGE_PARALLEL,
+	
+	/** Exchange management via mutual exclusion
+	 *
+	 * Suitable for any kind of client/server communication,
+	 * but can limit parallelism.
+	 *
+	 */
+	EXCHANGE_SERIALIZE
+} exch_mgmt_t;
+
+/** Session data */
+typedef struct {
+	/** List of inactive exchanges */
+	link_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;
+} async_sess_t;
+
+/** Exchange data */
+typedef struct {
+	/** 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;
+} async_exch_t;
+
 extern atomic_t threads_in_ipc_wait;
 
@@ -68,32 +140,32 @@
  * User-friendly wrappers for async_send_fast() and async_send_slow(). The
  * macros are in the form async_send_m(), where m denotes the number of payload
- * arguments.  Each macros chooses between the fast and the slow version based
+ * arguments. Each macros chooses between the fast and the slow version based
  * on m.
  */
 
-#define async_send_0(phoneid, method, dataptr) \
-	async_send_fast((phoneid), (method), 0, 0, 0, 0, (dataptr))
-#define async_send_1(phoneid, method, arg1, dataptr) \
-	async_send_fast((phoneid), (method), (arg1), 0, 0, 0, (dataptr))
-#define async_send_2(phoneid, method, arg1, arg2, dataptr) \
-	async_send_fast((phoneid), (method), (arg1), (arg2), 0, 0, (dataptr))
-#define async_send_3(phoneid, method, arg1, arg2, arg3, dataptr) \
-	async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (dataptr))
-#define async_send_4(phoneid, method, arg1, arg2, arg3, arg4, dataptr) \
-	async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
-	    (dataptr))
-#define async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, dataptr) \
-	async_send_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
-	    (arg5), (dataptr))
-
-extern aid_t async_send_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
-    sysarg_t, ipc_call_t *);
-extern aid_t async_send_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
+#define async_send_0(exch, method, dataptr) \
+	async_send_fast(exch, method, 0, 0, 0, 0, dataptr)
+#define async_send_1(exch, method, arg1, dataptr) \
+	async_send_fast(exch, method, arg1, 0, 0, 0, dataptr)
+#define async_send_2(exch, method, arg1, arg2, dataptr) \
+	async_send_fast(exch, method, arg1, arg2, 0, 0, dataptr)
+#define async_send_3(exch, method, arg1, arg2, arg3, dataptr) \
+	async_send_fast(exch, method, arg1, arg2, arg3, 0, dataptr)
+#define async_send_4(exch, method, arg1, arg2, arg3, arg4, dataptr) \
+	async_send_fast(exch, method, arg1, arg2, arg3, arg4, dataptr)
+#define async_send_5(exch, method, arg1, arg2, arg3, arg4, arg5, dataptr) \
+	async_send_slow(exch, method, arg1, arg2, arg3, arg4, arg5, dataptr)
+
+extern aid_t async_send_fast(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
     sysarg_t, sysarg_t, ipc_call_t *);
+extern aid_t async_send_slow(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
+
 extern void async_wait_for(aid_t, sysarg_t *);
 extern int async_wait_timeout(aid_t, sysarg_t *, suseconds_t);
 
 extern fid_t async_new_connection(sysarg_t, sysarg_t, ipc_callid_t,
-    ipc_call_t *, void (*)(ipc_callid_t, ipc_call_t *));
+    ipc_call_t *, async_client_conn_t);
+
 extern void async_usleep(suseconds_t);
 extern void async_create_manager(void);
@@ -102,6 +174,5 @@
 extern void async_set_client_data_constructor(async_client_data_ctor_t);
 extern void async_set_client_data_destructor(async_client_data_dtor_t);
-
-extern void *async_client_data_get(void);
+extern void *async_get_client_data(void);
 
 extern void async_set_client_connection(async_client_conn_t);
@@ -112,11 +183,12 @@
  */
 
-extern void async_msg_0(int, sysarg_t);
-extern void async_msg_1(int, sysarg_t, sysarg_t);
-extern void async_msg_2(int, sysarg_t, sysarg_t, sysarg_t);
-extern void async_msg_3(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
-extern void async_msg_4(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
-extern void async_msg_5(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
+extern void async_msg_0(async_exch_t *, sysarg_t);
+extern void async_msg_1(async_exch_t *, sysarg_t, sysarg_t);
+extern void async_msg_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t);
+extern void async_msg_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
+extern void async_msg_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
     sysarg_t);
+extern void async_msg_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t);
 
 /*
@@ -138,8 +210,8 @@
  */
 
-extern int async_forward_fast(ipc_callid_t, int, sysarg_t, sysarg_t, sysarg_t,
-    unsigned int);
-extern int async_forward_slow(ipc_callid_t, int, sysarg_t, sysarg_t, sysarg_t,
-    sysarg_t, sysarg_t, sysarg_t, unsigned int);
+extern int async_forward_fast(ipc_callid_t, async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, unsigned int);
+extern int async_forward_slow(ipc_callid_t, async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, sysarg_t, unsigned int);
 
 /*
@@ -150,161 +222,160 @@
  */
 
-#define async_req_0_0(phoneid, method) \
-	async_req_fast((phoneid), (method), 0, 0, 0, 0, NULL, NULL, NULL, NULL, \
-	    NULL)
-#define async_req_0_1(phoneid, method, r1) \
-	async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), NULL, NULL, NULL, \
-	    NULL)
-#define async_req_0_2(phoneid, method, r1, r2) \
-	async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), NULL, NULL, \
-	    NULL)
-#define async_req_0_3(phoneid, method, r1, r2, r3) \
-	async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), NULL, \
-	    NULL)
-#define async_req_0_4(phoneid, method, r1, r2, r3, r4) \
-	async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
-	    NULL)
-#define async_req_0_5(phoneid, method, r1, r2, r3, r4, r5) \
-	async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
-	    (r5))
-#define async_req_1_0(phoneid, method, arg1) \
-	async_req_fast((phoneid), (method), (arg1), 0, 0, 0, NULL, NULL, NULL, \
-	    NULL, NULL)
-#define async_req_1_1(phoneid, method, arg1, rc1) \
-	async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), NULL, NULL, \
-	    NULL, NULL)
-#define async_req_1_2(phoneid, method, arg1, rc1, rc2) \
-	async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), NULL, \
-	    NULL, NULL)
-#define async_req_1_3(phoneid, method, arg1, rc1, rc2, rc3) \
-	async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
-	    NULL, NULL)
-#define async_req_1_4(phoneid, method, arg1, rc1, rc2, rc3, rc4) \
-	async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
-	    (rc4), NULL)
-#define async_req_1_5(phoneid, method, arg1, rc1, rc2, rc3, rc4, rc5) \
-	async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
-	    (rc4), (rc5))
-#define async_req_2_0(phoneid, method, arg1, arg2) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL, NULL, \
+#define async_req_0_0(exch, method) \
+	async_req_fast(exch, method, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)
+#define async_req_0_1(exch, method, r1) \
+	async_req_fast(exch, method, 0, 0, 0, 0, r1, NULL, NULL, NULL, NULL)
+#define async_req_0_2(exch, method, r1, r2) \
+	async_req_fast(exch, method, 0, 0, 0, 0, r1, r2, NULL, NULL, NULL)
+#define async_req_0_3(exch, method, r1, r2, r3) \
+	async_req_fast(exch, method, 0, 0, 0, 0, r1, r2, r3, NULL, NULL)
+#define async_req_0_4(exch, method, r1, r2, r3, r4) \
+	async_req_fast(exch, method, 0, 0, 0, 0, r1, r2, r3, r4, NULL)
+#define async_req_0_5(exch, method, r1, r2, r3, r4, r5) \
+	async_req_fast(exch, method, 0, 0, 0, 0, r1, r2, r3, r4, r5)
+
+#define async_req_1_0(exch, method, arg1) \
+	async_req_fast(exch, method, arg1, 0, 0, 0, NULL, NULL, NULL, NULL, \
+	    NULL)
+#define async_req_1_1(exch, method, arg1, rc1) \
+	async_req_fast(exch, method, arg1, 0, 0, 0, rc1, NULL, NULL, NULL, \
+	    NULL)
+#define async_req_1_2(exch, method, arg1, rc1, rc2) \
+	async_req_fast(exch, method, arg1, 0, 0, 0, rc1, rc2, NULL, NULL, \
+	    NULL)
+#define async_req_1_3(exch, method, arg1, rc1, rc2, rc3) \
+	async_req_fast(exch, method, arg1, 0, 0, 0, rc1, rc2, rc3, NULL, \
+	    NULL)
+#define async_req_1_4(exch, method, arg1, rc1, rc2, rc3, rc4) \
+	async_req_fast(exch, method, arg1, 0, 0, 0, rc1, rc2, rc3, rc4, \
+	    NULL)
+#define async_req_1_5(exch, method, arg1, rc1, rc2, rc3, rc4, rc5) \
+	async_req_fast(exch, method, arg1, 0, 0, 0, rc1, rc2, rc3, rc4, \
+	    rc5)
+
+#define async_req_2_0(exch, method, arg1, arg2) \
+	async_req_fast(exch, method, arg1, arg2, 0, 0, NULL, NULL, NULL, \
+	    NULL, NULL)
+#define async_req_2_1(exch, method, arg1, arg2, rc1) \
+	async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, NULL, NULL, \
+	    NULL, NULL)
+#define async_req_2_2(exch, method, arg1, arg2, rc1, rc2) \
+	async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, rc2, NULL, NULL, \
+	    NULL)
+#define async_req_2_3(exch, method, arg1, arg2, rc1, rc2, rc3) \
+	async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, rc2, rc3, NULL, \
+	    NULL)
+#define async_req_2_4(exch, method, arg1, arg2, rc1, rc2, rc3, rc4) \
+	async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, rc2, rc3, rc4, \
+	    NULL)
+#define async_req_2_5(exch, method, arg1, arg2, rc1, rc2, rc3, rc4, rc5) \
+	async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, rc2, rc3, rc4, \
+	    rc5)
+
+#define async_req_3_0(exch, method, arg1, arg2, arg3) \
+	async_req_fast(exch, method, arg1, arg2, arg3, 0, NULL, NULL, NULL, \
+	    NULL, NULL)
+#define async_req_3_1(exch, method, arg1, arg2, arg3, rc1) \
+	async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, NULL, NULL, \
+	    NULL, NULL)
+#define async_req_3_2(exch, method, arg1, arg2, arg3, rc1, rc2) \
+	async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, rc2, NULL, \
+	    NULL, NULL)
+#define async_req_3_3(exch, method, arg1, arg2, arg3, rc1, rc2, rc3) \
+	async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, rc2, rc3, \
+	    NULL, NULL)
+#define async_req_3_4(exch, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4) \
+	async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, rc2, rc3, \
+	    rc4, NULL)
+#define async_req_3_5(exch, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4, \
+    rc5) \
+	async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, rc2, rc3, \
+	    rc4, rc5)
+
+#define async_req_4_0(exch, method, arg1, arg2, arg3, arg4) \
+	async_req_fast(exch, method, arg1, arg2, arg3, arg4, NULL, NULL, \
 	    NULL, NULL, NULL)
-#define async_req_2_1(phoneid, method, arg1, arg2, rc1) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), NULL, \
+#define async_req_4_1(exch, method, arg1, arg2, arg3, arg4, rc1) \
+	async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, NULL, \
 	    NULL, NULL, NULL)
-#define async_req_2_2(phoneid, method, arg1, arg2, rc1, rc2) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
+#define async_req_4_2(exch, method, arg1, arg2, arg3, arg4, rc1, rc2) \
+	async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, NULL, \
+	    NULL, NULL)
+#define async_req_4_3(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3) \
+	async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
+	    NULL, NULL)
+#define async_req_4_4(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
+    rc4) \
+	async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
+	    rc4, NULL)
+#define async_req_4_5(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
+    rc4, rc5) \
+	async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
+	    rc4, rc5)
+
+#define async_req_5_0(exch, method, arg1, arg2, arg3, arg4, arg5) \
+	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, NULL, \
+	    NULL, NULL, NULL, NULL)
+#define async_req_5_1(exch, method, arg1, arg2, arg3, arg4, arg5, rc1) \
+	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, \
+	    NULL, NULL, NULL, NULL)
+#define async_req_5_2(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2) \
+	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
 	    NULL, NULL, NULL)
-#define async_req_2_3(phoneid, method, arg1, arg2, rc1, rc2, rc3) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
-	    (rc3), NULL, NULL)
-#define async_req_2_4(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
-	    (rc3), (rc4), NULL)
-#define async_req_2_5(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4, rc5) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
-	    (rc3), (rc4), (rc5))
-#define async_req_3_0(phoneid, method, arg1, arg2, arg3) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, NULL, NULL, \
-	    NULL, NULL, NULL)
-#define async_req_3_1(phoneid, method, arg1, arg2, arg3, rc1) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
-	    NULL, NULL, NULL, NULL)
-#define async_req_3_2(phoneid, method, arg1, arg2, arg3, rc1, rc2) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
-	    (rc2), NULL, NULL, NULL)
-#define async_req_3_3(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
-	    (rc2), (rc3), NULL, NULL)
-#define async_req_3_4(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
-	    (rc2), (rc3), (rc4), NULL)
-#define async_req_3_5(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4, \
-    rc5) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
-	    (rc2), (rc3), (rc4), (rc5))
-#define async_req_4_0(phoneid, method, arg1, arg2, arg3, arg4) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
-	    NULL, NULL, NULL, NULL)
-#define async_req_4_1(phoneid, method, arg1, arg2, arg3, arg4, rc1) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
-	    NULL, NULL, NULL, NULL)
-#define async_req_4_2(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
-	    (rc2), NULL, NULL, NULL)
-#define async_req_4_3(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
-	    (rc2), (rc3), NULL, NULL)
-#define async_req_4_4(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
-    rc4) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
-	    (rc1), (rc2), (rc3), (rc4), NULL)
-#define async_req_4_5(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
-    rc4, rc5) \
-	async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
-	    (rc1), (rc2), (rc3), (rc4), (rc5))
-#define async_req_5_0(phoneid, method, arg1, arg2, arg3, arg4, arg5) \
-	async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
-	    (arg5), NULL, NULL, NULL, NULL, NULL)
-#define async_req_5_1(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1) \
-	async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
-	    (arg5), (rc1), NULL, NULL, NULL, NULL)
-#define async_req_5_2(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2) \
-	async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
-	    (arg5), (rc1), (rc2), NULL, NULL, NULL)
-#define async_req_5_3(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
+#define async_req_5_3(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
     rc3) \
-	async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
-	    (arg5), (rc1), (rc2), (rc3), NULL, NULL)
-#define async_req_5_4(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
+	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
+	    rc3, NULL, NULL)
+#define async_req_5_4(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
     rc3, rc4) \
-	async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
-	    (arg5), (rc1), (rc2), (rc3), (rc4), NULL)
-#define async_req_5_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
+	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
+	    rc3, rc4, NULL)
+#define async_req_5_5(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
     rc3, rc4, rc5) \
-	async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
-	    (arg5), (rc1), (rc2), (rc3), (rc4), (rc5))
-
-extern sysarg_t async_req_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
-    sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
-extern sysarg_t async_req_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
+	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
+	    rc3, rc4, rc5)
+
+extern sysarg_t async_req_fast(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
     sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *,
     sysarg_t *);
-
-static inline void async_serialize_start(void)
-{
-	fibril_inc_sercount();
-}
-
-static inline void async_serialize_end(void)
-{
-	fibril_dec_sercount();
-}
-
-extern int async_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t,
+extern sysarg_t async_req_slow(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *,
+    sysarg_t *, sysarg_t *);
+
+extern async_sess_t *async_connect_me(exch_mgmt_t, async_exch_t *);
+extern async_sess_t *async_connect_me_to(exch_mgmt_t, async_exch_t *, sysarg_t,
+    sysarg_t, sysarg_t);
+extern async_sess_t *async_connect_me_to_blocking(exch_mgmt_t, async_exch_t *,
+    sysarg_t, sysarg_t, sysarg_t);
+extern async_sess_t *async_connect_kbox(task_id_t);
+
+extern int async_connect_to_me(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
     async_client_conn_t);
-extern int async_connect_me_to(int, sysarg_t, sysarg_t, sysarg_t);
-extern int async_connect_me_to_blocking(int, sysarg_t, sysarg_t, sysarg_t);
-extern int async_connect_kbox(task_id_t);
-extern int async_hangup(int);
+
+extern int async_hangup(async_sess_t *);
 extern void async_poke(void);
 
+extern async_exch_t *async_exchange_begin(async_sess_t *);
+extern void async_exchange_end(async_exch_t *);
+
 /*
  * User-friendly wrappers for async_share_in_start().
  */
 
-#define async_share_in_start_0_0(phoneid, dst, size) \
-	async_share_in_start((phoneid), (dst), (size), 0, NULL)
-#define async_share_in_start_0_1(phoneid, dst, size, flags) \
-	async_share_in_start((phoneid), (dst), (size), 0, (flags))
-#define async_share_in_start_1_0(phoneid, dst, size, arg) \
-	async_share_in_start((phoneid), (dst), (size), (arg), NULL)
-#define async_share_in_start_1_1(phoneid, dst, size, arg, flags) \
-	async_share_in_start((phoneid), (dst), (size), (arg), (flags))
-
-extern int async_share_in_start(int, void *, size_t, sysarg_t, unsigned int *);
+#define async_share_in_start_0_0(exch, dst, size) \
+	async_share_in_start(exch, dst, size, 0, NULL)
+#define async_share_in_start_0_1(exch, dst, size, flags) \
+	async_share_in_start(exch, dst, size, 0, flags)
+#define async_share_in_start_1_0(exch, dst, size, arg) \
+	async_share_in_start(exch, dst, size, arg, NULL)
+#define async_share_in_start_1_1(exch, dst, size, arg, flags) \
+	async_share_in_start(exch, dst, size, arg, flags)
+
+extern int async_share_in_start(async_exch_t *, void *, size_t, sysarg_t,
+    unsigned int *);
 extern bool async_share_in_receive(ipc_callid_t *, size_t *);
 extern int async_share_in_finalize(ipc_callid_t, void *, unsigned int);
 
-extern int async_share_out_start(int, void *, unsigned int);
+extern int async_share_out_start(async_exch_t *, void *, unsigned int);
 extern bool async_share_out_receive(ipc_callid_t *, size_t *, unsigned int *);
 extern int async_share_out_finalize(ipc_callid_t, void *);
@@ -314,40 +385,37 @@
  */
 
-#define async_data_read_forward_0_0(phoneid, method, answer) \
-	async_data_read_forward_fast((phoneid), (method), 0, 0, 0, 0, NULL)
-#define async_data_read_forward_0_1(phoneid, method, answer) \
-	async_data_read_forward_fast((phoneid), (method), 0, 0, 0, 0, (answer))
-#define async_data_read_forward_1_0(phoneid, method, arg1, answer) \
-	async_data_read_forward_fast((phoneid), (method), (arg1), 0, 0, 0, NULL)
-#define async_data_read_forward_1_1(phoneid, method, arg1, answer) \
-	async_data_read_forward_fast((phoneid), (method), (arg1), 0, 0, 0, (answer))
-#define async_data_read_forward_2_0(phoneid, method, arg1, arg2, answer) \
-	async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL)
-#define async_data_read_forward_2_1(phoneid, method, arg1, arg2, answer) \
-	async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
-	    (answer))
-#define async_data_read_forward_3_0(phoneid, method, arg1, arg2, arg3, answer) \
-	async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \
-	    NULL)
-#define async_data_read_forward_3_1(phoneid, method, arg1, arg2, arg3, answer) \
-	async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \
-	    (answer))
-#define async_data_read_forward_4_0(phoneid, method, arg1, arg2, arg3, arg4, answer) \
-	async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
-	    (arg4), NULL)
-#define async_data_read_forward_4_1(phoneid, method, arg1, arg2, arg3, arg4, answer) \
-	async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
-	    (arg4), (answer))
-
-extern aid_t async_data_read(int, void *, size_t, ipc_call_t *);
-#define async_data_read_start(p, buf, len) \
-	async_data_read_start_generic((p), (buf), (len), IPC_XF_NONE)
-
-extern int async_data_read_start_generic(int, void *, size_t, int);
+#define async_data_read_forward_0_0(exch, method, answer) \
+	async_data_read_forward_fast(exch, method, 0, 0, 0, 0, NULL)
+#define async_data_read_forward_0_1(exch, method, answer) \
+	async_data_read_forward_fast(exch, method, 0, 0, 0, 0, answer)
+#define async_data_read_forward_1_0(exch, method, arg1, answer) \
+	async_data_read_forward_fast(exch, method, arg1, 0, 0, 0, NULL)
+#define async_data_read_forward_1_1(exch, method, arg1, answer) \
+	async_data_read_forward_fast(exch, method, arg1, 0, 0, 0, answer)
+#define async_data_read_forward_2_0(exch, method, arg1, arg2, answer) \
+	async_data_read_forward_fast(exch, method, arg1, arg2, 0, 0, NULL)
+#define async_data_read_forward_2_1(exch, method, arg1, arg2, answer) \
+	async_data_read_forward_fast(exch, method, arg1, arg2, 0, 0, answer)
+#define async_data_read_forward_3_0(exch, method, arg1, arg2, arg3, answer) \
+	async_data_read_forward_fast(exch, method, arg1, arg2, arg3, 0, NULL)
+#define async_data_read_forward_3_1(exch, method, arg1, arg2, arg3, answer) \
+	async_data_read_forward_fast(exch, method, arg1, arg2, arg3, 0, \
+	    answer)
+#define async_data_read_forward_4_0(exch, method, arg1, arg2, arg3, arg4, \
+    answer) \
+	async_data_read_forward_fast(exch, method, arg1, arg2, arg3, arg4, \
+	    NULL)
+#define async_data_read_forward_4_1(exch, method, arg1, arg2, arg3, arg4, \
+    answer) \
+	async_data_read_forward_fast(exch, method, arg1, arg2, arg3, arg4, \
+	    answer)
+
+extern aid_t async_data_read(async_exch_t *, void *, size_t, ipc_call_t *);
+extern int async_data_read_start(async_exch_t *, void *, size_t);
 extern bool async_data_read_receive(ipc_callid_t *, size_t *);
 extern int async_data_read_finalize(ipc_callid_t, const void *, size_t);
 
-extern int async_data_read_forward_fast(int, sysarg_t, sysarg_t, sysarg_t,
-    sysarg_t, sysarg_t, ipc_call_t *);
+extern int async_data_read_forward_fast(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
 
 /*
@@ -355,36 +423,32 @@
  */
 
-#define async_data_write_forward_0_0(phoneid, method, answer) \
-	async_data_write_forward_fast((phoneid), (method), 0, 0, 0, 0, NULL)
-#define async_data_write_forward_0_1(phoneid, method, answer) \
-	async_data_write_forward_fast((phoneid), (method), 0, 0, 0, 0, (answer))
-#define async_data_write_forward_1_0(phoneid, method, arg1, answer) \
-	async_data_write_forward_fast((phoneid), (method), (arg1), 0, 0, 0, NULL)
-#define async_data_write_forward_1_1(phoneid, method, arg1, answer) \
-	async_data_write_forward_fast((phoneid), (method), (arg1), 0, 0, 0, \
-	    (answer))
-#define async_data_write_forward_2_0(phoneid, method, arg1, arg2, answer) \
-	async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
-	    NULL)
-#define async_data_write_forward_2_1(phoneid, method, arg1, arg2, answer) \
-	async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
-	    (answer))
-#define async_data_write_forward_3_0(phoneid, method, arg1, arg2, arg3, answer) \
-	async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
-	    0, NULL)
-#define async_data_write_forward_3_1(phoneid, method, arg1, arg2, arg3, answer) \
-	async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
-	    0, (answer))
-#define async_data_write_forward_4_0(phoneid, method, arg1, arg2, arg3, arg4, answer) \
-	async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
-	    (arg4), NULL)
-#define async_data_write_forward_4_1(phoneid, method, arg1, arg2, arg3, arg4, answer) \
-	async_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
-	    (arg4), (answer))
-
-#define async_data_write_start(p, buf, len) \
-	async_data_write_start_generic((p), (buf), (len), IPC_XF_NONE)
-
-extern int async_data_write_start_generic(int, const void *, size_t, int);
+#define async_data_write_forward_0_0(exch, method, answer) \
+	async_data_write_forward_fast(exch, method, 0, 0, 0, 0, NULL)
+#define async_data_write_forward_0_1(exch, method, answer) \
+	async_data_write_forward_fast(exch, method, 0, 0, 0, 0, answer)
+#define async_data_write_forward_1_0(exch, method, arg1, answer) \
+	async_data_write_forward_fast(exch, method, arg1, 0, 0, 0, NULL)
+#define async_data_write_forward_1_1(exch, method, arg1, answer) \
+	async_data_write_forward_fast(exch, method, arg1, 0, 0, 0, answer)
+#define async_data_write_forward_2_0(exch, method, arg1, arg2, answer) \
+	async_data_write_forward_fast(exch, method, arg1, arg2, 0, 0, NULL)
+#define async_data_write_forward_2_1(exch, method, arg1, arg2, answer) \
+	async_data_write_forward_fast(exch, method, arg1, arg2, 0, 0, answer)
+#define async_data_write_forward_3_0(exch, method, arg1, arg2, arg3, answer) \
+	async_data_write_forward_fast(exch, method, arg1, arg2, arg3, 0, \
+	    NULL)
+#define async_data_write_forward_3_1(exch, method, arg1, arg2, arg3, answer) \
+	async_data_write_forward_fast(exch, method, arg1, arg2, arg3, 0, \
+	    answer)
+#define async_data_write_forward_4_0(exch, method, arg1, arg2, arg3, arg4, \
+    answer) \
+	async_data_write_forward_fast(exch, method, arg1, arg2, arg3, arg4, \
+	    NULL)
+#define async_data_write_forward_4_1(exch, method, arg1, arg2, arg3, arg4, \
+    answer) \
+	async_data_write_forward_fast(exch, method, arg1, arg2, arg3, arg4, \
+	    answer)
+
+extern int async_data_write_start(async_exch_t *, const void *, size_t);
 extern bool async_data_write_receive(ipc_callid_t *, size_t *);
 extern int async_data_write_finalize(ipc_callid_t, void *, size_t);
@@ -394,6 +458,10 @@
 extern void async_data_write_void(sysarg_t);
 
-extern int async_data_write_forward_fast(int, sysarg_t, sysarg_t, sysarg_t,
-    sysarg_t, sysarg_t, ipc_call_t *);
+extern int async_data_write_forward_fast(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
+
+extern int async_exchange_clone(async_exch_t *, async_exch_t *);
+extern async_sess_t *async_clone_receive(exch_mgmt_t);
+extern async_sess_t *async_callback_receive(exch_mgmt_t);
 
 #endif
Index: uspace/lib/c/include/async_obsolete.h
===================================================================
--- uspace/lib/c/include/async_obsolete.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
+++ uspace/lib/c/include/async_obsolete.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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
+ */
+
+#if ((defined(LIBC_IPC_H_)) && (!defined(LIBC_ASYNC_OBSOLETE_C_)))
+	#error Do not intermix low-level IPC interface and async framework
+#endif
+
+#ifndef LIBC_ASYNC_OBSOLETE_H_
+#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))
+#define async_obsolete_send_1(phoneid, method, arg1, dataptr) \
+	async_obsolete_send_fast((phoneid), (method), (arg1), 0, 0, 0, (dataptr))
+#define async_obsolete_send_2(phoneid, method, arg1, arg2, dataptr) \
+	async_obsolete_send_fast((phoneid), (method), (arg1), (arg2), 0, 0, (dataptr))
+#define async_obsolete_send_3(phoneid, method, arg1, arg2, arg3, dataptr) \
+	async_obsolete_send_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (dataptr))
+#define async_obsolete_send_4(phoneid, method, arg1, arg2, arg3, arg4, dataptr) \
+	async_obsolete_send_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
+	    (dataptr))
+#define async_obsolete_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, dataptr) \
+	async_obsolete_send_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
+	    (arg5), (dataptr))
+
+extern aid_t async_obsolete_send_fast(int phoneid, sysarg_t method, sysarg_t arg1,
+    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr);
+extern aid_t async_obsolete_send_slow(int phoneid, sysarg_t method, sysarg_t arg1,
+    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
+    ipc_call_t *dataptr);
+
+#define async_obsolete_req_0_0(phoneid, method) \
+	async_obsolete_req_fast((phoneid), (method), 0, 0, 0, 0, NULL, NULL, NULL, NULL, \
+	    NULL)
+#define async_obsolete_req_0_1(phoneid, method, r1) \
+	async_obsolete_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), NULL, NULL, NULL, \
+	    NULL)
+#define async_obsolete_req_0_2(phoneid, method, r1, r2) \
+	async_obsolete_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), NULL, NULL, \
+	    NULL)
+#define async_obsolete_req_0_3(phoneid, method, r1, r2, r3) \
+	async_obsolete_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), NULL, \
+	    NULL)
+#define async_obsolete_req_0_4(phoneid, method, r1, r2, r3, r4) \
+	async_obsolete_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
+	    NULL)
+#define async_obsolete_req_0_5(phoneid, method, r1, r2, r3, r4, r5) \
+	async_obsolete_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
+	    (r5))
+#define async_obsolete_req_1_0(phoneid, method, arg1) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), 0, 0, 0, NULL, NULL, NULL, \
+	    NULL, NULL)
+#define async_obsolete_req_1_1(phoneid, method, arg1, rc1) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), NULL, NULL, \
+	    NULL, NULL)
+#define async_obsolete_req_1_2(phoneid, method, arg1, rc1, rc2) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), NULL, \
+	    NULL, NULL)
+#define async_obsolete_req_1_3(phoneid, method, arg1, rc1, rc2, rc3) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
+	    NULL, NULL)
+#define async_obsolete_req_1_4(phoneid, method, arg1, rc1, rc2, rc3, rc4) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
+	    (rc4), NULL)
+#define async_obsolete_req_1_5(phoneid, method, arg1, rc1, rc2, rc3, rc4, rc5) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
+	    (rc4), (rc5))
+#define async_obsolete_req_2_0(phoneid, method, arg1, arg2) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL, NULL, \
+	    NULL, NULL, NULL)
+#define async_obsolete_req_2_1(phoneid, method, arg1, arg2, rc1) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), NULL, \
+	    NULL, NULL, NULL)
+#define async_obsolete_req_2_2(phoneid, method, arg1, arg2, rc1, rc2) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
+	    NULL, NULL, NULL)
+#define async_obsolete_req_2_3(phoneid, method, arg1, arg2, rc1, rc2, rc3) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
+	    (rc3), NULL, NULL)
+#define async_obsolete_req_2_4(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
+	    (rc3), (rc4), NULL)
+#define async_obsolete_req_2_5(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4, rc5) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
+	    (rc3), (rc4), (rc5))
+#define async_obsolete_req_3_0(phoneid, method, arg1, arg2, arg3) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, NULL, NULL, \
+	    NULL, NULL, NULL)
+#define async_obsolete_req_3_1(phoneid, method, arg1, arg2, arg3, rc1) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
+	    NULL, NULL, NULL, NULL)
+#define async_obsolete_req_3_2(phoneid, method, arg1, arg2, arg3, rc1, rc2) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
+	    (rc2), NULL, NULL, NULL)
+#define async_obsolete_req_3_3(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
+	    (rc2), (rc3), NULL, NULL)
+#define async_obsolete_req_3_4(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
+	    (rc2), (rc3), (rc4), NULL)
+#define async_obsolete_req_3_5(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4, \
+    rc5) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
+	    (rc2), (rc3), (rc4), (rc5))
+#define async_obsolete_req_4_0(phoneid, method, arg1, arg2, arg3, arg4) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
+	    NULL, NULL, NULL, NULL)
+#define async_obsolete_req_4_1(phoneid, method, arg1, arg2, arg3, arg4, rc1) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
+	    NULL, NULL, NULL, NULL)
+#define async_obsolete_req_4_2(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
+	    (rc2), NULL, NULL, NULL)
+#define async_obsolete_req_4_3(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
+	    (rc2), (rc3), NULL, NULL)
+#define async_obsolete_req_4_4(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
+    rc4) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
+	    (rc1), (rc2), (rc3), (rc4), NULL)
+#define async_obsolete_req_4_5(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
+    rc4, rc5) \
+	async_obsolete_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
+	    (rc1), (rc2), (rc3), (rc4), (rc5))
+#define async_obsolete_req_5_0(phoneid, method, arg1, arg2, arg3, arg4, arg5) \
+	async_obsolete_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
+	    (arg5), NULL, NULL, NULL, NULL, NULL)
+#define async_obsolete_req_5_1(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1) \
+	async_obsolete_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
+	    (arg5), (rc1), NULL, NULL, NULL, NULL)
+#define async_obsolete_req_5_2(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2) \
+	async_obsolete_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
+	    (arg5), (rc1), (rc2), NULL, NULL, NULL)
+#define async_obsolete_req_5_3(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
+    rc3) \
+	async_obsolete_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
+	    (arg5), (rc1), (rc2), (rc3), NULL, NULL)
+#define async_obsolete_req_5_4(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
+    rc3, rc4) \
+	async_obsolete_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
+	    (arg5), (rc1), (rc2), (rc3), (rc4), NULL)
+#define async_obsolete_req_5_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
+    rc3, rc4, rc5) \
+	async_obsolete_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
+	    (arg5), (rc1), (rc2), (rc3), (rc4), (rc5))
+
+extern sysarg_t async_obsolete_req_fast(int phoneid, sysarg_t method, sysarg_t arg1,
+    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2,
+    sysarg_t *r3, sysarg_t *r4, sysarg_t *r5);
+extern sysarg_t async_obsolete_req_slow(int phoneid, sysarg_t method, sysarg_t arg1,
+    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1,
+    sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5);
+
+extern void async_obsolete_msg_0(int, sysarg_t);
+extern void async_obsolete_msg_1(int, sysarg_t, sysarg_t);
+extern void async_obsolete_msg_2(int, sysarg_t, sysarg_t, sysarg_t);
+extern void async_obsolete_msg_3(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
+extern void async_obsolete_msg_4(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
+extern void async_obsolete_msg_5(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t);
+
+extern int async_obsolete_forward_slow(ipc_callid_t, int, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, unsigned int);
+
+extern int async_obsolete_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t,
+    async_client_conn_t);
+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);
+extern int async_obsolete_hangup(int);
+
+#define async_obsolete_share_in_start_0_0(phoneid, dst, size) \
+	async_obsolete_share_in_start((phoneid), (dst), (size), 0, NULL)
+#define async_obsolete_share_in_start_0_1(phoneid, dst, size, flags) \
+	async_obsolete_share_in_start((phoneid), (dst), (size), 0, (flags))
+#define async_obsolete_share_in_start_1_0(phoneid, dst, size, arg) \
+	async_obsolete_share_in_start((phoneid), (dst), (size), (arg), NULL)
+#define async_obsolete_share_in_start_1_1(phoneid, dst, size, arg, flags) \
+	async_obsolete_share_in_start((phoneid), (dst), (size), (arg), (flags))
+
+extern int async_obsolete_share_in_start(int, void *, size_t, sysarg_t,
+    unsigned int *);
+extern int async_obsolete_share_out_start(int, void *, unsigned int);
+
+#define async_obsolete_data_write_start(p, buf, len) \
+	async_obsolete_data_write_start_generic((p), (buf), (len), IPC_XF_NONE)
+
+#define async_obsolete_data_read_start(p, buf, len) \
+	async_obsolete_data_read_start_generic((p), (buf), (len), IPC_XF_NONE)
+
+#define async_obsolete_data_write_forward_0_0(phoneid, method, answer) \
+	async_obsolete_data_write_forward_fast((phoneid), (method), 0, 0, 0, 0, NULL)
+#define async_obsolete_data_write_forward_0_1(phoneid, method, answer) \
+	async_obsolete_data_write_forward_fast((phoneid), (method), 0, 0, 0, 0, (answer))
+#define async_obsolete_data_write_forward_1_0(phoneid, method, arg1, answer) \
+	async_obsolete_data_write_forward_fast((phoneid), (method), (arg1), 0, 0, 0, NULL)
+#define async_obsolete_data_write_forward_1_1(phoneid, method, arg1, answer) \
+	async_obsolete_data_write_forward_fast((phoneid), (method), (arg1), 0, 0, 0, \
+	    (answer))
+#define async_obsolete_data_write_forward_2_0(phoneid, method, arg1, arg2, answer) \
+	async_obsolete_data_write_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
+	    NULL)
+#define async_obsolete_data_write_forward_2_1(phoneid, method, arg1, arg2, answer) \
+	async_obsolete_data_write_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
+	    (answer))
+#define async_obsolete_data_write_forward_3_0(phoneid, method, arg1, arg2, arg3, answer) \
+	async_obsolete_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
+	    0, NULL)
+#define async_obsolete_data_write_forward_3_1(phoneid, method, arg1, arg2, arg3, answer) \
+	async_obsolete_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
+	    0, (answer))
+#define async_obsolete_data_write_forward_4_0(phoneid, method, arg1, arg2, arg3, arg4, answer) \
+	async_obsolete_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
+	    (arg4), NULL)
+#define async_obsolete_data_write_forward_4_1(phoneid, method, arg1, arg2, arg3, arg4, answer) \
+	async_obsolete_data_write_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
+	    (arg4), (answer))
+
+extern aid_t async_obsolete_data_read(int, void *, size_t, ipc_call_t *);
+extern int async_obsolete_data_read_start_generic(int, void *, size_t, int);
+
+extern int async_obsolete_data_write_start_generic(int, const void *, size_t, int);
+extern void async_obsolete_data_write_void(const int);
+
+extern int async_obsolete_forward_fast(ipc_callid_t, int, sysarg_t, sysarg_t,
+    sysarg_t, unsigned int);
+
+extern int async_obsolete_data_write_forward_fast(int, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, ipc_call_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/async_sess.h
===================================================================
--- uspace/lib/c/include/async_sess.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ 	(revision )
@@ -1,55 +1,0 @@
-/*
- * Copyright (c) 2010 Jakub Jermar
- * 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_ASYNC_SESS_H_
-#define LIBC_ASYNC_SESS_H_
-
-#include <adt/list.h>
-
-typedef struct {
-	int sess_phone;		/**< Phone for cloning off the connections. */
-	sysarg_t connect_arg1;  /**< Argument for CONNECT_ME_TO. */
-	link_t conn_head;	/**< List of open data connections. */
-	link_t sess_link;	/**< Link in global list of open sessions. */
-} async_sess_t;
-
-extern void async_session_create(async_sess_t *, int, sysarg_t);
-extern void async_session_destroy(async_sess_t *);
-extern int async_exchange_begin(async_sess_t *);
-extern void async_exchange_end(async_sess_t *, int);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/device/char_dev.h
===================================================================
--- uspace/lib/c/include/device/char_dev.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/include/device/char_dev.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -36,4 +36,6 @@
 #define LIBC_DEVICE_CHAR_DEV_H_
 
+#include <async.h>
+
 typedef enum {
 	CHAR_DEV_READ = 0,
@@ -41,6 +43,6 @@
 } char_dev_method_t;
 
-ssize_t char_dev_read(int dev_phone, void *buf, size_t len);
-ssize_t char_dev_write(int dev_phone, void *buf, size_t len);
+extern ssize_t char_dev_read(async_sess_t *, void *, size_t);
+extern ssize_t char_dev_write(async_sess_t *, void *, size_t);
 
 #endif
Index: uspace/lib/c/include/device/hw_res.h
===================================================================
--- uspace/lib/c/include/device/hw_res.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/include/device/hw_res.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -26,5 +26,5 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
- 
+
 /** @addtogroup libc
  * @{
@@ -32,9 +32,10 @@
 /** @file
  */
- 
+
 #ifndef LIBC_DEVICE_HW_RES_H_
 #define LIBC_DEVICE_HW_RES_H_
 
 #include <ipc/dev_iface.h>
+#include <async.h>
 #include <bool.h>
 
@@ -48,5 +49,5 @@
 typedef enum {
 	INTERRUPT,
-	IO_RANGE, 
+	IO_RANGE,
 	MEM_RANGE
 } hw_res_type_t;
@@ -66,5 +67,5 @@
 			size_t size;
 		} mem_range;
-
+		
 		struct {
 			uint64_t address;
@@ -72,5 +73,5 @@
 			size_t size;
 		} io_range;
-
+		
 		struct {
 			int irq;
@@ -88,13 +89,12 @@
 	if (hw_res->resources != NULL) {
 		free(hw_res->resources);
-
 		hw_res->resources = NULL;
 	}
-
+	
 	hw_res->count = 0;
 }
 
-extern int hw_res_get_resource_list(int, hw_resource_list_t *);
-extern bool hw_res_enable_interrupt(int);
+extern int hw_res_get_resource_list(async_sess_t *, hw_resource_list_t *);
+extern bool hw_res_enable_interrupt(async_sess_t *);
 
 #endif
Index: uspace/lib/c/include/devman.h
===================================================================
--- uspace/lib/c/include/devman.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/include/devman.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -41,6 +41,7 @@
 #include <bool.h>
 
-extern int devman_get_phone(devman_interface_t, unsigned int);
-extern void devman_hangup_phone(devman_interface_t);
+extern async_exch_t *devman_exchange_begin_blocking(devman_interface_t);
+extern async_exch_t *devman_exchange_begin(devman_interface_t);
+extern void devman_exchange_end(async_exch_t *);
 
 extern int devman_driver_register(const char *, async_client_conn_t);
@@ -48,6 +49,8 @@
     devman_handle_t, devman_handle_t *);
 
-extern int devman_device_connect(devman_handle_t, unsigned int);
-extern int devman_parent_device_connect(devman_handle_t, unsigned int);
+extern async_sess_t *devman_device_connect(exch_mgmt_t, devman_handle_t,
+    unsigned int);
+extern async_sess_t *devman_parent_device_connect(exch_mgmt_t, devman_handle_t,
+    unsigned int);
 
 extern int devman_device_get_handle(const char *, devman_handle_t *,
Index: uspace/lib/c/include/devman_obsolete.h
===================================================================
--- uspace/lib/c/include/devman_obsolete.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
+++ uspace/lib/c/include/devman_obsolete.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * Copyright (c) 2010 Lenka Trochtova 
+ * 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_DEVMAN_OBSOLETE_H_
+#define LIBC_DEVMAN_OBSOLETE_H_
+
+#include <ipc/devman.h>
+#include <async.h>
+#include <bool.h>
+
+extern int devman_obsolete_get_phone(devman_interface_t, unsigned int);
+extern void devman_obsolete_hangup_phone(devman_interface_t);
+
+extern int devman_obsolete_device_connect(devman_handle_t, unsigned int);
+extern int devman_obsolete_parent_device_connect(devman_handle_t, unsigned int);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/devmap.h
===================================================================
--- uspace/lib/c/include/devmap.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/include/devmap.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -40,16 +40,21 @@
 #include <bool.h>
 
-extern int devmap_get_phone(devmap_interface_t, unsigned int);
-extern void devmap_hangup_phone(devmap_interface_t iface);
+extern async_exch_t *devmap_exchange_begin_blocking(devmap_interface_t);
+extern async_exch_t *devmap_exchange_begin(devmap_interface_t);
+extern void devmap_exchange_end(async_exch_t *);
 
 extern int devmap_driver_register(const char *, async_client_conn_t);
 extern int devmap_device_register(const char *, devmap_handle_t *);
-extern int devmap_device_register_with_iface(const char *, devmap_handle_t *, sysarg_t);
+extern int devmap_device_register_with_iface(const char *, devmap_handle_t *,
+    sysarg_t);
 
-extern int devmap_device_get_handle(const char *, devmap_handle_t *, unsigned int);
-extern int devmap_namespace_get_handle(const char *, devmap_handle_t *, unsigned int);
+extern int devmap_device_get_handle(const char *, devmap_handle_t *,
+    unsigned int);
+extern int devmap_namespace_get_handle(const char *, devmap_handle_t *,
+    unsigned int);
 extern devmap_handle_type_t devmap_handle_probe(devmap_handle_t);
 
-extern int devmap_device_connect(devmap_handle_t, unsigned int);
+extern async_sess_t *devmap_device_connect(exch_mgmt_t, devmap_handle_t,
+    unsigned int);
 
 extern int devmap_null_create(void);
Index: uspace/lib/c/include/devmap_obsolete.h
===================================================================
--- uspace/lib/c/include/devmap_obsolete.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
+++ uspace/lib/c/include/devmap_obsolete.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -0,0 +1,50 @@
+/*
+ * 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/io/console.h
===================================================================
--- uspace/lib/c/include/io/console.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/include/io/console.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -36,10 +36,8 @@
 #define LIBC_IO_CONSOLE_H_
 
+#include <sys/time.h>
+#include <async.h>
 #include <bool.h>
-
-typedef enum {
-	KEY_PRESS,
-	KEY_RELEASE
-} console_ev_type_t;
+#include <stdio.h>
 
 typedef enum {
@@ -50,8 +48,34 @@
 } console_caps_t;
 
+/** Console control structure. */
+typedef struct {
+	/** Console input file */
+	FILE *input;
+	
+	/** Console output file */
+	FILE *output;
+	
+	/** Console input session */
+	async_sess_t *input_sess;
+	
+	/** Console output session */
+	async_sess_t *output_sess;
+	
+	/** Input request call with timeout */
+	ipc_call_t input_call;
+	
+	/** Input response with timeout */
+	aid_t input_aid;
+} console_ctrl_t;
+
+typedef enum {
+	KEY_PRESS,
+	KEY_RELEASE
+} kbd_event_type_t;
+
 /** Console event structure. */
 typedef struct {
 	/** Press or release event. */
-	console_ev_type_t type;
+	kbd_event_type_t type;
 	
 	/** Keycode of the key that was pressed or released. */
@@ -63,22 +87,26 @@
 	/** The character that was generated or '\0' for none. */
 	wchar_t c;
-} console_event_t;
+} kbd_event_t;
 
-extern void console_clear(int phone);
+extern console_ctrl_t *console_init(FILE *, FILE *);
+extern void console_done(console_ctrl_t *);
+extern bool console_kcon(void);
 
-extern int console_get_size(int phone, sysarg_t *cols, sysarg_t *rows);
-extern int console_get_pos(int phone, sysarg_t *col, sysarg_t *row);
-extern void console_set_pos(int phone, sysarg_t col, sysarg_t row);
+extern void console_flush(console_ctrl_t *);
+extern void console_clear(console_ctrl_t *);
 
-extern void console_set_style(int phone, uint8_t style);
-extern void console_set_color(int phone, uint8_t fg_color, uint8_t bg_color,
-    uint8_t flags);
-extern void console_set_rgb_color(int phone, uint32_t fg_color, uint32_t bg_color);
+extern int console_get_size(console_ctrl_t *, sysarg_t *, sysarg_t *);
+extern int console_get_pos(console_ctrl_t *, sysarg_t *, sysarg_t *);
+extern void console_set_pos(console_ctrl_t *, sysarg_t, sysarg_t);
 
-extern void console_cursor_visibility(int phone, bool show);
-extern int console_get_color_cap(int phone, sysarg_t *ccap);
-extern void console_kcon_enable(int phone);
+extern void console_set_style(console_ctrl_t *, uint8_t);
+extern void console_set_color(console_ctrl_t *, uint8_t, uint8_t, uint8_t);
+extern void console_set_rgb_color(console_ctrl_t *, uint32_t, uint32_t);
 
-extern bool console_get_event(int phone, console_event_t *event);
+extern void console_cursor_visibility(console_ctrl_t *, bool);
+extern int console_get_color_cap(console_ctrl_t *, sysarg_t *);
+extern bool console_get_kbd_event(console_ctrl_t *, kbd_event_t *);
+extern bool console_get_kbd_event_timeout(console_ctrl_t *, kbd_event_t *,
+    suseconds_t *);
 
 #endif
Index: uspace/lib/c/include/ipc/devmap.h
===================================================================
--- uspace/lib/c/include/ipc/devmap.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/include/ipc/devmap.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -31,6 +31,6 @@
  */
 
-#ifndef DEVMAP_DEVMAP_H_
-#define DEVMAP_DEVMAP_H_
+#ifndef LIBC_IPC_DEVMAP_H_
+#define LIBC_IPC_DEVMAP_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/ipc.h
===================================================================
--- uspace/lib/c/include/ipc/ipc.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/include/ipc/ipc.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -42,4 +42,5 @@
 #include <sys/types.h>
 #include <ipc/common.h>
+#include <kernel/ipc/ipc_methods.h>
 #include <kernel/synch/synch.h>
 #include <task.h>
@@ -255,4 +256,5 @@
 extern int ipc_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t *,
     sysarg_t *);
+extern int ipc_connect_me(int);
 extern int ipc_connect_me_to(int, sysarg_t, sysarg_t, sysarg_t);
 extern int ipc_connect_me_to_blocking(int, sysarg_t, sysarg_t, sysarg_t);
Index: uspace/lib/c/include/ipc/ns.h
===================================================================
--- uspace/lib/c/include/ipc/ns.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/include/ipc/ns.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -33,8 +33,7 @@
  */
 
-#ifndef LIBC_NS_H_
-#define LIBC_NS_H_
+#ifndef LIBC_IPC_NS_H_
+#define LIBC_IPC_NS_H_
 
-#include <sys/types.h>
 #include <ipc/common.h>
 
@@ -46,8 +45,4 @@
 } ns_request_t;
 
-extern int service_register(sysarg_t);
-extern int service_connect(sysarg_t, sysarg_t, sysarg_t);
-extern int service_connect_blocking(sysarg_t, sysarg_t, sysarg_t);
-
 #endif
 
Index: uspace/lib/c/include/ipc/serial_ctl.h
===================================================================
--- uspace/lib/c/include/ipc/serial_ctl.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/include/ipc/serial_ctl.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -32,11 +32,13 @@
 #include <ipc/dev_iface.h>
 
-/** ipc methods for getting/setting serial communication properties
- * 	1st ipc arg: baud rate
- * 	2nd ipc arg: parity
- *	3rd ipc arg: number of bits in one word
- *	4th ipc arg: number of stop bits
+/** IPC methods for getting/setting serial communication properties
+ *
+ * 1st IPC arg: baud rate
+ * 2nd IPC arg: parity
+ * 3rd IPC arg: number of bits in one word
+ * 4th IPC arg: number of stop bits
+ *
  */
-typedef enum {	
+typedef enum {
 	SERIAL_GET_COM_PROPS = DEV_FIRST_CUSTOM_METHOD,
 	SERIAL_SET_COM_PROPS
@@ -48,5 +50,5 @@
 	SERIAL_EVEN_PARITY = 3,
 	SERIAL_MARK_PARITY = 5,
-	SERIAL_SPACE_PARITY = 7	
+	SERIAL_SPACE_PARITY = 7
 } serial_parity_t;
 
Index: uspace/lib/c/include/ipc/vfs.h
===================================================================
--- uspace/lib/c/include/ipc/vfs.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/include/ipc/vfs.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -69,4 +69,5 @@
 	VFS_IN_FSTAT,
 	VFS_IN_CLOSE,
+	VFS_IN_PING,
 	VFS_IN_MOUNT,
 	VFS_IN_UNMOUNT,
Index: uspace/lib/c/include/loader/loader.h
===================================================================
--- uspace/lib/c/include/loader/loader.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/include/loader/loader.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -40,9 +40,7 @@
 #include <vfs/vfs.h>
 
-/** Abstraction of a loader connection */
-typedef struct {
-	/** ID of the phone connected to the loader. */
-	int phone_id;
-} loader_t;
+/** Forward declararion */
+struct loader;
+typedef struct loader loader_t;
 
 extern int loader_spawn(const char *);
Index: uspace/lib/c/include/ns.h
===================================================================
--- uspace/lib/c/include/ns.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
+++ uspace/lib/c/include/ns.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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_NS_H_
+#define LIBC_NS_H_
+
+#include <sys/types.h>
+#include <task.h>
+#include <async.h>
+
+extern int service_register(sysarg_t);
+extern async_sess_t *service_connect(exch_mgmt_t, sysarg_t, sysarg_t, sysarg_t);
+extern async_sess_t *service_connect_blocking(exch_mgmt_t, sysarg_t, sysarg_t,
+    sysarg_t);
+
+extern int ns_ping(void);
+extern int ns_intro(task_id_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ns_obsolete.h
===================================================================
--- uspace/lib/c/include/ns_obsolete.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
+++ uspace/lib/c/include/ns_obsolete.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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_NS_OBSOLETE_H_
+#define LIBC_NS_OBSOLETE_H_
+
+#include <sys/types.h>
+#include <task.h>
+
+extern int service_obsolete_connect(sysarg_t, sysarg_t, sysarg_t);
+extern int service_obsolete_connect_blocking(sysarg_t, sysarg_t,
+    sysarg_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/stdio.h
===================================================================
--- uspace/lib/c/include/stdio.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/include/stdio.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -97,47 +97,7 @@
 };
 
-typedef struct {
-	/** Linked list pointer. */
-	link_t link;
-	
-	/** Underlying file descriptor. */
-	int fd;
-	
-	/** Error indicator. */
-	int error;
-	
-	/** End-of-file indicator. */
-	int eof;
-	
-	/** Klog indicator */
-	int klog;
-	
-	/** Phone to the file provider */
-	int phone;
-
-	/**
-	 * Non-zero if the stream needs sync on fflush(). XXX change
-	 * console semantics so that sync is not needed.
-	 */
-	int need_sync;
-
-	/** Buffering type */
-	enum _buffer_type btype;
-
-	/** Buffer */
-	uint8_t *buf;
-
-	/** Buffer size */
-	size_t buf_size;
-
-	/** Buffer state */
-	enum _buffer_state buf_state;
-
-	/** Buffer I/O pointer */
-	uint8_t *buf_head;
-
-	/** Points to end of occupied space when in read mode. */
-	uint8_t *buf_tail;
-} FILE;
+/** Forward declaration */
+struct _IO_FILE;
+typedef struct _IO_FILE FILE;
 
 extern FILE *stdin;
Index: uspace/lib/c/include/udebug.h
===================================================================
--- uspace/lib/c/include/udebug.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/include/udebug.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -38,18 +38,23 @@
 #include <kernel/udebug/udebug.h>
 #include <sys/types.h>
+#include <async.h>
 
 typedef sysarg_t thash_t;
 
-int udebug_begin(int);
-int udebug_end(int);
-int udebug_set_evmask(int, udebug_evmask_t);
-int udebug_thread_read(int, void *, size_t , size_t *, size_t *);
-int udebug_name_read(int, void *, size_t, size_t *, size_t *);
-int udebug_areas_read(int, void *, size_t, size_t *, size_t *);
-int udebug_mem_read(int, void *, uintptr_t, size_t);
-int udebug_args_read(int, thash_t, sysarg_t *);
-int udebug_regs_read(int, thash_t, void *);
-int udebug_go(int, thash_t, udebug_event_t *, sysarg_t *, sysarg_t *);
-int udebug_stop(int, thash_t);
+extern int udebug_begin(async_sess_t *);
+extern int udebug_end(async_sess_t *);
+extern int udebug_set_evmask(async_sess_t *, udebug_evmask_t);
+extern int udebug_thread_read(async_sess_t *, void *, size_t , size_t *,
+    size_t *);
+extern int udebug_name_read(async_sess_t *, void *, size_t, size_t *,
+    size_t *);
+extern int udebug_areas_read(async_sess_t *, void *, size_t, size_t *,
+    size_t *);
+extern int udebug_mem_read(async_sess_t *, void *, uintptr_t, size_t);
+extern int udebug_args_read(async_sess_t *, thash_t, sysarg_t *);
+extern int udebug_regs_read(async_sess_t *, thash_t, void *);
+extern int udebug_go(async_sess_t *, thash_t, udebug_event_t *, sysarg_t *,
+    sysarg_t *);
+extern int udebug_stop(async_sess_t *, thash_t);
 
 #endif
Index: uspace/lib/c/include/vfs/vfs.h
===================================================================
--- uspace/lib/c/include/vfs/vfs.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/c/include/vfs/vfs.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -41,7 +41,9 @@
 #include <stdio.h>
 
-/**
- * This type is a libc version of the VFS triplet.
- * It uniquely identifies a file system node within a file system instance.
+/** Libc version of the VFS triplet.
+ *
+ * Unique identification of a file system node
+ * within a file system instance.
+ *
  */
 typedef struct {
@@ -58,9 +60,7 @@
 
 extern int open_node(fdi_node_t *, int);
-extern int fd_phone(int);
 extern int fd_node(int, fdi_node_t *);
 
 extern FILE *fopen_node(fdi_node_t *, const char *);
-extern int fphone(FILE *);
 extern int fnode(FILE *, fdi_node_t *);
 
Index: uspace/lib/c/include/vfs/vfs_sess.h
===================================================================
--- uspace/lib/c/include/vfs/vfs_sess.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
+++ uspace/lib/c/include/vfs/vfs_sess.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007 Jakub Jermar
+ * 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_VFS_SESS_H_
+#define LIBC_VFS_SESS_H_
+
+#include <async.h>
+#include <stdio.h>
+
+extern async_sess_t *fd_session(exch_mgmt_t, int);
+extern async_sess_t *fsession(exch_mgmt_t, FILE *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/clui/tinput.c
===================================================================
--- uspace/lib/clui/tinput.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/clui/tinput.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -54,8 +54,8 @@
 static void tinput_sel_all(tinput_t *);
 static void tinput_sel_delete(tinput_t *);
-static void tinput_key_ctrl(tinput_t *, console_event_t *);
-static void tinput_key_shift(tinput_t *, console_event_t *);
-static void tinput_key_ctrl_shift(tinput_t *, console_event_t *);
-static void tinput_key_unmod(tinput_t *, console_event_t *);
+static void tinput_key_ctrl(tinput_t *, kbd_event_t *);
+static void tinput_key_shift(tinput_t *, kbd_event_t *);
+static void tinput_key_ctrl_shift(tinput_t *, kbd_event_t *);
+static void tinput_key_unmod(tinput_t *, kbd_event_t *);
 static void tinput_pre_seek(tinput_t *, bool);
 static void tinput_post_seek(tinput_t *, bool);
@@ -88,7 +88,7 @@
 	tinput_sel_get_bounds(ti, &sa, &sb);
 	
-	console_set_pos(fphone(stdout), (ti->col0 + start) % ti->con_cols,
+	console_set_pos(ti->console, (ti->col0 + start) % ti->con_cols,
 	    ti->row0 + (ti->col0 + start) / ti->con_cols);
-	console_set_style(fphone(stdout), STYLE_NORMAL);
+	console_set_style(ti->console, STYLE_NORMAL);
 	
 	size_t p = start;
@@ -101,6 +101,7 @@
 	
 	if (p < sb) {
-		fflush(stdout);
-		console_set_style(fphone(stdout), STYLE_SELECTED);
+		console_flush(ti->console);
+		console_set_style(ti->console, STYLE_SELECTED);
+		
 		memcpy(dbuf, ti->buffer + p,
 		    (sb - p) * sizeof(wchar_t));
@@ -110,6 +111,6 @@
 	}
 	
-	fflush(stdout);
-	console_set_style(fphone(stdout), STYLE_NORMAL);
+	console_flush(ti->console);
+	console_set_style(ti->console, STYLE_NORMAL);
 	
 	if (p < ti->nc) {
@@ -123,5 +124,5 @@
 		putchar(' ');
 	
-	fflush(stdout);
+	console_flush(ti->console);
 }
 
@@ -133,5 +134,5 @@
 static void tinput_position_caret(tinput_t *ti)
 {
-	console_set_pos(fphone(stdout), (ti->col0 + ti->pos) % ti->con_cols,
+	console_set_pos(ti->console, (ti->col0 + ti->pos) % ti->con_cols,
 	    ti->row0 + (ti->col0 + ti->pos) / ti->con_cols);
 }
@@ -516,4 +517,5 @@
 static void tinput_init(tinput_t *ti)
 {
+	ti->console = console_init(stdin, stdout);
 	ti->hnum = 0;
 	ti->hpos = 0;
@@ -533,9 +535,9 @@
 int tinput_read(tinput_t *ti, char **dstr)
 {
-	fflush(stdout);
-	if (console_get_size(fphone(stdin), &ti->con_cols, &ti->con_rows) != EOK)
+	console_flush(ti->console);
+	if (console_get_size(ti->console, &ti->con_cols, &ti->con_rows) != EOK)
 		return EIO;
 	
-	if (console_get_pos(fphone(stdin), &ti->col0, &ti->row0) != EOK)
+	if (console_get_pos(ti->console, &ti->col0, &ti->row0) != EOK)
 		return EIO;
 	
@@ -548,8 +550,8 @@
 	
 	while (!ti->done) {
-		fflush(stdout);
-		
-		console_event_t ev;
-		if (!console_get_event(fphone(stdin), &ev))
+		console_flush(ti->console);
+		
+		kbd_event_t ev;
+		if (!console_get_kbd_event(ti->console, &ev))
 			return EIO;
 		
@@ -596,5 +598,5 @@
 }
 
-static void tinput_key_ctrl(tinput_t *ti, console_event_t *ev)
+static void tinput_key_ctrl(tinput_t *ti, kbd_event_t *ev)
 {
 	switch (ev->key) {
@@ -635,5 +637,5 @@
 }
 
-static void tinput_key_ctrl_shift(tinput_t *ti, console_event_t *ev)
+static void tinput_key_ctrl_shift(tinput_t *ti, kbd_event_t *ev)
 {
 	switch (ev->key) {
@@ -655,5 +657,5 @@
 }
 
-static void tinput_key_shift(tinput_t *ti, console_event_t *ev)
+static void tinput_key_shift(tinput_t *ti, kbd_event_t *ev)
 {
 	switch (ev->key) {
@@ -681,5 +683,5 @@
 }
 
-static void tinput_key_unmod(tinput_t *ti, console_event_t *ev)
+static void tinput_key_unmod(tinput_t *ti, kbd_event_t *ev)
 {
 	switch (ev->key) {
Index: uspace/lib/clui/tinput.h
===================================================================
--- uspace/lib/clui/tinput.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/clui/tinput.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -37,4 +37,9 @@
 #define LIBCLUI_TINPUT_H_
 
+#include <stdio.h>
+#include <async.h>
+#include <inttypes.h>
+#include <io/console.h>
+
 #define HISTORY_LEN     10
 #define INPUT_MAX_SIZE  1024
@@ -45,4 +50,7 @@
  */
 typedef struct {
+	/** Console */
+	console_ctrl_t *console;
+	
 	/** Buffer holding text currently being edited */
 	wchar_t buffer[INPUT_MAX_SIZE + 1];
Index: uspace/lib/drv/Makefile
===================================================================
--- uspace/lib/drv/Makefile	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/drv/Makefile	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -35,7 +35,7 @@
 	generic/driver.c \
 	generic/dev_iface.c \
-	generic/remote_char_dev.c \
 	generic/log.c \
 	generic/remote_hw_res.c \
+	generic/remote_char_dev.c \
 	generic/remote_usb.c \
 	generic/remote_pci.c \
Index: uspace/lib/drv/generic/dev_iface.c
===================================================================
--- uspace/lib/drv/generic/dev_iface.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/drv/generic/dev_iface.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -62,5 +62,4 @@
 {
 	assert(is_valid_iface_idx(idx));
-	
 	return remote_ifaces.ifaces[idx];
 }
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/drv/generic/driver.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -285,13 +285,12 @@
 	async_answer_0(iid, EOK);
 	
-	bool cont = true;
-	while (cont) {
+	while (true) {
 		ipc_call_t call;
 		ipc_callid_t callid = async_get_call(&call);
 		
+		if (!IPC_GET_IMETHOD(call))
+			break;
+		
 		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			cont = false;
-			continue;
 		case DRIVER_ADD_DEVICE:
 			driver_add_device(callid, &call);
@@ -303,9 +302,9 @@
 }
 
-/**
- * Generic client connection handler both for applications and drivers.
- *
- * @param drv		True for driver client, false for other clients
- *			(applications, services etc.).
+/** Generic client connection handler both for applications and drivers.
+ *
+ * @param drv True for driver client, false for other clients
+ *            (applications, services, etc.).
+ *
  */
 static void driver_connection_gen(ipc_callid_t iid, ipc_call_t *icall, bool drv)
@@ -317,5 +316,5 @@
 	devman_handle_t handle = IPC_GET_ARG2(*icall);
 	ddf_fun_t *fun = driver_get_function(&functions, handle);
-
+	
 	if (fun == NULL) {
 		printf("%s: driver_connection_gen error - no function with handle"
@@ -325,5 +324,4 @@
 	}
 	
-	
 	/*
 	 * TODO - if the client is not a driver, check whether it is allowed to
@@ -340,13 +338,11 @@
 		return;
 	
-	while (1) {
+	while (true) {
 		ipc_callid_t callid;
 		ipc_call_t call;
 		callid = async_get_call(&call);
 		sysarg_t method = IPC_GET_IMETHOD(call);
-		int iface_idx;
-		
-		switch  (method) {
-		case IPC_M_PHONE_HUNGUP:
+		
+		if (!method) {
 			/* Close device function */
 			if (fun->ops != NULL && fun->ops->close != NULL)
@@ -354,71 +350,68 @@
 			async_answer_0(callid, EOK);
 			return;
-		default:
-			/* convert ipc interface id to interface index */
-			
-			iface_idx = DEV_IFACE_IDX(method);
-			
-			if (!is_valid_iface_idx(iface_idx)) {
-				remote_handler_t *default_handler =
-				    function_get_default_handler(fun);
-				if (default_handler != NULL) {
-					(*default_handler)(fun, callid, &call);
-					break;
-				}
-				
-				/*
-				 * Function has no such interface and
-				 * default handler is not provided.
-				 */
-				printf("%s: driver_connection_gen error - "
-				    "invalid interface id %d.",
-				    driver->name, iface_idx);
-				async_answer_0(callid, ENOTSUP);
-				break;
-			}
-			
-			/* calling one of the function's interfaces */
-			
-			/* Get the interface ops structure. */
-			void *ops = function_get_ops(fun, iface_idx);
-			if (ops == NULL) {
-				printf("%s: driver_connection_gen error - ",
-				    driver->name);
-				printf("Function with handle %" PRIun " has no interface "
-				    "with id %d.\n", handle, iface_idx);
-				async_answer_0(callid, ENOTSUP);
+		}
+		
+		/* Convert ipc interface id to interface index */
+		
+		int iface_idx = DEV_IFACE_IDX(method);
+		
+		if (!is_valid_iface_idx(iface_idx)) {
+			remote_handler_t *default_handler =
+			    function_get_default_handler(fun);
+			if (default_handler != NULL) {
+				(*default_handler)(fun, callid, &call);
 				break;
 			}
 			
 			/*
-			 * Get the corresponding interface for remote request
-			 * handling ("remote interface").
+			 * Function has no such interface and
+			 * default handler is not provided.
 			 */
-			remote_iface_t *rem_iface = get_remote_iface(iface_idx);
-			assert(rem_iface != NULL);
-			
-			/* get the method of the remote interface */
-			sysarg_t iface_method_idx = IPC_GET_ARG1(call);
-			remote_iface_func_ptr_t iface_method_ptr =
-			    get_remote_method(rem_iface, iface_method_idx);
-			if (iface_method_ptr == NULL) {
-				/* The interface has not such method */
-				printf("%s: driver_connection_gen error - "
-				    "invalid interface method "
-				    "(index %" PRIun ").\n",
-				    driver->name, iface_method_idx);
-				async_answer_0(callid, ENOTSUP);
-				break;
-			}
-			
-			/*
-			 * Call the remote interface's method, which will
-			 * receive parameters from the remote client and it will
-			 * pass it to the corresponding local interface method
-			 * associated with the function by its driver.
-			 */
-			(*iface_method_ptr)(fun, ops, callid, &call);
+			printf("%s: driver_connection_gen error - "
+			    "invalid interface id %d.",
+			    driver->name, iface_idx);
+			async_answer_0(callid, ENOTSUP);
 			break;
 		}
+		
+		/* Calling one of the function's interfaces */
+		
+		/* Get the interface ops structure. */
+		void *ops = function_get_ops(fun, iface_idx);
+		if (ops == NULL) {
+			printf("%s: driver_connection_gen error - ", driver->name);
+			printf("Function with handle %" PRIun " has no interface "
+			    "with id %d.\n", handle, iface_idx);
+			async_answer_0(callid, ENOTSUP);
+			break;
+		}
+		
+		/*
+		 * Get the corresponding interface for remote request
+		 * handling ("remote interface").
+		 */
+		remote_iface_t *rem_iface = get_remote_iface(iface_idx);
+		assert(rem_iface != NULL);
+		
+		/* get the method of the remote interface */
+		sysarg_t iface_method_idx = IPC_GET_ARG1(call);
+		remote_iface_func_ptr_t iface_method_ptr =
+		    get_remote_method(rem_iface, iface_method_idx);
+		if (iface_method_ptr == NULL) {
+			/* The interface has not such method */
+			printf("%s: driver_connection_gen error - "
+			    "invalid interface method.", driver->name);
+			async_answer_0(callid, ENOTSUP);
+			break;
+		}
+		
+		/*
+		 * Call the remote interface's method, which will
+		 * receive parameters from the remote client and it will
+		 * pass it to the corresponding local interface method
+		 * associated with the function by its driver.
+		 */
+		(*iface_method_ptr)(fun, ops, callid, &call);
+		break;
 	}
 }
Index: uspace/lib/drv/include/ddf/driver.h
===================================================================
--- uspace/lib/drv/include/ddf/driver.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/drv/include/ddf/driver.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -37,7 +37,7 @@
 #define DDF_DRIVER_H_
 
+#include <async.h>
 #include <ipc/devman.h>
 #include <ipc/dev_iface.h>
-
 #include "../dev_iface.h"
 
@@ -83,8 +83,8 @@
 	
 	/**
-	 * Phone to the parent device driver (if it is different from this
+	 * Session to the parent device driver (if it is different from this
 	 * driver)
 	 */
-	int parent_phone;
+	async_sess_t *parent_sess;
 	
 	/** Device name */
Index: uspace/lib/ext2/libext2_filesystem.c
===================================================================
--- uspace/lib/ext2/libext2_filesystem.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/ext2/libext2_filesystem.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -62,5 +62,5 @@
 	fs->device = devmap_handle;
 	
-	rc = block_init(fs->device, 2048);
+	rc = block_init(EXCHANGE_SERIALIZE, fs->device, 2048);
 	if (rc != EOK) {
 		return rc;
Index: uspace/lib/fs/libfs.c
===================================================================
--- uspace/lib/fs/libfs.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/fs/libfs.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -67,16 +67,16 @@
  * code.
  *
- * @param vfs_phone Open phone for communication with VFS.
- * @param reg       File system registration structure. It will be
- *                  initialized by this function.
- * @param info      VFS info structure supplied by the file system
- *                  implementation.
- * @param conn      Connection fibril for handling all calls originating in
- *                  VFS.
+ * @param sess Session for communication with VFS.
+ * @param reg  File system registration structure. It will be
+ *             initialized by this function.
+ * @param info VFS info structure supplied by the file system
+ *             implementation.
+ * @param conn Connection fibril for handling all calls originating in
+ *             VFS.
  *
  * @return EOK on success or a non-zero error code on errror.
  *
  */
-int fs_register(int vfs_phone, fs_reg_t *reg, vfs_info_t *info,
+int fs_register(async_sess_t *sess, fs_reg_t *reg, vfs_info_t *info,
     async_client_conn_t conn)
 {
@@ -86,12 +86,17 @@
 	 * out-of-order, when it knows that the operation succeeded or failed.
 	 */
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	
 	ipc_call_t answer;
-	aid_t req = async_send_0(vfs_phone, VFS_IN_REGISTER, &answer);
+	aid_t req = async_send_0(exch, VFS_IN_REGISTER, &answer);
 	
 	/*
 	 * Send our VFS info structure to VFS.
 	 */
-	int rc = async_data_write_start(vfs_phone, info, sizeof(*info)); 
+	int rc = async_data_write_start(exch, info, sizeof(*info));
+	
 	if (rc != EOK) {
+		async_exchange_end(exch);
 		async_wait_for(req, NULL);
 		return rc;
@@ -101,5 +106,5 @@
 	 * Ask VFS for callback connection.
 	 */
-	async_connect_to_me(vfs_phone, 0, 0, 0, conn);
+	async_connect_to_me(exch, 0, 0, 0, conn);
 	
 	/*
@@ -108,4 +113,5 @@
 	reg->plb_ro = as_get_mappable_page(PLB_SIZE);
 	if (!reg->plb_ro) {
+		async_exchange_end(exch);
 		async_wait_for(req, NULL);
 		return ENOMEM;
@@ -115,5 +121,8 @@
 	 * Request sharing the Path Lookup Buffer with VFS.
 	 */
-	rc = async_share_in_start_0_0(vfs_phone, reg->plb_ro, PLB_SIZE);
+	rc = async_share_in_start_0_0(exch, reg->plb_ro, PLB_SIZE);
+	
+	async_exchange_end(exch);
+	
 	if (rc) {
 		async_wait_for(req, NULL);
@@ -148,27 +157,15 @@
 	fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*request);
 	devmap_handle_t mr_devmap_handle = (devmap_handle_t) IPC_GET_ARG4(*request);
-	int res;
-	sysarg_t rc;
-	
-	ipc_call_t call;
-	ipc_callid_t callid;
-	
-	/* Accept the phone */
-	callid = async_get_call(&call);
-	int mountee_phone = (int) IPC_GET_ARG1(call);
-	if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECTION_CLONE) ||
-	    (mountee_phone < 0)) {
-		async_answer_0(callid, EINVAL);
+	
+	async_sess_t *mountee_sess = async_clone_receive(EXCHANGE_PARALLEL);
+	if (mountee_sess == NULL) {
 		async_answer_0(rid, EINVAL);
 		return;
 	}
 	
-	/* Acknowledge the mountee_phone */
-	async_answer_0(callid, EOK);
-	
 	fs_node_t *fn;
-	res = ops->node_get(&fn, mp_devmap_handle, mp_fs_index);
+	int res = ops->node_get(&fn, mp_devmap_handle, mp_fs_index);
 	if ((res != EOK) || (!fn)) {
-		async_hangup(mountee_phone);
+		async_hangup(mountee_sess);
 		async_data_write_void(combine_rc(res, ENOENT));
 		async_answer_0(rid, combine_rc(res, ENOENT));
@@ -177,5 +174,5 @@
 	
 	if (fn->mp_data.mp_active) {
-		async_hangup(mountee_phone);
+		async_hangup(mountee_sess);
 		(void) ops->node_put(fn);
 		async_data_write_void(EBUSY);
@@ -184,16 +181,20 @@
 	}
 	
-	rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME);
-	if (rc != EOK) {
-		async_hangup(mountee_phone);
+	async_exch_t *exch = async_exchange_begin(mountee_sess);
+	async_sess_t *sess = async_connect_me(EXCHANGE_PARALLEL, exch);
+	
+	if (!sess) {
+		async_exchange_end(exch);
+		async_hangup(mountee_sess);
 		(void) ops->node_put(fn);
-		async_data_write_void(rc);
-		async_answer_0(rid, rc);
+		async_data_write_void(errno);
+		async_answer_0(rid, errno);
 		return;
 	}
 	
 	ipc_call_t answer;
-	rc = async_data_write_forward_1_1(mountee_phone, VFS_OUT_MOUNTED,
+	int rc = async_data_write_forward_1_1(exch, VFS_OUT_MOUNTED,
 	    mr_devmap_handle, &answer);
+	async_exchange_end(exch);
 	
 	if (rc == EOK) {
@@ -201,5 +202,5 @@
 		fn->mp_data.fs_handle = mr_fs_handle;
 		fn->mp_data.devmap_handle = mr_devmap_handle;
-		fn->mp_data.phone = mountee_phone;
+		fn->mp_data.sess = mountee_sess;
 	}
 	
@@ -236,6 +237,7 @@
 	 * Tell the mounted file system to unmount.
 	 */
-	res = async_req_1_0(fn->mp_data.phone, VFS_OUT_UNMOUNTED,
-	    fn->mp_data.devmap_handle);
+	async_exch_t *exch = async_exchange_begin(fn->mp_data.sess);
+	res = async_req_1_0(exch, VFS_OUT_UNMOUNTED, fn->mp_data.devmap_handle);
+	async_exchange_end(exch);
 
 	/*
@@ -243,9 +245,10 @@
 	 */
 	if (res == EOK) {
-		async_hangup(fn->mp_data.phone);
+		async_hangup(fn->mp_data.sess);
 		fn->mp_data.mp_active = false;
 		fn->mp_data.fs_handle = 0;
 		fn->mp_data.devmap_handle = 0;
-		fn->mp_data.phone = 0;
+		fn->mp_data.sess = NULL;
+		
 		/* Drop the reference created in libfs_mount(). */
 		(void) ops->node_put(fn);
@@ -293,7 +296,9 @@
 	
 	if (cur->mp_data.mp_active) {
-		async_forward_slow(rid, cur->mp_data.phone, VFS_OUT_LOOKUP,
-		    next, last, cur->mp_data.devmap_handle, lflag, index,
-		    IPC_FF_ROUTE_FROM_ME);
+		async_exch_t *exch = async_exchange_begin(cur->mp_data.sess);
+		async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last,
+		    cur->mp_data.devmap_handle, lflag, index, IPC_FF_ROUTE_FROM_ME);
+		async_exchange_end(exch);
+		
 		(void) ops->node_put(cur);
 		return;
@@ -351,7 +356,10 @@
 				next--;
 			
-			async_forward_slow(rid, tmp->mp_data.phone,
-			    VFS_OUT_LOOKUP, next, last, tmp->mp_data.devmap_handle,
-			    lflag, index, IPC_FF_ROUTE_FROM_ME);
+			async_exch_t *exch = async_exchange_begin(tmp->mp_data.sess);
+			async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last,
+			    tmp->mp_data.devmap_handle, lflag, index,
+			    IPC_FF_ROUTE_FROM_ME);
+			async_exchange_end(exch);
+			
 			(void) ops->node_put(cur);
 			(void) ops->node_put(tmp);
Index: uspace/lib/fs/libfs.h
===================================================================
--- uspace/lib/fs/libfs.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/fs/libfs.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -44,5 +44,5 @@
 typedef struct {
 	bool mp_active;
-	int phone;
+	async_sess_t *sess;
 	fs_handle_t fs_handle;
 	devmap_handle_t devmap_handle;
@@ -88,5 +88,6 @@
 } fs_reg_t;
 
-extern int fs_register(int, fs_reg_t *, vfs_info_t *, async_client_conn_t);
+extern int fs_register(async_sess_t *, fs_reg_t *, vfs_info_t *,
+    async_client_conn_t);
 
 extern void fs_node_initialize(fs_node_t *);
Index: uspace/lib/net/generic/generic.c
===================================================================
--- uspace/lib/net/generic/generic.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/net/generic/generic.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -37,4 +37,5 @@
 #include <generic.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <ipc/services.h>
 #include <net/device.h>
@@ -56,5 +57,5 @@
     int state, services_t target)
 {
-	async_msg_3(phone, (sysarg_t) message, (sysarg_t) device_id,
+	async_obsolete_msg_3(phone, (sysarg_t) message, (sysarg_t) device_id,
 	    (sysarg_t) state, target);
 	
@@ -78,5 +79,5 @@
     int arg2, services_t service)
 {
-	return (int) async_req_3_0(phone, (sysarg_t) message,
+	return (int) async_obsolete_req_3_0(phone, (sysarg_t) message,
 	    (sysarg_t) device_id, (sysarg_t) arg2, (sysarg_t) service);
 }
@@ -107,5 +108,5 @@
 
 	/* Request the address */
-	message_id = async_send_1(phone, (sysarg_t) message,
+	message_id = async_obsolete_send_1(phone, (sysarg_t) message,
 	    (sysarg_t) device_id, NULL);
 	string = measured_strings_return(phone, address, data, 1);
@@ -145,5 +146,5 @@
 	sysarg_t suffix;
 	
-	sysarg_t result = async_req_1_4(phone, (sysarg_t) message,
+	sysarg_t result = async_obsolete_req_1_4(phone, (sysarg_t) message,
 	    (sysarg_t) device_id, &addr_len, &prefix, &content, &suffix);
 	
@@ -172,8 +173,8 @@
 {
 	if (error) {
-		async_msg_4(phone, (sysarg_t) message, (sysarg_t) device_id,
+		async_obsolete_msg_4(phone, (sysarg_t) message, (sysarg_t) device_id,
 		    (sysarg_t) packet_id, (sysarg_t) target, (sysarg_t) error);
 	} else {
-		async_msg_3(phone, (sysarg_t) message, (sysarg_t) device_id,
+		async_obsolete_msg_3(phone, (sysarg_t) message, (sysarg_t) device_id,
 		    (sysarg_t) packet_id, (sysarg_t) target);
 	}
@@ -198,8 +199,8 @@
 {
 	if (error) {
-		async_msg_4(phone, (sysarg_t) message, (sysarg_t) device_id,
+		async_obsolete_msg_4(phone, (sysarg_t) message, (sysarg_t) device_id,
 		    (sysarg_t) packet_id, (sysarg_t) sender, (sysarg_t) error);
 	} else {
-		async_msg_3(phone, (sysarg_t) message, (sysarg_t) device_id,
+		async_obsolete_msg_3(phone, (sysarg_t) message, (sysarg_t) device_id,
 		    (sysarg_t) packet_id, (sysarg_t) sender);
 	}
@@ -243,5 +244,5 @@
 
 	/* Request the translation */
-	message_id = async_send_3(phone, (sysarg_t) message,
+	message_id = async_obsolete_send_3(phone, (sysarg_t) message,
 	    (sysarg_t) device_id, (sysarg_t) count, (sysarg_t) service, NULL);
 	measured_strings_send(phone, configuration, count);
Index: uspace/lib/net/generic/packet_remote.c
===================================================================
--- uspace/lib/net/generic/packet_remote.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/net/generic/packet_remote.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -37,4 +37,5 @@
 
 #include <async.h>
+#include <async_obsolete.h>
 #include <errno.h>
 #include <ipc/packet.h>
@@ -59,5 +60,5 @@
  * @return EOK on success.
  * @return Other error codes as defined for the pm_add() function.
- * @return Other error codes as defined for the async_share_in_start() function.
+ * @return Other error codes as defined for the async_obsolete_share_in_start() function.
  *
  */
@@ -69,8 +70,8 @@
 	int rc;
 	
-	message = async_send_1(phone, NET_PACKET_GET, packet_id, &answer);
+	message = async_obsolete_send_1(phone, NET_PACKET_GET, packet_id, &answer);
 
 	*packet = (packet_t *) as_get_mappable_page(size);
-	rc = async_share_in_start_0_0(phone, *packet, size);
+	rc = async_obsolete_share_in_start_0_0(phone, *packet, size);
 	if (rc != EOK) {
 		munmap(*packet, size);
@@ -117,5 +118,5 @@
 		sysarg_t size;
 		
-		rc = async_req_1_1(phone, NET_PACKET_GET_SIZE, packet_id,
+		rc = async_obsolete_req_1_1(phone, NET_PACKET_GET_SIZE, packet_id,
 		    &size);
 		if (rc != EOK)
@@ -154,5 +155,5 @@
 	int rc;
 	
-	rc = async_req_4_2(phone, NET_PACKET_CREATE_4, max_content, addr_len,
+	rc = async_obsolete_req_4_2(phone, NET_PACKET_CREATE_4, max_content, addr_len,
 	    max_prefix, max_suffix, &packet_id, &size);
 	if (rc != EOK)
@@ -185,5 +186,5 @@
 	int rc;
 	
-	rc = async_req_1_2(phone, NET_PACKET_CREATE_1, content, &packet_id,
+	rc = async_obsolete_req_1_2(phone, NET_PACKET_CREATE_1, content, &packet_id,
 	    &size);
 	if (rc != EOK)
@@ -212,5 +213,5 @@
 void pq_release_remote(int phone, packet_id_t packet_id)
 {
-	async_msg_1(phone, NET_PACKET_RELEASE, packet_id);
+	async_obsolete_msg_1(phone, NET_PACKET_RELEASE, packet_id);
 }
 
Index: uspace/lib/net/il/arp_remote.c
===================================================================
--- uspace/lib/net/il/arp_remote.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/net/il/arp_remote.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -40,4 +40,5 @@
 
 #include <async.h>
+#include <async_obsolete.h>
 #include <errno.h>
 #include <ipc/services.h>
@@ -68,5 +69,5 @@
 int arp_clean_cache_req(int arp_phone)
 {
-	return (int) async_req_0_0(arp_phone, NET_ARP_CLEAN_CACHE);
+	return (int) async_obsolete_req_0_0(arp_phone, NET_ARP_CLEAN_CACHE);
 }
 
@@ -87,5 +88,5 @@
 	sysarg_t result;
 
-	message_id = async_send_2(arp_phone, NET_ARP_CLEAR_ADDRESS,
+	message_id = async_obsolete_send_2(arp_phone, NET_ARP_CLEAR_ADDRESS,
 	    (sysarg_t) device_id, protocol, NULL);
 	measured_strings_send(arp_phone, address, 1);
@@ -104,5 +105,5 @@
 int arp_clear_device_req(int arp_phone, device_id_t device_id)
 {
-	return (int) async_req_1_0(arp_phone, NET_ARP_CLEAR_DEVICE,
+	return (int) async_obsolete_req_1_0(arp_phone, NET_ARP_CLEAR_DEVICE,
 	    (sysarg_t) device_id);
 }
@@ -137,5 +138,5 @@
 	sysarg_t result;
 
-	message_id = async_send_3(arp_phone, NET_ARP_DEVICE,
+	message_id = async_obsolete_send_3(arp_phone, NET_ARP_DEVICE,
 	    (sysarg_t) device_id, protocol, netif, NULL);
 	measured_strings_send(arp_phone, address, 1);
Index: uspace/lib/net/il/il_skel.c
===================================================================
--- uspace/lib/net/il/il_skel.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/net/il/il_skel.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -42,4 +42,7 @@
 #include <net/modules.h>
 
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
+
 /** Default thread for new connections.
  *
@@ -75,6 +78,5 @@
 		 * result.
 		 */
-		if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
-		    (res == EHANGUP))
+		if ((!IPC_GET_IMETHOD(call)) || (res == EHANGUP))
 			return;
 		
Index: uspace/lib/net/il/ip_remote.c
===================================================================
--- uspace/lib/net/il/ip_remote.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/net/il/ip_remote.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -44,5 +44,5 @@
 #include <packet_client.h>
 #include <generic.h>
-
+#include <async_obsolete.h>
 #include <ipc/services.h>
 #include <ipc/il.h>
@@ -66,5 +66,5 @@
     in_addr_t address, in_addr_t netmask, in_addr_t gateway)
 {
-	return (int) async_req_4_0(ip_phone, NET_IP_ADD_ROUTE,
+	return (int) async_obsolete_req_4_0(ip_phone, NET_IP_ADD_ROUTE,
 	    (sysarg_t) device_id, (sysarg_t) gateway.s_addr,
 	    (sysarg_t) address.s_addr, (sysarg_t) netmask.s_addr);
@@ -150,13 +150,13 @@
 	
 	ipc_call_t answer;
-	aid_t message_id = async_send_1(ip_phone, NET_IP_GET_ROUTE,
+	aid_t message_id = async_obsolete_send_1(ip_phone, NET_IP_GET_ROUTE,
 	    (sysarg_t) protocol, &answer);
 	
-	if ((async_data_write_start(ip_phone, destination, addrlen) == EOK) &&
-	    (async_data_read_start(ip_phone, headerlen,
+	if ((async_obsolete_data_write_start(ip_phone, destination, addrlen) == EOK) &&
+	    (async_obsolete_data_read_start(ip_phone, headerlen,
 	    sizeof(*headerlen)) == EOK) && (*headerlen > 0)) {
 		*header = malloc(*headerlen);
 		if (*header) {
-			if (async_data_read_start(ip_phone, *header,
+			if (async_obsolete_data_read_start(ip_phone, *header,
 			    *headerlen) != EOK)
 				free(*header);
@@ -243,5 +243,5 @@
     in_addr_t gateway)
 {
-	return (int) async_req_2_0(ip_phone, NET_IP_SET_GATEWAY,
+	return (int) async_obsolete_req_2_0(ip_phone, NET_IP_SET_GATEWAY,
 	    (sysarg_t) device_id, (sysarg_t) gateway.s_addr);
 }
Index: uspace/lib/net/netif/netif_remote.c
===================================================================
--- uspace/lib/net/netif/netif_remote.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/net/netif/netif_remote.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -38,5 +38,5 @@
 #include <packet_client.h>
 #include <generic.h>
-
+#include <async_obsolete.h>
 #include <ipc/services.h>
 #include <ipc/netif.h>
@@ -82,5 +82,5 @@
 int netif_probe_req(int netif_phone, device_id_t device_id, int irq, void *io)
 {
-	return async_req_3_0(netif_phone, NET_NETIF_PROBE, device_id, irq,
+	return async_obsolete_req_3_0(netif_phone, NET_NETIF_PROBE, device_id, irq,
 	    (sysarg_t) io);
 }
@@ -119,5 +119,5 @@
 int netif_start_req(int netif_phone, device_id_t device_id)
 {
-	return async_req_1_0(netif_phone, NET_NETIF_START, device_id);
+	return async_obsolete_req_1_0(netif_phone, NET_NETIF_START, device_id);
 }
 
@@ -136,5 +136,5 @@
 int netif_stop_req(int netif_phone, device_id_t device_id)
 {
-	return async_req_1_0(netif_phone, NET_NETIF_STOP, device_id);
+	return async_obsolete_req_1_0(netif_phone, NET_NETIF_STOP, device_id);
 }
 
@@ -154,7 +154,7 @@
 		return EBADMEM;
 	
-	aid_t message_id = async_send_1(netif_phone, NET_NETIF_STATS,
+	aid_t message_id = async_obsolete_send_1(netif_phone, NET_NETIF_STATS,
 	    (sysarg_t) device_id, NULL);
-	async_data_read_start(netif_phone, stats, sizeof(*stats));
+	async_obsolete_data_read_start(netif_phone, stats, sizeof(*stats));
 	
 	sysarg_t result;
Index: uspace/lib/net/netif/netif_skel.c
===================================================================
--- uspace/lib/net/netif/netif_skel.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/net/netif/netif_skel.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -54,4 +54,7 @@
 #include <nil_remote.h>
 
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
+
 DEVICE_MAP_IMPLEMENT(netif_device_map, netif_device_t);
 
@@ -288,8 +291,8 @@
 	*count = 0;
 	
+	if (!IPC_GET_IMETHOD(*call))
+		return EOK;
+	
 	switch (IPC_GET_IMETHOD(*call)) {
-	case IPC_M_PHONE_HUNGUP:
-		return EOK;
-	
 	case NET_NETIF_PROBE:
 		return netif_probe_req_local(0, IPC_GET_DEVICE(*call),
@@ -385,6 +388,5 @@
 		
 		/* End if said to either by the message or the processing result */
-		if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
-		    (res == EHANGUP))
+		if ((!IPC_GET_IMETHOD(call)) || (res == EHANGUP))
 			return;
 		
Index: uspace/lib/net/nil/nil_skel.c
===================================================================
--- uspace/lib/net/nil/nil_skel.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/net/nil/nil_skel.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -42,4 +42,7 @@
 #include <net/modules.h>
 
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
+
 /** Default thread for new connections.
  *
@@ -75,6 +78,5 @@
 		 * result.
 		 */
-		if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
-		    (res == EHANGUP))
+		if ((!IPC_GET_IMETHOD(call)) || (res == EHANGUP))
 			return;
 		
Index: uspace/lib/net/tl/icmp_remote.c
===================================================================
--- uspace/lib/net/tl/icmp_remote.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/net/tl/icmp_remote.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -41,4 +41,5 @@
 
 #include <async.h>
+#include <async_obsolete.h>
 #include <errno.h>
 #include <ipc/services.h>
@@ -64,5 +65,5 @@
     icmp_param_t mtu, packet_t *packet)
 {
-	async_msg_3(icmp_phone, NET_ICMP_DEST_UNREACH, (sysarg_t) code,
+	async_obsolete_msg_3(icmp_phone, NET_ICMP_DEST_UNREACH, (sysarg_t) code,
 	    (sysarg_t) packet_get_id(packet), (sysarg_t) mtu);
 	return EOK;
@@ -83,5 +84,5 @@
 int icmp_source_quench_msg(int icmp_phone, packet_t *packet)
 {
-	async_msg_2(icmp_phone, NET_ICMP_SOURCE_QUENCH, 0,
+	async_obsolete_msg_2(icmp_phone, NET_ICMP_SOURCE_QUENCH, 0,
 	    (sysarg_t) packet_get_id(packet));
 	return EOK;
@@ -103,5 +104,5 @@
 int icmp_time_exceeded_msg(int icmp_phone, icmp_code_t code, packet_t *packet)
 {
-	async_msg_2(icmp_phone, NET_ICMP_TIME_EXCEEDED, (sysarg_t) code,
+	async_obsolete_msg_2(icmp_phone, NET_ICMP_TIME_EXCEEDED, (sysarg_t) code,
 	    (sysarg_t) packet_get_id(packet));
 	return EOK;
@@ -125,5 +126,5 @@
     icmp_param_t pointer, packet_t *packet)
 {
-	async_msg_3(icmp_phone, NET_ICMP_PARAMETERPROB, (sysarg_t) code,
+	async_obsolete_msg_3(icmp_phone, NET_ICMP_PARAMETERPROB, (sysarg_t) code,
 	    (sysarg_t) packet_get_id(packet), (sysarg_t) pointer);
 	return EOK;
Index: uspace/lib/net/tl/tl_skel.c
===================================================================
--- uspace/lib/net/tl/tl_skel.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/net/tl/tl_skel.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -42,4 +42,7 @@
 #include <net/modules.h>
 
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
+
 /** Default thread for new connections.
  *
@@ -77,6 +80,5 @@
 		 * result.
 		 */
-		if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
-		    (res == EHANGUP))
+		if ((!IPC_GET_IMETHOD(call)) || (res == EHANGUP))
 			return;
 		
Index: uspace/lib/packet/generic/packet_server.c
===================================================================
--- uspace/lib/packet/generic/packet_server.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/packet/generic/packet_server.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -324,8 +324,9 @@
 
 	*answer_count = 0;
+	
+	if (!IPC_GET_IMETHOD(*call))
+		return EOK;
+	
 	switch (IPC_GET_IMETHOD(*call)) {
-	case IPC_M_PHONE_HUNGUP:
-		return EOK;
-	
 	case NET_PACKET_CREATE_1:
 		packet = packet_get_local(DEFAULT_ADDR_LEN, DEFAULT_PREFIX,
Index: uspace/lib/usb/include/usb/hc.h
===================================================================
--- uspace/lib/usb/include/usb/hc.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/usb/include/usb/hc.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -40,4 +40,5 @@
 #include <ddf/driver.h>
 #include <bool.h>
+#include <async.h>
 #include <usb/usb.h>
 
@@ -46,6 +47,6 @@
 	/** Devman handle of the host controller. */
 	devman_handle_t hc_handle;
-	/** Phone to the host controller. */
-	int hc_phone;
+	/** Session to the host controller. */
+	async_sess_t *hc_sess;
 } usb_hc_connection_t;
 
Index: uspace/lib/usb/src/ddfiface.c
===================================================================
--- uspace/lib/usb/src/ddfiface.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/usb/src/ddfiface.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -78,23 +78,24 @@
 {
 	assert(fun != NULL);
-
-	int parent_phone = devman_parent_device_connect(fun->handle,
+	
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, fun->handle,
 	    IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return parent_phone;
-	}
-
+	if (!parent_sess)
+		return ENOMEM;
+	
+	async_exch_t *exch = async_exchange_begin(parent_sess);
+	
 	sysarg_t hc_handle;
-	int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
 	    IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &hc_handle);
-
-	async_hangup(parent_phone);
-
-	if (rc != EOK) {
+	
+	async_exchange_end(exch);
+	async_hangup(parent_sess);
+	
+	if (rc != EOK)
 		return rc;
-	}
-
+	
 	*handle = hc_handle;
-
 	return EOK;
 }
@@ -128,24 +129,26 @@
 {
 	assert(fun);
-	int parent_phone = devman_parent_device_connect(fun->handle,
+	
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, fun->handle,
 	    IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return parent_phone;
-	}
-
+	if (!parent_sess)
+		return ENOMEM;
+	
+	async_exch_t *exch = async_exchange_begin(parent_sess);
+	
 	sysarg_t addr;
-	int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
 	    IPC_M_USB_GET_ADDRESS, handle, &addr);
-
-	async_hangup(parent_phone);
-
-	if (rc != EOK) {
+	
+	async_exchange_end(exch);
+	async_hangup(parent_sess);
+	
+	if (rc != EOK)
 		return rc;
-	}
-
-	if (address != NULL) {
+	
+	if (address != NULL)
 		*address = (usb_address_t) addr;
-	}
-
+	
 	return EOK;
 }
Index: uspace/lib/usb/src/hc.c
===================================================================
--- uspace/lib/usb/src/hc.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/usb/src/hc.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -81,5 +81,5 @@
 
 	connection->hc_handle = hc_handle;
-	connection->hc_phone = -1;
+	connection->hc_sess = NULL;
 
 	return EOK;
@@ -94,16 +94,14 @@
 {
 	assert(connection);
-
-	if (usb_hc_connection_is_opened(connection)) {
+	
+	if (usb_hc_connection_is_opened(connection))
 		return EBUSY;
-	}
-
-	int phone = devman_device_connect(connection->hc_handle, 0);
-	if (phone < 0) {
-		return phone;
-	}
-
-	connection->hc_phone = phone;
-
+	
+	async_sess_t *sess = devman_device_connect(EXCHANGE_SERIALIZE,
+	    connection->hc_handle, 0);
+	if (!sess)
+		return ENOMEM;
+	
+	connection->hc_sess = sess;
 	return EOK;
 }
@@ -117,6 +115,5 @@
 {
 	assert(connection);
-
-	return (connection->hc_phone >= 0);
+	return (connection->hc_sess != NULL);
 }
 
@@ -134,10 +131,10 @@
 	}
 
-	int rc = async_hangup(connection->hc_phone);
+	int rc = async_hangup(connection->hc_sess);
 	if (rc != EOK) {
 		return rc;
 	}
 
-	connection->hc_phone = -1;
+	connection->hc_sess = NULL;
 
 	return EOK;
@@ -154,17 +151,19 @@
     usb_address_t address, devman_handle_t *handle)
 {
-	if (!usb_hc_connection_is_opened(connection)) {
+	if (!usb_hc_connection_is_opened(connection))
 		return ENOENT;
-	}
-
+	
+	async_exch_t *exch = async_exchange_begin(connection->hc_sess);
+	
 	sysarg_t tmp;
-	int rc = async_req_2_1(connection->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE),
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
 	    IPC_M_USBHC_GET_HANDLE_BY_ADDRESS,
 	    address, &tmp);
-	if ((rc == EOK) && (handle != NULL)) {
+	
+	async_exchange_end(exch);
+	
+	if ((rc == EOK) && (handle != NULL))
 		*handle = tmp;
-	}
-
+	
 	return rc;
 }
@@ -177,22 +176,23 @@
 usb_address_t usb_hc_get_address_by_handle(devman_handle_t dev_handle)
 {
-	int parent_phone = devman_parent_device_connect(dev_handle,
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev_handle,
 	    IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return parent_phone;
-	}
-
+	if (!parent_sess)
+		return ENOMEM;
+	
+	async_exch_t *exch = async_exchange_begin(parent_sess);
+	
 	sysarg_t address;
-
-	int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
 	    IPC_M_USB_GET_ADDRESS,
 	    dev_handle, &address);
-
-	if (rc != EOK) {
-		return rc;
-	}
-
-	async_hangup(parent_phone);
-
+	
+	async_exchange_end(exch);
+	async_hangup(parent_sess);
+	
+	if (rc != EOK)
+		return rc;
+	
 	return (usb_address_t) address;
 }
@@ -240,24 +240,25 @@
 int usb_hc_find(devman_handle_t device_handle, devman_handle_t *hc_handle)
 {
-	int parent_phone = devman_parent_device_connect(device_handle,
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device_handle,
 	    IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return parent_phone;
-	}
-
+	if (!parent_sess)
+		return ENOMEM;
+	
+	async_exch_t *exch = async_exchange_begin(parent_sess);
+	
 	devman_handle_t h;
-	int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
 	    IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &h);
-
-	async_hangup(parent_phone);
-
-	if (rc != EOK) {
-		return rc;
-	}
-
-	if (hc_handle != NULL) {
+	
+	async_exchange_end(exch);
+	async_hangup(parent_sess);
+	
+	if (rc != EOK)
+		return rc;
+	
+	if (hc_handle != NULL)
 		*hc_handle = h;
-	}
-
+	
 	return EOK;
 }
Index: uspace/lib/usbdev/include/usb/dev/pipes.h
===================================================================
--- uspace/lib/usbdev/include/usb/dev/pipes.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/usbdev/include/usb/dev/pipes.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -43,4 +43,5 @@
 #include <ddf/driver.h>
 #include <fibril_synch.h>
+#include <async.h>
 
 /** Abstraction of a physical connection to the device.
@@ -62,6 +63,6 @@
  *
  * Locking order: if you want to lock both mutexes
- * (@c guard and @c hc_phone_mutex), lock @c guard first.
- * It is not necessary to lock @c guard if you want to lock @c hc_phone_mutex
+ * (@c guard and @c hc_sess_mutex), lock @c guard first.
+ * It is not necessary to lock @c guard if you want to lock @c hc_sess_mutex
  * only.
  */
@@ -85,15 +86,15 @@
 	size_t max_packet_size;
 
-	/** Phone to the host controller.
-	 * Negative when no session is active.
-	 * It is an error to access this member without @c hc_phone_mutex
+	/** Session to the host controller.
+	 * NULL when no session is active.
+	 * It is an error to access this member without @c hc_sess_mutex
 	 * being locked.
 	 * If call over the phone is to be made, it must be preceeded by
 	 * call to pipe_add_ref() [internal libusb function].
 	 */
-	int hc_phone;
+	async_sess_t *hc_sess;
 
-	/** Guard for serialization of requests over the phone. */
-	fibril_mutex_t hc_phone_mutex;
+	/** Guard for serialization of requests over the session. */
+	fibril_mutex_t hc_sess_mutex;
 
 	/** Number of active transfers over the pipe. */
Index: uspace/lib/usbdev/src/hub.c
===================================================================
--- uspace/lib/usbdev/src/hub.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/usbdev/src/hub.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -42,4 +42,5 @@
 #include <usb/debug.h>
 #include <time.h>
+#include <async.h>
 
 /** How much time to wait between attempts to register endpoint 0:0.
@@ -71,15 +72,18 @@
 {
 	CHECK_CONNECTION(connection);
-
+	
+	async_exch_t *exch = async_exchange_begin(connection->hc_sess);
+	
 	sysarg_t address;
-	int rc = async_req_2_1(connection->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE),
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
 	    IPC_M_USBHC_REQUEST_ADDRESS, speed,
 	    &address);
-	if (rc != EOK) {
+	
+	async_exchange_end(exch);
+	
+	if (rc != EOK)
 		return (usb_address_t) rc;
-	} else {
-		return (usb_address_t) address;
-	}
+	
+	return (usb_address_t) address;
 }
 
@@ -94,12 +98,15 @@
 {
 	CHECK_CONNECTION(connection);
-	if (attached_device == NULL) {
+	
+	if (attached_device == NULL)
 		return EBADMEM;
-	}
-
-	return async_req_3_0(connection->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE),
+	
+	async_exch_t *exch = async_exchange_begin(connection->hc_sess);
+	int rc = async_req_3_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
 	    IPC_M_USBHC_BIND_ADDRESS,
 	    attached_device->address, attached_device->handle);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
@@ -114,8 +121,11 @@
 {
 	CHECK_CONNECTION(connection);
-
-	return async_req_2_0(connection->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE),
+	
+	async_exch_t *exch = async_exchange_begin(connection->hc_sess);
+	int rc = async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
 	    IPC_M_USBHC_RELEASE_ADDRESS, address);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
@@ -192,5 +202,5 @@
 	usb_hc_connection_t hc_conn = {
 		.hc_handle = connection->hc_handle,
-		.hc_phone = -1
+		.hc_sess = NULL
 	};
 
Index: uspace/lib/usbdev/src/pipepriv.c
===================================================================
--- uspace/lib/usbdev/src/pipepriv.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/usbdev/src/pipepriv.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -44,5 +44,5 @@
 void pipe_start_transaction(usb_pipe_t *pipe)
 {
-	fibril_mutex_lock(&pipe->hc_phone_mutex);
+	fibril_mutex_lock(&pipe->hc_sess_mutex);
 }
 
@@ -53,5 +53,5 @@
 void pipe_end_transaction(usb_pipe_t *pipe)
 {
-	fibril_mutex_unlock(&pipe->hc_phone_mutex);
+	fibril_mutex_unlock(&pipe->hc_sess_mutex);
 }
 
@@ -85,26 +85,31 @@
 {
 	pipe_acquire(pipe);
-
+	
 	if (pipe->refcount == 0) {
 		/* Need to open the phone by ourselves. */
-		int phone = devman_device_connect(pipe->wire->hc_handle, 0);
-		if (phone < 0) {
+		async_sess_t *sess =
+		    devman_device_connect(EXCHANGE_SERIALIZE, pipe->wire->hc_handle, 0);
+		if (!sess) {
 			if (hide_failure) {
 				pipe->refcount_soft++;
-				phone = EOK;
+				pipe_release(pipe);
+				return EOK;
 			}
+			
 			pipe_release(pipe);
-			return phone;
+			return ENOMEM;
 		}
+		
 		/*
 		 * No locking is needed, refcount is zero and whole pipe
 		 * mutex is locked.
 		 */
-		pipe->hc_phone = phone;
+		
+		pipe->hc_sess = sess;
 	}
+	
 	pipe->refcount++;
-
 	pipe_release(pipe);
-
+	
 	return EOK;
 }
@@ -117,4 +122,5 @@
 {
 	pipe_acquire(pipe);
+	
 	if (pipe->refcount_soft > 0) {
 		pipe->refcount_soft--;
@@ -122,11 +128,15 @@
 		return;
 	}
+	
 	assert(pipe->refcount > 0);
+	
 	pipe->refcount--;
+	
 	if (pipe->refcount == 0) {
 		/* We were the last users, let's hang-up. */
-		async_hangup(pipe->hc_phone);
-		pipe->hc_phone = -1;
+		async_hangup(pipe->hc_sess);
+		pipe->hc_sess = NULL;
 	}
+	
 	pipe_release(pipe);
 }
Index: uspace/lib/usbdev/src/pipes.c
===================================================================
--- uspace/lib/usbdev/src/pipes.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/usbdev/src/pipes.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -48,12 +48,12 @@
 /** Tell USB address assigned to given device.
  *
- * @param phone Phone to parent device.
+ * @param sess Session to parent device.
  * @param dev Device in question.
  * @return USB address or error code.
  */
-static usb_address_t get_my_address(int phone, ddf_dev_t *dev)
-{
-	sysarg_t address;
-
+static usb_address_t get_my_address(async_sess_t *sess, ddf_dev_t *dev)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	
 	/*
 	 * We are sending special value as a handle - zero - to get
@@ -61,12 +61,13 @@
 	 * when registering our device @p dev.
 	 */
-	int rc = async_req_2_1(phone, DEV_IFACE_ID(USB_DEV_IFACE),
-	    IPC_M_USB_GET_ADDRESS,
-	    0, &address);
-
-	if (rc != EOK) {
+	sysarg_t address;
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
+	    IPC_M_USB_GET_ADDRESS, 0, &address);
+	
+	async_exchange_end(exch);
+	
+	if (rc != EOK)
 		return rc;
-	}
-
+	
 	return (usb_address_t) address;
 }
@@ -79,21 +80,22 @@
 int usb_device_get_assigned_interface(ddf_dev_t *device)
 {
-	int parent_phone = devman_parent_device_connect(device->handle,
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
 	    IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
+	if (!parent_sess)
 		return -1;
-	}
-
+	
+	async_exch_t *exch = async_exchange_begin(parent_sess);
+	
 	sysarg_t iface_no;
-	int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
-	    IPC_M_USB_GET_INTERFACE,
-	    device->handle, &iface_no);
-
-	async_hangup(parent_phone);
-
-	if (rc != EOK) {
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
+	    IPC_M_USB_GET_INTERFACE, device->handle, &iface_no);
+	
+	async_exchange_end(exch);
+	async_hangup(parent_sess);
+	
+	if (rc != EOK)
 		return -1;
-	}
-
+	
 	return (int) iface_no;
 }
@@ -110,20 +112,19 @@
 	assert(connection);
 	assert(dev);
-
+	
 	int rc;
 	devman_handle_t hc_handle;
 	usb_address_t my_address;
-
+	
 	rc = usb_hc_find(dev->handle, &hc_handle);
-	if (rc != EOK) {
+	if (rc != EOK)
 		return rc;
-	}
-
-	int parent_phone = devman_parent_device_connect(dev->handle,
+	
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
 	    IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return parent_phone;
-	}
-
+	if (!parent_sess)
+		return ENOMEM;
+	
 	/*
 	 * Asking for "my" address may require several attempts.
@@ -137,7 +138,8 @@
 	 *  So, we need to wait for the HC to learn the binding.
 	 */
+	
 	do {
-		my_address = get_my_address(parent_phone, dev);
-
+		my_address = get_my_address(parent_sess, dev);
+		
 		if (my_address == ENOENT) {
 			/* Be nice, let other fibrils run and try again. */
@@ -148,12 +150,12 @@
 			goto leave;
 		}
-
+	
 	} while (my_address < 0);
-
+	
 	rc = usb_device_connection_initialize(connection,
 	    hc_handle, my_address);
-
+	
 leave:
-	async_hangup(parent_phone);
+	async_hangup(parent_sess);
 	return rc;
 }
Index: uspace/lib/usbdev/src/pipesinit.c
===================================================================
--- uspace/lib/usbdev/src/pipesinit.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/usbdev/src/pipesinit.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -358,6 +358,6 @@
 	fibril_mutex_initialize(&pipe->guard);
 	pipe->wire = connection;
-	pipe->hc_phone = -1;
-	fibril_mutex_initialize(&pipe->hc_phone_mutex);
+	pipe->hc_sess = NULL;
+	fibril_mutex_initialize(&pipe->hc_sess_mutex);
 	pipe->endpoint_no = endpoint_no;
 	pipe->transfer_type = transfer_type;
@@ -482,20 +482,23 @@
 	assert(pipe);
 	assert(hc_connection);
-
-	if (!usb_hc_connection_is_opened(hc_connection)) {
+	
+	if (!usb_hc_connection_is_opened(hc_connection))
 		return EBADF;
-	}
-
+	
 #define _PACK2(high, low) (((high) << 16) + (low))
 #define _PACK3(high, middle, low) (((((high) << 8) + (middle)) << 8) + (low))
-
-	return async_req_4_0(hc_connection->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_REGISTER_ENDPOINT,
+	
+	async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess);
+	int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USBHC_REGISTER_ENDPOINT,
 	    _PACK2(pipe->wire->address, pipe->endpoint_no),
 	    _PACK3(speed, pipe->transfer_type, pipe->direction),
 	    _PACK2(pipe->max_packet_size, interval));
-
+	async_exchange_end(exch);
+	
 #undef _PACK2
 #undef _PACK3
+	
+	return rc;
 }
 
@@ -511,12 +514,15 @@
 	assert(pipe);
 	assert(hc_connection);
-
-	if (!usb_hc_connection_is_opened(hc_connection)) {
+	
+	if (!usb_hc_connection_is_opened(hc_connection))
 		return EBADF;
-	}
-
-	return async_req_4_0(hc_connection->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_UNREGISTER_ENDPOINT,
+	
+	async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess);
+	int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USBHC_UNREGISTER_ENDPOINT,
 	    pipe->wire->address, pipe->endpoint_no, pipe->direction);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
Index: uspace/lib/usbdev/src/pipesio.c
===================================================================
--- uspace/lib/usbdev/src/pipesio.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/usbdev/src/pipesio.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -44,4 +44,5 @@
  * obviously).
  */
+
 #include <usb/usb.h>
 #include <usb/dev/pipes.h>
@@ -50,4 +51,5 @@
 #include <usbhc_iface.h>
 #include <usb/dev/request.h>
+#include <async.h>
 #include "pipepriv.h"
 
@@ -79,33 +81,35 @@
 			return ENOTSUP;
 	}
-
+	
 	/* Ensure serialization over the phone. */
 	pipe_start_transaction(pipe);
-
+	async_exch_t *exch = async_exchange_begin(pipe->hc_sess);
+	
 	/*
 	 * Make call identifying target USB device and type of transfer.
 	 */
-	aid_t opening_request = async_send_3(pipe->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
-	    pipe->wire->address, pipe->endpoint_no,
-	    NULL);
+	aid_t opening_request = async_send_3(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    ipc_method, pipe->wire->address, pipe->endpoint_no, NULL);
+	
 	if (opening_request == 0) {
+		async_exchange_end(exch);
 		pipe_end_transaction(pipe);
 		return ENOMEM;
 	}
-
+	
 	/*
 	 * Retrieve the data.
 	 */
 	ipc_call_t data_request_call;
-	aid_t data_request = async_data_read(pipe->hc_phone, buffer, size,
+	aid_t data_request = async_data_read(exch, buffer, size,
 	    &data_request_call);
-
+	
 	/*
 	 * Since now on, someone else might access the backing phone
 	 * without breaking the transfer IPC protocol.
 	 */
+	async_exchange_end(exch);
 	pipe_end_transaction(pipe);
-
+	
 	if (data_request == 0) {
 		/*
@@ -116,5 +120,5 @@
 		return ENOMEM;
 	}
-
+	
 	/*
 	 * Wait for the answer.
@@ -124,5 +128,5 @@
 	async_wait_for(data_request, &data_request_rc);
 	async_wait_for(opening_request, &opening_request_rc);
-
+	
 	if (data_request_rc != EOK) {
 		/* Prefer the return code of the opening request. */
@@ -136,7 +140,7 @@
 		return (int) opening_request_rc;
 	}
-
+	
 	*size_transfered = IPC_GET_ARG2(data_request_call);
-
+	
 	return EOK;
 }
@@ -228,33 +232,35 @@
 	/* Ensure serialization over the phone. */
 	pipe_start_transaction(pipe);
-
+	async_exch_t *exch = async_exchange_begin(pipe->hc_sess);
+	
 	/*
 	 * Make call identifying target USB device and type of transfer.
 	 */
-	aid_t opening_request = async_send_3(pipe->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
-	    pipe->wire->address, pipe->endpoint_no,
-	    NULL);
+	aid_t opening_request = async_send_3(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    ipc_method, pipe->wire->address, pipe->endpoint_no, NULL);
+	
 	if (opening_request == 0) {
+		async_exchange_end(exch);
 		pipe_end_transaction(pipe);
 		return ENOMEM;
 	}
-
+	
 	/*
 	 * Send the data.
 	 */
-	int rc = async_data_write_start(pipe->hc_phone, buffer, size);
-
+	int rc = async_data_write_start(exch, buffer, size);
+	
 	/*
 	 * Since now on, someone else might access the backing phone
 	 * without breaking the transfer IPC protocol.
 	 */
+	async_exchange_end(exch);
 	pipe_end_transaction(pipe);
-
+	
 	if (rc != EOK) {
 		async_wait_for(opening_request, NULL);
 		return rc;
 	}
-
+	
 	/*
 	 * Wait for the answer.
@@ -262,5 +268,5 @@
 	sysarg_t opening_request_rc;
 	async_wait_for(opening_request, &opening_request_rc);
-
+	
 	return (int) opening_request_rc;
 }
@@ -349,38 +355,39 @@
 	 * Make call identifying target USB device and control transfer type.
 	 */
-	aid_t opening_request = async_send_3(pipe->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_READ,
-	    pipe->wire->address, pipe->endpoint_no,
+	async_exch_t *exch = async_exchange_begin(pipe->hc_sess);
+	aid_t opening_request = async_send_3(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USBHC_CONTROL_READ, pipe->wire->address, pipe->endpoint_no,
 	    NULL);
+	
 	if (opening_request == 0) {
+		async_exchange_end(exch);
 		return ENOMEM;
 	}
-
+	
 	/*
 	 * Send the setup packet.
 	 */
-	int rc = async_data_write_start(pipe->hc_phone,
-	    setup_buffer, setup_buffer_size);
-	if (rc != EOK) {
+	int rc = async_data_write_start(exch, setup_buffer, setup_buffer_size);
+	if (rc != EOK) {
+		async_exchange_end(exch);
 		pipe_end_transaction(pipe);
 		async_wait_for(opening_request, NULL);
 		return rc;
 	}
-
+	
 	/*
 	 * Retrieve the data.
 	 */
 	ipc_call_t data_request_call;
-	aid_t data_request = async_data_read(pipe->hc_phone,
-	    data_buffer, data_buffer_size,
-	    &data_request_call);
-
+	aid_t data_request = async_data_read(exch, data_buffer,
+	    data_buffer_size, &data_request_call);
+	
 	/*
 	 * Since now on, someone else might access the backing phone
 	 * without breaking the transfer IPC protocol.
 	 */
+	async_exchange_end(exch);
 	pipe_end_transaction(pipe);
-
-
+	
 	if (data_request == 0) {
 		async_wait_for(opening_request, NULL);
@@ -494,35 +501,36 @@
 	 * Make call identifying target USB device and control transfer type.
 	 */
-	aid_t opening_request = async_send_4(pipe->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_WRITE,
-	    pipe->wire->address, pipe->endpoint_no,
-	    data_buffer_size,
-	    NULL);
+	async_exch_t *exch = async_exchange_begin(pipe->hc_sess);
+	aid_t opening_request = async_send_4(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USBHC_CONTROL_WRITE, pipe->wire->address, pipe->endpoint_no,
+	    data_buffer_size, NULL);
+	
 	if (opening_request == 0) {
+		async_exchange_end(exch);
 		pipe_end_transaction(pipe);
 		return ENOMEM;
 	}
-
+	
 	/*
 	 * Send the setup packet.
 	 */
-	int rc = async_data_write_start(pipe->hc_phone,
-	    setup_buffer, setup_buffer_size);
-	if (rc != EOK) {
+	int rc = async_data_write_start(exch, setup_buffer, setup_buffer_size);
+	if (rc != EOK) {
+		async_exchange_end(exch);
 		pipe_end_transaction(pipe);
 		async_wait_for(opening_request, NULL);
 		return rc;
 	}
-
+	
 	/*
 	 * Send the data (if any).
 	 */
 	if (data_buffer_size > 0) {
-		rc = async_data_write_start(pipe->hc_phone,
-		    data_buffer, data_buffer_size);
-
+		rc = async_data_write_start(exch, data_buffer, data_buffer_size);
+		
 		/* All data sent, pipe can be released. */
+		async_exchange_end(exch);
 		pipe_end_transaction(pipe);
-
+	
 		if (rc != EOK) {
 			async_wait_for(opening_request, NULL);
@@ -531,7 +539,8 @@
 	} else {
 		/* No data to send, we can release the pipe for others. */
+		async_exchange_end(exch);
 		pipe_end_transaction(pipe);
 	}
-
+	
 	/*
 	 * Wait for the answer.
Index: uspace/lib/usbhid/include/usb/hid/iface.h
===================================================================
--- uspace/lib/usbhid/include/usb/hid/iface.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/usbhid/include/usb/hid/iface.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -37,10 +37,12 @@
 
 #include <sys/types.h>
+#include <async.h>
 
-int usbhid_dev_get_event_length(int, size_t *);
-int usbhid_dev_get_event(int, uint8_t *, size_t, size_t *, int *,
-    unsigned int);
-int usbhid_dev_get_report_descriptor_length(int, size_t *);
-int usbhid_dev_get_report_descriptor(int, uint8_t *, size_t, size_t *);
+extern int usbhid_dev_get_event_length(async_sess_t *, size_t *);
+extern int usbhid_dev_get_event(async_sess_t *, uint8_t *, size_t, size_t *,
+    int *, unsigned int);
+extern int usbhid_dev_get_report_descriptor_length(async_sess_t *, size_t *);
+extern int usbhid_dev_get_report_descriptor(async_sess_t *, uint8_t *, size_t,
+    size_t *);
 
 #endif
Index: uspace/lib/usbhid/src/hidiface.c
===================================================================
--- uspace/lib/usbhid/src/hidiface.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/usbhid/src/hidiface.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -43,20 +43,25 @@
 /** Ask for event array length.
  *
- * @param dev_phone Opened phone to DDF device providing USB HID interface.
+ * @param dev_sess Session to DDF device providing USB HID interface.
+ *
  * @return Number of usages returned or negative error code.
- */
-int usbhid_dev_get_event_length(int dev_phone, size_t *size)
-{
-	if (dev_phone < 0) {
-		return EINVAL;
-	}
-
+ *
+ */
+int usbhid_dev_get_event_length(async_sess_t *dev_sess, size_t *size)
+{
+	if (!dev_sess)
+		return EINVAL;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
 	sysarg_t len;
-	int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(USBHID_DEV_IFACE),
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(USBHID_DEV_IFACE),
 	    IPC_M_USBHID_GET_EVENT_LENGTH, &len);
+	
+	async_exchange_end(exch);
+	
 	if (rc == EOK) {
-		if (size != NULL) {
+		if (size != NULL)
 			*size = (size_t) len;
-		}
 	}
 	
@@ -66,49 +71,52 @@
 /** Request for next event from HID device.
  *
- * @param[in] dev_phone Opened phone to DDF device providing USB HID interface.
+ * @param[in]  dev_sess    Session to DDF device providing USB HID interface.
  * @param[out] usage_pages Where to store usage pages.
- * @param[out] usages Where to store usages (actual data).
- * @param[in] usage_count Length of @p usage_pages and @p usages buffer
- *	(in items, not bytes).
+ * @param[out] usages      Where to store usages (actual data).
+ * @param[in]  usage_count Length of @p usage_pages and @p usages buffer
+ *                         (in items, not bytes).
  * @param[out] actual_usage_count Number of usages actually returned by the
- *	device driver.
- * @param[in] flags Flags (see USBHID_IFACE_FLAG_*).
+ *                                device driver.
+ * @param[in] flags        Flags (see USBHID_IFACE_FLAG_*).
+ *
  * @return Error code.
- */
-int usbhid_dev_get_event(int dev_phone, uint8_t *buf, 
+ *
+ */
+int usbhid_dev_get_event(async_sess_t *dev_sess, uint8_t *buf,
     size_t size, size_t *actual_size, int *event_nr, unsigned int flags)
 {
-	if (dev_phone < 0) {
-		return EINVAL;
-	}
-	if ((buf == NULL)) {
-		return ENOMEM;
-	}
-	if (size == 0) {
-		return EINVAL;
-	}
-	
-//	if (size == 0) {
-//		return EOK;
-//	}
-
+	if (!dev_sess)
+		return EINVAL;
+	
+	if ((buf == NULL))
+		return ENOMEM;
+	
+	if (size == 0)
+		return EINVAL;
+	
 	size_t buffer_size =  size;
 	uint8_t *buffer = malloc(buffer_size);
-	if (buffer == NULL) {
-		return ENOMEM;
-	}
-
+	if (buffer == NULL)
+		return ENOMEM;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
 	ipc_call_t opening_request_call;
-	aid_t opening_request = async_send_2(dev_phone,
+	aid_t opening_request = async_send_2(exch,
 	    DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_EVENT,
 	    flags, &opening_request_call);
+	
 	if (opening_request == 0) {
+		async_exchange_end(exch);
 		free(buffer);
 		return ENOMEM;
 	}
-
+	
 	ipc_call_t data_request_call;
-	aid_t data_request = async_data_read(dev_phone, buffer, buffer_size,
+	aid_t data_request = async_data_read(exch, buffer, buffer_size,
 	    &data_request_call);
+	
+	async_exchange_end(exch);
+	
 	if (data_request == 0) {
 		async_wait_for(opening_request, NULL);
@@ -116,110 +124,111 @@
 		return ENOMEM;
 	}
-
+	
 	sysarg_t data_request_rc;
 	sysarg_t opening_request_rc;
 	async_wait_for(data_request, &data_request_rc);
 	async_wait_for(opening_request, &opening_request_rc);
-
+	
 	if (data_request_rc != EOK) {
 		/* Prefer return code of the opening request. */
-		if (opening_request_rc != EOK) {
+		if (opening_request_rc != EOK)
 			return (int) opening_request_rc;
-		} else {
+		else
 			return (int) data_request_rc;
-		}
-	}
-
-	if (opening_request_rc != EOK) {
+	}
+	
+	if (opening_request_rc != EOK)
 		return (int) opening_request_rc;
-	}
-
+	
 	size_t act_size = IPC_GET_ARG2(data_request_call);
-
+	
 	/* Copy the individual items. */
 	memcpy(buf, buffer, act_size);
-//	memcpy(usages, buffer + items, items * sizeof(int32_t));
-
-	if (actual_size != NULL) {
+	
+	if (actual_size != NULL)
 		*actual_size = act_size;
-	}
-	
-	if (event_nr != NULL) {
+	
+	if (event_nr != NULL)
 		*event_nr = IPC_GET_ARG1(opening_request_call);
-	}
-
+	
 	return EOK;
 }
 
-
-int usbhid_dev_get_report_descriptor_length(int dev_phone, size_t *size)
-{
-	if (dev_phone < 0) {
-		return EINVAL;
-	}
-
+int usbhid_dev_get_report_descriptor_length(async_sess_t *dev_sess,
+    size_t *size)
+{
+	if (!dev_sess)
+		return EINVAL;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
 	sysarg_t arg_size;
-	int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(USBHID_DEV_IFACE),
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(USBHID_DEV_IFACE),
 	    IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH, &arg_size);
+	
+	async_exchange_end(exch);
+	
 	if (rc == EOK) {
-		if (size != NULL) {
+		if (size != NULL)
 			*size = (size_t) arg_size;
-		}
-	}
+	}
+	
 	return rc;
 }
 
-int usbhid_dev_get_report_descriptor(int dev_phone, uint8_t *buf, size_t size, 
-    size_t *actual_size)
-{
-	if (dev_phone < 0) {
-		return EINVAL;
-	}
-	if ((buf == NULL)) {
-		return ENOMEM;
-	}
-	if (size == 0) {
-		return EINVAL;
-	}
-
-	aid_t opening_request = async_send_1(dev_phone,
+int usbhid_dev_get_report_descriptor(async_sess_t *dev_sess, uint8_t *buf,
+    size_t size, size_t *actual_size)
+{
+	if (!dev_sess)
+		return EINVAL;
+	
+	if ((buf == NULL))
+		return ENOMEM;
+	
+	if (size == 0)
+		return EINVAL;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	aid_t opening_request = async_send_1(exch,
 	    DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_REPORT_DESCRIPTOR,
 	    NULL);
 	if (opening_request == 0) {
-		return ENOMEM;
-	}
-
+		async_exchange_end(exch);
+		return ENOMEM;
+	}
+	
 	ipc_call_t data_request_call;
-	aid_t data_request = async_data_read(dev_phone, buf, size,
+	aid_t data_request = async_data_read(exch, buf, size,
 	    &data_request_call);
+	
+	async_exchange_end(exch);
+	
 	if (data_request == 0) {
 		async_wait_for(opening_request, NULL);
 		return ENOMEM;
 	}
-
+	
 	sysarg_t data_request_rc;
 	sysarg_t opening_request_rc;
 	async_wait_for(data_request, &data_request_rc);
 	async_wait_for(opening_request, &opening_request_rc);
-
+	
 	if (data_request_rc != EOK) {
 		/* Prefer return code of the opening request. */
-		if (opening_request_rc != EOK) {
+		if (opening_request_rc != EOK)
 			return (int) opening_request_rc;
-		} else {
+		else
 			return (int) data_request_rc;
-		}
-	}
-
-	if (opening_request_rc != EOK) {
+	}
+	
+	if (opening_request_rc != EOK)
 		return (int) opening_request_rc;
-	}
-
+	
 	size_t act_size = IPC_GET_ARG2(data_request_call);
-
-	if (actual_size != NULL) {
+	
+	if (actual_size != NULL)
 		*actual_size = act_size;
-	}
-
+	
 	return EOK;
 }
Index: uspace/lib/usbvirt/include/usbvirt/device.h
===================================================================
--- uspace/lib/usbvirt/include/usbvirt/device.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/usbvirt/include/usbvirt/device.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -33,4 +33,5 @@
  * Virtual USB device.
  */
+
 #ifndef LIBUSBVIRT_DEVICE_H_
 #define LIBUSBVIRT_DEVICE_H_
@@ -38,4 +39,5 @@
 #include <usb/usb.h>
 #include <usb/dev/request.h>
+#include <async.h>
 
 /** Maximum number of endpoints supported by virtual USB. */
@@ -194,8 +196,8 @@
 	 */
 	usbvirt_device_state_t state;
-	/** Phone to the host controller.
+	/** Session to the host controller.
 	 * You shall treat this field as read only in your code.
 	 */
-	int vhc_phone;
+	async_sess_t *vhc_sess;
 };
 
@@ -213,6 +215,6 @@
     void *, size_t, size_t *);
 
-
 #endif
+
 /**
  * @}
Index: uspace/lib/usbvirt/include/usbvirt/ipc.h
===================================================================
--- uspace/lib/usbvirt/include/usbvirt/ipc.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/usbvirt/include/usbvirt/ipc.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -33,4 +33,5 @@
  * IPC wrappers for virtual USB.
  */
+
 #ifndef LIBUSBVIRT_IPC_H_
 #define LIBUSBVIRT_IPC_H_
@@ -40,4 +41,5 @@
 #include <bool.h>
 #include <usbvirt/device.h>
+#include <async.h>
 
 /** IPC methods communication between host controller and virtual device. */
@@ -52,17 +54,19 @@
 } usbvirt_hc_to_device_method_t;
 
-int usbvirt_ipc_send_control_read(int, void *, size_t,
+extern int usbvirt_ipc_send_control_read(async_sess_t *, void *, size_t,
     void *, size_t, size_t *);
-int usbvirt_ipc_send_control_write(int, void *, size_t,
+extern int usbvirt_ipc_send_control_write(async_sess_t *, void *, size_t,
     void *, size_t);
-int usbvirt_ipc_send_data_in(int, usb_endpoint_t, usb_transfer_type_t,
-    void *, size_t, size_t *);
-int usbvirt_ipc_send_data_out(int, usb_endpoint_t, usb_transfer_type_t,
-    void *, size_t);
+extern int usbvirt_ipc_send_data_in(async_sess_t *, usb_endpoint_t,
+    usb_transfer_type_t, void *, size_t, size_t *);
+extern int usbvirt_ipc_send_data_out(async_sess_t *, usb_endpoint_t,
+    usb_transfer_type_t, void *, size_t);
 
-bool usbvirt_is_usbvirt_method(sysarg_t);
-bool usbvirt_ipc_handle_call(usbvirt_device_t *, ipc_callid_t, ipc_call_t *);
+extern bool usbvirt_is_usbvirt_method(sysarg_t);
+extern bool usbvirt_ipc_handle_call(usbvirt_device_t *, ipc_callid_t,
+    ipc_call_t *);
 
 #endif
+
 /**
  * @}
Index: uspace/lib/usbvirt/src/device.c
===================================================================
--- uspace/lib/usbvirt/src/device.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/usbvirt/src/device.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -65,12 +65,9 @@
 		bool processed = usbvirt_ipc_handle_call(DEV, callid, &call);
 		if (!processed) {
-			switch (IPC_GET_IMETHOD(call)) {
-				case IPC_M_PHONE_HUNGUP:
-					async_answer_0(callid, EOK);
-					return;
-				default:
-					async_answer_0(callid, EINVAL);
-					break;
-			}
+			if (!IPC_GET_IMETHOD(call)) {
+				async_answer_0(callid, EOK);
+				return;
+			} else
+				async_answer_0(callid, EINVAL);
 		}
 	}
@@ -85,30 +82,27 @@
 int usbvirt_device_plug(usbvirt_device_t *dev, const char *vhc_path)
 {
-	int rc;
+	if (DEV != NULL)
+		return ELIMIT;
+	
 	devman_handle_t handle;
-
-	if (DEV != NULL) {
-		return ELIMIT;
-	}
-
-	rc = devman_device_get_handle(vhc_path, &handle, 0);
-	if (rc != EOK) {
+	int rc = devman_device_get_handle(vhc_path, &handle, 0);
+	if (rc != EOK)
 		return rc;
-	}
-
-	int hcd_phone = devman_device_connect(handle, 0);
-
-	if (hcd_phone < 0) {
-		return hcd_phone;
-	}
-
+	
+	async_sess_t *hcd_sess =
+	    devman_device_connect(EXCHANGE_SERIALIZE, handle, 0);
+	if (!hcd_sess)
+		return ENOMEM;
+	
 	DEV = dev;
-	dev->vhc_phone = hcd_phone;
-
-	rc = async_connect_to_me(hcd_phone, 0, 0, 0, callback_connection);
-	if (rc != EOK) {
+	dev->vhc_sess = hcd_sess;
+	
+	async_exch_t *exch = async_exchange_begin(hcd_sess);
+	rc = async_connect_to_me(exch, 0, 0, 0, callback_connection);
+	async_exchange_end(exch);
+	
+	if (rc != EOK)
 		DEV = NULL;
-	}
-
+	
 	return rc;
 }
@@ -120,5 +114,5 @@
 void usbvirt_device_unplug(usbvirt_device_t *dev)
 {
-	async_hangup(dev->vhc_phone);
+	async_hangup(dev->vhc_sess);
 }
 
Index: uspace/lib/usbvirt/src/ipc_hc.c
===================================================================
--- uspace/lib/usbvirt/src/ipc_hc.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/lib/usbvirt/src/ipc_hc.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -45,5 +45,5 @@
 /** Send control read transfer to virtual USB device.
  *
- * @param phone IPC phone to the virtual device.
+ * @param sess Session to the virtual device.
  * @param ep Target endpoint number.
  * @param setup_buffer Setup buffer.
@@ -52,64 +52,67 @@
  * @param data_buffer_size Size of data buffer in bytes.
  * @param data_transfered_size Number of actually transferred bytes.
+ *
  * @return Error code.
- */
-int usbvirt_ipc_send_control_read(int phone,
-    void *setup_buffer, size_t setup_buffer_size,
-    void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size)
+ *
+ */
+int usbvirt_ipc_send_control_read(async_sess_t *sess, void *setup_buffer,
+    size_t setup_buffer_size, void *data_buffer, size_t data_buffer_size,
+    size_t *data_transfered_size)
 {
-	if (phone < 0) {
-		return EINVAL;
-	}
-	if ((setup_buffer == NULL) || (setup_buffer_size == 0)) {
-		return EINVAL;
-	}
-	if ((data_buffer == NULL) || (data_buffer_size == 0)) {
-		return EINVAL;
-	}
-
-	aid_t opening_request = async_send_0(phone,
-	    IPC_M_USBVIRT_CONTROL_READ, NULL);
+	if (!sess)
+		return EINVAL;
+	
+	if ((setup_buffer == NULL) || (setup_buffer_size == 0))
+		return EINVAL;
+	
+	if ((data_buffer == NULL) || (data_buffer_size == 0))
+		return EINVAL;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	
+	aid_t opening_request = async_send_0(exch, IPC_M_USBVIRT_CONTROL_READ,
+	    NULL);
 	if (opening_request == 0) {
-		return ENOMEM;
-	}
-
-	int rc = async_data_write_start(phone,
-	    setup_buffer, setup_buffer_size);
+		async_exchange_end(exch);
+		return ENOMEM;
+	}
+	
+	int rc = async_data_write_start(exch, setup_buffer, setup_buffer_size);
 	if (rc != EOK) {
+		async_exchange_end(exch);
 		async_wait_for(opening_request, NULL);
 		return rc;
 	}
-
+	
 	ipc_call_t data_request_call;
-	aid_t data_request = async_data_read(phone,
-	    data_buffer, data_buffer_size,
+	aid_t data_request = async_data_read(exch, data_buffer, data_buffer_size,
 	    &data_request_call);
-
+	
+	async_exchange_end(exch);
+	
 	if (data_request == 0) {
 		async_wait_for(opening_request, NULL);
 		return ENOMEM;
 	}
-
+	
 	sysarg_t data_request_rc;
 	sysarg_t opening_request_rc;
 	async_wait_for(data_request, &data_request_rc);
 	async_wait_for(opening_request, &opening_request_rc);
-
+	
 	if (data_request_rc != EOK) {
 		/* Prefer the return code of the opening request. */
-		if (opening_request_rc != EOK) {
+		if (opening_request_rc != EOK)
 			return (int) opening_request_rc;
-		} else {
+		else
 			return (int) data_request_rc;
-		}
-	}
-	if (opening_request_rc != EOK) {
+	}
+	
+	if (opening_request_rc != EOK)
 		return (int) opening_request_rc;
-	}
-
-	if (data_transfered_size != NULL) {
+	
+	if (data_transfered_size != NULL)
 		*data_transfered_size = IPC_GET_ARG2(data_request_call);
-	}
-
+	
 	return EOK;
 }
@@ -117,5 +120,5 @@
 /** Send control write transfer to virtual USB device.
  *
- * @param phone IPC phone to the virtual device.
+ * @param sess Session to the virtual device.
  * @param ep Target endpoint number.
  * @param setup_buffer Setup buffer.
@@ -123,46 +126,50 @@
  * @param data_buffer Data buffer (DATA stage of control transfer).
  * @param data_buffer_size Size of data buffer in bytes.
+ *
  * @return Error code.
- */
-int usbvirt_ipc_send_control_write(int phone,
-    void *setup_buffer, size_t setup_buffer_size,
-    void *data_buffer, size_t data_buffer_size)
+ *
+ */
+int usbvirt_ipc_send_control_write(async_sess_t *sess, void *setup_buffer,
+    size_t setup_buffer_size, void *data_buffer, size_t data_buffer_size)
 {
-	if (phone < 0) {
-		return EINVAL;
-	}
-	if ((setup_buffer == NULL) || (setup_buffer_size == 0)) {
-		return EINVAL;
-	}
-	if ((data_buffer_size > 0) && (data_buffer == NULL)) {
-		return EINVAL;
-	}
-
-	aid_t opening_request = async_send_1(phone,
-	    IPC_M_USBVIRT_CONTROL_WRITE, data_buffer_size,  NULL);
+	if (!sess)
+		return EINVAL;
+	
+	if ((setup_buffer == NULL) || (setup_buffer_size == 0))
+		return EINVAL;
+	
+	if ((data_buffer_size > 0) && (data_buffer == NULL))
+		return EINVAL;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	
+	aid_t opening_request = async_send_1(exch, IPC_M_USBVIRT_CONTROL_WRITE,
+	    data_buffer_size, NULL);
 	if (opening_request == 0) {
-		return ENOMEM;
-	}
-
-	int rc = async_data_write_start(phone,
-	    setup_buffer, setup_buffer_size);
+		async_exchange_end(exch);
+		return ENOMEM;
+	}
+	
+	int rc = async_data_write_start(exch, setup_buffer, setup_buffer_size);
 	if (rc != EOK) {
+		async_exchange_end(exch);
 		async_wait_for(opening_request, NULL);
 		return rc;
 	}
-
+	
 	if (data_buffer_size > 0) {
-		rc = async_data_write_start(phone,
-		    data_buffer, data_buffer_size);
-
+		rc = async_data_write_start(exch, data_buffer, data_buffer_size);
 		if (rc != EOK) {
+			async_exchange_end(exch);
 			async_wait_for(opening_request, NULL);
 			return rc;
 		}
 	}
-
+	
+	async_exchange_end(exch);
+	
 	sysarg_t opening_request_rc;
 	async_wait_for(opening_request, &opening_request_rc);
-
+	
 	return (int) opening_request_rc;
 }
@@ -170,5 +177,5 @@
 /** Request data transfer from virtual USB device.
  *
- * @param phone IPC phone to the virtual device.
+ * @param sess Session to the virtual device.
  * @param ep Target endpoint number.
  * @param tr_type Transfer type (interrupt or bulk).
@@ -176,13 +183,16 @@
  * @param data_size Size of the data buffer in bytes.
  * @param act_size Number of actually returned bytes.
+ *
  * @return Error code.
- */
-int usbvirt_ipc_send_data_in(int phone, usb_endpoint_t ep,
+ *
+ */
+int usbvirt_ipc_send_data_in(async_sess_t *sess, usb_endpoint_t ep,
     usb_transfer_type_t tr_type, void *data, size_t data_size, size_t *act_size)
 {
-	if (phone < 0) {
-		return EINVAL;
-	}
+	if (!sess)
+		return EINVAL;
+	
 	usbvirt_hc_to_device_method_t method;
+	
 	switch (tr_type) {
 	case USB_TRANSFER_INTERRUPT:
@@ -195,48 +205,49 @@
 		return EINVAL;
 	}
-	if ((ep <= 0) || (ep >= USBVIRT_ENDPOINT_MAX)) {
-		return EINVAL;
-	}
-	if ((data == NULL) || (data_size == 0)) {
-		return EINVAL;
-	}
-
-
-	aid_t opening_request = async_send_2(phone, method, ep, tr_type, NULL);
+	
+	if ((ep <= 0) || (ep >= USBVIRT_ENDPOINT_MAX))
+		return EINVAL;
+	
+	if ((data == NULL) || (data_size == 0))
+		return EINVAL;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	
+	aid_t opening_request = async_send_2(exch, method, ep, tr_type, NULL);
 	if (opening_request == 0) {
-		return ENOMEM;
-	}
-
-
+		async_exchange_end(exch);
+		return ENOMEM;
+	}
+	
 	ipc_call_t data_request_call;
-	aid_t data_request = async_data_read(phone,
-	    data, data_size,  &data_request_call);
-
+	aid_t data_request = async_data_read(exch, data, data_size,
+	    &data_request_call);
+	
+	async_exchange_end(exch);
+	
 	if (data_request == 0) {
 		async_wait_for(opening_request, NULL);
 		return ENOMEM;
 	}
-
+	
 	sysarg_t data_request_rc;
 	sysarg_t opening_request_rc;
 	async_wait_for(data_request, &data_request_rc);
 	async_wait_for(opening_request, &opening_request_rc);
-
+	
 	if (data_request_rc != EOK) {
 		/* Prefer the return code of the opening request. */
-		if (opening_request_rc != EOK) {
+		if (opening_request_rc != EOK)
 			return (int) opening_request_rc;
-		} else {
+		else
 			return (int) data_request_rc;
-		}
-	}
-	if (opening_request_rc != EOK) {
+	}
+	
+	if (opening_request_rc != EOK)
 		return (int) opening_request_rc;
-	}
-
-	if (act_size != NULL) {
+	
+	if (act_size != NULL)
 		*act_size = IPC_GET_ARG2(data_request_call);
-	}
-
+	
 	return EOK;
 }
@@ -244,18 +255,21 @@
 /** Send data to virtual USB device.
  *
- * @param phone IPC phone to the virtual device.
+ * @param sess Session to the virtual device.
  * @param ep Target endpoint number.
  * @param tr_type Transfer type (interrupt or bulk).
  * @param data Data buffer.
  * @param data_size Size of the data buffer in bytes.
+ *
  * @return Error code.
- */
-int usbvirt_ipc_send_data_out(int phone, usb_endpoint_t ep,
+ *
+ */
+int usbvirt_ipc_send_data_out(async_sess_t *sess, usb_endpoint_t ep,
     usb_transfer_type_t tr_type, void *data, size_t data_size)
 {
-	if (phone < 0) {
-		return EINVAL;
-	}
+	if (!sess)
+		return EINVAL;
+	
 	usbvirt_hc_to_device_method_t method;
+	
 	switch (tr_type) {
 	case USB_TRANSFER_INTERRUPT:
@@ -268,30 +282,34 @@
 		return EINVAL;
 	}
-	if ((ep <= 0) || (ep >= USBVIRT_ENDPOINT_MAX)) {
-		return EINVAL;
-	}
-	if ((data == NULL) || (data_size == 0)) {
-		return EINVAL;
-	}
-
-	aid_t opening_request = async_send_1(phone, method, ep, NULL);
+	
+	if ((ep <= 0) || (ep >= USBVIRT_ENDPOINT_MAX))
+		return EINVAL;
+	
+	if ((data == NULL) || (data_size == 0))
+		return EINVAL;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	
+	aid_t opening_request = async_send_1(exch, method, ep, NULL);
 	if (opening_request == 0) {
-		return ENOMEM;
-	}
-
-	int rc = async_data_write_start(phone,
-	    data, data_size);
+		async_exchange_end(exch);
+		return ENOMEM;
+	}
+	
+	int rc = async_data_write_start(exch, data, data_size);
+	
+	async_exchange_end(exch);
+	
 	if (rc != EOK) {
 		async_wait_for(opening_request, NULL);
 		return rc;
 	}
-
+	
 	sysarg_t opening_request_rc;
 	async_wait_for(opening_request, &opening_request_rc);
-
+	
 	return (int) opening_request_rc;
 }
 
-
 /**
  * @}
Index: uspace/srv/bd/ata_bd/ata_bd.c
===================================================================
--- uspace/srv/bd/ata_bd/ata_bd.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/bd/ata_bd/ata_bd.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -317,12 +317,15 @@
 	(void) async_share_out_finalize(callid, fs_va);
 
-	while (1) {
+	while (true) {
 		callid = async_get_call(&call);
 		method = IPC_GET_IMETHOD(call);
-		switch (method) {
-		case IPC_M_PHONE_HUNGUP:
+		
+		if (!method) {
 			/* The other side has hung up. */
 			async_answer_0(callid, EOK);
 			return;
+		}
+		
+		switch (method) {
 		case BD_READ_BLOCKS:
 			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
Index: uspace/srv/bd/file_bd/file_bd.c
===================================================================
--- uspace/srv/bd/file_bd/file_bd.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/bd/file_bd/file_bd.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -198,12 +198,15 @@
 	(void) async_share_out_finalize(callid, fs_va);
 
-	while (1) {
+	while (true) {
 		callid = async_get_call(&call);
 		method = IPC_GET_IMETHOD(call);
-		switch (method) {
-		case IPC_M_PHONE_HUNGUP:
+		
+		if (!method) {
 			/* The other side has hung up. */
 			async_answer_0(callid, EOK);
 			return;
+		}
+		
+		switch (method) {
 		case BD_READ_BLOCKS:
 			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
Index: uspace/srv/bd/gxe_bd/gxe_bd.c
===================================================================
--- uspace/srv/bd/gxe_bd/gxe_bd.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/bd/gxe_bd/gxe_bd.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -201,12 +201,15 @@
 	(void) async_share_out_finalize(callid, fs_va);
 
-	while (1) {
+	while (true) {
 		callid = async_get_call(&call);
 		method = IPC_GET_IMETHOD(call);
-		switch (method) {
-		case IPC_M_PHONE_HUNGUP:
+		
+		if (!method) {
 			/* The other side has hung up. */
 			async_answer_0(callid, EOK);
 			return;
+		}
+		
+		switch (method) {
 		case BD_READ_BLOCKS:
 			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
Index: uspace/srv/bd/part/guid_part/guid_part.c
===================================================================
--- uspace/srv/bd/part/guid_part/guid_part.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/bd/part/guid_part/guid_part.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -139,5 +139,5 @@
 	}
 
-	rc = block_init(indev_handle, 2048);
+	rc = block_init(EXCHANGE_SERIALIZE, indev_handle, 2048);
 	if (rc != EOK)  {
 		printf(NAME ": could not init libblock.\n");
@@ -356,12 +356,15 @@
 	(void) async_share_out_finalize(callid, fs_va);
 
-	while (1) {
+	while (true) {
 		callid = async_get_call(&call);
 		method = IPC_GET_IMETHOD(call);
-		switch (method) {
-		case IPC_M_PHONE_HUNGUP:
+		
+		if (!method) {
 			/* The other side has hung up. */
 			async_answer_0(callid, EOK);
 			return;
+		}
+		
+		switch (method) {
 		case BD_READ_BLOCKS:
 			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
Index: uspace/srv/bd/part/mbr_part/mbr_part.c
===================================================================
--- uspace/srv/bd/part/mbr_part/mbr_part.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/bd/part/mbr_part/mbr_part.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -190,5 +190,5 @@
 	}
 
-	rc = block_init(indev_handle, 2048);
+	rc = block_init(EXCHANGE_SERIALIZE, indev_handle, 2048);
 	if (rc != EOK)  {
 		printf(NAME ": could not init libblock.\n");
@@ -437,9 +437,12 @@
 		callid = async_get_call(&call);
 		method = IPC_GET_IMETHOD(call);
-		switch (method) {
-		case IPC_M_PHONE_HUNGUP:
+		
+		if (!method) {
 			/* The other side has hung up. */
 			async_answer_0(callid, EOK);
 			return;
+		}
+		
+		switch (method) {
 		case BD_READ_BLOCKS:
 			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
Index: uspace/srv/bd/rd/rd.c
===================================================================
--- uspace/srv/bd/rd/rd.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/bd/rd/rd.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -123,12 +123,15 @@
 	while (true) {
 		callid = async_get_call(&call);
-		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
+		
+		if (!IPC_GET_IMETHOD(call)) {
 			/*
 			 * The other side has hung up.
-			 * Answer the message and exit the fibril.
+			 * Exit the fibril.
 			 */
 			async_answer_0(callid, EOK);
 			return;
+		}
+		
+		switch (IPC_GET_IMETHOD(call)) {
 		case BD_READ_BLOCKS:
 			ba = MERGE_LOUP32(IPC_GET_ARG1(call),
@@ -243,5 +246,5 @@
 		return false;
 	}
-
+	
 	fibril_rwlock_initialize(&rd_lock);
 	
@@ -258,5 +261,5 @@
 	printf("%s: Accepting connections\n", NAME);
 	async_manager();
-
+	
 	/* Never reached */
 	return 0;
Index: uspace/srv/clip/clip.c
===================================================================
--- uspace/srv/clip/clip.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/clip/clip.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -30,5 +30,5 @@
 #include <bool.h>
 #include <async.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <ipc/services.h>
 #include <ipc/clipboard.h>
@@ -153,13 +153,12 @@
 	async_answer_0(iid, EOK);
 	
-	bool cont = true;
-	while (cont) {
+	while (true) {
 		ipc_call_t call;
 		ipc_callid_t callid = async_get_call(&call);
 		
+		if (!IPC_GET_IMETHOD(call))
+			break;
+		
 		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			cont = false;
-			continue;
 		case CLIPBOARD_PUT_DATA:
 			clip_put_data(callid, &call);
@@ -179,5 +178,5 @@
 int main(int argc, char *argv[])
 {
-	printf(NAME ": HelenOS clipboard service\n");
+	printf("%s: HelenOS clipboard service\n", NAME);
 	
 	async_set_client_connection(clip_connection);
@@ -186,5 +185,6 @@
 		return -1;
 	
-	printf(NAME ": Accepting connections\n");
+	printf("%s: Accepting connections\n", NAME);
+	task_retval(0);
 	async_manager();
 	
Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/devman/devman.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -564,5 +564,4 @@
 	dev_node_t *dev;
 	link_t *link;
-	int phone;
 
 	log_msg(LVL_DEBUG, "pass_devices_to_driver(driver=\"%s\")",
@@ -570,8 +569,11 @@
 
 	fibril_mutex_lock(&driver->driver_mutex);
-
-	phone = async_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 0);
-
-	if (phone < 0) {
+	
+	async_exch_t *exch = async_exchange_begin(driver->sess);
+	async_sess_t *sess = async_connect_me_to(EXCHANGE_SERIALIZE, exch,
+	    DRIVER_DEVMAN, 0, 0);
+	async_exchange_end(exch);
+
+	if (!sess) {
 		fibril_mutex_unlock(&driver->driver_mutex);
 		return;
@@ -602,5 +604,5 @@
 		fibril_mutex_unlock(&driver->driver_mutex);
 
-		add_device(phone, driver, dev, tree);
+		add_device(sess, driver, dev, tree);
 
 		/*
@@ -623,5 +625,5 @@
 	}
 
-	async_hangup(phone);
+	async_hangup(sess);
 
 	/*
@@ -673,5 +675,5 @@
 	list_initialize(&drv->devices);
 	fibril_mutex_initialize(&drv->driver_mutex);
-	drv->phone = -1;
+	drv->sess = NULL;
 }
 
@@ -737,5 +739,6 @@
  * @param node		The device's node in the device tree.
  */
-void add_device(int phone, driver_t *drv, dev_node_t *dev, dev_tree_t *tree)
+void add_device(async_sess_t *sess, driver_t *drv, dev_node_t *dev,
+    dev_tree_t *tree)
 {
 	/*
@@ -746,7 +749,4 @@
 	    drv->name, dev->pfun->name);
 	
-	sysarg_t rc;
-	ipc_call_t answer;
-	
 	/* Send the device to the driver. */
 	devman_handle_t parent_handle;
@@ -756,11 +756,17 @@
 		parent_handle = 0;
 	}
-
-	aid_t req = async_send_2(phone, DRIVER_ADD_DEVICE, dev->handle,
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	
+	ipc_call_t answer;
+	aid_t req = async_send_2(exch, DRIVER_ADD_DEVICE, dev->handle,
 	    parent_handle, &answer);
 	
-	/* Send the device's name to the driver. */
-	rc = async_data_write_start(phone, dev->pfun->name,
+	/* Send the device name to the driver. */
+	sysarg_t rc = async_data_write_start(exch, dev->pfun->name,
 	    str_size(dev->pfun->name) + 1);
+	
+	async_exchange_end(exch);
+	
 	if (rc != EOK) {
 		/* TODO handle error */
@@ -823,8 +829,12 @@
 	if (is_running) {
 		/* Notify the driver about the new device. */
-		int phone = async_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);
-		if (phone >= 0) {
-			add_device(phone, drv, dev, tree);
-			async_hangup(phone);
+		async_exch_t *exch = async_exchange_begin(drv->sess);
+		async_sess_t *sess = async_connect_me_to(EXCHANGE_SERIALIZE, exch,
+		    DRIVER_DEVMAN, 0, 0);
+		async_exchange_end(exch);
+		
+		if (sess) {
+			add_device(sess, drv, dev, tree);
+			async_hangup(sess);
 		}
 	}
Index: uspace/srv/devman/devman.h
===================================================================
--- uspace/srv/devman/devman.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/devman/devman.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -44,4 +44,5 @@
 #include <fibril_synch.h>
 #include <atomic.h>
+#include <async.h>
 
 #include "util.h"
@@ -87,6 +88,6 @@
 	int state;
 	
-	/** Phone asociated with this driver. */
-	int phone;
+	/** Session asociated with this driver. */
+	async_sess_t *sess;
 	/** Name of the device driver. */
 	char *name;
@@ -99,5 +100,5 @@
 	
 	/**
-	 * Fibril mutex for this driver - driver state, list of devices, phone.
+	 * Fibril mutex for this driver - driver state, list of devices, session.
 	 */
 	fibril_mutex_t driver_mutex;
@@ -312,5 +313,5 @@
 extern void add_driver(driver_list_t *, driver_t *);
 extern void attach_driver(dev_node_t *, driver_t *);
-extern void add_device(int, driver_t *, dev_node_t *, dev_tree_t *);
+extern void add_device(async_sess_t *, driver_t *, dev_node_t *, dev_tree_t *);
 extern bool start_driver(driver_t *);
 
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/devman/main.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -39,5 +39,5 @@
 #include <assert.h>
 #include <ipc/services.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <async.h>
 #include <stdio.h>
@@ -108,5 +108,5 @@
 	fibril_mutex_lock(&driver->driver_mutex);
 	
-	if (driver->phone >= 0) {
+	if (driver->sess) {
 		/* We already have a connection to the driver. */
 		log_msg(LVL_ERROR, "Driver '%s' already started.\n",
@@ -128,5 +128,5 @@
 		break;
 	case DRIVER_RUNNING:
-		/* Should not happen since we do not have a connected phone */
+		/* Should not happen since we do not have a connected session */
 		assert(false);
 	}
@@ -135,23 +135,17 @@
 	log_msg(LVL_DEBUG, "Creating connection to the `%s' driver.",
 	    driver->name);
-	ipc_call_t call;
-	ipc_callid_t callid = async_get_call(&call);
-	if (IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) {
+	driver->sess = async_callback_receive(EXCHANGE_SERIALIZE);
+	if (!driver->sess) {
 		fibril_mutex_unlock(&driver->driver_mutex);
-		async_answer_0(callid, ENOTSUP);
 		async_answer_0(iid, ENOTSUP);
 		return NULL;
 	}
 	
-	/* Remember driver's phone. */
-	driver->phone = IPC_GET_ARG5(call);
-	
 	fibril_mutex_unlock(&driver->driver_mutex);
 	
-	log_msg(LVL_NOTE, 
+	log_msg(LVL_NOTE,
 	    "The `%s' driver was successfully registered as running.",
 	    driver->name);
 	
-	async_answer_0(callid, EOK);
 	async_answer_0(iid, EOK);
 	
@@ -434,14 +428,12 @@
 	fibril_add_ready(fid);
 	
-	ipc_callid_t callid;
-	ipc_call_t call;
-	bool cont = true;
-	while (cont) {
-		callid = async_get_call(&call);
+	while (true) {
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+		
+		if (!IPC_GET_IMETHOD(call))
+			break;
 		
 		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			cont = false;
-			continue;
 		case DEVMAN_ADD_FUNCTION:
 			devman_add_function(callid, &call);
@@ -559,13 +551,12 @@
 	async_answer_0(iid, EOK);
 	
-	bool cont = true;
-	while (cont) {
+	while (true) {
 		ipc_call_t call;
 		ipc_callid_t callid = async_get_call(&call);
 		
+		if (!IPC_GET_IMETHOD(call))
+			break;
+		
 		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			cont = false;
-			continue;
 		case DEVMAN_DEVICE_GET_HANDLE:
 			devman_function_get_handle(callid, &call);
@@ -635,6 +626,5 @@
 	if (driver == NULL) {
 		log_msg(LVL_ERROR, "IPC forwarding refused - " \
-		    "the device %" PRIun "(%s) is not in usable state.",
-		    handle, dev->pfun->pathname);
+		    "the device %" PRIun " is not in usable state.", handle);
 		async_answer_0(iid, ENOENT);
 		return;
@@ -647,8 +637,7 @@
 		method = DRIVER_CLIENT;
 	
-	if (driver->phone < 0) {
-		log_msg(LVL_ERROR, 
-		    "Could not forward to driver `%s' (phone is %d).",
-		    driver->name, (int) driver->phone);
+	if (!driver->sess) {
+		log_msg(LVL_ERROR,
+		    "Could not forward to driver `%s'.", driver->name);
 		async_answer_0(iid, EINVAL);
 		return;
@@ -664,6 +653,8 @@
 		    dev->pfun->pathname, driver->name);
 	}
-
-	async_forward_fast(iid, driver->phone, method, fwd_h, 0, IPC_FF_NONE);
+	
+	async_exch_t *exch = async_exchange_begin(driver->sess);
+	async_forward_fast(iid, exch, method, fwd_h, 0, IPC_FF_NONE);
+	async_exchange_end(exch);
 }
 
@@ -687,12 +678,15 @@
 	dev = fun->dev;
 	
-	if (dev->state != DEVICE_USABLE || dev->drv->phone < 0) {
+	if ((dev->state != DEVICE_USABLE) || (!dev->drv->sess)) {
 		async_answer_0(iid, EINVAL);
 		return;
 	}
 	
-	async_forward_fast(iid, dev->drv->phone, DRIVER_CLIENT, fun->handle, 0,
+	async_exch_t *exch = async_exchange_begin(dev->drv->sess);
+	async_forward_fast(iid, exch, DRIVER_CLIENT, fun->handle, 0,
 	    IPC_FF_NONE);
-	log_msg(LVL_DEBUG, 
+	async_exchange_end(exch);
+	
+	log_msg(LVL_DEBUG,
 	    "Forwarding devmapper request for `%s' function to driver `%s'.",
 	    fun->pathname, dev->drv->name);
@@ -786,4 +780,5 @@
 
 	printf(NAME ": Accepting connections.\n");
+	task_retval(0);
 	async_manager();
 
Index: uspace/srv/devmap/devmap.c
===================================================================
--- uspace/srv/devmap/devmap.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/devmap/devmap.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -37,5 +37,5 @@
 
 #include <ipc/services.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <async.h>
 #include <stdio.h>
@@ -59,10 +59,14 @@
 	/** Pointers to previous and next drivers in linked list */
 	link_t drivers;
+	
 	/** Pointer to the linked list of devices controlled by this driver */
 	link_t devices;
-	/** Phone asociated with this driver */
-	sysarg_t phone;
+	
+	/** Session asociated with this driver */
+	async_sess_t *sess;
+	
 	/** Device driver name */
 	char *name;
+	
 	/** Fibril mutex for list of devices owned by this driver */
 	fibril_mutex_t devices_mutex;
@@ -75,8 +79,11 @@
 	/** Pointer to the previous and next device in the list of all namespaces */
 	link_t namespaces;
+	
 	/** Unique namespace identifier */
 	devmap_handle_t handle;
+	
 	/** Namespace name */
 	char *name;
+	
 	/** Reference count */
 	size_t refcnt;
@@ -405,17 +412,11 @@
 	 * Create connection to the driver
 	 */
-	ipc_call_t call;
-	ipc_callid_t callid = async_get_call(&call);
-	
-	if (IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) {
+	driver->sess = async_callback_receive(EXCHANGE_SERIALIZE);
+	if (!driver->sess) {
 		free(driver->name);
 		free(driver);
-		async_answer_0(callid, ENOTSUP);
 		async_answer_0(iid, ENOTSUP);
 		return NULL;
 	}
-	
-	driver->phone = IPC_GET_ARG5(call);
-	async_answer_0(callid, EOK);
 	
 	/*
@@ -462,6 +463,6 @@
 	fibril_mutex_lock(&drivers_list_mutex);
 	
-	if (driver->phone != 0)
-		async_hangup(driver->phone);
+	if (driver->sess)
+		async_hangup(driver->sess);
 	
 	/* Remove it from list of drivers */
@@ -607,5 +608,5 @@
 	devmap_device_t *dev = devmap_device_find_handle(handle);
 	
-	if ((dev == NULL) || (dev->driver == NULL) || (dev->driver->phone == 0)) {
+	if ((dev == NULL) || (dev->driver == NULL) || (!dev->driver->sess)) {
 		fibril_mutex_unlock(&devices_list_mutex);
 		async_answer_0(callid, ENOENT);
@@ -613,13 +614,13 @@
 	}
 	
-	if (dev->forward_interface == 0) {
-		async_forward_fast(callid, dev->driver->phone,
-		    dev->handle, 0, 0,
-		    IPC_FF_NONE);
-	} else {
-		async_forward_fast(callid, dev->driver->phone,
-		    dev->forward_interface, dev->handle, 0,
-		    IPC_FF_NONE);
-	}
+	async_exch_t *exch = async_exchange_begin(dev->driver->sess);
+	
+	if (dev->forward_interface == 0)
+		async_forward_fast(callid, exch, dev->handle, 0, 0, IPC_FF_NONE);
+	else
+		async_forward_fast(callid, exch, dev->forward_interface,
+		    dev->handle, 0, IPC_FF_NONE);
+	
+	async_exchange_end(exch);
 	
 	fibril_mutex_unlock(&devices_list_mutex);
@@ -1029,13 +1030,12 @@
 		return;
 	
-	bool cont = true;
-	while (cont) {
+	while (true) {
 		ipc_call_t call;
 		ipc_callid_t callid = async_get_call(&call);
 		
+		if (!IPC_GET_IMETHOD(call))
+			break;
+		
 		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			cont = false;
-			continue;
 		case DEVMAP_DRIVER_UNREGISTER:
 			if (NULL == driver)
@@ -1080,13 +1080,12 @@
 	async_answer_0(iid, EOK);
 	
-	bool cont = true;
-	while (cont) {
+	while (true) {
 		ipc_call_t call;
 		ipc_callid_t callid = async_get_call(&call);
 		
+		if (!IPC_GET_IMETHOD(call))
+			break;
+		
 		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			cont = false;
-			continue;
 		case DEVMAP_DEVICE_GET_HANDLE:
 			devmap_device_get_handle(callid, &call);
Index: uspace/srv/fs/devfs/devfs.c
===================================================================
--- uspace/srv/fs/devfs/devfs.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/fs/devfs/devfs.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -41,5 +41,5 @@
 #include <stdio.h>
 #include <ipc/services.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <async.h>
 #include <errno.h>
@@ -68,7 +68,8 @@
 		ipc_callid_t callid = async_get_call(&call);
 		
-		switch  (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
+		if (!IPC_GET_IMETHOD(call))
 			return;
+		
+		switch (IPC_GET_IMETHOD(call)) {
 		case VFS_OUT_MOUNTED:
 			devfs_mounted(callid, &call);
@@ -119,25 +120,26 @@
 int main(int argc, char *argv[])
 {
-	printf(NAME ": HelenOS Device Filesystem\n");
+	printf("%s: HelenOS Device Filesystem\n", NAME);
 	
 	if (!devfs_init()) {
-		printf(NAME ": failed to initialize devfs\n");
+		printf("%s: failed to initialize devfs\n", NAME);
 		return -1;
 	}
 	
-	int vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
-	if (vfs_phone < EOK) {
-		printf(NAME ": Unable to connect to VFS\n");
+	async_sess_t *vfs_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
+	    SERVICE_VFS, 0, 0);
+	if (!vfs_sess) {
+		printf("%s: Unable to connect to VFS\n", NAME);
 		return -1;
 	}
 	
-	int rc = fs_register(vfs_phone, &devfs_reg, &devfs_vfs_info,
+	int rc = fs_register(vfs_sess, &devfs_reg, &devfs_vfs_info,
 	    devfs_connection);
 	if (rc != EOK) {
-		printf(NAME ": Failed to register file system (%d)\n", rc);
+		printf("%s: Failed to register file system (%d)\n", NAME, rc);
 		return rc;
 	}
 	
-	printf(NAME ": Accepting connections\n");
+	printf("%s: Accepting connections\n", NAME);
 	task_retval(0);
 	async_manager();
Index: uspace/srv/fs/devfs/devfs_ops.c
===================================================================
--- uspace/srv/fs/devfs/devfs_ops.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/fs/devfs/devfs_ops.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -59,8 +59,8 @@
 typedef struct {
 	devmap_handle_t handle;
-	int phone;		/**< When < 0, the structure is incomplete. */
+	async_sess_t *sess;       /**< If NULL, the structure is incomplete. */
 	size_t refcount;
 	link_t link;
-	fibril_condvar_t cv;	/**< Broadcast when completed. */
+	fibril_condvar_t cv;      /**< Broadcast when completed. */
 } device_t;
 
@@ -232,5 +232,5 @@
 		};
 		link_t *lnk;
-
+		
 		fibril_mutex_lock(&devices_mutex);
 restart:
@@ -244,8 +244,10 @@
 			
 			dev->handle = node->handle;
-			dev->phone = -1;	/* mark as incomplete */
+			
+			/* Mark as incomplete */
+			dev->sess = NULL;
 			dev->refcount = 1;
 			fibril_condvar_initialize(&dev->cv);
-
+			
 			/*
 			 * Insert the incomplete device structure so that other
@@ -254,14 +256,15 @@
 			 */
 			hash_table_insert(&devices, key, &dev->link);
-
+			
 			/*
 			 * Drop the mutex to allow recursive devfs requests.
 			 */
 			fibril_mutex_unlock(&devices_mutex);
-
-			int phone = devmap_device_connect(node->handle, 0);
-
+			
+			async_sess_t *sess = devmap_device_connect(EXCHANGE_SERIALIZE,
+			    node->handle, 0);
+			
 			fibril_mutex_lock(&devices_mutex);
-
+			
 			/*
 			 * Notify possible waiters about this device structure
@@ -269,6 +272,6 @@
 			 */
 			fibril_condvar_broadcast(&dev->cv);
-
-			if (phone < 0) {
+			
+			if (!sess) {
 				/*
 				 * Connecting failed, need to remove the
@@ -277,14 +280,14 @@
 				hash_table_remove(&devices, key, DEVICES_KEYS);
 				fibril_mutex_unlock(&devices_mutex);
-
+				
 				return ENOENT;
 			}
 			
-			/* Set the correct phone. */
-			dev->phone = phone;
+			/* Set the correct session. */
+			dev->sess = sess;
 		} else {
 			device_t *dev = hash_table_get_instance(lnk, device_t, link);
-
-			if (dev->phone < 0) {
+			
+			if (!dev->sess) {
 				/*
 				 * Wait until the device structure is completed
@@ -608,5 +611,5 @@
 		
 		device_t *dev = hash_table_get_instance(lnk, device_t, link);
-		assert(dev->phone >= 0);
+		assert(dev->sess);
 		
 		ipc_callid_t callid;
@@ -619,11 +622,16 @@
 		
 		/* Make a request at the driver */
+		async_exch_t *exch = async_exchange_begin(dev->sess);
+		
 		ipc_call_t answer;
-		aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request),
+		aid_t msg = async_send_3(exch, IPC_GET_IMETHOD(*request),
 		    IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
 		    IPC_GET_ARG3(*request), &answer);
 		
 		/* Forward the IPC_M_DATA_READ request to the driver */
-		async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
+		async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
+		
+		async_exchange_end(exch);
+		
 		fibril_mutex_unlock(&devices_mutex);
 		
@@ -672,5 +680,5 @@
 		
 		device_t *dev = hash_table_get_instance(lnk, device_t, link);
-		assert(dev->phone >= 0);
+		assert(dev->sess);
 		
 		ipc_callid_t callid;
@@ -683,11 +691,15 @@
 		
 		/* Make a request at the driver */
+		async_exch_t *exch = async_exchange_begin(dev->sess);
+		
 		ipc_call_t answer;
-		aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request),
+		aid_t msg = async_send_3(exch, IPC_GET_IMETHOD(*request),
 		    IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
 		    IPC_GET_ARG3(*request), &answer);
 		
 		/* Forward the IPC_M_DATA_WRITE request to the driver */
-		async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
+		async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
+		
+		async_exchange_end(exch);
 		
 		fibril_mutex_unlock(&devices_mutex);
@@ -742,9 +754,9 @@
 		
 		device_t *dev = hash_table_get_instance(lnk, device_t, link);
-		assert(dev->phone >= 0);
+		assert(dev->sess);
 		dev->refcount--;
 		
 		if (dev->refcount == 0) {
-			async_hangup(dev->phone);
+			async_hangup(dev->sess);
 			hash_table_remove(&devices, key, DEVICES_KEYS);
 		}
@@ -790,10 +802,14 @@
 		
 		device_t *dev = hash_table_get_instance(lnk, device_t, link);
-		assert(dev->phone >= 0);
+		assert(dev->sess);
 		
 		/* Make a request at the driver */
+		async_exch_t *exch = async_exchange_begin(dev->sess);
+		
 		ipc_call_t answer;
-		aid_t msg = async_send_2(dev->phone, IPC_GET_IMETHOD(*request),
+		aid_t msg = async_send_2(exch, IPC_GET_IMETHOD(*request),
 		    IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer);
+		
+		async_exchange_end(exch);
 		
 		fibril_mutex_unlock(&devices_mutex);
Index: uspace/srv/fs/ext2fs/ext2fs.c
===================================================================
--- uspace/srv/fs/ext2fs/ext2fs.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/fs/ext2fs/ext2fs.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -40,5 +40,5 @@
 #include "ext2fs.h"
 #include <ipc/services.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <async.h>
 #include <errno.h>
@@ -87,12 +87,12 @@
 	
 	dprintf(NAME ": connection opened\n");
-	while (1) {
-		ipc_callid_t callid;
+	while (true) {
 		ipc_call_t call;
-	
-		callid = async_get_call(&call);
-		switch  (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
+		ipc_callid_t callid = async_get_call(&call);
+		
+		if (!IPC_GET_IMETHOD(call))
 			return;
+		
+		switch (IPC_GET_IMETHOD(call)) {
 		case VFS_OUT_MOUNTED:
 			ext2fs_mounted(callid, &call);
@@ -143,16 +143,14 @@
 int main(int argc, char **argv)
 {
-	int vfs_phone;
-	int rc;
-
 	printf(NAME ": HelenOS EXT2 file system server\n");
-
-	vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
-	if (vfs_phone < EOK) {
+	
+	async_sess_t *vfs_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
+	    SERVICE_VFS, 0, 0);
+	if (!vfs_sess) {
 		printf(NAME ": failed to connect to VFS\n");
 		return -1;
 	}
 
-	rc = ext2fs_global_init();
+	int rc = ext2fs_global_init();
 	if (rc != EOK) {
 		printf(NAME ": Failed global initialization\n");
@@ -160,5 +158,5 @@
 	}	
 		
-	rc = fs_register(vfs_phone, &ext2fs_reg, &ext2fs_vfs_info, ext2fs_connection);
+	rc = fs_register(vfs_sess, &ext2fs_reg, &ext2fs_vfs_info, ext2fs_connection);
 	if (rc != EOK) {
 		fprintf(stdout, NAME ": Failed to register fs (%d)\n", rc);
Index: uspace/srv/fs/fat/fat.c
===================================================================
--- uspace/srv/fs/fat/fat.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/fs/fat/fat.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -39,5 +39,5 @@
 #include "fat.h"
 #include <ipc/services.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <async.h>
 #include <errno.h>
@@ -88,12 +88,13 @@
 	
 	dprintf(NAME ": connection opened\n");
-	while (1) {
-		ipc_callid_t callid;
+	
+	while (true) {
 		ipc_call_t call;
-	
-		callid = async_get_call(&call);
-		switch  (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
+		ipc_callid_t callid = async_get_call(&call);
+		
+		if (!IPC_GET_IMETHOD(call))
 			return;
+		
+		switch (IPC_GET_IMETHOD(call)) {
 		case VFS_OUT_MOUNTED:
 			fat_mounted(callid, &call);
@@ -144,20 +145,18 @@
 int main(int argc, char **argv)
 {
-	int vfs_phone;
-	int rc;
-
 	printf(NAME ": HelenOS FAT file system server\n");
-
-	rc = fat_idx_init();
+	
+	int rc = fat_idx_init();
 	if (rc != EOK)
 		goto err;
-
-	vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
-	if (vfs_phone < EOK) {
+	
+	async_sess_t *vfs_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
+	    SERVICE_VFS, 0, 0);
+	if (!vfs_sess) {
 		printf(NAME ": failed to connect to VFS\n");
 		return -1;
 	}
 	
-	rc = fs_register(vfs_phone, &fat_reg, &fat_vfs_info, fat_connection);
+	rc = fs_register(vfs_sess, &fat_reg, &fat_vfs_info, fat_connection);
 	if (rc != EOK) {
 		fat_idx_fini();
@@ -168,7 +167,8 @@
 	task_retval(0);
 	async_manager();
-	/* not reached */
+	
+	/* Not reached */
 	return 0;
-
+	
 err:
 	printf(NAME ": Failed to register file system (%d)\n", rc);
@@ -178,3 +178,3 @@
 /**
  * @}
- */ 
+ */
Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/fs/fat/fat_ops.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -970,5 +970,5 @@
 
 	/* initialize libblock */
-	rc = block_init(devmap_handle, BS_SIZE);
+	rc = block_init(EXCHANGE_SERIALIZE, devmap_handle, BS_SIZE);
 	if (rc != EOK) {
 		async_answer_0(rid, rc);
Index: uspace/srv/fs/tmpfs/tmpfs.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/fs/tmpfs/tmpfs.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -30,5 +30,5 @@
 /** @addtogroup fs
  * @{
- */ 
+ */
 
 /**
@@ -43,5 +43,5 @@
 #include "tmpfs.h"
 #include <ipc/services.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <async.h>
 #include <errno.h>
@@ -94,12 +94,13 @@
 	
 	dprintf(NAME ": connection opened\n");
-	while (1) {
-		ipc_callid_t callid;
+	
+	while (true) {
 		ipc_call_t call;
-	
-		callid = async_get_call(&call);
-		switch  (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
+		ipc_callid_t callid = async_get_call(&call);
+		
+		if (!IPC_GET_IMETHOD(call))
 			return;
+		
+		switch (IPC_GET_IMETHOD(call)) {
 		case VFS_OUT_MOUNTED:
 			tmpfs_mounted(callid, &call);
@@ -151,17 +152,18 @@
 {
 	printf(NAME ": HelenOS TMPFS file system server\n");
-
+	
 	if (!tmpfs_init()) {
 		printf(NAME ": failed to initialize TMPFS\n");
 		return -1;
 	}
-
-	int vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
-	if (vfs_phone < EOK) {
+	
+	async_sess_t *vfs_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
+	    SERVICE_VFS, 0, 0);
+	if (!vfs_sess) {
 		printf(NAME ": Unable to connect to VFS\n");
 		return -1;
 	}
-
-	int rc = fs_register(vfs_phone, &tmpfs_reg, &tmpfs_vfs_info,
+	
+	int rc = fs_register(vfs_sess, &tmpfs_reg, &tmpfs_vfs_info,
 	    tmpfs_connection);
 	if (rc != EOK) {
@@ -169,9 +171,10 @@
 		return rc;
 	}
-
+	
 	printf(NAME ": Accepting connections\n");
 	task_retval(0);
 	async_manager();
-	/* not reached */
+	
+	/* Not reached */
 	return 0;
 }
@@ -179,3 +182,3 @@
 /**
  * @}
- */ 
+ */
Index: uspace/srv/fs/tmpfs/tmpfs_dump.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_dump.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/fs/tmpfs/tmpfs_dump.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -167,5 +167,5 @@
 	int rc;
 
-	rc = block_init(dev, TMPFS_COMM_SIZE);
+	rc = block_init(EXCHANGE_SERIALIZE, dev, TMPFS_COMM_SIZE);
 	if (rc != EOK)
 		return false; 
Index: uspace/srv/hid/adb_mouse/adb_dev.c
===================================================================
--- uspace/srv/hid/adb_mouse/adb_dev.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/adb_mouse/adb_dev.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -39,4 +39,9 @@
 #include <fcntl.h>
 #include <errno.h>
+#include <devmap.h>
+#include <devmap_obsolete.h>
+#include <async.h>
+#include <async_obsolete.h>
+#include <kernel/ipc/ipc_methods.h>
 
 #include "adb_mouse.h"
@@ -45,27 +50,23 @@
 static void adb_dev_events(ipc_callid_t iid, ipc_call_t *icall);
 
-static int dev_phone;
-
 int adb_dev_init(void)
 {
-	const char *input = "/dev/adb/mouse";
-	int input_fd;
-
-	printf(NAME ": open %s\n", input);
-
-	input_fd = open(input, O_RDONLY);
-	if (input_fd < 0) {
-		printf(NAME ": Failed opening %s (%d)\n", input, input_fd);
-		return false;
+	devmap_handle_t handle;
+	int rc = devmap_device_get_handle("adb/mouse", &handle,
+	    IPC_FLAG_BLOCKING);
+	
+	if (rc != EOK) {
+		printf("%s: Failed resolving ADB\n", NAME);
+		return rc;
 	}
-
-	dev_phone = fd_phone(input_fd);
+	
+	int dev_phone = devmap_obsolete_device_connect(handle, IPC_FLAG_BLOCKING);
 	if (dev_phone < 0) {
-		printf(NAME ": Failed to connect to device\n");
-		return false;
+		printf("%s: Failed connecting to ADB\n", NAME);
+		return ENOENT;
 	}
-
+	
 	/* NB: The callback connection is slotted for removal */
-	if (async_connect_to_me(dev_phone, 0, 0, 0, adb_dev_events) != 0) {
+	if (async_obsolete_connect_to_me(dev_phone, 0, 0, 0, adb_dev_events) != 0) {
 		printf(NAME ": Failed to create callback from device\n");
 		return false;
@@ -84,9 +85,11 @@
 
 		int retval;
+		
+		if (!IPC_GET_IMETHOD(call)) {
+			/* TODO: Handle hangup */
+			return;
+		}
 
 		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			/* TODO: Handle hangup */
-			return;
 		case IPC_FIRST_USER_METHOD:
 			mouse_handle_data(IPC_GET_ARG1(call));
Index: uspace/srv/hid/adb_mouse/adb_mouse.c
===================================================================
--- uspace/srv/hid/adb_mouse/adb_mouse.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/adb_mouse/adb_mouse.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -43,9 +43,12 @@
 #include <stdlib.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <errno.h>
 #include <devmap.h>
-
 #include "adb_mouse.h"
 #include "adb_dev.h"
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 static void client_connection(ipc_callid_t iid, ipc_call_t *icall);
@@ -101,8 +104,8 @@
 	while (1) {
 		callid = async_get_call(&call);
-		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
+		
+		if (!IPC_GET_IMETHOD(call)) {
 			if (client_phone != -1) {
-				async_hangup(client_phone);
+				async_obsolete_hangup(client_phone);
 				client_phone = -1;
 			}
@@ -110,4 +113,7 @@
 			async_answer_0(callid, EOK);
 			return;
+		}
+		
+		switch (IPC_GET_IMETHOD(call)) {
 		case IPC_M_CONNECT_TO_ME:
 			if (client_phone != -1) {
@@ -158,5 +164,5 @@
 {
 	if (client_phone != -1) {
-		async_msg_2(client_phone, MEVENT_BUTTON, button, press);
+		async_obsolete_msg_2(client_phone, MEVENT_BUTTON, button, press);
 	}
 }
@@ -165,5 +171,5 @@
 {
 	if (client_phone != -1)
-		async_msg_2(client_phone, MEVENT_MOVE, dx, dy);
+		async_obsolete_msg_2(client_phone, MEVENT_MOVE, dx, dy);
 }
 
Index: uspace/srv/hid/char_mouse/char_mouse.c
===================================================================
--- uspace/srv/hid/char_mouse/char_mouse.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/char_mouse/char_mouse.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -43,10 +43,13 @@
 #include <stdlib.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <errno.h>
 #include <devmap.h>
-
 #include <char_mouse.h>
 #include <mouse_port.h>
 #include <mouse_proto.h>
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 #define NAME       "mouse"
@@ -65,5 +68,5 @@
 /*	printf("ev_btn: button %d, press %d\n", button, press);*/
 	if (client_phone != -1) {
-		async_msg_2(client_phone, MEVENT_BUTTON, button, press);
+		async_obsolete_msg_2(client_phone, MEVENT_BUTTON, button, press);
 	}
 }
@@ -73,5 +76,5 @@
 /*	printf("ev_move: dx %d, dy %d\n", dx, dy);*/
 	if (client_phone != -1)
-		async_msg_2(client_phone, MEVENT_MOVE, dx, dy);
+		async_obsolete_msg_2(client_phone, MEVENT_MOVE, dx, dy);
 }
 
@@ -86,8 +89,8 @@
 	while (1) {
 		callid = async_get_call(&call);
-		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
+		
+		if (!IPC_GET_IMETHOD(call)) {
 			if (client_phone != -1) {
-				async_hangup(client_phone);
+				async_obsolete_hangup(client_phone);
 				client_phone = -1;
 			}
@@ -95,4 +98,7 @@
 			async_answer_0(callid, EOK);
 			return;
+		}
+		
+		switch (IPC_GET_IMETHOD(call)) {
 		case IPC_M_CONNECT_TO_ME:
 			if (client_phone != -1) {
Index: uspace/srv/hid/char_mouse/chardev.c
===================================================================
--- uspace/srv/hid/char_mouse/chardev.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/char_mouse/chardev.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -36,8 +36,10 @@
 #include <ipc/char.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <vfs/vfs.h>
 #include <fcntl.h>
 #include <errno.h>
-
+#include <devmap.h>
+#include <devmap_obsolete.h>
 #include <char_mouse.h>
 #include <mouse_port.h>
@@ -51,27 +53,25 @@
 int mouse_port_init(void)
 {
-	const char *input = "/dev/char/ps2b";
-	int input_fd;
-
-	printf(NAME ": open %s\n", input);
-
-	input_fd = open(input, O_RDONLY);
-	if (input_fd < 0) {
-		printf(NAME ": Failed opening %s (%d)\n", input, input_fd);
-		return false;
+	devmap_handle_t handle;
+	int rc = devmap_device_get_handle("char/ps2b", &handle,
+	    IPC_FLAG_BLOCKING);
+	
+	if (rc != EOK) {
+		printf("%s: Failed resolving PS/2\n", NAME);
+		return rc;
 	}
-
-	dev_phone = fd_phone(input_fd);
+	
+	dev_phone = devmap_obsolete_device_connect(handle, IPC_FLAG_BLOCKING);
 	if (dev_phone < 0) {
-		printf(NAME ": Failed to connect to device\n");
-		return false;
+		printf("%s: Failed connecting to PS/2\n", NAME);
+		return ENOENT;
 	}
-
+	
 	/* NB: The callback connection is slotted for removal */
-	if (async_connect_to_me(dev_phone, 0, 0, 0, chardev_events) != 0) {
+	if (async_obsolete_connect_to_me(dev_phone, 0, 0, 0, chardev_events) != 0) {
 		printf(NAME ": Failed to create callback from device\n");
 		return false;
 	}
-
+	
 	return 0;
 }
@@ -87,5 +87,5 @@
 void mouse_port_write(uint8_t data)
 {
-	async_msg_1(dev_phone, CHAR_WRITE_BYTE, data);
+	async_obsolete_msg_1(dev_phone, CHAR_WRITE_BYTE, data);
 }
 
@@ -99,9 +99,11 @@
 
 		int retval;
+		
+		if (!IPC_GET_IMETHOD(call)) {
+			/* TODO: Handle hangup */
+			return;
+		}
 
 		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			/* TODO: Handle hangup */
-			return;
 		case IPC_FIRST_USER_METHOD:
 			mouse_handle_byte(IPC_GET_ARG1(call));
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/console/console.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -39,5 +39,6 @@
 #include <ipc/fb.h>
 #include <ipc/services.h>
-#include <ipc/ns.h>
+#include <ns.h>
+#include <ns_obsolete.h>
 #include <errno.h>
 #include <str_error.h>
@@ -45,4 +46,5 @@
 #include <unistd.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <adt/fifo.h>
 #include <sys/mman.h>
@@ -52,4 +54,5 @@
 #include <event.h>
 #include <devmap.h>
+#include <devmap_obsolete.h>
 #include <fcntl.h>
 #include <vfs/vfs.h>
@@ -63,7 +66,10 @@
 #include "keybuffer.h"
 
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 #define NAME       "console"
 #define NAMESPACE  "term"
+
 /** Interval for checking for new keyboard (1/4s). */
 #define HOTPLUG_WATCH_INTERVAL (1000 * 250)
@@ -71,4 +77,5 @@
 /* Kernel defines 32 but does not export it. */
 #define MAX_IPC_OUTGOING_PHONES 128
+
 /** To allow proper phone closing. */
 static ipc_callid_t driver_phones[MAX_IPC_OUTGOING_PHONES] = { 0 };
@@ -97,6 +104,4 @@
 } console_t;
 
-
-
 /** Array of data for virtual consoles */
 static console_t consoles[CONSOLE_COUNT];
@@ -122,55 +127,55 @@
 static void curs_visibility(bool visible)
 {
-	async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible); 
+	async_obsolete_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible); 
 }
 
 static void curs_hide_sync(void)
 {
-	async_req_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false); 
+	async_obsolete_req_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false); 
 }
 
 static void curs_goto(sysarg_t x, sysarg_t y)
 {
-	async_msg_2(fb_info.phone, FB_CURSOR_GOTO, x, y);
+	async_obsolete_msg_2(fb_info.phone, FB_CURSOR_GOTO, x, y);
 }
 
 static void screen_clear(void)
 {
-	async_msg_0(fb_info.phone, FB_CLEAR);
+	async_obsolete_msg_0(fb_info.phone, FB_CLEAR);
 }
 
 static void screen_yield(void)
 {
-	async_req_0_0(fb_info.phone, FB_SCREEN_YIELD);
+	async_obsolete_req_0_0(fb_info.phone, FB_SCREEN_YIELD);
 }
 
 static void screen_reclaim(void)
 {
-	async_req_0_0(fb_info.phone, FB_SCREEN_RECLAIM);
+	async_obsolete_req_0_0(fb_info.phone, FB_SCREEN_RECLAIM);
 }
 
 static void kbd_yield(void)
 {
-	async_req_0_0(kbd_phone, KBD_YIELD);
+	async_obsolete_req_0_0(kbd_phone, KBD_YIELD);
 }
 
 static void kbd_reclaim(void)
 {
-	async_req_0_0(kbd_phone, KBD_RECLAIM);
+	async_obsolete_req_0_0(kbd_phone, KBD_RECLAIM);
 }
 
 static void set_style(uint8_t style)
 {
-	async_msg_1(fb_info.phone, FB_SET_STYLE, style);
+	async_obsolete_msg_1(fb_info.phone, FB_SET_STYLE, style);
 }
 
 static void set_color(uint8_t fgcolor, uint8_t bgcolor, uint8_t flags)
 {
-	async_msg_3(fb_info.phone, FB_SET_COLOR, fgcolor, bgcolor, flags);
+	async_obsolete_msg_3(fb_info.phone, FB_SET_COLOR, fgcolor, bgcolor, flags);
 }
 
 static void set_rgb_color(uint32_t fgcolor, uint32_t bgcolor)
 {
-	async_msg_2(fb_info.phone, FB_SET_RGB_COLOR, fgcolor, bgcolor); 
+	async_obsolete_msg_2(fb_info.phone, FB_SET_RGB_COLOR, fgcolor, bgcolor); 
 }
 
@@ -227,5 +232,5 @@
 		}
 		
-		async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
+		async_obsolete_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
 		    x0, y0, width, height);
 	}
@@ -268,5 +273,5 @@
 static void fb_putchar(wchar_t c, sysarg_t col, sysarg_t row)
 {
-	async_msg_3(fb_info.phone, FB_PUTCHAR, c, col, row);
+	async_obsolete_msg_3(fb_info.phone, FB_PUTCHAR, c, col, row);
 }
 
@@ -317,5 +322,5 @@
 		
 		if (cons == active_console)
-			async_msg_1(fb_info.phone, FB_SCROLL, 1);
+			async_obsolete_msg_1(fb_info.phone, FB_SCROLL, 1);
 	}
 	
@@ -328,17 +333,16 @@
 static void change_console(console_t *cons)
 {
-	if (cons == active_console) {
+	if (cons == active_console)
 		return;
-	}
 	
 	fb_pending_flush();
 	
 	if (cons == kernel_console) {
-		async_serialize_start();
+		async_obsolete_serialize_start();
 		curs_hide_sync();
 		gcons_in_kernel();
 		screen_yield();
 		kbd_yield();
-		async_serialize_end();
+		async_obsolete_serialize_end();
 		
 		if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) {
@@ -350,5 +354,5 @@
 	
 	if (cons != kernel_console) {
-		async_serialize_start();
+		async_obsolete_serialize_start();
 		
 		if (active_console == kernel_console) {
@@ -377,5 +381,5 @@
 			
 			/* This call can preempt, but we are already at the end */
-			rc = async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
+			rc = async_obsolete_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
 			    0, 0, cons->scr.size_x,
 			    cons->scr.size_y);
@@ -405,5 +409,5 @@
 		curs_visibility(cons->scr.is_cursor_visible);
 		
-		async_serialize_end();
+		async_obsolete_serialize_end();
 	}
 }
@@ -416,5 +420,5 @@
 			printf("Device %" PRIxn " gone.\n", hash);
 			driver_phones[i] = 0;
-			async_hangup(i);
+			async_obsolete_hangup(i);
 			return;
 		}
@@ -431,11 +435,13 @@
 		
 		int retval;
-		console_event_t ev;
-		
-		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
+		kbd_event_t ev;
+		
+		if (!IPC_GET_IMETHOD(call)) {
 			/* TODO: Handle hangup */
 			close_driver_phone(iid);
 			return;
+		}
+		
+		switch (IPC_GET_IMETHOD(call)) {
 		case KBD_EVENT:
 			/* Got event from keyboard driver. */
@@ -477,15 +483,16 @@
 		int retval;
 		
-		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
+		if (!IPC_GET_IMETHOD(call)) {
 			/* TODO: Handle hangup */
 			close_driver_phone(iid);
 			return;
+		}
+		
+		switch (IPC_GET_IMETHOD(call)) {
 		case MEVENT_BUTTON:
 			if (IPC_GET_ARG1(call) == 1) {
 				int newcon = gcons_mouse_btn((bool) IPC_GET_ARG2(call));
-				if (newcon != -1) {
+				if (newcon != -1)
 					change_console(&consoles[newcon]);
-				}
 			}
 			retval = 0;
@@ -515,5 +522,5 @@
 	}
 	
-	async_serialize_start();
+	async_obsolete_serialize_start();
 	
 	size_t off = 0;
@@ -523,5 +530,5 @@
 	}
 	
-	async_serialize_end();
+	async_obsolete_serialize_end();
 	
 	gcons_notify_char(cons->index);
@@ -549,5 +556,5 @@
 	
 	size_t pos = 0;
-	console_event_t ev;
+	kbd_event_t ev;
 	fibril_mutex_lock(&input_mutex);
 	
@@ -574,5 +581,5 @@
 static void cons_get_event(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
 {
-	console_event_t ev;
+	kbd_event_t ev;
 	
 	fibril_mutex_lock(&input_mutex);
@@ -618,5 +625,5 @@
 	int rc;
 	
-	async_serialize_start();
+	async_obsolete_serialize_start();
 	if (cons->refcount == 0)
 		gcons_notify_connect(cons->index);
@@ -628,7 +635,7 @@
 	
 	while (true) {
-		async_serialize_end();
+		async_obsolete_serialize_end();
 		callid = async_get_call(&call);
-		async_serialize_start();
+		async_obsolete_serialize_start();
 		
 		arg1 = 0;
@@ -636,24 +643,26 @@
 		arg3 = 0;
 		
-		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
+		if (!IPC_GET_IMETHOD(call)) {
 			cons->refcount--;
 			if (cons->refcount == 0)
 				gcons_notify_disconnect(cons->index);
 			return;
+		}
+		
+		switch (IPC_GET_IMETHOD(call)) {
 		case VFS_OUT_READ:
-			async_serialize_end();
+			async_obsolete_serialize_end();
 			cons_read(cons, callid, &call);
-			async_serialize_start();
+			async_obsolete_serialize_start();
 			continue;
 		case VFS_OUT_WRITE:
-			async_serialize_end();
+			async_obsolete_serialize_end();
 			cons_write(cons, callid, &call);
-			async_serialize_start();
+			async_obsolete_serialize_start();
 			continue;
 		case VFS_OUT_SYNC:
 			fb_pending_flush();
 			if (cons == active_console) {
-				async_req_0_0(fb_info.phone, FB_FLUSH);
+				async_obsolete_req_0_0(fb_info.phone, FB_FLUSH);
 				curs_goto(cons->scr.position_x, cons->scr.position_y);
 			}
@@ -662,5 +671,5 @@
 			/* Send message to fb */
 			if (cons == active_console)
-				async_msg_0(fb_info.phone, FB_CLEAR);
+				async_obsolete_msg_0(fb_info.phone, FB_CLEAR);
 			
 			screenbuffer_clear(&cons->scr);
@@ -721,7 +730,7 @@
 			break;
 		case CONSOLE_GET_EVENT:
-			async_serialize_end();
+			async_obsolete_serialize_end();
 			cons_get_event(cons, callid, &call);
-			async_serialize_start();
+			async_obsolete_serialize_start();
 			continue;
 		case CONSOLE_KCON_ENABLE:
@@ -739,65 +748,63 @@
 
 static int async_connect_to_me_hack(int phone, sysarg_t arg1, sysarg_t arg2,
-sysarg_t arg3, async_client_conn_t client_receiver, ipc_callid_t *hash)
+    sysarg_t arg3, async_client_conn_t client_receiver, ipc_callid_t *hash)
 {
 	sysarg_t task_hash;
 	sysarg_t phone_hash;
-	int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
+	int rc = async_obsolete_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
 	    NULL, NULL, NULL, &task_hash, &phone_hash);
 	if (rc != EOK)
 		return rc;
-
+	
 	if (client_receiver != NULL)
 		async_new_connection(task_hash, phone_hash, phone_hash, NULL,
 		    client_receiver);
-
-	if (hash != NULL) {
+	
+	if (hash != NULL)
 		*hash = phone_hash;
-	}
-
+	
 	return EOK;
 }
 
 static int connect_keyboard_or_mouse(const char *devname,
-    async_client_conn_t handler, const char *path)
-{
-	int fd = open(path, O_RDONLY);
-	if (fd < 0) {
-		return fd;
-	}
-	
-	int phone = fd_phone(fd);
-	close(fd);
-	if (phone < 0) {
-		printf(NAME ": Failed to connect to input device\n");
-		return phone;
-	}
-	
+    async_client_conn_t handler, const char *dev)
+{
+	int phone;
+	devmap_handle_t handle;
+	
+	int rc = devmap_device_get_handle(dev, &handle, 0);
+	if (rc == EOK) {
+		phone = devmap_obsolete_device_connect(handle, 0);
+		if (phone < 0) {
+			printf("%s: Failed to connect to input device\n", NAME);
+			return phone;
+		}
+	} else
+		return rc;
+	
+	/* NB: The callback connection is slotted for removal */
 	ipc_callid_t hash;
-	int rc = async_connect_to_me_hack(phone, SERVICE_CONSOLE, 0, phone,
+	rc = async_connect_to_me_hack(phone, SERVICE_CONSOLE, 0, phone,
 	    handler, &hash);
 	if (rc != EOK) {
-		async_hangup(phone);
-		printf(NAME ": " \
-		    "Failed to create callback from input device: %s.\n",
-		    str_error(rc));
+		async_obsolete_hangup(phone);
+		printf("%s: Failed to create callback from input device (%s).\n",
+		    NAME, str_error(rc));
 		return rc;
 	}
 	
 	driver_phones[phone] = hash;
-
-	printf(NAME ": found %s \"%s\" (%" PRIxn ").\n", devname, path, hash);
-
+	printf("%s: found %s \"%s\" (%" PRIxn ").\n", NAME, devname, dev, hash);
 	return phone;
 }
 
-static int connect_keyboard(const char *path)
-{
-	return connect_keyboard_or_mouse("keyboard", keyboard_events, path);
-}
-
-static int connect_mouse(const char *path)
-{
-	return connect_keyboard_or_mouse("mouse", mouse_events, path);
+static int connect_keyboard(const char *dev)
+{
+	return connect_keyboard_or_mouse("keyboard", keyboard_events, dev);
+}
+
+static int connect_mouse(const char *dev)
+{
+	return connect_keyboard_or_mouse("mouse", mouse_events, dev);
 }
 
@@ -810,33 +817,34 @@
  *
  * @param arg Class name.
+ *
  * @return This function should never exit.
+ *
  */
 static int check_new_device_fibril(void *arg)
 {
-	struct hid_class_info *dev_info = arg;
-
+	struct hid_class_info *dev_info = (struct hid_class_info *) arg;
+	
 	size_t index = 1;
-
+	
 	while (true) {
 		async_usleep(HOTPLUG_WATCH_INTERVAL);
-		char *path;
-		int rc = asprintf(&path, "/dev/class/%s\\%zu",
+		
+		char *dev;
+		int rc = asprintf(&dev, "class/%s\\%zu",
 		    dev_info->classname, index);
-		if (rc < 0) {
+		if (rc < 0)
 			continue;
-		}
-		rc = 0;
-		rc = dev_info->connection_func(path);
+		
+		rc = dev_info->connection_func(dev);
 		if (rc > 0) {
 			/* We do not allow unplug. */
 			index++;
 		}
-
-		free(path);
-	}
-
+		
+		free(dev);
+	}
+	
 	return EOK;
 }
-
 
 /** Start a fibril monitoring hot-plugged keyboards.
@@ -847,47 +855,45 @@
 	struct hid_class_info *dev_info = malloc(sizeof(struct hid_class_info));
 	if (dev_info == NULL) {
-		printf(NAME ": " \
-		    "out of memory, will not start hot-plug-watch fibril.\n");
+		printf("%s: Out of memory, no hot-plug support.\n", NAME);
 		return;
 	}
-	int rc;
-
-	rc = asprintf(&dev_info->classname, "%s", classname);
+	
+	int rc = asprintf(&dev_info->classname, "%s", classname);
 	if (rc < 0) {
-		printf(NAME ": failed to format classname: %s.\n",
+		printf("%s: Failed to format classname: %s.\n", NAME,
 		    str_error(rc));
 		return;
 	}
+	
 	dev_info->connection_func = connection_func;
-
-	fid_t fid = fibril_create(check_new_device_fibril, (void *)dev_info);
+	
+	fid_t fid = fibril_create(check_new_device_fibril, (void *) dev_info);
 	if (!fid) {
-		printf(NAME
-		    ": failed to create hot-plug-watch fibril for %s.\n",
+		printf("%s: Failed to create hot-plug fibril for %s.\n", NAME,
 		    classname);
 		return;
 	}
+	
 	fibril_add_ready(fid);
 }
 
-static bool console_init(char *input)
+static bool console_srv_init(char *kdev)
 {
 	/* Connect to input device */
-	kbd_phone = connect_keyboard(input);
-	if (kbd_phone < 0) {
+	kbd_phone = connect_keyboard(kdev);
+	if (kbd_phone < 0)
 		return false;
-	}
-
-	mouse_phone = connect_mouse("/dev/hid_in/mouse");
+	
+	mouse_phone = connect_mouse("hid_in/mouse");
 	if (mouse_phone < 0) {
-		printf(NAME ": Failed to connect to mouse device: %s.\n",
+		printf("%s: Failed to connect to mouse device %s\n", NAME,
 		    str_error(mouse_phone));
 	}
 	
 	/* Connect to framebuffer driver */
-	fb_info.phone = service_connect_blocking(SERVICE_VIDEO, 0, 0);
+	fb_info.phone = service_obsolete_connect_blocking(SERVICE_VIDEO, 0, 0);
 	if (fb_info.phone < 0) {
-		printf(NAME ": Failed to connect to video service\n");
-		return -1;
+		printf("%s: Failed to connect to video service\n", NAME);
+		return false;
 	}
 	
@@ -895,5 +901,5 @@
 	int rc = devmap_driver_register(NAME, client_connection);
 	if (rc < 0) {
-		printf(NAME ": Unable to register driver (%d)\n", rc);
+		printf("%s: Unable to register driver (%d)\n", NAME, rc);
 		return false;
 	}
@@ -903,7 +909,7 @@
 	
 	/* Synchronize, the gcons could put something in queue */
-	async_req_0_0(fb_info.phone, FB_FLUSH);
-	async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.cols, &fb_info.rows);
-	async_req_0_1(fb_info.phone, FB_GET_COLOR_CAP, &fb_info.color_cap);
+	async_obsolete_req_0_0(fb_info.phone, FB_FLUSH);
+	async_obsolete_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.cols, &fb_info.rows);
+	async_obsolete_req_0_1(fb_info.phone, FB_GET_COLOR_CAP, &fb_info.color_cap);
 	
 	/* Set up shared memory buffer. */
@@ -916,5 +922,5 @@
 	
 	if (interbuffer) {
-		if (async_share_out_start(fb_info.phone, interbuffer,
+		if (async_obsolete_share_out_start(fb_info.phone, interbuffer,
 		    AS_AREA_READ) != EOK) {
 			as_area_destroy(interbuffer);
@@ -931,5 +937,5 @@
 			if (screenbuffer_init(&consoles[i].scr,
 			    fb_info.cols, fb_info.rows) == NULL) {
-				printf(NAME ": Unable to allocate screen buffer %zu\n", i);
+				printf("%s: Unable to allocate screen buffer %zu\n", NAME, i);
 				return false;
 			}
@@ -943,5 +949,5 @@
 			
 			if (devmap_device_register(vc, &consoles[i].devmap_handle) != EOK) {
-				printf(NAME ": Unable to register device %s\n", vc);
+				printf("%s: Unable to register device %s\n", NAME, vc);
 				return false;
 			}
@@ -953,5 +959,5 @@
 	
 	/* Initialize the screen */
-	async_serialize_start();
+	async_obsolete_serialize_start();
 	gcons_redraw_console();
 	set_style(STYLE_NORMAL);
@@ -959,15 +965,15 @@
 	curs_goto(0, 0);
 	curs_visibility(active_console->scr.is_cursor_visible);
-	async_serialize_end();
+	async_obsolete_serialize_end();
 	
 	/* Receive kernel notifications */
 	async_set_interrupt_received(interrupt_received);
 	if (event_subscribe(EVENT_KCONSOLE, 0) != EOK)
-		printf(NAME ": Error registering kconsole notifications\n");
+		printf("%s: Error registering kconsole notifications\n", NAME);
 	
 	/* Start fibril for checking on hot-plugged keyboards. */
 	check_new_devices_in_background(connect_keyboard, "keyboard");
 	check_new_devices_in_background(connect_mouse, "mouse");
-
+	
 	return true;
 }
@@ -987,7 +993,7 @@
 	printf(NAME ": HelenOS Console service\n");
 	
-	if (!console_init(argv[1]))
+	if (!console_srv_init(argv[1]))
 		return -1;
-
+	
 	printf(NAME ": Accepting connections\n");
 	async_manager();
Index: uspace/srv/hid/console/gcons.c
===================================================================
--- uspace/srv/hid/console/gcons.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/console/gcons.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -35,4 +35,5 @@
 #include <ipc/fb.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <stdio.h>
 #include <sys/mman.h>
@@ -115,5 +116,5 @@
 static void vp_switch(int vp)
 {
-	async_msg_1(fbphone, FB_VIEWPORT_SWITCH, vp);
+	async_obsolete_msg_1(fbphone, FB_VIEWPORT_SWITCH, vp);
 }
 
@@ -121,5 +122,5 @@
 static int vp_create(sysarg_t x, sysarg_t y, sysarg_t width, sysarg_t height)
 {
-	return async_req_2_0(fbphone, FB_VIEWPORT_CREATE, (x << 16) | y,
+	return async_obsolete_req_2_0(fbphone, FB_VIEWPORT_CREATE, (x << 16) | y,
 	    (width << 16) | height);
 }
@@ -127,10 +128,10 @@
 static void clear(void)
 {
-	async_msg_0(fbphone, FB_CLEAR);
+	async_obsolete_msg_0(fbphone, FB_CLEAR);
 }
 
 static void set_rgb_color(uint32_t fgcolor, uint32_t bgcolor)
 {
-	async_msg_2(fbphone, FB_SET_RGB_COLOR, fgcolor, bgcolor);
+	async_obsolete_msg_2(fbphone, FB_SET_RGB_COLOR, fgcolor, bgcolor);
 }
 
@@ -138,5 +139,5 @@
 static void tran_putch(wchar_t ch, sysarg_t col, sysarg_t row)
 {
-	async_msg_3(fbphone, FB_PUTCHAR, ch, col, row);
+	async_obsolete_msg_3(fbphone, FB_PUTCHAR, ch, col, row);
 }
 
@@ -149,5 +150,5 @@
 	
 	if (ic_pixmaps[state] != -1)
-		async_msg_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[index],
+		async_obsolete_msg_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[index],
 		    ic_pixmaps[state]);
 	
@@ -177,5 +178,5 @@
 		
 		if (animation != -1)
-			async_msg_1(fbphone, FB_ANIM_START, animation);
+			async_obsolete_msg_1(fbphone, FB_ANIM_START, animation);
 	} else {
 		if (console_state[active_console] == CONS_DISCONNECTED_SEL)
@@ -258,5 +259,5 @@
 {
 	if (animation != -1)
-		async_msg_1(fbphone, FB_ANIM_STOP, animation);
+		async_obsolete_msg_1(fbphone, FB_ANIM_STOP, animation);
 	
 	active_console = KERNEL_CONSOLE;
@@ -294,5 +295,5 @@
 	
 	if (active_console != KERNEL_CONSOLE)
-		async_msg_2(fbphone, FB_POINTER_MOVE, mouse_x, mouse_y);
+		async_obsolete_msg_2(fbphone, FB_POINTER_MOVE, mouse_x, mouse_y);
 }
 
@@ -374,18 +375,18 @@
 	
 	/* Send area */
-	int rc = async_req_1_0(fbphone, FB_PREPARE_SHM, (sysarg_t) shm);
+	int rc = async_obsolete_req_1_0(fbphone, FB_PREPARE_SHM, (sysarg_t) shm);
 	if (rc)
 		goto exit;
 	
-	rc = async_share_out_start(fbphone, shm, PROTO_READ);
+	rc = async_obsolete_share_out_start(fbphone, shm, PROTO_READ);
 	if (rc)
 		goto drop;
 	
 	/* Draw logo */
-	async_msg_2(fbphone, FB_DRAW_PPM, x, y);
+	async_obsolete_msg_2(fbphone, FB_DRAW_PPM, x, y);
 	
 drop:
 	/* Drop area */
-	async_msg_0(fbphone, FB_DROP_SHM);
+	async_obsolete_msg_0(fbphone, FB_DROP_SHM);
 	
 exit:
@@ -436,14 +437,14 @@
 	
 	/* Send area */
-	int rc = async_req_1_0(fbphone, FB_PREPARE_SHM, (sysarg_t) shm);
+	int rc = async_obsolete_req_1_0(fbphone, FB_PREPARE_SHM, (sysarg_t) shm);
 	if (rc)
 		goto exit;
 	
-	rc = async_share_out_start(fbphone, shm, PROTO_READ);
+	rc = async_obsolete_share_out_start(fbphone, shm, PROTO_READ);
 	if (rc)
 		goto drop;
 	
 	/* Obtain pixmap */
-	rc = async_req_0_0(fbphone, FB_SHM2PIXMAP);
+	rc = async_obsolete_req_0_0(fbphone, FB_SHM2PIXMAP);
 	if (rc < 0)
 		goto drop;
@@ -453,5 +454,5 @@
 drop:
 	/* Drop area */
-	async_msg_0(fbphone, FB_DROP_SHM);
+	async_obsolete_msg_0(fbphone, FB_DROP_SHM);
 	
 exit:
@@ -464,5 +465,5 @@
 static void make_anim(void)
 {
-	int an = async_req_1_0(fbphone, FB_ANIM_CREATE,
+	int an = async_obsolete_req_1_0(fbphone, FB_ANIM_CREATE,
 	    cstatus_vp[KERNEL_CONSOLE]);
 	if (an < 0)
@@ -471,19 +472,19 @@
 	int pm = make_pixmap(_binary_gfx_anim_1_ppm_start,
 	    (size_t) &_binary_gfx_anim_1_ppm_size);
-	async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
+	async_obsolete_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
 	
 	pm = make_pixmap(_binary_gfx_anim_2_ppm_start,
 	    (size_t) &_binary_gfx_anim_2_ppm_size);
-	async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
+	async_obsolete_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
 	
 	pm = make_pixmap(_binary_gfx_anim_3_ppm_start,
 	    (size_t) &_binary_gfx_anim_3_ppm_size);
-	async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
+	async_obsolete_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
 	
 	pm = make_pixmap(_binary_gfx_anim_4_ppm_start,
 	    (size_t) &_binary_gfx_anim_4_ppm_size);
-	async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
-	
-	async_msg_1(fbphone, FB_ANIM_START, an);
+	async_obsolete_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
+	
+	async_obsolete_msg_1(fbphone, FB_ANIM_START, an);
 	
 	animation = an;
@@ -495,5 +496,5 @@
 	fbphone = phone;
 	
-	int rc = async_req_0_2(phone, FB_GET_RESOLUTION, &xres, &yres);
+	int rc = async_obsolete_req_0_2(phone, FB_GET_RESOLUTION, &xres, &yres);
 	if (rc)
 		return;
Index: uspace/srv/hid/console/keybuffer.c
===================================================================
--- uspace/srv/hid/console/keybuffer.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/console/keybuffer.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -90,5 +90,5 @@
  *
  */
-void keybuffer_push(keybuffer_t *keybuffer, const console_event_t *ev)
+void keybuffer_push(keybuffer_t *keybuffer, const kbd_event_t *ev)
 {
 	futex_down(&keybuffer_futex);
@@ -110,5 +110,5 @@
  *
  */
-bool keybuffer_pop(keybuffer_t *keybuffer, console_event_t *edst)
+bool keybuffer_pop(keybuffer_t *keybuffer, kbd_event_t *edst)
 {
 	futex_down(&keybuffer_futex);
Index: uspace/srv/hid/console/keybuffer.h
===================================================================
--- uspace/srv/hid/console/keybuffer.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/console/keybuffer.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -46,5 +46,5 @@
 
 typedef struct {
-	console_event_t fifo[KEYBUFFER_SIZE];
+	kbd_event_t fifo[KEYBUFFER_SIZE];
 	size_t head;
 	size_t tail;
@@ -56,6 +56,6 @@
 extern size_t keybuffer_available(keybuffer_t *);
 extern bool keybuffer_empty(keybuffer_t *);
-extern void keybuffer_push(keybuffer_t *, const console_event_t *);
-extern bool keybuffer_pop(keybuffer_t *, console_event_t *);
+extern void keybuffer_push(keybuffer_t *, const kbd_event_t *);
+extern bool keybuffer_pop(keybuffer_t *, kbd_event_t *);
 
 #endif
Index: uspace/srv/hid/fb/ega.c
===================================================================
--- uspace/srv/hid/fb/ega.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/fb/ega.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -52,7 +52,9 @@
 #include <io/screenbuffer.h>
 #include <sys/types.h>
-
 #include "ega.h"
 #include "main.h"
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 #define MAX_SAVED_SCREENS  256
@@ -291,6 +293,5 @@
 		int retval;
 		
-		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
+		if (!IPC_GET_IMETHOD(call)) {
 			client_connected = 0;
 			async_answer_0(callid, EOK);
@@ -298,4 +299,7 @@
 			/* Exit thread */
 			return;
+		}
+		
+		switch (IPC_GET_IMETHOD(call)) {
 		case IPC_M_SHARE_OUT:
 			/* We accept one area for data interchange */
Index: uspace/srv/hid/fb/fb.c
===================================================================
--- uspace/srv/hid/fb/fb.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/fb/fb.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -59,12 +59,13 @@
 #include <byteorder.h>
 #include <io/screenbuffer.h>
-
 #include "font-8x16.h"
 #include "fb.h"
 #include "main.h"
 #include "ppm.h"
-
 #include "pointer.xbm"
 #include "pointer_mask.xbm"
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 #define DEFAULT_BGCOLOR  0xf0f0f0
@@ -1620,6 +1621,5 @@
 			continue;
 		
-		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
+		if (!IPC_GET_IMETHOD(call)) {
 			client_connected = false;
 			
@@ -1630,5 +1630,7 @@
 			/* Exit thread */
 			return;
+		}
 		
+		switch (IPC_GET_IMETHOD(call)) {
 		case FB_PUTCHAR:
 			ch = IPC_GET_ARG1(call);
Index: uspace/srv/hid/fb/main.c
===================================================================
--- uspace/srv/hid/fb/main.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/fb/main.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -28,5 +28,5 @@
 
 #include <ipc/services.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <sysinfo.h>
 #include <async.h>
Index: uspace/srv/hid/fb/serial_console.c
===================================================================
--- uspace/srv/hid/fb/serial_console.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/fb/serial_console.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -52,4 +52,7 @@
 #include "serial_console.h"
 
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
+
 #define MAX_CONTROL 20
 
@@ -344,6 +347,5 @@
 		int retval;
 		
-		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
+		if (!IPC_GET_IMETHOD(call)) {
 			client_connected = 0;
 			async_answer_0(callid, EOK);
@@ -351,4 +353,7 @@
 			/* Exit thread */
 			return;
+		}
+		
+		switch (IPC_GET_IMETHOD(call)) {
 		case IPC_M_SHARE_OUT:
 			/* We accept one area for data interchange */
Index: uspace/srv/hid/kbd/ctl/apple.c
===================================================================
--- uspace/srv/hid/kbd/ctl/apple.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/kbd/ctl/apple.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -52,5 +52,5 @@
 void kbd_ctl_parse_scancode(int scancode)
 {
-	console_ev_type_t type;
+	kbd_event_type_t type;
 	unsigned int key;
 
Index: uspace/srv/hid/kbd/ctl/pc.c
===================================================================
--- uspace/srv/hid/kbd/ctl/pc.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/kbd/ctl/pc.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -205,5 +205,5 @@
 void kbd_ctl_parse_scancode(int scancode)
 {
-	console_ev_type_t type;
+	kbd_event_type_t type;
 	unsigned int key;
 	int *map;
Index: uspace/srv/hid/kbd/ctl/sun.c
===================================================================
--- uspace/srv/hid/kbd/ctl/sun.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/kbd/ctl/sun.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -53,5 +53,5 @@
 void kbd_ctl_parse_scancode(int scancode)
 {
-	console_ev_type_t type;
+	kbd_event_type_t type;
 	unsigned int key;
 
Index: uspace/srv/hid/kbd/generic/kbd.c
===================================================================
--- uspace/srv/hid/kbd/generic/kbd.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/kbd/generic/kbd.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -43,6 +43,8 @@
 #include <stdlib.h>
 #include <stdio.h>
-#include <ipc/ns.h>
+#include <ns.h>
+#include <ns_obsolete.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <errno.h>
 #include <adt/fifo.h>
@@ -50,9 +52,11 @@
 #include <io/keycode.h>
 #include <devmap.h>
-
 #include <kbd.h>
 #include <kbd_port.h>
 #include <kbd_ctl.h>
 #include <layout.h>
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 #define NAME       "kbd"
@@ -88,5 +92,5 @@
 void kbd_push_ev(int type, unsigned int key)
 {
-	console_event_t ev;
+	kbd_event_t ev;
 	unsigned mod_mask;
 
@@ -163,5 +167,5 @@
 	ev.c = layout[active_layout]->parse_ev(&ev);
 
-	async_msg_4(client_phone, KBD_EVENT, ev.type, ev.key, ev.mods, ev.c);
+	async_obsolete_msg_4(client_phone, KBD_EVENT, ev.type, ev.key, ev.mods, ev.c);
 }
 
@@ -174,10 +178,10 @@
 	async_answer_0(iid, EOK);
 
-	while (1) {
+	while (true) {
 		callid = async_get_call(&call);
-		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
+		
+		if (!IPC_GET_IMETHOD(call)) {
 			if (client_phone != -1) {
-				async_hangup(client_phone);
+				async_obsolete_hangup(client_phone);
 				client_phone = -1;
 			}
@@ -185,4 +189,7 @@
 			async_answer_0(callid, EOK);
 			return;
+		}
+		
+		switch (IPC_GET_IMETHOD(call)) {
 		case IPC_M_CONNECT_TO_ME:
 			if (client_phone != -1) {
@@ -222,5 +229,5 @@
 	if (irc_service) {
 		while (irc_phone < 0)
-			irc_phone = service_connect_blocking(SERVICE_IRC, 0, 0);
+			irc_phone = service_obsolete_connect_blocking(SERVICE_IRC, 0, 0);
 	}
 	
Index: uspace/srv/hid/kbd/include/layout.h
===================================================================
--- uspace/srv/hid/kbd/include/layout.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/kbd/include/layout.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -43,5 +43,5 @@
 typedef struct {
 	void (*reset)(void);
-	wchar_t (*parse_ev)(console_event_t *);
+	wchar_t (*parse_ev)(kbd_event_t *);
 } layout_op_t;
 
Index: uspace/srv/hid/kbd/layout/cz.c
===================================================================
--- uspace/srv/hid/kbd/layout/cz.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/kbd/layout/cz.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -39,5 +39,5 @@
 
 static void layout_reset(void);
-static wchar_t layout_parse_ev(console_event_t *ev);
+static wchar_t layout_parse_ev(kbd_event_t *ev);
 
 enum m_state {
@@ -273,5 +273,5 @@
 }
 
-static wchar_t parse_ms_hacek(console_event_t *ev)
+static wchar_t parse_ms_hacek(kbd_event_t *ev)
 {
 	wchar_t c;
@@ -291,5 +291,5 @@
 }
 
-static wchar_t parse_ms_carka(console_event_t *ev)
+static wchar_t parse_ms_carka(kbd_event_t *ev)
 {
 	wchar_t c;
@@ -309,5 +309,5 @@
 }
 
-static wchar_t parse_ms_start(console_event_t *ev)
+static wchar_t parse_ms_start(kbd_event_t *ev)
 {
 	wchar_t c;
@@ -384,5 +384,5 @@
 }
 
-static wchar_t layout_parse_ev(console_event_t *ev)
+static wchar_t layout_parse_ev(kbd_event_t *ev)
 {
 	if (ev->type != KEY_PRESS)
Index: uspace/srv/hid/kbd/layout/us_dvorak.c
===================================================================
--- uspace/srv/hid/kbd/layout/us_dvorak.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/kbd/layout/us_dvorak.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -38,5 +38,5 @@
 
 static void layout_reset(void);
-static wchar_t layout_parse_ev(console_event_t *ev);
+static wchar_t layout_parse_ev(kbd_event_t *ev);
 
 layout_op_t us_dvorak_op = {
@@ -210,5 +210,5 @@
 }
 
-static wchar_t layout_parse_ev(console_event_t *ev)
+static wchar_t layout_parse_ev(kbd_event_t *ev)
 {
 	wchar_t c;
Index: uspace/srv/hid/kbd/layout/us_qwerty.c
===================================================================
--- uspace/srv/hid/kbd/layout/us_qwerty.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/kbd/layout/us_qwerty.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -38,5 +38,5 @@
 
 static void layout_reset(void);
-static wchar_t layout_parse_ev(console_event_t *ev);
+static wchar_t layout_parse_ev(kbd_event_t *ev);
 
 layout_op_t us_qwerty_op = {
@@ -204,5 +204,5 @@
 }
 
-static wchar_t layout_parse_ev(console_event_t *ev)
+static wchar_t layout_parse_ev(kbd_event_t *ev)
 {
 	wchar_t c;
Index: uspace/srv/hid/kbd/port/adb.c
===================================================================
--- uspace/srv/hid/kbd/port/adb.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/kbd/port/adb.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -30,5 +30,5 @@
  * @ingroup kbd
  * @{
- */ 
+ */
 /** @file
  * @brief ADB keyboard port driver.
@@ -37,4 +37,5 @@
 #include <ipc/adb.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <kbd_port.h>
 #include <kbd.h>
@@ -42,4 +43,6 @@
 #include <fcntl.h>
 #include <errno.h>
+#include <devmap.h>
+#include <devmap_obsolete.h>
 
 static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall);
@@ -52,28 +55,25 @@
 int kbd_port_init(void)
 {
-	const char *input = "/dev/adb/kbd";
-	int input_fd;
-
-	printf(NAME ": open %s\n", input);
-
-	input_fd = open(input, O_RDONLY);
-	if (input_fd < 0) {
-		printf(NAME ": Failed opening %s (%d)\n", input, input_fd);
-		return false;
+	const char *dev = "adb/kbd";
+	devmap_handle_t handle;
+	
+	int rc = devmap_device_get_handle(dev, &handle, 0);
+	if (rc == EOK) {
+		dev_phone = devmap_obsolete_device_connect(handle, 0);
+		if (dev_phone < 0) {
+			printf("%s: Failed to connect to device\n", NAME);
+			return dev_phone;
+		}
+	} else
+		return rc;
+	
+	/* NB: The callback connection is slotted for removal */
+	rc = async_obsolete_connect_to_me(dev_phone, 0, 0, 0, kbd_port_events);
+	if (rc != EOK) {
+		printf(NAME ": Failed to create callback from device\n");
+		return rc;
 	}
-
-	dev_phone = fd_phone(input_fd);
-	if (dev_phone < 0) {
-		printf(NAME ": Failed to connect to device\n");
-		return false;
-	}
-
-	/* NB: The callback connection is slotted for removal */
-	if (async_connect_to_me(dev_phone, 0, 0, 0, kbd_port_events) != 0) {
-		printf(NAME ": Failed to create callback from device\n");
-		return false;
-	}
-
-	return 0;
+	
+	return EOK;
 }
 
@@ -100,9 +100,11 @@
 
 		int retval;
-
-		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
+		
+		if (!IPC_GET_IMETHOD(call)) {
 			/* TODO: Handle hangup */
 			return;
+		}
+		
+		switch (IPC_GET_IMETHOD(call)) {
 		case ADB_REG_NOTIF:
 			adb_kbd_reg0_data(IPC_GET_ARG1(call));
Index: uspace/srv/hid/kbd/port/chardev.c
===================================================================
--- uspace/srv/hid/kbd/port/chardev.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/kbd/port/chardev.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -30,5 +30,5 @@
  * @ingroup kbd
  * @{
- */ 
+ */
 /** @file
  * @brief Chardev keyboard port driver.
@@ -37,10 +37,13 @@
 #include <ipc/char.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <kbd_port.h>
 #include <kbd.h>
-#include <vfs/vfs.h>
-#include <sys/stat.h>
-#include <fcntl.h>
+#include <devmap.h>
+#include <devmap_obsolete.h>
 #include <errno.h>
+#include <stdio.h>
+
+#define NAME  "kbd/chardev"
 
 static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall);
@@ -48,47 +51,37 @@
 static int dev_phone;
 
-#define NAME "kbd"
-
 /** List of devices to try connecting to. */
 static const char *in_devs[] = {
-	"/dev/char/ps2a",
-	"/dev/char/s3c24ser"
+	"char/ps2a",
+	"char/s3c24ser"
 };
 
-static const int num_devs = sizeof(in_devs) / sizeof(in_devs[0]);
+static const unsigned int num_devs = sizeof(in_devs) / sizeof(in_devs[0]);
 
 int kbd_port_init(void)
 {
-	int input_fd;
-	int i;
-
-	input_fd = -1;
+	devmap_handle_t handle;
+	unsigned int i;
+	int rc;
+	
 	for (i = 0; i < num_devs; i++) {
-		struct stat s;
-
-		if (stat(in_devs[i], &s) == EOK)
+		rc = devmap_device_get_handle(in_devs[i], &handle, 0);
+		if (rc == EOK)
 			break;
 	}
-
+	
 	if (i >= num_devs) {
-		printf(NAME ": Could not find any suitable input device.\n");
+		printf("%s: Could not find any suitable input device\n", NAME);
 		return -1;
 	}
-
-	input_fd = open(in_devs[i], O_RDONLY);
-	if (input_fd < 0) {
-		printf(NAME ": failed opening device %s (%d).\n", in_devs[i],
-		    input_fd);
-		return -1;
+	
+	dev_phone = devmap_obsolete_device_connect(handle, IPC_FLAG_BLOCKING);
+	if (dev_phone < 0) {
+		printf("%s: Failed connecting to device\n", NAME);
+		return ENOENT;
 	}
-
-	dev_phone = fd_phone(input_fd);
-	if (dev_phone < 0) {
-		printf(NAME ": Failed connecting to device\n");
-		return -1;
-	}
-
+	
 	/* NB: The callback connection is slotted for removal */
-	if (async_connect_to_me(dev_phone, 0, 0, 0, kbd_port_events) != 0) {
+	if (async_obsolete_connect_to_me(dev_phone, 0, 0, 0, kbd_port_events) != 0) {
 		printf(NAME ": Failed to create callback from device\n");
 		return -1;
@@ -108,5 +101,5 @@
 void kbd_port_write(uint8_t data)
 {
-	async_msg_1(dev_phone, CHAR_WRITE_BYTE, data);
+	async_obsolete_msg_1(dev_phone, CHAR_WRITE_BYTE, data);
 }
 
@@ -118,11 +111,13 @@
 		ipc_call_t call;
 		ipc_callid_t callid = async_get_call(&call);
+		
+		if (!IPC_GET_IMETHOD(call)) {
+			/* TODO: Handle hangup */
+			return;
+		}
 
 		int retval;
 
 		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			/* TODO: Handle hangup */
-			return;
 		case CHAR_NOTIF_BYTE:
 			kbd_push_scancode(IPC_GET_ARG1(call));
Index: uspace/srv/hid/kbd/port/ns16550.c
===================================================================
--- uspace/srv/hid/kbd/port/ns16550.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/kbd/port/ns16550.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -37,4 +37,5 @@
 #include <ipc/irc.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <sysinfo.h>
 #include <kbd.h>
@@ -121,5 +122,5 @@
 	
 	if (irc_service)
-		async_msg_1(irc_phone, IRC_CLEAR_INTERRUPT,
+		async_obsolete_msg_1(irc_phone, IRC_CLEAR_INTERRUPT,
 		    IPC_GET_IMETHOD(*call));
 }
Index: uspace/srv/hid/kbd/port/z8530.c
===================================================================
--- uspace/srv/hid/kbd/port/z8530.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/kbd/port/z8530.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -37,4 +37,5 @@
 #include <ipc/irc.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <sysinfo.h>
 #include <kbd.h>
@@ -109,5 +110,5 @@
 	
 	if (irc_service)
-		async_msg_1(irc_phone, IRC_CLEAR_INTERRUPT,
+		async_obsolete_msg_1(irc_phone, IRC_CLEAR_INTERRUPT,
 		    IPC_GET_IMETHOD(*call));
 }
Index: uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c
===================================================================
--- uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -44,4 +44,5 @@
 #include <ipc/mouse.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <unistd.h>
 #include <stdio.h>
@@ -50,6 +51,8 @@
 #include <errno.h>
 #include <inttypes.h>
-
 #include "s3c24xx_ts.h"
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 #define NAME "s3c24ser"
@@ -280,5 +283,5 @@
 	button = 1;
 	press = 0;
-	async_msg_2(ts->client_phone, MEVENT_BUTTON, button, press);
+	async_obsolete_msg_2(ts->client_phone, MEVENT_BUTTON, button, press);
 
 	s3c24xx_ts_wait_for_int_mode(ts, updn_down);
@@ -321,6 +324,6 @@
 
 	/* Send notifications to client. */
-	async_msg_2(ts->client_phone, MEVENT_MOVE, dx, dy);
-	async_msg_2(ts->client_phone, MEVENT_BUTTON, button, press);
+	async_obsolete_msg_2(ts->client_phone, MEVENT_MOVE, dx, dy);
+	async_obsolete_msg_2(ts->client_phone, MEVENT_BUTTON, button, press);
 
 	ts->last_x = x_pos;
@@ -380,8 +383,8 @@
 	while (1) {
 		callid = async_get_call(&call);
-		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
+		
+		if (!IPC_GET_IMETHOD(call)) {
 			if (ts->client_phone != -1) {
-				async_hangup(ts->client_phone);
+				async_obsolete_hangup(ts->client_phone);
 				ts->client_phone = -1;
 			}
@@ -389,4 +392,7 @@
 			async_answer_0(callid, EOK);
 			return;
+		}
+		
+		switch (IPC_GET_IMETHOD(call)) {
 		case IPC_M_CONNECT_TO_ME:
 			if (ts->client_phone != -1) {
Index: uspace/srv/hw/bus/cuda_adb/cuda_adb.c
===================================================================
--- uspace/srv/hw/bus/cuda_adb/cuda_adb.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hw/bus/cuda_adb/cuda_adb.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -48,6 +48,10 @@
 #include <ipc/adb.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <assert.h>
 #include "cuda_adb.h"
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 #define NAME "cuda_adb"
@@ -219,9 +223,12 @@
 		callid = async_get_call(&call);
 		method = IPC_GET_IMETHOD(call);
-		switch (method) {
-		case IPC_M_PHONE_HUNGUP:
+		
+		if (!method) {
 			/* The other side has hung up. */
 			async_answer_0(callid, EOK);
 			return;
+		}
+		
+		switch (method) {
 		case IPC_M_CONNECT_TO_ME:
 			if (adb_dev[dev_addr].client_phone != -1) {
@@ -479,5 +486,5 @@
 		return;
 
-	async_msg_1(adb_dev[dev_addr].client_phone, ADB_REG_NOTIF, reg_val);
+	async_obsolete_msg_1(adb_dev[dev_addr].client_phone, ADB_REG_NOTIF, reg_val);
 }
 
Index: uspace/srv/hw/char/i8042/i8042.c
===================================================================
--- uspace/srv/hw/char/i8042/i8042.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hw/char/i8042/i8042.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -41,4 +41,5 @@
 #include <devmap.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <unistd.h>
 #include <sysinfo.h>
@@ -46,6 +47,8 @@
 #include <errno.h>
 #include <inttypes.h>
-
 #include "i8042.h"
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 #define NAME "i8042"
@@ -247,9 +250,12 @@
 		callid = async_get_call(&call);
 		method = IPC_GET_IMETHOD(call);
-		switch (method) {
-		case IPC_M_PHONE_HUNGUP:
+		
+		if (!method) {
 			/* The other side has hung up. */
 			async_answer_0(callid, EOK);
 			return;
+		}
+		
+		switch (method) {
 		case IPC_M_CONNECT_TO_ME:
 			printf(NAME ": creating callback connection\n");
@@ -300,5 +306,5 @@
 
 	if (i8042_port[devid].client_phone != -1) {
-		async_msg_1(i8042_port[devid].client_phone,
+		async_obsolete_msg_1(i8042_port[devid].client_phone,
 		    IPC_FIRST_USER_METHOD, data);
 	}
Index: uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c
===================================================================
--- uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -42,4 +42,5 @@
 #include <ipc/char.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <unistd.h>
 #include <stdio.h>
@@ -48,6 +49,8 @@
 #include <errno.h>
 #include <inttypes.h>
-
 #include "s3c24xx_uart.h"
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 #define NAME "s3c24ser"
@@ -123,9 +126,12 @@
 		callid = async_get_call(&call);
 		method = IPC_GET_IMETHOD(call);
-		switch (method) {
-		case IPC_M_PHONE_HUNGUP:
+		
+		if (!method) {
 			/* The other side has hung up. */
 			async_answer_0(callid, EOK);
 			return;
+		}
+		
+		switch (method) {
 		case IPC_M_CONNECT_TO_ME:
 			printf(NAME ": creating callback connection\n");
@@ -156,5 +162,5 @@
 
 		if (uart->client_phone != -1) {
-			async_msg_1(uart->client_phone, CHAR_NOTIF_BYTE,
+			async_obsolete_msg_1(uart->client_phone, CHAR_NOTIF_BYTE,
 			    data);
 		}
Index: uspace/srv/hw/irc/apic/apic.c
===================================================================
--- uspace/srv/hw/irc/apic/apic.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hw/irc/apic/apic.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -38,5 +38,5 @@
 #include <ipc/services.h>
 #include <ipc/irc.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <sysinfo.h>
 #include <as.h>
@@ -79,4 +79,10 @@
 		callid = async_get_call(&call);
 		
+		if (!IPC_GET_IMETHOD(call)) {
+			/* The other side has hung up. */
+			async_answer_0(callid, EOK);
+			return;
+		}
+		
 		switch (IPC_GET_IMETHOD(call)) {
 		case IRC_ENABLE_INTERRUPT:
@@ -87,8 +93,4 @@
 			async_answer_0(callid, EOK);
 			break;
-		case IPC_M_PHONE_HUNGUP:
-			/* The other side has hung up. */
-			async_answer_0(callid, EOK);
-			return;
 		default:
 			async_answer_0(callid, EINVAL);
@@ -106,5 +108,5 @@
 	
 	if ((sysinfo_get_value("apic", &apic) != EOK) || (!apic)) {
-		printf(NAME ": No APIC found\n");
+		printf("%s: No APIC found\n", NAME);
 		return false;
 	}
@@ -118,10 +120,11 @@
 int main(int argc, char **argv)
 {
-	printf(NAME ": HelenOS APIC driver\n");
+	printf("%s: HelenOS APIC driver\n", NAME);
 	
 	if (!apic_init())
 		return -1;
 	
-	printf(NAME ": Accepting connections\n");
+	printf("%s: Accepting connections\n", NAME);
+	task_retval(0);
 	async_manager();
 	
Index: uspace/srv/hw/irc/fhc/fhc.c
===================================================================
--- uspace/srv/hw/irc/fhc/fhc.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hw/irc/fhc/fhc.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -38,5 +38,5 @@
 #include <ipc/services.h>
 #include <ipc/irc.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <sysinfo.h>
 #include <as.h>
@@ -53,5 +53,5 @@
 #define NAME "fhc"
 
-#define FHC_UART_INR	0x39	
+#define FHC_UART_INR	0x39
 
 #define FHC_UART_IMAP	0x0
@@ -128,10 +128,10 @@
 	
 	if (retval < 0) {
-		printf(NAME ": Error mapping FHC UART registers\n");
+		printf("%s: Error mapping FHC UART registers\n", NAME);
 		return false;
 	}
 	
-	printf(NAME ": FHC UART registers at %p, %zu bytes\n", fhc_uart_phys,
-	    fhc_uart_size);
+	printf("%s: FHC UART registers at %p, %zu bytes\n", NAME,
+	    fhc_uart_phys, fhc_uart_size);
 	
 	async_set_client_connection(fhc_connection);
@@ -143,12 +143,13 @@
 int main(int argc, char **argv)
 {
-	printf(NAME ": HelenOS FHC bus controller driver\n");
+	printf("%s: HelenOS FHC bus controller driver\n", NAME);
 	
 	if (!fhc_init())
 		return -1;
 	
-	printf(NAME ": Accepting connections\n");
+	printf("%s: Accepting connections\n", NAME);
+	task_retval(0);
 	async_manager();
-
+	
 	/* Never reached */
 	return 0;
@@ -157,3 +158,3 @@
 /**
  * @}
- */ 
+ */
Index: uspace/srv/hw/irc/i8259/i8259.c
===================================================================
--- uspace/srv/hw/irc/i8259/i8259.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hw/irc/i8259/i8259.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -38,5 +38,5 @@
 #include <ipc/services.h>
 #include <ipc/irc.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <sysinfo.h>
 #include <as.h>
@@ -113,4 +113,10 @@
 		callid = async_get_call(&call);
 		
+		if (!IPC_GET_IMETHOD(call)) {
+			/* The other side has hung up. */
+			async_answer_0(callid, EOK);
+			return;
+		}
+		
 		switch (IPC_GET_IMETHOD(call)) {
 		case IRC_ENABLE_INTERRUPT:
@@ -121,8 +127,4 @@
 			async_answer_0(callid, EOK);
 			break;
-		case IPC_M_PHONE_HUNGUP:
-			/* The other side has hung up. */
-			async_answer_0(callid, EOK);
-			return;
 		default:
 			async_answer_0(callid, EINVAL);
@@ -140,5 +142,5 @@
 	
 	if ((sysinfo_get_value("i8259", &i8259) != EOK) || (!i8259)) {
-		printf(NAME ": No i8259 found\n");
+		printf("%s: No i8259 found\n", NAME);
 		return false;
 	}
@@ -148,5 +150,5 @@
 	    (pio_enable((void *) IO_RANGE1_START, IO_RANGE1_SIZE,
 	    (void **) &io_range1) != EOK)) {
-		printf(NAME ": i8259 not accessible\n");
+		printf("%s: i8259 not accessible\n", NAME);
 		return false;
 	}
@@ -160,10 +162,11 @@
 int main(int argc, char **argv)
 {
-	printf(NAME ": HelenOS i8259 driver\n");
+	printf("%s: HelenOS i8259 driver\n", NAME);
 	
 	if (!i8259_init())
 		return -1;
 	
-	printf(NAME ": Accepting connections\n");
+	printf("%s: Accepting connections\n", NAME);
+	task_retval(0);
 	async_manager();
 	
Index: uspace/srv/hw/irc/obio/obio.c
===================================================================
--- uspace/srv/hw/irc/obio/obio.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hw/irc/obio/obio.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -44,5 +44,5 @@
 #include <ipc/services.h>
 #include <ipc/irc.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <sysinfo.h>
 #include <as.h>
@@ -118,5 +118,5 @@
 	
 	if (sysinfo_get_value("obio.base.physical", &paddr) != EOK) {
-		printf(NAME ": no OBIO registers found\n");
+		printf("%s: No OBIO registers found\n", NAME);
 		return false;
 	}
@@ -130,9 +130,9 @@
 	
 	if (retval < 0) {
-		printf(NAME ": Error mapping OBIO registers\n");
+		printf("%s: Error mapping OBIO registers\n", NAME);
 		return false;
 	}
 	
-	printf(NAME ": OBIO registers with base at %p\n", base_phys);
+	printf("%s: OBIO registers with base at %p\n", NAME, base_phys);
 	
 	async_set_client_connection(obio_connection);
@@ -144,12 +144,13 @@
 int main(int argc, char **argv)
 {
-	printf(NAME ": HelenOS OBIO driver\n");
+	printf("%s: HelenOS OBIO driver\n", NAME);
 	
 	if (!obio_init())
 		return -1;
 	
-	printf(NAME ": Accepting connections\n");
+	printf("%s: Accepting connections\n", NAME);
+	task_retval(0);
 	async_manager();
-
+	
 	/* Never reached */
 	return 0;
@@ -158,3 +159,3 @@
 /**
  * @}
- */ 
+ */
Index: uspace/srv/hw/netif/ne2000/ne2000.c
===================================================================
--- uspace/srv/hw/netif/ne2000/ne2000.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/hw/netif/ne2000/ne2000.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -38,4 +38,5 @@
 #include <assert.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <ddi.h>
 #include <errno.h>
@@ -44,5 +45,6 @@
 #include <sysinfo.h>
 #include <ipc/services.h>
-#include <ipc/ns.h>
+#include <ns.h>
+#include <ns_obsolete.h>
 #include <ipc/irc.h>
 #include <net/modules.h>
@@ -330,5 +332,5 @@
 		
 		if (irc_service)
-			async_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, ne2k->irq);
+			async_obsolete_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, ne2k->irq);
 	}
 	
@@ -389,10 +391,10 @@
 	if (irc_service) {
 		while (irc_phone < 0)
-			irc_phone = service_connect_blocking(SERVICE_IRC, 0, 0);
+			irc_phone = service_obsolete_connect_blocking(SERVICE_IRC, 0, 0);
 	}
 	
 	async_set_interrupt_received(irq_handler);
 	
-	return async_connect_to_me(PHONE_NS, SERVICE_NE2000, 0, 0, NULL);
+	return service_register(SERVICE_NE2000);
 }
 
Index: uspace/srv/loader/main.c
===================================================================
--- uspace/srv/loader/main.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/loader/main.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -52,6 +52,5 @@
 #include <ipc/services.h>
 #include <ipc/loader.h>
-#include <ipc/ns.h>
-#include <macros.h>
+#include <ns.h>
 #include <loader/pcb.h>
 #include <entry_point.h>
@@ -60,5 +59,4 @@
 #include <str.h>
 #include <as.h>
-
 #include <elf.h>
 #include <elf_load.h>
@@ -414,8 +412,4 @@
 static void ldr_connection(ipc_callid_t iid, ipc_call_t *icall)
 {
-	ipc_callid_t callid;
-	ipc_call_t call;
-	int retval;
-	
 	/* Already have a connection? */
 	if (connected) {
@@ -430,13 +424,15 @@
 	
 	/* Ignore parameters, the connection is already open */
-	(void) iid;
 	(void) icall;
 	
-	while (1) {
-		callid = async_get_call(&call);
+	while (true) {
+		int retval;
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+		
+		if (!IPC_GET_IMETHOD(call))
+			exit(0);
 		
 		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			exit(0);
 		case LOADER_GET_TASKID:
 			ldr_get_taskid(callid, &call);
@@ -465,6 +461,5 @@
 		}
 		
-		if (IPC_GET_IMETHOD(call) != IPC_M_PHONE_HUNGUP)
-			async_answer_0(callid, retval);
+		async_answer_0(callid, retval);
 	}
 }
@@ -479,5 +474,5 @@
 	/* Introduce this task to the NS (give it our task ID). */
 	task_id_t id = task_get_id();
-	int rc = async_req_2_0(PHONE_NS, NS_ID_INTRO, LOWER32(id), UPPER32(id));
+	int rc = ns_intro(id);
 	if (rc != EOK)
 		return -1;
Index: uspace/srv/net/il/arp/arp.c
===================================================================
--- uspace/srv/net/il/arp/arp.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/net/il/arp/arp.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -845,8 +845,9 @@
 	
 	*count = 0;
+	
+	if (!IPC_GET_IMETHOD(*call))
+		return EOK;
+	
 	switch (IPC_GET_IMETHOD(*call)) {
-	case IPC_M_PHONE_HUNGUP:
-		return EOK;
-	
 	case NET_ARP_DEVICE:
 		rc = measured_strings_receive(&address, &data, 1);
Index: uspace/srv/net/il/ip/ip.c
===================================================================
--- uspace/srv/net/il/ip/ip.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/net/il/ip/ip.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -76,4 +76,7 @@
 #include <il_remote.h>
 #include <il_skel.h>
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 /** IP module name. */
@@ -1913,8 +1916,9 @@
 	
 	*answer_count = 0;
+	
+	if (!IPC_GET_IMETHOD(*call))
+		return EOK;
+	
 	switch (IPC_GET_IMETHOD(*call)) {
-	case IPC_M_PHONE_HUNGUP:
-		return EOK;
-	
 	case IPC_M_CONNECT_TO_ME:
 		return ip_register(IL_GET_PROTO(*call), IL_GET_SERVICE(*call),
Index: uspace/srv/net/net/net.c
===================================================================
--- uspace/srv/net/net/net.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/net/net/net.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -41,4 +41,5 @@
 #include <ctype.h>
 #include <ddi.h>
+#include <ns.h>
 #include <errno.h>
 #include <malloc.h>
@@ -339,5 +340,5 @@
 		goto out;
 	
-	rc = async_connect_to_me(PHONE_NS, SERVICE_NETWORKING, 0, 0, NULL);
+	rc = service_register(SERVICE_NETWORKING);
 	if (rc != EOK)
 		goto out;
@@ -638,7 +639,9 @@
 	
 	*answer_count = 0;
+	
+	if (!IPC_GET_IMETHOD(*call))
+		return EOK;
+	
 	switch (IPC_GET_IMETHOD(*call)) {
-	case IPC_M_PHONE_HUNGUP:
-		return EOK;
 	case NET_NET_GET_DEVICE_CONF:
 		rc = measured_strings_receive(&strings, &data,
@@ -703,5 +706,5 @@
 		
 		/* End if told to either by the message or the processing result */
-		if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))
+		if ((!IPC_GET_IMETHOD(call)) || (res == EHANGUP))
 			return;
 		
Index: uspace/srv/net/netif/lo/lo.c
===================================================================
--- uspace/srv/net/netif/lo/lo.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/net/netif/lo/lo.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -39,4 +39,5 @@
 #include <stdio.h>
 #include <str.h>
+#include <ns.h>
 #include <ipc/services.h>
 #include <ipc/nil.h>
@@ -164,5 +165,5 @@
 int netif_initialize(void)
 {
-	return async_connect_to_me(PHONE_NS, SERVICE_LO, 0, 0, NULL);
+	return service_register(SERVICE_LO);
 }
 
Index: uspace/srv/net/nil/eth/eth.c
===================================================================
--- uspace/srv/net/nil/eth/eth.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/net/nil/eth/eth.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -59,4 +59,7 @@
 #include <packet_remote.h>
 #include <nil_skel.h>
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 #include "eth.h"
@@ -846,8 +849,9 @@
 	
 	*answer_count = 0;
+	
+	if (!IPC_GET_IMETHOD(*call))
+		return EOK;
+	
 	switch (IPC_GET_IMETHOD(*call)) {
-	case IPC_M_PHONE_HUNGUP:
-		return EOK;
-	
 	case NET_NIL_DEVICE:
 		return eth_device_message(IPC_GET_DEVICE(*call),
Index: uspace/srv/net/nil/nildummy/nildummy.c
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/net/nil/nildummy/nildummy.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -54,4 +54,7 @@
 #include <nil_skel.h>
 
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
+
 #include "nildummy.h"
 
@@ -393,8 +396,9 @@
 	
 	*answer_count = 0;
+	
+	if (!IPC_GET_IMETHOD(*call))
+		return EOK;
+	
 	switch (IPC_GET_IMETHOD(*call)) {
-	case IPC_M_PHONE_HUNGUP:
-		return EOK;
-	
 	case NET_NIL_DEVICE:
 		return nildummy_device_message(IPC_GET_DEVICE(*call),
Index: uspace/srv/net/tl/icmp/icmp.c
===================================================================
--- uspace/srv/net/tl/icmp/icmp.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/net/tl/icmp/icmp.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -612,9 +612,11 @@
 static void icmp_receiver(ipc_callid_t iid, ipc_call_t *icall)
 {
-	bool loop = true;
 	packet_t *packet;
 	int rc;
 	
-	while (loop) {
+	while (true) {
+		if (!IPC_GET_IMETHOD(*icall))
+			break;
+		
 		switch (IPC_GET_IMETHOD(*icall)) {
 		case NET_TL_RECEIVED:
@@ -629,7 +631,4 @@
 			async_answer_0(iid, (sysarg_t) rc);
 			break;
-		case IPC_M_PHONE_HUNGUP:
-			loop = false;
-			continue;
 		default:
 			async_answer_0(iid, (sysarg_t) ENOTSUP);
Index: uspace/srv/net/tl/tcp/tcp.c
===================================================================
--- uspace/srv/net/tl/tcp/tcp.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/net/tl/tcp/tcp.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -38,4 +38,5 @@
 #include <assert.h>
 #include <async.h>
+#include <async_obsolete.h>
 #include <fibril_synch.h>
 #include <malloc.h>
@@ -72,4 +73,7 @@
 #include "tcp.h"
 #include "tcp_header.h"
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 /** TCP module name. */
@@ -799,5 +803,5 @@
 
 	/* Notify the destination socket */
-	async_msg_5(socket->phone, NET_SOCKET_RECEIVED,
+	async_obsolete_msg_5(socket->phone, NET_SOCKET_RECEIVED,
 	    (sysarg_t) socket->socket_id,
 	    ((packet_dimension->content < socket_data->data_fragment_size) ?
@@ -820,5 +824,5 @@
 
 	/* Notify the destination socket */
-	async_msg_5(socket->phone, NET_SOCKET_RECEIVED,
+	async_obsolete_msg_5(socket->phone, NET_SOCKET_RECEIVED,
 	    (sysarg_t) socket->socket_id,
 	    0, 0, 0,
@@ -1078,5 +1082,5 @@
 		if (rc == EOK) {
 			/* Notify the destination socket */
-			async_msg_5(socket->phone, NET_SOCKET_ACCEPTED,
+			async_obsolete_msg_5(socket->phone, NET_SOCKET_ACCEPTED,
 			    (sysarg_t) listening_socket->socket_id,
 			    socket_data->data_fragment_size, TCP_HEADER_SIZE,
@@ -1269,5 +1273,4 @@
 {
 	int res;
-	bool keep_on_going = true;
 	socket_cores_t local_sockets;
 	int app_phone = IPC_GET_PHONE(call);
@@ -1293,5 +1296,5 @@
 	fibril_rwlock_initialize(&lock);
 
-	while (keep_on_going) {
+	while (true) {
 
 		/* Answer the call */
@@ -1301,12 +1304,12 @@
 		/* Get the next call */
 		callid = async_get_call(&call);
+		
+		if (!IPC_GET_IMETHOD(call)) {
+			res = EHANGUP;
+			break;
+		}
 
 		/* Process the call */
 		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			keep_on_going = false;
-			res = EHANGUP;
-			break;
-
 		case NET_SOCKET:
 			socket_data =
@@ -1506,5 +1509,5 @@
 
 	/* Release the application phone */
-	async_hangup(app_phone);
+	async_obsolete_hangup(app_phone);
 
 	printf("release\n");
Index: uspace/srv/net/tl/udp/udp.c
===================================================================
--- uspace/srv/net/tl/udp/udp.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/net/tl/udp/udp.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -37,4 +37,5 @@
 
 #include <async.h>
+#include <async_obsolete.h>
 #include <fibril_synch.h>
 #include <malloc.h>
@@ -69,4 +70,7 @@
 #include "udp.h"
 #include "udp_header.h"
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
 
 /** UDP module name. */
@@ -299,5 +303,5 @@
 	/* Notify the destination socket */
 	fibril_rwlock_write_unlock(&udp_globals.lock);
-	async_msg_5(socket->phone, NET_SOCKET_RECEIVED,
+	async_obsolete_msg_5(socket->phone, NET_SOCKET_RECEIVED,
 	    (sysarg_t) socket->socket_id, packet_dimension->content, 0, 0,
 	    (sysarg_t) fragments);
@@ -748,5 +752,4 @@
 {
 	int res;
-	bool keep_on_going = true;
 	socket_cores_t local_sockets;
 	int app_phone = IPC_GET_PHONE(call);
@@ -773,5 +776,5 @@
 	socket_cores_initialize(&local_sockets);
 
-	while (keep_on_going) {
+	while (true) {
 
 		/* Answer the call */
@@ -783,12 +786,12 @@
 		/* Get the next call */
 		callid = async_get_call(&call);
+		
+		if (!IPC_GET_IMETHOD(call)) {
+			res = EHANGUP;
+			break;
+		}
 
 		/* Process the call */
 		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			keep_on_going = false;
-			res = EHANGUP;
-			break;
-
 		case NET_SOCKET:
 			socket_id = SOCKET_GET_SOCKET_ID(call);
@@ -880,5 +883,5 @@
 
 	/* Release the application phone */
-	async_hangup(app_phone);
+	async_obsolete_hangup(app_phone);
 
 	/* Release all local sockets */
Index: uspace/srv/taskmon/taskmon.c
===================================================================
--- uspace/srv/taskmon/taskmon.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/taskmon/taskmon.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -92,14 +92,15 @@
 int main(int argc, char *argv[])
 {
-	printf(NAME ": Task Monitoring Service\n");
-
+	printf("%s: Task Monitoring Service\n", NAME);
+	
 	if (event_subscribe(EVENT_FAULT, 0) != EOK) {
-		printf(NAME ": Error registering fault notifications.\n");
+		printf("%s: Error registering fault notifications.\n", NAME);
 		return -1;
 	}
-
+	
 	async_set_interrupt_received(fault_event);
+	task_retval(0);
 	async_manager();
-
+	
 	return 0;
 }
Index: uspace/srv/vfs/vfs.c
===================================================================
--- uspace/srv/vfs/vfs.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/vfs/vfs.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -37,5 +37,5 @@
 
 #include <ipc/services.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <async.h>
 #include <errno.h>
@@ -51,6 +51,6 @@
 static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall)
 {
-	bool keep_on_going = true;
-
+	bool cont = true;
+	
 	/*
 	 * The connection was opened via the IPC_CONNECT_ME_TO call.
@@ -59,15 +59,15 @@
 	async_answer_0(iid, EOK);
 	
-	while (keep_on_going) {
+	while (cont) {
 		ipc_call_t call;
 		ipc_callid_t callid = async_get_call(&call);
 		
+		if (!IPC_GET_IMETHOD(call))
+			break;
+		
 		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_PHONE_HUNGUP:
-			keep_on_going = false;
-			break;
 		case VFS_IN_REGISTER:
 			vfs_register(callid, &call);
-			keep_on_going = false;
+			cont = false;
 			break;
 		case VFS_IN_MOUNT:
@@ -123,5 +123,5 @@
 		}
 	}
-
+	
 	/*
 	 * Open files for this client will be cleaned up when its last
Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/vfs/vfs.h	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -53,5 +53,5 @@
 	vfs_info_t vfs_info;
 	fs_handle_t fs_handle;
-	async_sess_t session;
+	async_sess_t *sess;
 } fs_info_t;
 
@@ -167,6 +167,6 @@
 extern fibril_rwlock_t namespace_rwlock;
 
-extern int vfs_grab_phone(fs_handle_t);
-extern void vfs_release_phone(fs_handle_t, int);
+extern async_exch_t *vfs_exchange_grab(fs_handle_t);
+extern void vfs_exchange_release(async_exch_t *);
 
 extern fs_handle_t fs_name_to_handle(char *, bool);
Index: uspace/srv/vfs/vfs_file.c
===================================================================
--- uspace/srv/vfs/vfs_file.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/vfs/vfs_file.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -45,5 +45,5 @@
 #include "vfs.h"
 
-#define VFS_DATA	((vfs_client_data_t *) async_client_data_get())
+#define VFS_DATA	((vfs_client_data_t *) async_get_client_data())
 #define FILES		(VFS_DATA->files)
 
@@ -110,20 +110,19 @@
 static int vfs_file_close_remote(vfs_file_t *file)
 {
+	assert(!file->refcnt);
+	
+	async_exch_t *exch = vfs_exchange_grab(file->node->fs_handle);
+	
 	ipc_call_t answer;
-	aid_t msg;
+	aid_t msg = async_send_2(exch, VFS_OUT_CLOSE, file->node->devmap_handle,
+	    file->node->index, &answer);
+	
+	vfs_exchange_release(exch);
+	
 	sysarg_t rc;
-	int phone;
-
-	assert(!file->refcnt);
-
-	phone = vfs_grab_phone(file->node->fs_handle);
-	msg = async_send_2(phone, VFS_OUT_CLOSE, file->node->devmap_handle,
-	    file->node->index, &answer);
 	async_wait_for(msg, &rc);
-	vfs_release_phone(file->node->fs_handle, phone);
-
+	
 	return IPC_GET_ARG1(answer);
 }
-
 
 /** Increment reference count of VFS file structure.
Index: uspace/srv/vfs/vfs_lookup.c
===================================================================
--- uspace/srv/vfs/vfs_lookup.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/vfs/vfs_lookup.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -159,6 +159,6 @@
 
 	ipc_call_t answer;
-	int phone = vfs_grab_phone(root->fs_handle);
-	aid_t req = async_send_5(phone, VFS_OUT_LOOKUP, (sysarg_t) first,
+	async_exch_t *exch = vfs_exchange_grab(root->fs_handle);
+	aid_t req = async_send_5(exch, VFS_OUT_LOOKUP, (sysarg_t) first,
 	    (sysarg_t) (first + len - 1) % PLB_SIZE,
 	    (sysarg_t) root->devmap_handle, (sysarg_t) lflag, (sysarg_t) index,
@@ -167,5 +167,5 @@
 	sysarg_t rc;
 	async_wait_for(req, &rc);
-	vfs_release_phone(root->fs_handle, phone);
+	vfs_exchange_release(exch);
 	
 	fibril_mutex_lock(&plb_mutex);
@@ -208,8 +208,8 @@
 int vfs_open_node_internal(vfs_lookup_res_t *result)
 {
-	int phone = vfs_grab_phone(result->triplet.fs_handle);
+	async_exch_t *exch = vfs_exchange_grab(result->triplet.fs_handle);
 	
 	ipc_call_t answer;
-	aid_t req = async_send_2(phone, VFS_OUT_OPEN_NODE,
+	aid_t req = async_send_2(exch, VFS_OUT_OPEN_NODE,
 	    (sysarg_t) result->triplet.devmap_handle,
 	    (sysarg_t) result->triplet.index, &answer);
@@ -217,5 +217,5 @@
 	sysarg_t rc;
 	async_wait_for(req, &rc);
-	vfs_release_phone(result->triplet.fs_handle, phone);
+	vfs_exchange_release(exch);
 	
 	if (rc == EOK) {
Index: uspace/srv/vfs/vfs_node.c
===================================================================
--- uspace/srv/vfs/vfs_node.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/vfs/vfs_node.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -104,11 +104,14 @@
 	bool free_vfs_node = false;
 	bool free_fs_node = false;
-
-	fibril_mutex_lock(&nodes_mutex);
+	
+	fibril_mutex_lock(&nodes_mutex);
+	
 	if (node->refcnt-- == 1) {
+		
 		/*
 		 * We are dropping the last reference to this node.
 		 * Remove it from the VFS node hash table.
 		 */
+		
 		unsigned long key[] = {
 			[KEY_FS_HANDLE] = node->fs_handle,
@@ -116,23 +119,29 @@
 			[KEY_INDEX] = node->index
 		};
+		
 		hash_table_remove(&nodes, key, 3);
 		free_vfs_node = true;
+		
 		if (!node->lnkcnt)
 			free_fs_node = true;
 	}
-	fibril_mutex_unlock(&nodes_mutex);
-
+	
+	fibril_mutex_unlock(&nodes_mutex);
+	
 	if (free_fs_node) {
-		/* 
+		
+		/*
 		 * The node is not visible in the file system namespace.
 		 * Free up its resources.
 		 */
-		int phone = vfs_grab_phone(node->fs_handle);
-		sysarg_t rc;
-		rc = async_req_2_0(phone, VFS_OUT_DESTROY,
-		    (sysarg_t)node->devmap_handle, (sysarg_t)node->index);
+		
+		async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
+		sysarg_t rc = async_req_2_0(exch, VFS_OUT_DESTROY,
+		    (sysarg_t) node->devmap_handle, (sysarg_t)node->index);
+		
 		assert(rc == EOK);
-		vfs_release_phone(node->fs_handle, phone);
+		vfs_exchange_release(exch);
 	}
+	
 	if (free_vfs_node)
 		free(node);
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/vfs/vfs_ops.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -78,6 +78,6 @@
 	size_t rsize;
 	unsigned rlnkcnt;
+	async_exch_t *exch;
 	sysarg_t rc;
-	int phone;
 	aid_t msg;
 	ipc_call_t answer;
@@ -123,13 +123,14 @@
 			
 			/* Tell the mountee that it is being mounted. */
-			phone = vfs_grab_phone(fs_handle);
-			msg = async_send_1(phone, VFS_OUT_MOUNTED,
+			exch = vfs_exchange_grab(fs_handle);
+			msg = async_send_1(exch, VFS_OUT_MOUNTED,
 			    (sysarg_t) devmap_handle, &answer);
-			/* send the mount options */
-			rc = async_data_write_start(phone, (void *)opts,
+			/* Send the mount options */
+			rc = async_data_write_start(exch, (void *)opts,
 			    str_size(opts));
+			vfs_exchange_release(exch);
+			
 			if (rc != EOK) {
 				async_wait_for(msg, NULL);
-				vfs_release_phone(fs_handle, phone);
 				fibril_rwlock_write_unlock(&namespace_rwlock);
 				async_answer_0(rid, rc);
@@ -137,5 +138,4 @@
 			}
 			async_wait_for(msg, &rc);
-			vfs_release_phone(fs_handle, phone);
 			
 			if (rc != EOK) {
@@ -182,9 +182,9 @@
 	 */
 	
-	int mountee_phone = vfs_grab_phone(fs_handle);
-	assert(mountee_phone >= 0);
-
-	phone = vfs_grab_phone(mp_res.triplet.fs_handle);
-	msg = async_send_4(phone, VFS_OUT_MOUNT,
+	async_exch_t *mountee_exch = vfs_exchange_grab(fs_handle);
+	assert(mountee_exch);
+	
+	exch = vfs_exchange_grab(mp_res.triplet.fs_handle);
+	msg = async_send_4(exch, VFS_OUT_MOUNT,
 	    (sysarg_t) mp_res.triplet.devmap_handle,
 	    (sysarg_t) mp_res.triplet.index,
@@ -192,34 +192,38 @@
 	    (sysarg_t) devmap_handle, &answer);
 	
-	/* send connection */
-	rc = async_req_1_0(phone, IPC_M_CONNECTION_CLONE, mountee_phone);
-	if (rc != EOK) {
+	/* Send connection */
+	rc = async_exchange_clone(exch, mountee_exch);
+	vfs_exchange_release(mountee_exch);
+	
+	if (rc != EOK) {
+		vfs_exchange_release(exch);
 		async_wait_for(msg, NULL);
-		vfs_release_phone(fs_handle, mountee_phone);
-		vfs_release_phone(mp_res.triplet.fs_handle, phone);
+		
 		/* Mount failed, drop reference to mp_node. */
 		if (mp_node)
 			vfs_node_put(mp_node);
-		async_answer_0(rid, rc);
-		fibril_rwlock_write_unlock(&namespace_rwlock);
-		return;
-	}
-
-	vfs_release_phone(fs_handle, mountee_phone);
+		
+		async_answer_0(rid, rc);
+		fibril_rwlock_write_unlock(&namespace_rwlock);
+		return;
+	}
 	
 	/* send the mount options */
-	rc = async_data_write_start(phone, (void *)opts, str_size(opts));
-	if (rc != EOK) {
+	rc = async_data_write_start(exch, (void *) opts, str_size(opts));
+	if (rc != EOK) {
+		vfs_exchange_release(exch);
 		async_wait_for(msg, NULL);
-		vfs_release_phone(mp_res.triplet.fs_handle, phone);
+		
 		/* Mount failed, drop reference to mp_node. */
 		if (mp_node)
 			vfs_node_put(mp_node);
-		fibril_rwlock_write_unlock(&namespace_rwlock);
-		async_answer_0(rid, rc);
-		return;
-	}
+		
+		fibril_rwlock_write_unlock(&namespace_rwlock);
+		async_answer_0(rid, rc);
+		return;
+	}
+	
+	vfs_exchange_release(exch);
 	async_wait_for(msg, &rc);
-	vfs_release_phone(mp_res.triplet.fs_handle, phone);
 	
 	if (rc == EOK) {
@@ -227,5 +231,5 @@
 		rsize = (size_t) IPC_GET_ARG2(answer);
 		rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
-	
+		
 		mr_res.triplet.fs_handle = fs_handle;
 		mr_res.triplet.devmap_handle = devmap_handle;
@@ -234,5 +238,5 @@
 		mr_res.lnkcnt = rlnkcnt;
 		mr_res.type = VFS_NODE_DIRECTORY;
-	
+		
 		/* Add reference to the mounted root. */
 		mr_node = vfs_node_get(&mr_res); 
@@ -243,5 +247,5 @@
 			vfs_node_put(mp_node);
 	}
-
+	
 	async_answer_0(rid, rc);
 	fibril_rwlock_write_unlock(&namespace_rwlock);
@@ -303,10 +307,10 @@
 	
 	/*
-	 * Wait for IPC_M_PING so that we can return an error if we don't know
+	 * Wait for VFS_IN_PING so that we can return an error if we don't know
 	 * fs_name.
 	 */
 	ipc_call_t data;
 	ipc_callid_t callid = async_get_call(&data);
-	if (IPC_GET_IMETHOD(data) != IPC_M_PING) {
+	if (IPC_GET_IMETHOD(data) != VFS_IN_PING) {
 		async_answer_0(callid, ENOTSUP);
 		async_answer_0(rid, ENOTSUP);
@@ -358,6 +362,6 @@
 	vfs_lookup_res_t mr_res;
 	vfs_node_t *mr_node;
-	int phone;
-
+	async_exch_t *exch;
+	
 	/*
 	 * Receive the mount point path.
@@ -367,5 +371,5 @@
 	if (rc != EOK)
 		async_answer_0(rid, rc);
-
+	
 	/*
 	 * Taking the namespace lock will do two things for us. First, it will
@@ -395,5 +399,5 @@
 		return;
 	}
-
+	
 	/*
 	 * Count the total number of references for the mounted file system. We
@@ -411,7 +415,7 @@
 		return;
 	}
-
+	
 	if (str_cmp(mp, "/") == 0) {
-
+		
 		/*
 		 * Unmounting the root file system.
@@ -420,10 +424,12 @@
 		 * VFS_OUT_UNMOUNTED directly to the mounted file system.
 		 */
-
+		
 		free(mp);
-		phone = vfs_grab_phone(mr_node->fs_handle);
-		rc = async_req_1_0(phone, VFS_OUT_UNMOUNTED,
+		
+		exch = vfs_exchange_grab(mr_node->fs_handle);
+		rc = async_req_1_0(exch, VFS_OUT_UNMOUNTED,
 		    mr_node->devmap_handle);
-		vfs_release_phone(mr_node->fs_handle, phone);
+		vfs_exchange_release(exch);
+		
 		if (rc != EOK) {
 			fibril_rwlock_write_unlock(&namespace_rwlock);
@@ -432,8 +438,9 @@
 			return;
 		}
+		
 		rootfs.fs_handle = 0;
 		rootfs.devmap_handle = 0;
 	} else {
-
+		
 		/*
 		 * Unmounting a non-root file system.
@@ -442,5 +449,5 @@
 		 * file system, so we delegate the operation to it.
 		 */
-
+		
 		rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);
 		free(mp);
@@ -451,4 +458,5 @@
 			return;
 		}
+		
 		vfs_node_t *mp_node = vfs_node_get(&mp_res);
 		if (!mp_node) {
@@ -458,9 +466,10 @@
 			return;
 		}
-
-		phone = vfs_grab_phone(mp_node->fs_handle);
-		rc = async_req_2_0(phone, VFS_OUT_UNMOUNT,
+		
+		exch = vfs_exchange_grab(mp_node->fs_handle);
+		rc = async_req_2_0(exch, VFS_OUT_UNMOUNT,
 		    mp_node->devmap_handle, mp_node->index);
-		vfs_release_phone(mp_node->fs_handle, phone);
+		vfs_exchange_release(exch);
+		
 		if (rc != EOK) {
 			fibril_rwlock_write_unlock(&namespace_rwlock);
@@ -470,5 +479,5 @@
 			return;
 		}
-
+		
 		/* Drop the reference we got above. */
 		vfs_node_put(mp_node);
@@ -476,6 +485,5 @@
 		vfs_node_put(mp_node);
 	}
-
-
+	
 	/*
 	 * All went well, the mounted file system was successfully unmounted.
@@ -483,5 +491,5 @@
 	 */
 	vfs_node_forget(mr_node);
-
+	
 	fibril_rwlock_write_unlock(&namespace_rwlock);
 	async_answer_0(rid, EOK);
@@ -698,19 +706,20 @@
 	 */
 	fibril_mutex_lock(&file->lock);
-	int fs_phone = vfs_grab_phone(file->node->fs_handle);
+	async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle);
 	
 	/* Make a VFS_OUT_SYMC request at the destination FS server. */
 	aid_t msg;
 	ipc_call_t answer;
-	msg = async_send_2(fs_phone, VFS_OUT_SYNC, file->node->devmap_handle,
+	msg = async_send_2(fs_exch, VFS_OUT_SYNC, file->node->devmap_handle,
 	    file->node->index, &answer);
-
+	
+	vfs_exchange_release(fs_exch);
+	
 	/* Wait for reply from the FS server. */
 	sysarg_t rc;
 	async_wait_for(msg, &rc);
 	
-	vfs_release_phone(file->node->fs_handle, fs_phone);
 	fibril_mutex_unlock(&file->lock);
-
+	
 	vfs_file_put(file);
 	async_answer_0(rid, rc);
@@ -720,7 +729,5 @@
 {
 	int fd = IPC_GET_ARG1(*request);
-	int ret;
-	
-	ret = vfs_fd_free(fd);
+	int ret = vfs_fd_free(fd);
 	async_answer_0(rid, ret);
 }
@@ -728,6 +735,4 @@
 static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read)
 {
-	vfs_info_t *vi;
-
 	/*
 	 * The following code strongly depends on the fact that the files data
@@ -739,5 +744,5 @@
 	 * open files supports parallel access!
 	 */
-
+	
 	int fd = IPC_GET_ARG1(*request);
 	
@@ -754,8 +759,8 @@
 	 */
 	fibril_mutex_lock(&file->lock);
-
-	vi = fs_handle_to_info(file->node->fs_handle);
-	assert(vi);
-
+	
+	vfs_info_t *fs_info = fs_handle_to_info(file->node->fs_handle);
+	assert(fs_info);
+	
 	/*
 	 * Lock the file's node so that no other client can read/write to it at
@@ -763,9 +768,10 @@
 	 * write implementation does not modify the file size.
 	 */
-	if (read || (vi->concurrent_read_write && vi->write_retains_size))
+	if ((read) ||
+	    ((fs_info->concurrent_read_write) && (fs_info->write_retains_size)))
 		fibril_rwlock_read_lock(&file->node->contents_rwlock);
 	else
 		fibril_rwlock_write_lock(&file->node->contents_rwlock);
-
+	
 	if (file->node->type == VFS_NODE_DIRECTORY) {
 		/*
@@ -777,5 +783,5 @@
 	}
 	
-	int fs_phone = vfs_grab_phone(file->node->fs_handle);
+	async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle);
 	
 	/*
@@ -789,5 +795,5 @@
 	ipc_call_t answer;
 	if (read) {
-		rc = async_data_read_forward_3_1(fs_phone, VFS_OUT_READ,
+		rc = async_data_read_forward_3_1(fs_exch, VFS_OUT_READ,
 		    file->node->devmap_handle, file->node->index, file->pos,
 		    &answer);
@@ -796,10 +802,10 @@
 			file->pos = file->node->size;
 		
-		rc = async_data_write_forward_3_1(fs_phone, VFS_OUT_WRITE,
+		rc = async_data_write_forward_3_1(fs_exch, VFS_OUT_WRITE,
 		    file->node->devmap_handle, file->node->index, file->pos,
 		    &answer);
 	}
 	
-	vfs_release_phone(file->node->fs_handle, fs_phone);
+	vfs_exchange_release(fs_exch);
 	
 	size_t bytes = IPC_GET_ARG1(answer);
@@ -809,5 +815,6 @@
 	
 	/* Unlock the VFS node. */
-	if (read || (vi->concurrent_read_write && vi->write_retains_size))
+	if ((read) ||
+	    ((fs_info->concurrent_read_write) && (fs_info->write_retains_size)))
 		fibril_rwlock_read_unlock(&file->node->contents_rwlock);
 	else {
@@ -929,12 +936,11 @@
     fs_index_t index, aoff64_t size)
 {
-	sysarg_t rc;
-	int fs_phone;
-	
-	fs_phone = vfs_grab_phone(fs_handle);
-	rc = async_req_4_0(fs_phone, VFS_OUT_TRUNCATE, (sysarg_t) devmap_handle,
-	    (sysarg_t) index, LOWER32(size), UPPER32(size));
-	vfs_release_phone(fs_handle, fs_phone);
-	return (int)rc;
+	async_exch_t *exch = vfs_exchange_grab(fs_handle);
+	sysarg_t rc = async_req_4_0(exch, VFS_OUT_TRUNCATE,
+	    (sysarg_t) devmap_handle, (sysarg_t) index, LOWER32(size),
+	    UPPER32(size));
+	vfs_exchange_release(exch);
+	
+	return (int) rc;
 }
 
@@ -986,13 +992,15 @@
 	fibril_mutex_lock(&file->lock);
 
-	int fs_phone = vfs_grab_phone(file->node->fs_handle);
+	async_exch_t *exch = vfs_exchange_grab(file->node->fs_handle);
 	
 	aid_t msg;
-	msg = async_send_3(fs_phone, VFS_OUT_STAT, file->node->devmap_handle,
+	msg = async_send_3(exch, VFS_OUT_STAT, file->node->devmap_handle,
 	    file->node->index, true, NULL);
-	async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
+	async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
+	
+	vfs_exchange_release(exch);
+	
 	async_wait_for(msg, &rc);
-	vfs_release_phone(file->node->fs_handle, fs_phone);
-
+	
 	fibril_mutex_unlock(&file->lock);
 	vfs_file_put(file);
@@ -1037,13 +1045,15 @@
 	fibril_rwlock_read_unlock(&namespace_rwlock);
 
-	int fs_phone = vfs_grab_phone(node->fs_handle);
+	async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
+	
 	aid_t msg;
-	msg = async_send_3(fs_phone, VFS_OUT_STAT, node->devmap_handle,
+	msg = async_send_3(exch, VFS_OUT_STAT, node->devmap_handle,
 	    node->index, false, NULL);
-	async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
+	async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
+	
+	vfs_exchange_release(exch);
 	
 	sysarg_t rv;
 	async_wait_for(msg, &rv);
-	vfs_release_phone(node->fs_handle, fs_phone);
 
 	async_answer_0(rid, rv);
Index: uspace/srv/vfs/vfs_register.c
===================================================================
--- uspace/srv/vfs/vfs_register.c	(revision 764d71e80b7c72cc3d48b7d5d789623dd67c6961)
+++ uspace/srv/vfs/vfs_register.c	(revision 79ae36ddc409577eb0da3750b3a7280e034566a2)
@@ -62,12 +62,13 @@
 /** Verify the VFS info structure.
  *
- * @param info		Info structure to be verified.
- *
- * @return		Non-zero if the info structure is sane, zero otherwise.
+ * @param info Info structure to be verified.
+ *
+ * @return Non-zero if the info structure is sane, zero otherwise.
+ *
  */
 static bool vfs_info_sane(vfs_info_t *info)
 {
 	int i;
-
+	
 	/*
 	 * Check if the name is non-empty and is composed solely of ASCII
@@ -78,4 +79,5 @@
 		return false;
 	}
+	
 	for (i = 1; i < FS_NAME_MAXLEN; i++) {
 		if (!(islower(info->name[i]) || isdigit(info->name[i])) &&
@@ -90,4 +92,5 @@
 		}
 	}
+	
 	/*
 	 * This check is not redundant. It ensures that the name is
@@ -104,11 +107,10 @@
 /** VFS_REGISTER protocol function.
  *
- * @param rid		Hash of the call with the request.
- * @param request	Call structure with the request.
+ * @param rid     Hash of the call with the request.
+ * @param request Call structure with the request.
+ *
  */
 void vfs_register(ipc_callid_t rid, ipc_call_t *request)
 {
-	int phone;
-	
 	dprintf("Processing VFS_REGISTER request received from %p.\n",
 	    request->in_phone_hash);
@@ -174,20 +176,14 @@
 	 * which to forward VFS requests to it.
 	 */
-	ipc_call_t call;
-	ipc_callid_t callid = async_get_call(&call);
-	if (IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) {
-		dprintf("Unexpected call, method = %d\n", IPC_GET_IMETHOD(call));
+	fs_info->sess = async_callback_receive(EXCHANGE_PARALLEL);
+	if (!fs_info->sess) {
+		dprintf("Callback connection expected\n");
 		list_remove(&fs_info->fs_link);
 		fibril_mutex_unlock(&fs_head_lock);
 		free(fs_info);
-		async_answer_0(callid, EINVAL);
 		async_answer_0(rid, EINVAL);
 		return;
 	}
 	
-	phone = IPC_GET_ARG5(call);
-	async_session_create(&fs_info->session, phone, 0);
-	async_answer_0(callid, EOK);
-	
 	dprintf("Callback connection to FS created.\n");
 	
@@ -197,10 +193,10 @@
 	
 	size_t size;
+	ipc_callid_t callid;
 	if (!async_share_in_receive(&callid, &size)) {
 		dprintf("Unexpected call, method = %d\n", IPC_GET_IMETHOD(call));
 		list_remove(&fs_info->fs_link);
 		fibril_mutex_unlock(&fs_head_lock);
-		async_session_destroy(&fs_info->session);
-		async_hangup(phone);
+		async_hangup(fs_info->sess);
 		free(fs_info);
 		async_answer_0(callid, EINVAL);
@@ -216,6 +212,5 @@
 		list_remove(&fs_info->fs_link);
 		fibril_mutex_unlock(&fs_head_lock);
-		async_session_destroy(&fs_info->session);
-		async_hangup(phone);
+		async_hangup(fs_info->sess);
 		free(fs_info);
 		async_answer_0(callid, EINVAL);
@@ -247,69 +242,59 @@
 }
 
-/** For a given file system handle, implement policy for allocating a phone.
- *
- * @param handle	File system handle.
- *
- * @return		Phone over which a multi-call request can be safely
- *			sent. Return 0 if no phone was found.
- */
-int vfs_grab_phone(fs_handle_t handle)
-{
+/** Begin an exchange for a given file system handle
+ *
+ * @param handle File system handle.
+ *
+ * @return Exchange for a multi-call request.
+ * @return NULL if no such file exists.
+ *
+ */
+async_exch_t *vfs_exchange_grab(fs_handle_t handle)
+{
+	/*
+	 * For now, we don't try to be very clever and very fast.
+	 * We simply lookup the session in the fs_head list and
+	 * begin an exchange.
+	 */
+	fibril_mutex_lock(&fs_head_lock);
+	
 	link_t *cur;
-	fs_info_t *fs;
-	int phone;
-
-	/*
-	 * For now, we don't try to be very clever and very fast.  We simply
-	 * lookup the phone in the fs_head list and duplicate it.  The duplicate
-	 * phone will be returned to the client and the client will use it for
-	 * communication.  In the future, we should cache the connections so
-	 * that they do not have to be reestablished over and over again.
-	 */
-	fibril_mutex_lock(&fs_head_lock);
 	for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
-		fs = list_get_instance(cur, fs_info_t, fs_link);
+		fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
+		
 		if (fs->fs_handle == handle) {
 			fibril_mutex_unlock(&fs_head_lock);
-			phone = async_exchange_begin(&fs->session);
-
-			assert(phone > 0);
-			return phone;
+			
+			assert(fs->sess);
+			async_exch_t *exch = async_exchange_begin(fs->sess);
+			
+			assert(exch);
+			return exch;
 		}
 	}
+	
 	fibril_mutex_unlock(&fs_head_lock);
-	return 0;
-}
-
-/** Tell VFS that the phone is not needed anymore.
- *
- * @param phone		Phone to FS task.
- */
-void vfs_release_phone(fs_handle_t handle, int phone)
-{
-	link_t *cur;
-	fs_info_t *fs;
-
-	fibril_mutex_lock(&fs_head_lock);
-	for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
-		fs = list_get_instance(cur, fs_info_t, fs_link);
-		if (fs->fs_handle == handle) {
-			fibril_mutex_unlock(&fs_head_lock);
-			async_exchange_end(&fs->session, phone);
-			return;
-		}
-	}
-	/* should not really get here */
-	abort();
-	fibril_mutex_unlock(&fs_head_lock);
+	
+	return NULL;
+}
+
+/** End VFS server exchange.
+ *
+ * @param exch   VFS server exchange.
+ *
+ */
+void vfs_exchange_release(async_exch_t *exch)
+{
+	async_exchange_end(exch);
 }
 
 /** Convert file system name to its handle.
  *
- * @param name		File system name.
- * @param lock		If true, the function will lock and unlock the
- * 			fs_head_lock.
- *
- * @return		File system handle or zero if file system not found.
+ * @param name File system name.
+ * @param lock If true, the function will lock and unlock the
+ *             fs_head_lock.
+ *
+ * @return File system handle or zero if file system not found.
+ *
  */
 fs_handle_t fs_name_to_handle(char *name, bool lock)
@@ -319,4 +304,5 @@
 	if (lock)
 		fibril_mutex_lock(&fs_head_lock);
+	
 	link_t *cur;
 	for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
@@ -327,6 +313,8 @@
 		}
 	}
+	
 	if (lock)
 		fibril_mutex_unlock(&fs_head_lock);
+	
 	return handle;
 }
@@ -334,6 +322,8 @@
 /** Find the VFS info structure.
  *
- * @param handle	FS handle for which the VFS info structure is sought.
- * @return		VFS info structure on success or NULL otherwise.
+ * @param handle FS handle for which the VFS info structure is sought.
+ *
+ * @return VFS info structure on success or NULL otherwise.
+ *
  */
 vfs_info_t *fs_handle_to_info(fs_handle_t handle)
@@ -341,5 +331,5 @@
 	vfs_info_t *info = NULL;
 	link_t *cur;
-
+	
 	fibril_mutex_lock(&fs_head_lock);
 	for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
@@ -351,5 +341,5 @@
 	}
 	fibril_mutex_unlock(&fs_head_lock);
-
+	
 	return info;
 }
@@ -357,3 +347,3 @@
 /**
  * @}
- */ 
+ */
