Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/Makefile	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -153,5 +153,4 @@
 ifeq ($(UARCH),sparc64)
 	DIRS += \
-		srv/hw/irc/fhc \
 		srv/hw/irc/obio
 endif
@@ -165,4 +164,5 @@
 	lib/block \
 	lib/clui \
+	lib/scsi \
 	lib/softint \
 	lib/softfloat \
Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/Makefile.common	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -124,4 +124,6 @@
 LIBNET_PREFIX = $(LIB_PREFIX)/net
 
+LIBSCSI_PREFIX = $(LIB_PREFIX)/scsi
+
 ifeq ($(STATIC_NEEDED),y)
 	STATIC_BUILD = y
Index: uspace/app/ext2info/ext2info.c
===================================================================
--- uspace/app/ext2info/ext2info.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/app/ext2info/ext2info.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -590,5 +590,5 @@
 	printf("  Directory contents:\n");
 	
-	rc = ext2_directory_iterator_init(&it, fs, inode_ref);
+	rc = ext2_directory_iterator_init(&it, fs, inode_ref, 0);
 	if (rc != EOK) {
 		printf("Failed initializing directory iterator\n");
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/app/init/init.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -270,5 +270,4 @@
 	spawn("/srv/apic");
 	spawn("/srv/i8259");
-	spawn("/srv/fhc");
 	spawn("/srv/obio");
 	srv_start("/srv/cuda_adb");
Index: uspace/app/ping/ping.c
===================================================================
--- uspace/app/ping/ping.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/app/ping/ping.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -36,5 +36,4 @@
 
 #include <async.h>
-#include <async_obsolete.h>
 #include <stdio.h>
 #include <str.h>
@@ -341,9 +340,9 @@
 	    config.dest_str, config.size, config.size);
 	
-	int icmp_phone = icmp_connect_module();
-	if (icmp_phone < 0) {
+	async_sess_t *sess = icmp_connect_module();
+	if (!sess) {
 		fprintf(stderr, "%s: Unable to connect to ICMP service (%s)\n", NAME,
-		    str_error(icmp_phone));
-		return icmp_phone;
+		    str_error(errno));
+		return errno;
 	}
 	
@@ -356,10 +355,10 @@
 			    str_error(ret));
 			
-			async_obsolete_hangup(icmp_phone);
+			async_hangup(sess);
 			return ret;
 		}
 		
 		/* Ping! */
-		int result = icmp_echo_msg(icmp_phone, config.size, config.timeout,
+		int result = icmp_echo_msg(sess, config.size, config.timeout,
 		    config.ttl, config.tos, !config.fragments, config.dest_raw,
 		    config.dest_len);
@@ -371,5 +370,5 @@
 			    str_error(ret));
 			
-			async_obsolete_hangup(icmp_phone);
+			async_hangup(sess);
 			return ret;
 		}
@@ -391,5 +390,5 @@
 	}
 	
-	async_obsolete_hangup(icmp_phone);
+	async_hangup(sess);
 	
 	return 0;
Index: uspace/app/trace/syscalls.c
===================================================================
--- uspace/app/trace/syscalls.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/app/trace/syscalls.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -80,5 +80,5 @@
     [SYS_SYSINFO_GET_DATA] = { "sysinfo_get_data",		5,	V_ERRNO },
 
-    [SYS_DEBUG_ENABLE_CONSOLE] = { "debug_enable_console", 0,	V_ERRNO },
+    [SYS_DEBUG_ACTIVATE_CONSOLE] = { "debug_activate_console", 0,	V_ERRNO },
     [SYS_IPC_CONNECT_KBOX] = { "ipc_connect_kbox",	1,	V_ERRNO }
 };
Index: uspace/drv/bus/usb/uhci/transfer_list.c
===================================================================
--- uspace/drv/bus/usb/uhci/transfer_list.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/drv/bus/usb/uhci/transfer_list.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -141,5 +141,5 @@
 	list_append(&batch->link, &instance->batch_list);
 
-	usb_log_debug("Batch %p " USB_TRANSFER_BATCH_FMT " scheduled in queue %s.\n",
+	usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " scheduled in queue %s.\n",
 	    batch, USB_TRANSFER_BATCH_ARGS(*batch), instance->name);
 	fibril_mutex_unlock(&instance->guard);
Index: uspace/drv/bus/usb/usbmast/Makefile
===================================================================
--- uspace/drv/bus/usb/usbmast/Makefile	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/drv/bus/usb/usbmast/Makefile	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -32,17 +32,20 @@
 	$(LIBUSBDEV_PREFIX)/libusbdev.a \
 	$(LIBUSB_PREFIX)/libusb.a \
-	$(LIBDRV_PREFIX)/libdrv.a
+	$(LIBDRV_PREFIX)/libdrv.a \
+	$(LIBSCSI_PREFIX)/libscsi.a
 
 EXTRA_CFLAGS += \
 	-I$(LIBUSB_PREFIX)/include \
 	-I$(LIBUSBDEV_PREFIX)/include \
-	-I$(LIBDRV_PREFIX)/include
+	-I$(LIBDRV_PREFIX)/include \
+	-I$(LIBSCSI_PREFIX)/include
 
 BINARY = usbmast
 
 SOURCES = \
-	inquiry.c \
+	cmds.c \
 	main.c \
-	mast.c
+	mast.c \
+	scsi_ms.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/bus/usb/usbmast/cmds.c
===================================================================
--- uspace/drv/bus/usb/usbmast/cmds.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/drv/bus/usb/usbmast/cmds.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup drvusbmast
+ * @{
+ */
+/** @file
+ * USB mass storage commands.
+ */
+
+#include <byteorder.h>
+#include <mem.h>
+#include <sys/types.h>
+#include <usb/usb.h>
+#include "cmds.h"
+
+void usb_massstor_cbw_prepare(usb_massstor_cbw_t *cbw,
+    uint32_t tag, uint32_t transfer_length, usb_direction_t dir,
+    uint8_t lun, uint8_t cmd_len, const uint8_t *cmd)
+{
+	cbw->dCBWSignature = uint32_host2usb(0x43425355);
+	cbw->dCBWTag = tag;
+	cbw->dCBWDataTransferLength = transfer_length;
+
+	cbw->bmCBWFlags = 0;
+	if (dir == USB_DIRECTION_IN) {
+		cbw->bmCBWFlags |= (1 << 7);
+	}
+
+	/* Only lowest 4 bits. */
+	cbw->bCBWLUN = lun & 0x0F;
+
+	/* Only lowest 5 bits. */
+	cbw->bCBWBLength = cmd_len & 0x1F;
+
+	memcpy(cbw->CBWCB, cmd, cbw->bCBWBLength);
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/bus/usb/usbmast/cmds.h
===================================================================
--- uspace/drv/bus/usb/usbmast/cmds.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/drv/bus/usb/usbmast/cmds.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -57,25 +57,6 @@
 } __attribute__((packed)) usb_massstor_csw_t;
 
-static inline void usb_massstor_cbw_prepare(usb_massstor_cbw_t *cbw,
-    uint32_t tag, uint32_t transfer_length, usb_direction_t dir,
-    uint8_t lun, uint8_t cmd_len, uint8_t *cmd)
-{
-	cbw->dCBWSignature = uint32_host2usb(0x43425355);
-	cbw->dCBWTag = tag;
-	cbw->dCBWDataTransferLength = transfer_length;
-
-	cbw->bmCBWFlags = 0;
-	if (dir == USB_DIRECTION_IN) {
-		cbw->bmCBWFlags |= (1 << 7);
-	}
-
-	/* Only lowest 4 bits. */
-	cbw->bCBWLUN = lun & 0x0F;
-
-	/* Only lowest 5 bits. */
-	cbw->bCBWBLength = cmd_len & 0x1F;
-
-	memcpy(cbw->CBWCB, cmd, cbw->bCBWBLength);
-}
+extern void usb_massstor_cbw_prepare(usb_massstor_cbw_t *, uint32_t, uint32_t,
+    usb_direction_t, uint8_t, uint8_t, const uint8_t *);
 
 #endif
Index: uspace/drv/bus/usb/usbmast/inquiry.c
===================================================================
--- uspace/drv/bus/usb/usbmast/inquiry.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,193 +1,0 @@
-/*
- * 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.
- */
-
-/** @addtogroup drvusbmast
- * @{
- */
-/**
- * @file
- * Main routines of USB mass storage driver.
- */
-#include <usb/dev/driver.h>
-#include <usb/debug.h>
-#include <usb/classes/classes.h>
-#include <usb/classes/massstor.h>
-#include <errno.h>
-#include <str_error.h>
-#include <str.h>
-#include <ctype.h>
-#include "cmds.h"
-#include "scsi.h"
-#include "mast.h"
-
-#define BITS_GET_MASK(type, bitcount) (((type)(1 << (bitcount)))-1)
-#define BITS_GET_MID_MASK(type, bitcount, offset) \
-	((type)( BITS_GET_MASK(type, (bitcount) + (offset)) - BITS_GET_MASK(type, bitcount) ))
-#define BITS_GET(type, number, bitcount, offset) \
-	((type)( (number) & (BITS_GET_MID_MASK(type, bitcount, offset)) ) >> (offset))
-
-#define INQUIRY_RESPONSE_LENGTH 36
-
-#define STR_UNKNOWN "<unknown>"
-
-/** String constants for SCSI peripheral device types. */
-static const char *str_peripheral_device_types[] = {
-	"direct-access device",
-	"sequential-access device",
-	"printer device",
-	"processor device",
-	"write-once device",
-	"CDROM device",
-	"scanner device",
-	"optical memory device",
-	"medium changer",
-	"communications device",
-	"graphic arts pre-press device",
-	"graphic arts pre-press device",
-	"storage array controller device",
-	"enclosure services device",
-	"simplified direct-access device",
-	"optical card reader/writer device",
-	"bridging expander",
-	"object-based storage device",
-	"automation driver interface",
-	STR_UNKNOWN, // 0x13
-	STR_UNKNOWN, // 0x14
-	STR_UNKNOWN, // 0x15
-	STR_UNKNOWN, // 0x16
-	STR_UNKNOWN, // 0x17
-	STR_UNKNOWN, // 0x18
-	STR_UNKNOWN, // 0x19
-	STR_UNKNOWN, // 0x1A
-	STR_UNKNOWN, // 0x1B
-	STR_UNKNOWN, // 0x1C
-	STR_UNKNOWN, // 0x1D
-	"well-known logical unit",
-	"uknown or no device state"
-};
-#define str_peripheral_device_types_count \
-	(sizeof(str_peripheral_device_types)/sizeof(str_peripheral_device_types[0]))
-
-/** Get string representation for SCSI peripheral device type.
- *
- * See for example here for a list
- * http://en.wikipedia.org/wiki/SCSI_Peripheral_Device_Type.
- *
- * @param type SCSI peripheral device type code.
- * @return String representation.
- */
-const char *usb_str_masstor_scsi_peripheral_device_type(int type)
-{
-	if ((type < 0)
-	    || ((size_t)type >= str_peripheral_device_types_count)) {
-		return STR_UNKNOWN;
-	}
-	return str_peripheral_device_types[type];
-}
-
-/** Trim trailing spaces from a string (rewrite with string terminator).
- *
- * @param name String to be trimmed (in-out parameter).
- */
-static void trim_trailing_spaces(char *name)
-{
-	size_t len = str_length(name);
-	while ((len > 0) && isspace((int) name[len - 1])) {
-		name[len - 1] = 0;
-		len--;
-	}
-}
-
-/** Perform SCSI INQUIRY command on USB mass storage device.
- *
- * @param dev USB device.
- * @param bulk_in_idx Index (in dev->pipes) of bulk in pipe.
- * @param bulk_out_idx Index of bulk out pipe.
- * @param inquiry_result Where to store parsed inquiry result.
- * @return Error code.
- */
-int usb_massstor_inquiry(usb_device_t *dev,
-    size_t bulk_in_idx, size_t bulk_out_idx,
-    usb_massstor_inquiry_result_t *inquiry_result)
-{
-	scsi_cmd_inquiry_t inquiry = {
-		.op_code = 0x12,
-		.lun_evpd = 0,
-		.page_code = 0,
-		.alloc_length = host2uint16_t_be(INQUIRY_RESPONSE_LENGTH),
-		.ctrl = 0
-	};
-	size_t response_len;
-	uint8_t response[INQUIRY_RESPONSE_LENGTH];
-
-	int rc;
-
-	rc = usb_massstor_data_in(dev, bulk_in_idx, bulk_out_idx,
-	    0xDEADBEEF, 0, (uint8_t *) &inquiry, sizeof(inquiry),
-	    response, INQUIRY_RESPONSE_LENGTH, &response_len);
-
-	if (rc != EOK) {
-		usb_log_error("Failed to probe device %s using %s: %s.\n",
-		   dev->ddf_dev->name, "SCSI:INQUIRY", str_error(rc));
-		return rc;
-	}
-
-	if (response_len < 8) {
-		usb_log_error("The SCSI response is too short.\n");
-		return ERANGE;
-	}
-
-	/*
-	 * This is an ugly part of the code. We will parse the returned
-	 * data by hand and try to get as many useful data as possible.
-	 */
-	bzero(inquiry_result, sizeof(*inquiry_result));
-
-	/* This shall be returned by all devices. */
-	inquiry_result->peripheral_device_type
-	    = BITS_GET(uint8_t, response[0], 5, 0);
-	inquiry_result->removable = BITS_GET(uint8_t, response[1], 1, 7);
-
-	if (response_len < 32) {
-		return EOK;
-	}
-
-	str_ncpy(inquiry_result->vendor_id, 9,
-	    (const char *) &response[8], 8);
-	trim_trailing_spaces(inquiry_result->vendor_id);
-
-	str_ncpy(inquiry_result->product_and_revision, 12,
-	    (const char *) &response[16], 11);
-	trim_trailing_spaces(inquiry_result->product_and_revision);
-
-	return EOK;
-}
-
-/**
- * @}
- */
Index: uspace/drv/bus/usb/usbmast/main.c
===================================================================
--- uspace/drv/bus/usb/usbmast/main.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/drv/bus/usb/usbmast/main.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2011 Vojtech Horky
+ * Copyright (c) 2011 Jiri Svoboda
  * All rights reserved.
  *
@@ -34,4 +35,8 @@
  * Main routines of USB mass storage driver.
  */
+#include <as.h>
+#include <async.h>
+#include <ipc/bd.h>
+#include <macros.h>
 #include <usb/dev/driver.h>
 #include <usb/debug.h>
@@ -41,11 +46,8 @@
 #include <str_error.h>
 #include "cmds.h"
-#include "scsi.h"
 #include "mast.h"
+#include "scsi_ms.h"
 
 #define NAME "usbmast"
-
-#define BULK_IN_EP 0
-#define BULK_OUT_EP 1
 
 #define GET_BULK_IN(dev) ((dev)->pipes[BULK_IN_EP].pipe)
@@ -75,4 +77,22 @@
 };
 
+/** Mass storage function.
+ *
+ * Serves as soft state for function/LUN.
+ */
+typedef struct {
+	/** DDF function */
+	ddf_fun_t *ddf_fun;
+	/** Total number of blocks. */
+	uint64_t nblocks;
+	/** Block size in bytes. */
+	size_t block_size;
+	/** USB device function belongs to */
+	usb_device_t *usb_dev;
+} usbmast_fun_t;
+
+static void usbmast_bd_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg);
+
 /** Callback when new device is attached and recognized as a mass storage.
  *
@@ -83,20 +103,28 @@
 {
 	int rc;
-	const char *fun_name = "ctl";
-
-	ddf_fun_t *ctl_fun = ddf_fun_create(dev->ddf_dev, fun_exposed,
-	    fun_name);
-	if (ctl_fun == NULL) {
-		usb_log_error("Failed to create control function.\n");
-		return ENOMEM;
-	}
-	rc = ddf_fun_bind(ctl_fun);
-	if (rc != EOK) {
-		usb_log_error("Failed to bind control function: %s.\n",
-		    str_error(rc));
-		return rc;
-	}
-
-	usb_log_info("Pretending to control mass storage `%s'.\n",
+	const char *fun_name = "a";
+	ddf_fun_t *fun = NULL;
+	usbmast_fun_t *msfun = NULL;
+
+	/* Allocate softstate */
+	msfun = calloc(1, sizeof(usbmast_fun_t));
+	if (msfun == NULL) {
+		usb_log_error("Failed allocating softstate.\n");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	fun = ddf_fun_create(dev->ddf_dev, fun_exposed, fun_name);
+	if (fun == NULL) {
+		usb_log_error("Failed to create DDF function %s.\n", fun_name);
+		rc = ENOMEM;
+		goto error;
+	}
+
+	/* Set up a connection handler. */
+	fun->conn_handler = usbmast_bd_connection;
+	fun->driver_data = msfun;
+
+	usb_log_info("Initializing mass storage `%s'.\n",
 	    dev->ddf_dev->name);
 	usb_log_debug(" Bulk in endpoint: %d [%zuB].\n",
@@ -107,23 +135,136 @@
 	    (size_t) dev->pipes[BULK_OUT_EP].descriptor->max_packet_size);
 
+	usb_log_debug("Get LUN count...\n");
 	size_t lun_count = usb_masstor_get_lun_count(dev);
 
-	usb_massstor_inquiry_result_t inquiry;
-	rc = usb_massstor_inquiry(dev, BULK_IN_EP, BULK_OUT_EP, &inquiry);
+	/* XXX Handle more than one LUN properly. */
+	if (lun_count > 1) {
+		usb_log_warning ("Mass storage has %zu LUNs. Ignoring all "
+		    "but first.\n", lun_count);
+	}
+
+	usb_log_debug("Inquire...\n");
+	usbmast_inquiry_data_t inquiry;
+	rc = usbmast_inquiry(dev, &inquiry);
 	if (rc != EOK) {
-		usb_log_warning("Failed to inquiry device `%s': %s.\n",
+		usb_log_warning("Failed to inquire device `%s': %s.\n",
 		    dev->ddf_dev->name, str_error(rc));
-		return EOK;
+		rc = EIO;
+		goto error;
 	}
 
 	usb_log_info("Mass storage `%s': " \
-	    "`%s' by `%s' is %s (%s), %zu LUN(s).\n",
+	    "%s by %s rev. %s is %s (%s), %zu LUN(s).\n",
 	    dev->ddf_dev->name,
-	    inquiry.product_and_revision, inquiry.vendor_id,
-	    usb_str_masstor_scsi_peripheral_device_type(inquiry.peripheral_device_type),
+	    inquiry.product,
+	    inquiry.vendor,
+	    inquiry.revision,
+	    usbmast_scsi_dev_type_str(inquiry.device_type),
 	    inquiry.removable ? "removable" : "non-removable",
 	    lun_count);
 
+	uint32_t nblocks, block_size;
+
+	rc = usbmast_read_capacity(dev, &nblocks, &block_size);
+	if (rc != EOK) {
+		usb_log_warning("Failed to read capacity, device `%s': %s.\n",
+		    dev->ddf_dev->name, str_error(rc));
+		rc = EIO;
+		goto error;
+	}
+
+	usb_log_info("Read Capacity: nblocks=%" PRIu32 ", "
+	    "block_size=%" PRIu32 "\n", nblocks, block_size);
+
+	msfun->nblocks = nblocks;
+	msfun->block_size = block_size;
+	msfun->usb_dev = dev;
+
+	rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		usb_log_error("Failed to bind DDF function %s: %s.\n",
+		    fun_name, str_error(rc));
+		goto error;
+	}
+
 	return EOK;
+
+	/* Error cleanup */
+error:
+	if (fun != NULL)
+		ddf_fun_destroy(fun);
+	if (msfun != NULL)
+		free(msfun);
+	return rc;
+}
+
+/** Blockdev client connection handler. */
+static void usbmast_bd_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg)
+{
+	usbmast_fun_t *msfun;
+	void *comm_buf = NULL;
+	size_t comm_size;
+	ipc_callid_t callid;
+	ipc_call_t call;
+	unsigned int flags;
+	sysarg_t method;
+	uint64_t ba;
+	size_t cnt;
+	int retval;
+
+	async_answer_0(iid, EOK);
+
+	if (!async_share_out_receive(&callid, &comm_size, &flags)) {
+		async_answer_0(callid, EHANGUP);
+		return;
+	}
+
+	comm_buf = as_get_mappable_page(comm_size);
+	if (comm_buf == NULL) {
+		async_answer_0(callid, EHANGUP);
+		return;
+	}
+
+	(void) async_share_out_finalize(callid, comm_buf);
+
+	msfun = (usbmast_fun_t *) ((ddf_fun_t *)arg)->driver_data;
+
+	while (true) {
+		callid = async_get_call(&call);
+		method = IPC_GET_IMETHOD(call);
+
+		if (!method) {
+			/* The other side hung up. */
+			async_answer_0(callid, EOK);
+			return;
+		}
+
+		switch (method) {
+		case BD_GET_BLOCK_SIZE:
+			async_answer_1(callid, EOK, msfun->block_size);
+			break;
+		case BD_GET_NUM_BLOCKS:
+			async_answer_2(callid, EOK, LOWER32(msfun->nblocks),
+			    UPPER32(msfun->nblocks));
+			break;
+		case BD_READ_BLOCKS:
+			ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
+			cnt = IPC_GET_ARG3(call);
+			retval = usbmast_read(msfun->usb_dev, ba, cnt,
+			    msfun->block_size, comm_buf);
+			async_answer_0(callid, retval);
+			break;
+		case BD_WRITE_BLOCKS:
+			ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
+			cnt = IPC_GET_ARG3(call);
+			retval = usbmast_write(msfun->usb_dev, ba, cnt,
+			    msfun->block_size, comm_buf);
+			async_answer_0(callid, retval);
+			break;
+		default:
+			async_answer_0(callid, EINVAL);
+		}
+	}
 }
 
Index: uspace/drv/bus/usb/usbmast/mast.c
===================================================================
--- uspace/drv/bus/usb/usbmast/mast.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/drv/bus/usb/usbmast/mast.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -42,42 +42,42 @@
 #include <usb/dev/request.h>
 
-bool usb_mast_verbose = true;
+bool usb_mast_verbose = false;
 
 #define MASTLOG(format, ...) \
 	do { \
 		if (usb_mast_verbose) { \
-			usb_log_debug("USB cl08: " format, ##__VA_ARGS__); \
+			usb_log_debug2("USB cl08: " format, ##__VA_ARGS__); \
 		} \
 	} while (false)
 
-/** Request data from mass storage device.
- *
- * @param bulk_in_pipe Bulk in pipe to the device.
- * @param bulk_out_pipe Bulk out pipe to the device.
- * @param tag Command block wrapper tag (automatically compared with answer).
- * @param lun LUN index.
- * @param cmd SCSI command buffer (in SCSI endianness).
- * @param cmd_size Length of SCSI command @p cmd in bytes.
- * @param in_buffer Buffer where to store the answer (CSW is not returned).
- * @param in_buffer_size Size of the buffer (size of the request to the device).
- * @param received_size Number of actually received bytes.
- * @return Error code.
- */
-int usb_massstor_data_in(usb_device_t *dev,
-    size_t bulk_in_pipe_index, size_t bulk_out_pipe_index,
-    uint32_t tag, uint8_t lun, void *cmd, size_t cmd_size,
-    void *in_buffer, size_t in_buffer_size, size_t *received_size)
+/** Send command via bulk-only transport.
+ *
+ * @param tag		Command block wrapper tag (automatically compared
+ *			with answer)
+ * @param lun		LUN
+ * @param cmd		Command block
+ * @param cmd_size	Command block size in bytes
+ * @param ddir		Direction in which data will be transferred
+ * @param dbuf		Data send/receive buffer
+ * @param dbuf_size	Size of the data buffer
+ * @param xferred_size	Number of bytes actually transferred
+ *
+ * @return		Error code
+ */
+static int usb_massstor_cmd(usb_device_t *dev, uint32_t tag, uint8_t lun,
+    const void *cmd, size_t cmd_size, usb_direction_t ddir, void *dbuf,
+    size_t dbuf_size, size_t *xferred_size)
 {
 	int rc;
 	size_t act_size;
-	usb_pipe_t *bulk_in_pipe = dev->pipes[bulk_in_pipe_index].pipe;
-	usb_pipe_t *bulk_out_pipe = dev->pipes[bulk_out_pipe_index].pipe;
+	usb_pipe_t *bulk_in_pipe = dev->pipes[BULK_IN_EP].pipe;
+	usb_pipe_t *bulk_out_pipe = dev->pipes[BULK_OUT_EP].pipe;
 
 	/* Prepare CBW - command block wrapper */
 	usb_massstor_cbw_t cbw;
-	usb_massstor_cbw_prepare(&cbw, tag, in_buffer_size,
-	    USB_DIRECTION_IN, lun, cmd_size, cmd);
-
-	/* First, send the CBW. */
+	usb_massstor_cbw_prepare(&cbw, tag, dbuf_size, ddir, lun, cmd_size,
+	    cmd);
+
+	/* Send the CBW. */
 	rc = usb_pipe_write(bulk_out_pipe, &cbw, sizeof(cbw));
 	MASTLOG("CBW '%s' sent: %s.\n",
@@ -88,11 +88,23 @@
 	}
 
-	/* Try to retrieve the data from the device. */
-	act_size = 0;
-	rc = usb_pipe_read(bulk_in_pipe, in_buffer, in_buffer_size, &act_size);
-	MASTLOG("Received %zuB (%s): %s.\n", act_size,
-	    usb_debug_str_buffer((uint8_t *) in_buffer, act_size, 0),
-	    str_error(rc));
-	if (rc != EOK) {
+	if (ddir == USB_DIRECTION_IN) {
+		/* Recieve data from the device. */
+		rc = usb_pipe_read(bulk_in_pipe, dbuf, dbuf_size, &act_size);
+		MASTLOG("Received %zu bytes (%s): %s.\n", act_size,
+		    usb_debug_str_buffer((uint8_t *) dbuf, act_size, 0),
+		    str_error(rc));
+	} else {
+		/* Send data to the device. */
+		rc = usb_pipe_write(bulk_out_pipe, dbuf, dbuf_size);
+		MASTLOG("Sent %zu bytes (%s): %s.\n", act_size,
+		    usb_debug_str_buffer((uint8_t *) dbuf, act_size, 0),
+		    str_error(rc));
+	}
+
+	if (rc != EOK) {
+		/*
+		 * XXX If the pipe is stalled, we should clear it
+		 * and read CSW.
+		 */
 		return rc;
 	}
@@ -102,15 +114,19 @@
 	size_t csw_size;
 	rc = usb_pipe_read(bulk_in_pipe, &csw, sizeof(csw), &csw_size);
-	MASTLOG("CSW '%s' received (%zuB): %s.\n",
+	MASTLOG("CSW '%s' received (%zu bytes): %s.\n",
 	    usb_debug_str_buffer((uint8_t *) &csw, csw_size, 0), csw_size,
 	    str_error(rc));
 	if (rc != EOK) {
-		return rc;
-	}
+		MASTLOG("rc != EOK\n");
+		return rc;
+	}
+
 	if (csw_size != sizeof(csw)) {
+		MASTLOG("csw_size != sizeof(csw)\n");
 		return ERANGE;
 	}
 
 	if (csw.dCSWTag != tag) {
+		MASTLOG("csw.dCSWTag != tag\n");
 		return EBADCHECKSUM;
 	}
@@ -120,4 +136,5 @@
 	 */
 	if (csw.dCSWStatus != 0) {
+		MASTLOG("csw.dCSWStatus != 0\n");
 		// FIXME: better error code
 		// FIXME: distinguish 0x01 and 0x02
@@ -126,15 +143,62 @@
 
 	size_t residue = (size_t) uint32_usb2host(csw.dCSWDataResidue);
-	if (residue > in_buffer_size) {
+	if (residue > dbuf_size) {
+		MASTLOG("residue > dbuf_size\n");
 		return ERANGE;
 	}
-	if (act_size != in_buffer_size - residue) {
-		return ERANGE;
-	}
-	if (received_size != NULL) {
-		*received_size = in_buffer_size - residue;
-	}
+
+	/*
+	 * When the device has less data to send than requested (or cannot
+	 * receive moredata), it can either stall the pipe or send garbage
+	 * (ignore data) and indicate that via the residue field in CSW.
+	 * That means dbuf_size - residue is the authoritative size of data
+	 * received (sent).
+	 */
+
+	if (xferred_size != NULL)
+		*xferred_size = dbuf_size - residue;
 
 	return EOK;
+}
+
+/** Perform data-in command.
+ *
+ * @param tag		Command block wrapper tag (automatically compared with
+ *			answer)
+ * @param lun		LUN
+ * @param cmd		CDB (Command Descriptor)
+ * @param cmd_size	CDB length in bytes
+ * @param dbuf		Data receive buffer
+ * @param dbuf_size	Data receive buffer size in bytes
+ * @param proc_size	Number of bytes actually processed by device
+ *
+ * @return Error code
+ */
+int usb_massstor_data_in(usb_device_t *dev, uint32_t tag, uint8_t lun,
+    const void *cmd, size_t cmd_size, void *dbuf, size_t dbuf_size, size_t *proc_size)
+{
+	return usb_massstor_cmd(dev, tag, lun, cmd, cmd_size, USB_DIRECTION_IN,
+	    dbuf, dbuf_size, proc_size);
+}
+
+/** Perform data-out command.
+ *
+ * @param tag		Command block wrapper tag (automatically compared with
+ *			answer)
+ * @param lun		LUN
+ * @param cmd		CDB (Command Descriptor)
+ * @param cmd_size	CDB length in bytes
+ * @param data		Command data
+ * @param data_size	Size of @a data in bytes
+ * @param proc_size	Number of bytes actually processed by device
+ *
+ * @return Error code
+ */
+int usb_massstor_data_out(usb_device_t *dev, uint32_t tag, uint8_t lun,
+    const void *cmd, size_t cmd_size, const void *data, size_t data_size,
+    size_t *proc_size)
+{
+	return usb_massstor_cmd(dev, tag, lun, cmd, cmd_size, USB_DIRECTION_OUT,
+	    (void *) data, data_size, proc_size);
 }
 
@@ -157,9 +221,6 @@
  *
  * @param dev Device to be reseted.
- * @param bulk_in_idx Index of bulk in pipe.
- * @param bulk_out_idx Index of bulk out pipe.
- */
-void usb_massstor_reset_recovery(usb_device_t *dev,
-    size_t bulk_in_idx, size_t bulk_out_idx)
+ */
+void usb_massstor_reset_recovery(usb_device_t *dev)
 {
 	/* We would ignore errors here because if this fails
@@ -167,6 +228,6 @@
 	 */
 	usb_massstor_reset(dev);
-	usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[bulk_in_idx].pipe);
-	usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[bulk_out_idx].pipe);
+	usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[BULK_IN_EP].pipe);
+	usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[BULK_OUT_EP].pipe);
 }
 
Index: uspace/drv/bus/usb/usbmast/mast.h
===================================================================
--- uspace/drv/bus/usb/usbmast/mast.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/drv/bus/usb/usbmast/mast.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -37,4 +37,5 @@
 #define USB_USBMAST_MAST_H_
 
+#include <scsi/spc.h>
 #include <sys/types.h>
 #include <usb/usb.h>
@@ -42,28 +43,15 @@
 #include <usb/dev/driver.h>
 
-/** Result of SCSI INQUIRY command.
- * This is already parsed structure, not the original buffer returned by
- * the device.
- */
-typedef struct {
-	/** SCSI peripheral device type. */
-	int peripheral_device_type;
-	/** Whether the device is removable. */
-	bool removable;
-	/** Vendor ID string. */
-	char vendor_id[9];
-	/** Product ID and product revision string. */
-	char product_and_revision[12];
-} usb_massstor_inquiry_result_t;
+#define BULK_IN_EP 0
+#define BULK_OUT_EP 1
 
-int usb_massstor_data_in(usb_device_t *dev, size_t, size_t,
-    uint32_t, uint8_t, void *, size_t, void *, size_t, size_t *);
-int usb_massstor_reset(usb_device_t *);
-void usb_massstor_reset_recovery(usb_device_t *, size_t, size_t);
-int usb_massstor_get_max_lun(usb_device_t *);
-size_t usb_masstor_get_lun_count(usb_device_t *);
-int usb_massstor_inquiry(usb_device_t *, size_t, size_t,
-    usb_massstor_inquiry_result_t *);
-const char *usb_str_masstor_scsi_peripheral_device_type(int);
+extern int usb_massstor_data_in(usb_device_t *, uint32_t, uint8_t, const void *,
+    size_t, void *, size_t, size_t *);
+extern int usb_massstor_data_out(usb_device_t *, uint32_t, uint8_t, const void *,
+    size_t, const void *, size_t, size_t *);
+extern int usb_massstor_reset(usb_device_t *);
+extern void usb_massstor_reset_recovery(usb_device_t *);
+extern int usb_massstor_get_max_lun(usb_device_t *);
+extern size_t usb_masstor_get_lun_count(usb_device_t *);
 
 #endif
Index: uspace/drv/bus/usb/usbmast/scsi.h
===================================================================
--- uspace/drv/bus/usb/usbmast/scsi.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- * 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.
- */
-
-/** @addtogroup drvusbmast
- * @{
- */
-/** @file
- * SCSI related structures.
- */
-
-#ifndef USB_USBMAST_SCSI_H_
-#define USB_USBMAST_SCSI_H_
-
-#include <sys/types.h>
-#include <usb/usb.h>
-
-typedef struct {
-	uint8_t op_code;
-	uint8_t lun_evpd;
-	uint8_t page_code;
-	uint16_t alloc_length;
-	uint8_t ctrl;
-} __attribute__((packed)) scsi_cmd_inquiry_t;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/drv/bus/usb/usbmast/scsi_ms.c
===================================================================
--- uspace/drv/bus/usb/usbmast/scsi_ms.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/drv/bus/usb/usbmast/scsi_ms.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2011 Vojtech Horky
+ * Copyright (c) 2011 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 drvusbmast
+ * @{
+ */
+/**
+ * @file
+ * SCSI functions for USB mass storage driver.
+ */
+#include <bitops.h>
+#include <byteorder.h>
+#include <inttypes.h>
+#include <macros.h>
+#include <usb/dev/driver.h>
+#include <usb/debug.h>
+#include <errno.h>
+#include <str_error.h>
+#include <str.h>
+#include <scsi/sbc.h>
+#include <scsi/spc.h>
+#include "cmds.h"
+#include "mast.h"
+#include "scsi_ms.h"
+
+/** Get string representation for SCSI peripheral device type.
+ *
+ * @param type		SCSI peripheral device type code.
+ * @return		String representation.
+ */
+const char *usbmast_scsi_dev_type_str(unsigned type)
+{
+	return scsi_get_dev_type_str(type);
+}
+
+/** Perform SCSI Inquiry command on USB mass storage device.
+ *
+ * @param dev		USB device.
+ * @param inquiry_result Where to store parsed inquiry result.
+ * @return		Error code.
+ */
+int usbmast_inquiry(usb_device_t *dev, usbmast_inquiry_data_t *inq_res)
+{
+	scsi_std_inquiry_data_t inq_data;
+	size_t response_len;
+	scsi_cdb_inquiry_t cdb;
+	int rc;
+
+	memset(&cdb, 0, sizeof(cdb));
+	cdb.op_code = SCSI_CMD_INQUIRY;
+	cdb.alloc_len = host2uint16_t_be(sizeof(inq_data));
+
+	rc = usb_massstor_data_in(dev, 0xDEADBEEF, 0, (uint8_t *) &cdb,
+	    sizeof(cdb), &inq_data, sizeof(inq_data), &response_len);
+
+	if (rc != EOK) {
+		usb_log_error("Inquiry failed, device %s: %s.\n",
+		   dev->ddf_dev->name, str_error(rc));
+		return rc;
+	}
+
+	if (response_len < SCSI_STD_INQUIRY_DATA_MIN_SIZE) {
+		usb_log_error("SCSI Inquiry response too short (%zu).\n",
+		    response_len);
+		return EIO;
+	}
+
+	/*
+	 * Parse inquiry data and fill in the result structure.
+	 */
+
+	bzero(inq_res, sizeof(*inq_res));
+
+	inq_res->device_type = BIT_RANGE_EXTRACT(uint8_t,
+	    inq_data.pqual_devtype, SCSI_PQDT_DEV_TYPE_h, SCSI_PQDT_DEV_TYPE_l);
+
+	inq_res->removable = BIT_RANGE_EXTRACT(uint8_t,
+	    inq_data.rmb, SCSI_RMB_RMB, SCSI_RMB_RMB);
+
+	spascii_to_str(inq_res->vendor, SCSI_INQ_VENDOR_STR_BUFSIZE,
+	    inq_data.vendor, sizeof(inq_data.vendor));
+
+	spascii_to_str(inq_res->product, SCSI_INQ_PRODUCT_STR_BUFSIZE,
+	    inq_data.product, sizeof(inq_data.product));
+
+	spascii_to_str(inq_res->revision, SCSI_INQ_REVISION_STR_BUFSIZE,
+	    inq_data.revision, sizeof(inq_data.revision));
+
+	return EOK;
+}
+
+/** Perform SCSI Request Sense command on USB mass storage device.
+ *
+ * @param dev		USB device
+ * @param buf		Destination buffer
+ * @param size		Size of @a buf
+ *
+ * @return		Error code.
+ */
+int usbmast_request_sense(usb_device_t *dev, void *buf, size_t size)
+{
+	scsi_cdb_request_sense_t cdb;
+	size_t data_len;
+	int rc;
+
+	memset(&cdb, 0, sizeof(cdb));
+	cdb.op_code = SCSI_CMD_REQUEST_SENSE;
+	cdb.alloc_len = min(size, SCSI_SENSE_DATA_MAX_SIZE);
+
+	rc = usb_massstor_data_in(dev, 0xDEADBEEF, 0, (uint8_t *) &cdb,
+	    sizeof(cdb), buf, size, &data_len);
+
+        if (rc != EOK) {
+		usb_log_error("Request Sense failed, device %s: %s.\n",
+		   dev->ddf_dev->name, str_error(rc));
+		return rc;
+	}
+
+	if (data_len < SCSI_SENSE_DATA_MIN_SIZE) {
+		/* The missing bytes should be considered to be zeroes. */
+		memset((uint8_t *)buf + data_len, 0,
+		    SCSI_SENSE_DATA_MIN_SIZE - data_len);
+	}
+
+	return EOK;
+}
+
+/** Perform SCSI Read Capacity command on USB mass storage device.
+ *
+ * @param dev		USB device.
+ * @param nblocks	Output, number of blocks.
+ * @param block_size	Output, block size in bytes.
+ *
+ * @return		Error code.
+ */
+int usbmast_read_capacity(usb_device_t *dev, uint32_t *nblocks,
+    uint32_t *block_size)
+{
+	scsi_cdb_read_capacity_10_t cdb;
+	scsi_read_capacity_10_data_t data;
+	size_t data_len;
+	int rc;
+
+	memset(&cdb, 0, sizeof(cdb));
+	cdb.op_code = SCSI_CMD_READ_CAPACITY_10;
+
+	rc = usb_massstor_data_in(dev, 0xDEADBEEF, 0, (uint8_t *) &cdb,
+	    sizeof(cdb), &data, sizeof(data), &data_len);
+
+        if (rc != EOK) {
+		usb_log_error("Read Capacity (10) failed, device %s: %s.\n",
+		   dev->ddf_dev->name, str_error(rc));
+		return rc;
+	}
+
+	if (data_len < sizeof(data)) {
+		usb_log_error("SCSI Read Capacity response too short (%zu).\n",
+		    data_len);
+		return EIO;
+	}
+
+	*nblocks = uint32_t_be2host(data.last_lba) + 1;
+	*block_size = uint32_t_be2host(data.block_size);
+
+	return EOK;
+}
+
+/** Perform SCSI Read command on USB mass storage device.
+ *
+ * @param dev		USB device.
+ * @param ba		Address of first block.
+ * @param nblocks	Number of blocks to read.
+ * @param bsize		Block size.
+ *
+ * @return		Error code.
+ */
+int usbmast_read(usb_device_t *dev, uint64_t ba, size_t nblocks, size_t bsize,
+    void *buf)
+{
+	scsi_cdb_read_12_t cdb;
+	size_t data_len;
+	int rc;
+
+	/* XXX Need softstate to store block size. */
+
+	if (ba > UINT32_MAX)
+		return ELIMIT;
+
+	if ((uint64_t)nblocks * bsize > UINT32_MAX)
+		return ELIMIT;
+
+	memset(&cdb, 0, sizeof(cdb));
+	cdb.op_code = SCSI_CMD_READ_12;
+	cdb.lba = host2uint32_t_be(ba);
+	cdb.xfer_len = host2uint32_t_be(nblocks);
+
+	rc = usb_massstor_data_in(dev, 0xDEADBEEF, 0, (uint8_t *) &cdb,
+	    sizeof(cdb), buf, nblocks * bsize, &data_len);
+
+        if (rc != EOK) {
+		usb_log_error("Read (12) failed, device %s: %s.\n",
+		   dev->ddf_dev->name, str_error(rc));
+		return rc;
+	}
+
+	if (data_len < nblocks * bsize) {
+		usb_log_error("SCSI Read response too short (%zu).\n",
+		    data_len);
+		return EIO;
+	}
+
+	return EOK;
+}
+
+/** Perform SCSI Write command on USB mass storage device.
+ *
+ * @param dev		USB device
+ * @param ba		Address of first block
+ * @param nblocks	Number of blocks to read
+ * @param bsize		Block size
+ * @param data		Data to write
+ *
+ * @return		Error code
+ */
+int usbmast_write(usb_device_t *dev, uint64_t ba, size_t nblocks, size_t bsize,
+    const void *data)
+{
+	scsi_cdb_write_12_t cdb;
+	size_t sent_len;
+	int rc;
+
+	/* XXX Need softstate to store block size. */
+
+	if (ba > UINT32_MAX)
+		return ELIMIT;
+
+	if ((uint64_t)nblocks * bsize > UINT32_MAX)
+		return ELIMIT;
+
+	memset(&cdb, 0, sizeof(cdb));
+	cdb.op_code = SCSI_CMD_WRITE_12;
+	cdb.lba = host2uint32_t_be(ba);
+	cdb.xfer_len = host2uint32_t_be(nblocks);
+
+	rc = usb_massstor_data_out(dev, 0xDEADBEEF, 0, (uint8_t *) &cdb,
+	    sizeof(cdb), data, nblocks * bsize, &sent_len);
+
+        if (rc != EOK) {
+		usb_log_error("Write (12) failed, device %s: %s.\n",
+		   dev->ddf_dev->name, str_error(rc));
+		return rc;
+	}
+
+	if (sent_len < nblocks * bsize) {
+		usb_log_error("SCSI Write not all bytes transferred (%zu).\n",
+		    sent_len);
+		return EIO;
+	}
+
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/bus/usb/usbmast/scsi_ms.h
===================================================================
--- uspace/drv/bus/usb/usbmast/scsi_ms.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/drv/bus/usb/usbmast/scsi_ms.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup drvusbmast
+ * @{
+ */
+/** @file
+ * SCSI functions for USB mass storage.
+ */
+
+#ifndef USB_USBMAST_SCSI_MS_H_
+#define USB_USBMAST_SCSI_MS_H_
+
+#include <scsi/spc.h>
+#include <sys/types.h>
+#include <usb/usb.h>
+#include <usb/dev/driver.h>
+
+/** Result of SCSI Inquiry command.
+ * This is already parsed structure, not the original buffer returned by
+ * the device.
+ */
+typedef struct {
+	/** SCSI peripheral device type */
+	unsigned device_type;
+	/** Whether the device is removable */
+	bool removable;
+	/** Vendor ID string */
+	char vendor[SCSI_INQ_VENDOR_STR_BUFSIZE];
+	/** Product ID string */
+	char product[SCSI_INQ_PRODUCT_STR_BUFSIZE];
+	/** Revision string */
+	char revision[SCSI_INQ_REVISION_STR_BUFSIZE];
+} usbmast_inquiry_data_t;
+
+extern int usbmast_inquiry(usb_device_t *, usbmast_inquiry_data_t *);
+extern int usbmast_request_sense(usb_device_t *, void *, size_t);
+extern int usbmast_read_capacity(usb_device_t *, uint32_t *, uint32_t *);
+extern int usbmast_read(usb_device_t *, uint64_t, size_t, size_t, void *);
+extern int usbmast_write(usb_device_t *, uint64_t, size_t, size_t,
+    const void *);
+extern const char *usbmast_scsi_dev_type_str(unsigned);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/Makefile	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -69,5 +69,4 @@
 	generic/devmap.c \
 	generic/devman.c \
-	generic/devman_obsolete.c \
 	generic/device/hw_res.c \
 	generic/device/char_dev.c \
Index: uspace/lib/c/arch/mips32/Makefile.common
===================================================================
--- uspace/lib/c/arch/mips32/Makefile.common	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32/Makefile.common	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,5 +27,5 @@
 #
 
-GCC_CFLAGS += -mips3
+GCC_CFLAGS += -mips3 -mabi=32
 
 ENDIANESS = LE
Index: uspace/lib/c/arch/mips32/include/atomic.h
===================================================================
--- uspace/lib/c/arch/mips32/include/atomic.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32/include/atomic.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -31,5 +31,5 @@
  */
 /** @file
- * @ingroup libcmips32eb
+ * @ingroup libcmips32
  */
 
Index: uspace/lib/c/arch/mips32/include/fibril.h
===================================================================
--- uspace/lib/c/arch/mips32/include/fibril.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32/include/fibril.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,9 +27,9 @@
  */
 
-/** @addtogroup libcmips32	
+/** @addtogroup libcmips32
  * @{
  */
 /** @file
- * @ingroup libcmips32eb	
+ * @ingroup libcmips32
  */
 
Index: uspace/lib/c/arch/mips32/include/thread.h
===================================================================
--- uspace/lib/c/arch/mips32/include/thread.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32/include/thread.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,9 +27,9 @@
  */
 
-/** @addtogroup libcmips32	
+/** @addtogroup libcmips32
  * @{
  */
 /** @file
- * @ingroup libcmips32eb	
+ * @ingroup libcmips32
  */
 
Index: uspace/lib/c/arch/mips32/include/tls.h
===================================================================
--- uspace/lib/c/arch/mips32/include/tls.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32/include/tls.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,9 +27,9 @@
  */
 
-/** @addtogroup libcmips32	
+/** @addtogroup libcmips32
  * @{
  */
 /** @file
- * @ingroup libcmips32eb	
+ * @ingroup libcmips32
  */
 
Index: uspace/lib/c/arch/mips32/include/types.h
===================================================================
--- uspace/lib/c/arch/mips32/include/types.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32/include/types.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -31,5 +31,5 @@
  */
 /** @file
- * @ingroup libcmips32eb
+ * @ingroup libcmips32
  */
 
Index: uspace/lib/c/arch/mips32/src/syscall.c
===================================================================
--- uspace/lib/c/arch/mips32/src/syscall.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32/src/syscall.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,9 +27,9 @@
  */
 
- /** @addtogroup libcmips32
+/** @addtogroup libcmips32
  * @{
  */
 /** @file
-  * @ingroup libcmips32eb	
+  * @ingroup libcmips32
  */
 
@@ -64,5 +64,4 @@
 }
 
- /** @}
+/** @}
  */
-
Index: uspace/lib/c/arch/mips32/src/tls.c
===================================================================
--- uspace/lib/c/arch/mips32/src/tls.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32/src/tls.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,9 +27,9 @@
  */
 
-/** @addtogroup libcmips32	
+/** @addtogroup libcmips32
  * @{
  */
 /** @file
- * @ingroup libcmips32eb	
+ * @ingroup libcmips32
  */
 
Index: uspace/lib/c/arch/mips32eb/Makefile.common
===================================================================
--- uspace/lib/c/arch/mips32eb/Makefile.common	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32eb/Makefile.common	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,5 +27,5 @@
 #
 
-GCC_CFLAGS += -mips3
+GCC_CFLAGS += -mips3 -mabi=32
 
 ENDIANESS = BE
Index: uspace/lib/c/arch/mips64/Makefile.common
===================================================================
--- uspace/lib/c/arch/mips64/Makefile.common	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/Makefile.common	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2005 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.
+#
+
+GCC_CFLAGS += -mips3 -mabi=64
+AFLAGS = -64
+
+ENDIANESS = LE
+
+BFD_ARCH = mips:4000
+BFD_NAME = elf64-tradlittlemips
Index: uspace/lib/c/arch/mips64/Makefile.inc
===================================================================
--- uspace/lib/c/arch/mips64/Makefile.inc	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/Makefile.inc	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 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.
+#
+
+ARCH_SOURCES = \
+	arch/$(UARCH)/src/entry.s \
+	arch/$(UARCH)/src/entryjmp.s \
+	arch/$(UARCH)/src/thread_entry.s \
+	arch/$(UARCH)/src/syscall.c \
+	arch/$(UARCH)/src/fibril.S \
+	arch/$(UARCH)/src/tls.c \
+	arch/$(UARCH)/src/stacktrace.c \
+	arch/$(UARCH)/src/stacktrace_asm.S
+
+.PRECIOUS: arch/$(UARCH)/src/entry.o
Index: uspace/lib/c/arch/mips64/_link.ld.in
===================================================================
--- uspace/lib/c/arch/mips64/_link.ld.in	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/_link.ld.in	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,73 @@
+OUTPUT_FORMAT(elf64-tradlittlemips)
+STARTUP(LIBC_PATH/arch/UARCH/src/entry.o)
+ENTRY(__entry)
+
+PHDRS {
+#ifdef LOADER
+	interp PT_INTERP;
+	text PT_LOAD FILEHDR PHDRS FLAGS(5);
+#else
+	text PT_LOAD FLAGS(5);
+#endif
+	data PT_LOAD FLAGS(6);
+}
+
+SECTIONS {
+#ifdef LOADER
+	.interp : {
+		*(.interp);
+	} :interp
+	
+	. = 0x70004000 + SIZEOF_HEADERS;
+#else
+	. = 0x4000 + SIZEOF_HEADERS;
+#endif
+	.init : {
+		*(.init);
+	} :text
+	
+	.text : {
+		*(.text .text.*);
+		*(.rodata .rodata.*);
+	} :text
+	
+	. = . + 0x4000;
+	
+	.data : {
+		*(.data);
+		*(.data.rel*);
+	} :data
+	
+	.got : {
+		_gp = .;
+		*(.got);
+	} :data
+	
+	.tdata : {
+		_tdata_start = .;
+		*(.tdata);
+		_tdata_end = .;
+	} :data
+	
+	.tbss : {
+		_tbss_start = .;
+		*(.tbss);
+		_tbss_end = .;
+	} :data
+	
+	_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
+	
+	.sbss : {
+		*(.scommon);
+		*(.sbss);
+	}
+	
+	.bss : {
+		*(.bss);
+		*(COMMON);
+	} :data
+	
+	/DISCARD/ : {
+		*(*);
+	}
+}
Index: uspace/lib/c/arch/mips64/include/atomic.h
===================================================================
--- uspace/lib/c/arch/mips64/include/atomic.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/atomic.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2005 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 libcmips64
+ * @{
+ */
+/** @file
+ * @ingroup libcmips64
+ */
+
+#ifndef LIBC_mips64_ATOMIC_H_
+#define LIBC_mips64_ATOMIC_H_
+
+#define LIBC_ARCH_ATOMIC_H_
+
+#include <atomicdflt.h>
+
+#define atomic_inc(x)  ((void) atomic_add(x, 1))
+#define atomic_dec(x)  ((void) atomic_add(x, -1))
+
+#define atomic_postinc(x)  (atomic_add(x, 1) - 1)
+#define atomic_postdec(x)  (atomic_add(x, -1) + 1)
+
+#define atomic_preinc(x)  atomic_add(x, 1)
+#define atomic_predec(x)  atomic_add(x, -1)
+
+/* Atomic addition of immediate value.
+ *
+ * @param val Memory location to which will be the immediate value added.
+ * @param i   Signed immediate that will be added to *val.
+ *
+ * @return Value after addition.
+ *
+ */
+static inline atomic_count_t atomic_add(atomic_t *val, atomic_count_t i)
+{
+	atomic_count_t tmp;
+	atomic_count_t v;
+	
+	asm volatile (
+		"1:\n"
+		"	lld %0, %1\n"
+		"	daddu %0, %0, %3\n"  /* same as add, but never traps on overflow */
+		"	move %2, %0\n"
+		"	scd %0, %1\n"
+		"	beq %0, %4, 1b\n"    /* if the atomic operation failed, try again */
+		"	nop\n"
+		: "=&r" (tmp),
+		  "+m" (val->count),
+		  "=&r" (v)
+		: "r" (i),
+		  "i" (0)
+	);
+	
+	return v;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/config.h
===================================================================
--- uspace/lib/c/arch/mips64/include/config.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/config.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2006 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 libcmips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_mips64_CONFIG_H_
+#define LIBC_mips64_CONFIG_H_
+
+#define PAGE_WIDTH  14
+#define PAGE_SIZE   (1 << PAGE_WIDTH)
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/ddi.h
===================================================================
--- uspace/lib/c/arch/mips64/include/ddi.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/ddi.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009 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.
+ */
+
+/** @file
+ * @ingroup libcmips64
+ */
+
+#ifndef LIBC_mips64_DDI_H_
+#define LIBC_mips64_DDI_H_
+
+#include <sys/types.h>
+#include <libarch/types.h>
+
+static inline void pio_write_8(ioport8_t *port, uint8_t v)
+{
+	*port = v;
+}
+
+static inline void pio_write_16(ioport16_t *port, uint16_t v)
+{
+	*port = v;
+}
+
+static inline void pio_write_32(ioport32_t *port, uint32_t v)
+{
+	*port = v;
+}
+
+static inline uint8_t pio_read_8(ioport8_t *port)
+{
+	return *port;
+}
+
+static inline uint16_t pio_read_16(ioport16_t *port)
+{
+	return *port;
+}
+
+static inline uint32_t pio_read_32(ioport32_t *port)
+{
+	return *port;
+}
+
+#endif
Index: uspace/lib/c/arch/mips64/include/faddr.h
===================================================================
--- uspace/lib/c/arch/mips64/include/faddr.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/faddr.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2005 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 libcmips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_mips64_FADDR_H_
+#define LIBC_mips64_FADDR_H_
+
+#include <libarch/types.h>
+
+#define FADDR(fptr)  ((uintptr_t) (fptr))
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/fibril.h
===================================================================
--- uspace/lib/c/arch/mips64/include/fibril.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/fibril.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,93 @@
+/*
+ * 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 libcmips64
+ * @{
+ */
+/** @file
+ * @ingroup libcmips64
+ */
+
+#ifndef LIBC_mips64_FIBRIL_H_
+#define LIBC_mips64_FIBRIL_H_
+
+#include <sys/types.h>
+
+/* We define our own context_set, because we need to set
+ * the TLS pointer to the tcb+0x7000
+ *
+ * See tls_set in thread.h
+ */
+#define context_set(c, _pc, stack, size, ptls) \
+	(c)->pc = (sysarg_t) (_pc); \
+	(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
+	(c)->tls = ((sysarg_t)(ptls)) + 0x7000 + sizeof(tcb_t);
+
+/* +16 is just for sure that the called function
+ * have space to store it's arguments
+ */
+#define SP_DELTA  (8 + 16)
+
+typedef struct {
+	uint64_t sp;
+	uint64_t pc;
+	
+	uint64_t s0;
+	uint64_t s1;
+	uint64_t s2;
+	uint64_t s3;
+	uint64_t s4;
+	uint64_t s5;
+	uint64_t s6;
+	uint64_t s7;
+	uint64_t s8;
+	uint64_t gp;
+	uint64_t tls; /* Thread local storage (k1) */
+	
+	uint64_t f20;
+	uint64_t f21;
+	uint64_t f22;
+	uint64_t f23;
+	uint64_t f24;
+	uint64_t f25;
+	uint64_t f26;
+	uint64_t f27;
+	uint64_t f28;
+	uint64_t f29;
+	uint64_t f30;
+} context_t;
+
+static inline uintptr_t context_get_fp(context_t *ctx)
+{
+	return ctx->sp;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/inttypes.h
===================================================================
--- uspace/lib/c/arch/mips64/include/inttypes.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/inttypes.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 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 libcmips64
+ * @{
+ */
+
+#ifndef LIBC_mips64_INTTYPES_H_
+#define LIBC_mips64_INTTYPES_H_
+
+#define PRIdn  PRId64  /**< Format for native_t. */
+#define PRIun  PRIu64  /**< Format for sysarg_t. */
+#define PRIxn  PRIx64  /**< Format for hexadecimal sysarg_t. */
+#define PRIua  PRIu64  /**< Format for atomic_count_t. */
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/istate.h
===================================================================
--- uspace/lib/c/arch/mips64/include/istate.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/istate.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010 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 libcmips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_mips64__ISTATE_H_
+#define LIBC_mips64__ISTATE_H_
+
+#include <arch/istate.h>
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/syscall.h
===================================================================
--- uspace/lib/c/arch/mips64/include/syscall.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/syscall.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2005 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_mips64_SYSCALL_H_
+#define LIBC_mips64_SYSCALL_H_
+
+#define LIBARCH_SYSCALL_GENERIC
+
+#include <syscall.h>
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/thread.h
===================================================================
--- uspace/lib/c/arch/mips64/include/thread.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/thread.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,42 @@
+/*
+ * 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 libcmips64
+ * @{
+ */
+/** @file
+ * @ingroup libcmips64
+ */
+
+#ifndef LIBC_mips64_THREAD_H_
+#define LIBC_mips64_THREAD_H_
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/tls.h
===================================================================
--- uspace/lib/c/arch/mips64/include/tls.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/tls.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,93 @@
+/*
+ * 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 libcmips64
+ * @{
+ */
+/** @file
+ * @ingroup libcmips64
+ */
+
+/* TLS for MIPS is described in http://www.linux-mips.org/wiki/NPTL */
+
+#ifndef LIBC_mips64_TLS_H_
+#define LIBC_mips64_TLS_H_
+
+/*
+ * FIXME: Note that the use of variant I contradicts the observations made in
+ * the note below. Nevertheless the scheme we have used for allocating and
+ * deallocatin TLS corresponds to TLS variant I.
+ */
+#define CONFIG_TLS_VARIANT_1
+
+/* I did not find any specification (neither MIPS nor PowerPC), but
+ * as I found it
+ * - it uses Variant II
+ * - TCB is at Address(First TLS Block)+0x7000.
+ * - DTV is at Address(First TLS Block)+0x8000
+ * - What would happen if the TLS data was larger then 0x7000?
+ * - The linker never accesses DTV directly, has the second definition any
+ *   sense?
+ * We will make it this way:
+ * - TCB is at TP-0x7000-sizeof(tcb)
+ * - No assumption about DTV etc., but it will not have a fixed address
+ */
+#define MIPS_TP_OFFSET 0x7000
+
+typedef struct {
+	void *fibril_data;
+} tcb_t;
+
+static inline void __tcb_set(tcb_t *tcb)
+{
+	void *tp = tcb;
+	tp += MIPS_TP_OFFSET + sizeof(tcb_t);
+	
+	/* Move tls to K1 */
+	asm volatile (
+		"add $27, %0, $0"
+		:: "r" (tp)
+	);
+}
+
+static inline tcb_t *__tcb_get(void)
+{
+	void *retval;
+	
+	asm volatile (
+		"add %0, $27, $0"
+		: "=r" (retval)
+	);
+	
+	return (tcb_t *) (retval - MIPS_TP_OFFSET - sizeof(tcb_t));
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/types.h
===================================================================
--- uspace/lib/c/arch/mips64/include/types.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/types.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2005 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 libcmips64
+ * @{
+ */
+/** @file
+ * @ingroup libcmips32
+ */
+
+#ifndef LIBC_mips64_TYPES_H_
+#define LIBC_mips64_TYPES_H_
+
+#define __64_BITS__
+
+#include <libarch/common.h>
+
+#define SIZE_MIN  UINT64_MIN
+#define SIZE_MAX  UINT64_MAX
+
+#define SSIZE_MIN  INT64_MIN
+#define SSIZE_MAX  INT64_MAX
+
+typedef uint64_t sysarg_t;
+
+typedef int64_t ssize_t;
+typedef uint64_t size_t;
+
+typedef uint64_t uintptr_t;
+typedef uint64_t atomic_count_t;
+typedef int64_t atomic_signed_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/src/entry.s
===================================================================
--- uspace/lib/c/arch/mips64/src/entry.s	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/src/entry.s	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,57 @@
+#
+# Copyright (c) 2005 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.
+#
+
+.text
+.section .init, "ax"
+
+.global __entry
+
+.set noreorder
+.option pic2
+
+## User-space task entry point
+#
+# $a0 ($4) contains the PCB pointer
+#
+.ent __entry
+__entry:
+	.frame $sp, 32, $31
+	.cpload $25
+	
+	# FIXME: Reflect exactly ABI specs here
+	
+	addiu $sp, -32
+	.cprestore 16   # Allow PIC code
+	
+	# Pass pcb_ptr to __main() as the first argument. pcb_ptr is already
+	# in $a0. As the first argument is passed in $a0, no operation
+	# is needed.
+	
+	jal __main
+	nop
+.end
Index: uspace/lib/c/arch/mips64/src/entryjmp.s
===================================================================
--- uspace/lib/c/arch/mips64/src/entryjmp.s	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/src/entryjmp.s	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2008 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.
+#
+
+.text
+.section .text
+.global entry_point_jmp
+.set noreorder
+
+## void entry_point_jmp(void *entry_point, void *pcb);
+#
+# $a0 (=$4) contains entry_point
+# $a1 (=$5) contains pcb
+#
+# Jump to program entry point
+.ent entry_point_jmp
+entry_point_jmp:
+	# tmp := entry_point
+	move $25, $a0
+	
+	# Pass pcb to the entry point in $a0
+	move $a0, $a1
+	jr $25
+	nop
+.end
Index: uspace/lib/c/arch/mips64/src/fibril.S
===================================================================
--- uspace/lib/c/arch/mips64/src/fibril.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/src/fibril.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,55 @@
+#
+# Copyright (c) 2003-2004 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.
+#
+
+.text
+
+.set noat
+.set noreorder
+
+#include <arch/context_offset.h>
+
+.global context_save
+.global context_restore
+
+context_save:
+	CONTEXT_SAVE_ARCH_CORE $a0
+	
+	# context_save returns 1
+	j $ra
+	li $v0, 1
+
+context_restore:
+	CONTEXT_RESTORE_ARCH_CORE $a0
+	
+	# Just for the jump into first function,
+	# but one instruction should not bother us
+	move $t9, $ra
+	
+	# context_restore returns 0
+	j $ra
+	xor $v0, $v0
Index: uspace/lib/c/arch/mips64/src/stacktrace.c
===================================================================
--- uspace/lib/c/arch/mips64/src/stacktrace.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/src/stacktrace.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * Copyright (c) 2010 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 libcmips64 mips64
+ * @ingroup lc
+ * @{
+ */
+/** @file
+ */
+
+#include <sys/types.h>
+#include <bool.h>
+#include <errno.h>
+
+#include <stacktrace.h>
+
+bool stacktrace_fp_valid(stacktrace_t *st, uintptr_t fp)
+{
+	(void) st; (void) fp;
+	return false;
+}
+
+int stacktrace_fp_prev(stacktrace_t *st, uintptr_t fp, uintptr_t *prev)
+{
+	(void) st; (void) fp; (void) prev;
+	return ENOTSUP;
+}
+
+int stacktrace_ra_get(stacktrace_t *st, uintptr_t fp, uintptr_t *ra)
+{
+	(void) st; (void) fp; (void) ra;
+	return ENOTSUP;
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/src/stacktrace_asm.S
===================================================================
--- uspace/lib/c/arch/mips64/src/stacktrace_asm.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/src/stacktrace_asm.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2009 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.
+#
+
+.text
+
+.set noat
+.set noreorder
+
+.global stacktrace_prepare
+.global stacktrace_fp_get
+.global stacktrace_pc_get
+
+stacktrace_prepare:
+stacktrace_fp_get:
+stacktrace_pc_get:
+	j $ra
+	xor $v0, $v0
Index: uspace/lib/c/arch/mips64/src/syscall.c
===================================================================
--- uspace/lib/c/arch/mips64/src/syscall.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/src/syscall.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2005 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 libcmips64
+ * @{
+ */
+/** @file
+  * @ingroup libcmips64
+ */
+
+#include <libc.h>
+
+sysarg_t __syscall(const sysarg_t p1, const sysarg_t p2, const sysarg_t p3,
+    const sysarg_t p4, const sysarg_t p5, const sysarg_t p6, const syscall_t id)
+{
+	register sysarg_t __mips_reg_a0 asm("$4") = p1;
+	register sysarg_t __mips_reg_a1 asm("$5") = p2;
+	register sysarg_t __mips_reg_a2 asm("$6") = p3;
+	register sysarg_t __mips_reg_a3 asm("$7") = p4;
+	register sysarg_t __mips_reg_t0 asm("$8") = p5;
+	register sysarg_t __mips_reg_t1 asm("$9") = p6;
+	register sysarg_t __mips_reg_v0 asm("$2") = id;
+	
+	asm volatile (
+		"syscall\n"
+		: "=r" (__mips_reg_v0)
+		: "r" (__mips_reg_a0),
+		  "r" (__mips_reg_a1),
+		  "r" (__mips_reg_a2),
+		  "r" (__mips_reg_a3),
+		  "r" (__mips_reg_t0),
+		  "r" (__mips_reg_t1),
+		  "r" (__mips_reg_v0)
+		/*
+		 * We are a function call, although
+		 * C does not know it
+		 */
+		: "%ra"
+	);
+	
+	return __mips_reg_v0;
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/src/thread_entry.s
===================================================================
--- uspace/lib/c/arch/mips64/src/thread_entry.s	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/src/thread_entry.s	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,59 @@
+#
+# Copyright (c) 2006 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.
+#
+
+.text
+
+.set noat
+.set noreorder
+.option pic2
+
+.globl __thread_entry
+
+## User-space thread entry point for all but the first threads.
+#
+#
+.ent __thread_entry
+__thread_entry:
+	.frame $sp, 32, $31
+	.cpload $25
+	
+	#
+	# v0 contains address of uarg.
+	#
+	add $4, $2, 0
+	
+	addiu $sp, -32
+	.cprestore 16
+	
+	jal __thread_main
+	nop
+	
+	#
+	# Not reached.
+	#
+.end __thread_entry
Index: uspace/lib/c/arch/mips64/src/tls.c
===================================================================
--- uspace/lib/c/arch/mips64/src/tls.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/src/tls.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,50 @@
+/*
+ * 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 libcmips64
+ * @{
+ */
+/** @file
+ * @ingroup libcmips64
+ */
+
+#include <tls.h>
+#include <sys/types.h>
+
+tcb_t * __alloc_tls(void **data, size_t size)
+{
+	return tls_alloc_variant_1(data, size);
+}
+
+void __free_tls_arch(tcb_t *tcb, size_t size)
+{
+	tls_free_variant_1(tcb, size);
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/adt/measured_strings.c
===================================================================
--- uspace/lib/c/generic/adt/measured_strings.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/generic/adt/measured_strings.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -42,5 +42,4 @@
 #include <errno.h>
 #include <async.h>
-#include <async_obsolete.h>
 
 /** Creates a new measured string bundled with a copy of the given string
@@ -298,5 +297,5 @@
  * size has to be negotiated in advance.
  *
- * @param[in] phone	The other module phone.
+ * @param[in] exch	Exchange.
  * @param[out] strings	The returned measured strings array.
  * @param[out] data	The measured strings data. This memory block stores the
@@ -305,5 +304,5 @@
  * @return		EOK on success.
  * @return		EINVAL if the strings or data parameter is NULL.
- * @return		EINVAL if the phone or count parameter is not positive.
+ * @return		EINVAL if the exch or count parameter is invalid.
  * @return		EINVAL if the sent array differs in size.
  * @return		ENOMEM if there is not enough memory left.
@@ -311,7 +310,6 @@
  *			async_data_read_start() function.
  */
-int
-measured_strings_return(int phone, measured_string_t **strings, uint8_t **data,
-    size_t count)
+int measured_strings_return(async_exch_t *exch, measured_string_t **strings,
+    uint8_t **data, size_t count)
 {
 	size_t *lengths;
@@ -320,5 +318,5 @@
 	int rc;
 
-	if ((phone < 0) || (!strings) || (!data) || (count <= 0))
+	if ((exch == NULL) || (!strings) || (!data) || (count <= 0))
 		return EINVAL;
 
@@ -327,5 +325,5 @@
 		return ENOMEM;
 
-	rc = async_obsolete_data_read_start(phone, lengths,
+	rc = async_data_read_start(exch, lengths,
 	    sizeof(size_t) * (count + 1));
 	if (rc != EOK) {
@@ -352,5 +350,5 @@
 		(*strings)[index].length = lengths[index];
 		if (lengths[index] > 0) {
-			rc = async_obsolete_data_read_start(phone, next, lengths[index]);
+			rc = async_data_read_start(exch, next, lengths[index]);
 			if (rc != EOK) {
 			    	free(lengths);
@@ -376,15 +374,14 @@
  * size has to be negotiated in advance.
  *
- * @param[in] phone	The other module phone.
+ * @param[in] exch	Exchange.
  * @param[in] strings	The measured strings array to be transferred.
  * @param[in] count	The measured strings array size.
  * @return		EOK on success.
  * @return		EINVAL if the strings parameter is NULL.
- * @return		EINVAL if the phone or count parameter is not positive.
+ * @return		EINVAL if the exch or count parameter is invalid.
  * @return		Other error codes as defined for the
  *			async_data_write_start() function.
  */
-int
-measured_strings_send(int phone, const measured_string_t *strings,
+int measured_strings_send(async_exch_t *exch, const measured_string_t *strings,
     size_t count)
 {
@@ -393,5 +390,5 @@
 	int rc;
 
-	if ((phone < 0) || (!strings) || (count <= 0))
+	if ((exch == NULL) || (!strings) || (count <= 0))
 		return EINVAL;
 
@@ -400,5 +397,5 @@
 		return ENOMEM;
 
-	rc = async_obsolete_data_write_start(phone, lengths,
+	rc = async_data_write_start(exch, lengths,
 	    sizeof(size_t) * (count + 1));
 	if (rc != EOK) {
@@ -411,5 +408,5 @@
 	for (index = 0; index < count; index++) {
 		if (strings[index].length > 0) {
-			rc = async_obsolete_data_write_start(phone, strings[index].value,
+			rc = async_data_write_start(exch, strings[index].value,
 			    strings[index].length);
 			if (rc != EOK)
@@ -423,3 +420,2 @@
 /** @}
  */
-
Index: uspace/lib/c/generic/devman_obsolete.c
===================================================================
--- uspace/lib/c/generic/devman_obsolete.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,149 +1,0 @@
-/*
- * 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/io/console.c
===================================================================
--- uspace/lib/c/generic/io/console.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/generic/io/console.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -76,9 +76,5 @@
 bool console_kcon(void)
 {
-#if 0
 	return __SYSCALL0(SYS_DEBUG_ACTIVATE_CONSOLE);
-#endif
-	
-	return false;
 }
 
Index: uspace/lib/c/generic/net/icmp_api.c
===================================================================
--- uspace/lib/c/generic/net/icmp_api.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/generic/net/icmp_api.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -42,5 +42,4 @@
 #include <net/ip_codes.h>
 #include <async.h>
-#include <async_obsolete.h>
 #include <sys/types.h>
 #include <sys/time.h>
@@ -55,5 +54,5 @@
  * timeout occurs.
  *
- * @param[in] icmp_phone The ICMP module phone used for (semi)remote calls.
+ * @param[in] sess The ICMP session.
  * @param[in] size	The message data length in bytes.
  * @param[in] timeout	The timeout in milliseconds.
@@ -74,5 +73,5 @@
  */
 int
-icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl,
+icmp_echo_msg(async_sess_t *sess, size_t size, mseconds_t timeout, ip_ttl_t ttl,
     ip_tos_t tos, int dont_fragment, const struct sockaddr *addr,
     socklen_t addrlen)
@@ -83,10 +82,14 @@
 	if (addrlen <= 0)
 		return EINVAL;
-
-	message_id = async_obsolete_send_5(icmp_phone, NET_ICMP_ECHO, size, timeout, ttl,
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	
+	message_id = async_send_5(exch, NET_ICMP_ECHO, size, timeout, ttl,
 	    tos, (sysarg_t) dont_fragment, NULL);
-
+	
 	/* Send the address */
-	async_obsolete_data_write_start(icmp_phone, addr, (size_t) addrlen);
+	async_data_write_start(exch, addr, (size_t) addrlen);
+	
+	async_exchange_end(exch);
 
 	async_wait_for(message_id, &result);
Index: uspace/lib/c/generic/net/icmp_common.c
===================================================================
--- uspace/lib/c/generic/net/icmp_common.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/generic/net/icmp_common.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -45,8 +45,8 @@
 /** Connect to the ICMP module.
  *
- * @return ICMP module phone on success.
+ * @return ICMP module session.
  *
  */
-int icmp_connect_module(void)
+async_sess_t *icmp_connect_module(void)
 {
 	return connect_to_service(SERVICE_ICMP);
Index: uspace/lib/c/generic/net/modules.c
===================================================================
--- uspace/lib/c/generic/net/modules.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/generic/net/modules.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -40,5 +40,4 @@
 
 #include <async.h>
-#include <async_obsolete.h>
 #include <malloc.h>
 #include <errno.h>
@@ -47,8 +46,4 @@
 #include <net/modules.h>
 #include <ns.h>
-#include <ns_obsolete.h>
-
-/** The time between connect requests in microseconds. */
-#define MODULE_WAIT_TIME  (10 * 1000)
 
 /** Answer a call.
@@ -98,55 +93,65 @@
 }
 
-/** Create bidirectional connection with the needed module service and registers
+/** Create bidirectional connection with the needed module service and register
  * the message receiver.
  *
- * @param[in] need	The needed module service.
- * @param[in] arg1	The first parameter.
- * @param[in] arg2	The second parameter.
- * @param[in] arg3	The third parameter.
- * @param[in] client_receiver The message receiver.
- *
- * @return		The phone of the needed service.
- * @return		Other error codes as defined for the ipc_connect_to_me()
- *			function.
- */
-int bind_service(services_t need, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
-    async_client_conn_t client_receiver)
+ * @param[in] need            Needed module service.
+ * @param[in] arg1            First parameter.
+ * @param[in] arg2            Second parameter.
+ * @param[in] arg3            Third parameter.
+ * @param[in] client_receiver Message receiver.
+ *
+ * @return Session to the needed service.
+ * @return Other error codes as defined for the async_connect_to_me()
+ *         function.
+ *
+ */
+async_sess_t *bind_service(services_t need, sysarg_t arg1, sysarg_t arg2,
+    sysarg_t arg3, async_client_conn_t client_receiver)
 {
 	/* Connect to the needed service */
-	int phone = connect_to_service(need);
-	if (phone >= 0) {
+	async_sess_t *sess = connect_to_service(need);
+	if (sess != NULL) {
 		/* Request the bidirectional connection */
-		int rc = async_obsolete_connect_to_me(phone, arg1, arg2, arg3,
+		async_exch_t *exch = async_exchange_begin(sess);
+		int rc = async_connect_to_me(exch, arg1, arg2, arg3,
 		    client_receiver, NULL);
+		async_exchange_end(exch);
+		
 		if (rc != EOK) {
-			async_obsolete_hangup(phone);
-			return rc;
+			async_hangup(sess);
+			errno = rc;
+			return NULL;
 		}
 	}
 	
-	return phone;
-}
-
-/** Connects to the needed module.
- *
- * @param[in] need	The needed module service.
- * @return		The phone of the needed service.
- */
-int connect_to_service(services_t need)
-{
-	return service_obsolete_connect_blocking(need, 0, 0);
-}
-
-/** Replies the data to the other party.
- *
- * @param[in] data	The data buffer to be sent.
+	return sess;
+}
+
+/** Connect to the needed module.
+ *
+ * @param[in] need Needed module service.
+ *
+ * @return Session to the needed service.
+ * @return NULL if the connection timeouted.
+ *
+ */
+async_sess_t *connect_to_service(services_t need)
+{
+	return service_connect_blocking(EXCHANGE_SERIALIZE, need, 0, 0);
+}
+
+/** Reply the data to the other party.
+ *
+ * @param[in] data        The data buffer to be sent.
  * @param[in] data_length The buffer length.
- * @return		EOK on success.
- * @return		EINVAL if the client does not expect the data.
- * @return		EOVERFLOW if the client does not expect all the data.
- *			Only partial data are transfered.
- * @return		Other error codes as defined for the
- *			async_data_read_finalize() function.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the client does not expect the data.
+ * @return EOVERFLOW if the client does not expect all the data.
+ *         Only partial data are transfered.
+ * @return Other error codes as defined for the
+ *         async_data_read_finalize() function.
+ *
  */
 int data_reply(void *data, size_t data_length)
@@ -154,9 +159,9 @@
 	size_t length;
 	ipc_callid_t callid;
-
+	
 	/* Fetch the request */
 	if (!async_data_read_receive(&callid, &length))
 		return EINVAL;
-
+	
 	/* Check the requested data size */
 	if (length < data_length) {
@@ -164,5 +169,5 @@
 		return EOVERFLOW;
 	}
-
+	
 	/* Send the data */
 	return async_data_read_finalize(callid, data, data_length);
Index: uspace/lib/c/generic/net/socket_client.c
===================================================================
--- uspace/lib/c/generic/net/socket_client.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/generic/net/socket_client.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,5 +39,4 @@
 #include <assert.h>
 #include <async.h>
-#include <async_obsolete.h>
 #include <fibril_synch.h>
 #include <stdint.h>
@@ -84,6 +83,6 @@
 	/** Socket identifier. */
 	int socket_id;
-	/** Parent module phone. */
-	int phone;
+	/** Parent module session. */
+	async_sess_t *sess;
 	/** Parent module service. */
 	services_t service;
@@ -144,12 +143,8 @@
 /** Socket client library global data. */
 static struct socket_client_globals {
-	/** TCP module phone. */
-	int tcp_phone;
-	/** UDP module phone. */
-	int udp_phone;
-
-//	/** The last socket identifier.
-//	 */
-//	int last_id;
+	/** TCP module session. */
+	async_sess_t *tcp_sess;
+	/** UDP module session. */
+	async_sess_t *udp_sess;
 
 	/** Active sockets. */
@@ -164,7 +159,6 @@
 	fibril_rwlock_t lock;
 } socket_globals = {
-	.tcp_phone = -1,
-	.udp_phone = -1,
-//	.last_id = 0,
+	.tcp_sess = NULL,
+	.udp_sess = NULL,
 	.sockets = NULL,
 	.lock = FIBRIL_RWLOCK_INITIALIZER(socket_globals.lock)
@@ -280,38 +274,36 @@
 }
 
-/** Returns the TCP module phone.
- *
- * Connects to the TCP module if necessary.
- *
- * @return		The TCP module phone.
- * @return		Other error codes as defined for the
- *			bind_service() function.
- */
-static int socket_get_tcp_phone(void)
-{
-	if (socket_globals.tcp_phone < 0) {
-		socket_globals.tcp_phone = bind_service(SERVICE_TCP,
+/** Return the TCP module session.
+ *
+ * Connect to the TCP module if necessary.
+ *
+ * @return The TCP module session.
+ *
+ */
+static async_sess_t *socket_get_tcp_sess(void)
+{
+	if (socket_globals.tcp_sess == NULL) {
+		socket_globals.tcp_sess = bind_service(SERVICE_TCP,
 		    0, 0, SERVICE_TCP, socket_connection);
 	}
 
-	return socket_globals.tcp_phone;
-}
-
-/** Returns the UDP module phone.
- *
- * Connects to the UDP module if necessary.
- *
- * @return		The UDP module phone.
- * @return		Other error codes as defined for the
- *			bind_service() function.
- */
-static int socket_get_udp_phone(void)
-{
-	if (socket_globals.udp_phone < 0) {
-		socket_globals.udp_phone = bind_service(SERVICE_UDP,
+	return socket_globals.tcp_sess;
+}
+
+/** Return the UDP module session.
+ *
+ * Connect to the UDP module if necessary.
+ *
+ * @return The UDP module session.
+ *
+ */
+static async_sess_t *socket_get_udp_sess(void)
+{
+	if (socket_globals.udp_sess == NULL) {
+		socket_globals.udp_sess = bind_service(SERVICE_UDP,
 		    0, 0, SERVICE_UDP, socket_connection);
 	}
 
-	return socket_globals.udp_phone;
+	return socket_globals.udp_sess;
 }
 
@@ -329,5 +321,4 @@
 	sockets = socket_get_sockets();
 	count = 0;
-//	socket_id = socket_globals.last_id;
 
 	do {
@@ -342,14 +333,10 @@
 			if (socket_id < INT_MAX) {
 				++socket_id;
-/*			} else if(socket_globals.last_id) {
- *				socket_globals.last_id = 0;
- *				socket_id = 1;
- */			} else {
+			} else {
 				return ELIMIT;
 			}
 		}
 	} while (sockets_find(sockets, socket_id));
-
-//	last_id = socket_id
+	
 	return socket_id;
 }
@@ -358,14 +345,13 @@
  *
  * @param[in,out] socket The socket to be initialized.
- * @param[in] socket_id	The new socket identifier.
- * @param[in] phone	The parent module phone.
- * @param[in] service	The parent module service.
- */
-static void
-socket_initialize(socket_t *socket, int socket_id, int phone,
-    services_t service)
+ * @param[in] socket_id  The new socket identifier.
+ * @param[in] sess       The parent module session.
+ * @param[in] service    The parent module service.
+ */
+static void socket_initialize(socket_t *socket, int socket_id,
+    async_sess_t *sess, services_t service)
 {
 	socket->socket_id = socket_id;
-	socket->phone = phone;
+	socket->sess = sess;
 	socket->service = service;
 	dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE);
@@ -397,5 +383,5 @@
 {
 	socket_t *socket;
-	int phone;
+	async_sess_t *sess;
 	int socket_id;
 	services_t service;
@@ -414,5 +400,5 @@
 			switch (protocol) {
 			case IPPROTO_TCP:
-				phone = socket_get_tcp_phone();
+				sess = socket_get_tcp_sess();
 				service = SERVICE_TCP;
 				break;
@@ -429,5 +415,5 @@
 			switch (protocol) {
 			case IPPROTO_UDP:
-				phone = socket_get_udp_phone();
+				sess = socket_get_udp_sess();
 				service = SERVICE_UDP;
 				break;
@@ -450,6 +436,6 @@
 	}
 
-	if (phone < 0)
-		return phone;
+	if (sess == NULL)
+		return ENOENT;
 
 	/* Create a new socket structure */
@@ -468,7 +454,10 @@
 		return socket_id;
 	}
-
-	rc = (int) async_obsolete_req_3_3(phone, NET_SOCKET, socket_id, 0, service, NULL,
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	rc = (int) async_req_3_3(exch, NET_SOCKET, socket_id, 0, service, NULL,
 	    &fragment_size, &header_size);
+	async_exchange_end(exch);
+	
 	if (rc != EOK) {
 		fibril_rwlock_write_unlock(&socket_globals.lock);
@@ -481,5 +470,5 @@
 
 	/* Finish the new socket initialization */
-	socket_initialize(socket, socket_id, phone, service);
+	socket_initialize(socket, socket_id, sess, service);
 	/* Store the new socket */
 	rc = sockets_add(socket_get_sockets(), socket_id, socket);
@@ -490,6 +479,10 @@
 		dyn_fifo_destroy(&socket->accepted);
 		free(socket);
-		async_obsolete_msg_3(phone, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0,
+		
+		exch = async_exchange_begin(sess);
+		async_msg_3(exch, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0,
 		    service);
+		async_exchange_end(exch);
+		
 		return rc;
 	}
@@ -535,8 +528,10 @@
 
 	/* Request the message */
-	message_id = async_obsolete_send_3(socket->phone, message,
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	message_id = async_send_3(exch, message,
 	    (sysarg_t) socket->socket_id, arg2, socket->service, NULL);
 	/* Send the address */
-	async_obsolete_data_write_start(socket->phone, data, datalength);
+	async_data_write_start(exch, data, datalength);
+	async_exchange_end(exch);
 
 	fibril_rwlock_read_unlock(&socket_globals.lock);
@@ -595,6 +590,8 @@
 
 	/* Request listen backlog change */
-	result = (int) async_obsolete_req_3_0(socket->phone, NET_SOCKET_LISTEN,
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	result = (int) async_req_3_0(exch, NET_SOCKET_LISTEN,
 	    (sysarg_t) socket->socket_id, (sysarg_t) backlog, socket->service);
+	async_exchange_end(exch);
 
 	fibril_rwlock_read_unlock(&socket_globals.lock);
@@ -666,5 +663,5 @@
 		return socket_id;
 	}
-	socket_initialize(new_socket, socket_id, socket->phone,
+	socket_initialize(new_socket, socket_id, socket->sess,
 	    socket->service);
 	result = sockets_add(socket_get_sockets(), new_socket->socket_id,
@@ -678,10 +675,13 @@
 
 	/* Request accept */
-	message_id = async_obsolete_send_5(socket->phone, NET_SOCKET_ACCEPT,
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	message_id = async_send_5(exch, NET_SOCKET_ACCEPT,
 	    (sysarg_t) socket->socket_id, 0, socket->service, 0,
 	    new_socket->socket_id, &answer);
 
 	/* Read address */
-	async_obsolete_data_read_start(socket->phone, cliaddr, *addrlen);
+	async_data_read_start(exch, cliaddr, *addrlen);
+	async_exchange_end(exch);
+	
 	fibril_rwlock_write_unlock(&socket_globals.lock);
 	async_wait_for(message_id, &ipc_result);
@@ -777,6 +777,9 @@
 
 	/* Request close */
-	rc = (int) async_obsolete_req_3_0(socket->phone, NET_SOCKET_CLOSE,
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	rc = (int) async_req_3_0(exch, NET_SOCKET_CLOSE,
 	    (sysarg_t) socket->socket_id, 0, socket->service);
+	async_exchange_end(exch);
+	
 	if (rc != EOK) {
 		fibril_rwlock_write_unlock(&socket_globals.lock);
@@ -850,5 +853,7 @@
 
 	/* Request send */
-	message_id = async_obsolete_send_5(socket->phone, message,
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	
+	message_id = async_send_5(exch, message,
 	    (sysarg_t) socket->socket_id,
 	    (fragments == 1 ? datalength : socket->data_fragment_size),
@@ -857,11 +862,11 @@
 	/* Send the address if given */
 	if (!toaddr ||
-	    (async_obsolete_data_write_start(socket->phone, toaddr, addrlen) == EOK)) {
+	    (async_data_write_start(exch, toaddr, addrlen) == EOK)) {
 		if (fragments == 1) {
 			/* Send all if only one fragment */
-			async_obsolete_data_write_start(socket->phone, data, datalength);
+			async_data_write_start(exch, data, datalength);
 		} else {
 			/* Send the first fragment */
-			async_obsolete_data_write_start(socket->phone, data,
+			async_data_write_start(exch, data,
 			    socket->data_fragment_size - socket->header_size);
 			data = ((const uint8_t *) data) +
@@ -870,5 +875,5 @@
 			/* Send the middle fragments */
 			while (--fragments > 1) {
-				async_obsolete_data_write_start(socket->phone, data,
+				async_data_write_start(exch, data,
 				    socket->data_fragment_size);
 				data = ((const uint8_t *) data) +
@@ -877,9 +882,11 @@
 
 			/* Send the last fragment */
-			async_obsolete_data_write_start(socket->phone, data,
+			async_data_write_start(exch, data,
 			    (datalength + socket->header_size) %
 			    socket->data_fragment_size);
 		}
 	}
+	
+	async_exchange_end(exch);
 
 	async_wait_for(message_id, &result);
@@ -1023,4 +1030,6 @@
 		return 0;
 	}
+	
+	async_exch_t *exch = async_exchange_begin(socket->sess);
 
 	/* Prepare lengths if more fragments */
@@ -1035,5 +1044,5 @@
 
 		/* Request packet data */
-		message_id = async_obsolete_send_4(socket->phone, message,
+		message_id = async_send_4(exch, message,
 		    (sysarg_t) socket->socket_id, 0, socket->service,
 		    (sysarg_t) flags, &answer);
@@ -1041,8 +1050,8 @@
 		/* Read the address if desired */
 		if(!fromaddr ||
-		    (async_obsolete_data_read_start(socket->phone, fromaddr,
+		    (async_data_read_start(exch, fromaddr,
 		    *addrlen) == EOK)) {
 			/* Read the fragment lengths */
-			if (async_obsolete_data_read_start(socket->phone, lengths,
+			if (async_data_read_start(exch, lengths,
 			    sizeof(int) * (fragments + 1)) == EOK) {
 				if (lengths[fragments] <= datalength) {
@@ -1051,6 +1060,5 @@
 					for (index = 0; index < fragments;
 					    ++index) {
-						async_obsolete_data_read_start(
-						    socket->phone, data,
+						async_data_read_start(exch, data,
 						    lengths[index]);
 						data = ((uint8_t *) data) +
@@ -1064,5 +1072,5 @@
 	} else { /* fragments == 1 */
 		/* Request packet data */
-		message_id = async_obsolete_send_4(socket->phone, message,
+		message_id = async_send_4(exch, message,
 		    (sysarg_t) socket->socket_id, 0, socket->service,
 		    (sysarg_t) flags, &answer);
@@ -1070,10 +1078,11 @@
 		/* Read the address if desired */
 		if (!fromaddr ||
-		    (async_obsolete_data_read_start(socket->phone, fromaddr,
-		        *addrlen) == EOK)) {
+		    (async_data_read_start(exch, fromaddr, *addrlen) == EOK)) {
 			/* Read all if only one fragment */
-			async_obsolete_data_read_start(socket->phone, data, datalength);
+			async_data_read_start(exch, data, datalength);
 		}
 	}
+	
+	async_exchange_end(exch);
 
 	async_wait_for(message_id, &ipc_result);
@@ -1187,14 +1196,18 @@
 
 	/* Request option value */
-	message_id = async_obsolete_send_3(socket->phone, NET_SOCKET_GETSOCKOPT,
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	
+	message_id = async_send_3(exch, NET_SOCKET_GETSOCKOPT,
 	    (sysarg_t) socket->socket_id, (sysarg_t) optname, socket->service,
 	    NULL);
 
 	/* Read the length */
-	if (async_obsolete_data_read_start(socket->phone, optlen,
+	if (async_data_read_start(exch, optlen,
 	    sizeof(*optlen)) == EOK) {
 		/* Read the value */
-		async_obsolete_data_read_start(socket->phone, value, *optlen);
-	}
+		async_data_read_start(exch, value, *optlen);
+	}
+	
+	async_exchange_end(exch);
 
 	fibril_rwlock_read_unlock(&socket_globals.lock);
Index: uspace/lib/c/generic/str.c
===================================================================
--- uspace/lib/c/generic/str.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/generic/str.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -544,4 +544,67 @@
 	
 	str_cpy(dest + dstr_size, size - dstr_size, src);
+}
+
+/** Convert space-padded ASCII to string.
+ *
+ * Common legacy text encoding in hardware is 7-bit ASCII fitted into
+ * a fixed-with byte buffer (bit 7 always zero), right-padded with spaces
+ * (ASCII 0x20). Convert space-padded ascii to string representation.
+ *
+ * If the text does not fit into the destination buffer, the function converts
+ * as many characters as possible and returns EOVERFLOW.
+ *
+ * If the text contains non-ASCII bytes (with bit 7 set), the whole string is
+ * converted anyway and invalid characters are replaced with question marks
+ * (U_SPECIAL) and the function returns EIO.
+ *
+ * Regardless of return value upon return @a dest will always be well-formed.
+ *
+ * @param dest		Destination buffer
+ * @param size		Size of destination buffer
+ * @param src		Space-padded ASCII.
+ * @param n		Size of the source buffer in bytes.
+ *
+ * @return		EOK on success, EOVERFLOW if the text does not fit
+ *			destination buffer, EIO if the text contains
+ *			non-ASCII bytes.
+ */
+int spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n)
+{
+	size_t sidx;
+	size_t didx;
+	size_t dlast;
+	uint8_t byte;
+	int rc;
+	int result;
+
+	/* There must be space for a null terminator in the buffer. */
+	assert(size > 0);
+	result = EOK;
+
+	didx = 0;
+	dlast = 0;
+	for (sidx = 0; sidx < n; ++sidx) {
+		byte = src[sidx];
+		if (!ascii_check(byte)) {
+			byte = U_SPECIAL;
+			result = EIO;
+		}
+
+		rc = chr_encode(byte, dest, &didx, size - 1);
+		if (rc != EOK) {
+			assert(rc == EOVERFLOW);
+			dest[didx] = '\0';
+			return rc;
+		}
+
+		/* Remember dest index after last non-empty character */
+		if (byte != 0x20)
+			dlast = didx;
+	}
+
+	/* Terminate string after last non-empty character */
+	dest[dlast] = '\0';
+	return result;
 }
 
Index: uspace/lib/c/include/adt/measured_strings.h
===================================================================
--- uspace/lib/c/include/adt/measured_strings.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/adt/measured_strings.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -41,4 +41,5 @@
 
 #include <sys/types.h>
+#include <async.h>
 
 /** Type definition of the character string with measured length.
@@ -64,6 +65,9 @@
 extern int measured_strings_receive(measured_string_t **, uint8_t **, size_t);
 extern int measured_strings_reply(const measured_string_t *, size_t);
-extern int measured_strings_return(int, measured_string_t **, uint8_t **, size_t);
-extern int measured_strings_send(int, const measured_string_t *, size_t);
+
+extern int measured_strings_return(async_exch_t *, measured_string_t **,
+    uint8_t **, size_t);
+extern int measured_strings_send(async_exch_t *, const measured_string_t *,
+    size_t);
 
 #endif
Index: uspace/lib/c/include/bitops.h
===================================================================
--- uspace/lib/c/include/bitops.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/bitops.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,4 +38,19 @@
 #include <sys/types.h>
 
+/** Mask with bit @a n set. */
+#define BIT_V(type, n) \
+    ((type)1 << ((n) - 1))
+
+/** Mask with rightmost @a n bits set. */
+#define BIT_RRANGE(type, n) \
+    (BIT_V(type, (n) + 1) - 1)
+
+/** Mask with bits @a hi .. @a lo set. @a hi >= @a lo. */
+#define BIT_RANGE(type, hi, lo) \
+    (BIT_RRANGE(type, (hi) - (lo) + 1) << (lo))
+
+/** Extract range of bits @a hi .. @a lo from @a value. */
+#define BIT_RANGE_EXTRACT(type, hi, lo, value) \
+    (((value) >> (lo)) & BIT_RRANGE(type, (hi) - (lo) + 1))
 
 /** Return position of first non-zero bit from left (i.e. [log_2(arg)]).
Index: uspace/lib/c/include/devman_obsolete.h
===================================================================
--- uspace/lib/c/include/devman_obsolete.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,52 +1,0 @@
-/*
- * 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/fourcc.h
===================================================================
--- uspace/lib/c/include/fourcc.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/include/fourcc.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,47 @@
+/*
+ * 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_FOURCC_H_
+#define LIBC_FOURCC_H_
+
+#include <libarch/common.h>
+
+#define FOURCC(a, b, c, d) \
+	(((UINT32_T) (a)) | (((UINT32_T) (b)) << 8) | \
+	    (((UINT32_T) (c)) << 16) | (((UINT32_T) (d)) << 24))
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/console.h
===================================================================
--- uspace/lib/c/include/ipc/console.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/ipc/console.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -48,6 +48,5 @@
 	CONSOLE_SET_COLOR,
 	CONSOLE_SET_RGB_COLOR,
-	CONSOLE_CURSOR_VISIBILITY,
-	CONSOLE_KCON_ENABLE
+	CONSOLE_CURSOR_VISIBILITY
 } console_request_t;
 
Index: uspace/lib/c/include/ipc/net.h
===================================================================
--- uspace/lib/c/include/ipc/net.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/ipc/net.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -335,11 +335,4 @@
 #define IPC_GET_ERROR(call)  ((services_t) IPC_GET_ARG4(call))
 
-/** Return the phone message argument.
- *
- * @param[in] call Message call structure.
- *
- */
-#define IPC_GET_PHONE(call)  ((int) IPC_GET_ARG5(call))
-
 /** Set the device identifier in the message answer.
  *
Index: uspace/lib/c/include/ipc/services.h
===================================================================
--- uspace/lib/c/include/ipc/services.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/ipc/services.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,23 +38,25 @@
 #define LIBC_SERVICES_H_
 
+#include <fourcc.h>
+
 typedef enum {
-	SERVICE_NONE = 0,
-	SERVICE_LOAD,
-	SERVICE_VIDEO,
-	SERVICE_VFS,
-	SERVICE_DEVMAP,
-	SERVICE_DEVMAN,
-	SERVICE_IRC,
-	SERVICE_CLIPBOARD,
-	SERVICE_NETWORKING,
-	SERVICE_LO,
-	SERVICE_NE2000,
-	SERVICE_ETHERNET,
-	SERVICE_NILDUMMY,
-	SERVICE_IP,
-	SERVICE_ARP,
-	SERVICE_ICMP,
-	SERVICE_UDP,
-	SERVICE_TCP
+	SERVICE_NONE       = 0,
+	SERVICE_LOAD       = FOURCC('l', 'o', 'a', 'd'),
+	SERVICE_VIDEO      = FOURCC('v', 'i', 'd', ' '),
+	SERVICE_VFS        = FOURCC('v', 'f', 's', ' '),
+	SERVICE_DEVMAP     = FOURCC('d', 'e', 'v', 'p'),
+	SERVICE_DEVMAN     = FOURCC('d', 'e', 'v', 'n'),
+	SERVICE_IRC        = FOURCC('i', 'r', 'c', ' '),
+	SERVICE_CLIPBOARD  = FOURCC('c', 'l', 'i', 'p'),
+	SERVICE_NETWORKING = FOURCC('n', 'e', 't', ' '),
+	SERVICE_LO         = FOURCC('l', 'o', ' ', ' '),
+	SERVICE_NE2000     = FOURCC('n', 'e', '2', 'k'),
+	SERVICE_ETHERNET   = FOURCC('e', 't', 'h', ' '),
+	SERVICE_NILDUMMY   = FOURCC('n', 'i', 'l', 'd'),
+	SERVICE_IP         = FOURCC('i', 'p', 'v', '4'),
+	SERVICE_ARP        = FOURCC('a', 'r', 'p', ' '),
+	SERVICE_ICMP       = FOURCC('i', 'c', 'm', 'p'),
+	SERVICE_UDP        = FOURCC('u', 'd', 'p', ' '),
+	SERVICE_TCP        = FOURCC('t', 'c', 'p', ' ')
 } services_t;
 
Index: uspace/lib/c/include/net/icmp_api.h
===================================================================
--- uspace/lib/c/include/net/icmp_api.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/net/icmp_api.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -42,9 +42,9 @@
 #include <sys/types.h>
 #include <sys/time.h>
-
 #include <adt/measured_strings.h>
 #include <net/ip_codes.h>
 #include <net/icmp_codes.h>
 #include <net/icmp_common.h>
+#include <async.h>
 
 /** @name ICMP module application interface
@@ -53,6 +53,6 @@
 /*@{*/
 
-extern int icmp_echo_msg(int, size_t, mseconds_t, ip_ttl_t, ip_tos_t, int,
-    const struct sockaddr *, socklen_t);
+extern int icmp_echo_msg(async_sess_t *, size_t, mseconds_t, ip_ttl_t, ip_tos_t,
+    int, const struct sockaddr *, socklen_t);
 
 /*@}*/
Index: uspace/lib/c/include/net/icmp_common.h
===================================================================
--- uspace/lib/c/include/net/icmp_common.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/net/icmp_common.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -40,6 +40,7 @@
 #include <ipc/services.h>
 #include <sys/time.h>
+#include <async.h>
 
-extern int icmp_connect_module(void);
+extern async_sess_t *icmp_connect_module(void);
 
 #endif
Index: uspace/lib/c/include/net/modules.h
===================================================================
--- uspace/lib/c/include/net/modules.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/net/modules.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -46,17 +46,15 @@
 #include <sys/time.h>
 
-/** Connect to the needed module function type definition.
+/** Connect to module function type definition.
  *
- * @param[in] need The needed module service.
- *
- * @return The phone of the needed service.
+ * @return Session to the service.
  *
  */
-typedef int connect_module_t(services_t need);
+typedef async_sess_t *connect_module_t(services_t);
 
 extern void answer_call(ipc_callid_t, int, ipc_call_t *, size_t);
-extern int bind_service(services_t, sysarg_t, sysarg_t, sysarg_t,
+extern async_sess_t *bind_service(services_t, sysarg_t, sysarg_t, sysarg_t,
     async_client_conn_t);
-extern int connect_to_service(services_t);
+extern async_sess_t *connect_to_service(services_t);
 extern int data_reply(void *, size_t);
 extern void refresh_answer(ipc_call_t *, size_t *);
Index: uspace/lib/c/include/str.h
===================================================================
--- uspace/lib/c/include/str.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/str.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -48,4 +48,10 @@
 #define STR_BOUNDS(length)  ((length) << 2)
 
+/**
+ * Maximum size of a buffer needed to a string converted from space-padded
+ * ASCII of size @a spa_size using spascii_to_str().
+ */
+#define SPASCII_STR_BUFSIZE(spa_size) ((spa_size) + 1)
+
 extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
 extern int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t sz);
@@ -73,4 +79,5 @@
 extern void str_append(char *dest, size_t size, const char *src);
 
+extern int spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n);
 extern void wstr_to_str(char *dest, size_t size, const wchar_t *src);
 extern char *wstr_to_astr(const wchar_t *src);
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/drv/generic/driver.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -314,4 +314,10 @@
 		    " %" PRIun " was found.\n", driver->name, handle);
 		async_answer_0(iid, ENOENT);
+		return;
+	}
+	
+	if (fun->conn_handler != NULL) {
+		/* Driver has a custom connection handler. */
+		(*fun->conn_handler)(iid, icall, (void *)fun);
 		return;
 	}
Index: uspace/lib/drv/include/ddf/driver.h
===================================================================
--- uspace/lib/drv/include/ddf/driver.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/drv/include/ddf/driver.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -118,4 +118,6 @@
 	/** Implementation of operations provided by this function */
 	ddf_dev_ops_t *ops;
+	/** Connection handler or @c NULL to use the DDF default handler. */
+	async_client_conn_t conn_handler;
 	
 	/** Link in the list of functions handled by the driver */
Index: uspace/lib/ext2/libext2_directory.c
===================================================================
--- uspace/lib/ext2/libext2_directory.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/ext2/libext2_directory.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -86,32 +86,17 @@
  * @param fs pointer to filesystem structure
  * @param inode pointer to inode reference structure
+ * @param pos position within inode to start at, 0 is the first entry
  * @return EOK on success or negative error code on failure
  */
 int ext2_directory_iterator_init(ext2_directory_iterator_t *it,
-    ext2_filesystem_t *fs, ext2_inode_ref_t *inode_ref)
-{
-	int rc;
-	uint32_t block_id;
-	uint32_t block_size;
-	
+    ext2_filesystem_t *fs, ext2_inode_ref_t *inode_ref, aoff64_t pos)
+{	
 	it->inode_ref = inode_ref;
 	it->fs = fs;
-	
-	/* Get the first data block, so we can get the first entry */
-	rc = ext2_filesystem_get_inode_data_block_index(fs, inode_ref->inode, 0, 
-	    &block_id);
-	if (rc != EOK) {
-		return rc;
-	}
-	
-	rc = block_get(&it->current_block, fs->device, block_id, 0);
-	if (rc != EOK) {
-		return rc;
-	}
-	
-	block_size = ext2_superblock_get_block_size(fs->superblock);
-	
-	it->current_offset = 0;	
-	return ext2_directory_iterator_set(it, block_size);
+	it->current = NULL;
+	it->current_offset = 0;
+	it->current_block = NULL;
+	
+	return ext2_directory_iterator_seek(it, pos);
 }
 
@@ -124,6 +109,23 @@
 int ext2_directory_iterator_next(ext2_directory_iterator_t *it)
 {
+	uint16_t skip;
+	
+	assert(it->current != NULL);
+	
+	skip = ext2_directory_entry_ll_get_entry_length(it->current);
+	
+	return ext2_directory_iterator_seek(it, it->current_offset + skip);
+}
+
+/**
+ * Seek the directory iterator to the given byte offset within the inode.
+ * 
+ * @param it pointer to iterator to initialize
+ * @return EOK on success or negative error code on failure
+ */
+int ext2_directory_iterator_seek(ext2_directory_iterator_t *it, aoff64_t pos)
+{
 	int rc;
-	uint16_t skip;
+	
 	uint64_t size;
 	aoff64_t current_block_idx;
@@ -132,19 +134,20 @@
 	uint32_t block_size;
 	
-	assert(it->current != NULL);
-	
-	skip = ext2_directory_entry_ll_get_entry_length(it->current);
 	size = ext2_inode_get_size(it->fs->superblock, it->inode_ref->inode);
 	
+	/* The iterator is not valid until we seek to the desired position */
+	it->current = NULL;
+	
 	/* Are we at the end? */
-	if (it->current_offset + skip >= size) {
-		rc = block_put(it->current_block);
-		it->current_block = NULL;
-		it->current = NULL;
-		if (rc != EOK) {
-			return rc;
+	if (pos >= size) {		
+		if (it->current_block) {
+			rc = block_put(it->current_block);
+			it->current_block = NULL;
+			if (rc != EOK) {
+				return rc;
+			}
 		}
 		
-		it->current_offset += skip;
+		it->current_offset = pos;
 		return EOK;
 	}
@@ -152,15 +155,16 @@
 	block_size = ext2_superblock_get_block_size(it->fs->superblock);
 	current_block_idx = it->current_offset / block_size;
-	next_block_idx = (it->current_offset + skip) / block_size;
-	
-	/* If we are moving accross block boundary,
+	next_block_idx = pos / block_size;
+	
+	/* If we don't have a block or are moving accross block boundary,
 	 * we need to get another block
 	 */
-	if (current_block_idx != next_block_idx) {
-		rc = block_put(it->current_block);
-		it->current_block = NULL;
-		it->current = NULL;
-		if (rc != EOK) {
-			return rc;
+	if (it->current_block == NULL || current_block_idx != next_block_idx) {		
+		if (it->current_block) {
+			rc = block_put(it->current_block);
+			it->current_block = NULL;
+			if (rc != EOK) {
+				return rc;
+			}
 		}
 		
@@ -179,8 +183,15 @@
 	}
 	
-	it->current_offset += skip;
+	it->current_offset = pos;
 	return ext2_directory_iterator_set(it, block_size);
 }
 
+/** Setup the entry at the current iterator offset.
+ * 
+ * This function checks the validity of the directory entry,
+ * before setting the data pointer.
+ *
+ * @return EOK on success or error code on failure 
+ */
 static int ext2_directory_iterator_set(ext2_directory_iterator_t *it,
     uint32_t block_size)
Index: uspace/lib/ext2/libext2_directory.h
===================================================================
--- uspace/lib/ext2/libext2_directory.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/ext2/libext2_directory.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -71,6 +71,7 @@
 
 extern int ext2_directory_iterator_init(ext2_directory_iterator_t *,
-    ext2_filesystem_t *, ext2_inode_ref_t *);
+    ext2_filesystem_t *, ext2_inode_ref_t *, aoff64_t);
 extern int ext2_directory_iterator_next(ext2_directory_iterator_t *);
+extern int ext2_directory_iterator_seek(ext2_directory_iterator_t *, aoff64_t pos);
 extern int ext2_directory_iterator_fini(ext2_directory_iterator_t *);
 
Index: uspace/lib/net/adt/module_map.c
===================================================================
--- uspace/lib/net/adt/module_map.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/adt/module_map.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,9 +39,5 @@
 #include <unistd.h>
 #include <errno.h>
-
-#include <ipc/services.h>
-
 #include <net/modules.h>
-
 #include <adt/generic_char_map.h>
 #include <adt/module_map.h>
@@ -49,19 +45,20 @@
 GENERIC_CHAR_MAP_IMPLEMENT(modules, module_t)
 
-/** Adds module to the module map.
+/** Add module to the module map.
  *
- * @param[out] module	The module structure added.
- * @param[in] modules	The module map.
- * @param[in] name	The module name.
- * @param[in] filename	The full path filename.
- * @param[in] service	The module service.
- * @param[in] task_id	The module current task identifier. Zero means not
- *			running.
- * @param[in] connect_module The module connecting function.
- * @return		EOK on success.
- * @return		ENOMEM if there is not enough memory left.
+ * @param[out] module         Module structure added.
+ * @param[in]  modules        Module map.
+ * @param[in]  name           Module name.
+ * @param[in]  filename       Full path filename.
+ * @param[in]  service        Module service.
+ * @param[in]  task_id        Module current task identifier.
+ *                            Zero means not running.
+ * @param[in]  connect_module Module connecting function.
+ *
+ * @return EOK on success.
+ * @return ENOMEM if there is not enough memory left.
+ *
  */
-int
-add_module(module_t **module, modules_t *modules, const uint8_t *name,
+int add_module(module_t **module, modules_t *modules, const uint8_t *name,
     const uint8_t *filename, services_t service, task_id_t task_id,
     connect_module_t connect_module)
@@ -69,11 +66,11 @@
 	module_t *tmp_module;
 	int rc;
-
+	
 	tmp_module = (module_t *) malloc(sizeof(module_t));
 	if (!tmp_module)
 		return ENOMEM;
-
+	
 	tmp_module->task_id = task_id;
-	tmp_module->phone = 0;
+	tmp_module->sess = NULL;
 	tmp_module->usage = 0;
 	tmp_module->name = name;
@@ -81,5 +78,5 @@
 	tmp_module->service = service;
 	tmp_module->connect_module = connect_module;
-
+	
 	rc = modules_add(modules, tmp_module->name, 0, tmp_module);
 	if (rc != EOK) {
@@ -87,29 +84,30 @@
 		return rc;
 	}
+	
 	if (module)
 		*module = tmp_module;
-
+	
 	return EOK;
 }
 
-/** Searches and returns the specified module.
+/** Search and return the specified module.
  *
  * If the module is not running, the module filaname is spawned.
  * If the module is not connected, the connect_function is called.
  *
- * @param[in] modules	The module map.
- * @param[in] name	The module name.
- * @return		The running module found. It does not have to be
- *			connected.
- * @return		NULL if there is no such module.
+ * @param[in] modules Module map.
+ * @param[in] name    Module name.
+ *
+ * @return The running module found. It does not have to be
+ *         connected.
+ * @return NULL if there is no such module.
+ *
  */
 module_t *get_running_module(modules_t *modules, uint8_t *name)
 {
-	module_t *module;
-
-	module = modules_find(modules, name, 0);
+	module_t *module = modules_find(modules, name, 0);
 	if (!module)
 		return NULL;
-
+	
 	if (!module->task_id) {
 		module->task_id = net_spawn(module->filename);
@@ -117,7 +115,8 @@
 			return NULL;
 	}
-	if (!module->phone)
-		module->phone = module->connect_module(module->service);
-
+	
+	if (!module->sess)
+		module->sess = module->connect_module(module->service);
+	
 	return module;
 }
Index: uspace/lib/net/generic/generic.c
===================================================================
--- uspace/lib/net/generic/generic.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/generic/generic.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -37,5 +37,4 @@
 #include <generic.h>
 #include <async.h>
-#include <async_obsolete.h>
 #include <ipc/services.h>
 #include <net/device.h>
@@ -45,18 +44,19 @@
 /** Notify the module about the device state change.
  *
- * @param[in] phone	The service module phone.
- * @param[in] message	The service specific message.
- * @param[in] device_id	The device identifier.
- * @param[in] state	The new device state.
- * @param[in] target	The target module service.
- * @return		EOK on success.
- *
- */
-int
-generic_device_state_msg_remote(int phone, int message, device_id_t device_id,
-    int state, services_t target)
-{
-	async_obsolete_msg_3(phone, (sysarg_t) message, (sysarg_t) device_id,
-	    (sysarg_t) state, target);
+ * @param[in] sess      Service module session.
+ * @param[in] message   Service specific message.
+ * @param[in] device_id Device identifier.
+ * @param[in] state     New device state.
+ * @param[in] target    Target module service.
+ *
+ * @return EOK on success.
+ *
+ */
+int generic_device_state_msg_remote(async_sess_t *sess, sysarg_t message,
+    device_id_t device_id, sysarg_t state, services_t target)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	async_msg_3(exch, message, (sysarg_t) device_id, state, target);
+	async_exchange_end(exch);
 	
 	return EOK;
@@ -65,54 +65,59 @@
 /** Notify a module about the device.
  *
- * @param[in] phone	The service module phone.
- * @param[in] message	The service specific message.
- * @param[in] device_id	The device identifier.
- * @param[in] arg2	The second argument of the message.
- * @param[in] service	The device module service.
- * @return		EOK on success.
- * @return		Other error codes as defined for the specific service
- *			 message.
- *
- */
-int
-generic_device_req_remote(int phone, int message, device_id_t device_id,
-    int arg2, services_t service)
-{
-	return (int) async_obsolete_req_3_0(phone, (sysarg_t) message,
-	    (sysarg_t) device_id, (sysarg_t) arg2, (sysarg_t) service);
+ * @param[in] sess      Service module session.
+ * @param[in] message   Service specific message.
+ * @param[in] device_id Device identifier.
+ * @param[in] arg2      Second argument of the message.
+ * @param[in] service   Device module service.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the specific service
+ *         message.
+ *
+ */
+int generic_device_req_remote(async_sess_t *sess, sysarg_t message,
+    device_id_t device_id, sysarg_t arg2, services_t service)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_3_0(exch, message, (sysarg_t) device_id,
+	    arg2, (sysarg_t) service);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
 /** Returns the address.
  *
- * @param[in] phone	The service module phone.
- * @param[in] message	The service specific message.
- * @param[in] device_id	The device identifier.
- * @param[out] address	The desired address.
- * @param[out] data	The address data container.
- * @return		EOK on success.
- * @return		EBADMEM if the address parameter and/or the data
- *			parameter is NULL.
- * @return		Other error codes as defined for the specific service
- *			message.
- */
-int
-generic_get_addr_req(int phone, int message, device_id_t device_id,
-    measured_string_t **address, uint8_t **data)
-{
-	aid_t message_id;
+ * @param[in] sess      Service module session.
+ * @param[in] message   Service specific message.
+ * @param[in] device_id Device identifier.
+ * @param[out] address  Desired address.
+ * @param[out] data     Address data container.
+ *
+ * @return EOK on success.
+ * @return EBADMEM if the address parameter and/or the data
+ *         parameter is NULL.
+ * @return Other error codes as defined for the specific service
+ *         message.
+ *
+ */
+int generic_get_addr_req(async_sess_t *sess, sysarg_t message,
+    device_id_t device_id, measured_string_t **address, uint8_t **data)
+{
+	if ((!address) || (!data))
+		return EBADMEM;
+	
+	/* Request the address */
+	async_exch_t *exch = async_exchange_begin(sess);
+	aid_t message_id = async_send_1(exch, message, (sysarg_t) device_id,
+	    NULL);
+	int rc = measured_strings_return(exch, address, data, 1);
+	async_exchange_end(exch);
+	
 	sysarg_t result;
-	int string;
-
-	if (!address || !data)
-		return EBADMEM;
-
-	/* Request the address */
-	message_id = async_obsolete_send_1(phone, (sysarg_t) message,
-	    (sysarg_t) device_id, NULL);
-	string = measured_strings_return(phone, address, data, 1);
 	async_wait_for(message_id, &result);
-
+	
 	/* If not successful */
-	if ((string == EOK) && (result != EOK)) {
+	if ((rc == EOK) && (result != EOK)) {
 		/* Clear the data */
 		free(*address);
@@ -125,16 +130,17 @@
 /** Return the device packet dimension for sending.
  *
- * @param[in] phone	The service module phone.
- * @param[in] message	The service specific message.
- * @param[in] device_id	The device identifier.
- * @param[out] packet_dimension The packet dimension.
- * @return		EOK on success.
- * @return		EBADMEM if the packet_dimension parameter is NULL.
- * @return		Other error codes as defined for the specific service
- *			message.
- */
-int
-generic_packet_size_req_remote(int phone, int message, device_id_t device_id,
-    packet_dimension_t *packet_dimension)
+ * @param[in] sess              Service module session.
+ * @param[in] message           Service specific message.
+ * @param[in] device_id         Device identifier.
+ * @param[out] packet_dimension Packet dimension.
+ *
+ * @return EOK on success.
+ * @return EBADMEM if the packet_dimension parameter is NULL.
+ * @return Other error codes as defined for the specific service
+ *         message.
+ *
+ */
+int generic_packet_size_req_remote(async_sess_t *sess, sysarg_t message,
+    device_id_t device_id, packet_dimension_t *packet_dimension)
 {
 	if (!packet_dimension)
@@ -146,6 +152,8 @@
 	sysarg_t suffix;
 	
-	sysarg_t result = async_obsolete_req_1_4(phone, (sysarg_t) message,
-	    (sysarg_t) device_id, &addr_len, &prefix, &content, &suffix);
+	async_exch_t *exch = async_exchange_begin(sess);
+	sysarg_t result = async_req_1_4(exch, message, (sysarg_t) device_id,
+	    &addr_len, &prefix, &content, &suffix);
+	async_exchange_end(exch);
 	
 	packet_dimension->prefix = (size_t) prefix;
@@ -159,25 +167,31 @@
 /** Pass the packet queue to the module.
  *
- * @param[in] phone	The service module phone.
- * @param[in] message	The service specific message.
- * @param[in] device_id	The device identifier.
- * @param[in] packet_id	The received packet or the received packet queue
- *			identifier.
- * @param[in] target	The target module service.
- * @param[in] error	The error module service.
- * @return		EOK on success.
- */
-int
-generic_received_msg_remote(int phone, int message, device_id_t device_id,
-    packet_id_t packet_id, services_t target, services_t error)
-{
+ * @param[in] sess      Service module session.
+ * @param[in] message   Service specific message.
+ * @param[in] device_id Device identifier.
+ * @param[in] packet_id Received packet or the received packet queue
+ *                      identifier.
+ * @param[in] target    Target module service.
+ * @param[in] error     Error module service.
+ *
+ * @return EOK on success.
+ *
+ */
+int generic_received_msg_remote(async_sess_t *sess, sysarg_t message,
+    device_id_t device_id, packet_id_t packet_id, services_t target,
+    services_t error)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	
 	if (error) {
-		async_obsolete_msg_4(phone, (sysarg_t) message, (sysarg_t) device_id,
+		async_msg_4(exch, message, (sysarg_t) device_id,
 		    (sysarg_t) packet_id, (sysarg_t) target, (sysarg_t) error);
 	} else {
-		async_obsolete_msg_3(phone, (sysarg_t) message, (sysarg_t) device_id,
+		async_msg_3(exch, message, (sysarg_t) device_id,
 		    (sysarg_t) packet_id, (sysarg_t) target);
 	}
 	
+	async_exchange_end(exch);
+	
 	return EOK;
 }
@@ -185,25 +199,30 @@
 /** Send the packet queue.
  *
- * @param[in] phone	The service module phone.
- * @param[in] message	The service specific message.
- * @param[in] device_id	The device identifier.
- * @param[in] packet_id	The packet or the packet queue identifier.
- * @param[in] sender	The sending module service.
- * @param[in] error	The error module service.
- * @return		EOK on success.
- *
- */
-int
-generic_send_msg_remote(int phone, int message, device_id_t device_id,
-    packet_id_t packet_id, services_t sender, services_t error)
-{
+ * @param[in] sess      Service module session.
+ * @param[in] message   Service specific message.
+ * @param[in] device_id Device identifier.
+ * @param[in] packet_id Packet or the packet queue identifier.
+ * @param[in] sender    Sending module service.
+ * @param[in] error     Error module service.
+ *
+ * @return EOK on success.
+ *
+ */
+int generic_send_msg_remote(async_sess_t *sess, sysarg_t message,
+    device_id_t device_id, packet_id_t packet_id, services_t sender,
+    services_t error)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	
 	if (error) {
-		async_obsolete_msg_4(phone, (sysarg_t) message, (sysarg_t) device_id,
+		async_msg_4(exch, message, (sysarg_t) device_id,
 		    (sysarg_t) packet_id, (sysarg_t) sender, (sysarg_t) error);
 	} else {
-		async_obsolete_msg_3(phone, (sysarg_t) message, (sysarg_t) device_id,
+		async_msg_3(exch, message, (sysarg_t) device_id,
 		    (sysarg_t) packet_id, (sysarg_t) sender);
 	}
 	
+	async_exchange_end(exch);
+	
 	return EOK;
 }
@@ -213,48 +232,51 @@
  * Allocates and returns the needed memory block as the data parameter.
  *
- * @param[in] phone	The service module phone.
- * @param[in] message	The service specific message.
- * @param[in] device_id	The device identifier.
- * @param[in] service	The module service.
- * @param[in] configuration The key strings.
- * @param[in] count	The number of configuration keys.
- * @param[out] translation The translated values.
- * @param[out] data	The translation data container.
- * @return		EOK on success.
- * @return		EINVAL if the configuration parameter is NULL.
- * @return		EINVAL if the count parameter is zero.
- * @return		EBADMEM if the translation or the data parameters are
- *			NULL.
- * @return		Other error codes as defined for the specific service
- *			message.
- */
-int
-generic_translate_req(int phone, int message, device_id_t device_id,
-    services_t service, measured_string_t *configuration, size_t count,
+ * @param[in] sess          Service module session.
+ * @param[in] message       Service specific message.
+ * @param[in] device_id     Device identifier.
+ * @param[in] service       Module service.
+ * @param[in] configuration Key strings.
+ * @param[in] count         Number of configuration keys.
+ * @param[out] translation  Translated values.
+ * @param[out] data         Translation data container.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the configuration parameter is NULL.
+ * @return EINVAL if the count parameter is zero.
+ * @return EBADMEM if the translation or the data parameters are
+ *         NULL.
+ * @return Other error codes as defined for the specific service
+ *         message.
+ *
+ */
+int generic_translate_req(async_sess_t *sess, sysarg_t message,
+    device_id_t device_id, services_t service,
+    measured_string_t *configuration, size_t count,
     measured_string_t **translation, uint8_t **data)
 {
-	aid_t message_id;
+	if ((!configuration) || (count == 0))
+		return EINVAL;
+	
+	if ((!translation) || (!data))
+		return EBADMEM;
+	
+	/* Request the translation */
+	async_exch_t *exch = async_exchange_begin(sess);
+	aid_t message_id = async_send_3(exch, message, (sysarg_t) device_id,
+	    (sysarg_t) count, (sysarg_t) service, NULL);
+	measured_strings_send(exch, configuration, count);
+	int rc = measured_strings_return(exch, translation, data, count);
+	async_exchange_end(exch);
+	
 	sysarg_t result;
-	int string;
-
-	if (!configuration || (count == 0))
-		return EINVAL;
-	if (!translation || !data)
-		return EBADMEM;
-
-	/* Request the translation */
-	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);
-	string = measured_strings_return(phone, translation, data, count);
 	async_wait_for(message_id, &result);
-
+	
 	/* If not successful */
-	if ((string == EOK) && (result != EOK)) {
+	if ((rc == EOK) && (result != EOK)) {
 		/* Clear the data */
 		free(*translation);
 		free(*data);
 	}
-
+	
 	return (int) result;
 }
Index: uspace/lib/net/generic/net_remote.c
===================================================================
--- uspace/lib/net/generic/net_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/generic/net_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -47,19 +47,22 @@
 #include <adt/measured_strings.h>
 
-/** Connects to the networking module.
+/** Connect to the networking module.
  *
- * @return		The networking module phone on success.
+ * @return Networking module session on success.
+ *
  */
-int net_connect_module(void)
+async_sess_t *net_connect_module(void)
 {
 	return connect_to_service(SERVICE_NETWORKING);
 }
 
-/** Frees the received settings.
+/** Free the received settings.
  *
- * @param[in] settings	The received settings.
- * @param[in] data	The received settings data.
- * @see	net_get_device_conf_req()
+ * @param[in] settings Received settings.
+ * @param[in] data     Received settings data.
+ *
+ * @see net_get_device_conf_req()
  * @see net_get_conf_req()
+ *
  */
 void net_free_settings(measured_string_t *settings, uint8_t *data)
@@ -71,5 +74,5 @@
 }
 
-/** Returns the global configuration.
+/** Return the global configuration.
  *
  * The configuration names are read and the appropriate settings are set
@@ -77,48 +80,52 @@
  * configuration.
  *
- * @param[in] net_phone	The networking module phone.
- * @param[in,out] configuration The requested configuration. The names are read
- * and the appropriate settings are set instead.
+ * @param[in]     sess          Networking module session.
+ * @param[in,out] configuration Requested configuration. The names are
+ *                              read and the appropriate settings are set
+ *                              instead.
  *
- * @param[in] count	The configuration entries count.
- * @param[in,out] data	The configuration and settings data.
- * @return		EOK on success.
- * @return		EINVAL if the configuration is NULL.
- * @return		EINVAL if the count is zero.
- * @return		Other error codes as defined for the
- *			generic_translate_req() function.
+ * @param[in]     count         Configuration entries count.
+ * @param[in,out] data          Configuration and settings data.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the configuration is NULL.
+ * @return EINVAL if the count is zero.
+ * @return Other error codes as defined for the
+ *         generic_translate_req() function.
+ *
  */
-int
-net_get_conf_req(int net_phone, measured_string_t **configuration,
+int net_get_conf_req(async_sess_t *sess, measured_string_t **configuration,
     size_t count, uint8_t **data)
 {
-	return generic_translate_req(net_phone, NET_NET_GET_DEVICE_CONF, 0, 0,
+	return generic_translate_req(sess, NET_NET_GET_DEVICE_CONF, 0, 0,
 	    *configuration, count, configuration, data);
 }
 
-/** Returns the device specific configuration.
+/** Return the device specific configuration.
  *
- * Returns the global configuration if the device specific is not found.
+ * Return the global configuration if the device specific is not found.
  * The configuration names are read and the appropriate settings are set
  * instead. Call net_free_settings() function to release the returned
  * configuration.
  *
- * @param[in] net_phone	The networking module phone.
- * @param[in] device_id	The device identifier.
- * @param[in,out] configuration The requested device configuration. The names
- *			are read and the appropriate settings are set instead.
- * @param[in] count	The configuration entries count.
- * @param[in,out] data	The configuration and settings data.
- * @return		EOK on success.
- * @return		EINVAL if the configuration is NULL.
- * @return		EINVAL if the count is zero.
- * @return		Other error codes as defined for the
- *			generic_translate_req() function.
+ * @param[in]     sess          The networking module session.
+ * @param[in]     device_id     Device identifier.
+ * @param[in,out] configuration Requested device configuration. The names
+ *                              are read and the appropriate settings are
+ *                              set instead.
+ * @param[in]     count         Configuration entries count.
+ * @param[in,out] data          Configuration and settings data.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the configuration is NULL.
+ * @return EINVAL if the count is zero.
+ * @return Other error codes as defined for the
+ *         generic_translate_req() function.
+ *
  */
-int
-net_get_device_conf_req(int net_phone, device_id_t device_id,
+int net_get_device_conf_req(async_sess_t *sess, device_id_t device_id,
     measured_string_t **configuration, size_t count, uint8_t **data)
 {
-	return generic_translate_req(net_phone, NET_NET_GET_DEVICE_CONF,
+	return generic_translate_req(sess, NET_NET_GET_DEVICE_CONF,
 	    device_id, 0, *configuration, count, configuration, data);
 }
Index: uspace/lib/net/generic/packet_client.c
===================================================================
--- uspace/lib/net/generic/packet_client.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/generic/packet_client.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -247,33 +247,34 @@
 }
 
-/** Returns the packet copy.
- *
- * Copies the addresses, data, order and metric values.
- * Does not copy the queue placement.
- *
- * @param[in] phone	The packet server module phone.
- * @param[in] packet	The original packet.
- * @return		The packet copy.
- * @return		NULL on error.
- */
-packet_t *packet_get_copy(int phone, packet_t *packet)
-{
-	packet_t *copy;
-	uint8_t * src = NULL;
-	uint8_t * dest = NULL;
-	size_t addrlen;
-
-	if (!packet_is_valid(packet))
-		return NULL;
-
+/** Return the packet copy.
+ *
+ * Copy the addresses, data, order and metric values.
+ * Queue placement is not copied.
+ *
+ * @param[in] sess   Packet server module session.
+ * @param[in] packet Original packet.
+ *
+ * @return Packet copy.
+ * @return NULL on error.
+ *
+ */
+packet_t *packet_get_copy(async_sess_t *sess, packet_t *packet)
+{
+	if (!packet_is_valid(packet))
+		return NULL;
+	
 	/* Get a new packet */
-	copy = packet_get_4_remote(phone, PACKET_DATA_LENGTH(packet),
+	packet_t *copy = packet_get_4_remote(sess, PACKET_DATA_LENGTH(packet),
 	    PACKET_MAX_ADDRESS_LENGTH(packet), packet->max_prefix,
 	    PACKET_MIN_SUFFIX(packet));
+	
 	if (!copy)
 		return NULL;
-
+	
 	/* Get addresses */
-	addrlen = packet_get_addr(packet, &src, &dest);
+	uint8_t *src = NULL;
+	uint8_t *dest = NULL;
+	size_t addrlen = packet_get_addr(packet, &src, &dest);
+	
 	/* Copy data */
 	if ((packet_copy_data(copy, packet_get_data(packet),
@@ -286,5 +287,5 @@
 		return copy;
 	} else {
-		pq_release_remote(phone, copy->packet_id);
+		pq_release_remote(sess, copy->packet_id);
 		return NULL;
 	}
Index: uspace/lib/net/generic/packet_remote.c
===================================================================
--- uspace/lib/net/generic/packet_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/generic/packet_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -37,5 +37,4 @@
 
 #include <async.h>
-#include <async_obsolete.h>
 #include <errno.h>
 #include <ipc/packet.h>
@@ -52,63 +51,64 @@
  * Create the local packet mapping as well.
  *
- * @param[in]  phone     The packet server module phone.
- * @param[out] packet    The packet reference pointer to store the received
+ * @param[in]  sess      Packet server module session.
+ * @param[out] packet    Packet reference pointer to store the received
  *                       packet reference.
- * @param[in]  packet_id The packet identifier.
- * @param[in]  size      The packet total size in bytes.
+ * @param[in]  packet_id Packet identifier.
+ * @param[in]  size      Packet total size in bytes.
  *
  * @return EOK on success.
  * @return Other error codes as defined for the pm_add() function.
- * @return Other error codes as defined for the async_obsolete_share_in_start() function.
- *
- */
-static int
-packet_return(int phone, packet_t **packet, packet_id_t packet_id, size_t size)
-{
+ * @return Other error codes as defined for the async_share_in_start()
+ *         function.
+ *
+ */
+static int packet_return(async_sess_t *sess, packet_t **packet,
+    packet_id_t packet_id, size_t size)
+{
+	*packet = (packet_t *) as_get_mappable_page(size);
+	
+	async_exch_t *exch = async_exchange_begin(sess);
 	ipc_call_t answer;
-	aid_t message;
-	int rc;
-	
-	message = async_obsolete_send_1(phone, NET_PACKET_GET, packet_id, &answer);
-
-	*packet = (packet_t *) as_get_mappable_page(size);
-	rc = async_obsolete_share_in_start_0_0(phone, *packet, size);
+	aid_t message = async_send_1(exch, NET_PACKET_GET, packet_id, &answer);
+	int rc = async_share_in_start_0_0(exch, *packet, size);
+	async_exchange_end(exch);
+	
+	sysarg_t result;
+	async_wait_for(message, &result);
+	
 	if (rc != EOK) {
 		munmap(*packet, size);
-		async_wait_for(message, NULL);
 		return rc;
 	}
+	
 	rc = pm_add(*packet);
 	if (rc != EOK) {
 		munmap(*packet, size);
-		async_wait_for(message, NULL);
 		return rc;
 	}
 	
-	sysarg_t result;
-	async_wait_for(message, &result);
-	
 	return result;
 }
 
-/** Translates the packet identifier to the packet reference.
- *
- * Tries to find mapping first.
- * Contacts the packet server to share the packet if the mapping is not present.
- *
- * @param[in] phone	The packet server module phone.
- * @param[out] packet	The packet reference.
- * @param[in] packet_id	The packet identifier.
- * @return		EOK on success.
- * @return		EINVAL if the packet parameter is NULL.
- * @return		Other error codes as defined for the NET_PACKET_GET_SIZE
- *			message.
- * @return		Other error codes as defined for the packet_return()
- *			function.
- */
-int packet_translate_remote(int phone, packet_t **packet, packet_id_t packet_id)
-{
-	int rc;
-	
+/** Translate the packet identifier to the packet reference.
+ *
+ * Try to find mapping first. The packet server is asked to share
+ * the packet if the mapping is not present.
+ *
+ * @param[in]  sess      Packet server module session.
+ * @param[out] packet    Packet reference.
+ * @param[in]  packet_id Packet identifier.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the packet parameter is NULL.
+ * @return Other error codes as defined for the NET_PACKET_GET_SIZE
+ *         message.
+ * @return Other error codes as defined for the packet_return()
+ *         function.
+ *
+ */
+int packet_translate_remote(async_sess_t *sess, packet_t **packet,
+    packet_id_t packet_id)
+{
 	if (!packet)
 		return EINVAL;
@@ -116,18 +116,21 @@
 	*packet = pm_find(packet_id);
 	if (!*packet) {
+		async_exch_t *exch = async_exchange_begin(sess);
 		sysarg_t size;
+		int rc = async_req_1_1(exch, NET_PACKET_GET_SIZE, packet_id,
+		    &size);
+		async_exchange_end(exch);
 		
-		rc = async_obsolete_req_1_1(phone, NET_PACKET_GET_SIZE, packet_id,
-		    &size);
 		if (rc != EOK)
 			return rc;
-		rc = packet_return(phone, packet, packet_id, size);
+		
+		rc = packet_return(sess, packet, packet_id, size);
 		if (rc != EOK)
 			return rc;
 	}
+	
 	if ((*packet)->next) {
 		packet_t *next;
-		
-		return packet_translate_remote(phone, &next, (*packet)->next);
+		return packet_translate_remote(sess, &next, (*packet)->next);
 	}
 	
@@ -135,33 +138,35 @@
 }
 
-/** Obtains the packet of the given dimensions.
- *
- * Contacts the packet server to return the appropriate packet.
- *
- * @param[in] phone	The packet server module phone.
- * @param[in] addr_len	The source and destination addresses maximal length in
- *			bytes.
- * @param[in] max_prefix The maximal prefix length in bytes.
- * @param[in] max_content The maximal content length in bytes.
- * @param[in] max_suffix The maximal suffix length in bytes.
- * @return		The packet reference.
- * @return		NULL on error.
- */
-packet_t *packet_get_4_remote(int phone, size_t max_content, size_t addr_len,
-    size_t max_prefix, size_t max_suffix)
-{
+/** Obtain the packet of given dimensions.
+ *
+ * Contact the packet server to return the appropriate packet.
+ *
+ * @param[in] sess        Packet server module session.
+ * @param[in] addr_len    Source and destination addresses maximal length
+ *                        in bytes.
+ * @param[in] max_prefix  Maximal prefix length in bytes.
+ * @param[in] max_content Maximal content length in bytes.
+ * @param[in] max_suffix  Maximal suffix length in bytes.
+ *
+ * @return The packet reference.
+ * @return NULL on error.
+ *
+ */
+packet_t *packet_get_4_remote(async_sess_t *sess, size_t max_content,
+    size_t addr_len, size_t max_prefix, size_t max_suffix)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
 	sysarg_t packet_id;
 	sysarg_t size;
-	int rc;
-	
-	rc = async_obsolete_req_4_2(phone, NET_PACKET_CREATE_4, max_content, addr_len,
+	int rc = async_req_4_2(exch, NET_PACKET_CREATE_4, max_content, addr_len,
 	    max_prefix, max_suffix, &packet_id, &size);
+	async_exchange_end(exch);
+	
 	if (rc != EOK)
 		return NULL;
 	
-	
 	packet_t *packet = pm_find(packet_id);
 	if (!packet) {
-		rc = packet_return(phone, &packet, packet_id, size);
+		rc = packet_return(sess, &packet, packet_id, size);
 		if (rc != EOK)
 			return NULL;
@@ -171,21 +176,24 @@
 }
 
-/** Obtains the packet of the given content size.
- *
- * Contacts the packet server to return the appropriate packet.
- *
- * @param[in] phone	The packet server module phone.
- * @param[in] content	The maximal content length in bytes.
- * @return		The packet reference.
- * @return		NULL on error.
- */
-packet_t *packet_get_1_remote(int phone, size_t content)
-{
+/** Obtain the packet of given content size.
+ *
+ * Contact the packet server to return the appropriate packet.
+ *
+ * @param[in] sess    Packet server module session.
+ * @param[in] content Maximal content length in bytes.
+ *
+ * @return The packet reference.
+ * @return NULL on error.
+ *
+ */
+packet_t *packet_get_1_remote(async_sess_t *sess, size_t content)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
 	sysarg_t packet_id;
 	sysarg_t size;
-	int rc;
-	
-	rc = async_obsolete_req_1_2(phone, NET_PACKET_CREATE_1, content, &packet_id,
+	int rc = async_req_1_2(exch, NET_PACKET_CREATE_1, content, &packet_id,
 	    &size);
+	async_exchange_end(exch);
+	
 	if (rc != EOK)
 		return NULL;
@@ -193,5 +201,5 @@
 	packet_t *packet = pm_find(packet_id);
 	if (!packet) {
-		rc = packet_return(phone, &packet, packet_id, size);
+		rc = packet_return(sess, &packet, packet_id, size);
 		if (rc != EOK)
 			return NULL;
@@ -201,5 +209,5 @@
 }
 
-/** Releases the packet queue.
+/** Release the packet queue.
  *
  * All packets in the queue are marked as free for use.
@@ -208,10 +216,13 @@
  * received or obtained again.
  *
- * @param[in] phone	The packet server module phone.
- * @param[in] packet_id	The packet identifier.
- */
-void pq_release_remote(int phone, packet_id_t packet_id)
-{
-	async_obsolete_msg_1(phone, NET_PACKET_RELEASE, packet_id);
+ * @param[in] sess      Packet server module session.
+ * @param[in] packet_id Packet identifier.
+ *
+ */
+void pq_release_remote(async_sess_t *sess, packet_id_t packet_id)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	async_msg_1(exch, NET_PACKET_RELEASE, packet_id);
+	async_exchange_end(exch);
 }
 
Index: uspace/lib/net/il/arp_remote.c
===================================================================
--- uspace/lib/net/il/arp_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/il/arp_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,25 +38,20 @@
 #include <arp_interface.h>
 #include <generic.h>
-
-#include <async.h>
-#include <async_obsolete.h>
-#include <errno.h>
 #include <ipc/services.h>
 #include <ipc/arp.h>
-
 #include <net/modules.h>
 #include <net/device.h>
 #include <adt/measured_strings.h>
+#include <async.h>
+#include <errno.h>
 
-/** Connects to the ARP module.
+/** Connect to the ARP module.
  *
- * @param service	The ARP module service. Ignored parameter.
- * @return		The ARP module phone on success.
+ * @return ARP module session on success.
+ *
  */
-int arp_connect_module(services_t service)
+async_sess_t *arp_connect_module(services_t service)
 {
-	if (service != SERVICE_ARP)
-		return EINVAL;
-
+	// FIXME: Get rid of the useless argument
 	return connect_to_service(SERVICE_ARP);
 }
@@ -64,31 +59,98 @@
 /** Cleans the cache.
  *
- * @param[in] arp_phone	The ARP module phone used for (semi)remote calls.
- * @return		EOK on success.
+ * @param[in] sess ARP module session.
+ *
+ * @return EOK on success.
+ *
  */
-int arp_clean_cache_req(int arp_phone)
+int arp_clean_cache_req(async_sess_t *sess)
 {
-	return (int) async_obsolete_req_0_0(arp_phone, NET_ARP_CLEAN_CACHE);
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_0_0(exch, NET_ARP_CLEAN_CACHE);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
-/** Clears the given protocol address from the cache.
+/** Clear the given protocol address from the cache.
  *
- * @param[in] arp_phone	The ARP module phone used for (semi)remote calls.
- * @param[in] device_id	The device identifier.
- * @param[in] protocol	The requesting protocol service.
- * @param[in] address	The protocol address to be cleared.
- * @return		EOK on success.
- * @return		ENOENT if the mapping is not found.
+ * @param[in] sess      ARP module session.
+ * @param[in] device_id Device identifier.
+ * @param[in] protocol  Requesting protocol service.
+ * @param[in] address   Protocol address to be cleared.
+ *
+ * @return EOK on success.
+ * @return ENOENT if the mapping is not found.
+ *
  */
-int
-arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol,
-    measured_string_t *address)
+int arp_clear_address_req(async_sess_t *sess, device_id_t device_id,
+    services_t protocol, measured_string_t *address)
 {
-	aid_t message_id;
+	async_exch_t *exch = async_exchange_begin(sess);
+	aid_t message_id = async_send_2(exch, NET_ARP_CLEAR_ADDRESS,
+	    (sysarg_t) device_id, protocol, NULL);
+	measured_strings_send(exch, address, 1);
+	async_exchange_end(exch);
+	
 	sysarg_t result;
+	async_wait_for(message_id, &result);
+	
+	return (int) result;
+}
 
-	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);
+/** Clear the device cache.
+ *
+ * @param[in] sess      ARP module session.
+ * @param[in] device_id Device identifier.
+ *
+ * @return EOK on success.
+ * @return ENOENT if the device is not found.
+ *
+ */
+int arp_clear_device_req(async_sess_t *sess, device_id_t device_id)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_1_0(exch, NET_ARP_CLEAR_DEVICE,
+	    (sysarg_t) device_id);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Register new device and the requesting protocol service.
+ *
+ * Connect to the network interface layer service.
+ * Determine the device broadcast address, its address lengths and packet size.
+ *
+ * @param[in] sess      ARP module session.
+ * @param[in] device_id New device identifier.
+ * @param[in] protocol  Requesting protocol service.
+ * @param[in] netif     Underlying device network interface layer service.
+ * @param[in] address   Local requesting protocol address of the device.
+ *
+ * @return EOK on success.
+ * @return EEXIST if the device is already used.
+ * @return ENOMEM if there is not enough memory left.
+ * @return ENOENT if the network interface service is not known.
+ * @return EREFUSED if the network interface service is not
+ *         responding.
+ * @return Other error codes as defined for the
+ *         nil_packet_get_size() function.
+ * @return Other error codes as defined for the nil_get_addr()
+ *         function.
+ * @return Other error codes as defined for the
+ *         nil_get_broadcast_addr() function.
+ *
+ */
+int arp_device_req(async_sess_t *sess, device_id_t device_id,
+    services_t protocol, services_t netif, measured_string_t *address)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	aid_t message_id = async_send_3(exch, NET_ARP_DEVICE,
+	    (sysarg_t) device_id, protocol, netif, NULL);
+	measured_strings_send(exch, address, 1);
+	async_exchange_end(exch);
+	
+	sysarg_t result;
 	async_wait_for(message_id, &result);
 
@@ -96,76 +158,28 @@
 }
 
-/** Clears the device cache.
+/** Translate the given protocol address to the network interface address.
  *
- * @param[in] arp_phone	The ARP module phone used for (semi)remote calls.
- * @param[in] device_id	The device identifier.
- * @return		EOK on success.
- * @return		ENOENT if the device is not found.
+ * Broadcast the ARP request if the mapping is not found.
+ * Allocate and returns the needed memory block as the data parameter.
+ *
+ * @param[in]  sess        ARP module session.
+ * @param[in]  device_id   Device identifier.
+ * @param[in]  protocol    Requesting protocol service.
+ * @param[in]  address     Local requesting protocol address.
+ * @param[out] translation Translation of the local protocol address.
+ * @param[out] data        Allocated raw translation data container.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the address parameter is NULL.
+ * @return EBADMEM if the translation or the data parameters are
+ *         NULL.
+ * @return ENOENT if the mapping is not found.
+ *
  */
-int arp_clear_device_req(int arp_phone, device_id_t device_id)
+int arp_translate_req(async_sess_t *sess, device_id_t device_id,
+    services_t protocol, measured_string_t *address,
+    measured_string_t **translation, uint8_t **data)
 {
-	return (int) async_obsolete_req_1_0(arp_phone, NET_ARP_CLEAR_DEVICE,
-	    (sysarg_t) device_id);
-}
-
-/** Registers the new device and the requesting protocol service.
- *
- * Connects to the network interface layer service.
- * Determines the device broadcast address, its address lengths and packet size.
- *
- * @param[in] arp_phone	The ARP module phone used for (semi)remote calls.
- * @param[in] device_id	The new device identifier.
- * @param[in] protocol	The requesting protocol service.
- * @param[in] netif	The underlying device network interface layer service.
- * @param[in] address	The local requesting protocol address of the device.
- * @return		EOK on success.
- * @return		EEXIST if the device is already used.
- * @return		ENOMEM if there is not enough memory left.
- * @return		ENOENT if the network interface service is not known.
- * @return		EREFUSED if the network interface service is not
- *			responding.
- * @return		Other error codes as defined for the
- *			nil_packet_get_size() function.
- * @return		Other error codes as defined for the nil_get_addr()
- *			function.
- * @return		Other error codes as defined for the
- *			nil_get_broadcast_addr() function.
- */
-int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol,
-    services_t netif, measured_string_t *address)
-{
-	aid_t message_id;
-	sysarg_t result;
-
-	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);
-	async_wait_for(message_id, &result);
-
-	return (int) result;
-}
-
-/** Translates the given protocol address to the network interface address.
- *
- * Broadcasts the ARP request if the mapping is not found.
- * Allocates and returns the needed memory block as the data parameter.
- *
- * @param[in] arp_phone	The ARP module phone used for (semi)remote calls.
- * @param[in] device_id	The device identifier.
- * @param[in] protocol	The requesting protocol service.
- * @param[in] address	The local requesting protocol address.
- * @param[out] translation The translation of the local protocol address.
- * @param[out] data	The allocated raw translation data container.
- * @return		EOK on success.
- * @return		EINVAL if the address parameter is NULL.
- * @return		EBADMEM if the translation or the data parameters are
- *			NULL.
- * @return		ENOENT if the mapping is not found.
- */
-int
-arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol,
-    measured_string_t *address, measured_string_t **translation, uint8_t **data)
-{
-	return generic_translate_req(arp_phone, NET_ARP_TRANSLATE, device_id,
+	return generic_translate_req(sess, NET_ARP_TRANSLATE, device_id,
 	    protocol, address, 1, translation, data);
 }
Index: uspace/lib/net/il/il_remote.c
===================================================================
--- uspace/lib/net/il/il_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/il/il_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,8 +39,6 @@
 #include <generic.h>
 #include <packet_client.h>
-
 #include <ipc/services.h>
 #include <ipc/il.h>
-
 #include <net/device.h>
 #include <net/packet.h>
@@ -48,9 +46,8 @@
 /** Notify the internetwork layer modules about the device state change.
  *
- * @param[in] il_phone  The internetwork layer module phone used for
- *                      (semi)remote calls.
- * @param[in] device_id The device identifier.
- * @param[in] state     The new device state.
- * @param[in] target    The target internetwork module service to be
+ * @param[in] sess      Internetwork layer module session.
+ * @param[in] device_id Device identifier.
+ * @param[in] state     New device state.
+ * @param[in] target    Target internetwork module service to be
  *                      delivered to.
  *
@@ -58,8 +55,8 @@
  *
  */
-int il_device_state_msg(int il_phone, device_id_t device_id,
+int il_device_state_msg(async_sess_t *sess, device_id_t device_id,
     device_state_t state, services_t target)
 {
-	return generic_device_state_msg_remote(il_phone, NET_IL_DEVICE_STATE,
+	return generic_device_state_msg_remote(sess, NET_IL_DEVICE_STATE,
 	    device_id, state, target);
 }
@@ -67,9 +64,8 @@
 /** Notify the internetwork layer modules about the received packet/s.
  *
- * @param[in] il_phone  The internetwork layer module phone used for
- *                      (semi)remote calls.
- * @param[in] device_id The device identifier.
- * @param[in] packet    The received packet or the received packet queue.
- * @param[in] target    The target internetwork module service to be
+ * @param[in] sess      Internetwork layer module session.
+ * @param[in] device_id Device identifier.
+ * @param[in] packet    Received packet or the received packet queue.
+ * @param[in] target    Target internetwork module service to be
  *                      delivered to.
  *
@@ -77,8 +73,8 @@
  *
  */
-int il_received_msg(int il_phone, device_id_t device_id, packet_t *packet,
+int il_received_msg(async_sess_t *sess, device_id_t device_id, packet_t *packet,
     services_t target)
 {
-	return generic_received_msg_remote(il_phone, NET_IL_RECEIVED, device_id,
+	return generic_received_msg_remote(sess, NET_IL_RECEIVED, device_id,
 	    packet_get_id(packet), target, 0);
 }
@@ -86,9 +82,8 @@
 /** Notify the internetwork layer modules about the mtu change.
  *
- * @param[in] il_phone  The internetwork layer module phone used for
- *                      (semi)remote calls.
- * @param[in] device_id The device identifier.
- * @param[in] mtu       The new mtu value.
- * @param[in] target    The target internetwork module service to be
+ * @param[in] sess      Internetwork layer module session.
+ * @param[in] device_id Device identifier.
+ * @param[in] mtu       New MTU value.
+ * @param[in] target    Target internetwork module service to be
  *                      delivered to.
  *
@@ -96,9 +91,9 @@
  *
  */
-int il_mtu_changed_msg(int il_phone, device_id_t device_id, size_t mtu,
+int il_mtu_changed_msg(async_sess_t *sess, device_id_t device_id, size_t mtu,
     services_t target)
 {
-	return generic_device_state_msg_remote(il_phone, NET_IL_MTU_CHANGED,
-	    device_id, (int) mtu, target);
+	return generic_device_state_msg_remote(sess, NET_IL_MTU_CHANGED,
+	    device_id, mtu, target);
 }
 
Index: uspace/lib/net/il/il_skel.c
===================================================================
--- uspace/lib/net/il/il_skel.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/il/il_skel.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,10 +38,8 @@
 #include <bool.h>
 #include <errno.h>
+#include <ns.h>
 #include <il_skel.h>
 #include <net_interface.h>
 #include <net/modules.h>
-
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
 
 /** Default thread for new connections.
@@ -99,14 +97,12 @@
  * @return Other error codes as defined for the il_initialize()
  *         function.
- * @return Other error codes as defined for the REGISTER_ME() macro
- *         function.
  *
  */
-int il_module_start(int service)
+int il_module_start(sysarg_t service)
 {
 	async_set_client_connection(il_client_connection);
-	int net_phone = net_connect_module();
-	if (net_phone < 0)
-		return net_phone;
+	async_sess_t *sess = net_connect_module();
+	if (!sess)
+		return ENOENT;
 	
 	int rc = pm_init();
@@ -114,9 +110,9 @@
 		return rc;
 	
-	rc = il_initialize(net_phone);
+	rc = il_initialize(sess);
 	if (rc != EOK)
 		goto out;
 	
-	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL, NULL);
+	rc = service_register(service);
 	if (rc != EOK)
 		goto out;
Index: uspace/lib/net/il/ip_remote.c
===================================================================
--- uspace/lib/net/il/ip_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/il/ip_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -44,9 +44,7 @@
 #include <packet_client.h>
 #include <generic.h>
-#include <async_obsolete.h>
 #include <ipc/services.h>
 #include <ipc/il.h>
 #include <ipc/ip.h>
-
 #include <net/modules.h>
 #include <net/device.h>
@@ -57,44 +55,50 @@
  * The target network is routed using this device.
  *
- * @param[in] ip_phone	The IP module phone used for (semi)remote calls.
- * @param[in] device_id	The device identifier.
- * @param[in] address	The target network address.
- * @param[in] netmask	The target network mask.
- * @param[in] gateway	The target network gateway. Not used if zero.
- */
-int ip_add_route_req_remote(int ip_phone, device_id_t device_id,
+ * @param[in] sess      IP module sessions.
+ * @param[in] device_id Device identifier.
+ * @param[in] address   Target network address.
+ * @param[in] netmask   Target network mask.
+ * @param[in] gateway   Target network gateway. Not used if zero.
+ *
+ */
+int ip_add_route_req_remote(async_sess_t *sess, device_id_t device_id,
     in_addr_t address, in_addr_t netmask, in_addr_t gateway)
 {
-	return (int) async_obsolete_req_4_0(ip_phone, NET_IP_ADD_ROUTE,
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_4_0(exch, NET_IP_ADD_ROUTE,
 	    (sysarg_t) device_id, (sysarg_t) gateway.s_addr,
 	    (sysarg_t) address.s_addr, (sysarg_t) netmask.s_addr);
-}
-
-/** Creates bidirectional connection with the ip module service and registers
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Create bidirectional connection with the ip module service and register
  * the message receiver.
  *
- * @param[in] service	The IP module service.
- * @param[in] protocol	The transport layer protocol.
- * @param[in] me	The requesting module service.
- * @param[in] receiver	The message receiver. Used for remote connection.
- * @return		The phone of the needed service.
- * @return		EOK on success.
- * @return		Other error codes as defined for the bind_service()
- *			function.
- */
-int ip_bind_service(services_t service, int protocol, services_t me,
+ * @param[in] service  IP module service.
+ * @param[in] protocol Transport layer protocol.
+ * @param[in] me       Rquesting module service.
+ * @param[in] receiver Message receiver. Used for remote connection.
+ *
+ * @return Session to the needed service.
+ * @return NULL on failure.
+ *
+ */
+async_sess_t *ip_bind_service(services_t service, int protocol, services_t me,
     async_client_conn_t receiver)
 {
-	return (int) bind_service(service, (sysarg_t) protocol, me, service,
+	return bind_service(service, (sysarg_t) protocol, me, service,
 	    receiver);
 }
 
-/** Connects to the IP module.
- *
- * @param service	The IP module service. Ignored parameter.
- * @return		The IP module phone on success.
- */
-int ip_connect_module(services_t service)
-{
+/** Connect to the IP module.
+ *
+ * @return The IP module session.
+ *
+ */
+async_sess_t *ip_connect_module(services_t service)
+{
+	// FIXME: Get rid of the useless argument
 	return connect_to_service(SERVICE_IP);
 }
@@ -105,21 +109,22 @@
  * If the device uses ARP registers also the new ARP device.
  *
- * @param[in] ip_phone	The IP module phone used for (semi)remote calls.
- * @param[in] device_id	The new device identifier.
- * @param[in] netif	The underlying device network interface layer service.
- * @return		EOK on success.
- * @return		ENOMEM if there is not enough memory left.
- * @return		EINVAL if the device configuration is invalid.
- * @return		ENOTSUP if the device uses IPv6.
- * @return		ENOTSUP if the device uses DHCP.
- * @return		Other error codes as defined for the
- *			net_get_device_conf_req() function.
- * @return		Other error codes as defined for the arp_device_req()
- *			function.
- */
-int ip_device_req_remote(int ip_phone, device_id_t device_id,
+ * @param[in] sess      IP module session.
+ * @param[in] device_id New device identifier.
+ *
+ * @return EOK on success.
+ * @return ENOMEM if there is not enough memory left.
+ * @return EINVAL if the device configuration is invalid.
+ * @return ENOTSUP if the device uses IPv6.
+ * @return ENOTSUP if the device uses DHCP.
+ * @return Other error codes as defined for the
+ *         net_get_device_conf_req() function.
+ * @return Other error codes as defined for the arp_device_req()
+ *         function.
+ *
+ */
+int ip_device_req_remote(async_sess_t *sess, device_id_t device_id,
     services_t service)
 {
-	return generic_device_req_remote(ip_phone, NET_IP_DEVICE, device_id, 0,
+	return generic_device_req_remote(sess, NET_IP_DEVICE, device_id, 0,
 	    service);
 }
@@ -128,35 +133,37 @@
  * destination address.
  *
- * @param[in] ip_phone	The IP module phone used for (semi)remote calls.
- * @param[in] protocol	The transport protocol.
- * @param[in] destination The destination address.
- * @param[in] addrlen	The destination address length.
- * @param[out] device_id The device identifier.
- * @param[out] header	The constructed IP pseudo header.
- * @param[out] headerlen The IP pseudo header length.
- *
- */
-int ip_get_route_req_remote(int ip_phone, ip_protocol_t protocol,
+ * @param[in] sess        IP module session.
+ * @param[in] protocol    Transport protocol.
+ * @param[in] destination Destination address.
+ * @param[in] addrlen     Destination address length.
+ * @param[out] device_id  Device identifier.
+ * @param[out] header     Constructed IP pseudo header.
+ * @param[out] headerlen  IP pseudo header length.
+ *
+ */
+int ip_get_route_req_remote(async_sess_t *sess, ip_protocol_t protocol,
     const struct sockaddr *destination, socklen_t addrlen,
     device_id_t *device_id, void **header, size_t *headerlen)
 {
-	if (!destination || (addrlen == 0))
+	if ((!destination) || (addrlen == 0))
 		return EINVAL;
 	
-	if (!device_id || !header || !headerlen)
+	if ((!device_id) || (!header) || (!headerlen))
 		return EBADMEM;
 	
 	*header = NULL;
 	
+	async_exch_t *exch = async_exchange_begin(sess);
+	
 	ipc_call_t answer;
-	aid_t message_id = async_obsolete_send_1(ip_phone, NET_IP_GET_ROUTE,
+	aid_t message_id = async_send_1(exch, NET_IP_GET_ROUTE,
 	    (sysarg_t) protocol, &answer);
 	
-	if ((async_obsolete_data_write_start(ip_phone, destination, addrlen) == EOK) &&
-	    (async_obsolete_data_read_start(ip_phone, headerlen,
-	    sizeof(*headerlen)) == EOK) && (*headerlen > 0)) {
+	if ((async_data_write_start(exch, destination, addrlen) == EOK) &&
+	    (async_data_read_start(exch, headerlen, sizeof(*headerlen)) == EOK) &&
+	    (*headerlen > 0)) {
 		*header = malloc(*headerlen);
 		if (*header) {
-			if (async_obsolete_data_read_start(ip_phone, *header,
+			if (async_data_read_start(exch, *header,
 			    *headerlen) != EOK)
 				free(*header);
@@ -164,4 +171,6 @@
 	}
 	
+	async_exchange_end(exch);
+	
 	sysarg_t result;
 	async_wait_for(message_id, &result);
@@ -177,16 +186,18 @@
 /** Return the device packet dimension for sending.
  *
- * @param[in] ip_phone	The IP module phone used for (semi)remote calls.
- * @param[in] device_id	The device identifier.
- * @param[out] packet_dimension The packet dimension.
- * @return		EOK on success.
- * @return		ENOENT if there is no such device.
- * @return		Other error codes as defined for the
- *			generic_packet_size_req_remote() function.
- */
-int ip_packet_size_req_remote(int ip_phone, device_id_t device_id,
+ * @param[in] sess              IP module session.
+ * @param[in] device_id         Device identifier.
+ * @param[out] packet_dimension Packet dimension.
+ *
+ * @return EOK on success.
+ * @return ENOENT if there is no such device.
+ * @return Other error codes as defined for the
+ *         generic_packet_size_req_remote() function.
+ *
+ */
+int ip_packet_size_req_remote(async_sess_t *sess, device_id_t device_id,
     packet_dimension_t *packet_dimension)
 {
-	return generic_packet_size_req_remote(ip_phone, NET_IP_PACKET_SPACE,
+	return generic_packet_size_req_remote(sess, NET_IP_PACKET_SPACE,
 	    device_id, packet_dimension);
 }
@@ -194,17 +205,19 @@
 /** Notify the IP module about the received error notification packet.
  *
- * @param[in] ip_phone	The IP module phone used for (semi)remote calls.
- * @param[in] device_id	The device identifier.
- * @param[in] packet	The received packet or the received packet queue.
- * @param[in] target	The target internetwork module service to be
- *			delivered to.
- * @param[in] error	The packet error reporting service. Prefixes the
- *			received packet.
- * @return		EOK on success.
- */
-int ip_received_error_msg_remote(int ip_phone, device_id_t device_id,
+ * @param[in] sess      IP module session.
+ * @param[in] device_id Device identifier.
+ * @param[in] packet    Received packet or the received packet queue.
+ * @param[in] target    Target internetwork module service to be
+ *                      delivered to.
+ * @param[in] error     Packet error reporting service. Prefixes the
+ *                      received packet.
+ *
+ * @return EOK on success.
+ *
+ */
+int ip_received_error_msg_remote(async_sess_t *sess, device_id_t device_id,
     packet_t *packet, services_t target, services_t error)
 {
-	return generic_received_msg_remote(ip_phone, NET_IP_RECEIVED_ERROR,
+	return generic_received_msg_remote(sess, NET_IP_RECEIVED_ERROR,
 	    device_id, packet_get_id(packet), target, error);
 }
@@ -214,19 +227,21 @@
  * The packets may get fragmented if needed.
  *
- * @param[in] ip_phone	The IP module phone used for (semi)remote calls.
- * @param[in] device_id	The device identifier.
- * @param[in] packet	The packet fragments as a packet queue. All the
- *			packets have to have the same destination address.
- * @param[in] sender	The sending module service.
- * @param[in] error	The packet error reporting service. Prefixes the
- *			received packet.
- * @return		EOK on success.
- * @return		Other error codes as defined for the generic_send_msg()
- *			function.
- */
-int ip_send_msg_remote(int ip_phone, device_id_t device_id, packet_t *packet,
-    services_t sender, services_t error)
-{
-	return generic_send_msg_remote(ip_phone, NET_IP_SEND, device_id,
+ * @param[in] sess      IP module session.
+ * @param[in] device_id Device identifier.
+ * @param[in] packet    Packet fragments as a packet queue. All the
+ *                      packets have to have the same destination address.
+ * @param[in] sender    Sending module service.
+ * @param[in] error     Packet error reporting service. Prefixes the
+ *                      received packet.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the generic_send_msg()
+ *         function.
+ *
+ */
+int ip_send_msg_remote(async_sess_t *sess, device_id_t device_id,
+    packet_t *packet, services_t sender, services_t error)
+{
+	return generic_send_msg_remote(sess, NET_IP_SEND, device_id,
 	    packet_get_id(packet), sender, error);
 }
@@ -236,13 +251,18 @@
  * This gateway is used if no other route is found.
  *
- * @param[in] ip_phone	The IP module phone used for (semi)remote calls.
- * @param[in] device_id	The device identifier.
- * @param[in] gateway	The default gateway.
- */
-int ip_set_gateway_req_remote(int ip_phone, device_id_t device_id,
+ * @param[in] sess      IP module session.
+ * @param[in] device_id Device identifier.
+ * @param[in] gateway   Default gateway.
+ *
+ */
+int ip_set_gateway_req_remote(async_sess_t *sess, device_id_t device_id,
     in_addr_t gateway)
 {
-	return (int) async_obsolete_req_2_0(ip_phone, NET_IP_SET_GATEWAY,
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_2_0(exch, NET_IP_SET_GATEWAY,
 	    (sysarg_t) device_id, (sysarg_t) gateway.s_addr);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
Index: uspace/lib/net/include/adt/module_map.h
===================================================================
--- uspace/lib/net/include/adt/module_map.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/adt/module_map.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,5 +39,5 @@
 
 #include <task.h>
-#include <ipc/services.h>
+#include <async.h>
 #include <net/modules.h>
 #include <adt/generic_char_map.h>
@@ -60,6 +60,6 @@
 	/** Module service identifier. */
 	services_t service;
-	/** Module phone if running and connected. */
-	int phone;
+	/** Module session if running and connected. */
+	async_sess_t *sess;
 	/** Usage counter. */
 	int usage;
Index: uspace/lib/net/include/arp_interface.h
===================================================================
--- uspace/lib/net/include/arp_interface.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/arp_interface.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -36,9 +36,8 @@
 #include <adt/measured_strings.h>
 #include <task.h>
-
 #include <ipc/services.h>
-
 #include <net/device.h>
 #include <net/socket.h>
+#include <async.h>
 
 /** @name ARP module interface
@@ -47,13 +46,13 @@
 /*@{*/
 
-extern int arp_device_req(int, device_id_t, services_t, services_t,
+extern int arp_device_req(async_sess_t *, device_id_t, services_t, services_t,
     measured_string_t *);
-extern int arp_translate_req(int, device_id_t, services_t, measured_string_t *,
-    measured_string_t **, uint8_t **);
-extern int arp_clear_device_req(int, device_id_t);
-extern int arp_clear_address_req(int, device_id_t, services_t,
+extern int arp_translate_req(async_sess_t *, device_id_t, services_t,
+    measured_string_t *, measured_string_t **, uint8_t **);
+extern int arp_clear_device_req(async_sess_t *, device_id_t);
+extern int arp_clear_address_req(async_sess_t *, device_id_t, services_t,
     measured_string_t *);
-extern int arp_clean_cache_req(int);
-extern int arp_connect_module(services_t);
+extern int arp_clean_cache_req(async_sess_t *);
+extern async_sess_t *arp_connect_module(services_t);
 
 /*@}*/
Index: uspace/lib/net/include/generic.h
===================================================================
--- uspace/lib/net/include/generic.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/generic.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,24 +38,24 @@
 #define LIBNET_GENERIC_H_
 
-#include <async.h>
 #include <ipc/services.h>
-
 #include <net/device.h>
 #include <adt/measured_strings.h>
 #include <net/packet.h>
+#include <async.h>
 
-extern int generic_device_state_msg_remote(int, int, device_id_t, int,
-    services_t);
-extern int generic_device_req_remote(int, int, device_id_t, int, services_t);
-extern int generic_get_addr_req(int, int, device_id_t, measured_string_t **,
-    uint8_t **);
-extern int generic_packet_size_req_remote(int, int, device_id_t,
+extern int generic_device_state_msg_remote(async_sess_t *, sysarg_t,
+    device_id_t, sysarg_t, services_t);
+extern int generic_device_req_remote(async_sess_t *, sysarg_t, device_id_t,
+    sysarg_t, services_t);
+extern int generic_get_addr_req(async_sess_t *, sysarg_t, device_id_t,
+    measured_string_t **, uint8_t **);
+extern int generic_packet_size_req_remote(async_sess_t *, sysarg_t, device_id_t,
     packet_dimension_t *);
-extern int generic_received_msg_remote(int, int, device_id_t, packet_id_t,
-    services_t, services_t);
-extern int generic_send_msg_remote(int, int, device_id_t, packet_id_t,
-    services_t, services_t);
-extern int generic_translate_req(int, int, device_id_t, services_t,
-    measured_string_t *, size_t, measured_string_t **, uint8_t **);
+extern int generic_received_msg_remote(async_sess_t *, sysarg_t, device_id_t,
+    packet_id_t, services_t, services_t);
+extern int generic_send_msg_remote(async_sess_t *, sysarg_t, device_id_t,
+    packet_id_t, services_t, services_t);
+extern int generic_translate_req(async_sess_t *, sysarg_t, device_id_t,
+    services_t, measured_string_t *, size_t, measured_string_t **, uint8_t **);
 
 #endif
Index: uspace/lib/net/include/icmp_remote.h
===================================================================
--- uspace/lib/net/include/icmp_remote.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/icmp_remote.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -36,5 +36,4 @@
 #include <net/socket_codes.h>
 #include <sys/types.h>
-
 #include <net/device.h>
 #include <adt/measured_strings.h>
@@ -44,4 +43,5 @@
 #include <net/icmp_codes.h>
 #include <net/icmp_common.h>
+#include <async.h>
 
 /** @name ICMP module interface
@@ -50,9 +50,9 @@
 /*@{*/
 
-extern int icmp_destination_unreachable_msg(int, icmp_code_t, icmp_param_t,
-    packet_t *);
-extern int icmp_source_quench_msg(int, packet_t *);
-extern int icmp_time_exceeded_msg(int, icmp_code_t, packet_t *);
-extern int icmp_parameter_problem_msg(int, icmp_code_t, icmp_param_t,
+extern int icmp_destination_unreachable_msg(async_sess_t *, icmp_code_t,
+    icmp_param_t, packet_t *);
+extern int icmp_source_quench_msg(async_sess_t *, packet_t *);
+extern int icmp_time_exceeded_msg(async_sess_t *, icmp_code_t, packet_t *);
+extern int icmp_parameter_problem_msg(async_sess_t *, icmp_code_t, icmp_param_t,
     packet_t *);
 
Index: uspace/lib/net/include/il_remote.h
===================================================================
--- uspace/lib/net/include/il_remote.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/il_remote.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -41,7 +41,7 @@
 #include <ipc/services.h>
 #include <sys/types.h>
-
 #include <net/device.h>
 #include <net/packet.h>
+#include <async.h>
 
 /** @name Internetwork layer module interface
@@ -50,7 +50,8 @@
 /*@{*/
 
-extern int il_device_state_msg(int, device_id_t, device_state_t, services_t);
-extern int il_received_msg(int, device_id_t, packet_t *, services_t);
-extern int il_mtu_changed_msg(int, device_id_t, size_t, services_t);
+extern int il_device_state_msg(async_sess_t *, device_id_t, device_state_t,
+    services_t);
+extern int il_received_msg(async_sess_t *, device_id_t, packet_t *, services_t);
+extern int il_mtu_changed_msg(async_sess_t *, device_id_t, size_t, services_t);
 
 /*@}*/
Index: uspace/lib/net/include/il_skel.h
===================================================================
--- uspace/lib/net/include/il_skel.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/il_skel.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,11 +39,9 @@
  */
 
-#include <async.h>
-#include <fibril_synch.h>
 #include <ipc/services.h>
-
 #include <adt/measured_strings.h>
 #include <net/device.h>
 #include <net/packet.h>
+#include <async.h>
 
 /** Module initialization.
@@ -51,5 +49,5 @@
  * This has to be implemented in user code.
  *
- * @param[in] net_phone Networking module phone.
+ * @param[in] sess Networking module session.
  *
  * @return EOK on success.
@@ -58,5 +56,5 @@
  *
  */
-extern int il_initialize(int net_phone);
+extern int il_initialize(async_sess_t *sess);
 
 /** Process the internetwork layer module message.
@@ -76,5 +74,5 @@
     ipc_call_t *answer, size_t *answer_count);
 
-extern int il_module_start(int);
+extern int il_module_start(sysarg_t);
 
 #endif
Index: uspace/lib/net/include/ip_interface.h
===================================================================
--- uspace/lib/net/include/ip_interface.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/ip_interface.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -35,14 +35,11 @@
 
 #include <net/socket_codes.h>
-#include <async.h>
 #include <ipc/services.h>
-
 #include <net/device.h>
 #include <net/packet.h>
-
 #include <net/in.h>
 #include <net/ip_codes.h>
-
 #include <ip_remote.h>
+#include <async.h>
 
 #define ip_received_error_msg  ip_received_error_msg_remote
@@ -61,18 +58,20 @@
 /** The transport layer notification function type definition.
  *
- * Notifies the transport layer modules about the received packet/s.
+ * Notify the transport layer modules about the received packet/s.
  *
- * @param[in] device_id	The device identifier.
- * @param[in] packet	The received packet or the received packet queue.
- * @param[in] receiver	The receiving module service.
- * @param[in] error	The packet error reporting service. Prefixes the
- *			received packet.
- * @return		EOK on success.
+ * @param[in] device_id Device identifier.
+ * @param[in] packet    Received packet or the received packet queue.
+ * @param[in] receiver  Receiving module service.
+ * @param[in] error     Packet error reporting service. Prefixes the
+ *                      received packet.
+ *
+ * @return EOK on success.
+ *
  */
 typedef int (*tl_received_msg_t)(device_id_t device_id, packet_t *packet,
     services_t receiver, services_t error);
 
-extern int ip_bind_service(services_t, int, services_t, async_client_conn_t);
-extern int ip_connect_module(services_t);
+extern async_sess_t *ip_bind_service(services_t, int, services_t, async_client_conn_t);
+extern async_sess_t *ip_connect_module(services_t);
 
 /*@}*/
Index: uspace/lib/net/include/ip_remote.h
===================================================================
--- uspace/lib/net/include/ip_remote.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/ip_remote.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -35,5 +35,4 @@
 
 #include <ipc/services.h>
-
 #include <net/ip_codes.h>
 #include <net/inet.h>
@@ -42,16 +41,18 @@
 #include <net/device.h>
 #include <net/socket.h>
+#include <async.h>
 
-extern int ip_set_gateway_req_remote(int, device_id_t, in_addr_t);
-extern int ip_packet_size_req_remote(int, device_id_t, packet_dimension_t *);
-extern int ip_received_error_msg_remote(int, device_id_t, packet_t *, services_t,
-    services_t);
-extern int ip_device_req_remote(int, device_id_t, services_t);
-extern int ip_add_route_req_remote(int, device_id_t, in_addr_t, in_addr_t,
-    in_addr_t);
-extern int ip_send_msg_remote(int, device_id_t, packet_t *, services_t,
-    services_t);
-extern int ip_get_route_req_remote(int, ip_protocol_t, const struct sockaddr *,
-    socklen_t, device_id_t *, void **, size_t *);
+extern int ip_set_gateway_req_remote(async_sess_t *, device_id_t, in_addr_t);
+extern int ip_packet_size_req_remote(async_sess_t *, device_id_t,
+    packet_dimension_t *);
+extern int ip_received_error_msg_remote(async_sess_t *, device_id_t, packet_t *,
+    services_t, services_t);
+extern int ip_device_req_remote(async_sess_t *, device_id_t, services_t);
+extern int ip_add_route_req_remote(async_sess_t *, device_id_t, in_addr_t,
+    in_addr_t, in_addr_t);
+extern int ip_send_msg_remote(async_sess_t *, device_id_t, packet_t *,
+    services_t, services_t);
+extern int ip_get_route_req_remote(async_sess_t *, ip_protocol_t,
+    const struct sockaddr *, socklen_t, device_id_t *, void **, size_t *);
 
 #endif
Index: uspace/lib/net/include/net_interface.h
===================================================================
--- uspace/lib/net/include/net_interface.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/net_interface.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,4 +38,5 @@
 #include <net/device.h>
 #include <adt/measured_strings.h>
+#include <async.h>
 
 /** @name Networking module interface
@@ -44,9 +45,10 @@
 /*@{*/
 
-extern int net_get_device_conf_req(int, device_id_t, measured_string_t **,
-    size_t, uint8_t **);
-extern int net_get_conf_req(int, measured_string_t **, size_t, uint8_t **);
+extern int net_get_device_conf_req(async_sess_t *, device_id_t,
+    measured_string_t **, size_t, uint8_t **);
+extern int net_get_conf_req(async_sess_t *, measured_string_t **, size_t,
+    uint8_t **);
 extern void net_free_settings(measured_string_t *, uint8_t *);
-extern int net_connect_module(void);
+extern async_sess_t *net_connect_module(void);
 
 /*@}*/
Index: uspace/lib/net/include/netif_remote.h
===================================================================
--- uspace/lib/net/include/netif_remote.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/netif_remote.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -34,19 +34,18 @@
 #define LIBNET_NETIF_REMOTE_H_
 
-#include <async.h>
 #include <ipc/services.h>
 #include <adt/measured_strings.h>
-
 #include <net/device.h>
 #include <net/packet.h>
+#include <async.h>
 
-extern int netif_get_addr_req(int, device_id_t, measured_string_t **,
+extern int netif_get_addr_req(async_sess_t *, device_id_t, measured_string_t **,
     uint8_t **);
-extern int netif_probe_req(int, device_id_t, int, void *);
-extern int netif_send_msg(int, device_id_t, packet_t *, services_t);
-extern int netif_start_req(int, device_id_t);
-extern int netif_stop_req(int, device_id_t);
-extern int netif_stats_req(int, device_id_t, device_stats_t *);
-extern int netif_bind_service(services_t, device_id_t, services_t,
+extern int netif_probe_req(async_sess_t *, device_id_t, int, void *);
+extern int netif_send_msg(async_sess_t *, device_id_t, packet_t *, services_t);
+extern int netif_start_req(async_sess_t *, device_id_t);
+extern int netif_stop_req(async_sess_t *, device_id_t);
+extern int netif_stats_req(async_sess_t *, device_id_t, device_stats_t *);
+extern async_sess_t *netif_bind_service(services_t, device_id_t, services_t,
     async_client_conn_t);
 
Index: uspace/lib/net/include/netif_skel.h
===================================================================
--- uspace/lib/net/include/netif_skel.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/netif_skel.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,18 +39,16 @@
 #define NET_NETIF_SKEL_H_
 
-#include <async.h>
 #include <fibril_synch.h>
 #include <ipc/services.h>
-
 #include <adt/measured_strings.h>
 #include <net/device.h>
 #include <net/packet.h>
+#include <async.h>
 
 /** Network interface device specific data. */
 typedef struct {
-	device_id_t device_id;  /**< Device identifier. */
-	int nil_phone;          /**< Receiving network interface layer phone. */
-	device_state_t state;   /**< Actual device state. */
-	void *specific;         /**< Driver specific data. */
+	device_id_t device_id;   /**< Device identifier. */
+	device_state_t state;    /**< Actual device state. */
+	void *specific;          /**< Driver specific data. */
 } netif_device_t;
 
@@ -65,5 +63,6 @@
 /** Network interface module skeleton global data. */
 typedef struct {
-	int net_phone;                  /**< Networking module phone. */
+	async_sess_t *sess;             /**< Networking module session. */
+	async_sess_t *nil_sess;         /**< Network interface layer session. */
 	netif_device_map_t device_map;  /**< Device map. */
 	fibril_rwlock_t lock;           /**< Safety lock. */
@@ -127,5 +126,4 @@
  * @return Other error codes as defined for the specific module
  *         message implementation.
- 
  *
  */
Index: uspace/lib/net/include/nil_remote.h
===================================================================
--- uspace/lib/net/include/nil_remote.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/nil_remote.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,29 +38,31 @@
 #include <net/packet.h>
 #include <generic.h>
+#include <async.h>
 
 #define nil_bind_service(service, device_id, me, receiver) \
 	bind_service(service, device_id, me, 0, receiver)
 
-#define nil_packet_size_req(nil_phone, device_id, packet_dimension) \
-	generic_packet_size_req_remote(nil_phone, NET_NIL_PACKET_SPACE, \
+#define nil_packet_size_req(sess, device_id, packet_dimension) \
+	generic_packet_size_req_remote(sess, NET_NIL_PACKET_SPACE, \
 	    device_id, packet_dimension)
 
-#define nil_get_addr_req(nil_phone, device_id, address, data) \
-	generic_get_addr_req(nil_phone, NET_NIL_ADDR, device_id, address, data)
+#define nil_get_addr_req(sess, device_id, address, data) \
+	generic_get_addr_req(sess, NET_NIL_ADDR, device_id, address, data)
 
-#define nil_get_broadcast_addr_req(nil_phone, device_id, address, data) \
-	generic_get_addr_req(nil_phone, NET_NIL_BROADCAST_ADDR, device_id, \
+#define nil_get_broadcast_addr_req(sess, device_id, address, data) \
+	generic_get_addr_req(sess, NET_NIL_BROADCAST_ADDR, device_id, \
 	    address, data)
 
-#define nil_send_msg(nil_phone, device_id, packet, sender) \
-	generic_send_msg_remote(nil_phone, NET_NIL_SEND, device_id, \
+#define nil_send_msg(sess, device_id, packet, sender) \
+	generic_send_msg_remote(sess, NET_NIL_SEND, device_id, \
 	    packet_get_id(packet), sender, 0)
 
-#define nil_device_req(nil_phone, device_id, mtu, netif_service) \
-	generic_device_req_remote(nil_phone, NET_NIL_DEVICE, device_id, mtu, \
+#define nil_device_req(sess, device_id, mtu, netif_service) \
+	generic_device_req_remote(sess, NET_NIL_DEVICE, device_id, mtu, \
 	    netif_service)
 
-extern int nil_device_state_msg(int, device_id_t, int);
-extern int nil_received_msg(int, device_id_t, packet_t *, services_t);
+extern int nil_device_state_msg(async_sess_t *, device_id_t, sysarg_t);
+extern int nil_received_msg(async_sess_t *, device_id_t, packet_t *,
+    services_t);
 
 #endif
Index: uspace/lib/net/include/nil_skel.h
===================================================================
--- uspace/lib/net/include/nil_skel.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/nil_skel.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,11 +39,9 @@
 #define LIBNET_NIL_SKEL_H_
 
-#include <async.h>
-#include <fibril_synch.h>
 #include <ipc/services.h>
-
 #include <adt/measured_strings.h>
 #include <net/device.h>
 #include <net/packet.h>
+#include <async.h>
 
 /** Module initialization.
@@ -51,5 +49,5 @@
  * This has to be implemented in user code.
  *
- * @param[in] net_phone Networking module phone.
+ * @param[in] sess Networking module session.
  *
  * @return EOK on success.
@@ -58,5 +56,5 @@
  *
  */
-extern int nil_initialize(int net_phone);
+extern int nil_initialize(async_sess_t *sess);
 
 /** Notify the network interface layer about the device state change.
@@ -64,5 +62,4 @@
  * This has to be implemented in user code.
  *
- * @param[in] nil_phone Network interface layer phone.
  * @param[in] device_id Device identifier.
  * @param[in] state     New device state.
@@ -73,5 +70,5 @@
  *
  */
-extern int nil_device_state_msg_local(int, device_id_t, int);
+extern int nil_device_state_msg_local(device_id_t device_id, sysarg_t state);
 
 /** Pass the packet queue to the network interface layer.
@@ -82,5 +79,4 @@
  * This has to be implemented in user code.
  *
- * @param[in] nil_phone Network interface layer phone.
  * @param[in] device_id Source device identifier.
  * @param[in] packet    Received packet or the received packet queue.
@@ -92,5 +88,6 @@
  *
  */
-extern int nil_received_msg_local(int, device_id_t, packet_t *, services_t);
+extern int nil_received_msg_local(device_id_t device_id, packet_t *packet,
+    services_t target);
 
 /** Message processing function.
@@ -98,5 +95,4 @@
  * This has to be implemented in user code.
  *
- * @param[in]  name   Module name.
  * @param[in]  callid Message identifier.
  * @param[in]  call   Message parameters.
@@ -112,8 +108,8 @@
  *
  */
-extern int nil_module_message(ipc_callid_t, ipc_call_t *, ipc_call_t *,
-    size_t *);
+extern int nil_module_message(ipc_callid_t callid, ipc_call_t *call,
+    ipc_call_t *answer, size_t *count);
 
-extern int nil_module_start(int);
+extern int nil_module_start(sysarg_t);
 
 #endif
Index: uspace/lib/net/include/packet_client.h
===================================================================
--- uspace/lib/net/include/packet_client.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/packet_client.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -49,4 +49,5 @@
 
 #include <net/packet.h>
+#include <async.h>
 
 /** @name Packet client interface */
@@ -108,5 +109,5 @@
 extern int packet_get_addr(const packet_t *, uint8_t **, uint8_t **);
 extern int packet_set_addr(packet_t *, const uint8_t *, const uint8_t *, size_t);
-extern packet_t *packet_get_copy(int, packet_t *);
+extern packet_t *packet_get_copy(async_sess_t *, packet_t *);
 
 /*@}*/
Index: uspace/lib/net/include/packet_remote.h
===================================================================
--- uspace/lib/net/include/packet_remote.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/packet_remote.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -36,9 +36,11 @@
 #include <net/packet.h>
 #include <sys/types.h>
+#include <async.h>
 
-extern int packet_translate_remote(int, packet_t **, packet_id_t);
-extern packet_t *packet_get_4_remote(int, size_t, size_t, size_t, size_t);
-extern packet_t *packet_get_1_remote(int, size_t);
-extern void pq_release_remote(int, packet_id_t);
+extern int packet_translate_remote(async_sess_t *, packet_t **, packet_id_t);
+extern packet_t *packet_get_4_remote(async_sess_t *, size_t, size_t, size_t,
+    size_t);
+extern packet_t *packet_get_1_remote(async_sess_t *, size_t);
+extern void pq_release_remote(async_sess_t *, packet_id_t);
 
 #endif
Index: uspace/lib/net/include/socket_core.h
===================================================================
--- uspace/lib/net/include/socket_core.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/socket_core.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup libnet 
+/** @addtogroup libnet
  *  @{
  */
@@ -45,19 +45,20 @@
 #include <net/device.h>
 #include <net/packet.h>
+#include <async.h>
 
 /** Initial size of the received packet queue. */
-#define SOCKET_INITIAL_RECEIVED_SIZE	4
+#define SOCKET_INITIAL_RECEIVED_SIZE  4
 
 /** Maximum size of the received packet queue. */
-#define SOCKET_MAX_RECEIVED_SIZE	0
+#define SOCKET_MAX_RECEIVED_SIZE  0
 
 /** Initial size of the sockets for acceptance queue. */
-#define SOCKET_INITIAL_ACCEPTED_SIZE	1
+#define SOCKET_INITIAL_ACCEPTED_SIZE  1
 
 /** Maximum size of the sockets for acceptance queue. */
-#define SOCKET_MAX_ACCEPTEDED_SIZE	0
+#define SOCKET_MAX_ACCEPTEDED_SIZE  0
 
 /** Listening sockets' port map key. */
-#define SOCKET_MAP_KEY_LISTENING	"L"
+#define SOCKET_MAP_KEY_LISTENING  "L"
 
 /** Type definition of the socket core.
@@ -75,6 +76,6 @@
 	/** Socket identifier. */
 	int socket_id;
-	/** Client application phone. */
-	int phone;
+	/** Client application session. */
+	async_sess_t *sess;
 	/** Bound port. */
 	int port;
@@ -108,13 +109,13 @@
 INT_MAP_DECLARE(socket_ports, socket_port_t);
 
-extern void socket_cores_release(int, socket_cores_t *, socket_ports_t *,
-    void (*)(socket_core_t *));
+extern void socket_cores_release(async_sess_t *, socket_cores_t *,
+    socket_ports_t *, void (*)(socket_core_t *));
 extern int socket_bind(socket_cores_t *, socket_ports_t *, int, void *, size_t,
     int, int, int);
 extern int socket_bind_free_port(socket_ports_t *, socket_core_t *, int, int,
     int);
-extern int socket_create(socket_cores_t *, int, void *, int *);
-extern int socket_destroy(int, int, socket_cores_t *, socket_ports_t *,
-    void (*)(socket_core_t *));
+extern int socket_create(socket_cores_t *, async_sess_t *, void *, int *);
+extern int socket_destroy(async_sess_t *, int, socket_cores_t *,
+    socket_ports_t *, void (*)(socket_core_t *));
 extern int socket_reply_packets(packet_t *, size_t *);
 extern socket_core_t *socket_port_find(socket_ports_t *, int, const uint8_t *,
Index: uspace/lib/net/include/tl_common.h
===================================================================
--- uspace/lib/net/include/tl_common.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/tl_common.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup libnet 
+/** @addtogroup libnet
  * @{
  */
@@ -39,9 +39,9 @@
 
 #include <ipc/services.h>
-
 #include <net/socket_codes.h>
 #include <net/packet.h>
 #include <net/device.h>
 #include <net/inet.h>
+#include <async.h>
 
 /** Device packet dimensions.
@@ -51,5 +51,5 @@
 DEVICE_MAP_DECLARE(packet_dimensions, packet_dimension_t);
 
-extern int tl_get_ip_packet_dimension(int, packet_dimensions_t *,
+extern int tl_get_ip_packet_dimension(async_sess_t *, packet_dimensions_t *,
     device_id_t, packet_dimension_t **);
 extern int tl_get_address_port(const struct sockaddr *, int, uint16_t *);
@@ -57,6 +57,7 @@
     size_t);
 extern int tl_set_address_port(struct sockaddr *, int, uint16_t);
-extern int tl_prepare_icmp_packet(int, int, packet_t *, services_t);
-extern int tl_socket_read_packet_data(int, packet_t **, size_t,
+extern int tl_prepare_icmp_packet(async_sess_t *, async_sess_t *, packet_t *,
+    services_t);
+extern int tl_socket_read_packet_data(async_sess_t *, packet_t **, size_t,
     const packet_dimension_t *, const struct sockaddr *, socklen_t);
 
@@ -65,3 +66,2 @@
 /** @}
  */
-
Index: uspace/lib/net/include/tl_remote.h
===================================================================
--- uspace/lib/net/include/tl_remote.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/tl_remote.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,12 +38,11 @@
 #define LIBNET_TL_REMOTE_H_
 
-#include <async.h>
 #include <ipc/services.h>
 #include <ipc/tl.h>
-
 #include <generic.h>
 #include <net/device.h>
 #include <net/packet.h>
 #include <packet_client.h>
+#include <async.h>
 
 /** @name Transport layer module interface
@@ -52,5 +51,5 @@
 /*@{*/
 
-extern int tl_received_msg(int, device_id_t, packet_t *, services_t,
+extern int tl_received_msg(async_sess_t *, device_id_t, packet_t *, services_t,
     services_t);
 
Index: uspace/lib/net/include/tl_skel.h
===================================================================
--- uspace/lib/net/include/tl_skel.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/tl_skel.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,11 +39,10 @@
  */
 
-#include <async.h>
 #include <fibril_synch.h>
 #include <ipc/services.h>
-
 #include <adt/measured_strings.h>
 #include <net/device.h>
 #include <net/packet.h>
+#include <async.h>
 
 /** Module initialization.
@@ -51,5 +50,5 @@
  * This has to be implemented in user code.
  *
- * @param[in] net_phone Networking module phone.
+ * @param[in] sess Networking module session.
  *
  * @return EOK on success.
@@ -58,5 +57,5 @@
  *
  */
-extern int tl_initialize(int net_phone);
+extern int tl_initialize(async_sess_t *sess);
 
 /** Per-connection module initialization.
@@ -83,5 +82,5 @@
     ipc_call_t *, size_t *);
 
-extern int tl_module_start(int);
+extern int tl_module_start(sysarg_t);
 
 #endif
Index: uspace/lib/net/netif/netif_remote.c
===================================================================
--- uspace/lib/net/netif/netif_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/netif/netif_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,8 +38,6 @@
 #include <packet_client.h>
 #include <generic.h>
-#include <async_obsolete.h>
 #include <ipc/services.h>
 #include <ipc/netif.h>
-
 #include <net/modules.h>
 #include <adt/measured_strings.h>
@@ -49,8 +47,8 @@
 /** Return the device local hardware address.
  *
- * @param[in]  netif_phone Network interface phone.
- * @param[in]  device_id   Device identifier.
- * @param[out] address     Device local hardware address.
- * @param[out] data        Address data.
+ * @param[in]  sess      Network interface session.
+ * @param[in]  device_id Device identifier.
+ * @param[out] address   Device local hardware address.
+ * @param[out] data      Address data.
  *
  * @return EOK on success.
@@ -61,8 +59,8 @@
  *
  */
-int netif_get_addr_req(int netif_phone, device_id_t device_id,
+int netif_get_addr_req(async_sess_t *sess, device_id_t device_id,
     measured_string_t **address, uint8_t **data)
 {
-	return generic_get_addr_req(netif_phone, NET_NETIF_GET_ADDR, device_id,
+	return generic_get_addr_req(sess, NET_NETIF_GET_ADDR, device_id,
 	    address, data);
 }
@@ -70,8 +68,8 @@
 /** Probe the existence of the device.
  *
- * @param[in] netif_phone Network interface phone.
- * @param[in] device_id   Device identifier.
- * @param[in] irq         Device interrupt number.
- * @param[in] io          Device input/output address.
+ * @param[in] sess      Network interface session.
+ * @param[in] device_id Device identifier.
+ * @param[in] irq       Device interrupt number.
+ * @param[in] io        Device input/output address.
  *
  * @return EOK on success.
@@ -80,16 +78,20 @@
  *
  */
-int netif_probe_req(int netif_phone, device_id_t device_id, int irq, void *io)
+int netif_probe_req(async_sess_t *sess, device_id_t device_id, int irq, void *io)
 {
-	return async_obsolete_req_3_0(netif_phone, NET_NETIF_PROBE, device_id, irq,
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_3_0(exch, NET_NETIF_PROBE, device_id, (sysarg_t) irq,
 	    (sysarg_t) io);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
 /** Send the packet queue.
  *
- * @param[in] netif_phone Network interface phone.
- * @param[in] device_id   Device identifier.
- * @param[in] packet      Packet queue.
- * @param[in] sender      Sending module service.
+ * @param[in] sess      Network interface session.
+ * @param[in] device_id Device identifier.
+ * @param[in] packet    Packet queue.
+ * @param[in] sender    Sending module service.
  *
  * @return EOK on success.
@@ -98,8 +100,8 @@
  *
  */
-int netif_send_msg(int netif_phone, device_id_t device_id, packet_t *packet,
+int netif_send_msg(async_sess_t *sess, device_id_t device_id, packet_t *packet,
     services_t sender)
 {
-	return generic_send_msg_remote(netif_phone, NET_NETIF_SEND, device_id,
+	return generic_send_msg_remote(sess, NET_NETIF_SEND, device_id,
 	    packet_get_id(packet), sender, 0);
 }
@@ -107,6 +109,6 @@
 /** Start the device.
  *
- * @param[in] netif_phone Network interface phone.
- * @param[in] device_id   Device identifier.
+ * @param[in] sess      Network interface session.
+ * @param[in] device_id Device identifier.
  *
  * @return EOK on success.
@@ -117,13 +119,17 @@
  *
  */
-int netif_start_req(int netif_phone, device_id_t device_id)
+int netif_start_req(async_sess_t *sess, device_id_t device_id)
 {
-	return async_obsolete_req_1_0(netif_phone, NET_NETIF_START, device_id);
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_1_0(exch, NET_NETIF_START, device_id);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
 /** Stop the device.
  *
- * @param[in] netif_phone Network interface phone.
- * @param[in] device_id   Device identifier.
+ * @param[in] sess      Network interface session.
+ * @param[in] device_id Device identifier.
  *
  * @return EOK on success.
@@ -134,19 +140,23 @@
  *
  */
-int netif_stop_req(int netif_phone, device_id_t device_id)
+int netif_stop_req(async_sess_t *sess, device_id_t device_id)
 {
-	return async_obsolete_req_1_0(netif_phone, NET_NETIF_STOP, device_id);
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_1_0(exch, NET_NETIF_STOP, device_id);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
 /** Return the device usage statistics.
  *
- * @param[in] netif_phone Network interface phone.
- * @param[in] device_id   Device identifier.
- * @param[out] stats      Device usage statistics.
+ * @param[in]  sess      Network interface session.
+ * @param[in]  device_id Device identifier.
+ * @param[out] stats     Device usage statistics.
  *
  * @return EOK on success.
  *
  */
-int netif_stats_req(int netif_phone, device_id_t device_id,
+int netif_stats_req(async_sess_t *sess, device_id_t device_id,
     device_stats_t *stats)
 {
@@ -154,7 +164,9 @@
 		return EBADMEM;
 	
-	aid_t message_id = async_obsolete_send_1(netif_phone, NET_NETIF_STATS,
+	async_exch_t *exch = async_exchange_begin(sess);
+	aid_t message_id = async_send_1(exch, NET_NETIF_STATS,
 	    (sysarg_t) device_id, NULL);
-	async_obsolete_data_read_start(netif_phone, stats, sizeof(*stats));
+	async_data_read_start(exch, stats, sizeof(*stats));
+	async_exchange_end(exch);
 	
 	sysarg_t result;
@@ -169,16 +181,14 @@
  * register the message receiver.
  *
- * @param[in] service   The network interface module service.
- * @param[in] device_id The device identifier.
- * @param[in] me        The requesting module service.
- * @param[in] receiver  The message receiver.
+ * @param[in] service   Network interface module service.
+ * @param[in] device_id Device identifier.
+ * @param[in] me        Requesting module service.
+ * @param[in] receiver  Message receiver.
  *
- * @return The phone of the needed service.
- * @return EOK on success.
- * @return Other error codes as defined for the bind_service()
- *         function.
+ * @return Session to the needed service.
+ * @return NULL on failure.
  *
  */
-int netif_bind_service(services_t service, device_id_t device_id,
+async_sess_t *netif_bind_service(services_t service, device_id_t device_id,
     services_t me, async_client_conn_t receiver)
 {
Index: uspace/lib/net/netif/netif_skel.c
===================================================================
--- uspace/lib/net/netif/netif_skel.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/netif/netif_skel.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -54,7 +54,4 @@
 #include <nil_remote.h>
 
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
-
 DEVICE_MAP_IMPLEMENT(netif_device_map, netif_device_t);
 
@@ -64,5 +61,4 @@
 /** Probe the existence of the device.
  *
- * @param[in] netif_phone Network interface phone.
  * @param[in] device_id   Device identifier.
  * @param[in] irq         Device interrupt number.
@@ -74,6 +70,5 @@
  *
  */
-static int netif_probe_req_local(int netif_phone, device_id_t device_id,
-    int irq, void *io)
+static int netif_probe_req_local(device_id_t device_id, int irq, void *io)
 {
 	fibril_rwlock_write_lock(&netif_globals.lock);
@@ -86,5 +81,4 @@
 /** Send the packet queue.
  *
- * @param[in] netif_phone Network interface phone.
  * @param[in] device_id   Device identifier.
  * @param[in] packet      Packet queue.
@@ -96,6 +90,6 @@
  *
  */
-static int netif_send_msg_local(int netif_phone, device_id_t device_id,
-    packet_t *packet, services_t sender)
+static int netif_send_msg_local(device_id_t device_id, packet_t *packet,
+    services_t sender)
 {
 	fibril_rwlock_write_lock(&netif_globals.lock);
@@ -108,5 +102,4 @@
 /** Start the device.
  *
- * @param[in] netif_phone Network interface phone.
  * @param[in] device_id   Device identifier.
  *
@@ -118,5 +111,5 @@
  *
  */
-static int netif_start_req_local(int netif_phone, device_id_t device_id)
+static int netif_start_req_local(device_id_t device_id)
 {
 	fibril_rwlock_write_lock(&netif_globals.lock);
@@ -131,6 +124,5 @@
 	int result = netif_start_message(device);
 	if (result > NETIF_NULL) {
-		int phone = device->nil_phone;
-		nil_device_state_msg(phone, device_id, result);
+		nil_device_state_msg(netif_globals.nil_sess, device_id, result);
 		fibril_rwlock_write_unlock(&netif_globals.lock);
 		return EOK;
@@ -144,5 +136,4 @@
 /** Stop the device.
  *
- * @param[in] netif_phone Network interface phone.
  * @param[in] device_id   Device identifier.
  *
@@ -154,5 +145,5 @@
  *
  */
-static int netif_stop_req_local(int netif_phone, device_id_t device_id)
+static int netif_stop_req_local(device_id_t device_id)
 {
 	fibril_rwlock_write_lock(&netif_globals.lock);
@@ -167,6 +158,5 @@
 	int result = netif_stop_message(device);
 	if (result > NETIF_NULL) {
-		int phone = device->nil_phone;
-		nil_device_state_msg(phone, device_id, result);
+		nil_device_state_msg(netif_globals.nil_sess, device_id, result);
 		fibril_rwlock_write_unlock(&netif_globals.lock);
 		return EOK;
@@ -222,5 +212,5 @@
 void netif_pq_release(packet_id_t packet_id)
 {
-	pq_release_remote(netif_globals.net_phone, packet_id);
+	pq_release_remote(netif_globals.sess, packet_id);
 }
 
@@ -235,31 +225,29 @@
 packet_t *netif_packet_get_1(size_t content)
 {
-	return packet_get_1_remote(netif_globals.net_phone, content);
+	return packet_get_1_remote(netif_globals.sess, content);
 }
 
 /** Register the device notification receiver,
  *
- * Register a  network interface layer module as the device
+ * Register a network interface layer module as the device
  * notification receiver.
  *
- * @param[in] device_id Device identifier.
- * @param[in] phone     Network interface layer module phone.
- *
- * @return EOK on success.
- * @return ENOENT if there is no such device.
+ * @param[in] sess      Session to the network interface layer module.
+ *
+ * @return EOK on success.
  * @return ELIMIT if there is another module registered.
  *
  */
-static int register_message(device_id_t device_id, int phone)
-{
-	netif_device_t *device;
-	int rc = find_device(device_id, &device);
-	if (rc != EOK)
-		return rc;
-	
-	if (device->nil_phone >= 0)
+static int register_message(async_sess_t *sess)
+{
+	fibril_rwlock_write_lock(&netif_globals.lock);
+	if (netif_globals.nil_sess != NULL) {
+		fibril_rwlock_write_unlock(&netif_globals.lock);
 		return ELIMIT;
-	
-	device->nil_phone = phone;
+	}
+	
+	netif_globals.nil_sess = sess;
+	
+	fibril_rwlock_write_unlock(&netif_globals.lock);
 	return EOK;
 }
@@ -294,28 +282,25 @@
 		return EOK;
 	
+	async_sess_t *callback =
+	    async_callback_receive_start(EXCHANGE_SERIALIZE, call);
+	if (callback)
+		return register_message(callback);
+	
 	switch (IPC_GET_IMETHOD(*call)) {
 	case NET_NETIF_PROBE:
-		return netif_probe_req_local(0, IPC_GET_DEVICE(*call),
+		return netif_probe_req_local(IPC_GET_DEVICE(*call),
 		    NETIF_GET_IRQ(*call), NETIF_GET_IO(*call));
 	
-	case IPC_M_CONNECT_TO_ME:
-		fibril_rwlock_write_lock(&netif_globals.lock);
-		
-		rc = register_message(IPC_GET_DEVICE(*call), IPC_GET_PHONE(*call));
-		
-		fibril_rwlock_write_unlock(&netif_globals.lock);
-		return rc;
-	
 	case NET_NETIF_SEND:
-		rc = packet_translate_remote(netif_globals.net_phone, &packet,
+		rc = packet_translate_remote(netif_globals.sess, &packet,
 		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
 		
-		return netif_send_msg_local(0, IPC_GET_DEVICE(*call), packet,
+		return netif_send_msg_local(IPC_GET_DEVICE(*call), packet,
 		    IPC_GET_SENDER(*call));
 	
 	case NET_NETIF_START:
-		return netif_start_req_local(0, IPC_GET_DEVICE(*call));
+		return netif_start_req_local(IPC_GET_DEVICE(*call));
 	
 	case NET_NETIF_STATS:
@@ -343,5 +328,5 @@
 	
 	case NET_NETIF_STOP:
-		return netif_stop_req_local(0, IPC_GET_DEVICE(*call));
+		return netif_stop_req_local(IPC_GET_DEVICE(*call));
 	
 	case NET_NETIF_GET_ADDR:
@@ -412,5 +397,6 @@
 	async_set_client_connection(netif_client_connection);
 	
-	netif_globals.net_phone = connect_to_service(SERVICE_NETWORKING);
+	netif_globals.sess = connect_to_service(SERVICE_NETWORKING);
+	netif_globals.nil_sess = NULL;
 	netif_device_map_initialize(&netif_globals.device_map);
 	
Index: uspace/lib/net/nil/nil_remote.c
===================================================================
--- uspace/lib/net/nil/nil_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/nil/nil_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -45,5 +45,5 @@
 /** Notify the network interface layer about the device state change.
  *
- * @param[in] nil_phone Network interface layer phone.
+ * @param[in] sess      Network interface layer session.
  * @param[in] device_id Device identifier.
  * @param[in] state     New device state.
@@ -54,7 +54,8 @@
  *
  */
-int nil_device_state_msg(int nil_phone, device_id_t device_id, int state)
+int nil_device_state_msg(async_sess_t *sess, device_id_t device_id,
+    sysarg_t state)
 {
-	return generic_device_state_msg_remote(nil_phone, NET_NIL_DEVICE_STATE,
+	return generic_device_state_msg_remote(sess, NET_NIL_DEVICE_STATE,
 	    device_id, state, 0);
 }
@@ -65,5 +66,5 @@
  * upper layers.
  *
- * @param[in] nil_phone Network interface layer phone.
+ * @param[in] sess      Network interface layer session.
  * @param[in] device_id Source device identifier.
  * @param[in] packet    Received packet or the received packet queue.
@@ -75,8 +76,8 @@
  *
  */
-int nil_received_msg(int nil_phone, device_id_t device_id,
+int nil_received_msg(async_sess_t *sess, device_id_t device_id,
     packet_t *packet, services_t target)
 {
-	return generic_received_msg_remote(nil_phone, NET_NIL_RECEIVED,
+	return generic_received_msg_remote(sess, NET_NIL_RECEIVED,
 	    device_id, packet_get_id(packet), target, 0);
 }
Index: uspace/lib/net/nil/nil_skel.c
===================================================================
--- uspace/lib/net/nil/nil_skel.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/nil/nil_skel.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,10 +38,8 @@
 #include <bool.h>
 #include <errno.h>
+#include <ns.h>
 #include <nil_skel.h>
 #include <net_interface.h>
 #include <net/modules.h>
-
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
 
 /** Default thread for new connections.
@@ -99,14 +97,12 @@
  * @return Other error codes as defined for the nil_initialize()
  *         function.
- * @return Other error codes as defined for the REGISTER_ME() macro
- *         function.
  *
  */
-int nil_module_start(int service)
+int nil_module_start(sysarg_t service)
 {
 	async_set_client_connection(nil_client_connection);
-	int net_phone = net_connect_module();
-	if (net_phone < 0)
-		return net_phone;
+	async_sess_t *sess = net_connect_module();
+	if (!sess)
+		return ENOENT;
 	
 	int rc = pm_init();
@@ -114,9 +110,9 @@
 		return rc;
 	
-	rc = nil_initialize(net_phone);
+	rc = nil_initialize(sess);
 	if (rc != EOK)
 		goto out;
 	
-	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL, NULL);
+	rc = service_register(service);
 	if (rc != EOK)
 		goto out;
Index: uspace/lib/net/tl/icmp_remote.c
===================================================================
--- uspace/lib/net/tl/icmp_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/tl/icmp_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,13 +39,11 @@
 #include <net/modules.h>
 #include <packet_client.h>
-
-#include <async.h>
-#include <async_obsolete.h>
-#include <errno.h>
 #include <ipc/services.h>
 #include <ipc/icmp.h>
 #include <sys/types.h>
+#include <async.h>
+#include <errno.h>
 
-/** Sends the Destination Unreachable error notification packet.
+/** Send the Destination Unreachable error notification packet.
  *
  * Beginning of the packet is sent as the notification packet data.
@@ -53,22 +51,26 @@
  * packet.
  *
- * @param[in] icmp_phone The ICMP module phone used for (semi)remote calls.
- * @param[in] code	The error specific code.
- * @param[in] mtu	The error MTU value.
- * @param[in] packet	The original packet.
- * @return		EOK on success.
- * @return		EPERM if the ICMP error notifications are disabled.
- * @return		ENOMEM if there is not enough memory left.
+ * @param[in] sess   ICMP module session.
+ * @param[in] code   Error specific code.
+ * @param[in] mtu    Error MTU value.
+ * @param[in] packet Original packet.
+ *
+ * @return EOK on success.
+ * @return EPERM if the ICMP error notifications are disabled.
+ * @return ENOMEM if there is not enough memory left.
+ *
  */
-int
-icmp_destination_unreachable_msg(int icmp_phone, icmp_code_t code,
+int icmp_destination_unreachable_msg(async_sess_t *sess, icmp_code_t code,
     icmp_param_t mtu, packet_t *packet)
 {
-	async_obsolete_msg_3(icmp_phone, NET_ICMP_DEST_UNREACH, (sysarg_t) code,
+	async_exch_t *exch = async_exchange_begin(sess);
+	async_msg_3(exch, NET_ICMP_DEST_UNREACH, (sysarg_t) code,
 	    (sysarg_t) packet_get_id(packet), (sysarg_t) mtu);
+	async_exchange_end(exch);
+	
 	return EOK;
 }
 
-/** Sends the Source Quench error notification packet.
+/** Send the Source Quench error notification packet.
  *
  * Beginning of the packet is sent as the notification packet data.
@@ -76,18 +78,23 @@
  * packet.
  *
- * @param[in] icmp_phone The ICMP module phone used for (semi)remote calls.
- * @param[in] packet	The original packet.
- * @return		EOK on success.
- * @return		EPERM if the ICMP error notifications are disabled.
- * @return		ENOMEM if there is not enough memory left.
+ * @param[in] sess   ICMP module session.
+ * @param[in] packet Original packet.
+ *
+ * @return EOK on success.
+ * @return EPERM if the ICMP error notifications are disabled.
+ * @return ENOMEM if there is not enough memory left.
+ *
  */
-int icmp_source_quench_msg(int icmp_phone, packet_t *packet)
+int icmp_source_quench_msg(async_sess_t *sess, packet_t *packet)
 {
-	async_obsolete_msg_2(icmp_phone, NET_ICMP_SOURCE_QUENCH, 0,
+	async_exch_t *exch = async_exchange_begin(sess);
+	async_msg_2(exch, NET_ICMP_SOURCE_QUENCH, 0,
 	    (sysarg_t) packet_get_id(packet));
+	async_exchange_end(exch);
+	
 	return EOK;
 }
 
-/** Sends the Time Exceeded error notification packet.
+/** Send the Time Exceeded error notification packet.
  *
  * Beginning of the packet is sent as the notification packet data.
@@ -95,19 +102,25 @@
  * packet.
  *
- * @param[in] icmp_phone The ICMP module phone used for (semi)remote calls.
- * @param[in] code	The error specific code.
- * @param[in] packet	The original packet.
- * @return		EOK on success.
- * @return		EPERM if the ICMP error notifications are disabled.
- * @return		ENOMEM if there is not enough memory left.
+ * @param[in] sess   ICMP module session.
+ * @param[in] code   Error specific code.
+ * @param[in] packet Original packet.
+ *
+ * @return EOK on success.
+ * @return EPERM if the ICMP error notifications are disabled.
+ * @return ENOMEM if there is not enough memory left.
+ *
  */
-int icmp_time_exceeded_msg(int icmp_phone, icmp_code_t code, packet_t *packet)
+int icmp_time_exceeded_msg(async_sess_t *sess, icmp_code_t code,
+    packet_t *packet)
 {
-	async_obsolete_msg_2(icmp_phone, NET_ICMP_TIME_EXCEEDED, (sysarg_t) code,
+	async_exch_t *exch = async_exchange_begin(sess);
+	async_msg_2(exch, NET_ICMP_TIME_EXCEEDED, (sysarg_t) code,
 	    (sysarg_t) packet_get_id(packet));
+	async_exchange_end(exch);
+	
 	return EOK;
 }
 
-/** Sends the Parameter Problem error notification packet.
+/** Send the Parameter Problem error notification packet.
  *
  * Beginning of the packet is sent as the notification packet data.
@@ -115,17 +128,22 @@
  * packet.
  *
- * @param[in] icmp_phone The ICMP module phone used for (semi)remote calls.
- * @param[in] code	The error specific code.
- * @param[in] pointer	The problematic parameter offset.
- * @param[in] packet	The original packet.
- * @return		EOK on success.
- * @return		EPERM if the ICMP error notifications are disabled.
- * @return		ENOMEM if there is not enough memory left.
+ * @param[in] sess    ICMP module session.
+ * @param[in] code    Error specific code.
+ * @param[in] pointer Problematic parameter offset.
+ * @param[in] packet  Original packet.
+ *
+ * @return EOK on success.
+ * @return EPERM if the ICMP error notifications are disabled.
+ * @return ENOMEM if there is not enough memory left.
+ *
  */
-int icmp_parameter_problem_msg(int icmp_phone, icmp_code_t code,
+int icmp_parameter_problem_msg(async_sess_t *sess, icmp_code_t code,
     icmp_param_t pointer, packet_t *packet)
 {
-	async_obsolete_msg_3(icmp_phone, NET_ICMP_PARAMETERPROB, (sysarg_t) code,
+	async_exch_t *exch = async_exchange_begin(sess);
+	async_msg_3(exch, NET_ICMP_PARAMETERPROB, (sysarg_t) code,
 	    (sysarg_t) packet_get_id(packet), (sysarg_t) pointer);
+	async_exchange_end(exch);
+	
 	return EOK;
 }
@@ -133,3 +151,2 @@
 /** @}
  */
-
Index: uspace/lib/net/tl/socket_core.c
===================================================================
--- uspace/lib/net/tl/socket_core.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/tl/socket_core.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,5 +38,4 @@
 #include <packet_client.h>
 #include <packet_remote.h>
-
 #include <net/socket_codes.h>
 #include <net/in.h>
@@ -44,9 +43,7 @@
 #include <net/packet.h>
 #include <net/modules.h>
-
 #include <stdint.h>
 #include <stdlib.h>
 #include <errno.h>
-
 #include <adt/dynamic_fifo.h>
 #include <adt/int_map.h>
@@ -56,5 +53,5 @@
  * switching to the sequence.
  */
-#define SOCKET_ID_TRIES	100
+#define SOCKET_ID_TRIES  100
 
 /** Bound port sockets.*/
@@ -72,23 +69,21 @@
 INT_MAP_IMPLEMENT(socket_ports, socket_port_t);
 
-/** Destroys the socket.
+/** Destroy the socket.
  *
  * If the socket is bound, the port is released.
- * Releases all buffered packets, calls the release function and removes the
+ * Release all buffered packets, call the release function and remove the
  * socket from the local sockets.
  *
- * @param[in] packet_phone The packet server phone to release buffered packets.
- * @param[in] socket	The socket to be destroyed.
- * @param[in,out] local_sockets The local sockets to be updated.
- * @param[in,out] global_sockets The global sockets to be updated.
- * @param[in] socket_release The client release callback function.
- */
-static void
-socket_destroy_core(int packet_phone, socket_core_t *socket,
+ * @param[in]     sess           Packet server session.
+ * @param[in]     socket         Socket to be destroyed.
+ * @param[in,out] local_sockets  Local sockets to be updated.
+ * @param[in,out] global_sockets Global sockets to be updated.
+ * @param[in]     socket_release Client release callback function.
+ *
+ */
+static void socket_destroy_core(async_sess_t *sess, socket_core_t *socket,
     socket_cores_t *local_sockets, socket_ports_t *global_sockets,
     void (* socket_release)(socket_core_t *socket))
 {
-	int packet_id;
-
 	/* If bound */
 	if (socket->port) {
@@ -98,44 +93,44 @@
 	
 	/* Release all received packets */
+	int packet_id;
 	while ((packet_id = dyn_fifo_pop(&socket->received)) >= 0)
-		pq_release_remote(packet_phone, packet_id);
-
+		pq_release_remote(sess, packet_id);
+	
 	dyn_fifo_destroy(&socket->received);
 	dyn_fifo_destroy(&socket->accepted);
-
+	
 	if (socket_release)
 		socket_release(socket);
-
+	
 	socket_cores_exclude(local_sockets, socket->socket_id, free);
 }
 
-/** Destroys local sockets.
- *
- * Releases all buffered packets and calls the release function for each of the
+/** Destroy local sockets.
+ *
+ * Release all buffered packets and call the release function for each of the
  * sockets.
  *
- * @param[in] packet_phone The packet server phone to release buffered packets.
- * @param[in] local_sockets The local sockets to be destroyed.
- * @param[in,out] global_sockets The global sockets to be updated.
- * @param[in] socket_release The client release callback function.
- */
-void
-socket_cores_release(int packet_phone, socket_cores_t *local_sockets,
+ * @param[in]     sess           Packet server session.
+ * @param[in]     local_sockets  Local sockets to be destroyed.
+ * @param[in,out] global_sockets Global sockets to be updated.
+ * @param[in]     socket_release Client release callback function.
+ *
+ */
+void socket_cores_release(async_sess_t *sess, socket_cores_t *local_sockets,
     socket_ports_t *global_sockets,
     void (* socket_release)(socket_core_t *socket))
 {
-	int index;
-
 	if (!socket_cores_is_valid(local_sockets))
 		return;
-
+	
 	local_sockets->magic = 0;
-
+	
+	int index;
 	for (index = 0; index < local_sockets->next; ++index) {
 		if (socket_cores_item_is_valid(&local_sockets->items[index])) {
 			local_sockets->items[index].magic = 0;
-
+			
 			if (local_sockets->items[index].value) {
-				socket_destroy_core(packet_phone,
+				socket_destroy_core(sess,
 				    local_sockets->items[index].value,
 				    local_sockets, global_sockets,
@@ -146,5 +141,5 @@
 		}
 	}
-
+	
 	free(local_sockets->items);
 }
@@ -406,18 +401,20 @@
 }
 
-/** Creates a new socket.
- *
- * @param[in,out] local_sockets The local sockets to be updated.
- * @param[in] app_phone	The application phone.
- * @param[in] specific_data The socket specific data.
- * @param[in,out] socket_id The new socket identifier. A new identifier is
- *			chosen if set to zero or negative. A negative identifier
- *			is chosen if set to negative.
- * @return		EOK on success.
- * @return		EINVAL if the socket_id parameter is NULL.
- * @return		ENOMEM if there is not enough memory left.
- */
-int
-socket_create(socket_cores_t *local_sockets, int app_phone,
+/** Create a new socket.
+ *
+ * @param[in,out] local_sockets Local sockets to be updated.
+ * @param[in]     sess          Application session.
+ * @param[in]     specific_data Socket specific data.
+ * @param[in,out] socket_id     New socket identifier. A new identifier
+ *                              is chosen if set to zero or negative.
+ *                              A negative identifier is chosen if set
+ *                              to negative.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the socket_id parameter is NULL.
+ * @return ENOMEM if there is not enough memory left.
+ *
+ */
+int socket_create(socket_cores_t *local_sockets, async_sess_t* sess,
     void *specific_data, int *socket_id)
 {
@@ -446,5 +443,5 @@
 	
 	/* Initialize */
-	socket->phone = app_phone;
+	socket->sess = sess;
 	socket->port = -1;
 	socket->key = NULL;
@@ -475,37 +472,37 @@
 }
 
-/** Destroys the socket.
+/** Destroy the socket.
  *
  * If the socket is bound, the port is released.
- * Releases all buffered packets, calls the release function and removes the
+ * Release all buffered packets, call the release function and remove the
  * socket from the local sockets.
  *
- * @param[in] packet_phone The packet server phone to release buffered packets.
- * @param[in] socket_id	The socket identifier.
- * @param[in,out] local_sockets The local sockets to be updated.
- * @param[in,out] global_sockets The global sockets to be updated.
- * @param[in] socket_release The client release callback function.
- * @return		EOK on success.
- * @return		ENOTSOCK if the socket is not found.
+ * @param[in]     sess           Packet server session.
+ * @param[in]     socket_id      Socket identifier.
+ * @param[in,out] local_sockets  Local sockets to be updated.
+ * @param[in,out] global_sockets Global sockets to be updated.
+ * @param[in]     socket_release Client release callback function.
+ *
+ * @return EOK on success.
+ * @return ENOTSOCK if the socket is not found.
+ *
  */
 int
-socket_destroy(int packet_phone, int socket_id, socket_cores_t *local_sockets,
+socket_destroy(async_sess_t *sess, int socket_id, socket_cores_t *local_sockets,
     socket_ports_t *global_sockets,
     void (*socket_release)(socket_core_t *socket))
 {
-	socket_core_t *socket;
-	int accepted_id;
-
 	/* Find the socket */
-	socket = socket_cores_find(local_sockets, socket_id);
+	socket_core_t *socket = socket_cores_find(local_sockets, socket_id);
 	if (!socket)
 		return ENOTSOCK;
 	
 	/* Destroy all accepted sockets */
+	int accepted_id;
 	while ((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0)
-		socket_destroy(packet_phone, accepted_id, local_sockets,
+		socket_destroy(sess, accepted_id, local_sockets,
 		    global_sockets, socket_release);
 	
-	socket_destroy_core(packet_phone, socket, local_sockets, global_sockets,
+	socket_destroy_core(sess, socket, local_sockets, global_sockets,
 	    socket_release);
 	
Index: uspace/lib/net/tl/tl_common.c
===================================================================
--- uspace/lib/net/tl/tl_common.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/tl/tl_common.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -43,5 +43,4 @@
 #include <ip_interface.h>
 #include <tl_remote.h>
-
 #include <net/socket_codes.h>
 #include <net/in.h>
@@ -50,5 +49,4 @@
 #include <net/device.h>
 #include <net/packet.h>
-
 #include <async.h>
 #include <ipc/services.h>
@@ -107,22 +105,21 @@
  * The reply is cached then.
  *
- * @param[in] ip_phone	The IP moduel phone for (semi)remote calls.
- * @param[in] packet_dimensions The packet dimensions cache.
- * @param[in] device_id	The device identifier.
- * @param[out] packet_dimension The IP packet dimensions.
- * @return		EOK on success.
- * @return		EBADMEM if the packet_dimension parameter is NULL.
- * @return		ENOMEM if there is not enough memory left.
- * @return		EINVAL if the packet_dimensions cache is not valid.
- * @return		Other codes as defined for the ip_packet_size_req()
- *			function.
- */
-int
-tl_get_ip_packet_dimension(int ip_phone,
+ * @param[in]  sess              IP module session.
+ * @param[in]  packet_dimensions Packet dimensions cache.
+ * @param[in]  device_id         Device identifier.
+ * @param[out] packet_dimension  IP packet dimensions.
+ *
+ * @return EOK on success.
+ * @return EBADMEM if the packet_dimension parameter is NULL.
+ * @return ENOMEM if there is not enough memory left.
+ * @return EINVAL if the packet_dimensions cache is not valid.
+ * @return Other codes as defined for the ip_packet_size_req()
+ *         function.
+ *
+ */
+int tl_get_ip_packet_dimension(async_sess_t *sess,
     packet_dimensions_t *packet_dimensions, device_id_t device_id,
     packet_dimension_t **packet_dimension)
 {
-	int rc;
-	
 	if (!packet_dimension)
 		return EBADMEM;
@@ -133,8 +130,8 @@
 		/* Ask for and remember them if not found */
 		*packet_dimension = malloc(sizeof(**packet_dimension));
-		if(!*packet_dimension)
+		if (!*packet_dimension)
 			return ENOMEM;
 		
-		rc = ip_packet_size_req(ip_phone, device_id, *packet_dimension);
+		int rc = ip_packet_size_req(sess, device_id, *packet_dimension);
 		if (rc != EOK) {
 			free(*packet_dimension);
@@ -236,30 +233,28 @@
 /** Prepares the packet for ICMP error notification.
  *
- * Keeps the first packet and releases all the others.
- * Releases all the packets on error.
- *
- * @param[in] packet_phone The packet server module phone.
- * @param[in] icmp_phone The ICMP module phone.
- * @param[in] packet	The packet to be send.
- * @param[in] error	The packet error reporting service. Prefixes the
- *			received packet.
- * @return		EOK on success.
- * @return		ENOENT if no packet may be sent.
- */
-int
-tl_prepare_icmp_packet(int packet_phone, int icmp_phone, packet_t *packet,
-    services_t error)
-{
-	packet_t *next;
+ * Keep the first packet and release all the others.
+ * Release all the packets on error.
+ *
+ * @param[in] packet_sess Packet server module session.
+ * @param[in] icmp_sess   ICMP module phone.
+ * @param[in] packet      Packet to be send.
+ * @param[in] error       Packet error reporting service. Prefixes the
+ *                        received packet.
+ *
+ * @return EOK on success.
+ * @return ENOENT if no packet may be sent.
+ *
+ */
+int tl_prepare_icmp_packet(async_sess_t *packet_sess, async_sess_t *icmp_sess,
+    packet_t *packet, services_t error)
+{
+	/* Detach the first packet and release the others */
+	packet_t *next = pq_detach(packet);
+	if (next)
+		pq_release_remote(packet_sess, packet_get_id(next));
+	
 	uint8_t *src;
-	int length;
-
-	/* Detach the first packet and release the others */
-	next = pq_detach(packet);
-	if (next)
-		pq_release_remote(packet_phone, packet_get_id(next));
-	
-	length = packet_get_addr(packet, &src, NULL);
-	if ((length > 0) && (!error) && (icmp_phone >= 0) &&
+	int length = packet_get_addr(packet, &src, NULL);
+	if ((length > 0) && (!error) && (icmp_sess) &&
 	    /*
 	     * Set both addresses to the source one (avoids the source address
@@ -269,6 +264,6 @@
 		return EOK;
 	} else
-		pq_release_remote(packet_phone, packet_get_id(packet));
-
+		pq_release_remote(packet_sess, packet_get_id(packet));
+	
 	return ENOENT;
 }
@@ -276,20 +271,21 @@
 /** Receives data from the socket into a packet.
  *
- * @param[in] packet_phone The packet server module phone.
- * @param[out] packet	The new created packet.
- * @param[in] prefix	Reserved packet data prefix length.
- * @param[in] dimension	The packet dimension.
- * @param[in] addr	The destination address.
- * @param[in] addrlen	The address length.
- * @return		Number of bytes received.
- * @return		EINVAL if the client does not send data.
- * @return		ENOMEM if there is not enough memory left.
- * @return		Other error codes as defined for the
- *			async_data_read_finalize() function.
- */
-int
-tl_socket_read_packet_data(int packet_phone, packet_t **packet, size_t prefix,
-    const packet_dimension_t *dimension, const struct sockaddr *addr,
-    socklen_t addrlen)
+ * @param[in]  sess      Packet server module session.
+ * @param[out] packet    New created packet.
+ * @param[in]  prefix    Reserved packet data prefix length.
+ * @param[in]  dimension Packet dimension.
+ * @param[in]  addr      Destination address.
+ * @param[in]  addrlen   Address length.
+ *
+ * @return Number of bytes received.
+ * @return EINVAL if the client does not send data.
+ * @return ENOMEM if there is not enough memory left.
+ * @return Other error codes as defined for the
+ *         async_data_read_finalize() function.
+ *
+ */
+int tl_socket_read_packet_data(async_sess_t *sess, packet_t **packet,
+    size_t prefix, const packet_dimension_t *dimension,
+    const struct sockaddr *addr, socklen_t addrlen)
 {
 	ipc_callid_t callid;
@@ -306,5 +302,5 @@
 
 	/* Get a new packet */
-	*packet = packet_get_4_remote(packet_phone, length, dimension->addr_len,
+	*packet = packet_get_4_remote(sess, length, dimension->addr_len,
 	    prefix + dimension->prefix, dimension->suffix);
 	if (!packet)
@@ -314,5 +310,5 @@
 	data = packet_suffix(*packet, length);
 	if (!data) {
-		pq_release_remote(packet_phone, packet_get_id(*packet));
+		pq_release_remote(sess, packet_get_id(*packet));
 		return ENOMEM;
 	}
@@ -321,5 +317,5 @@
 	rc = async_data_write_finalize(callid, data, length);
 	if (rc != EOK) {
-		pq_release_remote(packet_phone, packet_get_id(*packet));
+		pq_release_remote(sess, packet_get_id(*packet));
 		return rc;
 	}
@@ -328,5 +324,5 @@
 	rc = packet_set_addr(*packet, NULL, (uint8_t *) addr, addrlen);
 	if (rc != EOK) {
-		pq_release_remote(packet_phone, packet_get_id(*packet));
+		pq_release_remote(sess, packet_get_id(*packet));
 		return rc;
 	}
Index: uspace/lib/net/tl/tl_remote.c
===================================================================
--- uspace/lib/net/tl/tl_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/tl/tl_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -34,22 +34,21 @@
 #include <generic.h>
 #include <packet_client.h>
-
 #include <ipc/services.h>
 #include <ipc/tl.h>
-
 #include <net/device.h>
 #include <net/packet.h>
+#include <async.h>
 
 /** Notify the remote transport layer modules about the received packet/s.
  *
- * @param[in] tl_phone  The transport layer module phone used for remote calls.
- * @param[in] device_id The device identifier.
- * @param[in] packet    The received packet or the received packet queue.
+ * @param[in] sess      Transport layer module session.
+ * @param[in] device_id Device identifier.
+ * @param[in] packet    Received packet or the received packet queue.
  *                      The packet queue is used to carry a fragmented
  *                      datagram. The first packet contains the headers,
  *                      the others contain only data.
- * @param[in] target    The target transport layer module service to be
+ * @param[in] target    Target transport layer module service to be
  *                      delivered to.
- * @param[in] error     The packet error reporting service. Prefixes the
+ * @param[in] error     Packet error reporting service. Prefixes the
  *                      received packet.
  *
@@ -57,8 +56,8 @@
  *
  */
-int tl_received_msg(int tl_phone, device_id_t device_id, packet_t *packet,
+int tl_received_msg(async_sess_t *sess, device_id_t device_id, packet_t *packet,
     services_t target, services_t error)
 {
-	return generic_received_msg_remote(tl_phone, NET_TL_RECEIVED, device_id,
+	return generic_received_msg_remote(sess, NET_TL_RECEIVED, device_id,
 	    packet_get_id(packet), target, error);
 }
Index: uspace/lib/net/tl/tl_skel.c
===================================================================
--- uspace/lib/net/tl/tl_skel.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/tl/tl_skel.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,16 +38,14 @@
 #include <bool.h>
 #include <errno.h>
+#include <ns.h>
 #include <tl_skel.h>
 #include <net_interface.h>
 #include <net/modules.h>
 
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
-
 /** Default thread for new connections.
  *
- * @param[in] iid  	The initial message identifier.
- * @param[in] icall	The initial message call structure.
- * @param[in] arg	Local argument.
+ * @param[in] iid   The initial message identifier.
+ * @param[in] icall The initial message call structure.
+ * @param[in] arg   Local argument.
  *
  */
@@ -106,10 +104,10 @@
  *
  */
-int tl_module_start(int service)
+int tl_module_start(sysarg_t service)
 {
 	async_set_client_connection(tl_client_connection);
-	int net_phone = net_connect_module();
-	if (net_phone < 0)
-		return net_phone;
+	async_sess_t *sess = net_connect_module();
+	if (!sess)
+		return ENOENT;
 	
 	int rc = pm_init();
@@ -117,9 +115,9 @@
 		return rc;
 	
-	rc = tl_initialize(net_phone);
+	rc = tl_initialize(sess);
 	if (rc != EOK)
 		goto out;
 	
-	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL, NULL);
+	rc = service_register(service);
 	if (rc != EOK)
 		goto out;
Index: uspace/lib/packet/generic/packet_server.c
===================================================================
--- uspace/lib/packet/generic/packet_server.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/packet/generic/packet_server.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -36,5 +36,4 @@
 
 #include <packet_server.h>
-
 #include <align.h>
 #include <assert.h>
@@ -317,15 +316,13 @@
  *			packet_release_wrapper() function.
  */
-int
-packet_server_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
+int packet_server_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
     size_t *answer_count)
 {
 	packet_t *packet;
-
-	*answer_count = 0;
 	
 	if (!IPC_GET_IMETHOD(*call))
 		return EOK;
 	
+	*answer_count = 0;
 	switch (IPC_GET_IMETHOD(*call)) {
 	case NET_PACKET_CREATE_1:
Index: uspace/lib/scsi/Makefile
===================================================================
--- uspace/lib/scsi/Makefile	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/scsi/Makefile	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2011 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.
+#
+
+USPACE_PREFIX = ../..
+EXTRA_CFLAGS = -Iinclude
+LIBRARY = libscsi
+
+SOURCES = \
+	src/spc.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/scsi/include/scsi/sbc.h
===================================================================
--- uspace/lib/scsi/include/scsi/sbc.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/scsi/include/scsi/sbc.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2011 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 libscsi
+ * @{
+ */
+/**
+ * @file SCSI Block Commands.
+ */
+
+#ifndef LIBSCSI_SBC_H_
+#define LIBSCSI_SBC_H_
+
+#include <stdint.h>
+
+/** SCSI command codes defined in SCSI-SBC */
+enum scsi_cmd_sbc {
+	SCSI_CMD_READ_6			= 0x08,
+	SCSI_CMD_READ_10		= 0x28,
+	SCSI_CMD_READ_12		= 0xa8,
+	SCSI_CMD_READ_16		= 0x88,
+	SCSI_CMD_READ_32		= 0x7f,
+
+	SCSI_CMD_READ_CAPACITY_10	= 0x25,
+	SCSI_CMD_READ_CAPACITY_16	= 0x9e,
+
+	SCSI_CMD_WRITE_6		= 0x0a,
+	SCSI_CMD_WRITE_10		= 0x2a,
+	SCSI_CMD_WRITE_12		= 0xaa,
+	SCSI_CMD_WRITE_16		= 0x8a
+};
+
+/** SCSI Read (12) command */
+typedef struct {
+	/** Operation code (SCSI_CMD_READ_12) */
+	uint8_t op_code;
+	/** RdProtect, DPO, FUA, Reserved, FUA_NV, Reserved */
+	uint8_t flags;
+	/** Logical block address */
+	uint32_t lba;
+	/** Transfer length */
+	uint32_t xfer_len;
+	/** Reserved, Group Number */
+	uint8_t group_no;
+	/** Control */
+	uint8_t control;
+} __attribute__((packed)) scsi_cdb_read_12_t;
+
+/** SCSI Read (16) command */
+typedef struct {
+	/** Operation code (SCSI_CMD_READ_16) */
+	uint8_t op_code;
+	/** RdProtect, DPO, FUA, Reserved, FUA_NV, Reserved */
+	uint8_t flags;
+	/** Logical block address */
+	uint64_t lba;
+	/** Transfer length */
+	uint32_t xfer_len;
+	/** Reserved, Group Number */
+	uint8_t group_no;
+	/** Control */
+	uint8_t control;
+} __attribute__((packed)) scsi_cdb_read_16_t;
+
+/** SCSI Read Capacity (10) command */
+typedef struct {
+	/** Operation code (SCSI_CMD_READ_CAPACITY_10) */
+	uint8_t op_code;
+	/** Reserved, Obsolete */
+	uint8_t reserved_1;
+	/** Logical block address */
+	uint32_t lba;
+	/** Reserved */
+	uint32_t reserved_6;
+	/** Reserved, PM */
+	uint8_t pm;
+	/** Control */
+	uint8_t control;
+} __attribute__((packed)) scsi_cdb_read_capacity_10_t;
+
+/** Read Capacity (10) parameter data.
+ *
+ * Returned for Read Capacity (10) command.
+ */
+typedef struct {
+	/** Logical address of last block */
+	uint32_t last_lba;
+	/** Size of block in bytes */
+	uint32_t block_size;
+} scsi_read_capacity_10_data_t;
+
+/** SCSI Write (12) command */
+typedef struct {
+	/** Operation code (SCSI_CMD_WRITE_12) */
+	uint8_t op_code;
+	/** WrProtect, DPO, FUA, Reserved, FUA_NV, Reserved */
+	uint8_t flags;
+	/** Logical block address */
+	uint32_t lba;
+	/** Transfer length */
+	uint32_t xfer_len;
+	/** Reserved, Group Number */
+	uint8_t group_no;
+	/** Control */
+	uint8_t control;
+} __attribute__((packed)) scsi_cdb_write_12_t;
+
+/** SCSI Write (16) command */
+typedef struct {
+	/** Operation code (SCSI_CMD_WRITE_16) */
+	uint8_t op_code;
+	/** WrProtect, DPO, FUA, Reserved, FUA_NV, Reserved */
+	uint8_t flags;
+	/** Logical block address */
+	uint64_t lba;
+	/** Transfer length */
+	uint32_t xfer_len;
+	/** Reserved, Group Number */
+	uint8_t group_no;
+	/** Control */
+	uint8_t control;
+} __attribute__((packed)) scsi_cdb_write_16_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/scsi/include/scsi/spc.h
===================================================================
--- uspace/lib/scsi/include/scsi/spc.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/scsi/include/scsi/spc.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2011 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 libscsi
+ * @{
+ */
+/**
+ * @file SCSI Primary Commands.
+ */
+
+#ifndef LIBSCSI_SPC_H_
+#define LIBSCSI_SPC_H_
+
+#include <stdint.h>
+#include <str.h>
+
+/** SCSI command codes defined in SCSI-SPC */
+enum scsi_cmd_spc {
+	SCSI_CMD_INQUIRY	= 0x12,
+	SCSI_CMD_REQUEST_SENSE	= 0x03
+};
+
+/** SCSI Inquiry command */
+typedef struct {
+	/** Operation code (SCSI_CMD_INQUIRY) */
+	uint8_t op_code;
+	/** Reserved:7-2, obsolete:1, evpd:0 */
+	uint8_t evpd;
+	/* Page Code */
+	uint8_t page_code;
+	/* Allocation Length */
+	uint16_t alloc_len;
+	/* Control */
+	uint8_t control;
+} __attribute__((packed)) scsi_cdb_inquiry_t;
+
+/** Minimum size of inquiry data required since SCSI-2 */
+#define SCSI_STD_INQUIRY_DATA_MIN_SIZE 36
+
+/** Standard inquiry data.
+ *
+ * Returned for Inquiry command with evpd bit cleared.
+ */
+typedef struct {
+	/** Peripheral qualifier, Peripheral device type */
+	uint8_t pqual_devtype;
+	/** RMB, reserved */
+	uint8_t rmb;
+	/** Version */
+	uint8_t version;
+	/** Obsolete, NormACA, HiSup, Response Data Format */
+	uint8_t aca_hisup_rdf;
+	/** Additional Length */
+	uint8_t additional_len;
+	/** SCCS, ACC, TPGS, 3PC, Reserved, Protect */
+	uint8_t cap1;
+	/** Obsolete, EncServ, VS, MuliP, Obsolete, Addr16 */
+	uint8_t cap2;
+	/** Obsolete, WBus16, Sync, Obsolete, CmdQue, VS */
+	uint8_t cap3;
+
+	/** Vendor string */
+	uint8_t vendor[8];
+	/** Product string */
+	uint8_t product[16];
+	/** Revision string */
+	uint8_t revision[4];
+
+	/* End of required data */
+} __attribute__((packed)) scsi_std_inquiry_data_t;
+
+/** Size of struct or union member. */
+#define SCSI_MEMBER_SIZE(type, member) \
+    (sizeof(((type *)0) -> member))
+
+/** Size of string buffer needed to hold converted inquiry vendor string */
+#define SCSI_INQ_VENDOR_STR_BUFSIZE \
+    SPASCII_STR_BUFSIZE(SCSI_MEMBER_SIZE(scsi_std_inquiry_data_t, vendor))
+
+/** Size of string buffer needed to hold converted inquiry product string */
+#define SCSI_INQ_PRODUCT_STR_BUFSIZE \
+    SPASCII_STR_BUFSIZE(SCSI_MEMBER_SIZE(scsi_std_inquiry_data_t, product))
+
+/** Size of string buffer needed to hold converted inquiry revision string */
+#define SCSI_INQ_REVISION_STR_BUFSIZE \
+    SPASCII_STR_BUFSIZE(SCSI_MEMBER_SIZE(scsi_std_inquiry_data_t, revision))
+
+/** Bits in scsi_std_inquiry_data_t.pqual_devtype */
+enum scsi_pqual_devtype_bits {
+	/* Peripheral qualifier */
+	SCSI_PQDT_PQUAL_h	= 7,
+	SCSI_PQDT_PQUAL_l	= 5,
+
+	/* Peripheral device type */
+	SCSI_PQDT_DEV_TYPE_h	= 4,
+	SCSI_PQDT_DEV_TYPE_l	= 0
+};
+
+/** Bits in scsi_std_inquiry_data_t.rmb */
+enum scsi_rmb_bits {
+	SCSI_RMB_RMB		= 7
+};
+
+/** SCSI peripheral device type */
+enum scsi_device_type {
+	SCSI_DEV_BLOCK		= 0x00,
+	SCSI_DEV_STREAM		= 0x01,
+	SCSI_DEV_CD_DVD		= 0x05,
+	SCSI_DEV_CHANGER	= 0x08,
+	SCSI_DEV_ENCLOSURE	= 0x0d,
+	SCSI_DEV_OSD		= 0x11,
+
+	SCSI_DEV_LIMIT		= 0x20
+};
+
+/** SCSI Request Sense command */
+typedef struct {
+	/** Operation code (SCSI_CMD_REQUEST_SENSE) */
+	uint8_t op_code;
+	/** Reserved, Desc */
+	uint8_t desc;
+	/* Reserved */
+	uint16_t res_2;
+	/* Allocation Length */
+	uint8_t alloc_len;
+	/* Control */
+	uint8_t control;
+} __attribute__((packed)) scsi_cdb_request_sense_t;
+
+/** Minimum size of sense data.
+ *
+ * If the target returns less data, the missing bytes should be considered
+ * zero.
+ */
+#define SCSI_SENSE_DATA_MIN_SIZE 18
+
+/** Maximum size of sense data */
+#define SCSI_SENSE_DATA_MAX_SIZE 252
+
+/** Fixed-format sense data.
+ *
+ * Returned for Request Sense command with Desc bit cleared.
+ */
+typedef struct {
+	/** Valid, Response Code */
+	uint8_t valid_rcode;
+	/** Peripheral qualifier, Peripheral device type */
+	uint8_t obsolete_1;
+	/** Filemark, EOM, ILI, Reserved, Sense Key */
+	uint8_t flags_key;
+	/** Information */
+	uint32_t info;
+	/** Additional Sense Length */
+	uint8_t additional_len;
+	/** Command-specific Information */
+	uint8_t cmd_spec;
+	/** Additional Sense Code */
+	uint8_t additional_code;
+	/** Additional Sense Code Qualifier */
+	uint8_t additional_cqual;
+	/** Field-replaceable Unit Code */
+	uint8_t fru_code;
+	/** SKSV, Sense-key specific */
+	uint8_t key_spec[3];
+} __attribute__((packed)) scsi_sense_data_t;
+
+/** Sense key */
+enum scsi_sense_key {
+	SCSI_SK_NO_SENSE	= 0x0,
+	SCSI_SK_RECOVERED_ERROR	= 0x1,
+	SCSI_SK_NOT_READY	= 0x2,
+	SCSI_SK_MEDIUM_ERROR	= 0x3,
+	SCSI_SK_HARDWARE_ERROR	= 0x4,
+	SCSI_SK_ILLEGAL_REQUEST	= 0x5,
+	SCSI_SK_UNIT_ATTENTION	= 0x6,
+	SCSI_SK_DATA_PROTECT	= 0x7,
+	SCSI_SK_BLANK_CHECK	= 0x8,
+	SCSI_SK_VENDOR_SPECIFIC	= 0x9,
+	SCSI_SK_COPY_ABORTED	= 0xa,
+	SCSI_SK_ABORTED_COMMAND	= 0xb,
+	SCSI_SK_VOLUME_OVERFLOW	= 0xd,
+	SCSI_SK_MISCOMPARE	= 0xe
+};
+
+extern const char *scsi_dev_type_str[SCSI_DEV_LIMIT];
+extern const char *scsi_get_dev_type_str(unsigned);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/scsi/src/spc.c
===================================================================
--- uspace/lib/scsi/src/spc.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/scsi/src/spc.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2011 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 <stdint.h>
+#include <stdlib.h>
+#include "scsi/spc.h"
+
+/** String descriptions for SCSI peripheral device type.
+ *
+ * Only device types that we are ever likely to encounter are listed here.
+ */
+const char *scsi_dev_type_str[SCSI_DEV_LIMIT] = {
+	[SCSI_DEV_BLOCK]	= "Direct-Access Block Device (Disk)",
+	[SCSI_DEV_STREAM]	= "Sequential-Access Device (Tape)",
+	[SCSI_DEV_CD_DVD]	= "CD/DVD",
+	[SCSI_DEV_CHANGER]	= "Media Changer",
+	[SCSI_DEV_ENCLOSURE]	= "SCSI Enclosure",
+	[SCSI_DEV_OSD]		= "Object Storage Device"
+};
+
+/** Get peripheral device type string.
+ *
+ * Return string description of SCSI peripheral device type.
+ * The returned string is valid indefinitely, the caller should
+ * not attempt to free it.
+ */
+const char *scsi_get_dev_type_str(unsigned dev_type)
+{
+	if (dev_type >= SCSI_DEV_LIMIT || scsi_dev_type_str[dev_type] == NULL)
+		return "<unknown>";
+
+	return scsi_dev_type_str[dev_type];
+}
Index: uspace/lib/softfloat/arch/mips32/include/functions.h
===================================================================
--- uspace/lib/softfloat/arch/mips32/include/functions.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/softfloat/arch/mips32/include/functions.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup softfloatmips32 mips32	
+/** @addtogroup softfloatmips32 mips32
  * @ingroup sfl
  * @brief softfloat architecture dependent definitions 
@@ -72,6 +72,4 @@
 #endif
 
-
- /** @}
+/** @}
  */
-
Index: uspace/lib/softfloat/arch/mips64/include/functions.h
===================================================================
--- uspace/lib/softfloat/arch/mips64/include/functions.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/softfloat/arch/mips64/include/functions.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * 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 softfloatmips64 mips64
+ * @ingroup sfl
+ * @brief softfloat architecture dependent definitions
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __SOFTFLOAT_FUNCTIONS_H__
+#define __SOFTFLOAT_FUNCTIONS_H__
+
+#define float32_to_int(X) float32_to_int32(X);
+#define float32_to_long(X) float32_to_int64(X);
+#define float32_to_longlong(X) float32_to_int64(X);
+
+#define float64_to_int(X) float64_to_int32(X);
+#define float64_to_long(X) float64_to_int64(X);
+#define float64_to_longlong(X) float64_to_int64(X);
+
+#define float32_to_uint(X) float32_to_uint32(X);
+#define float32_to_ulong(X) float32_to_uint64(X);
+#define float32_to_ulonglong(X) float32_to_uint64(X);
+
+#define float64_to_uint(X) float64_to_uint32(X);
+#define float64_to_ulong(X) float64_to_uint64(X);
+#define float64_to_ulonglong(X) float64_to_uint64(X);
+
+#define int_to_float32(X) int32_to_float32(X);
+#define long_to_float32(X) int64_to_float32(X);
+#define longlong_to_float32(X) int64_to_float32(X);
+
+#define int_to_float64(X) int32_to_float64(X);
+#define long_to_float64(X) int64_to_float64(X);
+#define longlong_to_float64(X) int64_to_float64(X);
+
+#define uint_to_float32(X) uint32_to_float32(X);
+#define ulong_to_float32(X) uint64_to_float32(X);
+#define ulonglong_to_float32(X) uint64_to_float32(X);
+
+#define uint_to_float64(X) uint32_to_float64(X);
+#define ulong_to_float64(X) uint64_to_float64(X);
+#define ulonglong_to_float64(X) uint64_to_float64(X);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/usbhost/src/batch.c
===================================================================
--- uspace/lib/usbhost/src/batch.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/usbhost/src/batch.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -128,5 +128,5 @@
 	memcpy(instance->buffer, instance->data_buffer, instance->buffer_size);
 
-	usb_log_debug("Batch %p " USB_TRANSFER_BATCH_FMT " completed (%zuB): %s.\n",
+	usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " completed (%zuB): %s.\n",
 	    instance, USB_TRANSFER_BATCH_ARGS(*instance),
 	    instance->transfered_size, str_error(instance->error));
@@ -145,5 +145,5 @@
 	assert(instance->callback_out);
 
-	usb_log_debug("Batch %p " USB_TRANSFER_BATCH_FMT " completed: %s.\n",
+	usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " completed: %s.\n",
 	    instance, USB_TRANSFER_BATCH_ARGS(*instance),
 	    str_error(instance->error));
Index: uspace/srv/bd/ata_bd/ata_bd.c
===================================================================
--- uspace/srv/bd/ata_bd/ata_bd.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/bd/ata_bd/ata_bd.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -80,7 +80,4 @@
  */
 static const size_t identify_data_size = 512;
-
-/** Size of the communication area. */
-static size_t comm_size;
 
 /** I/O base address of the command registers. */
@@ -281,4 +278,5 @@
 	sysarg_t method;
 	devmap_handle_t dh;
+	size_t comm_size;	/**< Size of the communication area. */
 	unsigned int flags;
 	int retval;
Index: uspace/srv/fs/ext2fs/ext2fs_ops.c
===================================================================
--- uspace/srv/fs/ext2fs/ext2fs_ops.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/fs/ext2fs/ext2fs_ops.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -240,5 +240,5 @@
 	}
 	
-	rc = ext2_directory_iterator_init(&it, fs, eparent->inode_ref);
+	rc = ext2_directory_iterator_init(&it, fs, eparent->inode_ref, 0);
 	if (rc != EOK) {
 		return rc;
@@ -478,5 +478,5 @@
 	}
 	
-	rc = ext2_directory_iterator_init(&it, fs, enode->inode_ref);
+	rc = ext2_directory_iterator_init(&it, fs, enode->inode_ref, 0);
 	if (rc != EOK) {
 		EXT2FS_DBG("error %u", rc);
@@ -818,5 +818,5 @@
 {
 	ext2_directory_iterator_t it;
-	aoff64_t cur;
+	aoff64_t next;
 	uint8_t *buf;
 	size_t name_size;
@@ -824,5 +824,5 @@
 	bool found = false;
 	
-	rc = ext2_directory_iterator_init(&it, inst->filesystem, inode_ref);
+	rc = ext2_directory_iterator_init(&it, inst->filesystem, inode_ref, pos);
 	if (rc != EOK) {
 		async_answer_0(callid, rc);
@@ -831,11 +831,8 @@
 	}
 	
-	/* Find the index we want to read
-	 * Note that we need to iterate and count as
-	 * the underlying structure is a linked list
-	 * Moreover, we want to skip . and .. entries
+	/* Find next interesting directory entry.
+	 * We want to skip . and .. entries
 	 * as these are not used in HelenOS
 	 */
-	cur = 0;
 	while (it.current != NULL) {
 		if (it.current->inode == 0) {
@@ -851,25 +848,21 @@
 		}
 		
-		/* Is this the dir entry we want to read? */
-		if (cur == pos) {
-			/* The on-disk entry does not contain \0 at the end
-			 * end of entry name, so we copy it to new buffer
-			 * and add the \0 at the end
-			 */
-			buf = malloc(name_size+1);
-			if (buf == NULL) {
-				ext2_directory_iterator_fini(&it);
-				async_answer_0(callid, ENOMEM);
-				async_answer_0(rid, ENOMEM);
-				return;
-			}
-			memcpy(buf, &it.current->name, name_size);
-			*(buf+name_size) = 0;
-			found = true;
-			(void) async_data_read_finalize(callid, buf, name_size+1);
-			free(buf);
-			break;
-		}
-		cur++;
+		/* The on-disk entry does not contain \0 at the end
+			* end of entry name, so we copy it to new buffer
+			* and add the \0 at the end
+			*/
+		buf = malloc(name_size+1);
+		if (buf == NULL) {
+			ext2_directory_iterator_fini(&it);
+			async_answer_0(callid, ENOMEM);
+			async_answer_0(rid, ENOMEM);
+			return;
+		}
+		memcpy(buf, &it.current->name, name_size);
+		*(buf+name_size) = 0;
+		found = true;
+		(void) async_data_read_finalize(callid, buf, name_size+1);
+		free(buf);
+		break;
 		
 skip:
@@ -883,4 +876,13 @@
 	}
 	
+	if (found) {
+		rc = ext2_directory_iterator_next(&it);
+		if (rc != EOK) {
+			async_answer_0(rid, rc);
+			return;
+		}
+		next = it.current_offset;
+	}
+	
 	rc = ext2_directory_iterator_fini(&it);
 	if (rc != EOK) {
@@ -890,5 +892,5 @@
 	
 	if (found) {
-		async_answer_1(rid, EOK, 1);
+		async_answer_1(rid, EOK, next-pos);
 	}
 	else {
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/console/console.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -357,5 +357,5 @@
 		console_serialize_end();
 		
-		if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) {
+		if (console_kcon()) {
 			prev_console = active_console;
 			active_console = kernel_console;
@@ -711,7 +711,4 @@
 			console_serialize_start();
 			continue;
-		case CONSOLE_KCON_ENABLE:
-			change_console(kernel_console);
-			break;
 		}
 		async_answer_3(callid, EOK, arg1, arg2, arg3);
@@ -833,7 +830,4 @@
 	}
 	
-	/* Disable kernel output to the console */
-	__SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE);
-	
 	/* Initialize the screen */
 	console_serialize_start();
Index: uspace/srv/hid/fb/Makefile
===================================================================
--- uspace/srv/hid/fb/Makefile	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/fb/Makefile	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -84,11 +84,4 @@
 		EXTRA_CFLAGS += -DNIAGARA_ENABLED
 	endif
-	
-	ifeq ($(MACHINE),serengeti)
-		SOURCES += \
-			sgcn.c \
-			serial_console.c
-		EXTRA_CFLAGS += -DSGCN_ENABLED
-	endif
 endif
 
Index: uspace/srv/hid/fb/main.c
===================================================================
--- uspace/srv/hid/fb/main.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/fb/main.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -40,5 +40,4 @@
 #include "msim.h"
 #include "ski.h"
-#include "sgcn.h"
 #include "niagara.h"
 #include "main.h"
@@ -92,10 +91,4 @@
 	}
 #endif
-#ifdef SGCN_ENABLED
-	if ((!initialized) && (fb_kind == 4)) {
-		if (sgcn_init() == 0)
-			initialized = true;
-	}
-#endif
 #ifdef NIAGARA_ENABLED
 	if ((!initialized) && (fb_kind == 5)) {
Index: uspace/srv/hid/fb/niagara.c
===================================================================
--- uspace/srv/hid/fb/niagara.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/fb/niagara.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -29,5 +29,5 @@
  */
 
-/** @defgroup niagarafb SGCN
+/** @defgroup niagarafb
  * @brief	userland driver of the Niagara console output
  * @{
Index: uspace/srv/hid/fb/niagara.h
===================================================================
--- uspace/srv/hid/fb/niagara.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/fb/niagara.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,6 +27,6 @@
  */
 
-/** @defgroup sgcnfb SGCN
- * @brief	userland driver of the Serengeti console output
+/** @defgroup niagarafb
+ * @brief	userland driver of the Niagara console output
  * @{
  */
Index: uspace/srv/hid/fb/sgcn.c
===================================================================
--- uspace/srv/hid/fb/sgcn.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,150 +1,0 @@
-/*
- * Copyright (c) 2006 Ondrej Palkovsky
- * Copyright (c) 2008 Martin Decky
- * Copyright (c) 2008 Pavel Rimsky
- * 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.
- */
-
-/** @defgroup sgcnfb SGCN
- * @brief	userland driver of the Serengeti console output
- * @{
- */ 
-/** @file
- */
-
-#include <async.h>
-#include <sysinfo.h>
-#include <as.h>
-#include <errno.h>
-#include <stdio.h>
-#include <ddi.h>
-
-#include "serial_console.h"
-#include "sgcn.h"
-
-#define WIDTH 80
-#define HEIGHT 24
-
-/**
- * Virtual address mapped to SRAM.
- */
-static uintptr_t sram_virt_addr;
-
-/**
- * SGCN buffer offset within SGCN.
- */
-static uintptr_t sram_buffer_offset;
-
-/**
- * SGCN buffer header. It is placed at the very beginning of the SGCN
- * buffer. 
- */
-typedef struct {
-	/** hard-wired to "CON" */
-	char magic[4];
-	
-	/** we don't need this */
-	char unused[24];
-
-	/** offset within the SGCN buffer of the output buffer start */
-	uint32_t out_begin;
-	
-	/** offset within the SGCN buffer of the output buffer end */
-	uint32_t out_end;
-	
-	/** offset within the SGCN buffer of the output buffer read pointer */
-	uint32_t out_rdptr;
-	
-	/** offset within the SGCN buffer of the output buffer write pointer */
-	uint32_t out_wrptr;
-} __attribute__ ((packed)) sgcn_buffer_header_t;
-
-
-/*
- * Returns a pointer to the object of a given type which is placed at the given
- * offset from the console buffer beginning.
- */
-#define SGCN_BUFFER(type, offset) \
-		((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
-
-/** Returns a pointer to the console buffer header. */
-#define SGCN_BUFFER_HEADER	(SGCN_BUFFER(sgcn_buffer_header_t, 0))
-
-/**
- * Pushes the character to the SGCN serial.
- * @param c	character to be pushed
- */
-static void sgcn_putc(char c)
-{
-	uint32_t begin = SGCN_BUFFER_HEADER->out_begin;
-	uint32_t end = SGCN_BUFFER_HEADER->out_end;
-	uint32_t size = end - begin;
-	
-	/* we need pointers to volatile variables */
-	volatile char *buf_ptr = (volatile char *)
-		SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr);
-	volatile uint32_t *out_wrptr_ptr = &(SGCN_BUFFER_HEADER->out_wrptr);
-	volatile uint32_t *out_rdptr_ptr = &(SGCN_BUFFER_HEADER->out_rdptr);
-
-	uint32_t new_wrptr = (((*out_wrptr_ptr) - begin + 1) % size) + begin;
-	while (*out_rdptr_ptr == new_wrptr)
-		;
-	*buf_ptr = c;
-	*out_wrptr_ptr = new_wrptr;
-}
-
-/**
- * Initializes the SGCN serial driver.
- */
-int sgcn_init(void)
-{
-	sysarg_t sram_paddr;
-	if (sysinfo_get_value("sram.address.physical", &sram_paddr) != EOK)
-		return -1;
-	
-	sysarg_t sram_size;
-	if (sysinfo_get_value("sram.area.size", &sram_size) != EOK)
-		return -1;
-	
-	if (sysinfo_get_value("sram.buffer.offset", &sram_buffer_offset) != EOK)
-		sram_buffer_offset = 0;
-	
-	sram_virt_addr = (uintptr_t) as_get_mappable_page(sram_size);
-	
-	if (physmem_map((void *) sram_paddr, (void *) sram_virt_addr,
-	    sram_size / PAGE_SIZE, AS_AREA_READ | AS_AREA_WRITE) != 0)
-		return -1;
-	
-	serial_console_init(sgcn_putc, WIDTH, HEIGHT);
-	
-	async_set_client_connection(serial_client_connection);
-	return 0;
-}
-
-/** 
- * @}
- */
- 
Index: uspace/srv/hid/fb/sgcn.h
===================================================================
--- uspace/srv/hid/fb/sgcn.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
- * Copyright (c) 2008 Pavel Rimsky
- * 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.
- */
-
-/** @defgroup sgcnfb SGCN
- * @brief	userland driver of the Serengeti console output
- * @{
- */
- 
-/** @file
- */
-
-#ifndef FB_SGCN_H_
-#define FB_SGCN_H_
-
-int sgcn_init(void);
-
-#endif
-
-/** 
- * @}
- */
Index: uspace/srv/hid/input/Makefile
===================================================================
--- uspace/srv/hid/input/Makefile	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/input/Makefile	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -49,7 +49,5 @@
 	port/ns16550.c \
 	port/pl050.c \
-	port/sgcn.c \
 	port/ski.c \
-	port/z8530.c \
 	proto/adb.c \
 	proto/mousedev.c \
Index: uspace/srv/hid/input/generic/input.c
===================================================================
--- uspace/srv/hid/input/generic/input.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/input/generic/input.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -424,9 +424,5 @@
 	kbd_add_dev(&niagara_port, &stty_ctl);
 #endif
-#if defined(UARCH_sparc64) && defined(MACHINE_serengeti)
-	kbd_add_dev(&sgcn_port, &stty_ctl);
-#endif
 #if defined(UARCH_sparc64) && defined(MACHINE_generic)
-	kbd_add_dev(&z8530_port, &sun_ctl);
 	kbd_add_dev(&ns16550_port, &sun_ctl);
 #endif
@@ -556,5 +552,4 @@
 	printf("%s: HelenOS input service\n", NAME);
 	
-	sysarg_t fhc;
 	sysarg_t obio;
 	
@@ -562,6 +557,5 @@
 	list_initialize(&mouse_devs);
 	
-	if (((sysinfo_get_value("kbd.cir.fhc", &fhc) == EOK) && (fhc))
-	    || ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio)))
+	if ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio))
 		irc_service = true;
 	
Index: uspace/srv/hid/input/include/kbd_port.h
===================================================================
--- uspace/srv/hid/input/include/kbd_port.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/input/include/kbd_port.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -56,7 +56,5 @@
 extern kbd_port_ops_t ns16550_port;
 extern kbd_port_ops_t pl050_port;
-extern kbd_port_ops_t sgcn_port;
 extern kbd_port_ops_t ski_port;
-extern kbd_port_ops_t z8530_port;
 
 #endif
Index: uspace/srv/hid/input/port/niagara.c
===================================================================
--- uspace/srv/hid/input/port/niagara.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/input/port/niagara.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -154,5 +154,5 @@
 
 /**
- * Thread to poll SGCN for keypresses.
+ * Thread to poll Niagara console for keypresses.
  */
 static void niagara_thread_impl(void *arg)
Index: uspace/srv/hid/input/port/sgcn.c
===================================================================
--- uspace/srv/hid/input/port/sgcn.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,205 +1,0 @@
-/*
- * Copyright (c) 2008 Pavel Rimsky
- * Copyright (c) 2011 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 kbd_port
- * @ingroup  kbd
- * @{
- */
-/** @file
- * @brief SGCN (Serengeti Console) keyboard port driver.
- */
-
-#include <as.h>
-#include <ddi.h>
-#include <async.h>
-#include <kbd.h>
-#include <kbd_port.h>
-#include <sysinfo.h>
-#include <stdio.h>
-#include <thread.h>
-#include <bool.h>
-#include <errno.h>
-
-static int sgcn_port_init(kbd_dev_t *);
-static void sgcn_port_yield(void);
-static void sgcn_port_reclaim(void);
-static void sgcn_port_write(uint8_t data);
-
-kbd_port_ops_t sgcn_port = {
-	.init = sgcn_port_init,
-	.yield = sgcn_port_yield,
-	.reclaim = sgcn_port_reclaim,
-	.write = sgcn_port_write
-};
-
-static kbd_dev_t *kbd_dev;
-
-#define POLL_INTERVAL  10000
-
-/**
- * SGCN buffer header. It is placed at the very beginning of the SGCN
- * buffer.
- */
-typedef struct {
-	/** hard-wired to "CON" */
-	char magic[4];
-	
-	/** we don't need this */
-	char unused[8];
-	
-	/** offset within the SGCN buffer of the input buffer start */
-	uint32_t in_begin;
-	
-	/** offset within the SGCN buffer of the input buffer end */
-	uint32_t in_end;
-	
-	/** offset within the SGCN buffer of the input buffer read pointer */
-	uint32_t in_rdptr;
-	
-	/** offset within the SGCN buffer of the input buffer write pointer */
-	uint32_t in_wrptr;
-} __attribute__ ((packed)) sgcn_buffer_header_t;
-
-/*
- * Returns a pointer to the object of a given type which is placed at the given
- * offset from the console buffer beginning.
- */
-#define SGCN_BUFFER(type, offset) \
-		((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
-
-/** Returns a pointer to the console buffer header. */
-#define SGCN_BUFFER_HEADER	(SGCN_BUFFER(sgcn_buffer_header_t, 0))
-
-/**
- * Virtual address mapped to SRAM.
- */
-static uintptr_t sram_virt_addr;
-
-/**
- * SGCN buffer offset within SGCN.
- */
-static uintptr_t sram_buffer_offset;
-
-/* polling thread */
-static void sgcn_thread_impl(void *arg);
-
-static volatile bool polling_disabled = false;
-
-/**
- * Initializes the SGCN driver.
- * Maps the physical memory (SRAM) and creates the polling thread. 
- */
-static int sgcn_port_init(kbd_dev_t *kdev)
-{
-	kbd_dev = kdev;
-	
-	sysarg_t sram_paddr;
-	if (sysinfo_get_value("sram.address.physical", &sram_paddr) != EOK)
-		return -1;
-	
-	sysarg_t sram_size;
-	if (sysinfo_get_value("sram.area.size", &sram_size) != EOK)
-		return -1;
-	
-	if (sysinfo_get_value("sram.buffer.offset", &sram_buffer_offset) != EOK)
-		sram_buffer_offset = 0;
-	
-	sram_virt_addr = (uintptr_t) as_get_mappable_page(sram_size);
-	
-	if (physmem_map((void *) sram_paddr, (void *) sram_virt_addr,
-	    sram_size / PAGE_SIZE, AS_AREA_READ | AS_AREA_WRITE) != 0) {
-		printf("SGCN: uspace driver could not map physical memory.");
-		return -1;
-	}
-	
-	thread_id_t tid;
-	int rc = thread_create(sgcn_thread_impl, NULL, "kbd_poll", &tid);
-	if (rc != 0)
-		return rc;
-	
-	return 0;
-}
-
-static void sgcn_port_yield(void)
-{
-	polling_disabled = true;
-}
-
-static void sgcn_port_reclaim(void)
-{
-	polling_disabled = false;
-}
-
-static void sgcn_port_write(uint8_t data)
-{
-	(void) data;
-}
-
-/**
- * Handler of the "key pressed" event. Reads codes of all the pressed keys from
- * the buffer. 
- */
-static void sgcn_key_pressed(void)
-{
-	char c;
-	
-	uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
-	uint32_t end = SGCN_BUFFER_HEADER->in_end;
-	uint32_t size = end - begin;
-	
-	volatile char *buf_ptr = (volatile char *)
-		SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
-	volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
-	volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
-	
-	while (*in_rdptr_ptr != *in_wrptr_ptr) {
-		c = *buf_ptr;
-		*in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
-		buf_ptr = (volatile char *)
-		    SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
-		kbd_push_data(kbd_dev, c);
-	}
-}
-
-/**
- * Thread to poll SGCN for keypresses.
- */
-static void sgcn_thread_impl(void *arg)
-{
-	(void) arg;
-
-	while (1) {
-		if (polling_disabled == false)
-			sgcn_key_pressed();
-		usleep(POLL_INTERVAL);
-	}
-}
-
-/** @}
- */
Index: uspace/srv/hid/input/port/z8530.c
===================================================================
--- uspace/srv/hid/input/port/z8530.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,152 +1,0 @@
-/*
- * Copyright (c) 2006 Martin Decky
- * Copyright (c) 2011 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 kbd_port
- * @ingroup  kbd
- * @{
- */
-/** @file
- * @brief Z8530 keyboard port driver.
- */
-
-#include <ipc/irc.h>
-#include <async.h>
-#include <async_obsolete.h>
-#include <sysinfo.h>
-#include <input.h>
-#include <kbd.h>
-#include <kbd_port.h>
-#include <sys/types.h>
-#include <ddi.h>
-#include <errno.h>
-
-static int z8530_port_init(kbd_dev_t *);
-static void z8530_port_yield(void);
-static void z8530_port_reclaim(void);
-static void z8530_port_write(uint8_t data);
-
-kbd_port_ops_t z8530_port = {
-	.init = z8530_port_init,
-	.yield = z8530_port_yield,
-	.reclaim = z8530_port_reclaim,
-	.write = z8530_port_write
-};
-
-static kbd_dev_t *kbd_dev;
-
-#define CHAN_A_STATUS  4
-#define CHAN_A_DATA    6
-
-#define RR0_RCA  1
-
-static irq_cmd_t z8530_cmds[] = {
-	{
-		.cmd = CMD_PIO_READ_8,
-		.addr = (void *) 0,     /* Will be patched in run-time */
-		.dstarg = 1
-	},
-	{
-		.cmd = CMD_BTEST,
-		.value = RR0_RCA,
-		.srcarg = 1,
-		.dstarg = 3
-	},
-	{
-		.cmd = CMD_PREDICATE,
-		.value = 2,
-		.srcarg = 3
-	},
-	{
-		.cmd = CMD_PIO_READ_8,
-		.addr = (void *) 0,     /* Will be patched in run-time */
-		.dstarg = 2
-	},
-	{
-		.cmd = CMD_ACCEPT
-	}
-};
-
-static irq_code_t z8530_kbd = {
-	sizeof(z8530_cmds) / sizeof(irq_cmd_t),
-	z8530_cmds
-};
-
-static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call);
-
-static int z8530_port_init(kbd_dev_t *kdev)
-{
-	kbd_dev = kdev;
-	
-	sysarg_t z8530;
-	if (sysinfo_get_value("kbd.type.z8530", &z8530) != EOK)
-		return -1;
-	if (!z8530)
-		return -1;
-	
-	sysarg_t kaddr;
-	if (sysinfo_get_value("kbd.address.kernel", &kaddr) != EOK)
-		return -1;
-	
-	sysarg_t inr;
-	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
-		return -1;
-	
-	z8530_cmds[0].addr = (void *) kaddr + CHAN_A_STATUS;
-	z8530_cmds[3].addr = (void *) kaddr + CHAN_A_DATA;
-	
-	async_set_interrupt_received(z8530_irq_handler);
-	register_irq(inr, device_assign_devno(), inr, &z8530_kbd);
-	
-	return 0;
-}
-
-static void z8530_port_yield(void)
-{
-}
-
-static void z8530_port_reclaim(void)
-{
-}
-
-static void z8530_port_write(uint8_t data)
-{
-	(void) data;
-}
-
-static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call)
-{
-	kbd_push_data(kbd_dev, IPC_GET_ARG2(*call));
-	
-	if (irc_service)
-		async_obsolete_msg_1(irc_phone, IRC_CLEAR_INTERRUPT,
-		    IPC_GET_IMETHOD(*call));
-}
-
-/** @}
- */
Index: uspace/srv/hw/irc/fhc/Makefile
===================================================================
--- uspace/srv/hw/irc/fhc/Makefile	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,36 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# 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.
-#
-
-USPACE_PREFIX = ../../../..
-BINARY = fhc
-
-SOURCES = \
-	fhc.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/hw/irc/fhc/fhc.c
===================================================================
--- uspace/srv/hw/irc/fhc/fhc.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,161 +1,0 @@
-/*
- * Copyright (c) 2009 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 fhc
- * @{
- */
-
-/**
- * @file fhc.c
- * @brief FHC bus controller driver.
- */
-
-#include <ipc/services.h>
-#include <ipc/irc.h>
-#include <ns.h>
-#include <sysinfo.h>
-#include <as.h>
-#include <ddi.h>
-#include <align.h>
-#include <bool.h>
-#include <errno.h>
-#include <async.h>
-#include <align.h>
-#include <async.h>
-#include <stdio.h>
-#include <ipc/devmap.h>
-
-#define NAME "fhc"
-
-#define FHC_UART_INR	0x39
-
-#define FHC_UART_IMAP	0x0
-#define FHC_UART_ICLR	0x4
-
-static void *fhc_uart_phys;
-static volatile uint32_t *fhc_uart_virt;
-static size_t fhc_uart_size;
-
-/** Handle one connection to fhc.
- *
- * @param iid		Hash of the request that opened the connection.
- * @param icall		Call data of the request that opened the connection.
- * @param arg		Local argument.
- */
-static void fhc_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
-{
-	ipc_callid_t callid;
-	ipc_call_t call;
-
-	/*
-	 * Answer the first IPC_M_CONNECT_ME_TO call.
-	 */
-	async_answer_0(iid, EOK);
-
-	while (1) {
-		int inr;
-	
-		callid = async_get_call(&call);
-		switch (IPC_GET_IMETHOD(call)) {
-		case IRC_ENABLE_INTERRUPT:
-			/* Noop */
-			async_answer_0(callid, EOK);
-			break;
-		case IRC_CLEAR_INTERRUPT:
-			inr = IPC_GET_ARG1(call);
-			switch (inr) {
-			case FHC_UART_INR:
-				fhc_uart_virt[FHC_UART_ICLR] = 0;
-				async_answer_0(callid, EOK);
-				break;
-			default:
-				async_answer_0(callid, ENOTSUP);
-				break;
-			}
-			break;
-		default:
-			async_answer_0(callid, EINVAL);
-			break;
-		}
-	}
-}
-
-/** Initialize the FHC driver.
- *
- * So far, the driver heavily depends on information provided by the kernel via
- * sysinfo. In the future, there should be a standalone FHC driver.
- */
-static bool fhc_init(void)
-{
-	sysarg_t paddr;
-
-	if ((sysinfo_get_value("fhc.uart.physical", &paddr) != EOK)
-	    || (sysinfo_get_value("fhc.uart.size", &fhc_uart_size) != EOK)) {
-		printf(NAME ": no FHC UART registers found\n");
-		return false;
-	}
-	
-	fhc_uart_phys = (void *) paddr;
-	fhc_uart_virt = as_get_mappable_page(fhc_uart_size);
-	
-	int flags = AS_AREA_READ | AS_AREA_WRITE;
-	int retval = physmem_map(fhc_uart_phys, (void *) fhc_uart_virt,
-	    ALIGN_UP(fhc_uart_size, PAGE_SIZE) >> PAGE_WIDTH, flags);
-	
-	if (retval < 0) {
-		printf("%s: Error mapping FHC UART registers\n", NAME);
-		return false;
-	}
-	
-	printf("%s: FHC UART registers at %p, %zu bytes\n", NAME,
-	    fhc_uart_phys, fhc_uart_size);
-	
-	async_set_client_connection(fhc_connection);
-	service_register(SERVICE_IRC);
-	
-	return true;
-}
-
-int main(int argc, char **argv)
-{
-	printf("%s: HelenOS FHC bus controller driver\n", NAME);
-	
-	if (!fhc_init())
-		return -1;
-	
-	printf("%s: Accepting connections\n", NAME);
-	task_retval(0);
-	async_manager();
-	
-	/* Never reached */
-	return 0;
-}
-
-/**
- * @}
- */
Index: uspace/srv/hw/netif/ne2000/ne2000.c
===================================================================
--- uspace/srv/hw/netif/ne2000/ne2000.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hw/netif/ne2000/ne2000.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,5 +38,4 @@
 #include <assert.h>
 #include <async.h>
-#include <async_obsolete.h>
 #include <ddi.h>
 #include <errno.h>
@@ -44,7 +43,6 @@
 #include <malloc.h>
 #include <sysinfo.h>
+#include <ns.h>
 #include <ipc/services.h>
-#include <ns.h>
-#include <ns_obsolete.h>
 #include <ipc/irc.h>
 #include <net/modules.h>
@@ -78,5 +76,5 @@
 
 static bool irc_service = false;
-static int irc_phone = -1;
+static async_sess_t *irc_sess = NULL;
 
 /** NE2000 kernel interrupt command sequence.
@@ -154,13 +152,14 @@
 	device_id_t device_id = IRQ_GET_DEVICE(*call);
 	netif_device_t *device;
-	int nil_phone;
+	async_sess_t *nil_sess;
 	ne2k_t *ne2k;
 	
 	fibril_rwlock_read_lock(&netif_globals.lock);
 	
-	if (find_device(device_id, &device) == EOK) {
-		nil_phone = device->nil_phone;
+	nil_sess = netif_globals.nil_sess;
+	
+	if (find_device(device_id, &device) == EOK)
 		ne2k = (ne2k_t *) device->specific;
-	} else
+	else
 		ne2k = NULL;
 	
@@ -177,6 +176,6 @@
 				
 				list_remove(&frame->link);
-				nil_received_msg(nil_phone, device_id,
-				    frame->packet, SERVICE_NONE);
+				nil_received_msg(nil_sess, device_id, frame->packet,
+				    SERVICE_NONE);
 				free(frame);
 			}
@@ -278,5 +277,4 @@
 	
 	device->device_id = device_id;
-	device->nil_phone = -1;
 	device->specific = (void *) ne2k;
 	device->state = NETIF_STOPPED;
@@ -331,6 +329,9 @@
 		change_state(device, NETIF_ACTIVE);
 		
-		if (irc_service)
-			async_obsolete_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, ne2k->irq);
+		if (irc_service) {
+			async_exch_t *exch = async_exchange_begin(irc_sess);
+			async_msg_1(exch, IRC_ENABLE_INTERRUPT, ne2k->irq);
+			async_exchange_end(exch);
+		}
 	}
 	
@@ -390,6 +391,7 @@
 	
 	if (irc_service) {
-		while (irc_phone < 0)
-			irc_phone = service_obsolete_connect_blocking(SERVICE_IRC, 0, 0);
+		while (!irc_sess)
+			irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
+			    SERVICE_IRC, 0, 0);
 	}
 	
Index: uspace/srv/net/il/arp/arp.c
===================================================================
--- uspace/srv/net/il/arp/arp.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/il/arp/arp.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -164,5 +164,5 @@
 }
 
-static int arp_clean_cache_req(int arp_phone)
+static int arp_clean_cache_req(void)
 {
 	int count;
@@ -190,6 +190,6 @@
 }
 
-static int arp_clear_address_req(int arp_phone, device_id_t device_id,
-    services_t protocol, measured_string_t *address)
+static int arp_clear_address_req(device_id_t device_id, services_t protocol,
+    measured_string_t *address)
 {
 	fibril_mutex_lock(&arp_globals.lock);
@@ -218,5 +218,5 @@
 }
 
-static int arp_clear_device_req(int arp_phone, device_id_t device_id)
+static int arp_clear_device_req(device_id_t device_id)
 {
 	fibril_mutex_lock(&arp_globals.lock);
@@ -375,5 +375,5 @@
 				return rc;
 			
-			nil_send_msg(device->phone, device_id, packet,
+			nil_send_msg(device->sess, device_id, packet,
 			    SERVICE_ARP);
 			return 1;
@@ -416,5 +416,6 @@
  * @param[in]     iid   Message identifier.
  * @param[in,out] icall Message parameters.
- * @param[in]	  arg	Local argument.
+ * @param[in]     arg   Local argument.
+ *
  */
 static void arp_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
@@ -431,5 +432,5 @@
 		
 		case NET_IL_RECEIVED:
-			rc = packet_translate_remote(arp_globals.net_phone, &packet,
+			rc = packet_translate_remote(arp_globals.net_sess, &packet,
 			    IPC_GET_PACKET(*icall));
 			if (rc == EOK) {
@@ -439,5 +440,5 @@
 					rc = arp_receive_message(IPC_GET_DEVICE(*icall), packet);
 					if (rc != 1) {
-						pq_release_remote(arp_globals.net_phone,
+						pq_release_remote(arp_globals.net_sess,
 						    packet_get_id(packet));
 					}
@@ -564,8 +565,8 @@
 		
 		/* Bind */
-		device->phone = nil_bind_service(device->service,
+		device->sess = nil_bind_service(device->service,
 		    (sysarg_t) device->device_id, SERVICE_ARP,
 		    arp_receiver);
-		if (device->phone < 0) {
+		if (device->sess == NULL) {
 			fibril_mutex_unlock(&arp_globals.lock);
 			arp_protos_destroy(&device->protos, free);
@@ -575,5 +576,5 @@
 		
 		/* Get packet dimensions */
-		rc = nil_packet_size_req(device->phone, device_id,
+		rc = nil_packet_size_req(device->sess, device_id,
 		    &device->packet_dimension);
 		if (rc != EOK) {
@@ -585,5 +586,5 @@
 		
 		/* Get hardware address */
-		rc = nil_get_addr_req(device->phone, device_id, &device->addr,
+		rc = nil_get_addr_req(device->sess, device_id, &device->addr,
 		    &device->addr_data);
 		if (rc != EOK) {
@@ -595,5 +596,5 @@
 		
 		/* Get broadcast address */
-		rc = nil_get_broadcast_addr_req(device->phone, device_id,
+		rc = nil_get_broadcast_addr_req(device->sess, device_id,
 		    &device->broadcast_addr, &device->broadcast_data);
 		if (rc != EOK) {
@@ -627,10 +628,10 @@
 }
 
-int il_initialize(int net_phone)
+int il_initialize(async_sess_t *net_sess)
 {
 	fibril_mutex_initialize(&arp_globals.lock);
 	
 	fibril_mutex_lock(&arp_globals.lock);
-	arp_globals.net_phone = net_phone;
+	arp_globals.net_sess = net_sess;
 	int rc = arp_cache_initialize(&arp_globals.cache);
 	fibril_mutex_unlock(&arp_globals.lock);
@@ -647,5 +648,5 @@
 		return ELIMIT;
 	
-	packet_t *packet = packet_get_4_remote(arp_globals.net_phone,
+	packet_t *packet = packet_get_4_remote(arp_globals.net_sess,
 	    device->packet_dimension.addr_len, device->packet_dimension.prefix,
 	    length, device->packet_dimension.suffix);
@@ -655,5 +656,5 @@
 	arp_header_t *header = (arp_header_t *) packet_suffix(packet, length);
 	if (!header) {
-		pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(arp_globals.net_sess, packet_get_id(packet));
 		return ENOMEM;
 	}
@@ -680,9 +681,9 @@
 	    (uint8_t *) device->broadcast_addr->value, device->addr->length);
 	if (rc != EOK) {
-		pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(arp_globals.net_sess, packet_get_id(packet));
 		return rc;
 	}
 	
-	nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
+	nil_send_msg(device->sess, device_id, packet, SERVICE_ARP);
 	return EOK;
 }
@@ -890,5 +891,5 @@
 	
 	case NET_ARP_CLEAR_DEVICE:
-		return arp_clear_device_req(0, IPC_GET_DEVICE(*call));
+		return arp_clear_device_req(IPC_GET_DEVICE(*call));
 	
 	case NET_ARP_CLEAR_ADDRESS:
@@ -897,5 +898,5 @@
 			return rc;
 		
-		arp_clear_address_req(0, IPC_GET_DEVICE(*call),
+		arp_clear_address_req(IPC_GET_DEVICE(*call),
 		    IPC_GET_SERVICE(*call), address);
 		free(address);
@@ -904,5 +905,5 @@
 	
 	case NET_ARP_CLEAN_CACHE:
-		return arp_clean_cache_req(0);
+		return arp_clean_cache_req();
 	}
 	
Index: uspace/srv/net/il/arp/arp.h
===================================================================
--- uspace/srv/net/il/arp/arp.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/il/arp/arp.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,4 +38,5 @@
 #define NET_ARP_H_
 
+#include <async.h>
 #include <fibril_synch.h>
 #include <ipc/services.h>
@@ -104,6 +105,6 @@
 	/** Packet dimension. */
 	packet_dimension_t packet_dimension;
-	/** Device module phone. */
-	int phone;
+	/** Device module session. */
+	async_sess_t *sess;
 	
 	/**
@@ -122,6 +123,7 @@
 	arp_cache_t cache;
 	
-	/** Networking module phone. */
-	int net_phone;
+	/** Networking module session. */
+	async_sess_t *net_sess;
+	
 	/** Safety lock. */
 	fibril_mutex_t lock;
Index: uspace/srv/net/il/ip/ip.c
===================================================================
--- uspace/srv/net/il/ip/ip.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/il/ip/ip.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -77,7 +77,4 @@
 #include <il_skel.h>
 
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
-
 /** IP module name. */
 #define NAME			"ip"
@@ -125,33 +122,34 @@
 static void ip_receiver(ipc_callid_t, ipc_call_t *, void *);
 
-/** Releases the packet and returns the result.
- *
- * @param[in] packet	The packet queue to be released.
- * @param[in] result	The result to be returned.
- * @return		The result parameter.
+/** Release the packet and returns the result.
+ *
+ * @param[in] packet Packet queue to be released.
+ * @param[in] result Result to be returned.
+ *
+ * @return Result parameter.
+ *
  */
 static int ip_release_and_return(packet_t *packet, int result)
 {
-	pq_release_remote(ip_globals.net_phone, packet_get_id(packet));
+	pq_release_remote(ip_globals.net_sess, packet_get_id(packet));
 	return result;
 }
 
-/** Returns the ICMP phone.
- *
- * Searches the registered protocols.
- *
- * @return		The found ICMP phone.
- * @return		ENOENT if the ICMP is not registered.
- */
-static int ip_get_icmp_phone(void)
-{
-	ip_proto_t *proto;
-	int phone;
-
+/** Return the ICMP session.
+ *
+ * Search the registered protocols.
+ *
+ * @return Found ICMP session.
+ * @return NULL if the ICMP is not registered.
+ *
+ */
+static async_sess_t *ip_get_icmp_session(void)
+{
 	fibril_rwlock_read_lock(&ip_globals.protos_lock);
-	proto = ip_protos_find(&ip_globals.protos, IPPROTO_ICMP);
-	phone = proto ? proto->phone : ENOENT;
+	ip_proto_t *proto = ip_protos_find(&ip_globals.protos, IPPROTO_ICMP);
+	async_sess_t *sess = proto ? proto->sess : NULL;
 	fibril_rwlock_read_unlock(&ip_globals.protos_lock);
-	return phone;
+	
+	return sess;
 }
 
@@ -182,5 +180,5 @@
 	next = pq_detach(packet);
 	if (next)
-		pq_release_remote(ip_globals.net_phone, packet_get_id(next));
+		pq_release_remote(ip_globals.net_sess, packet_get_id(next));
 
 	if (!header) {
@@ -221,30 +219,33 @@
 }
 
-/** Prepares the ICMP notification packet.
- *
- * Releases additional packets and keeps only the first one.
+/** Prepare the ICMP notification packet.
+ *
+ * Release additional packets and keep only the first one.
  * All packets are released on error.
  *
- * @param[in] error	The packet error service.
- * @param[in] packet	The packet or the packet queue to be reported as faulty.
- * @param[in] header	The first packet IP header. May be NULL.
- * @return		The found ICMP phone.
- * @return		EINVAL if the error parameter is set.
- * @return		EINVAL if the ICMP phone is not found.
- * @return		EINVAL if the ip_prepare_icmp() fails.
- */
-static int
-ip_prepare_icmp_and_get_phone(services_t error, packet_t *packet,
-    ip_header_t *header)
-{
-	int phone;
-
-	phone = ip_get_icmp_phone();
-	if (error || (phone < 0) || ip_prepare_icmp(packet, header))
-		return ip_release_and_return(packet, EINVAL);
-	return phone;
-}
-
-int il_initialize(int net_phone)
+ * @param[in] error  Packet error service.
+ * @param[in] packet Packet or the packet queue to be reported as faulty.
+ * @param[in] header First packet IP header. May be NULL.
+ *
+ * @return Found ICMP session.
+ * @return NULL if the error parameter is set.
+ * @return NULL if the ICMP session is not found.
+ * @return NULL if the ip_prepare_icmp() fails.
+ *
+ */
+static async_sess_t *ip_prepare_icmp_and_get_session(services_t error,
+    packet_t *packet, ip_header_t *header)
+{
+	async_sess_t *sess = ip_get_icmp_session();
+	
+	if ((error) || (!sess) || (ip_prepare_icmp(packet, header))) {
+		pq_release_remote(ip_globals.net_sess, packet_get_id(packet));
+		return NULL;
+	}
+	
+	return sess;
+}
+
+int il_initialize(async_sess_t *net_sess)
 {
 	fibril_rwlock_initialize(&ip_globals.lock);
@@ -253,5 +254,5 @@
 	fibril_rwlock_initialize(&ip_globals.netifs_lock);
 	
-	ip_globals.net_phone = net_phone;
+	ip_globals.net_sess = net_sess;
 	ip_globals.packet_counter = 0;
 	ip_globals.gateway.address.s_addr = 0;
@@ -355,5 +356,5 @@
 
 	/* Get configuration */
-	rc = net_get_device_conf_req(ip_globals.net_phone, ip_netif->device_id,
+	rc = net_get_device_conf_req(ip_globals.net_sess, ip_netif->device_id,
 	    &configuration, count, &data);
 	if (rc != EOK)
@@ -423,11 +424,11 @@
 
 	/* Bind netif service which also initializes the device */
-	ip_netif->phone = nil_bind_service(ip_netif->service,
+	ip_netif->sess = nil_bind_service(ip_netif->service,
 	    (sysarg_t) ip_netif->device_id, SERVICE_IP,
 	    ip_receiver);
-	if (ip_netif->phone < 0) {
+	if (ip_netif->sess == NULL) {
 		printf("Failed to contact the nil service %d\n",
 		    ip_netif->service);
-		return ip_netif->phone;
+		return ENOENT;
 	}
 
@@ -438,5 +439,5 @@
 			address.length = sizeof(in_addr_t);
 			
-			rc = arp_device_req(ip_netif->arp->phone,
+			rc = arp_device_req(ip_netif->arp->sess,
 			    ip_netif->device_id, SERVICE_IP, ip_netif->service,
 			    &address);
@@ -449,5 +450,5 @@
 
 	/* Get packet dimensions */
-	rc = nil_packet_size_req(ip_netif->phone, ip_netif->device_id,
+	rc = nil_packet_size_req(ip_netif->sess, ip_netif->device_id,
 	    &ip_netif->packet_dimension);
 	if (rc != EOK)
@@ -481,6 +482,5 @@
 }
 
-static int ip_device_req_local(int il_phone, device_id_t device_id,
-    services_t netif)
+static int ip_device_req_local(device_id_t device_id, services_t netif)
 {
 	ip_netif_t *ip_netif;
@@ -516,6 +516,6 @@
 
 	/* Print the settings */
-	printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n",
-	    NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv,
+	printf("%s: Device registered (id: %d, ipv: %d, conf: %s)\n",
+	    NAME, ip_netif->device_id, ip_netif->ipv,
 	    ip_netif->dhcp ? "dhcp" : "static");
 	
@@ -932,5 +932,5 @@
 
 	/* Create the last fragment */
-	new_packet = packet_get_4_remote(ip_globals.net_phone, prefix, length,
+	new_packet = packet_get_4_remote(ip_globals.net_sess, prefix, length,
 	    suffix, ((addrlen > addr_len) ? addrlen : addr_len));
 	if (!new_packet)
@@ -969,5 +969,5 @@
 	/* Create middle fragments */
 	while (IP_TOTAL_LENGTH(header) > length) {
-		new_packet = packet_get_4_remote(ip_globals.net_phone, prefix,
+		new_packet = packet_get_4_remote(ip_globals.net_sess, prefix,
 		    length, suffix,
 		    ((addrlen >= addr_len) ? addrlen : addr_len));
@@ -994,21 +994,22 @@
 }
 
-/** Checks the packet queue lengths and fragments the packets if needed.
+/** Check the packet queue lengths and fragments the packets if needed.
  *
  * The ICMP_FRAG_NEEDED error notification may be sent if the packet needs to
  * be fragmented and the fragmentation is not allowed.
  *
- * @param[in,out] packet The packet or the packet queue to be checked.
- * @param[in] prefix	The minimum prefix size.
- * @param[in] content	The maximum content size.
- * @param[in] suffix	The minimum suffix size.
- * @param[in] addr_len	The minimum address length.
- * @param[in] error	The error module service.
- * @return		The packet or the packet queue of the allowed length.
- * @return		NULL if there are no packets left.
- */
-static packet_t *
-ip_split_packet(packet_t *packet, size_t prefix, size_t content, size_t suffix,
-    socklen_t addr_len, services_t error)
+ * @param[in,out] packet   Packet or the packet queue to be checked.
+ * @param[in]     prefix   Minimum prefix size.
+ * @param[in]     content  Maximum content size.
+ * @param[in]     suffix   Minimum suffix size.
+ * @param[in]     addr_len Minimum address length.
+ * @param[in]     error    Error module service.
+ *
+ * @return The packet or the packet queue of the allowed length.
+ * @return NULL if there are no packets left.
+ *
+ */
+static packet_t *ip_split_packet(packet_t *packet, size_t prefix, size_t content,
+    size_t suffix, socklen_t addr_len, services_t error)
 {
 	size_t length;
@@ -1016,6 +1017,6 @@
 	packet_t *new_packet;
 	int result;
-	int phone;
-
+	async_sess_t *sess;
+	
 	next = packet;
 	/* Check all packets */
@@ -1039,13 +1040,12 @@
 			/* Fragmentation needed? */
 			if (result == EPERM) {
-				phone = ip_prepare_icmp_and_get_phone(
-				    error, next, NULL);
-				if (phone >= 0) {
+				sess = ip_prepare_icmp_and_get_session(error, next, NULL);
+				if (sess) {
 					/* Fragmentation necessary ICMP */
-					icmp_destination_unreachable_msg(phone,
+					icmp_destination_unreachable_msg(sess,
 					    ICMP_FRAG_NEEDED, content, next);
 				}
 			} else {
-				pq_release_remote(ip_globals.net_phone,
+				pq_release_remote(ip_globals.net_sess,
 				    packet_get_id(next));
 			}
@@ -1061,20 +1061,20 @@
 }
 
-/** Sends the packet or the packet queue via the specified route.
+/** Send the packet or the packet queue via the specified route.
  *
  * The ICMP_HOST_UNREACH error notification may be sent if route hardware
  * destination address is found.
  *
- * @param[in,out] packet The packet to be sent.
- * @param[in] netif	The target network interface.
- * @param[in] route	The target route.
- * @param[in] src	The source address.
- * @param[in] dest	The destination address.
- * @param[in] error	The error module service.
- * @return		EOK on success.
- * @return		Other error codes as defined for the arp_translate_req()
- *			function.
- * @return		Other error codes as defined for the ip_prepare_packet()
- *			function.
+ * @param[in,out] packet Packet to be sent.
+ * @param[in]     netif  Target network interface.
+ * @param[in]     route  Target route.
+ * @param[in]     src    Source address.
+ * @param[in]     dest   Destination address.
+ * @param[in]     error  Error module service.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for arp_translate_req().
+ * @return Other error codes as defined for ip_prepare_packet().
+ *
  */
 static int ip_send_route(packet_t *packet, ip_netif_t *netif,
@@ -1084,5 +1084,5 @@
 	measured_string_t *translation;
 	uint8_t *data;
-	int phone;
+	async_sess_t *sess;
 	int rc;
 
@@ -1093,8 +1093,8 @@
 		destination.length = sizeof(dest.s_addr);
 
-		rc = arp_translate_req(netif->arp->phone, netif->device_id,
+		rc = arp_translate_req(netif->arp->sess, netif->device_id,
 		    SERVICE_IP, &destination, &translation, &data);
 		if (rc != EOK) {
-			pq_release_remote(ip_globals.net_phone,
+			pq_release_remote(ip_globals.net_sess,
 			    packet_get_id(packet));
 			return rc;
@@ -1106,9 +1106,9 @@
 				free(data);
 			}
-			phone = ip_prepare_icmp_and_get_phone(error, packet,
+			sess = ip_prepare_icmp_and_get_session(error, packet,
 			    NULL);
-			if (phone >= 0) {
+			if (sess) {
 				/* Unreachable ICMP if no routing */
-				icmp_destination_unreachable_msg(phone,
+				icmp_destination_unreachable_msg(sess,
 				    ICMP_HOST_UNREACH, 0, packet);
 			}
@@ -1122,5 +1122,5 @@
 	rc = ip_prepare_packet(src, dest, packet, translation);
 	if (rc != EOK) {
-		pq_release_remote(ip_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(ip_globals.net_sess, packet_get_id(packet));
 	} else {
 		packet = ip_split_packet(packet, netif->packet_dimension.prefix,
@@ -1129,5 +1129,5 @@
 		    netif->packet_dimension.addr_len, error);
 		if (packet) {
-			nil_send_msg(netif->phone, netif->device_id, packet,
+			nil_send_msg(netif->sess, netif->device_id, packet,
 			    SERVICE_IP);
 		}
@@ -1142,6 +1142,6 @@
 }
 
-static int ip_send_msg_local(int il_phone, device_id_t device_id,
-    packet_t *packet, services_t sender, services_t error)
+static int ip_send_msg_local(device_id_t device_id, packet_t *packet,
+    services_t sender, services_t error)
 {
 	int addrlen;
@@ -1152,5 +1152,5 @@
 	in_addr_t *dest;
 	in_addr_t *src;
-	int phone;
+	async_sess_t *sess;
 	int rc;
 
@@ -1197,8 +1197,8 @@
 	if (!netif || !route) {
 		fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
-		phone = ip_prepare_icmp_and_get_phone(error, packet, NULL);
-		if (phone >= 0) {
+		sess = ip_prepare_icmp_and_get_session(error, packet, NULL);
+		if (sess) {
 			/* Unreachable ICMP if no routing */
-			icmp_destination_unreachable_msg(phone,
+			icmp_destination_unreachable_msg(sess,
 			    ICMP_NET_UNREACH, 0, packet);
 		}
@@ -1228,9 +1228,9 @@
 		if (!netif || !route) {
 			fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
-			phone = ip_prepare_icmp_and_get_phone(error, packet,
+			sess = ip_prepare_icmp_and_get_session(error, packet,
 			    NULL);
-			if (phone >= 0) {
+			if (sess) {
 				/* Unreachable ICMP if no routing */
-				icmp_destination_unreachable_msg(phone,
+				icmp_destination_unreachable_msg(sess,
 				    ICMP_HOST_UNREACH, 0, packet);
 			}
@@ -1316,5 +1316,5 @@
 {
 	ip_proto_t *proto;
-	int phone;
+	async_sess_t *sess;
 	services_t service;
 	tl_received_msg_t received_msg;
@@ -1369,8 +1369,8 @@
 	if (!proto) {
 		fibril_rwlock_read_unlock(&ip_globals.protos_lock);
-		phone = ip_prepare_icmp_and_get_phone(error, packet, header);
-		if (phone >= 0) {
+		sess = ip_prepare_icmp_and_get_session(error, packet, header);
+		if (sess) {
 			/* Unreachable ICMP */
-			icmp_destination_unreachable_msg(phone,
+			icmp_destination_unreachable_msg(sess,
 			    ICMP_PROT_UNREACH, 0, packet);
 		}
@@ -1384,5 +1384,5 @@
 		rc = received_msg(device_id, packet, service, error);
 	} else {
-		rc = tl_received_msg(proto->phone, device_id, packet,
+		rc = tl_received_msg(proto->sess, device_id, packet,
 		    proto->service, error);
 		fibril_rwlock_read_unlock(&ip_globals.protos_lock);
@@ -1418,5 +1418,5 @@
 	in_addr_t dest;
 	ip_route_t *route;
-	int phone;
+	async_sess_t *sess;
 	struct sockaddr *addr;
 	struct sockaddr_in addr_in;
@@ -1431,8 +1431,8 @@
 	if ((header->header_checksum) &&
 	    (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)) {
-		phone = ip_prepare_icmp_and_get_phone(0, packet, header);
-		if (phone >= 0) {
+		sess = ip_prepare_icmp_and_get_session(0, packet, header);
+		if (sess) {
 			/* Checksum error ICMP */
-			icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER,
+			icmp_parameter_problem_msg(sess, ICMP_PARAM_POINTER,
 			    ((size_t) ((void *) &header->header_checksum)) -
 			    ((size_t) ((void *) header)), packet);
@@ -1442,8 +1442,8 @@
 
 	if (header->ttl <= 1) {
-		phone = ip_prepare_icmp_and_get_phone(0, packet, header);
-		if (phone >= 0) {
+		sess = ip_prepare_icmp_and_get_session(0, packet, header);
+		if (sess) {
 			/* TTL exceeded ICMP */
-			icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet);
+			icmp_time_exceeded_msg(sess, ICMP_EXC_TTL, packet);
 		}
 		return EINVAL;
@@ -1473,8 +1473,8 @@
 	route = ip_find_route(dest);
 	if (!route) {
-		phone = ip_prepare_icmp_and_get_phone(0, packet, header);
-		if (phone >= 0) {
+		sess = ip_prepare_icmp_and_get_session(0, packet, header);
+		if (sess) {
 			/* Unreachable ICMP */
-			icmp_destination_unreachable_msg(phone,
+			icmp_destination_unreachable_msg(sess,
 			    ICMP_HOST_UNREACH, 0, packet);
 		}
@@ -1493,8 +1493,8 @@
 	}
 
-	phone = ip_prepare_icmp_and_get_phone(0, packet, header);
-	if (phone >= 0) {
+	sess = ip_prepare_icmp_and_get_session(0, packet, header);
+	if (sess) {
 		/* Unreachable ICMP if no routing */
-		icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0,
+		icmp_destination_unreachable_msg(sess, ICMP_HOST_UNREACH, 0,
 		    packet);
 	}
@@ -1503,14 +1503,14 @@
 }
 
-/** Returns the device packet dimensions for sending.
- *
- * @param[in] phone	The service module phone.
- * @param[in] message	The service specific message.
- * @param[in] device_id	The device identifier.
- * @param[out] addr_len	The minimum reserved address length.
- * @param[out] prefix	The minimum reserved prefix size.
- * @param[out] content	The maximum content size.
- * @param[out] suffix	The minimum reserved suffix size.
- * @return		EOK on success.
+/** Return the device packet dimensions for sending.
+ *
+ * @param[in]  device_id Device identifier.
+ * @param[out] addr_len  Minimum reserved address length.
+ * @param[out] prefix    Minimum reserved prefix size.
+ * @param[out] content   Maximum content size.
+ * @param[out] suffix    Minimum reserved suffix size.
+ *
+ * @return EOK on success.
+ *
  */
 static int ip_packet_size_message(device_id_t device_id, size_t *addr_len,
@@ -1595,4 +1595,5 @@
  * @param[in,out] icall Message parameters.
  * @param[in]     arg   Local argument.
+ *
  */
 static void ip_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
@@ -1610,5 +1611,5 @@
 		
 		case NET_IL_RECEIVED:
-			rc = packet_translate_remote(ip_globals.net_phone, &packet,
+			rc = packet_translate_remote(ip_globals.net_sess, &packet,
 			    IPC_GET_PACKET(*icall));
 			if (rc == EOK) {
@@ -1637,22 +1638,23 @@
 }
 
-/** Registers the transport layer protocol.
+/** Register the transport layer protocol.
  *
  * The traffic of this protocol will be supplied using either the receive
  * function or IPC message.
  *
- * @param[in] protocol	The transport layer module protocol.
- * @param[in] service	The transport layer module service.
- * @param[in] phone	The transport layer module phone.
- * @param[in] received_msg The receiving function.
- * @return		EOK on success.
- * @return		EINVAL if the protocol parameter and/or the service
- *			parameter is zero.
- * @return		EINVAL if the phone parameter is not a positive number
- *			and the tl_receive_msg is NULL.
- * @return		ENOMEM if there is not enough memory left.
- */
-static int
-ip_register(int protocol, services_t service, int phone,
+ * @param[in] protocol     Transport layer module protocol.
+ * @param[in] service      Transport layer module service.
+ * @param[in] sess         Transport layer module session.
+ * @param[in] received_msg Receiving function.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the protocol parameter and/or the service
+ *         parameter is zero.
+ * @return EINVAL if the phone parameter is not a positive number
+ *         and the tl_receive_msg is NULL.
+ * @return ENOMEM if there is not enough memory left.
+ *
+ */
+static int ip_register(int protocol, services_t service, async_sess_t *sess,
     tl_received_msg_t received_msg)
 {
@@ -1660,7 +1662,7 @@
 	int index;
 
-	if (!protocol || !service || ((phone < 0) && !received_msg))
+	if ((!protocol) || (!service) || ((!sess) && (!received_msg)))
 		return EINVAL;
-
+	
 	proto = (ip_proto_t *) malloc(sizeof(ip_protos_t));
 	if (!proto)
@@ -1669,5 +1671,5 @@
 	proto->protocol = protocol;
 	proto->service = service;
-	proto->phone = phone;
+	proto->sess = sess;
 	proto->received_msg = received_msg;
 
@@ -1681,13 +1683,11 @@
 	fibril_rwlock_write_unlock(&ip_globals.protos_lock);
 
-	printf("%s: Protocol registered (protocol: %d, phone: %d)\n",
-	    NAME, proto->protocol, proto->phone);
+	printf("%s: Protocol registered (protocol: %d)\n",
+	    NAME, proto->protocol);
 
 	return EOK;
 }
 
-
-static int
-ip_add_route_req_local(int ip_phone, device_id_t device_id, in_addr_t address,
+static int ip_add_route_req_local(device_id_t device_id, in_addr_t address,
     in_addr_t netmask, in_addr_t gateway)
 {
@@ -1723,6 +1723,5 @@
 }
 
-static int
-ip_set_gateway_req_local(int ip_phone, device_id_t device_id, in_addr_t gateway)
+static int ip_set_gateway_req_local(device_id_t device_id, in_addr_t gateway)
 {
 	ip_netif_t *netif;
@@ -1748,16 +1747,15 @@
 /** Notify the IP module about the received error notification packet.
  *
- * @param[in] ip_phone	The IP module phone used for (semi)remote calls.
- * @param[in] device_id	The device identifier.
- * @param[in] packet	The received packet or the received packet queue.
- * @param[in] target	The target internetwork module service to be
- *			delivered to.
- * @param[in] error	The packet error reporting service. Prefixes the
- *			received packet.
- * @return		EOK on success.
- *
- */
-static int
-ip_received_error_msg_local(int ip_phone, device_id_t device_id,
+ * @param[in] device_id Device identifier.
+ * @param[in] packet    Received packet or the received packet queue.
+ * @param[in] target    Target internetwork module service to be
+ *                      delivered to.
+ * @param[in] error     Packet error reporting service. Prefixes the
+ *                      received packet.
+ *
+ * @return EOK on success.
+ *
+ */
+static int ip_received_error_msg_local(device_id_t device_id,
     packet_t *packet, services_t target, services_t error)
 {
@@ -1804,5 +1802,5 @@
 			address.value = (uint8_t *) &header->destination_address;
 			address.length = sizeof(header->destination_address);
-			arp_clear_address_req(netif->arp->phone,
+			arp_clear_address_req(netif->arp->sess,
 			    netif->device_id, SERVICE_IP, &address);
 		}
@@ -1818,6 +1816,5 @@
 }
 
-static int
-ip_get_route_req_local(int ip_phone, ip_protocol_t protocol,
+static int ip_get_route_req_local(ip_protocol_t protocol,
     const struct sockaddr *destination, socklen_t addrlen,
     device_id_t *device_id, void **header, size_t *headerlen)
@@ -1920,28 +1917,30 @@
 		return EOK;
 	
+	async_sess_t *callback =
+	    async_callback_receive_start(EXCHANGE_SERIALIZE, call);
+	if (callback)
+		return ip_register(IL_GET_PROTO(*call), IL_GET_SERVICE(*call),
+		    callback, NULL);
+	
 	switch (IPC_GET_IMETHOD(*call)) {
-	case IPC_M_CONNECT_TO_ME:
-		return ip_register(IL_GET_PROTO(*call), IL_GET_SERVICE(*call),
-		    IPC_GET_PHONE(*call), NULL);
-	
 	case NET_IP_DEVICE:
-		return ip_device_req_local(0, IPC_GET_DEVICE(*call),
+		return ip_device_req_local(IPC_GET_DEVICE(*call),
 		    IPC_GET_SERVICE(*call));
 	
 	case NET_IP_RECEIVED_ERROR:
-		rc = packet_translate_remote(ip_globals.net_phone, &packet,
+		rc = packet_translate_remote(ip_globals.net_sess, &packet,
 		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
-		return ip_received_error_msg_local(0, IPC_GET_DEVICE(*call),
+		return ip_received_error_msg_local(IPC_GET_DEVICE(*call),
 		    packet, IPC_GET_TARGET(*call), IPC_GET_ERROR(*call));
 	
 	case NET_IP_ADD_ROUTE:
-		return ip_add_route_req_local(0, IPC_GET_DEVICE(*call),
+		return ip_add_route_req_local(IPC_GET_DEVICE(*call),
 		    IP_GET_ADDRESS(*call), IP_GET_NETMASK(*call),
 		    IP_GET_GATEWAY(*call));
 
 	case NET_IP_SET_GATEWAY:
-		return ip_set_gateway_req_local(0, IPC_GET_DEVICE(*call),
+		return ip_set_gateway_req_local(IPC_GET_DEVICE(*call),
 		    IP_GET_GATEWAY(*call));
 
@@ -1952,5 +1951,5 @@
 			return rc;
 		
-		rc = ip_get_route_req_local(0, IP_GET_PROTOCOL(*call), addr,
+		rc = ip_get_route_req_local(IP_GET_PROTOCOL(*call), addr,
 		    (socklen_t) addrlen, &device_id, &header, &headerlen);
 		if (rc != EOK)
@@ -1983,10 +1982,10 @@
 	
 	case NET_IP_SEND:
-		rc = packet_translate_remote(ip_globals.net_phone, &packet,
+		rc = packet_translate_remote(ip_globals.net_sess, &packet,
 		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
 		
-		return ip_send_msg_local(0, IPC_GET_DEVICE(*call), packet, 0,
+		return ip_send_msg_local(IPC_GET_DEVICE(*call), packet, 0,
 		    IPC_GET_ERROR(*call));
 	}
Index: uspace/srv/net/il/ip/ip.h
===================================================================
--- uspace/srv/net/il/ip/ip.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/il/ip/ip.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,4 +38,5 @@
 #define NET_IP_H_
 
+#include <async.h>
 #include <fibril_synch.h>
 #include <ipc/services.h>
@@ -98,6 +99,6 @@
 	/** Packet dimension. */
 	packet_dimension_t packet_dimension;
-	/** Netif module phone. */
-	int phone;
+	/** Netif module session. */
+	async_sess_t *sess;
 	/** Routing table. */
 	ip_routes_t routes;
@@ -112,6 +113,6 @@
 /** IP protocol specific data. */
 struct ip_proto {
-	/** Protocol module phone. */
-	int phone;
+	/** Protocol module session. */
+	async_sess_t *sess;
 	/** Protocol number. */
 	int protocol;
@@ -142,6 +143,6 @@
 	/** Known support modules. */
 	modules_t modules;
-	/** Networking module phone. */
-	int net_phone;
+	/** Networking module session. */
+	async_sess_t *net_sess;
 	/** Registered network interfaces. */
 	ip_netifs_t netifs;
Index: uspace/srv/net/net/net.c
===================================================================
--- uspace/srv/net/net/net.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/net/net.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -36,10 +36,7 @@
  */
 
-#include "net.h"
-
 #include <async.h>
 #include <ctype.h>
 #include <ddi.h>
-#include <ns.h>
 #include <errno.h>
 #include <malloc.h>
@@ -47,5 +44,5 @@
 #include <str.h>
 #include <str_error.h>
-
+#include <ns.h>
 #include <ipc/services.h>
 #include <ipc/net.h>
@@ -53,18 +50,16 @@
 #include <ipc/il.h>
 #include <ipc/nil.h>
-
 #include <net/modules.h>
 #include <net/packet.h>
 #include <net/device.h>
-
 #include <adt/char_map.h>
 #include <adt/generic_char_map.h>
 #include <adt/measured_strings.h>
 #include <adt/module_map.h>
-
 #include <netif_remote.h>
 #include <nil_remote.h>
 #include <net_interface.h>
 #include <ip_interface.h>
+#include "net.h"
 
 /** Networking module name. */
@@ -394,5 +389,5 @@
 }
 
-int net_get_conf_req(int net_phone, measured_string_t **configuration,
+static int net_get_conf_req_local(measured_string_t **configuration,
     size_t count, uint8_t **data)
 {
@@ -403,5 +398,5 @@
 }
 
-int net_get_device_conf_req(int net_phone, device_id_t device_id,
+static int net_get_device_conf_req_local(device_id_t device_id,
     measured_string_t **configuration, size_t count, uint8_t **data)
 {
@@ -479,5 +474,5 @@
 	uintptr_t io = setting ? strtol((char *) setting->value, NULL, 16) : 0;
 	
-	rc = netif_probe_req(netif->driver->phone, netif->id, irq, (void *) io);
+	rc = netif_probe_req(netif->driver->sess, netif->id, irq, (void *) io);
 	if (rc != EOK)
 		return rc;
@@ -492,6 +487,5 @@
 		
 		int mtu = setting ? strtol((char *) setting->value, NULL, 10) : 0;
-		
-		rc = nil_device_req(netif->nil->phone, netif->id, mtu,
+		rc = nil_device_req(netif->nil->sess, netif->id, mtu,
 		    netif->driver->service);
 		if (rc != EOK)
@@ -503,16 +497,9 @@
 	
 	/* Inter-network layer startup */
-	switch (netif->il->service) {
-	case SERVICE_IP:
-		rc = ip_device_req(netif->il->phone, netif->id,
-		    internet_service);
-		if (rc != EOK)
-			return rc;
-		break;
-	default:
-		return ENOENT;
-	}
-	
-	return netif_start_req(netif->driver->phone, netif->id);
+	rc = ip_device_req(netif->il->sess, netif->id, internet_service);
+	if (rc != EOK)
+		return rc;
+	
+	return netif_start_req(netif->driver->sess, netif->id);
 }
 
@@ -649,5 +636,5 @@
 		if (rc != EOK)
 			return rc;
-		net_get_device_conf_req(0, IPC_GET_DEVICE(*call), &strings,
+		net_get_device_conf_req_local(IPC_GET_DEVICE(*call), &strings,
 		    IPC_GET_COUNT(*call), NULL);
 		
@@ -663,5 +650,5 @@
 		if (rc != EOK)
 			return rc;
-		net_get_conf_req(0, &strings, IPC_GET_COUNT(*call), NULL);
+		net_get_conf_req_local(&strings, IPC_GET_COUNT(*call), NULL);
 		
 		/* Strings should not contain received data anymore */
@@ -683,4 +670,5 @@
  * @param[in] icall The initial message call structure.
  * @param[in] arg   Local argument.
+ *
  */
 static void net_client_connection(ipc_callid_t iid, ipc_call_t *icall,
Index: uspace/srv/net/netif/lo/lo.c
===================================================================
--- uspace/srv/net/netif/lo/lo.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/netif/lo/lo.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -148,5 +148,4 @@
 	null_device_stats((device_stats_t *) (*device)->specific);
 	(*device)->device_id = device_id;
-	(*device)->nil_phone = -1;
 	(*device)->state = NETIF_STOPPED;
 	int index = netif_device_map_add(&netif_globals.device_map,
@@ -202,8 +201,8 @@
 	} while (next);
 	
-	int phone = device->nil_phone;
+	async_sess_t *nil_sess = netif_globals.nil_sess;
 	fibril_rwlock_write_unlock(&netif_globals.lock);
 	
-	nil_received_msg(phone, device_id, packet, sender);
+	nil_received_msg(nil_sess, device_id, packet, sender);
 	
 	fibril_rwlock_write_lock(&netif_globals.lock);
Index: uspace/srv/net/nil/eth/eth.c
===================================================================
--- uspace/srv/net/nil/eth/eth.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/nil/eth/eth.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -59,8 +59,4 @@
 #include <packet_remote.h>
 #include <nil_skel.h>
-
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
-
 #include "eth.h"
 
@@ -171,5 +167,5 @@
 INT_MAP_IMPLEMENT(eth_protos, eth_proto_t);
 
-int nil_device_state_msg_local(int nil_phone, device_id_t device_id, int state)
+int nil_device_state_msg_local(device_id_t device_id, sysarg_t state)
 {
 	int index;
@@ -180,6 +176,6 @@
 	    index--) {
 		proto = eth_protos_get_index(&eth_globals.protos, index);
-		if (proto && proto->phone) {
-			il_device_state_msg(proto->phone, device_id, state,
+		if ((proto) && (proto->sess)) {
+			il_device_state_msg(proto->sess, device_id, state,
 			    proto->service);
 		}
@@ -190,5 +186,5 @@
 }
 
-int nil_initialize(int net_phone)
+int nil_initialize(async_sess_t *sess)
 {
 	int rc;
@@ -199,5 +195,5 @@
 	fibril_rwlock_write_lock(&eth_globals.devices_lock);
 	fibril_rwlock_write_lock(&eth_globals.protos_lock);
-	eth_globals.net_phone = net_phone;
+	eth_globals.net_sess = sess;
 
 	eth_globals.broadcast_addr =
@@ -226,10 +222,11 @@
 }
 
-/** Processes IPC messages from the registered device driver modules in an
+/** Process IPC messages from the registered device driver modules in an
  * infinite loop.
  *
- * @param[in] iid	The message identifier.
- * @param[in,out] icall	The message parameters.
- * @param[in] arg	Local argument.
+ * @param[in]     iid   Message identifier.
+ * @param[in,out] icall Message parameters.
+ * @param[in]     arg   Local argument.
+ *
  */
 static void eth_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
@@ -241,14 +238,14 @@
 		switch (IPC_GET_IMETHOD(*icall)) {
 		case NET_NIL_DEVICE_STATE:
-			nil_device_state_msg_local(0, IPC_GET_DEVICE(*icall),
+			nil_device_state_msg_local(IPC_GET_DEVICE(*icall),
 			    IPC_GET_STATE(*icall));
 			async_answer_0(iid, EOK);
 			break;
 		case NET_NIL_RECEIVED:
-			rc = packet_translate_remote(eth_globals.net_phone,
+			rc = packet_translate_remote(eth_globals.net_sess,
 			    &packet, IPC_GET_PACKET(*icall));
 			if (rc == EOK)
-				rc = nil_received_msg_local(0,
-				    IPC_GET_DEVICE(*icall), packet, 0);
+				rc = nil_received_msg_local(IPC_GET_DEVICE(*icall),
+				    packet, 0);
 			
 			async_answer_0(iid, (sysarg_t) rc);
@@ -326,6 +323,6 @@
 			proto = eth_protos_get_index(&eth_globals.protos,
 			    index);
-			if (proto->phone) {
-				il_mtu_changed_msg(proto->phone,
+			if (proto->sess) {
+				il_mtu_changed_msg(proto->sess,
 				    device->device_id, device->mtu,
 				    proto->service);
@@ -351,5 +348,5 @@
 
 	configuration = &names[0];
-	rc = net_get_device_conf_req(eth_globals.net_phone, device->device_id,
+	rc = net_get_device_conf_req(eth_globals.net_sess, device->device_id,
 	    &configuration, count, &data);
 	if (rc != EOK) {
@@ -380,14 +377,14 @@
 	
 	/* Bind the device driver */
-	device->phone = netif_bind_service(device->service, device->device_id,
+	device->sess = netif_bind_service(device->service, device->device_id,
 	    SERVICE_ETHERNET, eth_receiver);
-	if (device->phone < 0) {
+	if (device->sess == NULL) {
 		fibril_rwlock_write_unlock(&eth_globals.devices_lock);
 		free(device);
-		return device->phone;
+		return ENOENT;
 	}
 	
 	/* Get hardware address */
-	rc = netif_get_addr_req(device->phone, device->device_id, &device->addr,
+	rc = netif_get_addr_req(device->sess, device->device_id, &device->addr,
 	    &device->addr_data);
 	if (rc != EOK) {
@@ -509,6 +506,6 @@
 }
 
-int nil_received_msg_local(int nil_phone, device_id_t device_id,
-    packet_t *packet, services_t target)
+int nil_received_msg_local(device_id_t device_id, packet_t *packet,
+    services_t target)
 {
 	eth_proto_t *proto;
@@ -532,9 +529,9 @@
 		proto = eth_process_packet(flags, packet);
 		if (proto) {
-			il_received_msg(proto->phone, device_id, packet,
+			il_received_msg(proto->sess, device_id, packet,
 			    proto->service);
 		} else {
 			/* Drop invalid/unknown */
-			pq_release_remote(eth_globals.net_phone,
+			pq_release_remote(eth_globals.net_sess,
 			    packet_get_id(packet));
 		}
@@ -615,15 +612,17 @@
 }
 
-/** Registers receiving module service.
- *
- * Passes received packets for this service.
- *
- * @param[in] service	The module service.
- * @param[in] phone	The service phone.
- * @return		EOK on success.
- * @return		ENOENT if the service is not known.
- * @return		ENOMEM if there is not enough memory left.
- */
-static int eth_register_message(services_t service, int phone)
+/** Register receiving module service.
+ *
+ * Pass received packets for this service.
+ *
+ * @param[in] service Module service.
+ * @param[in] sess    Service session.
+ *
+ * @return EOK on success.
+ * @return ENOENT if the service is not known.
+ * @return ENOMEM if there is not enough memory left.
+ *
+ */
+static int eth_register_message(services_t service, async_sess_t *sess)
 {
 	eth_proto_t *proto;
@@ -638,5 +637,5 @@
 	proto = eth_protos_find(&eth_globals.protos, protocol);
 	if (proto) {
-		proto->phone = phone;
+		proto->sess = sess;
 		fibril_rwlock_write_unlock(&eth_globals.protos_lock);
 		return EOK;
@@ -650,5 +649,5 @@
 		proto->service = service;
 		proto->protocol = protocol;
-		proto->phone = phone;
+		proto->sess = sess;
 
 		index = eth_protos_add(&eth_globals.protos, protocol, proto);
@@ -660,6 +659,6 @@
 	}
 	
-	printf("%s: Protocol registered (protocol: %d, service: %d, phone: "
-	    "%d)\n", NAME, proto->protocol, proto->service, proto->phone);
+	printf("%s: Protocol registered (protocol: %d, service: %d)\n",
+	    NAME, proto->protocol, proto->service);
 	
 	fibril_rwlock_write_unlock(&eth_globals.protos_lock);
@@ -799,5 +798,5 @@
 	ethertype = htons(protocol_map(SERVICE_ETHERNET, sender));
 	if (!ethertype) {
-		pq_release_remote(eth_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(eth_globals.net_sess, packet_get_id(packet));
 		return EINVAL;
 	}
@@ -820,5 +819,5 @@
 			if (next == packet)
 				packet = tmp;
-			pq_release_remote(eth_globals.net_phone,
+			pq_release_remote(eth_globals.net_sess,
 			    packet_get_id(next));
 			next = tmp;
@@ -830,5 +829,5 @@
 	/* Send packet queue */
 	if (packet) {
-		netif_send_msg(device->phone, device_id, packet,
+		netif_send_msg(device->sess, device_id, packet,
 		    SERVICE_ETHERNET);
 	}
@@ -854,4 +853,9 @@
 		return EOK;
 	
+	async_sess_t *callback =
+	    async_callback_receive_start(EXCHANGE_SERIALIZE, call);
+	if (callback)
+		return eth_register_message(NIL_GET_PROTO(*call), callback);
+	
 	switch (IPC_GET_IMETHOD(*call)) {
 	case NET_NIL_DEVICE:
@@ -859,5 +863,5 @@
 		    IPC_GET_SERVICE(*call), IPC_GET_MTU(*call));
 	case NET_NIL_SEND:
-		rc = packet_translate_remote(eth_globals.net_phone, &packet,
+		rc = packet_translate_remote(eth_globals.net_sess, &packet,
 		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
@@ -888,7 +892,4 @@
 			return EOK;
 		return measured_strings_reply(address, 1);
-	case IPC_M_CONNECT_TO_ME:
-		return eth_register_message(NIL_GET_PROTO(*call),
-		    IPC_GET_PHONE(*call));
 	}
 	
Index: uspace/srv/net/nil/eth/eth.h
===================================================================
--- uspace/srv/net/nil/eth/eth.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/nil/eth/eth.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,7 +38,7 @@
 #define NET_ETH_H_
 
+#include <async.h>
 #include <fibril_synch.h>
 #include <ipc/services.h>
-
 #include <net/device.h>
 #include <adt/measured_strings.h>
@@ -223,6 +223,6 @@
 	/** Device driver service. */
 	services_t service;
-	/** Driver phone. */
-	int phone;
+	/** Driver session. */
+	async_sess_t *sess;
 	/** Maximal transmission unit. */
 	size_t mtu;
@@ -248,12 +248,12 @@
 	/** Protocol identifier. */
 	int protocol;
-	/** Protocol module phone. */
-	int phone;
+	/** Protocol module session. */
+	async_sess_t *sess;
 };
 
 /** Ethernet global data. */
 struct eth_globals {
-	/** Networking module phone. */
-	int net_phone;
+	/** Networking module session. */
+	async_sess_t *net_sess;
 	/** Safety lock for devices. */
 	fibril_rwlock_t devices_lock;
@@ -265,5 +265,5 @@
 	/**
 	 * Protocol map.
-	 * Service phone map for each protocol.
+	 * Service map for each protocol.
 	 */
 	eth_protos_t protos;
Index: uspace/srv/net/nil/nildummy/nildummy.c
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/nil/nildummy/nildummy.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -44,5 +44,4 @@
 #include <ipc/net.h>
 #include <ipc/services.h>
-
 #include <net/modules.h>
 #include <net/device.h>
@@ -53,8 +52,4 @@
 #include <netif_remote.h>
 #include <nil_skel.h>
-
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
-
 #include "nildummy.h"
 
@@ -70,9 +65,9 @@
 DEVICE_MAP_IMPLEMENT(nildummy_devices, nildummy_device_t);
 
-int nil_device_state_msg_local(int nil_phone, device_id_t device_id, int state)
+int nil_device_state_msg_local(device_id_t device_id, sysarg_t state)
 {
 	fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
-	if (nildummy_globals.proto.phone)
-		il_device_state_msg(nildummy_globals.proto.phone, device_id,
+	if (nildummy_globals.proto.sess)
+		il_device_state_msg(nildummy_globals.proto.sess, device_id,
 		    state, nildummy_globals.proto.service);
 	fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
@@ -81,5 +76,5 @@
 }
 
-int nil_initialize(int net_phone)
+int nil_initialize(async_sess_t *sess)
 {
 	fibril_rwlock_initialize(&nildummy_globals.devices_lock);
@@ -88,6 +83,6 @@
 	fibril_rwlock_write_lock(&nildummy_globals.protos_lock);
 	
-	nildummy_globals.net_phone = net_phone;
-	nildummy_globals.proto.phone = 0;
+	nildummy_globals.net_sess = sess;
+	nildummy_globals.proto.sess = NULL;
 	int rc = nildummy_devices_initialize(&nildummy_globals.devices);
 	
@@ -102,5 +97,6 @@
  * @param[in]     iid   Message identifier.
  * @param[in,out] icall Message parameters.
- * @param[in]     arg   Local argument.
+ * @param[in]     arg    Local argument.
+ *
  */
 static void nildummy_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
@@ -112,15 +108,15 @@
 		switch (IPC_GET_IMETHOD(*icall)) {
 		case NET_NIL_DEVICE_STATE:
-			rc = nil_device_state_msg_local(0,
-			    IPC_GET_DEVICE(*icall), IPC_GET_STATE(*icall));
+			rc = nil_device_state_msg_local(IPC_GET_DEVICE(*icall),
+			    IPC_GET_STATE(*icall));
 			async_answer_0(iid, (sysarg_t) rc);
 			break;
 		
 		case NET_NIL_RECEIVED:
-			rc = packet_translate_remote(nildummy_globals.net_phone,
+			rc = packet_translate_remote(nildummy_globals.net_sess,
 			    &packet, IPC_GET_PACKET(*icall));
 			if (rc == EOK)
-				rc = nil_received_msg_local(0,
-				    IPC_GET_DEVICE(*icall), packet, 0);
+				rc = nil_received_msg_local(IPC_GET_DEVICE(*icall),
+				    packet, 0);
 			
 			async_answer_0(iid, (sysarg_t) rc);
@@ -180,6 +176,6 @@
 		/* Notify the upper layer module */
 		fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
-		if (nildummy_globals.proto.phone) {
-			il_mtu_changed_msg(nildummy_globals.proto.phone,
+		if (nildummy_globals.proto.sess) {
+			il_mtu_changed_msg(nildummy_globals.proto.sess,
 			    device->device_id, device->mtu,
 			    nildummy_globals.proto.service);
@@ -203,14 +199,14 @@
 
 	/* Bind the device driver */
-	device->phone = netif_bind_service(device->service, device->device_id,
+	device->sess = netif_bind_service(device->service, device->device_id,
 	    SERVICE_ETHERNET, nildummy_receiver);
-	if (device->phone < 0) {
+	if (device->sess == NULL) {
 		fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
 		free(device);
-		return device->phone;
+		return ENOENT;
 	}
 	
 	/* Get hardware address */
-	int rc = netif_get_addr_req(device->phone, device->device_id,
+	int rc = netif_get_addr_req(device->sess, device->device_id,
 	    &device->addr, &device->addr_data);
 	if (rc != EOK) {
@@ -307,13 +303,13 @@
 }
 
-int nil_received_msg_local(int nil_phone, device_id_t device_id,
-    packet_t *packet, services_t target)
+int nil_received_msg_local(device_id_t device_id, packet_t *packet,
+    services_t target)
 {
 	fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
 	
-	if (nildummy_globals.proto.phone) {
+	if (nildummy_globals.proto.sess) {
 		do {
 			packet_t *next = pq_detach(packet);
-			il_received_msg(nildummy_globals.proto.phone, device_id,
+			il_received_msg(nildummy_globals.proto.sess, device_id,
 			    packet, nildummy_globals.proto.service);
 			packet = next;
@@ -331,5 +327,5 @@
  *
  * @param[in] service Module service.
- * @param[in] phone   Service phone.
+ * @param[in] sess    Service session.
  *
  * @return EOK on success.
@@ -338,12 +334,12 @@
  *
  */
-static int nildummy_register_message(services_t service, int phone)
+static int nildummy_register_message(services_t service, async_sess_t *sess)
 {
 	fibril_rwlock_write_lock(&nildummy_globals.protos_lock);
 	nildummy_globals.proto.service = service;
-	nildummy_globals.proto.phone = phone;
-	
-	printf("%s: Protocol registered (service: %d, phone: %d)\n",
-	    NAME, nildummy_globals.proto.service, nildummy_globals.proto.phone);
+	nildummy_globals.proto.sess = sess;
+	
+	printf("%s: Protocol registered (service: %d)\n",
+	    NAME, nildummy_globals.proto.service);
 	
 	fibril_rwlock_write_unlock(&nildummy_globals.protos_lock);
@@ -376,5 +372,5 @@
 	/* Send packet queue */
 	if (packet)
-		netif_send_msg(device->phone, device_id, packet,
+		netif_send_msg(device->sess, device_id, packet,
 		    SERVICE_NILDUMMY);
 	
@@ -400,4 +396,9 @@
 		return EOK;
 	
+	async_sess_t *callback =
+	    async_callback_receive_start(EXCHANGE_SERIALIZE, call);
+	if (callback)
+		return nildummy_register_message(NIL_GET_PROTO(*call), callback);
+	
 	switch (IPC_GET_IMETHOD(*call)) {
 	case NET_NIL_DEVICE:
@@ -406,5 +407,5 @@
 	
 	case NET_NIL_SEND:
-		rc = packet_translate_remote(nildummy_globals.net_phone,
+		rc = packet_translate_remote(nildummy_globals.net_sess,
 		    &packet, IPC_GET_PACKET(*call));
 		if (rc != EOK)
@@ -436,8 +437,4 @@
 			return rc;
 		return measured_strings_reply(address, 1);
-	
-	case IPC_M_CONNECT_TO_ME:
-		return nildummy_register_message(NIL_GET_PROTO(*call),
-		    IPC_GET_PHONE(*call));
 	}
 	
Index: uspace/srv/net/nil/nildummy/nildummy.h
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/nil/nildummy/nildummy.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,7 +38,7 @@
 #define NET_NILDUMMY_H_
 
+#include <async.h>
 #include <fibril_synch.h>
 #include <ipc/services.h>
-
 #include <net/device.h>
 #include <adt/measured_strings.h>
@@ -81,6 +81,6 @@
 	services_t service;
 	
-	/** Driver phone. */
-	int phone;
+	/** Driver session. */
+	async_sess_t *sess;
 	
 	/** Maximal transmission unit. */
@@ -99,12 +99,12 @@
 	services_t service;
 	
-	/** Protocol module phone. */
-	int phone;
+	/** Protocol module session. */
+	async_sess_t *sess;
 };
 
 /** Dummy nil global data. */
 struct nildummy_globals {
-	/** Networking module phone. */
-	int net_phone;
+	/** Networking module session. */
+	async_sess_t *net_sess;
 	
 	/** Lock for devices. */
Index: uspace/srv/net/tl/icmp/icmp.c
===================================================================
--- uspace/srv/net/tl/icmp/icmp.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/tl/icmp/icmp.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -118,6 +118,6 @@
 
 /** Global data */
-static int phone_net = -1;
-static int phone_ip = -1;
+static async_sess_t *net_sess = NULL;
+static async_sess_t *ip_sess = NULL;
 static bool error_reporting = true;
 static bool echo_replying = true;
@@ -173,5 +173,5 @@
 static void icmp_release(packet_t *packet)
 {
-	pq_release_remote(phone_net, packet_get_id(packet));
+	pq_release_remote(net_sess, packet_get_id(packet));
 }
 
@@ -225,5 +225,5 @@
 	}
 	
-	return ip_send_msg(phone_ip, -1, packet, SERVICE_ICMP, error);
+	return ip_send_msg(ip_sess, -1, packet, SERVICE_ICMP, error);
 }
 
@@ -297,5 +297,5 @@
 	size_t length = (size_t) addrlen;
 	
-	packet_t *packet = packet_get_4_remote(phone_net, size,
+	packet_t *packet = packet_get_4_remote(net_sess, size,
 	    icmp_dimension.addr_len, ICMP_HEADER_SIZE + icmp_dimension.prefix,
 	    icmp_dimension.suffix);
@@ -595,5 +595,5 @@
 	case ICMP_SKIP:
 	case ICMP_PHOTURIS:
-		ip_received_error_msg(phone_ip, -1, packet,
+		ip_received_error_msg(ip_sess, -1, packet,
 		    SERVICE_IP, SERVICE_ICMP);
 		return EOK;
@@ -609,4 +609,5 @@
  * @param[in,out] icall Message parameters.
  * @param[in]     arg   Local argument.
+ *
  */
 static void icmp_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
@@ -621,5 +622,5 @@
 		switch (IPC_GET_IMETHOD(*icall)) {
 		case NET_TL_RECEIVED:
-			rc = packet_translate_remote(phone_net, &packet,
+			rc = packet_translate_remote(net_sess, &packet,
 			    IPC_GET_PACKET(*icall));
 			if (rc == EOK) {
@@ -641,5 +642,5 @@
 /** Initialize the ICMP module.
  *
- * @param[in] net_phone Network module phone.
+ * @param[in] sess Network module session.
  *
  * @return EOK on success.
@@ -647,5 +648,5 @@
  *
  */
-int tl_initialize(int net_phone)
+int tl_initialize(async_sess_t *sess)
 {
 	measured_string_t names[] = {
@@ -669,11 +670,11 @@
 	atomic_set(&icmp_client, 0);
 	
-	phone_net = net_phone;
-	phone_ip = ip_bind_service(SERVICE_IP, IPPROTO_ICMP, SERVICE_ICMP,
+	net_sess = sess;
+	ip_sess = ip_bind_service(SERVICE_IP, IPPROTO_ICMP, SERVICE_ICMP,
 	    icmp_receiver);
-	if (phone_ip < 0)
-		return phone_ip;
-	
-	int rc = ip_packet_size_req(phone_ip, -1, &icmp_dimension);
+	if (ip_sess == NULL)
+		return ENOENT;
+	
+	int rc = ip_packet_size_req(ip_sess, -1, &icmp_dimension);
 	if (rc != EOK)
 		return rc;
@@ -684,5 +685,5 @@
 	/* Get configuration */
 	configuration = &names[0];
-	rc = net_get_conf_req(phone_net, &configuration, count, &data);
+	rc = net_get_conf_req(net_sess, &configuration, count, &data);
 	if (rc != EOK)
 		return rc;
@@ -762,5 +763,5 @@
 	
 	case NET_ICMP_DEST_UNREACH:
-		rc = packet_translate_remote(phone_net, &packet,
+		rc = packet_translate_remote(net_sess, &packet,
 		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
@@ -771,5 +772,5 @@
 	
 	case NET_ICMP_SOURCE_QUENCH:
-		rc = packet_translate_remote(phone_net, &packet,
+		rc = packet_translate_remote(net_sess, &packet,
 		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
@@ -779,5 +780,5 @@
 	
 	case NET_ICMP_TIME_EXCEEDED:
-		rc = packet_translate_remote(phone_net, &packet,
+		rc = packet_translate_remote(net_sess, &packet,
 		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
@@ -787,5 +788,5 @@
 	
 	case NET_ICMP_PARAMETERPROB:
-		rc = packet_translate_remote(phone_net, &packet,
+		rc = packet_translate_remote(net_sess, &packet,
 		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
Index: uspace/srv/net/tl/tcp/tcp.c
===================================================================
--- uspace/srv/net/tl/tcp/tcp.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/tl/tcp/tcp.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,5 +38,4 @@
 #include <assert.h>
 #include <async.h>
-#include <async_obsolete.h>
 #include <fibril_synch.h>
 #include <malloc.h>
@@ -74,7 +73,4 @@
 #include "tcp_header.h"
 
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
-
 /** TCP module name. */
 #define NAME  "tcp"
@@ -210,5 +206,6 @@
 
 static int tcp_received_msg(device_id_t, packet_t *, services_t, services_t);
-static int tcp_process_client_messages(ipc_callid_t, ipc_call_t);
+static int tcp_process_client_messages(async_sess_t *, ipc_callid_t,
+    ipc_call_t);
 
 static int tcp_listen_message(socket_cores_t *, int, int);
@@ -328,7 +325,7 @@
 
 	if (!socket) {
-		if (tl_prepare_icmp_packet(tcp_globals.net_phone,
-		    tcp_globals.icmp_phone, packet, error) == EOK) {
-			icmp_destination_unreachable_msg(tcp_globals.icmp_phone,
+		if (tl_prepare_icmp_packet(tcp_globals.net_sess,
+		    tcp_globals.icmp_sess, packet, error) == EOK) {
+			icmp_destination_unreachable_msg(tcp_globals.icmp_sess,
 			    ICMP_PORT_UNREACH, 0, packet);
 		}
@@ -401,9 +398,9 @@
 		fibril_rwlock_write_unlock(socket_data->local_lock);
 
-		rc = tl_prepare_icmp_packet(tcp_globals.net_phone,
-		    tcp_globals.icmp_phone, packet, error);
+		rc = tl_prepare_icmp_packet(tcp_globals.net_sess,
+		    tcp_globals.icmp_sess, packet, error);
 		if (rc == EOK) {
 			/* Checksum error ICMP */
-			icmp_parameter_problem_msg(tcp_globals.icmp_phone,
+			icmp_parameter_problem_msg(tcp_globals.icmp_sess,
 			    ICMP_PARAM_POINTER,
 			    ((size_t) ((void *) &header->checksum)) -
@@ -443,5 +440,5 @@
 		break;
 	default:
-		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 	}
 
@@ -506,5 +503,5 @@
 			/* Release the acknowledged packets */
 			next_packet = pq_next(packet);
-			pq_release_remote(tcp_globals.net_phone,
+			pq_release_remote(tcp_globals.net_sess,
 			    packet_get_id(packet));
 			packet = next_packet;
@@ -565,5 +562,5 @@
 			next_packet = pq_next(next_packet);
 			pq_insert_after(tmp_packet, next_packet);
-			pq_release_remote(tcp_globals.net_phone,
+			pq_release_remote(tcp_globals.net_sess,
 			    packet_get_id(tmp_packet));
 		}
@@ -602,5 +599,5 @@
 				if (packet == socket_data->incoming)
 					socket_data->incoming = next_packet;
-				pq_release_remote(tcp_globals.net_phone,
+				pq_release_remote(tcp_globals.net_sess,
 				    packet_get_id(packet));
 				packet = next_packet;
@@ -625,5 +622,5 @@
 				if (length <= 0) {
 					/* Remove the empty packet */
-					pq_release_remote(tcp_globals.net_phone,
+					pq_release_remote(tcp_globals.net_sess,
 					    packet_get_id(packet));
 					packet = next_packet;
@@ -672,5 +669,5 @@
 				}
 				/* Remove the duplicit or corrupted packet */
-				pq_release_remote(tcp_globals.net_phone,
+				pq_release_remote(tcp_globals.net_sess,
 				    packet_get_id(packet));
 				packet = next_packet;
@@ -699,7 +696,7 @@
 		if (rc != EOK) {
 			/* Remove the corrupted packets */
-			pq_release_remote(tcp_globals.net_phone,
+			pq_release_remote(tcp_globals.net_sess,
 			    packet_get_id(packet));
-			pq_release_remote(tcp_globals.net_phone,
+			pq_release_remote(tcp_globals.net_sess,
 			    packet_get_id(next_packet));
 		} else {
@@ -712,10 +709,10 @@
 				    new_sequence_number, length);
 				if (rc != EOK) {
-					pq_release_remote(tcp_globals.net_phone,
+					pq_release_remote(tcp_globals.net_sess,
 					    packet_get_id(next_packet));
 				}
 				rc = pq_insert_after(packet, next_packet);
 				if (rc != EOK) {
-					pq_release_remote(tcp_globals.net_phone,
+					pq_release_remote(tcp_globals.net_sess,
 					    packet_get_id(next_packet));
 				}
@@ -726,5 +723,5 @@
 		printf("unexpected\n");
 		/* Release duplicite or restricted */
-		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 		forced_ack = true;
 	}
@@ -794,5 +791,5 @@
 	if (rc != EOK)
 		return tcp_release_and_return(packet, rc);
-	rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
+	rc = tl_get_ip_packet_dimension(tcp_globals.ip_sess,
 	    &tcp_globals.dimensions, socket_data->device_id, &packet_dimension);
 	if (rc != EOK)
@@ -803,9 +800,10 @@
 
 	/* Notify the destination socket */
-	async_obsolete_msg_5(socket->phone, NET_SOCKET_RECEIVED,
-	    (sysarg_t) socket->socket_id,
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t) socket->socket_id,
 	    ((packet_dimension->content < socket_data->data_fragment_size) ?
 	    packet_dimension->content : socket_data->data_fragment_size), 0, 0,
 	    (sysarg_t) fragments);
+	async_exchange_end(exch);
 
 	return EOK;
@@ -824,8 +822,8 @@
 
 	/* Notify the destination socket */
-	async_obsolete_msg_5(socket->phone, NET_SOCKET_RECEIVED,
-	    (sysarg_t) socket->socket_id,
-	    0, 0, 0,
-	    (sysarg_t) 0 /* 0 fragments == no more data */);
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t) socket->socket_id,
+	    0, 0, 0, (sysarg_t) 0 /* 0 fragments == no more data */);
+	async_exchange_end(exch);
 }
 
@@ -853,5 +851,5 @@
 	next_packet = pq_detach(packet);
 	if (next_packet) {
-		pq_release_remote(tcp_globals.net_phone,
+		pq_release_remote(tcp_globals.net_sess,
 		    packet_get_id(next_packet));
 	}
@@ -940,5 +938,5 @@
 	/* Create a socket */
 	socket_id = -1;
-	rc = socket_create(socket_data->local_sockets, listening_socket->phone,
+	rc = socket_create(socket_data->local_sockets, listening_socket->sess,
 	    socket_data, &socket_id);
 	if (rc != EOK) {
@@ -993,5 +991,5 @@
 	fibril_rwlock_write_unlock(&tcp_globals.lock);
 	if (rc != EOK) {
-		socket_destroy(tcp_globals.net_phone, socket->socket_id,
+		socket_destroy(tcp_globals.net_sess, socket->socket_id,
 		    socket_data->local_sockets, &tcp_globals.sockets,
 		    tcp_free_socket_data);
@@ -1005,5 +1003,5 @@
 	next_packet = pq_detach(packet);
 	if (next_packet) {
-		pq_release_remote(tcp_globals.net_phone,
+		pq_release_remote(tcp_globals.net_sess,
 		    packet_get_id(next_packet));
 	}
@@ -1014,5 +1012,5 @@
 		    packet_get_data_length(packet) - sizeof(*header));
 		if (rc != EOK) {
-			socket_destroy(tcp_globals.net_phone, socket->socket_id,
+			socket_destroy(tcp_globals.net_sess, socket->socket_id,
 			    socket_data->local_sockets, &tcp_globals.sockets,
 			    tcp_free_socket_data);
@@ -1025,5 +1023,5 @@
 	rc = tcp_queue_packet(socket, socket_data, packet, 1);
 	if (rc != EOK) {
-		socket_destroy(tcp_globals.net_phone, socket->socket_id,
+		socket_destroy(tcp_globals.net_sess, socket->socket_id,
 		    socket_data->local_sockets, &tcp_globals.sockets,
 		    tcp_free_socket_data);
@@ -1033,5 +1031,5 @@
 	packet = tcp_get_packets_to_send(socket, socket_data);
 	if (!packet) {
-		socket_destroy(tcp_globals.net_phone, socket->socket_id,
+		socket_destroy(tcp_globals.net_sess, socket->socket_id,
 		    socket_data->local_sockets, &tcp_globals.sockets,
 		    tcp_free_socket_data);
@@ -1068,5 +1066,5 @@
 
 	socket_data->next_incoming = ntohl(header->sequence_number); /* + 1; */
-	pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+	pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 	socket_data->state = TCP_SOCKET_ESTABLISHED;
 	listening_socket = socket_cores_find(socket_data->local_sockets,
@@ -1082,8 +1080,10 @@
 		if (rc == EOK) {
 			/* Notify the destination socket */
-			async_obsolete_msg_5(socket->phone, NET_SOCKET_ACCEPTED,
+			async_exch_t *exch = async_exchange_begin(socket->sess);
+			async_msg_5(exch, NET_SOCKET_ACCEPTED,
 			    (sysarg_t) listening_socket->socket_id,
 			    socket_data->data_fragment_size, TCP_HEADER_SIZE,
 			    0, (sysarg_t) socket->socket_id);
+			async_exchange_end(exch);
 
 			fibril_rwlock_write_unlock(socket_data->local_lock);
@@ -1181,5 +1181,5 @@
 				/* Add to acknowledged or release */
 				if (pq_add(&acknowledged, packet, 0, 0) != EOK)
-					pq_release_remote(tcp_globals.net_phone,
+					pq_release_remote(tcp_globals.net_sess,
 					    packet_get_id(packet));
 				packet = next;
@@ -1190,5 +1190,5 @@
 		/* Release acknowledged */
 		if (acknowledged) {
-			pq_release_remote(tcp_globals.net_phone,
+			pq_release_remote(tcp_globals.net_sess,
 			    packet_get_id(acknowledged));
 		}
@@ -1234,11 +1234,12 @@
 	assert(answer);
 	assert(answer_count);
-
+	
 	*answer_count = 0;
-	switch (IPC_GET_IMETHOD(*call)) {
-	case IPC_M_CONNECT_TO_ME:
-		return tcp_process_client_messages(callid, *call);
-	}
-
+	
+	async_sess_t *callback =
+	    async_callback_receive_start(EXCHANGE_SERIALIZE, call);
+	if (callback)
+		return tcp_process_client_messages(callback, callid, *call);
+	
 	return ENOTSUP;
 }
@@ -1270,9 +1271,9 @@
 }
 
-int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call)
+int tcp_process_client_messages(async_sess_t *sess, ipc_callid_t callid,
+    ipc_call_t call)
 {
 	int res;
 	socket_cores_t local_sockets;
-	int app_phone = IPC_GET_PHONE(call);
 	struct sockaddr *addr;
 	int socket_id;
@@ -1325,5 +1326,5 @@
 			fibril_rwlock_write_lock(&lock);
 			socket_id = SOCKET_GET_SOCKET_ID(call);
-			res = socket_create(&local_sockets, app_phone,
+			res = socket_create(&local_sockets, sess,
 			    socket_data, &socket_id);
 			SOCKET_SET_SOCKET_ID(answer, socket_id);
@@ -1333,5 +1334,5 @@
 				break;
 			}
-			if (tl_get_ip_packet_dimension(tcp_globals.ip_phone,
+			if (tl_get_ip_packet_dimension(tcp_globals.ip_sess,
 			    &tcp_globals.dimensions, DEVICE_INVALID_ID,
 			    &packet_dimension) == EOK) {
@@ -1508,10 +1509,10 @@
 	}
 
-	/* Release the application phone */
-	async_obsolete_hangup(app_phone);
+	/* Release the application session */
+	async_hangup(sess);
 
 	printf("release\n");
 	/* Release all local sockets */
-	socket_cores_release(tcp_globals.net_phone, &local_sockets,
+	socket_cores_release(tcp_globals.net_sess, &local_sockets,
 	    &tcp_globals.sockets, tcp_free_socket_data);
 
@@ -1621,5 +1622,5 @@
 			local_lock = socket_data->local_lock;
 			fibril_rwlock_write_lock(local_lock);
-			socket_destroy(tcp_globals.net_phone,
+			socket_destroy(tcp_globals.net_sess,
 			    timeout->socket_id, timeout->local_sockets,
 			    &tcp_globals.sockets, tcp_free_socket_data);
@@ -1754,5 +1755,5 @@
 	}
 
-	rc = ip_get_route_req(tcp_globals.ip_phone, IPPROTO_TCP,
+	rc = ip_get_route_req(tcp_globals.ip_sess, IPPROTO_TCP,
 	    addr, addrlen, &socket_data->device_id,
 	    &socket_data->pseudo_header, &socket_data->headerlen);
@@ -1902,5 +1903,5 @@
 			rc = pq_insert_after(previous, copy);
 			if (rc != EOK) {
-				pq_release_remote(tcp_globals.net_phone,
+				pq_release_remote(tcp_globals.net_sess,
 				    packet_get_id(copy));
 				return sending;
@@ -1939,5 +1940,5 @@
 	    socket_data->headerlen, packet_get_data_length(packet));
 	if (rc != EOK) {
-		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 		return NULL;
 	}
@@ -1946,5 +1947,5 @@
 	header = (tcp_header_t *) packet_get_data(packet);
 	if (!header) {
-		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 		return NULL;
 	}
@@ -1971,5 +1972,5 @@
 	rc = ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0, 0, 0);
 	if (rc != EOK) {
-		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 		return NULL;
 	}
@@ -1978,5 +1979,5 @@
 	    sequence_number, socket_data->state, socket_data->timeout, true);
 	if (rc != EOK) {
-		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 		return NULL;
 	}
@@ -1995,5 +1996,5 @@
 
 	/* Make a copy of the packet */
-	copy = packet_get_copy(tcp_globals.net_phone, packet);
+	copy = packet_get_copy(tcp_globals.net_sess, packet);
 	if (!copy)
 		return NULL;
@@ -2009,5 +2010,5 @@
 	while (packet) {
 		next = pq_detach(packet);
-		ip_send_msg(tcp_globals.ip_phone, device_id, packet,
+		ip_send_msg(tcp_globals.ip_sess, device_id, packet,
 		    SERVICE_TCP, 0);
 		packet = next;
@@ -2122,5 +2123,5 @@
 		return NO_DATA;
 
-	rc = packet_translate_remote(tcp_globals.net_phone, &packet, packet_id);
+	rc = packet_translate_remote(tcp_globals.net_sess, &packet, packet_id);
 	if (rc != EOK)
 		return rc;
@@ -2133,5 +2134,5 @@
 	/* Release the packet */
 	dyn_fifo_pop(&socket->received);
-	pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+	pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 
 	/* Return the total length */
@@ -2171,5 +2172,5 @@
 		return ENOTCONN;
 
-	rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
+	rc = tl_get_ip_packet_dimension(tcp_globals.ip_sess,
 	    &tcp_globals.dimensions, socket_data->device_id, &packet_dimension);
 	if (rc != EOK)
@@ -2182,5 +2183,5 @@
 	for (index = 0; index < fragments; index++) {
 		/* Read the data fragment */
-		result = tl_socket_read_packet_data(tcp_globals.net_phone,
+		result = tl_socket_read_packet_data(tcp_globals.net_sess,
 		    &packet, TCP_HEADER_SIZE, packet_dimension,
 		    socket_data->addr, socket_data->addrlen);
@@ -2245,5 +2246,5 @@
 	default:
 		/* Just destroy */
-		rc = socket_destroy(tcp_globals.net_phone, socket_id,
+		rc = socket_destroy(tcp_globals.net_sess, socket_id,
 		    local_sockets, &tcp_globals.sockets,
 		    tcp_free_socket_data);
@@ -2293,5 +2294,5 @@
 
 	/* Get the device packet dimension */
-	rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
+	rc = tl_get_ip_packet_dimension(tcp_globals.ip_sess,
 	    &tcp_globals.dimensions, socket_data->device_id, &packet_dimension);
 	if (rc != EOK)
@@ -2299,5 +2300,5 @@
 
 	/* Get a new packet */
-	*packet = packet_get_4_remote(tcp_globals.net_phone, TCP_HEADER_SIZE,
+	*packet = packet_get_4_remote(tcp_globals.net_sess, TCP_HEADER_SIZE,
 	    packet_dimension->addr_len, packet_dimension->prefix,
 	    packet_dimension->suffix);
@@ -2362,5 +2363,5 @@
 			if (rc != EOK)
 				return rc;
-			rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
+			rc = tl_get_ip_packet_dimension(tcp_globals.ip_sess,
 			    &tcp_globals.dimensions, socket_data->device_id,
 			    &packet_dimension);
@@ -2434,5 +2435,5 @@
 int tcp_release_and_return(packet_t *packet, int result)
 {
-	pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+	pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 	return result;
 }
@@ -2443,4 +2444,5 @@
  * @param[in,out] icall Message parameters.
  * @param[in]     arg   Local argument.
+ *
  */
 static void tcp_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
@@ -2452,5 +2454,5 @@
 		switch (IPC_GET_IMETHOD(*icall)) {
 		case NET_TL_RECEIVED:
-			rc = packet_translate_remote(tcp_globals.net_phone, &packet,
+			rc = packet_translate_remote(tcp_globals.net_sess, &packet,
 			    IPC_GET_PACKET(*icall));
 			if (rc == EOK)
@@ -2470,5 +2472,5 @@
 /** Initialize the TCP module.
  *
- * @param[in] net_phone Network module phone.
+ * @param[in] sess Network module session.
  *
  * @return EOK on success.
@@ -2476,17 +2478,17 @@
  *
  */
-int tl_initialize(int net_phone)
+int tl_initialize(async_sess_t *sess)
 {
 	fibril_rwlock_initialize(&tcp_globals.lock);
 	fibril_rwlock_write_lock(&tcp_globals.lock);
 	
-	tcp_globals.net_phone = net_phone;
+	tcp_globals.net_sess = sess;
 	
-	tcp_globals.icmp_phone = icmp_connect_module();
-	tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP,
+	tcp_globals.icmp_sess = icmp_connect_module();
+	tcp_globals.ip_sess = ip_bind_service(SERVICE_IP, IPPROTO_TCP,
 	    SERVICE_TCP, tcp_receiver);
-	if (tcp_globals.ip_phone < 0) {
+	if (tcp_globals.ip_sess == NULL) {
 		fibril_rwlock_write_unlock(&tcp_globals.lock);
-		return tcp_globals.ip_phone;
+		return ENOENT;
 	}
 	
Index: uspace/srv/net/tl/tcp/tcp.h
===================================================================
--- uspace/srv/net/tl/tcp/tcp.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/tl/tcp/tcp.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,6 +38,6 @@
 #define NET_TCP_H_
 
+#include <async.h>
 #include <fibril_synch.h>
-
 #include <net/packet.h>
 #include <net/device.h>
@@ -284,10 +284,10 @@
 /** TCP global data. */
 struct tcp_globals {
-	/** Networking module phone. */
-	int net_phone;
-	/** IP module phone. */
-	int ip_phone;
-	/** ICMP module phone. */
-	int icmp_phone;
+	/** Networking module session. */
+	async_sess_t *net_sess;
+	/** IP module session. */
+	async_sess_t *ip_sess;
+	/** ICMP module session. */
+	async_sess_t *icmp_sess;
 	/** Last used free port. */
 	int last_used_port;
Index: uspace/srv/net/tl/udp/udp.c
===================================================================
--- uspace/srv/net/tl/udp/udp.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/tl/udp/udp.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -37,5 +37,4 @@
 
 #include <async.h>
-#include <async_obsolete.h>
 #include <fibril_synch.h>
 #include <malloc.h>
@@ -71,7 +70,4 @@
 #include "udp_header.h"
 
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
-
 /** UDP module name. */
 #define NAME  "udp"
@@ -103,5 +99,5 @@
 static int udp_release_and_return(packet_t *packet, int result)
 {
-	pq_release_remote(udp_globals.net_phone, packet_get_id(packet));
+	pq_release_remote(udp_globals.net_sess, packet_get_id(packet));
 	return result;
 }
@@ -196,7 +192,7 @@
 	    ntohs(header->destination_port), (uint8_t *) SOCKET_MAP_KEY_LISTENING, 0);
 	if (!socket) {
-		if (tl_prepare_icmp_packet(udp_globals.net_phone,
-		    udp_globals.icmp_phone, packet, error) == EOK) {
-			icmp_destination_unreachable_msg(udp_globals.icmp_phone,
+		if (tl_prepare_icmp_packet(udp_globals.net_sess,
+		    udp_globals.icmp_sess, packet, error) == EOK) {
+			icmp_destination_unreachable_msg(udp_globals.icmp_sess,
 			    ICMP_PORT_UNREACH, 0, packet);
 		}
@@ -255,5 +251,5 @@
 			while (tmp_packet) {
 				next_packet = pq_detach(tmp_packet);
-				pq_release_remote(udp_globals.net_phone,
+				pq_release_remote(udp_globals.net_sess,
 				    packet_get_id(tmp_packet));
 				tmp_packet = next_packet;
@@ -278,9 +274,9 @@
 		if (flip_checksum(compact_checksum(checksum)) !=
 		    IP_CHECKSUM_ZERO) {
-			if (tl_prepare_icmp_packet(udp_globals.net_phone,
-			    udp_globals.icmp_phone, packet, error) == EOK) {
+			if (tl_prepare_icmp_packet(udp_globals.net_sess,
+			    udp_globals.icmp_sess, packet, error) == EOK) {
 				/* Checksum error ICMP */
 				icmp_parameter_problem_msg(
-				    udp_globals.icmp_phone, ICMP_PARAM_POINTER,
+				    udp_globals.icmp_sess, ICMP_PARAM_POINTER,
 				    ((size_t) ((void *) &header->checksum)) -
 				    ((size_t) ((void *) header)), packet);
@@ -296,5 +292,5 @@
 		return udp_release_and_return(packet, rc);
 		
-	rc = tl_get_ip_packet_dimension(udp_globals.ip_phone,
+	rc = tl_get_ip_packet_dimension(udp_globals.ip_sess,
 	    &udp_globals.dimensions, device_id, &packet_dimension);
 	if (rc != EOK)
@@ -303,7 +299,9 @@
 	/* Notify the destination socket */
 	fibril_rwlock_write_unlock(&udp_globals.lock);
-	async_obsolete_msg_5(socket->phone, NET_SOCKET_RECEIVED,
-	    (sysarg_t) socket->socket_id, packet_dimension->content, 0, 0,
-	    (sysarg_t) fragments);
+	
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t) socket->socket_id,
+	    packet_dimension->content, 0, 0, (sysarg_t) fragments);
+	async_exchange_end(exch);
 
 	return EOK;
@@ -342,4 +340,5 @@
  * @param[in,out] icall Message parameters.
  * @param[in]     arg   Local argument.
+ *
  */
 static void udp_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
@@ -351,5 +350,5 @@
 		switch (IPC_GET_IMETHOD(*icall)) {
 		case NET_TL_RECEIVED:
-			rc = packet_translate_remote(udp_globals.net_phone, &packet,
+			rc = packet_translate_remote(udp_globals.net_sess, &packet,
 			    IPC_GET_PACKET(*icall));
 			if (rc == EOK)
@@ -369,5 +368,5 @@
 /** Initialize the UDP module.
  *
- * @param[in] net_phone Network module phone.
+ * @param[in] sess Network module session.
  *
  * @return EOK on success.
@@ -375,5 +374,5 @@
  *
  */
-int tl_initialize(int net_phone)
+int tl_initialize(async_sess_t *sess)
 {
 	measured_string_t names[] = {
@@ -394,17 +393,16 @@
 	fibril_rwlock_write_lock(&udp_globals.lock);
 	
-	udp_globals.net_phone = net_phone;
-	
-	udp_globals.icmp_phone = icmp_connect_module();
-	
-	udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP,
-	    SERVICE_UDP, udp_receiver);
-	if (udp_globals.ip_phone < 0) {
-		fibril_rwlock_write_unlock(&udp_globals.lock);
-		return udp_globals.ip_phone;
+	udp_globals.net_sess = sess;
+	udp_globals.icmp_sess = icmp_connect_module();
+	
+	udp_globals.ip_sess = ip_bind_service(SERVICE_IP, IPPROTO_UDP,
+	     SERVICE_UDP, udp_receiver);
+	if (udp_globals.ip_sess == NULL) {
+	    fibril_rwlock_write_unlock(&udp_globals.lock);
+	    return ENOENT;
 	}
 	
 	/* Read default packet dimensions */
-	int rc = ip_packet_size_req(udp_globals.ip_phone, -1,
+	int rc = ip_packet_size_req(udp_globals.ip_sess, -1,
 	    &udp_globals.packet_dimension);
 	if (rc != EOK) {
@@ -435,5 +433,5 @@
 	/* Get configuration */
 	configuration = &names[0];
-	rc = net_get_conf_req(udp_globals.net_phone, &configuration, count,
+	rc = net_get_conf_req(udp_globals.net_sess, &configuration, count,
 	    &data);
 	if (rc != EOK) {
@@ -529,10 +527,10 @@
 
 	if (udp_globals.checksum_computing) {
-		rc = ip_get_route_req(udp_globals.ip_phone, IPPROTO_UDP, addr,
+		rc = ip_get_route_req(udp_globals.ip_sess, IPPROTO_UDP, addr,
 		    addrlen, &device_id, &ip_header, &headerlen);
 		if (rc != EOK)
 			return rc;
 		/* Get the device packet dimension */
-//		rc = tl_get_ip_packet_dimension(udp_globals.ip_phone,
+//		rc = tl_get_ip_packet_dimension(udp_globals.ip_sess,
 //		    &udp_globals.dimensions, device_id, &packet_dimension);
 //		if (rc != EOK)
@@ -541,5 +539,5 @@
 //	} else {
 		/* Do not ask all the time */
-		rc = ip_packet_size_req(udp_globals.ip_phone, -1,
+		rc = ip_packet_size_req(udp_globals.ip_sess, -1,
 		    &udp_globals.packet_dimension);
 		if (rc != EOK)
@@ -559,5 +557,5 @@
 
 	/* Read the first packet fragment */
-	result = tl_socket_read_packet_data(udp_globals.net_phone, &packet,
+	result = tl_socket_read_packet_data(udp_globals.net_sess, &packet,
 	    UDP_HEADER_SIZE, packet_dimension, addr, addrlen);
 	if (result < 0)
@@ -580,5 +578,5 @@
 	/* Read the rest of the packet fragments */
 	for (index = 1; index < fragments; index++) {
-		result = tl_socket_read_packet_data(udp_globals.net_phone,
+		result = tl_socket_read_packet_data(udp_globals.net_sess,
 		    &next_packet, 0, packet_dimension, addr, addrlen);
 		if (result < 0)
@@ -632,5 +630,5 @@
 
 	/* Send the packet */
-	ip_send_msg(udp_globals.ip_phone, device_id, packet, SERVICE_UDP, 0);
+	ip_send_msg(udp_globals.ip_sess, device_id, packet, SERVICE_UDP, 0);
 
 	return EOK;
@@ -679,5 +677,5 @@
 		return NO_DATA;
 	
-	rc = packet_translate_remote(udp_globals.net_phone, &packet, packet_id);
+	rc = packet_translate_remote(udp_globals.net_sess, &packet, packet_id);
 	if (rc != EOK) {
 		(void) dyn_fifo_pop(&socket->received);
@@ -739,19 +737,22 @@
 }
 
-/** Processes the socket client messages.
- *
- * Runs until the client module disconnects.
- *
- * @param[in] callid 	The message identifier.
- * @param[in] call	The message parameters.
- * @return		EOK on success.
- *
- * @see	socket.h
- */
-static int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call)
+/** Process the socket client messages.
+ *
+ * Run until the client module disconnects.
+ *
+ * @see socket.h
+ *
+ * @param[in] sess   Callback session.
+ * @param[in] callid Message identifier.
+ * @param[in] call   Message parameters.
+ *
+ * @return EOK on success.
+ *
+ */
+static int udp_process_client_messages(async_sess_t *sess, ipc_callid_t callid,
+    ipc_call_t call)
 {
 	int res;
 	socket_cores_t local_sockets;
-	int app_phone = IPC_GET_PHONE(call);
 	struct sockaddr *addr;
 	int socket_id;
@@ -786,15 +787,15 @@
 		/* Get the next call */
 		callid = async_get_call(&call);
-		
+
+		/* Process the call */
 		if (!IPC_GET_IMETHOD(call)) {
 			res = EHANGUP;
 			break;
 		}
-
-		/* Process the call */
+		
 		switch (IPC_GET_IMETHOD(call)) {
 		case NET_SOCKET:
 			socket_id = SOCKET_GET_SOCKET_ID(call);
-			res = socket_create(&local_sockets, app_phone, NULL,
+			res = socket_create(&local_sockets, sess, NULL,
 			    &socket_id);
 			SOCKET_SET_SOCKET_ID(answer, socket_id);
@@ -804,5 +805,5 @@
 			
 			size = MAX_UDP_FRAGMENT_SIZE;
-			if (tl_get_ip_packet_dimension(udp_globals.ip_phone,
+			if (tl_get_ip_packet_dimension(udp_globals.ip_sess,
 			    &udp_globals.dimensions, DEVICE_INVALID_ID,
 			    &packet_dimension) == EOK) {
@@ -868,5 +869,5 @@
 		case NET_SOCKET_CLOSE:
 			fibril_rwlock_write_lock(&udp_globals.lock);
-			res = socket_destroy(udp_globals.net_phone,
+			res = socket_destroy(udp_globals.net_sess,
 			    SOCKET_GET_SOCKET_ID(call), &local_sockets,
 			    &udp_globals.sockets, NULL);
@@ -882,9 +883,9 @@
 	}
 
-	/* Release the application phone */
-	async_obsolete_hangup(app_phone);
+	/* Release the application session */
+	async_hangup(sess);
 
 	/* Release all local sockets */
-	socket_cores_release(udp_globals.net_phone, &local_sockets,
+	socket_cores_release(udp_globals.net_sess, &local_sockets,
 	    &udp_globals.sockets, NULL);
 
@@ -916,10 +917,10 @@
 {
 	*answer_count = 0;
-
-	switch (IPC_GET_IMETHOD(*call)) {
-	case IPC_M_CONNECT_TO_ME:
-		return udp_process_client_messages(callid, *call);
-	}
-
+	
+	async_sess_t *callback =
+	    async_callback_receive_start(EXCHANGE_SERIALIZE, call);
+	if (callback)
+		return udp_process_client_messages(callback, callid, *call);
+	
 	return ENOTSUP;
 }
Index: uspace/srv/net/tl/udp/udp.h
===================================================================
--- uspace/srv/net/tl/udp/udp.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/tl/udp/udp.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,4 +38,5 @@
 #define NET_UDP_H_
 
+#include <async.h>
 #include <fibril_synch.h>
 #include <socket_core.h>
@@ -49,10 +50,10 @@
 /** UDP global data. */
 struct udp_globals {
-	/** Networking module phone. */
-	int net_phone;
-	/** IP module phone. */
-	int ip_phone;
-	/** ICMP module phone. */
-	int icmp_phone;
+	/** Networking module session. */
+	async_sess_t *net_sess;
+	/** IP module session. */
+	async_sess_t *ip_sess;
+	/** ICMP module session. */
+	async_sess_t *icmp_sess;
 	/** Packet dimension. */
 	packet_dimension_t packet_dimension;
