Index: .bzrignore
===================================================================
--- .bzrignore	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ .bzrignore	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -107,4 +107,6 @@
 ./uspace/srv/hw/char/i8042/i8042
 ./uspace/srv/hw/char/s3c24xx_uart/s3c24ser
+./uspace/srv/hw/irc/apic/apic
+./uspace/srv/hw/irc/i8259/i8259
 ./uspace/srv/hw/netif/dp8390/dp8390
 ./uspace/srv/loader/loader
Index: boot/arch/amd64/Makefile.inc
===================================================================
--- boot/arch/amd64/Makefile.inc	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ boot/arch/amd64/Makefile.inc	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -30,5 +30,7 @@
 
 RD_SRVS_ESSENTIAL += \
-	$(USPACE_PATH)/srv/hw/char/i8042/i8042
+	$(USPACE_PATH)/srv/hw/char/i8042/i8042 \
+	$(USPACE_PATH)/srv/hw/irc/apic/apic \
+	$(USPACE_PATH)/srv/hw/irc/i8259/i8259
 
 RD_SRVS_NON_ESSENTIAL += \
@@ -45,5 +47,5 @@
 	usbkbd \
 	vhc
-	
+
 RD_DRV_CFG += \
 	isa/isa.dev
Index: boot/arch/sparc64/Makefile.inc
===================================================================
--- boot/arch/sparc64/Makefile.inc	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ boot/arch/sparc64/Makefile.inc	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -43,6 +43,6 @@
 
 RD_SRVS_ESSENTIAL += \
-	$(USPACE_PATH)/srv/hw/cir/fhc/fhc \
-	$(USPACE_PATH)/srv/hw/cir/obio/obio
+	$(USPACE_PATH)/srv/hw/irc/fhc/fhc \
+	$(USPACE_PATH)/srv/hw/irc/obio/obio
 
 SOURCES = \
Index: kernel/arch/amd64/include/interrupt.h
===================================================================
--- kernel/arch/amd64/include/interrupt.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ kernel/arch/amd64/include/interrupt.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -74,4 +74,5 @@
 extern void (* enable_irqs_function)(uint16_t);
 extern void (* eoi_function)(void);
+extern const char *irqs_info;
 
 extern void interrupt_init(void);
Index: kernel/arch/amd64/src/amd64.c
===================================================================
--- kernel/arch/amd64/src/amd64.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ kernel/arch/amd64/src/amd64.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -235,8 +235,7 @@
 #endif
 	
-	/*
-	 * This nasty hack should also go away ASAP.
-	 */
-	trap_virtual_enable_irqs(1 << IRQ_DP8390);
+	if (irqs_info != NULL)
+		sysinfo_set_item_val(irqs_info, NULL, true);
+	
 	sysinfo_set_item_val("netif.dp8390.inr", NULL, IRQ_DP8390);
 }
Index: kernel/arch/amd64/src/interrupt.c
===================================================================
--- kernel/arch/amd64/src/interrupt.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ kernel/arch/amd64/src/interrupt.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -62,4 +62,5 @@
 void (* enable_irqs_function)(uint16_t irqmask) = NULL;
 void (* eoi_function)(void) = NULL;
+const char *irqs_info = NULL;
 
 void istate_decode(istate_t *istate)
Index: kernel/arch/ia32/include/interrupt.h
===================================================================
--- kernel/arch/ia32/include/interrupt.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ kernel/arch/ia32/include/interrupt.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -74,4 +74,5 @@
 extern void (* enable_irqs_function)(uint16_t);
 extern void (* eoi_function)(void);
+extern const char *irqs_info;
 
 extern void interrupt_init(void);
Index: kernel/arch/ia32/src/drivers/i8259.c
===================================================================
--- kernel/arch/ia32/src/drivers/i8259.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ kernel/arch/ia32/src/drivers/i8259.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -86,4 +86,5 @@
 	disable_irqs_function = pic_disable_irqs;
 	eoi_function = pic_eoi;
+	irqs_info = "i8259";
 
 	pic_disable_irqs(0xffff);		/* disable all irq's */
Index: kernel/arch/ia32/src/ia32.c
===================================================================
--- kernel/arch/ia32/src/ia32.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ kernel/arch/ia32/src/ia32.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -193,8 +193,7 @@
 #endif
 	
-	/*
-	 * This nasty hack should also go away ASAP.
-	 */
-	trap_virtual_enable_irqs(1 << IRQ_DP8390);
+	if (irqs_info != NULL)
+		sysinfo_set_item_val(irqs_info, NULL, true);
+	
 	sysinfo_set_item_val("netif.dp8390.inr", NULL, IRQ_DP8390);
 }
Index: kernel/arch/ia32/src/interrupt.c
===================================================================
--- kernel/arch/ia32/src/interrupt.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ kernel/arch/ia32/src/interrupt.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -62,4 +62,5 @@
 void (* enable_irqs_function)(uint16_t irqmask) = NULL;
 void (* eoi_function)(void) = NULL;
+const char *irqs_info = NULL;
 
 void istate_decode(istate_t *istate)
Index: kernel/arch/ia32/src/smp/apic.c
===================================================================
--- kernel/arch/ia32/src/smp/apic.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ kernel/arch/ia32/src/smp/apic.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -178,4 +178,5 @@
 	disable_irqs_function = io_apic_disable_irqs;
 	eoi_function = l_apic_eoi;
+	irqs_info = "apic";
 	
 	/*
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ kernel/generic/src/ipc/ipc.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -706,6 +706,7 @@
 				break;
 			case IPC_PHONE_CONNECTED:
-				printf("connected to: %p ",
-				    task->phones[i].callee);
+				printf("connected to: %p (%" PRIu64 ") ",
+				    task->phones[i].callee,
+				    task->phones[i].callee->task->taskid);
 				break;
 			case IPC_PHONE_SLAMMED:
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/Makefile	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -110,23 +110,29 @@
 
 ifeq ($(UARCH),amd64)
-	DIRS += drv/rootpc
-	DIRS += drv/pciintel
-	DIRS += drv/isa
-	DIRS += drv/ns8250
-	DIRS += drv/uhci
-	DIRS += drv/usbhub
-	DIRS += drv/usbkbd
-	DIRS += drv/vhc
+	DIRS += \
+		drv/rootpc \
+		drv/pciintel \
+		drv/isa \
+		drv/ns8250 \
+		srv/hw/irc/apic \
+		srv/hw/irc/i8259 \
+		drv/uhci \
+		drv/usbhub \
+		drv/usbkbd \
+		drv/vhc
 endif
 
 ifeq ($(UARCH),ia32)
-	DIRS += drv/rootpc
-	DIRS += drv/pciintel
-	DIRS += drv/isa
-	DIRS += drv/ns8250
-	DIRS += drv/uhci
-	DIRS += drv/usbhub
-	DIRS += drv/usbkbd
-	DIRS += drv/vhc
+	DIRS += \
+		drv/rootpc \
+		drv/pciintel \
+		drv/isa \
+		drv/ns8250 \
+		srv/hw/irc/apic \
+		srv/hw/irc/i8259 \
+		drv/uhci \
+		drv/usbhub \
+		drv/usbkbd \
+		drv/vhc
 endif
 
@@ -137,6 +143,6 @@
 ifeq ($(UARCH),sparc64)
 	DIRS += \
-		srv/hw/cir/fhc \
-		srv/hw/cir/obio
+		srv/hw/irc/fhc \
+		srv/hw/irc/obio
 endif
 
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/app/init/init.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -273,4 +273,6 @@
 	mount_tmpfs();
 	
+	spawn("/srv/apic");
+	spawn("/srv/i8259");
 	spawn("/srv/fhc");
 	spawn("/srv/obio");
Index: uspace/app/tester/hw/misc/virtchar1.c
===================================================================
--- uspace/app/tester/hw/misc/virtchar1.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/app/tester/hw/misc/virtchar1.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -40,10 +40,9 @@
 #include <sys/types.h>
 #include <async.h>
-#include <device/char.h>
+#include <device/char_dev.h>
 #include <str.h>
 #include <vfs/vfs.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <device/char.h>
 #include "../../tester.h"
 
@@ -79,5 +78,5 @@
 	size_t i;
 	char buffer[BUFFER_SIZE];
-	read_dev(phone, buffer, BUFFER_SIZE);
+	char_dev_read(phone, buffer, BUFFER_SIZE);
 	TPRINTF(" ...verifying that we read zeroes only...\n");
 	for (i = 0; i < BUFFER_SIZE; i++) {
Index: uspace/app/tester/hw/serial/serial1.c
===================================================================
--- uspace/app/tester/hw/serial/serial1.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/app/tester/hw/serial/serial1.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -45,5 +45,5 @@
 #include <ipc/devman.h>
 #include <devman.h>
-#include <device/char.h>
+#include <device/char_dev.h>
 #include <str.h>
 #include <ipc/serial_ctl.h>
@@ -121,5 +121,5 @@
 	size_t total = 0;
 	while (total < cnt) {
-		ssize_t read = read_dev(phone, buf, cnt - total);
+		ssize_t read = char_dev_read(phone, buf, cnt - total);
 		
 		if (read < 0) {
@@ -152,5 +152,5 @@
 			 * direction of data transfer.
 			 */
-			ssize_t written = write_dev(phone, buf, read);
+			ssize_t written = char_dev_write(phone, buf, read);
 			
 			if (written < 0) {
@@ -181,5 +181,5 @@
 	
 	size_t eot_size = str_size(EOT);
-	ssize_t written = write_dev(phone, (void *) EOT, eot_size);
+	ssize_t written = char_dev_write(phone, (void *) EOT, eot_size);
 	
 	ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
Index: uspace/app/usbinfo/Makefile
===================================================================
--- uspace/app/usbinfo/Makefile	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/app/usbinfo/Makefile	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -35,4 +35,5 @@
 SOURCES = \
 	dump.c \
+	info.c \
 	main.c
 
Index: uspace/app/usbinfo/info.c
===================================================================
--- uspace/app/usbinfo/info.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/app/usbinfo/info.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,118 @@
+/*
+ * 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 usb
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+#include <stdio.h>
+#include <str_error.h>
+#include <errno.h>
+#include <usb/usbdrv.h>
+#include "usbinfo.h"
+
+int dump_device(int hc_phone, usb_address_t address)
+{
+	/*
+	 * Dump information about possible match ids.
+	 */
+	match_id_list_t match_id_list;
+	init_match_ids(&match_id_list);
+	int rc = usb_drv_create_device_match_ids(hc_phone, &match_id_list, address);
+	if (rc != EOK) {
+		fprintf(stderr,
+		    NAME ": failed to fetch match ids of the device: %s.\n",
+		    str_error(rc));
+		return rc;
+	}
+	dump_match_ids(&match_id_list);
+
+	/*
+	 * Get device descriptor and dump it.
+	 */
+	usb_standard_device_descriptor_t device_descriptor;
+	usb_dprintf(NAME, 1,
+	    "usb_drv_req_get_device_descriptor(%d, %d, %p)\n",
+	    hc_phone, (int) address, &device_descriptor);
+
+	rc = usb_drv_req_get_device_descriptor(hc_phone, address,
+	    &device_descriptor);
+	if (rc != EOK) {
+		fprintf(stderr,
+		    NAME ": failed to fetch standard device descriptor: %s.\n",
+		    str_error(rc));
+		return rc;
+	}
+	dump_standard_device_descriptor(&device_descriptor);
+
+	/*
+	 * Get first configuration descriptor and dump it.
+	 */
+	usb_standard_configuration_descriptor_t config_descriptor;
+	int config_index = 0;
+	usb_dprintf(NAME, 1,
+	    "usb_drv_req_get_bare_configuration_descriptor(%d, %d, %d, %p)\n",
+	    hc_phone, (int) address, config_index, &config_descriptor);
+
+	rc = usb_drv_req_get_bare_configuration_descriptor(hc_phone, address,
+	    config_index, &config_descriptor );
+	if (rc != EOK) {
+		fprintf(stderr,
+		    NAME ": failed to fetch standard configuration descriptor: %s.\n",
+		    str_error(rc));
+		return rc;
+	}
+	dump_standard_configuration_descriptor(config_index,
+	    &config_descriptor);
+
+	void *full_config_descriptor = malloc(config_descriptor.total_length);
+	usb_dprintf(NAME, 1,
+	    "usb_drv_req_get_full_configuration_descriptor(%d, %d, %d, %p, %zu)\n",
+	    hc_phone, (int) address, config_index,
+	    full_config_descriptor, config_descriptor.total_length);
+
+	rc = usb_drv_req_get_full_configuration_descriptor(hc_phone, address,
+	    config_index,
+	    full_config_descriptor, config_descriptor.total_length, NULL);
+	if (rc != EOK) {
+		fprintf(stderr,
+		    NAME ": failed to fetch full configuration descriptor: %s.\n",
+		    str_error(rc));
+		return rc;
+	}
+	dump_buffer("Full configuration descriptor:",
+	    full_config_descriptor, config_descriptor.total_length);
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/app/usbinfo/main.c
===================================================================
--- uspace/app/usbinfo/main.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/app/usbinfo/main.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2010 Vojtech Horky
+ * Copyright (c) 2010-2011 Vojtech Horky
  * All rights reserved.
  *
@@ -40,65 +40,98 @@
 #include <str_error.h>
 #include <bool.h>
+#include <getopt.h>
 #include <devman.h>
+#include <devmap.h>
 #include <usb/usbdrv.h>
 #include "usbinfo.h"
 
-#define DEFAULT_HOST_CONTROLLER_PATH "/virt/usbhc"
+enum {
+	ACTION_HELP = 256,
+	ACTION_DEVICE_ADDRESS,
+	ACTION_HOST_CONTROLLER,
+	ACTION_DEVICE,
+};
+
+static struct option long_options[] = {
+	{"help", no_argument, NULL, ACTION_HELP},
+	{"address", required_argument, NULL, ACTION_DEVICE_ADDRESS},
+	{"host-controller", required_argument, NULL, ACTION_HOST_CONTROLLER},
+	{"device", required_argument, NULL, ACTION_DEVICE},
+	{0, 0, NULL, 0}
+};
+static const char *short_options = "ha:t:d:";
 
 static void print_usage(char *app_name)
 {
+#define INDENT "      "
 	printf(NAME ": query USB devices for descriptors\n\n");
-	printf("Usage: %s /path/to/hc usb-address\n where\n", app_name);
-	printf("   /path/to/hc   Devman path to USB host controller " \
-	    "(use `-' for\n");
-	printf("                   default HC at `%s').\n",
-	    DEFAULT_HOST_CONTROLLER_PATH);
-	printf("   usb-address   USB address of device to be queried\n");
+	printf("Usage: %s [options]\n", app_name);
+	printf(" -h --help\n" INDENT \
+	    "Display this help.\n");
+	printf(" -tID --host-controller ID\n" INDENT \
+	    "Set host controller (ID can be path or class number)\n");
+	printf(" -aADDR --address ADDR\n" INDENT \
+	    "Set device address\n");
 	printf("\n");
-}
-
-static int connect_to_hc(const char *path)
+#undef INDENT
+}
+
+static int set_new_host_controller(int *phone, const char *path)
 {
 	int rc;
-	devman_handle_t handle;
-
-	rc = devman_device_get_handle(path, &handle, 0);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	int phone = devman_device_connect(handle, 0);
-
-	return phone;
-}
-
-int main(int argc, char *argv[])
-{
-	if (argc != 3) {
-		print_usage(argv[0]);
-		return EINVAL;
-	}
-
-	char *hc_path = argv[1];
-	long int address_long = strtol(argv[2], NULL, 0);
-
-	/*
-	 * Connect to given host controller driver.
-	 */
-	if (str_cmp(hc_path, "-") == 0) {
-		hc_path = (char *) DEFAULT_HOST_CONTROLLER_PATH;
-	}
-	int hc_phone = connect_to_hc(hc_path);
-	if (hc_phone < 0) {
-		fprintf(stderr,
-		    NAME ": unable to connect to HC at `%s': %s.\n",
-		    hc_path, str_error(hc_phone));
-		return hc_phone;
-	}
-
-	/*
-	 * Verify address is okay.
-	 */
-	usb_address_t address = (usb_address_t) address_long;
+	int tmp_phone;
+
+	if (path[0] != '/') {
+		int hc_class_index = (int) strtol(path, NULL, 10);
+		char *dev_path;
+		rc = asprintf(&dev_path, "class/usbhc\\%d", hc_class_index);
+		if (rc < 0) {
+			internal_error(rc);
+			return rc;
+		}
+		devmap_handle_t handle;
+		rc = devmap_device_get_handle(dev_path, &handle, 0);
+		if (rc < 0) {
+			fprintf(stderr,
+			    NAME ": failed getting handle of `devman://%s'.\n",
+			    dev_path);
+			free(dev_path);
+			return rc;
+		}
+		tmp_phone = devmap_device_connect(handle, 0);
+		if (tmp_phone < 0) {
+			fprintf(stderr,
+			    NAME ": could not connect to `%s'.\n",
+			    dev_path);
+			free(dev_path);
+			return tmp_phone;
+		}
+		free(dev_path);
+	} else {
+		devman_handle_t handle;
+		rc = devman_device_get_handle(path, &handle, 0);
+		if (rc != EOK) {
+			fprintf(stderr,
+			    NAME ": failed getting handle of `devmap::/%s'.\n",
+			    path);
+			return rc;
+		}
+		tmp_phone = devman_device_connect(handle, 0);
+		if (tmp_phone < 0) {
+			fprintf(stderr,
+			    NAME ": could not connect to `%s'.\n",
+			    path);
+			return tmp_phone;
+		}
+	}
+
+	*phone = tmp_phone;
+
+	return EOK;
+}
+
+static int connect_with_address(int hc_phone, const char *str_address)
+{
+	usb_address_t address = (usb_address_t) strtol(str_address, NULL, 0);
 	if ((address < 0) || (address >= USB11_ADDRESS_MAX)) {
 		fprintf(stderr, NAME ": USB address out of range.\n");
@@ -106,80 +139,68 @@
 	}
 
-	/*
-	 * Now, learn information about the device.
-	 */
-	int rc;
-
-	/*
-	 * Dump information about possible match ids.
-	 */
-	match_id_list_t match_id_list;
-	init_match_ids(&match_id_list);
-	rc = usb_drv_create_device_match_ids(hc_phone, &match_id_list, address);
-	if (rc != EOK) {
-		fprintf(stderr,
-		    NAME ": failed to fetch match ids of the device: %s.\n",
-		    str_error(rc));
-		return rc;
-	}
-	dump_match_ids(&match_id_list);
-
-	/*
-	 * Get device descriptor and dump it.
-	 */
-	usb_standard_device_descriptor_t device_descriptor;
-	usb_dprintf(NAME, 1,
-	    "usb_drv_req_get_device_descriptor(%d, %d, %p)\n",
-	    hc_phone, (int) address, &device_descriptor);
-
-	rc = usb_drv_req_get_device_descriptor(hc_phone, address,
-	    &device_descriptor);
-	if (rc != EOK) {
-		fprintf(stderr,
-		    NAME ": failed to fetch standard device descriptor: %s.\n",
-		    str_error(rc));
-		return rc;
-	}
-	dump_standard_device_descriptor(&device_descriptor);
-
-	/*
-	 * Get first configuration descriptor and dump it.
-	 */
-	usb_standard_configuration_descriptor_t config_descriptor;
-	int config_index = 0;
-	usb_dprintf(NAME, 1,
-	    "usb_drv_req_get_bare_configuration_descriptor(%d, %d, %d, %p)\n",
-	    hc_phone, (int) address, config_index, &config_descriptor);
-
-	rc = usb_drv_req_get_bare_configuration_descriptor(hc_phone, address,
-	    config_index, &config_descriptor );
-	if (rc != EOK) {
-		fprintf(stderr,
-		    NAME ": failed to fetch standard configuration descriptor: %s.\n",
-		    str_error(rc));
-		return rc;
-	}
-	dump_standard_configuration_descriptor(config_index,
-	    &config_descriptor);
-
-	void *full_config_descriptor = malloc(config_descriptor.total_length);
-	usb_dprintf(NAME, 1,
-	    "usb_drv_req_get_full_configuration_descriptor(%d, %d, %d, %p, %zu)\n",
-	    hc_phone, (int) address, config_index,
-	    full_config_descriptor, config_descriptor.total_length);
-
-	rc = usb_drv_req_get_full_configuration_descriptor(hc_phone, address,
-	    config_index,
-	    full_config_descriptor, config_descriptor.total_length, NULL);
-	if (rc != EOK) {
-		fprintf(stderr,
-		    NAME ": failed to fetch full configuration descriptor: %s.\n",
-		    str_error(rc));
-		return rc;
-	}
-	dump_buffer("Full configuration descriptor:",
-	    full_config_descriptor, config_descriptor.total_length);
-
-	return EOK;
+	if (hc_phone < 0) {
+		fprintf(stderr, NAME ": no active host controller.\n");
+		return ENOENT;
+	}
+
+	return dump_device(hc_phone, address);
+}
+
+
+int main(int argc, char *argv[])
+{
+	int hc_phone = -1;
+
+	if (argc <= 1) {
+		print_usage(argv[0]);
+		return -1;
+	}
+
+	int i;
+	do {
+		i = getopt_long(argc, argv, short_options, long_options, NULL);
+		switch (i) {
+			case -1:
+				break;
+
+			case '?':
+				print_usage(argv[0]);
+				return -1;
+
+			case 'h':
+			case ACTION_HELP:
+				print_usage(argv[0]);
+				return 0;
+
+			case 'a':
+			case ACTION_DEVICE_ADDRESS: {
+				int rc = connect_with_address(hc_phone, optarg);
+				if (rc != EOK) {
+					return rc;
+				}
+				break;
+			}
+
+			case 't':
+			case ACTION_HOST_CONTROLLER: {
+				int rc = set_new_host_controller(&hc_phone,
+				    optarg);
+				if (rc != EOK) {
+					return rc;
+				}
+				break;
+			}
+
+			case 'd':
+			case ACTION_DEVICE:
+				break;
+
+			default:
+				break;
+		}
+
+	} while (i != -1);
+
+	return 0;
 }
 
Index: uspace/app/usbinfo/usbinfo.h
===================================================================
--- uspace/app/usbinfo/usbinfo.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/app/usbinfo/usbinfo.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -49,4 +49,10 @@
 void dump_standard_configuration_descriptor(int, 
     usb_standard_configuration_descriptor_t *);
+int dump_device(int, usb_address_t);
+
+static inline void internal_error(int err)
+{
+	fprintf(stderr, NAME ": internal error (%s).\n", str_error(err));
+}
 
 #endif
Index: uspace/drv/isa/isa.c
===================================================================
--- uspace/drv/isa/isa.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/drv/isa/isa.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -51,5 +51,5 @@
 
 #include <driver.h>
-#include <resource.h>
+#include <ops/hw_res.h>
 
 #include <devman.h>
@@ -84,5 +84,5 @@
 }
 
-static resource_iface_t isa_child_res_iface = {
+static hw_res_ops_t isa_child_hw_res_ops = {
 	&isa_get_child_resources,
 	&isa_enable_child_interrupt
@@ -502,5 +502,5 @@
 static void isa_init() 
 {
-	isa_child_dev_ops.interfaces[HW_RES_DEV_IFACE] = &isa_child_res_iface;
+	isa_child_dev_ops.interfaces[HW_RES_DEV_IFACE] = &isa_child_hw_res_ops;
 }
 
Index: uspace/drv/ns8250/ns8250.c
===================================================================
--- uspace/drv/ns8250/ns8250.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/drv/ns8250/ns8250.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -53,6 +53,5 @@
 
 #include <driver.h>
-#include <char.h>
-#include <resource.h>
+#include <ops/char_dev.h>
 
 #include <devman.h>
@@ -227,5 +226,5 @@
 
 /** The character interface's callbacks. */
-static char_iface_t ns8250_char_iface = {
+static char_dev_ops_t ns8250_char_dev_ops = {
 	.read = &ns8250_read,
 	.write = &ns8250_write
@@ -347,5 +346,5 @@
 	
 	/* Get hw resources. */
-	ret = get_hw_resources(dev->parent_phone, &hw_resources);
+	ret = hw_res_get_resource_list(dev->parent_phone, &hw_resources);
 	if (ret != EOK) {
 		printf(NAME ": failed to get hw resources for the device "
@@ -394,10 +393,10 @@
 	}
 	
-	clean_hw_resource_list(&hw_resources);
+	hw_res_clean_resource_list(&hw_resources);
 	return ret;
 	
 failed:
 	ns8250_dev_cleanup(dev);
-	clean_hw_resource_list(&hw_resources);
+	hw_res_clean_resource_list(&hw_resources);
 	return ret;
 }
@@ -924,5 +923,5 @@
 	ns8250_dev_ops.close = &ns8250_close;
 	
-	ns8250_dev_ops.interfaces[CHAR_DEV_IFACE] = &ns8250_char_iface;
+	ns8250_dev_ops.interfaces[CHAR_DEV_IFACE] = &ns8250_char_dev_ops;
 	ns8250_dev_ops.default_handler = &ns8250_default_handler;
 }
Index: uspace/drv/pciintel/pci.c
===================================================================
--- uspace/drv/pciintel/pci.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/drv/pciintel/pci.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -49,5 +49,5 @@
 #include <ipc/devman.h>
 #include <ipc/dev_iface.h>
-#include <resource.h>
+#include <ops/hw_res.h>
 #include <device/hw_res.h>
 #include <ddi.h>
@@ -77,5 +77,5 @@
 }
 
-static resource_iface_t pciintel_child_res_iface = {
+static hw_res_ops_t pciintel_child_hw_res_ops = {
 	&pciintel_get_child_resources,
 	&pciintel_enable_child_interrupt
@@ -473,5 +473,5 @@
 	hw_resource_list_t hw_resources;
 	
-	rc = get_hw_resources(dev->parent_phone, &hw_resources);
+	rc = hw_res_get_resource_list(dev->parent_phone, &hw_resources);
 	if (rc != EOK) {
 		printf(NAME ": pci_add_device failed to get hw resources for "
@@ -497,5 +497,5 @@
 		delete_pci_bus_data(bus_data);
 		ipc_hangup(dev->parent_phone);
-		clean_hw_resource_list(&hw_resources);
+		hw_res_clean_resource_list(&hw_resources);
 		return EADDRNOTAVAIL;
 	}
@@ -508,5 +508,5 @@
 	pci_bus_scan(dev, 0);
 	
-	clean_hw_resource_list(&hw_resources);
+	hw_res_clean_resource_list(&hw_resources);
 	
 	return EOK;
@@ -515,5 +515,5 @@
 static void pciintel_init(void)
 {
-	pci_child_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_child_res_iface;
+	pci_child_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_child_hw_res_ops;
 }
 
@@ -537,5 +537,5 @@
 {
 	if (dev_data != NULL) {
-		clean_hw_resource_list(&dev_data->hw_resources);
+		hw_res_clean_resource_list(&dev_data->hw_resources);
 		free(dev_data);
 	}
Index: uspace/drv/rootpc/rootpc.c
===================================================================
--- uspace/drv/rootpc/rootpc.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/drv/rootpc/rootpc.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -50,5 +50,5 @@
 #include <ipc/devman.h>
 #include <ipc/dev_iface.h>
-#include <resource.h>
+#include <ops/hw_res.h>
 #include <device/hw_res.h>
 
@@ -107,5 +107,5 @@
 }
 
-static resource_iface_t child_res_iface = {
+static hw_res_ops_t child_hw_res_ops = {
 	&rootpc_get_child_resources,
 	&rootpc_enable_child_interrupt
@@ -190,5 +190,5 @@
 static void root_pc_init(void)
 {
-	rootpc_child_ops.interfaces[HW_RES_DEV_IFACE] = &child_res_iface;
+	rootpc_child_ops.interfaces[HW_RES_DEV_IFACE] = &child_hw_res_ops;
 }
 
Index: uspace/drv/test1/char.c
===================================================================
--- uspace/drv/test1/char.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/drv/test1/char.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -33,5 +33,5 @@
 #include <errno.h>
 #include <mem.h>
-#include <char.h>
+#include <ops/char_dev.h>
 
 #include "test1.h"
@@ -46,5 +46,5 @@
 }
 
-static char_iface_t char_interface = {
+static char_dev_ops_t char_dev_ops = {
 	.read = &impl_char_read,
 	.write = &imp_char_write
@@ -52,5 +52,5 @@
 
 device_ops_t char_device_ops = {
-	.interfaces[CHAR_DEV_IFACE] = &char_interface
+	.interfaces[CHAR_DEV_IFACE] = &char_dev_ops
 };
 
Index: uspace/drv/usbhub/main.c
===================================================================
--- uspace/drv/usbhub/main.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/drv/usbhub/main.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -38,4 +38,5 @@
 
 usb_general_list_t usb_hub_list;
+futex_t usb_hub_list_lock;
 
 static driver_ops_t hub_driver_ops = {
@@ -60,5 +61,7 @@
 {
 	usb_dprintf_enable(NAME,1);
+	futex_initialize(&usb_hub_list_lock, 0);
 	usb_lst_init(&usb_hub_list);
+	futex_up(&usb_hub_list_lock);
 	fid_t fid = fibril_create(usb_hub_control_loop, NULL);
 	if (fid == 0) {
Index: uspace/drv/usbhub/usbhub.c
===================================================================
--- uspace/drv/usbhub/usbhub.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/drv/usbhub/usbhub.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -75,5 +75,5 @@
 	//get some hub info
 	usb_address_t addr = usb_drv_get_my_address(hc, device);
-	dprintf(1,"[usb_hub] addres of newly created hub = %d", addr);
+	dprintf(1,"[usb_hub] address of newly created hub = %d", addr);
 	/*if(addr<0){
 		//return result;
@@ -174,4 +174,5 @@
 		dprintf(1,"[usb_hub] THERE ARE NO CONFIGURATIONS AVAILABLE");
 	}
+	/// \TODO check other configurations
 	usb_standard_configuration_descriptor_t config_descriptor;
 	opResult = usb_drv_req_get_bare_configuration_descriptor(hc,
@@ -194,5 +195,4 @@
 	}
 
-
 	for (port = 1; port < hub_info->port_count+1; ++port) {
 		usb_hub_set_power_port_request(&request, port);
@@ -205,9 +205,11 @@
 	//ports powered, hub seems to be enabled
 
-
 	ipc_hangup(hc);
 
 	//add the hub to list
+	futex_down(&usb_hub_list_lock);
 	usb_lst_append(&usb_hub_list, hub_info);
+	futex_up(&usb_hub_list_lock);
+
 	dprintf(1,"[usb_hub] hub info added to list");
 	//(void)hub_info;
@@ -233,4 +235,20 @@
 //
 //*********************************************
+
+/**
+ * convenience function for releasing default address and writing debug info
+ * (these few lines are used too often to be written again and again)
+ * @param hc
+ * @return
+ */
+inline static int usb_hub_release_default_address(int hc){
+	int opResult;
+	dprintf(1,"[usb_hub] releasing default address");
+	opResult = usb_drv_release_default_address(hc);
+	if (opResult != EOK) {
+		dprintf(1,"[usb_hub] failed to release default address");
+	}
+	return opResult;
+}
 
 /**
@@ -259,23 +277,7 @@
 	if (opResult != EOK) {
 		dprintf(1,"[usb_hub] something went wrong when reseting a port");
-	}
-}
-
-/**
- * convenience function for releasing default address and writing debug info
- * (these few lines are used too often to be written again and again)
- * @param hc
- * @return
- */
-inline static int usb_hub_release_default_address(int hc){
-	int opResult;
-	dprintf(1,"[usb_hub] releasing default address");
-	opResult = usb_drv_release_default_address(hc);
-	if (opResult != EOK) {
-		dprintf(1,"[usb_hub] failed to release default address");
-	}
-	return opResult;
-}
-
+		usb_hub_release_default_address(hc);
+	}
+}
 
 /**
@@ -343,5 +345,5 @@
 
 /**
- * unregister device address in hc, close the port
+ * unregister device address in hc
  * @param hc
  * @param port
@@ -352,15 +354,5 @@
 	//usb_device_request_setup_packet_t request;
 	int opResult;
-	//disable port
-	/*usb_hub_set_disable_port_request(&request, port);
-	opResult = usb_drv_sync_control_write(
-			hc, target,
-			&request,
-			NULL, 0
-			);
-	if (opResult != EOK) {
-		//continue;
-		printf("[usb_hub] something went wrong when disabling a port\n");
-	}*/
+	
 	/// \TODO remove device
 
@@ -457,7 +449,9 @@
 	 */
 	usb_general_list_t * lst_item;
+	futex_down(&usb_hub_list_lock);
 	for (lst_item = usb_hub_list.next;
 			lst_item != &usb_hub_list;
 			lst_item = lst_item->next) {
+		futex_up(&usb_hub_list_lock);
 		usb_hub_info_t * hub_info = ((usb_hub_info_t*)lst_item->data);
 		/*
@@ -510,7 +504,10 @@
 			}
 		}
+		free(change_bitmap);
 
 		ipc_hangup(hc);
-	}
+		futex_down(&usb_hub_list_lock);
+	}
+	futex_up(&usb_hub_list_lock);
 }
 
Index: uspace/drv/usbhub/usbhub_private.h
===================================================================
--- uspace/drv/usbhub/usbhub_private.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/drv/usbhub/usbhub_private.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -43,4 +43,6 @@
 #include <bool.h>
 #include <driver.h>
+#include <futex.h>
+
 #include <usb/usb.h>
 #include <usb/usbdrv.h>
@@ -66,5 +68,5 @@
 
 /**
- * @brief create hub structure instance
+ * create hub structure instance
  *
  * Set the address and port count information most importantly.
@@ -79,7 +81,10 @@
 extern usb_general_list_t usb_hub_list;
 
+/** lock for hub list*/
+extern futex_t usb_hub_list_lock;
+
 
 /**
- * @brief perform complete control read transaction
+ * perform complete control read transaction
  *
  * manages all three steps of transaction: setup, read and finalize
@@ -99,7 +104,7 @@
 
 /**
- * @brief perform complete control write transaction
+ * perform complete control write transaction
  *
- * maanges all three steps of transaction: setup, write and finalize
+ * manages all three steps of transaction: setup, write and finalize
  * @param phone
  * @param target
@@ -114,21 +119,4 @@
     void * sent_buffer, size_t sent_size
 );
-
-
-/**
- * set the device request to be a set address request
- * @param request
- * @param addr
- * \TODO this will be obsolete see usb/dev_req.h
- */
-static inline void usb_hub_set_set_address_request(
-usb_device_request_setup_packet_t * request, uint16_t addr
-){
-	request->index = 0;
-	request->request_type = 0;/// \TODO this is not very nice sollution, we ned constant
-	request->request = USB_DEVREQ_SET_ADDRESS;
-	request->value = addr;
-	request->length = 0;
-}
 
 /**
Index: uspace/drv/usbhub/utils.c
===================================================================
--- uspace/drv/usbhub/utils.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/drv/usbhub/utils.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -200,60 +200,5 @@
 
 
-/*
- * method for testing port status bitmap
- 
-static void usb_hub_test_port_status(void) {
-	printf("[usb_hub] -------------port status test---------\n");
-	usb_port_status_t status = 0;
-
-	//printf("original status %d (should be 0)\n",(uint32_t)status);
-	usb_port_set_bit(&status, 1, 1);
-	//printf("%d =?= 2\n",(uint32_t)status);
-	if (status != 2) {
-		printf("[usb_port_status] test failed: wrong set of bit 1\n");
-		return;
-	}
-	usb_port_set_bit(&status, 3, 1);
-	if (status != 10) {
-		printf("[usb_port_status] test failed: wrong set of bit 3\n");
-		return;
-	}
-
-	usb_port_set_bit(&status, 15, 1);
-	if (status != 10 + (1 << 15)) {
-		printf("[usb_port_status] test failed: wrong set of bit 15\n");
-		return;
-	}
-	usb_port_set_bit(&status, 1, 0);
-	if (status != 8 + (1 << 15)) {
-		printf("[usb_port_status] test failed: wrong unset of bit 1\n");
-		return;
-	}
-	int i;
-	for (i = 0; i < 32; ++i) {
-		if (i == 3 || i == 15) {
-			if (!usb_port_get_bit(&status, i)) {
-				printf("[usb_port_status] test failed: wrong bit at %d\n", i);
-			}
-		} else {
-			if (usb_port_get_bit(&status, i)) {
-				printf("[usb_port_status] test failed: wrong bit at %d\n", i);
-			}
-		}
-	}
-
-	printf("test ok\n");
-
-
-	//printf("%d =?= 10\n",(uint32_t)status);
-
-	//printf("this should be 0: %d \n",usb_port_get_bit(&status,0));
-	//printf("this should be 1: %d \n",usb_port_get_bit(&status,1));
-	//printf("this should be 0: %d \n",usb_port_get_bit(&status,2));
-	//printf("this should be 1: %d \n",usb_port_get_bit(&status,3));
-	//printf("this should be 0: %d \n",usb_port_get_bit(&status,4));
-
-}
-*/
+
 
 
Index: uspace/drv/usbkbd/main.c
===================================================================
--- uspace/drv/usbkbd/main.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/drv/usbkbd/main.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -79,14 +79,10 @@
 }
 
+#if 0
 static void send_key(int key, int type, wchar_t c) {
 	async_msg_4(console_callback_phone, KBD_EVENT, type, key,
 	    KM_NUM_LOCK, c);
 }
-
-static void send_alnum(int key, wchar_t c) {
-	printf(NAME ": sending key '%lc' to console\n", (wint_t) c);
-	send_key(key, KEY_PRESS, c);
-	send_key(key, KEY_RELEASE, c);
-}
+#endif
 
 /*
@@ -230,13 +226,4 @@
 	callbacks->keyboard = usbkbd_process_keycodes;
 
-	if (console_callback_phone != -1) {
-		static size_t counter = 0;
-		counter++;
-		if (counter > 3) {
-			counter = 0;
-			send_alnum(KC_A, L'a');
-		}
-	}
-
 	usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks, 
 	    NULL);
Index: uspace/drv/vhc/hcd.c
===================================================================
--- uspace/drv/vhc/hcd.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/drv/vhc/hcd.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -86,4 +86,6 @@
 	dev->ops = &vhc_ops;
 
+	devman_add_device_to_class(dev->handle, "usbhc");
+
 	/*
 	 * Initialize our hub and announce its presence.
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/Makefile	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -59,5 +59,5 @@
 	generic/devman.c \
 	generic/device/hw_res.c \
-	generic/device/char.c \
+	generic/device/char_dev.c \
 	generic/event.c \
 	generic/errno.c \
Index: uspace/lib/c/generic/adt/char_map.c
===================================================================
--- uspace/lib/c/generic/adt/char_map.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/generic/adt/char_map.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -65,5 +65,5 @@
  */
 static int
-char_map_add_item(char_map_t *map, const char *identifier, size_t length,
+char_map_add_item(char_map_t *map, const uint8_t *identifier, size_t length,
     const int value)
 {
@@ -139,5 +139,5 @@
  */
 int
-char_map_add(char_map_t *map, const char *identifier, size_t length,
+char_map_add(char_map_t *map, const uint8_t *identifier, size_t length,
     const int value)
 {
@@ -200,5 +200,5 @@
  */
 static char_map_t *
-char_map_find_node(const char_map_t *map, const char *identifier,
+char_map_find_node(const char_map_t *map, const uint8_t *identifier,
     size_t length)
 {
@@ -241,5 +241,5 @@
  * @return		CHAR_MAP_NULL if the key is not assigned a value.
  */
-int char_map_exclude(char_map_t *map, const char *identifier, size_t length)
+int char_map_exclude(char_map_t *map, const uint8_t *identifier, size_t length)
 {
 	char_map_t *node;
@@ -269,5 +269,5 @@
  *  @return		CHAR_MAP_NULL if the key is not assigned a value.
  */
-int char_map_find(const char_map_t *map, const char *identifier, size_t length)
+int char_map_find(const char_map_t *map, const uint8_t *identifier, size_t length)
 {
 	char_map_t *node;
@@ -329,5 +329,5 @@
  */
 int
-char_map_update(char_map_t *map, const char *identifier, const size_t length,
+char_map_update(char_map_t *map, const uint8_t *identifier, const size_t length,
     const int value)
 {
Index: uspace/lib/c/generic/adt/measured_strings.c
===================================================================
--- uspace/lib/c/generic/adt/measured_strings.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/generic/adt/measured_strings.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -59,5 +59,5 @@
  */
 measured_string_t *
-measured_string_create_bulk(const char *string, size_t length)
+measured_string_create_bulk(const uint8_t *string, size_t length)
 {
 	measured_string_t *new;
@@ -68,10 +68,10 @@
 	}
 	new = (measured_string_t *) malloc(sizeof(measured_string_t) +
-	    (sizeof(char) * (length + 1)));
+	    (sizeof(uint8_t) * (length + 1)));
 	if (!new)
 		return NULL;
 
 	new->length = length;
-	new->value = ((char *) new) + sizeof(measured_string_t);
+	new->value = ((uint8_t *) new) + sizeof(measured_string_t);
 	// append terminating zero explicitly - to be safe
 	memcpy(new->value, string, new->length);
@@ -97,5 +97,5 @@
 	new = (measured_string_t *) malloc(sizeof(measured_string_t));
 	if (new) {
-		new->value = (char *) malloc(source->length + 1);
+		new->value = (uint8_t *) malloc(source->length + 1);
 		if (new->value) {
 			new->length = source->length;
@@ -131,5 +131,5 @@
  */
 int
-measured_strings_receive(measured_string_t **strings, char **data,
+measured_strings_receive(measured_string_t **strings, uint8_t **data,
     size_t count)
 {
@@ -137,5 +137,5 @@
 	size_t index;
 	size_t length;
-	char *next;
+	uint8_t *next;
 	ipc_callid_t callid;
 	int rc;
@@ -311,10 +311,10 @@
  */
 int
-measured_strings_return(int phone, measured_string_t **strings, char **data,
+measured_strings_return(int phone, measured_string_t **strings, uint8_t **data,
     size_t count)
 {
 	size_t *lengths;
 	size_t index;
-	char *next;
+	uint8_t *next;
 	int rc;
 
Index: uspace/lib/c/generic/async_sess.c
===================================================================
--- uspace/lib/c/generic/async_sess.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/generic/async_sess.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -110,10 +110,11 @@
 typedef struct {
 	link_t sess_link;	/**< Link for the session list of inactive connections. */
-	link_t global_link;	/**< Link for the global list of inactive connectinos. */
+	link_t global_link;	/**< Link for the global list of inactive connections. */
 	int data_phone;		/**< Connected data phone. */
 } conn_node_t;
 
 /**
- * Mutex protecting the inactive_conn_head list and the session list.
+ * Mutex protecting the inactive_conn_head list, the session list and the
+ * avail_phone condition variable.
  */
 static fibril_mutex_t async_sess_mutex;
@@ -128,4 +129,9 @@
  */
 static LIST_INITIALIZE(session_list_head);
+
+/**
+ * Condition variable used to wait for a phone to become available.
+ */
+static FIBRIL_CONDVAR_INITIALIZE(avail_phone_cv);
 
 /** Initialize the async_sess subsystem.
@@ -150,8 +156,13 @@
  * @param sess	Session structure provided by caller, will be filled in.
  * @param phone	Phone connected to the desired server task.
- */
-void async_session_create(async_sess_t *sess, int phone)
+ * @param arg1	Value to pass as first argument upon creating a new
+ *		connection. Typical use is to identify a resource within
+ *		the server that the caller wants to access (port ID,
+ *		interface ID, device ID, etc.).
+ */
+void async_session_create(async_sess_t *sess, int phone, sysarg_t arg1)
 {
 	sess->sess_phone = phone;
+	sess->connect_arg1 = arg1;
 	list_initialize(&sess->conn_head);
 	
@@ -192,4 +203,6 @@
 		free(conn);
 	}
+	
+	fibril_condvar_broadcast(&avail_phone_cv);
 }
 
@@ -231,5 +244,6 @@
 		 */
 retry:
-		data_phone = async_connect_me_to(sess->sess_phone, 0, 0, 0);
+		data_phone = async_connect_me_to(sess->sess_phone,
+		    sess->connect_arg1, 0, 0);
 		if (data_phone >= 0) {
 			/* success, do nothing */
@@ -250,10 +264,8 @@
 		} else {
 			/*
-			 * This is unfortunate. We failed both to find a cached
-			 * connection or to create a new one even after cleaning up
-			 * the cache. This is most likely due to too many
-			 * open sessions (connected session phones).
+			 * Wait for a phone to become available.
 			 */
-			data_phone = ELIMIT;
+			fibril_condvar_wait(&avail_phone_cv, &async_sess_mutex);
+			goto retry;
 		}
 	}
@@ -273,4 +285,5 @@
 
 	fibril_mutex_lock(&async_sess_mutex);
+	fibril_condvar_signal(&avail_phone_cv);
 	conn = (conn_node_t *) malloc(sizeof(conn_node_t));
 	if (!conn) {
@@ -279,6 +292,6 @@
 		 * means that we simply hang up.
 		 */
+		ipc_hangup(data_phone);
 		fibril_mutex_unlock(&async_sess_mutex);
-		ipc_hangup(data_phone);
 		return;
 	}
Index: pace/lib/c/generic/device/char.c
===================================================================
--- uspace/lib/c/generic/device/char.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,133 +1,0 @@
-/*
- * 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 <ipc/dev_iface.h>
-#include <device/char.h>
-#include <errno.h>
-#include <async.h>
-#include <malloc.h>
-#include <stdio.h>
-
-/** Read to or write from device.
- *
- * Helper function to read to or write from a device
- * using its character interface.
- *
- * @param dev_phone Phone to the device.
- * @param buf       Buffer for the data read
- *                  from or written to the device.
- * @param len       Maximum length of the data to be
- *                  read or written.
- * @param read      Read from the device if true,
- *                  write to it otherwise.
- *
- * @return Non-negative number of bytes actually read
- *         from or written to the device on success,
- *         negative error number otherwise.
- *
- */
-static ssize_t rw_dev(int dev_phone, void *buf, size_t len, bool read)
-{
-	async_serialize_start();
-	
-	ipc_call_t answer;
-	aid_t req;
-	int ret;
-	
-	if (read) {
-		req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE),
-		    CHAR_READ_DEV, &answer);
-		ret = async_data_read_start(dev_phone, buf, len);
-	} else {
-		req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE),
-		    CHAR_WRITE_DEV, &answer);
-		ret = async_data_write_start(dev_phone, buf, len);
-	}
-	
-	sysarg_t rc;
-	if (ret != EOK) {
-		async_wait_for(req, &rc);
-		async_serialize_end();
-		if (rc == EOK)
-			return (ssize_t) ret;
-			
-		return (ssize_t) rc;
-	}
-	
-	async_wait_for(req, &rc);
-	async_serialize_end();
-	
-	ret = (int) rc;
-	if (ret != EOK)
-		return (ssize_t) ret;
-	
-	return (ssize_t) IPC_GET_ARG1(answer);
-}
-
-/** Read from device using its character interface.
- *
- * @param dev_phone Phone to the device.
- * @param buf       Output buffer for the data
- *                  read from the device.
- * @param len       Maximum length of the data to be read.
- *
- * @return Non-negative number of bytes actually read
- *         from the device on success, negative error
- *         number otherwise.
- *
- */
-ssize_t read_dev(int dev_phone, void *buf, size_t len)
-{
-	return rw_dev(dev_phone, buf, len, true);
-}
-
-/** Write to device using its character interface.
- *
- * @param dev_phone Phone to the device.
- * @param buf       Input buffer containg the data
- *                  to be written to the device.
- * @param len       Maximum length of the data to be written.
- *
- * @return Non-negative number of bytes actually written
- *         to the device on success, negative error number
- *         otherwise.
- *
- */
-ssize_t write_dev(int dev_phone, void *buf, size_t len)
-{
-	return rw_dev(dev_phone, buf, len, false);
-}
-
-/** @}
- */
Index: uspace/lib/c/generic/device/char_dev.c
===================================================================
--- uspace/lib/c/generic/device/char_dev.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/lib/c/generic/device/char_dev.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,124 @@
+/*
+ * 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 <ipc/dev_iface.h>
+#include <device/char_dev.h>
+#include <errno.h>
+#include <async.h>
+#include <malloc.h>
+#include <stdio.h>
+
+/** Read to or write from device.
+ *
+ * Helper function to read to or write from a device
+ * using its character interface.
+ *
+ * @param dev_phone	Phone to the device.
+ * @param buf		Buffer for the data read from or written to the device.
+ * @param size		Maximum size of data (in bytes) to be read or written.
+ * @param read		Read from the device if true, write to it otherwise.
+ *
+ * @return		Non-negative number of bytes actually read from or
+ *			written to the device on success, negative error number
+ *			otherwise.
+ */
+static ssize_t char_dev_rw(int dev_phone, void *buf, size_t size, bool read)
+{
+	async_serialize_start();
+	
+	ipc_call_t answer;
+	aid_t req;
+	int ret;
+	
+	if (read) {
+		req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE),
+		    CHAR_DEV_READ, &answer);
+		ret = async_data_read_start(dev_phone, buf, size);
+	} else {
+		req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE),
+		    CHAR_DEV_WRITE, &answer);
+		ret = async_data_write_start(dev_phone, buf, size);
+	}
+	
+	sysarg_t rc;
+	if (ret != EOK) {
+		async_wait_for(req, &rc);
+		async_serialize_end();
+		if (rc == EOK)
+			return (ssize_t) ret;
+		
+		return (ssize_t) rc;
+	}
+	
+	async_wait_for(req, &rc);
+	async_serialize_end();
+	
+	ret = (int) rc;
+	if (ret != EOK)
+		return (ssize_t) ret;
+	
+	return (ssize_t) IPC_GET_ARG1(answer);
+}
+
+/** Read from character device.
+ *
+ * @param dev_phone	Phone to the device.
+ * @param buf		Output buffer for the data read from the device.
+ * @param size		Maximum size (in bytes) of the data to be read.
+ *
+ * @return		Non-negative number of bytes actually read from the
+ *			device on success, negative error number otherwise.
+ */
+ssize_t char_dev_read(int dev_phone, void *buf, size_t size)
+{
+	return char_dev_rw(dev_phone, buf, size, true);
+}
+
+/** Write to character device.
+ *
+ * @param dev_phone	Phone to the device.
+ * @param buf		Input buffer containg the data to be written to the
+ *			device.
+ * @param size		Maximum size (in bytes) of the data to be written.
+ *
+ * @return		Non-negative number of bytes actually written to the
+ *			device on success, negative error number otherwise.
+ */
+ssize_t char_dev_write(int dev_phone, void *buf, size_t size)
+{
+	return char_dev_rw(dev_phone, buf, size, false);
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/device/hw_res.c
===================================================================
--- uspace/lib/c/generic/device/hw_res.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/generic/device/hw_res.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -26,5 +26,5 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
- 
+
  /** @addtogroup libc
  * @{
@@ -32,5 +32,5 @@
 /** @file
  */
- 
+
 #include <device/hw_res.h>
 #include <errno.h>
@@ -38,8 +38,11 @@
 #include <malloc.h>
 
-int get_hw_resources(int dev_phone, hw_resource_list_t *hw_resources)
+int hw_res_get_resource_list(int dev_phone, hw_resource_list_t *hw_resources)
 {
 	sysarg_t count = 0;
-	int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(HW_RES_DEV_IFACE), GET_RESOURCE_LIST, &count);
+
+	int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(HW_RES_DEV_IFACE),
+	    HW_RES_GET_RESOURCE_LIST, &count);
+
 	hw_resources->count = count;
 	if (rc != EOK)
@@ -57,16 +60,16 @@
 		return rc;
 	}
-	 	 
+	
 	return EOK;
 }
 
-bool enable_interrupt(int dev_phone)
+bool hw_res_enable_interrupt(int dev_phone)
 {
-	int rc = async_req_1_0(dev_phone, DEV_IFACE_ID(HW_RES_DEV_IFACE), ENABLE_INTERRUPT);
+	int rc = async_req_1_0(dev_phone, DEV_IFACE_ID(HW_RES_DEV_IFACE),
+	    HW_RES_ENABLE_INTERRUPT);
+
 	return rc == EOK;
 }
- 
- 
- 
- /** @}
+
+/** @}
  */
Index: uspace/lib/c/generic/devman.c
===================================================================
--- uspace/lib/c/generic/devman.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/generic/devman.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -42,4 +42,5 @@
 #include <devman.h>
 #include <async.h>
+#include <fibril_synch.h>
 #include <errno.h>
 #include <malloc.h>
@@ -50,30 +51,40 @@
 static int devman_phone_client = -1;
 
+static FIBRIL_MUTEX_INITIALIZE(devman_phone_mutex);
+
 int devman_get_phone(devman_interface_t iface, unsigned int flags)
 {
 	switch (iface) {
 	case DEVMAN_DRIVER:
-		if (devman_phone_driver >= 0)
+		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 = ipc_connect_me_to_blocking(PHONE_NS,
+			devman_phone_driver = async_connect_me_to_blocking(
+			    PHONE_NS, SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
+		else
+			devman_phone_driver = async_connect_me_to(PHONE_NS,
 			    SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
-		else
-			devman_phone_driver = ipc_connect_me_to(PHONE_NS,
-			    SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
-		
+		
+		fibril_mutex_unlock(&devman_phone_mutex);
 		return devman_phone_driver;
 	case DEVMAN_CLIENT:
-		if (devman_phone_client >= 0)
+		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 = ipc_connect_me_to_blocking(PHONE_NS,
+			devman_phone_client = async_connect_me_to_blocking(
+			    PHONE_NS, SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
+		else
+			devman_phone_client = async_connect_me_to(PHONE_NS,
 			    SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
-		else
-			devman_phone_client = ipc_connect_me_to(PHONE_NS,
-			    SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
-		
+		
+		fibril_mutex_unlock(&devman_phone_mutex);
 		return devman_phone_client;
 	default:
@@ -245,8 +256,8 @@
 	
 	if (flags & IPC_FLAG_BLOCKING) {
-		phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,
+		phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,
 		    DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
 	} else {
-		phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
+		phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
 		    DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
 	}
Index: uspace/lib/c/generic/fibril.c
===================================================================
--- uspace/lib/c/generic/fibril.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/generic/fibril.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -361,4 +361,9 @@
 }
 
+int fibril_get_sercount(void)
+{
+	return serialization_count;
+}
+
 /** @}
  */
Index: uspace/lib/c/generic/fibril_synch.c
===================================================================
--- uspace/lib/c/generic/fibril_synch.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/generic/fibril_synch.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -104,4 +104,7 @@
 	fibril_t *f = (fibril_t *) fibril_get_id();
 
+	if (fibril_get_sercount() != 0)
+		core();
+
 	futex_down(&async_futex);
 	if (fm->counter-- <= 0) {
@@ -194,4 +197,7 @@
 	fibril_t *f = (fibril_t *) fibril_get_id();
 	
+	if (fibril_get_sercount() != 0)
+		core();
+
 	futex_down(&async_futex);
 	if (frw->writers) {
@@ -219,4 +225,7 @@
 	fibril_t *f = (fibril_t *) fibril_get_id();
 	
+	if (fibril_get_sercount() != 0)
+		core();
+
 	futex_down(&async_futex);
 	if (frw->writers || frw->readers) {
Index: uspace/lib/c/generic/io/vprintf.c
===================================================================
--- uspace/lib/c/generic/io/vprintf.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/generic/io/vprintf.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -37,9 +37,9 @@
 #include <unistd.h>
 #include <io/printf_core.h>
-#include <futex.h>
+#include <fibril_synch.h>
 #include <async.h>
 #include <str.h>
 
-static atomic_t printf_futex = FUTEX_INITIALIZER;
+static FIBRIL_MUTEX_INITIALIZE(printf_mutex);
 
 static int vprintf_str_write(const char *str, size_t size, void *stream)
@@ -85,16 +85,9 @@
 	 * Prevent other threads to execute printf_core()
 	 */
-	futex_down(&printf_futex);
-	
-	/*
-	 * Prevent other fibrils of the same thread
-	 * to execute printf_core()
-	 */
-	async_serialize_start();
+	fibril_mutex_lock(&printf_mutex);
 	
 	int ret = printf_core(fmt, &ps, ap);
 	
-	async_serialize_end();
-	futex_up(&printf_futex);
+	fibril_mutex_unlock(&printf_mutex);
 	
 	return ret;
Index: uspace/lib/c/generic/mem.c
===================================================================
--- uspace/lib/c/generic/mem.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/generic/mem.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -222,15 +222,20 @@
 /** Compare two memory areas.
  *
- * @param s1		Pointer to the first area to compare.
- * @param s2		Pointer to the second area to compare.
- * @param len		Size of the first area in bytes. Both areas must have
- * 			the same length.
- * @return		If len is 0, return zero. If the areas match, return
- * 			zero. Otherwise return non-zero.
- */
-int bcmp(const char *s1, const char *s2, size_t len)
-{
-	for (; len && *s1++ == *s2++; len--)
-		;
+ * @param s1  Pointer to the first area to compare.
+ * @param s2  Pointer to the second area to compare.
+ * @param len Size of the first area in bytes. Both areas must have
+ *            the same length.
+ *
+ * @return If len is 0, return zero. If the areas match, return
+ *         zero. Otherwise return non-zero.
+ *
+ */
+int bcmp(const void *s1, const void *s2, size_t len)
+{
+	uint8_t *u1 = (uint8_t *) s1;
+	uint8_t *u2 = (uint8_t *) s2;
+	
+	for (; (len != 0) && (*u1++ == *u2++); len--);
+	
 	return len;
 }
Index: uspace/lib/c/generic/net/modules.c
===================================================================
--- uspace/lib/c/generic/net/modules.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/generic/net/modules.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -32,5 +32,5 @@
 
 /** @file
- * Generic module functions implementation. 
+ * Generic module functions implementation.
  *
  * @todo MAKE IT POSSIBLE TO REMOVE THIS FILE VIA EITHER REPLACING PART OF ITS
@@ -52,18 +52,18 @@
 #define MODULE_WAIT_TIME	(10 * 1000)
 
-/** Answers the call.
- *
- * @param[in] callid	The call identifier.
- * @param[in] result	The message processing result.
- * @param[in] answer	The message processing answer.
- * @param[in] answer_count The number of answer parameters.
- */
-void
-answer_call(ipc_callid_t callid, int result, ipc_call_t *answer,
-    int answer_count)
-{
-	/* Choose the most efficient answer function */
-	if (answer || (!answer_count)) {
-		switch (answer_count) {
+/** Answer a call.
+ *
+ * @param[in] callid Call identifier.
+ * @param[in] result Message processing result.
+ * @param[in] answer Message processing answer.
+ * @param[in] count  Number of answer parameters.
+ *
+ */
+void answer_call(ipc_callid_t callid, int result, ipc_call_t *answer,
+    size_t count)
+{
+	/* Choose the most efficient function */
+	if ((answer != NULL) || (count == 0)) {
+		switch (count) {
 		case 0:
 			ipc_answer_0(callid, (sysarg_t) result);
@@ -228,19 +228,19 @@
 }
 
-/** Refreshes answer structure and parameters count.
- *
- * Erases all attributes.
- *
- * @param[in,out] answer The message processing answer structure.
- * @param[in,out] answer_count The number of answer parameters.
- */
-void refresh_answer(ipc_call_t *answer, int *answer_count)
-{
-	if (answer_count)
-		*answer_count = 0;
-
-	if (answer) {
+/** Refresh answer structure and argument count.
+ *
+ * Erase all arguments.
+ *
+ * @param[in,out] answer Message processing answer structure.
+ * @param[in,out] count  Number of answer arguments.
+ *
+ */
+void refresh_answer(ipc_call_t *answer, size_t *count)
+{
+	if (count != NULL)
+		*count = 0;
+	
+	if (answer != NULL) {
 		IPC_SET_RETVAL(*answer, 0);
-		/* Just to be precise */
 		IPC_SET_IMETHOD(*answer, 0);
 		IPC_SET_ARG1(*answer, 0);
Index: uspace/lib/c/include/adt/char_map.h
===================================================================
--- uspace/lib/c/include/adt/char_map.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/adt/char_map.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -41,10 +41,10 @@
 
 /** Invalid assigned value used also if an&nbsp;entry does not exist. */
-#define CHAR_MAP_NULL	(-1)
+#define CHAR_MAP_NULL  (-1)
 
 /** Type definition of the character string to integer map.
  *  @see char_map
  */
-typedef struct char_map	char_map_t;
+typedef struct char_map char_map_t;
 
 /** Character string to integer map item.
@@ -56,5 +56,5 @@
 struct char_map {
 	/** Actually mapped character. */
-	char c;
+	uint8_t c;
 	/** Stored integral value. */
 	int value;
@@ -71,8 +71,8 @@
 extern int char_map_initialize(char_map_t *);
 extern void char_map_destroy(char_map_t *);
-extern int char_map_exclude(char_map_t *, const char *, size_t);
-extern int char_map_add(char_map_t *, const char *, size_t, const int);
-extern int char_map_find(const char_map_t *, const char *, size_t);
-extern int char_map_update(char_map_t *, const char *, size_t, const int);
+extern int char_map_exclude(char_map_t *, const uint8_t *, size_t);
+extern int char_map_add(char_map_t *, const uint8_t *, size_t, const int);
+extern int char_map_find(const char_map_t *, const uint8_t *, size_t);
+extern int char_map_update(char_map_t *, const uint8_t *, size_t, const int);
 
 #endif
Index: uspace/lib/c/include/adt/generic_char_map.h
===================================================================
--- uspace/lib/c/include/adt/generic_char_map.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/adt/generic_char_map.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -62,9 +62,9 @@
 	}; \
 	\
-	int name##_add(name##_t *, const char *, const size_t, type *); \
+	int name##_add(name##_t *, const uint8_t *, const size_t, type *); \
 	int name##_count(name##_t *); \
 	void name##_destroy(name##_t *); \
-	void name##_exclude(name##_t *, const char *, const size_t); \
-	type *name##_find(name##_t *, const char *, const size_t); \
+	void name##_exclude(name##_t *, const uint8_t *, const size_t); \
+	type *name##_find(name##_t *, const uint8_t *, const size_t); \
 	int name##_initialize(name##_t *); \
 	int name##_is_valid(name##_t *);
@@ -74,11 +74,12 @@
  * Should follow declaration with the same parameters.
  *
- * @param[in] name	Name of the map.
- * @param[in] type	Inner object type.
+ * @param[in] name Name of the map.
+ * @param[in] type Inner object type.
+ *
  */
 #define GENERIC_CHAR_MAP_IMPLEMENT(name, type) \
 	GENERIC_FIELD_IMPLEMENT(name##_items, type) \
 	\
-	int name##_add(name##_t *map, const char *name, const size_t length, \
+	int name##_add(name##_t *map, const uint8_t *name, const size_t length, \
 	     type *value) \
 	{ \
@@ -112,5 +113,5 @@
 	} \
 	\
-	void name##_exclude(name##_t *map, const char *name, \
+	void name##_exclude(name##_t *map, const uint8_t *name, \
 	    const size_t length) \
 	{ \
@@ -124,5 +125,5 @@
 	} \
 	\
-	type *name##_find(name##_t *map, const char *name, \
+	type *name##_find(name##_t *map, const uint8_t *name, \
 	    const size_t length) \
 	{ \
Index: uspace/lib/c/include/adt/measured_strings.h
===================================================================
--- uspace/lib/c/include/adt/measured_strings.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/adt/measured_strings.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -54,14 +54,14 @@
 struct measured_string {
 	/** Character string data. */
-	char *value;
+	uint8_t *value;
 	/** Character string length. */
 	size_t length;
 };
 
-extern measured_string_t *measured_string_create_bulk(const char *, size_t);
+extern measured_string_t *measured_string_create_bulk(const uint8_t *, size_t);
 extern measured_string_t *measured_string_copy(measured_string_t *);
-extern int measured_strings_receive(measured_string_t **, char **, size_t);
+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 **, char **, 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);
 
Index: uspace/lib/c/include/assert.h
===================================================================
--- uspace/lib/c/include/assert.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/assert.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -57,4 +57,6 @@
 			printf("Assertion failed (%s) at file '%s', " \
 			    "line %d.\n", #expr, __FILE__, __LINE__); \
+			stacktrace_print(); \
+			core(); \
 			abort(); \
 		} \
Index: uspace/lib/c/include/async_sess.h
===================================================================
--- uspace/lib/c/include/async_sess.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/async_sess.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -40,4 +40,5 @@
 typedef struct {
 	int sess_phone;		/**< Phone for cloning off the connections. */
+	sysarg_t connect_arg1;  /**< Argument for CONNECT_ME_TO. */
 	link_t conn_head;	/**< List of open data connections. */
 	link_t sess_link;	/**< Link in global list of open sessions. */
@@ -45,5 +46,5 @@
 
 extern void _async_sess_init(void);
-extern void async_session_create(async_sess_t *, int);
+extern void async_session_create(async_sess_t *, int, sysarg_t);
 extern void async_session_destroy(async_sess_t *);
 extern int async_exchange_begin(async_sess_t *);
Index: pace/lib/c/include/device/char.h
===================================================================
--- uspace/lib/c/include/device/char.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * 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_DEVICE_HW_RES_H_
-#define LIBC_DEVICE_HW_RES_H_
-
-typedef enum {
-	CHAR_READ_DEV = 0,
-	CHAR_WRITE_DEV
-} hw_res_funcs_t;
-
-ssize_t read_dev(int dev_phone, void *buf, size_t len);
-ssize_t write_dev(int dev_phone, void *buf, size_t len);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/device/char_dev.h
===================================================================
--- uspace/lib/c/include/device/char_dev.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/lib/c/include/device/char_dev.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,49 @@
+/*
+ * 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_DEVICE_CHAR_DEV_H_
+#define LIBC_DEVICE_CHAR_DEV_H_
+
+typedef enum {
+	CHAR_DEV_READ = 0,
+	CHAR_DEV_WRITE
+} char_dev_method_t;
+
+ssize_t char_dev_read(int dev_phone, void *buf, size_t len);
+ssize_t char_dev_write(int dev_phone, void *buf, size_t len);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/device/hw_res.h
===================================================================
--- uspace/lib/c/include/device/hw_res.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/device/hw_res.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -27,5 +27,5 @@
  */
  
- /** @addtogroup libc
+/** @addtogroup libc
  * @{
  */
@@ -39,12 +39,11 @@
 #include <bool.h>
 
-// HW resource provider interface
+/** HW resource provider interface */
+typedef enum {
+	HW_RES_GET_RESOURCE_LIST = 0,
+	HW_RES_ENABLE_INTERRUPT
+} hw_res_method_t;
 
-typedef enum {
-	GET_RESOURCE_LIST = 0,
-	ENABLE_INTERRUPT	
-} hw_res_funcs_t;
-
-/** HW resource types. */
+/** HW resource types */
 typedef enum {
 	INTERRUPT,
@@ -58,44 +57,44 @@
 } endianness_t;
 
-
-/** HW resource (e.g. interrupt, memory register, i/o register etc.). */
-typedef struct hw_resource {
+/** HW resource (e.g. interrupt, memory register, i/o register etc.) */
+typedef struct {
 	hw_res_type_t type;
 	union {
 		struct {
 			uint64_t address;
-			endianness_t endianness;			
-			size_t size;			
+			endianness_t endianness;
+			size_t size;
 		} mem_range;
+
 		struct {
 			uint64_t address;
-			endianness_t endianness;			
-			size_t size;			
+			endianness_t endianness;
+			size_t size;
 		} io_range;
+
 		struct {
-			int irq;			
-		} interrupt;		
-	} res;	
+			int irq;
+		} interrupt;
+	} res;
 } hw_resource_t;
 
-typedef struct hw_resource_list {
+typedef struct {
 	size_t count;
-	hw_resource_t *resources;	
+	hw_resource_t *resources;
 } hw_resource_list_t;
 
-static inline void clean_hw_resource_list(hw_resource_list_t *hw_res)
+static inline void hw_res_clean_resource_list(hw_resource_list_t *hw_res)
 {
-	if(NULL != hw_res->resources) {
+	if (hw_res->resources != NULL) {
 		free(hw_res->resources);
+
 		hw_res->resources = NULL;
 	}
-	hw_res->count = 0;	
+
+	hw_res->count = 0;
 }
 
-
-
-extern int get_hw_resources(int, hw_resource_list_t *);
-extern bool enable_interrupt(int);
-
+extern int hw_res_get_resource_list(int, hw_resource_list_t *);
+extern bool hw_res_enable_interrupt(int);
 
 #endif
Index: uspace/lib/c/include/fibril.h
===================================================================
--- uspace/lib/c/include/fibril.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/fibril.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -94,4 +94,5 @@
 extern void fibril_inc_sercount(void);
 extern void fibril_dec_sercount(void);
+extern int fibril_get_sercount(void);
 
 static inline int fibril_yield(void)
Index: uspace/lib/c/include/ipc/arp.h
===================================================================
--- uspace/lib/c/include/ipc/arp.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/ipc/arp.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -69,12 +69,10 @@
 /*@{*/
 
-/** Returns the protocol service message parameter.
- * @param[in] call The message call structure.
+/** Return the protocol service message parameter.
+ *
+ * @param[in] call Message call structure.
+ *
  */
-#define ARP_GET_NETIF(call) \
-	({ \
-		services_t service = (services_t) IPC_GET_ARG2(*call); \
-		service; \
-	})
+#define ARP_GET_NETIF(call) ((services_t) IPC_GET_ARG2(call))
 
 /*@}*/
Index: pace/lib/c/include/ipc/bus.h
===================================================================
--- uspace/lib/c/include/ipc/bus.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,47 +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 libcipc
- * @{
- */
-/** @file
- */ 
-
-#ifndef LIBC_BUS_H_
-#define LIBC_BUS_H_
-
-#include <ipc/ipc.h>
-
-typedef enum {
-	BUS_CLEAR_INTERRUPT = IPC_FIRST_USER_METHOD
-} bus_request_t;
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/ipc/dev_iface.h
===================================================================
--- uspace/lib/c/include/ipc/dev_iface.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/ipc/dev_iface.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -35,6 +35,6 @@
 #include <libarch/types.h>
 
-typedef enum {	
-	HW_RES_DEV_IFACE = 0,	
+typedef enum {
+	HW_RES_DEV_IFACE = 0,
 	CHAR_DEV_IFACE,
 
@@ -44,5 +44,4 @@
 	USBHC_DEV_IFACE,
 
-	// TODO add more interfaces
 	DEV_IFACE_MAX
 } dev_inferface_idx_t;
Index: uspace/lib/c/include/ipc/icmp.h
===================================================================
--- uspace/lib/c/include/ipc/icmp.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/ipc/icmp.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -82,83 +82,58 @@
 /*@{*/
 
-/** Returns the ICMP code message parameter.
+/** Return the ICMP code message parameter.
  *
- * @param[in] call	The message call structure.
+ * @param[in] call Message call structure.
+ *
  */
-#define ICMP_GET_CODE(call) \
-	({ \
-		icmp_code_t code = (icmp_code_t) IPC_GET_ARG1(*call); \
-		code; \
-	})
+#define ICMP_GET_CODE(call)  ((icmp_code_t) IPC_GET_ARG1(call))
 
-/** Returns the ICMP link MTU message parameter.
+/** Return the ICMP link MTU message parameter.
  *
- * @param[in] call	The message call structure.
+ * @param[in] call Message call structure.
+ *
  */
-#define ICMP_GET_MTU(call) \
-	({ \
-		icmp_param_t mtu = (icmp_param_t) IPC_GET_ARG3(*call); \
-		mtu; \
-	})
+#define ICMP_GET_MTU(call)  ((icmp_param_t) IPC_GET_ARG3(call))
 
-/** Returns the pointer message parameter.
+/** Return the pointer message parameter.
  *
- * @param[in] call	The message call structure.
+ * @param[in] call Message call structure.
+ *
  */
-#define ICMP_GET_POINTER(call) \
-	({ \
-		icmp_param_t pointer = (icmp_param_t) IPC_GET_ARG3(*call); \
-		pointer; \
-	})
+#define ICMP_GET_POINTER(call)  ((icmp_param_t) IPC_GET_ARG3(call))
 
-/** Returns the size message parameter.
+/** Return the size message parameter.
  *
- * @param[in] call	The message call structure.
+ * @param[in] call Message call structure.
+ *
  */
-#define ICMP_GET_SIZE(call) \
-	({ \
-		size_t size = (size_t) IPC_GET_ARG1(call); \
-		size; \
-	})
+#define ICMP_GET_SIZE(call)  ((size_t) IPC_GET_ARG1(call))
 
-/** Returns the timeout message parameter.
+/** Return the timeout message parameter.
  *
- * @param[in] call	The message call structure.
+ * @param[in] call Message call structure.
+ *
  */
-#define ICMP_GET_TIMEOUT(call) \
-	({ \
-		suseconds_t timeout = (suseconds_t) IPC_GET_ARG2(call); \
-		timeout; \
-	})
+#define ICMP_GET_TIMEOUT(call)  ((suseconds_t) IPC_GET_ARG2(call))
 
-/** Returns the time to live message parameter.
+/** Return the time to live message parameter.
  *
- * @param[in] call	The message call structure.
+ * @param[in] call Message call structure.
+ *
  */
-#define ICMP_GET_TTL(call) \
-	({ \
-		ip_ttl_t ttl = (ip_ttl_t) IPC_GET_ARG3(call); \
-		ttl; \
-	})
+#define ICMP_GET_TTL(call)  ((ip_ttl_t) IPC_GET_ARG3(call))
 
-/** Returns the type of service message parameter.
+/** Return the type of service message parameter.
  *
- * @param[in] call	The message call structure.
+ * @param[in] call Message call structure.
+ *
  */
-#define ICMP_GET_TOS(call) \
-	({ \
-		ip_tos_t tos = (ip_tos_t) IPC_GET_ARG4(call); \
-		tos; \
-	})
+#define ICMP_GET_TOS(call)  ((ip_tos_t) IPC_GET_ARG4(call))
 
-/** Returns the dont fragment message parameter.
+/** Return the dont fragment message parameter.
  *
- * @param[in] call	The message call structure.
+ * @param[in] call Message call structure.
  */
-#define ICMP_GET_DONT_FRAGMENT(call) \
-	({ \
-		int dont_fragment = (int) IPC_GET_ARG5(call); \
-		dont_fragment; \
-	})
+#define ICMP_GET_DONT_FRAGMENT(call)  ((int) IPC_GET_ARG5(call))
 
 /*@}*/
Index: uspace/lib/c/include/ipc/il.h
===================================================================
--- uspace/lib/c/include/ipc/il.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/ipc/il.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -75,12 +75,16 @@
 
 /** Return the protocol number message parameter.
- * @param[in] call The message call structure.
+ *
+ * @param[in] call Message call structure.
+ *
  */
-#define IL_GET_PROTO(call)	(int) IPC_GET_ARG1(*call)
+#define IL_GET_PROTO(call)  ((int) IPC_GET_ARG1(call))
 
 /** Return the registering service message parameter.
- * @param[in] call The message call structure.
+ *
+ * @param[in] call Message call structure.
+ *
  */
-#define IL_GET_SERVICE(call)	(services_t) IPC_GET_ARG2(*call)
+#define IL_GET_SERVICE(call)  ((services_t) IPC_GET_ARG2(call))
 
 /*@}*/
Index: uspace/lib/c/include/ipc/ip.h
===================================================================
--- uspace/lib/c/include/ipc/ip.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/ipc/ip.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -51,12 +51,15 @@
 	 */
 	NET_IP_ADD_ROUTE = NET_IP_FIRST,
+	
 	/** Gets the actual route information.
 	 * @see ip_get_route()
 	 */
 	NET_IP_GET_ROUTE,
+	
 	/** Processes the received error notification.
 	 * @see ip_received_error_msg()
 	 */
 	NET_IP_RECEIVED_ERROR,
+	
 	/** Sets the default gateway.
 	 * @see ip_set_default_gateway()
@@ -68,51 +71,53 @@
 /*@{*/
 
-/** Returns the address message parameter.
- * @param[in] call The message call structure.
+/** Return the address message parameter.
+ *
+ * @param[in] call Message call structure.
+ *
  */
 #define IP_GET_ADDRESS(call) \
 	({ \
 		in_addr_t addr; \
-		addr.s_addr = IPC_GET_ARG3(*call); \
+		addr.s_addr = IPC_GET_ARG3(call); \
 		addr; \
 	})
 
-/** Returns the gateway message parameter.
- * @param[in] call The message call structure.
+/** Return the gateway message parameter.
+ *
+ * @param[in] call Message call structure.
+ *
  */
 #define IP_GET_GATEWAY(call) \
 	({ \
 		in_addr_t addr; \
-		addr.s_addr = IPC_GET_ARG2(*call); \
+		addr.s_addr = IPC_GET_ARG2(call); \
 		addr; \
 	})
 
-/** Sets the header length in the message answer.
- * @param[out] answer The message answer structure.
+/** Set the header length in the message answer.
+ *
+ * @param[out] answer Message answer structure.
+ *
  */
-#define IP_SET_HEADERLEN(answer, value) \
-	do { \
-		sysarg_t argument = (sysarg_t) (value); \
-		IPC_SET_ARG2(*answer, argument); \
-	} while (0)
+#define IP_SET_HEADERLEN(answer, value)  IPC_SET_ARG2(answer, (sysarg_t) (value))
 
-/** Returns the network mask message parameter.
- * @param[in] call The message call structure.
+/** Return the network mask message parameter.
+ *
+ * @param[in] call Message call structure.
+ *
  */
 #define IP_GET_NETMASK(call) \
 	({ \
 		in_addr_t addr; \
-		addr.s_addr = IPC_GET_ARG4(*call); \
+		addr.s_addr = IPC_GET_ARG4(call); \
 		addr; \
 	})
 
-/** Returns the protocol message parameter.
- * @param[in] call The message call structure.
+/** Return the protocol message parameter.
+ *
+ * @param[in] call Message call structure.
+ *
  */
-#define IP_GET_PROTOCOL(call) \
-	({ \
-		ip_protocol_t protocol = (ip_protocol_t) IPC_GET_ARG1(*call); \
-		protocol; \
-	})
+#define IP_GET_PROTOCOL(call)  ((ip_protocol_t) IPC_GET_ARG1(call))
 
 /*@}*/
Index: uspace/lib/c/include/ipc/irc.h
===================================================================
--- uspace/lib/c/include/ipc/irc.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/lib/c/include/ipc/irc.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,48 @@
+/*
+ * 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 libcipc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_IRC_H_
+#define LIBC_IRC_H_
+
+#include <ipc/ipc.h>
+
+typedef enum {
+	IRC_ENABLE_INTERRUPT = IPC_FIRST_USER_METHOD,
+	IRC_CLEAR_INTERRUPT
+} irc_request_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/net.h
===================================================================
--- uspace/lib/c/include/ipc/net.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/ipc/net.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -44,8 +44,10 @@
 #include <net/packet.h>
 
-/** Returns a value indicating whether the value is in the interval.
- * @param[in] item	The value to be checked.
- * @param[in] first_inclusive The first value in the interval inclusive.
- * @param[in] last_exclusive The first value after the interval.
+/** Return a value indicating whether the value is in the interval.
+ *
+ * @param[in] item            Value to be checked.
+ * @param[in] first_inclusive First value in the interval inclusive.
+ * @param[in] last_exclusive  First value after the interval.
+ *
  */
 #define IS_IN_INTERVAL(item, first_inclusive, last_exclusive) \
@@ -55,42 +57,17 @@
 /*@{*/
 
-/** The number of ARP messages. */
-#define NET_ARP_COUNT		5
-
-/** The number of Ethernet messages. */
-#define NET_ETH_COUNT		0
-
-/** The number of ICMP messages. */
-#define NET_ICMP_COUNT		6
-
-/** The number of inter-network messages. */
-#define NET_IL_COUNT		6
-
-/** The number of IP messages. */
-#define NET_IP_COUNT		4
-
-/** The number of general networking messages. */
-#define NET_NET_COUNT		3
-
-/** The number of network interface driver messages. */
-#define NET_NETIF_COUNT		6
-
-/** The number of network interface layer messages. */
-#define NET_NIL_COUNT		7
-
-/** The number of packet management system messages. */
-#define NET_PACKET_COUNT	5
-
-/** The number of socket messages. */
-#define NET_SOCKET_COUNT	14
-
-/** The number of TCP messages. */
-#define NET_TCP_COUNT		0
-
-/** The number of transport layer messages. */
-#define NET_TL_COUNT		1
-
-/** The number of UDP messages. */
-#define NET_UDP_COUNT		0
+#define NET_ARP_COUNT     5   /**< Number of ARP messages. */
+#define NET_ETH_COUNT     0   /**< Number of Ethernet messages. */
+#define NET_ICMP_COUNT    6   /**< Number of ICMP messages. */
+#define NET_IL_COUNT      6   /**< Number of inter-network messages. */
+#define NET_IP_COUNT      4   /**< Number of IP messages. */
+#define NET_NET_COUNT     3   /**< Number of general networking messages. */
+#define NET_NETIF_COUNT   6   /**< Number of network interface driver messages. */
+#define NET_NIL_COUNT     7   /**< Number of network interface layer messages. */
+#define NET_PACKET_COUNT  5   /**< Number of packet management system messages. */
+#define NET_SOCKET_COUNT  14  /**< Number of socket messages. */
+#define NET_TCP_COUNT     0   /**< Number of TCP messages. */
+#define NET_TL_COUNT      1   /**< Number of transport layer messages. */
+#define NET_UDP_COUNT     0   /**< Number of UDP messages. */
 
 /*@}*/
@@ -100,173 +77,195 @@
 /*@{*/
 
-/** The first networking message. */
-#define NET_FIRST		2000
-
-/** The first network interface layer message. */
-#define NET_NETIF_FIRST		NET_FIRST
-
-/** The last network interface layer message. */
-#define NET_NETIF_LAST		(NET_NETIF_FIRST + NET_NETIF_COUNT)
-
-/** The first general networking message. */
-#define NET_NET_FIRST		(NET_NETIF_LAST + 0)
-
-/** The last general networking message. */
-#define NET_NET_LAST		(NET_NET_FIRST + NET_NET_COUNT)
-
-/** The first network interface layer message. */
-#define NET_NIL_FIRST		(NET_NET_LAST + 0)
-
-/** The last network interface layer message. */
-#define NET_NIL_LAST		(NET_NIL_FIRST + NET_NIL_COUNT)
-
-/** The first Ethernet message. */
-#define NET_ETH_FIRST		(NET_NIL_LAST + 0)
-
-/** The last Ethernet message. */
-#define NET_ETH_LAST		(NET_ETH_FIRST + NET_ETH_COUNT)
-
-/** The first inter-network message. */
-#define NET_IL_FIRST		(NET_ETH_LAST + 0)
-
-/** The last inter-network message. */
-#define NET_IL_LAST		(NET_IL_FIRST + NET_IL_COUNT)
-
-/** The first IP message. */
-#define NET_IP_FIRST		(NET_IL_LAST + 0)
-
-/** The last IP message. */
-#define NET_IP_LAST		(NET_IP_FIRST + NET_IP_COUNT)
-
-/** The first ARP message. */
-#define NET_ARP_FIRST		(NET_IP_LAST + 0)
-
-/** The last ARP message. */
-#define NET_ARP_LAST		(NET_ARP_FIRST + NET_ARP_COUNT)
-
-/** The first ICMP message. */
-#define NET_ICMP_FIRST		(NET_ARP_LAST + 0)
-
-/** The last ICMP message. */
-#define NET_ICMP_LAST		(NET_ICMP_FIRST + NET_ICMP_COUNT)
-
-/** The first ICMP message. */
-#define NET_TL_FIRST		(NET_ICMP_LAST + 0)
-
-/** The last ICMP message. */
-#define NET_TL_LAST		(NET_TL_FIRST + NET_TL_COUNT)
-
-/** The first UDP message. */
-#define NET_UDP_FIRST		(NET_TL_LAST + 0)
-
-/** The last UDP message. */
-#define NET_UDP_LAST		(NET_UDP_FIRST + NET_UDP_COUNT)
-
-/** The first TCP message. */
-#define NET_TCP_FIRST		(NET_UDP_LAST + 0)
-
-/** The last TCP message. */
-#define NET_TCP_LAST		(NET_TCP_FIRST + NET_TCP_COUNT)
-
-/** The first socket message. */
-#define NET_SOCKET_FIRST	(NET_TCP_LAST + 0)
-
-/** The last socket message. */
-#define NET_SOCKET_LAST		(NET_SOCKET_FIRST + NET_SOCKET_COUNT)
-
-/** The first packet management system message. */
-#define NET_PACKET_FIRST	(NET_SOCKET_LAST + 0)
-
-/** The last packet management system message. */
-#define NET_PACKET_LAST		(NET_PACKET_FIRST + NET_PACKET_COUNT)
-
-/** The last networking message. */
-#define NET_LAST		NET_PACKET_LAST
-
-/** The number of networking messages. */
-#define NET_COUNT		(NET_LAST - NET_FIRST)
-
-/** Returns a value indicating whether the IPC call is a generic networking
- * message.
- * @param[in] call The IPC call to be checked.
+
+/** First networking message. */
+#define NET_FIRST  2000
+
+/** First network interface layer message. */
+#define NET_NETIF_FIRST  NET_FIRST
+
+/** Last network interface layer message. */
+#define NET_NETIF_LAST  (NET_NETIF_FIRST + NET_NETIF_COUNT)
+
+/** First general networking message. */
+#define NET_NET_FIRST  (NET_NETIF_LAST + 0)
+
+/** Last general networking message. */
+#define NET_NET_LAST  (NET_NET_FIRST + NET_NET_COUNT)
+
+/** First network interface layer message. */
+#define NET_NIL_FIRST  (NET_NET_LAST + 0)
+
+/** Last network interface layer message. */
+#define NET_NIL_LAST  (NET_NIL_FIRST + NET_NIL_COUNT)
+
+/** First Ethernet message. */
+#define NET_ETH_FIRST  (NET_NIL_LAST + 0)
+
+/** Last Ethernet message. */
+#define NET_ETH_LAST  (NET_ETH_FIRST + NET_ETH_COUNT)
+
+/** First inter-network message. */
+#define NET_IL_FIRST  (NET_ETH_LAST + 0)
+
+/** Last inter-network message. */
+#define NET_IL_LAST  (NET_IL_FIRST + NET_IL_COUNT)
+
+/** First IP message. */
+#define NET_IP_FIRST  (NET_IL_LAST + 0)
+
+/** Last IP message. */
+#define NET_IP_LAST  (NET_IP_FIRST + NET_IP_COUNT)
+
+/** First ARP message. */
+#define NET_ARP_FIRST  (NET_IP_LAST + 0)
+
+/** Last ARP message. */
+#define NET_ARP_LAST  (NET_ARP_FIRST + NET_ARP_COUNT)
+
+/** First ICMP message. */
+#define NET_ICMP_FIRST  (NET_ARP_LAST + 0)
+
+/** Last ICMP message. */
+#define NET_ICMP_LAST  (NET_ICMP_FIRST + NET_ICMP_COUNT)
+
+/** First ICMP message. */
+#define NET_TL_FIRST  (NET_ICMP_LAST + 0)
+
+/** Last ICMP message. */
+#define NET_TL_LAST  (NET_TL_FIRST + NET_TL_COUNT)
+
+/** First UDP message. */
+#define NET_UDP_FIRST  (NET_TL_LAST + 0)
+
+/** Last UDP message. */
+#define NET_UDP_LAST  (NET_UDP_FIRST + NET_UDP_COUNT)
+
+/** First TCP message. */
+#define NET_TCP_FIRST  (NET_UDP_LAST + 0)
+
+/** Last TCP message. */
+#define NET_TCP_LAST  (NET_TCP_FIRST + NET_TCP_COUNT)
+
+/** First socket message. */
+#define NET_SOCKET_FIRST  (NET_TCP_LAST + 0)
+
+/** Last socket message. */
+#define NET_SOCKET_LAST  (NET_SOCKET_FIRST + NET_SOCKET_COUNT)
+
+/** First packet management system message. */
+#define NET_PACKET_FIRST  (NET_SOCKET_LAST + 0)
+
+/** Last packet management system message. */
+#define NET_PACKET_LAST  (NET_PACKET_FIRST + NET_PACKET_COUNT)
+
+/** Last networking message. */
+#define NET_LAST  NET_PACKET_LAST
+
+/** Number of networking messages. */
+#define NET_COUNT  (NET_LAST - NET_FIRST)
+
+/** Check if the IPC call is a generic networking message.
+ *
+ * @param[in] call IPC call to be checked.
+ *
  */
 #define IS_NET_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_IMETHOD(*call), NET_FIRST, NET_LAST)
-
-/** Returns a value indicating whether the IPC call is an ARP message.
- * @param[in] call The IPC call to be checked.
+	IS_IN_INTERVAL(IPC_GET_IMETHOD(call), NET_FIRST, NET_LAST)
+
+/** Check if the IPC call is an ARP message.
+ *
+ * @param[in] call IPC call to be checked.
+ *
  */
 #define IS_NET_ARP_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_IMETHOD(*call), NET_ARP_FIRST, NET_ARP_LAST)
-
-/** Returns a value indicating whether the IPC call is an Ethernet message.
- * @param[in] call The IPC call to be checked.
+	IS_IN_INTERVAL(IPC_GET_IMETHOD(call), NET_ARP_FIRST, NET_ARP_LAST)
+
+/** Check if the IPC call is an Ethernet message.
+ *
+ * @param[in] call IPC call to be checked.
+ *
  */
 #define IS_NET_ETH_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_IMETHOD(*call), NET_ETH_FIRST, NET_ETH_LAST)
-
-/** Returns a value indicating whether the IPC call is an ICMP message.
- * @param[in] call The IPC call to be checked.
+	IS_IN_INTERVAL(IPC_GET_IMETHOD(call), NET_ETH_FIRST, NET_ETH_LAST)
+
+/** Check if the IPC call is an ICMP message.
+ *
+ * @param[in] call IPC call to be checked.
+ *
  */
 #define IS_NET_ICMP_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_IMETHOD(*call), NET_ICMP_FIRST, NET_ICMP_LAST)
-
-/** Returns a value indicating whether the IPC call is an inter-network layer
- * message.
- * @param[in] call The IPC call to be checked.
+	IS_IN_INTERVAL(IPC_GET_IMETHOD(call), NET_ICMP_FIRST, NET_ICMP_LAST)
+
+/** Check if the IPC call is an inter-network layer message.
+ *
+ * @param[in] call IPC call to be checked.
+ *
  */
 #define IS_NET_IL_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_IMETHOD(*call), NET_IL_FIRST, NET_IL_LAST)
-
-/** Returns a value indicating whether the IPC call is an IP message.
- * @param[in] call The IPC call to be checked.
+	IS_IN_INTERVAL(IPC_GET_IMETHOD(call), NET_IL_FIRST, NET_IL_LAST)
+
+/** Check if the IPC call is an IP message.
+ *
+ * @param[in] call IPC call to be checked.
+ *
  */
 #define IS_NET_IP_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_IMETHOD(*call), NET_IP_FIRST, NET_IP_LAST)
-
-/** Returns a value indicating whether the IPC call is a generic networking
- * message.
- * @param[in] call The IPC call to be checked.
+	IS_IN_INTERVAL(IPC_GET_IMETHOD(call), NET_IP_FIRST, NET_IP_LAST)
+
+/** Check if the IPC call is a generic networking message.
+ *
+ * @param[in] call IPC call to be checked.
+ *
  */
 #define IS_NET_NET_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_IMETHOD(*call), NET_NET_FIRST, NET_NET_LAST)
-
-/** Returns a value indicating whether the IPC call is a network interface layer
- * message.
- * @param[in] call The IPC call to be checked.
+	IS_IN_INTERVAL(IPC_GET_IMETHOD(call), NET_NET_FIRST, NET_NET_LAST)
+
+/** Check if the IPC call is a network interface layer message.
+ *
+ * @param[in] call IPC call to be checked.
+ *
  */
 #define IS_NET_NIL_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_IMETHOD(*call), NET_NIL_FIRST, NET_NIL_LAST)
-
-/** Returns a value indicating whether the IPC call is a packet manaagement
- * system message.
- * @param[in] call The IPC call to be checked.
+	IS_IN_INTERVAL(IPC_GET_IMETHOD(call), NET_NIL_FIRST, NET_NIL_LAST)
+
+/** Check if the IPC call is a packet manaagement system message.
+ *
+ * @param[in] call IPC call to be checked.
+ *
  */
 #define IS_NET_PACKET_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_IMETHOD(*call), NET_PACKET_FIRST, NET_PACKET_LAST)
-
-/** Returns a value indicating whether the IPC call is a socket message.
- * @param[in] call The IPC call to be checked.
+	IS_IN_INTERVAL(IPC_GET_IMETHOD(call), NET_PACKET_FIRST, NET_PACKET_LAST)
+
+/** Check if the IPC call is a socket message.
+ *
+ * @param[in] call IPC call to be checked.
+ *
  */
 #define IS_NET_SOCKET_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_IMETHOD(*call), NET_SOCKET_FIRST, NET_SOCKET_LAST)
-
-/** Returns a value indicating whether the IPC call is a TCP message.
- * @param[in] call The IPC call to be checked.
+	IS_IN_INTERVAL(IPC_GET_IMETHOD(call), NET_SOCKET_FIRST, NET_SOCKET_LAST)
+
+/** Check if the IPC call is a TCP message.
+ *
+ * @param[in] call IPC call to be checked.
+ *
  */
 #define IS_NET_TCP_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_IMETHOD(*call), NET_TCP_FIRST, NET_TCP_LAST)
-
-/** Returns a value indicating whether the IPC call is a transport layer message.
- * @param[in] call The IPC call to be checked.
+	IS_IN_INTERVAL(IPC_GET_IMETHOD(call), NET_TCP_FIRST, NET_TCP_LAST)
+
+/** Check if the IPC call is a transport layer message.
+ *
+ * @param[in] call IPC call to be checked.
+ *
  */
 #define IS_NET_TL_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_IMETHOD(*call), NET_TL_FIRST, NET_TL_LAST)
-
-/** Returns a value indicating whether the IPC call is a UDP message.
- * @param[in] call The IPC call to be checked.
+	IS_IN_INTERVAL(IPC_GET_IMETHOD(call), NET_TL_FIRST, NET_TL_LAST)
+
+/** Check if the IPC call is a UDP message.
+ *
+ * @param[in] call IPC call to be checked.
+ *
  */
 #define IS_NET_UDP_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_IMETHOD(*call), NET_UDP_FIRST, NET_UDP_LAST)
+	IS_IN_INTERVAL(IPC_GET_IMETHOD(call), NET_UDP_FIRST, NET_UDP_LAST)
 
 /*@}*/
@@ -275,138 +274,113 @@
 /*@{*/
 
-/** Returns the device identifier message argument.
- * @param[in] call The message call structure.
- */
-#define IPC_GET_DEVICE(call) \
-	({ \
-		device_id_t device_id = (device_id_t) IPC_GET_ARG1(*call); \
-		device_id; \
-	})
-
-/** Returns the packet identifier message argument.
- * @param[in] call The message call structure.
- */
-#define IPC_GET_PACKET(call) \
-	({ \
-		packet_id_t packet_id = (packet_id_t) IPC_GET_ARG2(*call); \
-		packet_id; \
-	})
-
-/** Returns the count message argument.
- * @param[in] call The message call structure.
- */
-#define IPC_GET_COUNT(call) \
-	({ \
-		size_t size = (size_t) IPC_GET_ARG2(*call); \
-		size; \
-	})
-
-/** Returns the device state message argument.
- * @param[in] call The message call structure.
- */
-#define IPC_GET_STATE(call) \
-	({ \
-		device_state_t state = (device_state_t) IPC_GET_ARG2(*call); \
-		state; \
-	})
-
-/** Returns the maximum transmission unit message argument.
- * @param[in] call The message call structure.
- */
-#define IPC_GET_MTU(call) \
-	({ \
-		size_t size = (size_t) IPC_GET_ARG2(*call); \
-		size; \
-	})
-
-/** Returns the device driver service message argument.
- * @param[in] call The message call structure.
- */
-#define IPC_GET_SERVICE(call) \
-	({ \
-		services_t service = (services_t) IPC_GET_ARG3(*call); \
-		service; \
-	})
-
-/** Returns the target service message argument.
- * @param[in] call The message call structure.
- */
-#define IPC_GET_TARGET(call) \
-	({ \
-		services_t service = (services_t) IPC_GET_ARG3(*call); \
-		service; \
-	})
-
-/** Returns the sender service message argument.
- * @param[in] call The message call structure.
- */
-#define IPC_GET_SENDER(call) \
-	({ \
-		services_t service = (services_t) IPC_GET_ARG3(*call); \
-		service; \
-	})
-
-/** Returns the error service message argument.
- * @param[in] call The message call structure.
- */
-#define IPC_GET_ERROR(call) \
-	({ \
-		services_t service = (services_t) IPC_GET_ARG4(*call); \
-		service; \
-	})
-
-/** Returns the phone message argument.
- * @param[in] call The message call structure.
- */
-#define IPC_GET_PHONE(call) \
-	({ \
-		int phone = (int) IPC_GET_ARG5(*call); \
-		phone; \
-	})
-
-/** Sets the device identifier in the message answer.
- * @param[out] answer The message answer structure.
- */
-#define IPC_SET_DEVICE(answer, value) \
-	do { \
-		sysarg_t argument = (sysarg_t) (value); \
-		IPC_SET_ARG1(*answer, argument); \
-	} while (0)
-
-/** Sets the minimum address length in the message answer.
- * @param[out] answer The message answer structure.
- */
-#define IPC_SET_ADDR(answer, value) \
-	do { \
-		sysarg_t argument = (sysarg_t) (value); \
-		IPC_SET_ARG1(*answer, argument); \
-	} while (0)
-
-/** Sets the minimum prefix size in the message answer.
- * @param[out] answer The message answer structure.
- */
-#define IPC_SET_PREFIX(answer, value) \
-	do { \
-		sysarg_t argument = (sysarg_t) (value); \
-		IPC_SET_ARG2(*answer, argument); \
-	} while (0)
-
-/** Sets the maximum content size in the message answer.
- * @param[out] answer The message answer structure.
- */
-#define IPC_SET_CONTENT(answer, value) \
-	do { \
-		sysarg_t argument = (sysarg_t) (value); \
-		IPC_SET_ARG3(*answer, argument); \
-	} while (0)
-
-/** Sets the minimum suffix size in the message answer.
- * @param[out] answer The message answer structure.
- */
-#define IPC_SET_SUFFIX(answer, value) \
-	do { \
-		sysarg_t argument = (sysarg_t) (value); \
-		IPC_SET_ARG4(*answer, argument); \
-	} while (0)
+/** Return the device identifier message argument.
+ *
+ * @param[in] call Message call structure.
+ *
+ */
+#define IPC_GET_DEVICE(call)  ((device_id_t) IPC_GET_ARG1(call))
+
+/** Return the packet identifier message argument.
+ *
+ * @param[in] call Message call structure.
+ *
+ */
+#define IPC_GET_PACKET(call)  ((packet_id_t) IPC_GET_ARG2(call))
+
+/** Return the count message argument.
+ *
+ * @param[in] call Message call structure.
+ *
+ */
+#define IPC_GET_COUNT(call)  ((size_t) IPC_GET_ARG2(call))
+
+/** Return the device state message argument.
+ *
+ * @param[in] call Message call structure.
+ *
+ */
+#define IPC_GET_STATE(call)  ((device_state_t) IPC_GET_ARG2(call))
+
+/** Return the maximum transmission unit message argument.
+ *
+ * @param[in] call Message call structure.
+ *
+ */
+#define IPC_GET_MTU(call)  ((size_t) IPC_GET_ARG2(call))
+
+/** Return the device driver service message argument.
+ *
+ * @param[in] call Message call structure.
+ *
+ */
+#define IPC_GET_SERVICE(call)  ((services_t) IPC_GET_ARG3(call))
+
+/** Return the target service message argument.
+ *
+ * @param[in] call Message call structure.
+ *
+ */
+#define IPC_GET_TARGET(call)  ((services_t) IPC_GET_ARG3(call))
+
+/** Return the sender service message argument.
+ *
+ * @param[in] call Message call structure.
+ *
+ */
+#define IPC_GET_SENDER(call)  ((services_t) IPC_GET_ARG3(call))
+
+/** Return the error service message argument.
+ &
+ * @param[in] call Message call structure.
+ *
+ */
+#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.
+ *
+ * @param[out] answer Message answer structure.
+ * @param[in]  value  Value to set.
+ *
+ */
+#define IPC_SET_DEVICE(answer, value)  IPC_SET_ARG1(answer, (sysarg_t) (value))
+
+/** Set the minimum address length in the message answer.
+ *
+ * @param[out] answer Message answer structure.
+ * @param[in]  value  Value to set.
+ *
+ */
+#define IPC_SET_ADDR(answer, value)  IPC_SET_ARG1(answer, (sysarg_t) (value))
+
+/** Set the minimum prefix size in the message answer.
+ *
+ * @param[out] answer Message answer structure.
+ * @param[in]  value  Value to set.
+ *
+ */
+#define IPC_SET_PREFIX(answer, value)  IPC_SET_ARG2(answer, (sysarg_t) (value))
+
+/** Set the maximum content size in the message answer.
+ *
+ * @param[out] answer Message answer structure.
+ * @param[in]  value  Value to set.
+ *
+ */
+#define IPC_SET_CONTENT(answer, value)  IPC_SET_ARG3(answer, (sysarg_t) (value))
+
+/** Set the minimum suffix size in the message answer.
+ *
+ * @param[out] answer Message answer structure.
+ * @param[in]  value  Value to set.
+ *
+ */
+#define IPC_SET_SUFFIX(answer, value)  IPC_SET_ARG4(answer, (sysarg_t) (value))
 
 /*@}*/
Index: uspace/lib/c/include/ipc/netif.h
===================================================================
--- uspace/lib/c/include/ipc/netif.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/ipc/netif.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -47,20 +47,25 @@
 	 */
 	NET_NETIF_PROBE = NET_NETIF_FIRST,
+	
 	/** Send packet message.
 	 * @see netif_send_msg()
 	 */
 	NET_NETIF_SEND,
+	
 	/** Start device message.
 	 * @see netif_start_req()
 	 */
 	NET_NETIF_START,
+	
 	/** Get device usage statistics message.
 	 * @see netif_stats_req()
 	 */
 	NET_NETIF_STATS,
+	
 	/** Stop device message.
 	 * @see netif_stop_req()
 	 */
 	NET_NETIF_STOP,
+	
 	/** Get device address message.
 	 * @see netif_get_addr_req()
@@ -73,20 +78,16 @@
 
 /** Return the interrupt number message parameter.
- * @param[in] call The message call structure.
+ *
+ * @param[in] call Mmessage call structure.
+ *
  */
-#define NETIF_GET_IRQ(call) \
-	({ \
-		int irq = (int) IPC_GET_ARG2(*call); \
-		irq; \
-	})
+#define NETIF_GET_IRQ(call) ((int) IPC_GET_ARG2(call))
 
 /** Return the input/output address message parameter.
- * @param[in] call The message call structure.
+ *
+ * @param[in] call Message call structure.
+ *
  */
-#define NETIF_GET_IO(call) \
-	({ \
-		int io = (int) IPC_GET_ARG3(*call); \
-		io; \
-	})
+#define NETIF_GET_IO(call) ((void *) IPC_GET_ARG3(call))
 
 /*@}*/
Index: uspace/lib/c/include/ipc/nil.h
===================================================================
--- uspace/lib/c/include/ipc/nil.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/ipc/nil.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -77,9 +77,5 @@
 
 /** Return the protocol service message parameter. */
-#define NIL_GET_PROTO(call) \
-	({ \
-		services_t service = (services_t) IPC_GET_ARG2(*call); \
-		service; \
-	})
+#define NIL_GET_PROTO(call)  ((services_t) IPC_GET_ARG2(call))
 
 /*@}*/
Index: uspace/lib/c/include/ipc/packet.h
===================================================================
--- uspace/lib/c/include/ipc/packet.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/ipc/packet.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -70,21 +70,21 @@
 } packet_messages;
 
-/** Returns the protocol service message parameter. */
-#define ARP_GET_PROTO(call)	(services_t) IPC_GET_ARG2(*call)
+/** Return the protocol service message parameter. */
+#define ARP_GET_PROTO(call)  ((services_t) IPC_GET_ARG2(call))
 
-/** Returns the packet identifier message parameter. */
-#define IPC_GET_ID(call)	(packet_id_t) IPC_GET_ARG1(*call)
+/** Return the packet identifier message parameter. */
+#define IPC_GET_ID(call)  ((packet_id_t) IPC_GET_ARG1(call))
 
-/** Returns the maximal content length message parameter. */
-#define IPC_GET_CONTENT(call)	(size_t) IPC_GET_ARG1(*call)
+/** Return the maximal content length message parameter. */
+#define IPC_GET_CONTENT(call)  ((size_t) IPC_GET_ARG1(call))
 
-/** Returns the maximal address length message parameter. */
-#define IPC_GET_ADDR_LEN(call)	(size_t) IPC_GET_ARG2(*call)
+/** Return the maximal address length message parameter. */
+#define IPC_GET_ADDR_LEN(call)  ((size_t) IPC_GET_ARG2(call))
 
-/** Returns the maximal prefix length message parameter. */
-#define IPC_GET_PREFIX(call)	(size_t) IPC_GET_ARG3(*call)
+/** Return the maximal prefix length message parameter. */
+#define IPC_GET_PREFIX(call)  ((size_t) IPC_GET_ARG3(call))
 
-/** Returns the maximal suffix length message parameter. */
-#define IPC_GET_SUFFIX(call)	(size_t) IPC_GET_ARG4(*call)
+/** Return the maximal suffix length message parameter. */
+#define IPC_GET_SUFFIX(call)  ((size_t) IPC_GET_ARG4(call))
 
 #endif
Index: uspace/lib/c/include/ipc/services.h
===================================================================
--- uspace/lib/c/include/ipc/services.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/ipc/services.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -49,4 +49,6 @@
 	SERVICE_FHC,
 	SERVICE_OBIO,
+	SERVICE_APIC,
+	SERVICE_I8259,
 	SERVICE_CLIPBOARD,
 	SERVICE_NETWORKING,
Index: uspace/lib/c/include/mem.h
===================================================================
--- uspace/lib/c/include/mem.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/mem.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -44,5 +44,5 @@
 extern void *memmove(void *, const void *, size_t);
 
-extern int bcmp(const char *, const char *, size_t);
+extern int bcmp(const void *, const void *, size_t);
 
 #endif
Index: uspace/lib/c/include/net/in.h
===================================================================
--- uspace/lib/c/include/net/in.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/net/in.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -43,10 +43,10 @@
 
 /** INET string address maximum length. */
-#define INET_ADDRSTRLEN		(4 * 3 + 3 + 1)
+#define INET_ADDRSTRLEN  (4 * 3 + 3 + 1)
 
 /** Type definition of the INET address.
  * @see in_addr
  */
-typedef struct in_addr		in_addr_t;
+typedef struct in_addr in_addr_t;
 
 /** Type definition of the INET socket address.
Index: uspace/lib/c/include/net/modules.h
===================================================================
--- uspace/lib/c/include/net/modules.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/net/modules.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -51,10 +51,12 @@
 /** Connect to the needed module function type definition.
  *
- * @param[in] need	The needed module service.
- * @return		The phone of the needed service.
+ * @param[in] need The needed module service.
+ *
+ * @return The phone of the needed service.
+ *
  */
 typedef int connect_module_t(services_t need);
 
-extern void answer_call(ipc_callid_t, int, ipc_call_t *, int);
+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,
     async_client_conn_t);
@@ -64,5 +66,5 @@
 extern int connect_to_service_timeout(services_t, suseconds_t);
 extern int data_reply(void *, size_t);
-extern void refresh_answer(ipc_call_t *, int *);
+extern void refresh_answer(ipc_call_t *, size_t *);
 
 #endif
Index: uspace/lib/c/include/stdlib.h
===================================================================
--- uspace/lib/c/include/stdlib.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/c/include/stdlib.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -46,4 +46,7 @@
 	} while (0)
 
+#define core() \
+	*((int *) 0) = 0xbadbad;
+
 #define exit(status)  _exit((status))
 
Index: uspace/lib/drv/Makefile
===================================================================
--- uspace/lib/drv/Makefile	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/drv/Makefile	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -35,8 +35,8 @@
 	generic/driver.c \
 	generic/dev_iface.c \
-	generic/remote_res.c \
+	generic/remote_char_dev.c \
+	generic/remote_hw_res.c \
 	generic/remote_usb.c \
-	generic/remote_usbhc.c \
-	generic/remote_char.c
+	generic/remote_usbhc.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/drv/generic/dev_iface.c
===================================================================
--- uspace/lib/drv/generic/dev_iface.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/drv/generic/dev_iface.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -36,7 +36,9 @@
  */
 
+#include <assert.h>
+
 #include "dev_iface.h"
-#include "remote_res.h"
-#include "remote_char.h"
+#include "remote_hw_res.h"
+#include "remote_char_dev.h"
 #include "remote_usb.h"
 #include "remote_usbhc.h"
@@ -44,6 +46,6 @@
 static iface_dipatch_table_t remote_ifaces = {
 	.ifaces = {
-		&remote_res_iface,
-		&remote_char_iface,
+		&remote_hw_res_iface,
+		&remote_char_dev_iface,
 		&remote_usb_iface,
 		&remote_usbhc_iface
@@ -51,6 +53,6 @@
 };
 
-remote_iface_t* get_remote_iface(int idx)
-{	
+remote_iface_t *get_remote_iface(int idx)
+{
 	assert(is_valid_iface_idx(idx));
 	return remote_ifaces.ifaces[idx];
@@ -63,5 +65,11 @@
 		return NULL;
 	}
+
 	return rem_iface->methods[iface_method_idx];
+}
+
+bool is_valid_iface_idx(int idx)
+{
+	return (0 <= idx) && (idx < DEV_IFACE_MAX);
 }
 
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/drv/generic/driver.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -52,17 +52,15 @@
 #include <ipc/driver.h>
 
+#include "dev_iface.h"
 #include "driver.h"
 
-/* driver structure */
-
+/** Driver structure */
 static driver_t *driver;
 
-/* devices */
-
+/** Devices */
 LIST_INITIALIZE(devices);
 FIBRIL_MUTEX_INITIALIZE(devices_mutex);
 
-/* interrupts */
-
+/** Interrupts */
 static interrupt_context_list_t interrupt_contexts;
 
@@ -85,7 +83,91 @@
 	
 	ctx = find_interrupt_context_by_id(&interrupt_contexts, id);
-	if (NULL != ctx && NULL != ctx->handler)
+	if (ctx != NULL && ctx->handler != NULL)
 		(*ctx->handler)(ctx->dev, iid, icall);
 }
+
+interrupt_context_t *create_interrupt_context(void)
+{
+	interrupt_context_t *ctx;
+	
+	ctx = (interrupt_context_t *) malloc(sizeof(interrupt_context_t));
+	if (ctx != NULL)
+		memset(ctx, 0, sizeof(interrupt_context_t));
+	
+	return ctx;
+}
+
+void delete_interrupt_context(interrupt_context_t *ctx)
+{
+	if (ctx != NULL)
+		free(ctx);
+}
+
+void init_interrupt_context_list(interrupt_context_list_t *list)
+{
+	memset(list, 0, sizeof(interrupt_context_list_t));
+	fibril_mutex_initialize(&list->mutex);
+	list_initialize(&list->contexts);
+}
+
+void
+add_interrupt_context(interrupt_context_list_t *list, interrupt_context_t *ctx)
+{
+	fibril_mutex_lock(&list->mutex);
+	ctx->id = list->curr_id++;
+	list_append(&ctx->link, &list->contexts);
+	fibril_mutex_unlock(&list->mutex);
+}
+
+void remove_interrupt_context(interrupt_context_list_t *list,
+    interrupt_context_t *ctx)
+{
+	fibril_mutex_lock(&list->mutex);
+	list_remove(&ctx->link);
+	fibril_mutex_unlock(&list->mutex);
+}
+
+interrupt_context_t *
+find_interrupt_context_by_id(interrupt_context_list_t *list, int id)
+{
+	fibril_mutex_lock(&list->mutex);
+	
+	link_t *link = list->contexts.next;
+	interrupt_context_t *ctx;
+	
+	while (link != &list->contexts) {
+		ctx = list_get_instance(link, interrupt_context_t, link);
+		if (ctx->id == id) {
+			fibril_mutex_unlock(&list->mutex);
+			return ctx;
+		}
+		link = link->next;
+	}
+	
+	fibril_mutex_unlock(&list->mutex);
+	return NULL;
+}
+
+interrupt_context_t *
+find_interrupt_context(interrupt_context_list_t *list, device_t *dev, int irq)
+{
+	fibril_mutex_lock(&list->mutex);
+	
+	link_t *link = list->contexts.next;
+	interrupt_context_t *ctx;
+	
+	while (link != &list->contexts) {
+		ctx = list_get_instance(link, interrupt_context_t, link);
+		if (ctx->irq == irq && ctx->dev == dev) {
+			fibril_mutex_unlock(&list->mutex);
+			return ctx;
+		}
+		link = link->next;
+	}
+	
+	fibril_mutex_unlock(&list->mutex);
+	return NULL;
+}
+
 
 int
@@ -101,9 +183,9 @@
 	add_interrupt_context(&interrupt_contexts, ctx);
 	
-	if (NULL == pseudocode)
+	if (pseudocode == NULL)
 		pseudocode = &default_pseudocode;
 	
 	int res = ipc_register_irq(irq, dev->handle, ctx->id, pseudocode);
-	if (0 != res) {
+	if (res != EOK) {
 		remove_interrupt_context(&interrupt_contexts, ctx);
 		delete_interrupt_context(ctx);
@@ -118,9 +200,10 @@
 	    dev, irq);
 	int res = ipc_unregister_irq(irq, dev->handle);
-
-	if (NULL != ctx) {
+	
+	if (ctx != NULL) {
 		remove_interrupt_context(&interrupt_contexts, ctx);
 		delete_interrupt_context(ctx);
 	}
+	
 	return res;
 }
@@ -140,5 +223,5 @@
 }
 
-static device_t * driver_get_device(link_t *devices, devman_handle_t handle)
+static device_t *driver_get_device(link_t *devices, devman_handle_t handle)
 {
 	device_t *dev = NULL;
@@ -146,7 +229,8 @@
 	fibril_mutex_lock(&devices_mutex);
 	link_t *link = devices->next;
+	
 	while (link != devices) {
 		dev = list_get_instance(link, device_t, link);
-		if (handle == dev->handle) {
+		if (dev->handle == handle) {
 			fibril_mutex_unlock(&devices_mutex);
 			return dev;
@@ -154,6 +238,7 @@
 		link = link->next;
 	}
+	
 	fibril_mutex_unlock(&devices_mutex);
-
+	
 	return NULL;
 }
@@ -162,9 +247,9 @@
 {
 	char *dev_name = NULL;
-	int res = EOK;
-	
-	devman_handle_t dev_handle =  IPC_GET_ARG1(*icall);
+	int res;
+	
+	devman_handle_t dev_handle = IPC_GET_ARG1(*icall);
     	devman_handle_t parent_dev_handle = IPC_GET_ARG2(*icall);
-    
+	
 	device_t *dev = create_device();
 	dev->handle = dev_handle;
@@ -177,5 +262,5 @@
 	
 	res = driver->driver_ops->add_device(dev);
-	if (0 == res) {
+	if (res == EOK) {
 		printf("%s: new device with handle=%" PRIun " was added.\n",
 		    driver->name, dev_handle);
@@ -194,10 +279,10 @@
 	/* Accept connection */
 	ipc_answer_0(iid, EOK);
-
+	
 	bool cont = true;
 	while (cont) {
 		ipc_call_t call;
 		ipc_callid_t callid = async_get_call(&call);
-
+		
 		switch (IPC_GET_IMETHOD(call)) {
 		case IPC_M_PHONE_HUNGUP:
@@ -240,14 +325,14 @@
 	 * use the device.
 	 */
-
+	
 	int ret = EOK;
 	/* open the device */
-	if (NULL != dev->ops && NULL != dev->ops->open)
+	if (dev->ops != NULL && dev->ops->open != NULL)
 		ret = (*dev->ops->open)(dev);
 	
-	ipc_answer_0(iid, ret);	
-	if (EOK != ret)
+	ipc_answer_0(iid, ret);
+	if (ret != EOK)
 		return;
-
+	
 	while (1) {
 		ipc_callid_t callid;
@@ -258,11 +343,11 @@
 		
 		switch  (method) {
-		case IPC_M_PHONE_HUNGUP:		
+		case IPC_M_PHONE_HUNGUP:
 			/* close the device */
-			if (NULL != dev->ops && NULL != dev->ops->close)
+			if (dev->ops != NULL && dev->ops->close != NULL)
 				(*dev->ops->close)(dev);
 			ipc_answer_0(callid, EOK);
 			return;
-		default:		
+		default:
 			/* convert ipc interface id to interface index */
 			
@@ -272,5 +357,5 @@
 				remote_handler_t *default_handler =
 				    device_get_default_handler(dev);
-				if (NULL != default_handler) {
+				if (default_handler != NULL) {
 					(*default_handler)(dev, callid, &call);
 					break;
@@ -286,10 +371,10 @@
 				break;
 			}
-
+			
 			/* calling one of the device's interfaces */
 			
-			/* get the device interface structure */
-			void *iface = device_get_iface(dev, iface_idx);
-			if (NULL == iface) {
+			/* Get the interface ops structure. */
+			void *ops = device_get_ops(dev, iface_idx);
+			if (ops == NULL) {
 				printf("%s: driver_connection_gen error - ",
 				    driver->name);
@@ -299,17 +384,17 @@
 				break;
 			}
-
+			
 			/*
 			 * Get the corresponding interface for remote request
 			 * handling ("remote interface").
 			 */
-			remote_iface_t* rem_iface = get_remote_iface(iface_idx);
-			assert(NULL != rem_iface);
-
+			remote_iface_t *rem_iface = get_remote_iface(iface_idx);
+			assert(rem_iface != NULL);
+			
 			/* get the method of the remote interface */
 			sysarg_t iface_method_idx = IPC_GET_ARG1(call);
 			remote_iface_func_ptr_t iface_method_ptr =
 			    get_remote_method(rem_iface, iface_method_idx);
-			if (NULL == iface_method_ptr) {
+			if (iface_method_ptr == NULL) {
 				// the interface has not such method
 				printf("%s: driver_connection_gen error - "
@@ -325,5 +410,5 @@
 			 * associated with the device by its driver.
 			 */
-			(*iface_method_ptr)(dev, iface, callid, &call);
+			(*iface_method_ptr)(dev, ops, callid, &call);
 			break;
 		}
@@ -348,16 +433,15 @@
 	switch ((sysarg_t) (IPC_GET_ARG1(*icall))) {
 	case DRIVER_DEVMAN:
-		/* handle PnP events from device manager */
+		/* Handle request from device manager */
 		driver_connection_devman(iid, icall);
 		break;
 	case DRIVER_DRIVER:
-		/* handle request from drivers of child devices */
+		/* Handle request from drivers of child devices */
 		driver_connection_driver(iid, icall);
 		break;
 	case DRIVER_CLIENT:
-		/* handle requests from client applications */
+		/* Handle request from client applications */
 		driver_connection_client(iid, icall);
 		break;
-
 	default:
 		/* No such interface */
@@ -366,8 +450,44 @@
 }
 
+/** Create new device structure.
+ *
+ * @return		The device structure.
+ */
+device_t *create_device(void)
+{
+	device_t *dev = malloc(sizeof(device_t));
+
+	if (dev != NULL) {
+		memset(dev, 0, sizeof(device_t));
+		init_match_ids(&dev->match_ids);
+	}
+
+	return dev;
+}
+
+/** Delete device structure.
+ *
+ * @param dev		The device structure.
+ */
+void delete_device(device_t *dev)
+{
+	clean_match_ids(&dev->match_ids);
+	if (dev->name != NULL)
+		free(dev->name);
+	free(dev);
+}
+
+void *device_get_ops(device_t *dev, dev_inferface_idx_t idx)
+{
+	assert(is_valid_iface_idx(idx));
+	if (dev->ops == NULL)
+		return NULL;
+	return dev->ops->interfaces[idx];
+}
+
 int child_device_register(device_t *child, device_t *parent)
 {
-	assert(NULL != child->name);
-
+	assert(child->name != NULL);
+	
 	int res;
 	
@@ -375,7 +495,9 @@
 	res = devman_child_device_register(child->name, &child->match_ids,
 	    parent->handle, &child->handle);
-	if (EOK == res)
+	if (res != EOK) {
+		remove_from_devices_list(child);
 		return res;
-	remove_from_devices_list(child);	
+	}
+	
 	return res;
 }
@@ -396,5 +518,5 @@
 	match_id_t *match_id = NULL;
 	int rc;
-
+	
 	child = create_device();
 	if (child == NULL) {
@@ -402,7 +524,7 @@
 		goto failure;
 	}
-
+	
 	child->name = child_name;
-
+	
 	match_id = create_match_id();
 	if (match_id == NULL) {
@@ -410,11 +532,11 @@
 		goto failure;
 	}
-
+	
 	match_id->id = child_match_id;
 	match_id->score = child_match_score;
 	add_match_id(&child->match_ids, match_id);
-
+	
 	rc = child_device_register(child, parent);
-	if (EOK != rc)
+	if (rc != EOK)
 		goto failure;
 
@@ -422,6 +544,7 @@
 		*child_handle = child->handle;
 	}
+
 	return EOK;
-
+	
 failure:
 	if (match_id != NULL) {
@@ -429,11 +552,24 @@
 		delete_match_id(match_id);
 	}
-
+	
 	if (child != NULL) {
 		child->name = NULL;
 		delete_device(child);
 	}
-
+	
 	return rc;
+}
+
+/** Get default handler for client requests */
+remote_handler_t *device_get_default_handler(device_t *dev)
+{
+	if (dev->ops == NULL)
+		return NULL;
+	return dev->ops->default_handler;
+}
+
+int add_device_to_class(device_t *dev, const char *class_name)
+{
+	return devman_add_device_to_class(dev->handle, class_name);
 }
 
@@ -445,5 +581,5 @@
 	 */
 	driver = drv;
-
+	
 	/* Initialize the list of interrupt contexts. */
 	init_interrupt_context_list(&interrupt_contexts);
@@ -457,7 +593,7 @@
 	 */
 	devman_driver_register(driver->name, driver_connection);
-
+	
 	async_manager();
-
+	
 	/* Never reached. */
 	return 0;
Index: pace/lib/drv/generic/remote_char.c
===================================================================
--- uspace/lib/drv/generic/remote_char.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,162 +1,0 @@
-/*
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#include <ipc/ipc.h>
-#include <async.h>
-#include <errno.h>
-
-#include "char.h"
-#include "driver.h"
-
-#define MAX_CHAR_RW_COUNT 256
-
-static void remote_char_read(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_char_write(device_t *, void *, ipc_callid_t, ipc_call_t *);
-
-/** Remote character interface operations. */
-static remote_iface_func_ptr_t remote_char_iface_ops [] = {
-	&remote_char_read,
-	&remote_char_write
-};
-
-/** Remote character interface structure.
- *
- * Interface for processing request from remote clients addressed to the
- * character interface.
- */
-remote_iface_t remote_char_iface = {
-	.method_count = sizeof(remote_char_iface_ops) /
-	    sizeof(remote_iface_func_ptr_t),
-	.methods = remote_char_iface_ops
-};
-
-/** Process the read request from the remote client.
- *
- * Receive the read request's parameters from the remote client and pass them
- * to the local interface. Return the result of the operation processed by the
- * local interface to the remote client.
- *
- * @param dev		The device from which the data are read.
- * @param iface		The local interface structure.
- */
-static void
-remote_char_read(device_t *dev, void *iface, ipc_callid_t callid,
-    ipc_call_t *call)
-{	
-	char_iface_t *char_iface = (char_iface_t *) iface;
-	ipc_callid_t cid;
-	
-	size_t len;
-	if (!async_data_read_receive(&cid, &len)) {
-		/* TODO handle protocol error. */
-		ipc_answer_0(callid, EINVAL);
-		return;
-	}
-	
-	if (!char_iface->read) {
-		async_data_read_finalize(cid, NULL, 0);
-		ipc_answer_0(callid, ENOTSUP);
-		return;
-	}
-	
-	if (len > MAX_CHAR_RW_COUNT)
-		len = MAX_CHAR_RW_COUNT;
-	
-	char buf[MAX_CHAR_RW_COUNT];
-	int ret = (*char_iface->read)(dev, buf, len);
-	
-	if (ret < 0) {
-		/* Some error occured. */
-		async_data_read_finalize(cid, buf, 0);
-		ipc_answer_0(callid, ret);
-		return;
-	}
-	
-	/* The operation was successful, return the number of data read. */
-	async_data_read_finalize(cid, buf, ret);
-	ipc_answer_1(callid, EOK, ret);
-}
-
-/** Process the write request from the remote client.
- *
- * Receive the write request's parameters from the remote client and pass them
- * to the local interface. Return the result of the operation processed by the
- * local interface to the remote client.
- *
- * @param dev		The device to which the data are written.
- * @param iface		The local interface structure.
- */
-static void
-remote_char_write(device_t *dev, void *iface, ipc_callid_t callid,
-    ipc_call_t *call)
-{
-	char_iface_t *char_iface = (char_iface_t *) iface;
-	ipc_callid_t cid;
-	size_t len;
-	
-	if (!async_data_write_receive(&cid, &len)) {
-		/* TODO handle protocol error. */
-		ipc_answer_0(callid, EINVAL);
-		return;
-	}
-	
-	if (!char_iface->write) {
-		async_data_write_finalize(cid, NULL, 0);
-		ipc_answer_0(callid, ENOTSUP);
-		return;
-	}	
-	
-	if (len > MAX_CHAR_RW_COUNT)
-		len = MAX_CHAR_RW_COUNT;
-	
-	char buf[MAX_CHAR_RW_COUNT];
-	
-	async_data_write_finalize(cid, buf, len);
-	
-	int ret = (*char_iface->write)(dev, buf, len);
-	if (ret < 0) {
-		/* Some error occured. */
-		ipc_answer_0(callid, ret);
-	} else {
-		/*
-		 * The operation was successful, return the number of data
-		 * written.
-		 */
-		ipc_answer_1(callid, EOK, ret);
-	}
-}
-
-/**
- * @}
- */
Index: uspace/lib/drv/generic/remote_char_dev.c
===================================================================
--- uspace/lib/drv/generic/remote_char_dev.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/lib/drv/generic/remote_char_dev.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,162 @@
+/*
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/ipc.h>
+#include <async.h>
+#include <errno.h>
+
+#include "ops/char_dev.h"
+#include "driver.h"
+
+#define MAX_CHAR_RW_COUNT 256
+
+static void remote_char_read(device_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_char_write(device_t *, void *, ipc_callid_t, ipc_call_t *);
+
+/** Remote character interface operations. */
+static remote_iface_func_ptr_t remote_char_dev_iface_ops[] = {
+	&remote_char_read,
+	&remote_char_write
+};
+
+/** Remote character interface structure.
+ *
+ * Interface for processing request from remote clients addressed to the
+ * character interface.
+ */
+remote_iface_t remote_char_dev_iface = {
+	.method_count = sizeof(remote_char_dev_iface_ops) /
+	    sizeof(remote_iface_func_ptr_t),
+	.methods = remote_char_dev_iface_ops
+};
+
+/** Process the read request from the remote client.
+ *
+ * Receive the read request's parameters from the remote client and pass them
+ * to the local interface. Return the result of the operation processed by the
+ * local interface to the remote client.
+ *
+ * @param dev		The device from which the data are read.
+ * @param ops		The local ops structure.
+ */
+static void
+remote_char_read(device_t *dev, void *ops, ipc_callid_t callid,
+    ipc_call_t *call)
+{
+	char_dev_ops_t *char_dev_ops = (char_dev_ops_t *) ops;
+	ipc_callid_t cid;
+	
+	size_t len;
+	if (!async_data_read_receive(&cid, &len)) {
+		/* TODO handle protocol error. */
+		ipc_answer_0(callid, EINVAL);
+		return;
+	}
+	
+	if (!char_dev_ops->read) {
+		async_data_read_finalize(cid, NULL, 0);
+		ipc_answer_0(callid, ENOTSUP);
+		return;
+	}
+	
+	if (len > MAX_CHAR_RW_COUNT)
+		len = MAX_CHAR_RW_COUNT;
+	
+	char buf[MAX_CHAR_RW_COUNT];
+	int ret = (*char_dev_ops->read)(dev, buf, len);
+	
+	if (ret < 0) {
+		/* Some error occured. */
+		async_data_read_finalize(cid, buf, 0);
+		ipc_answer_0(callid, ret);
+		return;
+	}
+	
+	/* The operation was successful, return the number of data read. */
+	async_data_read_finalize(cid, buf, ret);
+	ipc_answer_1(callid, EOK, ret);
+}
+
+/** Process the write request from the remote client.
+ *
+ * Receive the write request's parameters from the remote client and pass them
+ * to the local interface. Return the result of the operation processed by the
+ * local interface to the remote client.
+ *
+ * @param dev		The device to which the data are written.
+ * @param ops		The local ops structure.
+ */
+static void
+remote_char_write(device_t *dev, void *ops, ipc_callid_t callid,
+    ipc_call_t *call)
+{
+	char_dev_ops_t *char_dev_ops = (char_dev_ops_t *) ops;
+	ipc_callid_t cid;
+	size_t len;
+	
+	if (!async_data_write_receive(&cid, &len)) {
+		/* TODO handle protocol error. */
+		ipc_answer_0(callid, EINVAL);
+		return;
+	}
+	
+	if (!char_dev_ops->write) {
+		async_data_write_finalize(cid, NULL, 0);
+		ipc_answer_0(callid, ENOTSUP);
+		return;
+	}
+	
+	if (len > MAX_CHAR_RW_COUNT)
+		len = MAX_CHAR_RW_COUNT;
+	
+	char buf[MAX_CHAR_RW_COUNT];
+	
+	async_data_write_finalize(cid, buf, len);
+	
+	int ret = (*char_dev_ops->write)(dev, buf, len);
+	if (ret < 0) {
+		/* Some error occured. */
+		ipc_answer_0(callid, ret);
+	} else {
+		/*
+		 * The operation was successful, return the number of data
+		 * written.
+		 */
+		ipc_answer_1(callid, EOK, ret);
+	}
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/remote_hw_res.c
===================================================================
--- uspace/lib/drv/generic/remote_hw_res.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/lib/drv/generic/remote_hw_res.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,99 @@
+/*
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/ipc.h>
+#include <async.h>
+#include <errno.h>
+
+#include "ops/hw_res.h"
+#include "driver.h"
+
+static void remote_hw_res_get_resource_list(device_t *, void *, ipc_callid_t,
+    ipc_call_t *);
+static void remote_hw_res_enable_interrupt(device_t *, void *, ipc_callid_t,
+    ipc_call_t *);
+
+static remote_iface_func_ptr_t remote_hw_res_iface_ops [] = {
+	&remote_hw_res_get_resource_list,
+	&remote_hw_res_enable_interrupt
+};
+
+remote_iface_t remote_hw_res_iface = {
+	.method_count = sizeof(remote_hw_res_iface_ops) /
+	    sizeof(remote_iface_func_ptr_t),
+	.methods = remote_hw_res_iface_ops
+};
+
+static void remote_hw_res_enable_interrupt(device_t *dev, void *ops,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	hw_res_ops_t *hw_res_ops = (hw_res_ops_t *) ops;
+	
+	if (hw_res_ops->enable_interrupt == NULL)
+		ipc_answer_0(callid, ENOTSUP);
+	else if (hw_res_ops->enable_interrupt(dev))
+		ipc_answer_0(callid, EOK);
+	else
+		ipc_answer_0(callid, EREFUSED);
+}
+
+static void remote_hw_res_get_resource_list(device_t *dev, void *ops,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	hw_res_ops_t *hw_res_ops = (hw_res_ops_t *) ops;
+
+	if (hw_res_ops->get_resource_list == NULL) {
+		ipc_answer_0(callid, ENOTSUP);
+		return;
+	}
+	
+	hw_resource_list_t *hw_resources = hw_res_ops->get_resource_list(dev);
+	if (hw_resources == NULL){
+		ipc_answer_0(callid, ENOENT);
+		return;
+	}
+	
+	ipc_answer_1(callid, EOK, hw_resources->count);
+
+	size_t len;
+	if (!async_data_read_receive(&callid, &len)) {
+		/* Protocol error - the recipient is not accepting data */
+		return;
+	}
+	async_data_read_finalize(callid, hw_resources->resources, len);
+}
+
+/**
+ * @}
+ */
Index: pace/lib/drv/generic/remote_res.c
===================================================================
--- uspace/lib/drv/generic/remote_res.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,98 +1,0 @@
-/*
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#include <ipc/ipc.h>
-#include <async.h>
-#include <errno.h>
-
-#include "driver.h"
-#include "resource.h"
-
-static void remote_res_get_resources(device_t *, void *, ipc_callid_t,
-    ipc_call_t *);
-static void remote_res_enable_interrupt(device_t *, void *, ipc_callid_t,
-    ipc_call_t *);
-
-static remote_iface_func_ptr_t remote_res_iface_ops [] = {
-	&remote_res_get_resources,
-	&remote_res_enable_interrupt
-};
-
-remote_iface_t remote_res_iface = {
-	.method_count = sizeof(remote_res_iface_ops) /
-	    sizeof(remote_iface_func_ptr_t),
-	.methods = remote_res_iface_ops
-};
-
-static void remote_res_enable_interrupt(device_t *dev, void *iface,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	resource_iface_t *ires = (resource_iface_t *) iface;
-	
-	if (NULL == ires->enable_interrupt)
-		ipc_answer_0(callid, ENOTSUP);
-	else if (ires->enable_interrupt(dev))
-		ipc_answer_0(callid, EOK);
-	else
-		ipc_answer_0(callid, EREFUSED);
-}
-
-static void remote_res_get_resources(device_t *dev, void *iface,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	resource_iface_t *ires = (resource_iface_t *) iface;
-	if (NULL == ires->get_resources) {
-		ipc_answer_0(callid, ENOTSUP);
-		return;
-	}
-	
-	hw_resource_list_t *hw_resources = ires->get_resources(dev);
-	if (NULL == hw_resources){
-		ipc_answer_0(callid, ENOENT);
-		return;
-	}	
-	
-	ipc_answer_1(callid, EOK, hw_resources->count);	
-
-	size_t len;
-	if (!async_data_read_receive(&callid, &len)) {
-		/* protocol error - the recipient is not accepting data */
-		return;
-	}
-	async_data_read_finalize(callid, hw_resources->resources, len);
-}
-
-/**
- * @}
- */
Index: pace/lib/drv/include/char.h
===================================================================
--- uspace/lib/drv/include/char.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_CHAR_H_
-#define LIBDRV_CHAR_H_
-
-#include "driver.h"
-
-typedef struct char_iface {
-	int (*read)(device_t *, char *, size_t);
-	int (*write)(device_t *, char *, size_t);
-} char_iface_t;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/lib/drv/include/dev_iface.h
===================================================================
--- uspace/lib/drv/include/dev_iface.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/drv/include/dev_iface.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -36,7 +36,35 @@
 #define LIBDRV_DEV_IFACE_H_
 
-#include "driver.h"
+#include <ipc/dev_iface.h>
 
-/* TODO declare device interface structures here */
+/*
+ * Device interface
+ */
+
+struct device;
+
+/*
+ * First two parameters: device and interface structure registered by the
+ * devices driver.
+ */
+typedef void remote_iface_func_t(struct device *, void *, ipc_callid_t,
+    ipc_call_t *);
+typedef remote_iface_func_t *remote_iface_func_ptr_t;
+typedef void remote_handler_t(struct device *, ipc_callid_t, ipc_call_t *);
+
+typedef struct {
+	size_t method_count;
+	remote_iface_func_ptr_t *methods;
+} remote_iface_t;
+
+typedef struct {
+	remote_iface_t *ifaces[DEV_IFACE_COUNT];
+} iface_dipatch_table_t;
+
+extern remote_iface_t *get_remote_iface(int);
+extern remote_iface_func_ptr_t get_remote_method(remote_iface_t *, sysarg_t);
+
+
+extern bool is_valid_iface_idx(int);
 
 #endif
Index: uspace/lib/drv/include/driver.h
===================================================================
--- uspace/lib/drv/include/driver.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/drv/include/driver.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -41,6 +41,4 @@
 #include <ipc/devman.h>
 #include <ipc/dev_iface.h>
-#include <device/hw_res.h>
-#include <device/char.h>
 #include <assert.h>
 #include <ddi.h>
@@ -49,40 +47,14 @@
 #include <malloc.h>
 
+#include "dev_iface.h"
+
 struct device;
 typedef struct device device_t;
 
-/* device interface */
+/*
+ * Device class
+ */
 
-/*
- * First two parameters: device and interface structure registered by the
- * devices driver.
- */
-typedef void remote_iface_func_t(device_t *, void *, ipc_callid_t,
-    ipc_call_t *);
-typedef remote_iface_func_t *remote_iface_func_ptr_t;
-typedef void remote_handler_t(device_t *, ipc_callid_t, ipc_call_t *);
-
-typedef struct {
-	size_t method_count;
-	remote_iface_func_ptr_t *methods;
-} remote_iface_t;
-
-typedef struct {
-	remote_iface_t *ifaces[DEV_IFACE_COUNT];
-} iface_dipatch_table_t;
-
-
-static inline bool is_valid_iface_idx(int idx)
-{
-	return 0 <= idx && idx < DEV_IFACE_MAX;
-}
-
-remote_iface_t *get_remote_iface(int);
-remote_iface_func_ptr_t get_remote_method(remote_iface_t *, sysarg_t);
-
-
-/* device class */
-
-/** Devices operations. */
+/** Devices operations */
 typedef struct device_ops {
 	/**
@@ -110,7 +82,9 @@
 
 
-/* device */
+/*
+ * Device
+ */
 
-/** The device. */
+/** Device structure */
 struct device {
 	/**
@@ -121,42 +95,40 @@
 	
 	/**
-	 * The phone to the parent device driver (if it is different from this
-	 * driver).
+	 * Phone to the parent device driver (if it is different from this
+	 * driver)
 	 */
 	int parent_phone;
 	
-	/** Parent device if handled by this driver, NULL otherwise. */
+	/** Parent device if handled by this driver, NULL otherwise */
 	device_t *parent;
-	/** The device's name. */
+	/** Device name */
 	const char *name;
-	/** The list of device ids for device-to-driver matching. */
+	/** List of device ids for device-to-driver matching */
 	match_id_list_t match_ids;
-	/** The device driver's data associated with this device. */
+	/** Driver-specific data associated with this device */
 	void *driver_data;
-	/** The implementation of operations provided by this device. */
+	/** The implementation of operations provided by this device */
 	device_ops_t *ops;
 	
-	/**
-	 * Pointer to the previous and next device in the list of devices
-	 * handled by the driver.
-	 */
+	/** Link in the list of devices handled by the driver */
 	link_t link;
 };
 
+/*
+ * Driver
+ */
 
-/* driver */
-
-/** Generic device driver operations. */
+/** Generic device driver operations */
 typedef struct driver_ops {
-	/** Callback method for passing a new device to the device driver.*/
+	/** Callback method for passing a new device to the device driver */
 	int (*add_device)(device_t *dev);
-	/* TODO add other generic driver operations */
+	/* TODO: add other generic driver operations */
 } driver_ops_t;
 
-/** The driver structure.*/
+/** Driver structure */
 typedef struct driver {
-	/** The name of the device driver. */
+	/** Name of the device driver */
 	const char *name;
-	/** Generic device driver operations. */
+	/** Generic device driver operations */
 	driver_ops_t *driver_ops;
 } driver_t;
@@ -168,40 +140,15 @@
  * @return		The device structure.
  */
-static inline device_t *create_device(void)
-{
-	device_t *dev = malloc(sizeof(device_t));
-	if (NULL != dev) {
-		memset(dev, 0, sizeof(device_t));
-		init_match_ids(&dev->match_ids);
-	}	
-	return dev;
-}
+extern device_t *create_device(void);
+extern void delete_device(device_t *);
+extern void *device_get_ops(device_t *, dev_inferface_idx_t);
 
-/** Delete device structure.
- *
- * @param dev		The device structure.
+extern int child_device_register(device_t *, device_t *);
+extern int child_device_register_wrapper(device_t *, const char *, const char *,
+    int, devman_handle_t *);
+
+/*
+ * Interrupts
  */
-static inline void delete_device(device_t *dev)
-{
-	clean_match_ids(&dev->match_ids);
-	if (NULL != dev->name)
-		free(dev->name);
-	free(dev);
-}
-
-static inline void *device_get_iface(device_t *dev, dev_inferface_idx_t idx)
-{
-	assert(is_valid_iface_idx(idx));
-	if (NULL == dev->ops)
-		return NULL;
-	return dev->ops->interfaces[idx];
-}
-
-int child_device_register(device_t *, device_t *);
-int child_device_register_wrapper(device_t *, const char *, const char *, int,
-    devman_handle_t *);
-
-
-/* interrupts */
 
 typedef void interrupt_handler_t(device_t *, ipc_callid_t, ipc_call_t *);
@@ -221,106 +168,22 @@
 } interrupt_context_list_t;
 
-static inline interrupt_context_t *create_interrupt_context(void)
-{
-	interrupt_context_t *ctx;
-	
-	ctx = (interrupt_context_t *) malloc(sizeof(interrupt_context_t));
-	if (NULL != ctx)
-		memset(ctx, 0, sizeof(interrupt_context_t));
-	
-	return ctx;
-}
+extern interrupt_context_t *create_interrupt_context(void);
+extern void delete_interrupt_context(interrupt_context_t *);
+extern void init_interrupt_context_list(interrupt_context_list_t *);
+extern void add_interrupt_context(interrupt_context_list_t *,
+    interrupt_context_t *);
+extern void remove_interrupt_context(interrupt_context_list_t *,
+    interrupt_context_t *);
+extern interrupt_context_t *find_interrupt_context_by_id(
+    interrupt_context_list_t *, int);
+extern interrupt_context_t *find_interrupt_context(
+    interrupt_context_list_t *, device_t *, int);
 
-static inline void delete_interrupt_context(interrupt_context_t *ctx)
-{
-	if (NULL != ctx)
-		free(ctx);
-}
+extern int register_interrupt_handler(device_t *, int, interrupt_handler_t *,
+    irq_code_t *);
+extern int unregister_interrupt_handler(device_t *, int);
 
-static inline void init_interrupt_context_list(interrupt_context_list_t *list)
-{
-	memset(list, 0, sizeof(interrupt_context_list_t));
-	fibril_mutex_initialize(&list->mutex);
-	list_initialize(&list->contexts);
-}
-
-static inline void
-add_interrupt_context(interrupt_context_list_t *list, interrupt_context_t *ctx)
-{
-	fibril_mutex_lock(&list->mutex);
-	ctx->id = list->curr_id++;
-	list_append(&ctx->link, &list->contexts);
-	fibril_mutex_unlock(&list->mutex);
-}
-
-static inline void
-remove_interrupt_context(interrupt_context_list_t *list,
-    interrupt_context_t *ctx)
-{
-	fibril_mutex_lock(&list->mutex);
-	list_remove(&ctx->link);
-	fibril_mutex_unlock(&list->mutex);
-}
-
-static inline interrupt_context_t *
-find_interrupt_context_by_id(interrupt_context_list_t *list, int id)
-{
-	fibril_mutex_lock(&list->mutex);
-	
-	link_t *link = list->contexts.next;
-	interrupt_context_t *ctx;
-	
-	while (link != &list->contexts) {
-		ctx = list_get_instance(link, interrupt_context_t, link);
-		if (id == ctx->id) {
-			fibril_mutex_unlock(&list->mutex);
-			return ctx;
-		}
-		link = link->next;
-	}
-	
-	fibril_mutex_unlock(&list->mutex);
-	return NULL;
-}
-
-static inline interrupt_context_t *
-find_interrupt_context(interrupt_context_list_t *list, device_t *dev, int irq)
-{
-	fibril_mutex_lock(&list->mutex);
-	
-	link_t *link = list->contexts.next;
-	interrupt_context_t *ctx;
-	
-	while (link != &list->contexts) {
-		ctx = list_get_instance(link, interrupt_context_t, link);
-		if (irq == ctx->irq && dev == ctx->dev) {
-			fibril_mutex_unlock(&list->mutex);
-			return ctx;
-		}
-		link = link->next;
-	}
-	
-	fibril_mutex_unlock(&list->mutex);
-	return NULL;
-}
-
-int register_interrupt_handler(device_t *, int, interrupt_handler_t *,
-    irq_code_t *);
-int unregister_interrupt_handler(device_t *, int);
-
-
-/* default handler for client requests */
-
-static inline remote_handler_t *device_get_default_handler(device_t *dev)
-{
-	if (NULL == dev->ops)
-		return NULL;
-	return dev->ops->default_handler;
-}
-
-static inline int add_device_to_class(device_t *dev, const char *class_name)
-{
-	return devman_add_device_to_class(dev->handle, class_name);
-}
+extern remote_handler_t *device_get_default_handler(device_t *);
+extern int add_device_to_class(device_t *, const char *);
 
 #endif
Index: uspace/lib/drv/include/ops/char_dev.h
===================================================================
--- uspace/lib/drv/include/ops/char_dev.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/lib/drv/include/ops/char_dev.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,49 @@
+/*
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_OPS_CHAR_DEV_H_
+#define LIBDRV_OPS_CHAR_DEV_H_
+
+#include "../driver.h"
+
+typedef struct {
+	int (*read)(device_t *, char *, size_t);
+	int (*write)(device_t *, char *, size_t);
+} char_dev_ops_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/include/ops/hw_res.h
===================================================================
--- uspace/lib/drv/include/ops/hw_res.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/lib/drv/include/ops/hw_res.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,52 @@
+/*
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_OPS_HW_RES_H_
+#define LIBDRV_OPS_HW_RES_H_
+
+#include <device/hw_res.h>
+#include <sys/types.h>
+
+#include "../driver.h"
+
+typedef struct {
+	 hw_resource_list_t *(*get_resource_list)(device_t *);
+	 bool (*enable_interrupt)(device_t *);
+} hw_res_ops_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: pace/lib/drv/include/remote_char.h
===================================================================
--- uspace/lib/drv/include/remote_char.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_CHAR_H_
-#define LIBDRV_REMOTE_CHAR_H_
-
-remote_iface_t remote_char_iface;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/lib/drv/include/remote_char_dev.h
===================================================================
--- uspace/lib/drv/include/remote_char_dev.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/lib/drv/include/remote_char_dev.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,44 @@
+/*
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_CHAR_DEV_H_
+#define LIBDRV_REMOTE_CHAR_DEV_H_
+
+extern remote_iface_t remote_char_dev_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/include/remote_hw_res.h
===================================================================
--- uspace/lib/drv/include/remote_hw_res.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/lib/drv/include/remote_hw_res.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,44 @@
+/*
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_HW_RES_H_
+#define LIBDRV_REMOTE_HW_RES_H_
+
+extern remote_iface_t remote_hw_res_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: pace/lib/drv/include/remote_res.h
===================================================================
--- uspace/lib/drv/include/remote_res.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_RES_H_
-#define LIBDRV_REMOTE_RES_H_
-
-remote_iface_t remote_res_iface;
-
-#endif
-
-/**
- * @}
- */
Index: pace/lib/drv/include/resource.h
===================================================================
--- uspace/lib/drv/include/resource.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,50 +1,0 @@
-/*
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_RESOURCE_H_
-#define LIBDRV_RESOURCE_H_
-
-#include "driver.h"
-
-typedef struct resource_iface {
-	 hw_resource_list_t *(* get_resources)(device_t *);
-	 bool (*enable_interrupt)(device_t *);
-} resource_iface_t;
-
-
-#endif
-
-/**
- * @}
- */
Index: uspace/lib/net/Makefile
===================================================================
--- uspace/lib/net/Makefile	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/net/Makefile	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -40,6 +40,6 @@
 	generic/protocol_map.c \
 	adt/module_map.c \
-	netif/netif_local.c \
 	netif/netif_remote.c \
+	netif/netif_skel.c \
 	nil/nil_remote.c \
 	il/il_interface.c \
Index: uspace/lib/net/adt/module_map.c
===================================================================
--- uspace/lib/net/adt/module_map.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/net/adt/module_map.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -63,6 +63,6 @@
  */
 int
-add_module(module_t **module, modules_t *modules, const char *name,
-    const char *filename, services_t service, task_id_t task_id,
+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)
 {
@@ -104,5 +104,5 @@
  * @return		NULL if there is no such module.
  */
-module_t *get_running_module(modules_t *modules, char *name)
+module_t *get_running_module(modules_t *modules, uint8_t *name)
 {
 	module_t *module;
@@ -113,5 +113,5 @@
 
 	if (!module->task_id) {
-		module->task_id = spawn(module->filename);
+		module->task_id = net_spawn(module->filename);
 		if (!module->task_id)
 			return NULL;
@@ -123,16 +123,18 @@
 }
 
-/** Starts the given module.
+/** Start the given module.
  *
- * @param[in] fname	The module full or relative path filename.
- * @return		The new module task identifier on success.
- * @return		Zero if there is no such module.
+ * @param[in] fname The module full or relative path filename.
+ *
+ * @return The new module task identifier on success.
+ * @return Zero if there is no such module.
+ *
  */
-task_id_t spawn(const char *fname)
+task_id_t net_spawn(const uint8_t *fname)
 {
 	task_id_t id;
 	int rc;
 	
-	rc = task_spawnl(&id, fname, fname, NULL);
+	rc = task_spawnl(&id, (const char *) fname, (const char *) fname, NULL);
 	if (rc != EOK)
 		return 0;
Index: uspace/lib/net/generic/generic.c
===================================================================
--- uspace/lib/net/generic/generic.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/net/generic/generic.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -100,5 +100,5 @@
 int
 generic_get_addr_req(int phone, int message, device_id_t device_id,
-    measured_string_t **address, char ** data)
+    measured_string_t **address, uint8_t **data)
 {
 	aid_t message_id;
@@ -234,5 +234,5 @@
 generic_translate_req(int phone, int message, device_id_t device_id,
     services_t service, measured_string_t *configuration, size_t count,
-    measured_string_t **translation, char **data)
+    measured_string_t **translation, uint8_t **data)
 {
 	aid_t message_id;
Index: uspace/lib/net/generic/net_remote.c
===================================================================
--- uspace/lib/net/generic/net_remote.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/net/generic/net_remote.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -63,5 +63,5 @@
  * @see net_get_conf_req()
  */
-void net_free_settings(measured_string_t *settings, char *data)
+void net_free_settings(measured_string_t *settings, uint8_t *data)
 {
 	if (settings)
@@ -91,5 +91,5 @@
 int
 net_get_conf_req(int net_phone, measured_string_t **configuration,
-    size_t count, char **data)
+    size_t count, uint8_t **data)
 {
 	return generic_translate_req(net_phone, NET_NET_GET_DEVICE_CONF, 0, 0,
@@ -118,5 +118,5 @@
 int
 net_get_device_conf_req(int net_phone, device_id_t device_id,
-    measured_string_t **configuration, size_t count, char **data)
+    measured_string_t **configuration, size_t count, uint8_t **data)
 {
 	return generic_translate_req(net_phone, NET_NET_GET_DEVICE_CONF,
Index: uspace/lib/net/il/arp_remote.c
===================================================================
--- uspace/lib/net/il/arp_remote.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/net/il/arp_remote.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -165,5 +165,5 @@
 int
 arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol,
-    measured_string_t *address, measured_string_t **translation, char **data)
+    measured_string_t *address, measured_string_t **translation, uint8_t **data)
 {
 	return generic_translate_req(arp_phone, NET_ARP_TRANSLATE, device_id,
Index: uspace/lib/net/il/ip_remote.c
===================================================================
--- uspace/lib/net/il/ip_remote.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/net/il/ip_remote.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -170,5 +170,5 @@
 		free(*header);
 	else
-		*device_id = IPC_GET_DEVICE(&answer);
+		*device_id = IPC_GET_DEVICE(answer);
 	
 	return (int) result;
Index: uspace/lib/net/include/adt/module_map.h
===================================================================
--- uspace/lib/net/include/adt/module_map.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/net/include/adt/module_map.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -65,15 +65,15 @@
 	int usage;
 	/** Module name. */
-	const char *name;
+	const uint8_t *name;
 	/** Module full path filename. */
-	const char *filename;
+	const uint8_t *filename;
 	/** Connecting function. */
 	connect_module_t *connect_module;
 };
 
-extern int add_module(module_t **, modules_t *, const char *, const char *,
-    services_t, task_id_t, connect_module_t *);
-extern module_t *get_running_module(modules_t *, char *);
-extern task_id_t spawn(const char *);
+extern int add_module(module_t **, modules_t *, const uint8_t *,
+    const uint8_t *, services_t, task_id_t, connect_module_t *);
+extern module_t *get_running_module(modules_t *, uint8_t *);
+extern task_id_t net_spawn(const uint8_t *);
 
 #endif
Index: uspace/lib/net/include/arp_interface.h
===================================================================
--- uspace/lib/net/include/arp_interface.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/net/include/arp_interface.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -50,5 +50,5 @@
     measured_string_t *);
 extern int arp_translate_req(int, device_id_t, services_t, measured_string_t *,
-    measured_string_t **, char **);
+    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,
Index: uspace/lib/net/include/generic.h
===================================================================
--- uspace/lib/net/include/generic.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/net/include/generic.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -50,5 +50,5 @@
 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 **,
-    char **);
+    uint8_t **);
 extern int generic_packet_size_req_remote(int, int, device_id_t,
     packet_dimension_t *);
@@ -58,5 +58,5 @@
     services_t, services_t);
 extern int generic_translate_req(int, int, device_id_t, services_t,
-    measured_string_t *, size_t, measured_string_t **, char **);
+    measured_string_t *, size_t, measured_string_t **, uint8_t **);
 
 #endif
Index: uspace/lib/net/include/il_local.h
===================================================================
--- uspace/lib/net/include/il_local.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/net/include/il_local.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -49,5 +49,5 @@
  */
 extern int il_module_message_standalone(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count);
+    ipc_call_t *answer, size_t *answer_count);
 
 /** Starts the Internet layer module.
Index: uspace/lib/net/include/net_interface.h
===================================================================
--- uspace/lib/net/include/net_interface.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/net/include/net_interface.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -45,7 +45,7 @@
 
 extern int net_get_device_conf_req(int, device_id_t, measured_string_t **,
-    size_t, char **);
-extern int net_get_conf_req(int, measured_string_t **, size_t, char **);
-extern void net_free_settings(measured_string_t *, char *);
+    size_t, uint8_t **);
+extern int net_get_conf_req(int, measured_string_t **, size_t, uint8_t **);
+extern void net_free_settings(measured_string_t *, uint8_t *);
 extern int net_connect_module(void);
 
Index: pace/lib/net/include/netif_interface.h
===================================================================
--- uspace/lib/net/include/netif_interface.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,52 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * 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 libnet
- * @{
- */
-
-#ifndef LIBNET_NETIF_INTERFACE_H_
-#define LIBNET_NETIF_INTERFACE_H_
-
-#include <netif_remote.h>
-#include <packet_client.h>
-
-#define netif_module_message    netif_module_message_standalone
-#define netif_module_start      netif_module_start_standalone
-#define netif_get_addr_req      netif_get_addr_req_remote
-#define netif_probe_req         netif_probe_req_remote
-#define netif_send_msg          netif_send_msg_remote
-#define netif_start_req         netif_start_req_remote
-#define netif_stop_req          netif_stop_req_remote
-#define netif_stats_req         netif_stats_req_remote
-#define netif_bind_service      netif_bind_service_remote
-
-#endif
-
-/** @}
- */
Index: pace/lib/net/include/netif_local.h
===================================================================
--- uspace/lib/net/include/netif_local.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,220 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * 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 libnet
- * @{
- */
-
-/** @file
- * Network interface module skeleton.
- * The skeleton has to be part of each network interface module.
- */
-
-#ifndef NET_NETIF_LOCAL_H_
-#define NET_NETIF_LOCAL_H_
-
-#include <async.h>
-#include <fibril_synch.h>
-#include <ipc/ipc.h>
-#include <ipc/services.h>
-
-#include <adt/measured_strings.h>
-#include <net/device.h>
-#include <net/packet.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. */
-} netif_device_t;
-
-/** Device map.
- *
- * Maps device identifiers to the network interface device specific data.
- * @see device.h
- *
- */
-DEVICE_MAP_DECLARE(netif_device_map, netif_device_t);
-
-/** Network interface module skeleton global data. */
-typedef struct {
-	int net_phone;                  /**< Networking module phone. */
-	netif_device_map_t device_map;  /**< Device map. */
-	fibril_rwlock_t lock;           /**< Safety lock. */
-} netif_globals_t;
-
-extern netif_globals_t netif_globals;
-
-/** Initialize the specific module.
- *
- * This function has to be implemented in user code.
- */
-extern int netif_initialize(void);
-
-/** Probe the existence of the device.
- *
- * This has to be implemented in user code.
- *
- * @param[in] device_id	The device identifier.
- * @param[in] irq	The device interrupt number.
- * @param[in] io	The device input/output address.
- *
- * @return		EOK on success.
- * @return		Other error codes as defined for the find_device()
- *			function.
- * @return		Other error codes as defined for the specific module
- *			message implementation.
- */
-extern int netif_probe_message(device_id_t device_id, int irq, uintptr_t io);
-
-/** Send the packet queue.
- *
- * This has to be implemented in user code.
- *
- * @param[in] device_id	The device identifier.
- * @param[in] packet	The packet queue.
- * @param[in] sender	The sending module service.
- *
- * @return		EOK on success.
- * @return		EFORWARD if the device is not active (in the
- *			NETIF_ACTIVE state).
- * @return		Other error codes as defined for the find_device()
- *			function.
- * @return		Other error codes as defined for the specific module
- *			message implementation.
- */
-extern int netif_send_message(device_id_t device_id, packet_t *packet,
-    services_t sender);
-
-/** Start the device.
- *
- * This has to be implemented in user code.
- *
- * @param[in] device	The device structure.
- *
- * @return		EOK on success.
- * @return		Other error codes as defined for the find_device()
- *			function.
- * @return		Other error codes as defined for the specific module
- *			message implementation.
- */
-extern int netif_start_message(netif_device_t *device);
-
-/** Stop the device.
- *
- * This has to be implemented in user code.
- *
- * @param[in] device	The device structure.
- *
- * @return		EOK on success.
- * @return		Other error codes as defined for the find_device()
- *			function.
- * @return		Other error codes as defined for the specific module
- *			message implementation.
- */
-extern int netif_stop_message(netif_device_t *device);
-
-/** Return the device local hardware address.
- *
- * This has to be implemented in user code.
- *
- * @param[in] device_id	The device identifier.
- * @param[out] address	The device local hardware address.
- *
- * @return		EOK on success.
- * @return		EBADMEM if the address parameter is NULL.
- * @return		ENOENT if there no such device.
- * @return		Other error codes as defined for the find_device()
- *			function.
- * @return		Other error codes as defined for the specific module
- *			message implementation.
- */
-extern int netif_get_addr_message(device_id_t device_id,
-    measured_string_t *address);
-
-/** Process the netif driver specific message.
- *
- * This function is called for uncommon messages received by the netif
- * skeleton. This has to be implemented in user code.
- *
- * @param[in] callid	The message identifier.
- * @param[in] call	The message parameters.
- * @param[out] answer	The message answer parameters.
- * @param[out] answer_count The last parameter for the actual answer in
- *			the answer parameter.
- *
- * @return		EOK on success.
- * @return		ENOTSUP if the message is not known.
- * @return		Other error codes as defined for the specific module
- *			message implementation.
- */
-extern int netif_specific_message(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count);
-
-/** Return the device usage statistics.
- *
- * This has to be implemented in user code.
- *
- * @param[in] device_id	The device identifier.
- * @param[out] stats	The device usage statistics.
- *
- * @return		EOK on success.
- * @return		Other error codes as defined for the find_device()
- *			function.
- * @return		Other error codes as defined for the specific module
- *			message implementation.
- */
-extern int netif_get_device_stats(device_id_t device_id,
-    device_stats_t *stats);
-
-extern int netif_get_addr_req_local(int, device_id_t, measured_string_t **,
-    char **);
-extern int netif_probe_req_local(int, device_id_t, int, int);
-extern int netif_send_msg_local(int, device_id_t, packet_t *, services_t);
-extern int netif_start_req_local(int, device_id_t);
-extern int netif_stop_req_local(int, device_id_t);
-extern int netif_stats_req_local(int, device_id_t, device_stats_t *);
-extern int netif_bind_service_local(services_t, device_id_t, services_t,
-    async_client_conn_t);
-
-extern int find_device(device_id_t, netif_device_t **);
-extern void null_device_stats(device_stats_t *);
-extern void netif_pq_release(packet_id_t);
-extern packet_t *netif_packet_get_1(size_t);
-extern int netif_init_module(async_client_conn_t);
-
-extern int netif_module_message_standalone(const char *, ipc_callid_t,
-    ipc_call_t *, ipc_call_t *, int *);
-extern int netif_module_start_standalone(async_client_conn_t);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/net/include/netif_remote.h
===================================================================
--- uspace/lib/net/include/netif_remote.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/net/include/netif_remote.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -41,12 +41,12 @@
 #include <net/packet.h>
 
-extern int netif_get_addr_req_remote(int, device_id_t, measured_string_t **,
-    char **);
-extern int netif_probe_req_remote(int, device_id_t, int, int);
-extern int netif_send_msg_remote(int, device_id_t, packet_t *, services_t);
-extern int netif_start_req_remote(int, device_id_t);
-extern int netif_stop_req_remote(int, device_id_t);
-extern int netif_stats_req_remote(int, device_id_t, device_stats_t *);
-extern int netif_bind_service_remote(services_t, device_id_t, services_t,
+extern int netif_get_addr_req(int, 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,
     async_client_conn_t);
 
Index: uspace/lib/net/include/netif_skel.h
===================================================================
--- uspace/lib/net/include/netif_skel.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/lib/net/include/netif_skel.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * 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 libnet
+ * @{
+ */
+
+/** @file
+ * Network interface module skeleton.
+ * The skeleton has to be part of each network interface module.
+ */
+
+#ifndef NET_NETIF_SKEL_H_
+#define NET_NETIF_SKEL_H_
+
+#include <async.h>
+#include <fibril_synch.h>
+#include <ipc/ipc.h>
+#include <ipc/services.h>
+
+#include <adt/measured_strings.h>
+#include <net/device.h>
+#include <net/packet.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. */
+} netif_device_t;
+
+/** Device map.
+ *
+ * Maps device identifiers to the network interface device specific data.
+ * @see device.h
+ *
+ */
+DEVICE_MAP_DECLARE(netif_device_map, netif_device_t);
+
+/** Network interface module skeleton global data. */
+typedef struct {
+	int net_phone;                  /**< Networking module phone. */
+	netif_device_map_t device_map;  /**< Device map. */
+	fibril_rwlock_t lock;           /**< Safety lock. */
+} netif_globals_t;
+
+extern netif_globals_t netif_globals;
+
+/** Initialize the specific module.
+ *
+ * This function has to be implemented in user code.
+ *
+ */
+extern int netif_initialize(void);
+
+/** Probe the existence of the device.
+ *
+ * This has to be implemented in user code.
+ *
+ * @param[in] device_id Device identifier.
+ * @param[in] irq       Device interrupt number.
+ * @param[in] io        Device input/output address.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the find_device()
+ *         function.
+ * @return Other error codes as defined for the specific module
+ *         message implementation.
+ *
+ */
+extern int netif_probe_message(device_id_t device_id, int irq, void *io);
+
+/** Send the packet queue.
+ *
+ * This has to be implemented in user code.
+ *
+ * @param[in] device_id Device identifier.
+ * @param[in] packet    Packet queue.
+ * @param[in] sender    Sending module service.
+ *
+ * @return EOK on success.
+ * @return EFORWARD if the device is not active (in the
+ *         NETIF_ACTIVE state).
+ * @return Other error codes as defined for the find_device()
+ *         function.
+ * @return Other error codes as defined for the specific module
+ *         message implementation.
+ *
+ */
+extern int netif_send_message(device_id_t device_id, packet_t *packet,
+    services_t sender);
+
+/** Start the device.
+ *
+ * This has to be implemented in user code.
+ *
+ * @param[in] device Device structure.
+ *
+ * @return New network interface state (non-negative values).
+ * @return Other error codes as defined for the find_device()
+ *         function.
+ * @return Other error codes as defined for the specific module
+ *         message implementation.
+ 
+ *
+ */
+extern int netif_start_message(netif_device_t *device);
+
+/** Stop the device.
+ *
+ * This has to be implemented in user code.
+ *
+ * @param[in] device Device structure.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the find_device()
+ *         function.
+ * @return Other error codes as defined for the specific module
+ *         message implementation.
+ *
+ */
+extern int netif_stop_message(netif_device_t *device);
+
+/** Return the device local hardware address.
+ *
+ * This has to be implemented in user code.
+ *
+ * @param[in] device_id Device identifier.
+ * @param[out] address  Device local hardware address.
+ *
+ * @return EOK on success.
+ * @return EBADMEM if the address parameter is NULL.
+ * @return ENOENT if there no such device.
+ * @return Other error codes as defined for the find_device()
+ *         function.
+ * @return Other error codes as defined for the specific module
+ *         message implementation.
+ *
+ */
+extern int netif_get_addr_message(device_id_t device_id,
+    measured_string_t *address);
+
+/** Process the netif driver specific message.
+ *
+ * This function is called for uncommon messages received by the netif
+ * skeleton. This has to be implemented in user code.
+ *
+ * @param[in]  callid Message identifier.
+ * @param[in]  call   Message.
+ * @param[out] answer Answer.
+ * @param[out] count  Number of answer arguments.
+ *
+ * @return EOK on success.
+ * @return ENOTSUP if the message is not known.
+ * @return Other error codes as defined for the specific module
+ *         message implementation.
+ *
+ */
+extern int netif_specific_message(ipc_callid_t callid, ipc_call_t *call,
+    ipc_call_t *answer, size_t *count);
+
+/** Return the device usage statistics.
+ *
+ * This has to be implemented in user code.
+ *
+ * @param[in]  device_id Device identifier.
+ * @param[out] stats     Device usage statistics.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the find_device()
+ *         function.
+ * @return Other error codes as defined for the specific module
+ *         message implementation.
+ *
+ */
+extern int netif_get_device_stats(device_id_t device_id,
+    device_stats_t *stats);
+
+extern int find_device(device_id_t, netif_device_t **);
+extern void null_device_stats(device_stats_t *);
+extern void netif_pq_release(packet_id_t);
+extern packet_t *netif_packet_get_1(size_t);
+
+extern int netif_module_start(void);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/net/include/nil_local.h
===================================================================
--- uspace/lib/net/include/nil_local.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/net/include/nil_local.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -96,5 +96,5 @@
  */
 extern int nil_message_standalone(const char *, ipc_callid_t, ipc_call_t *,
-    ipc_call_t *, int *);
+    ipc_call_t *, size_t *);
 
 /** Pass the parameters to the module specific nil_message() function.
@@ -112,5 +112,5 @@
  */
 extern int nil_module_message_standalone(const char *, ipc_callid_t,
-    ipc_call_t *, ipc_call_t *, int *);
+    ipc_call_t *, ipc_call_t *, size_t *);
 
 /** Start the standalone nil layer module.
Index: uspace/lib/net/include/socket_core.h
===================================================================
--- uspace/lib/net/include/socket_core.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/net/include/socket_core.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -86,5 +86,5 @@
 	void *specific_data;
 	/** Socket ports map key. */
-	const char *key;
+	const uint8_t *key;
 	/** Length of the Socket ports map key. */
 	size_t key_length;
@@ -118,9 +118,9 @@
     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 char *,
+extern socket_core_t *socket_port_find(socket_ports_t *, int, const uint8_t *,
     size_t);
 extern void socket_port_release(socket_ports_t *, socket_core_t *);
 extern int socket_port_add(socket_ports_t *, int, socket_core_t *,
-    const char *, size_t);
+    const uint8_t *, size_t);
 
 #endif
Index: uspace/lib/net/include/tl_local.h
===================================================================
--- uspace/lib/net/include/tl_local.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/net/include/tl_local.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -52,6 +52,5 @@
  */
 extern int tl_module_message_standalone(ipc_callid_t, ipc_call_t *,
-    ipc_call_t *, int *);
-
+    ipc_call_t *, size_t *);
 
 /** Processes the TL module message.
Index: pace/lib/net/netif/netif_local.c
===================================================================
--- uspace/lib/net/netif/netif_local.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,458 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * 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 libnet 
- * @{
- */
-
-/** @file
- * Network interface module skeleton implementation.
- * @see netif.h
- */
-
-#include <async.h>
-#include <mem.h>
-#include <fibril_synch.h>
-#include <stdio.h>
-#include <ipc/ipc.h>
-#include <ipc/services.h>
-#include <ipc/netif.h>
-#include <errno.h>
-
-#include <generic.h>
-#include <net/modules.h>
-#include <net/packet.h>
-#include <packet_client.h>
-#include <packet_remote.h>
-#include <adt/measured_strings.h>
-#include <net/device.h>
-#include <nil_interface.h>
-#include <netif_local.h>
-#include <netif_interface.h>
-
-DEVICE_MAP_IMPLEMENT(netif_device_map, netif_device_t);
-
-/** Network interface global data. */
-netif_globals_t netif_globals;
-
-/** Probe the existence of the device.
- *
- * @param[in] netif_phone The network interface phone.
- * @param[in] device_id	The device identifier.
- * @param[in] irq	The device interrupt number.
- * @param[in] io	The device input/output address.
- * @return		EOK on success.
- * @return		Other error codes as defined for the
- *			netif_probe_message().
- */
-int
-netif_probe_req_local(int netif_phone, device_id_t device_id, int irq, int io)
-{
-	fibril_rwlock_write_lock(&netif_globals.lock);
-	int result = netif_probe_message(device_id, irq, io);
-	fibril_rwlock_write_unlock(&netif_globals.lock);
-	
-	return result;
-}
-
-/** Send the packet queue.
- *
- * @param[in] netif_phone The network interface phone.
- * @param[in] device_id	The device identifier.
- * @param[in] packet	The packet queue.
- * @param[in] sender	The sending module service.
- * @return		EOK on success.
- * @return		Other error codes as defined for the generic_send_msg()
- *			function.
- */
-int netif_send_msg_local(int netif_phone, device_id_t device_id,
-    packet_t *packet, services_t sender)
-{
-	fibril_rwlock_write_lock(&netif_globals.lock);
-	int result = netif_send_message(device_id, packet, sender);
-	fibril_rwlock_write_unlock(&netif_globals.lock);
-	
-	return result;
-}
-
-/** Start the device.
- *
- * @param[in] netif_phone The network interface phone.
- * @param[in] device_id	The device identifier.
- * @return		EOK on success.
- * @return		Other error codes as defined for the find_device()
- *			function.
- * @return		Other error codes as defined for the
- *			netif_start_message() function.
- */
-int netif_start_req_local(int netif_phone, device_id_t device_id)
-{
-	int rc;
-	
-	fibril_rwlock_write_lock(&netif_globals.lock);
-	
-	netif_device_t *device;
-	rc = find_device(device_id, &device);
-	if (rc != EOK) {
-		fibril_rwlock_write_unlock(&netif_globals.lock);
-		return rc;
-	}
-	
-	int result = netif_start_message(device);
-	if (result > NETIF_NULL) {
-		int phone = device->nil_phone;
-		fibril_rwlock_write_unlock(&netif_globals.lock);
-		nil_device_state_msg(phone, device_id, result);
-		return EOK;
-	}
-	
-	fibril_rwlock_write_unlock(&netif_globals.lock);
-	
-	return result;
-}
-
-/** Stop the device.
- *
- * @param[in] netif_phone The network interface phone.
- * @param[in] device_id	The device identifier.
- * @return		EOK on success.
- * @return		Other error codes as defined for the find_device()
- *			function.
- * @return		Other error codes as defined for the
- *			netif_stop_message() function.
- */
-int netif_stop_req_local(int netif_phone, device_id_t device_id)
-{
-	int rc;
-	
-	fibril_rwlock_write_lock(&netif_globals.lock);
-	
-	netif_device_t *device;
-	rc = find_device(device_id, &device);
-	if (rc != EOK) {
-		fibril_rwlock_write_unlock(&netif_globals.lock);
-		return rc;
-	}
-	
-	int result = netif_stop_message(device);
-	if (result > NETIF_NULL) {
-		int phone = device->nil_phone;
-		fibril_rwlock_write_unlock(&netif_globals.lock);
-		nil_device_state_msg(phone, device_id, result);
-		return EOK;
-	}
-	
-	fibril_rwlock_write_unlock(&netif_globals.lock);
-	
-	return result;
-}
-
-/** Return the device usage statistics.
- *
- * @param[in] netif_phone The network interface phone.
- * @param[in] device_id	The device identifier.
- * @param[out] stats	The device usage statistics.
- * @return EOK on success.
- */
-int netif_stats_req_local(int netif_phone, device_id_t device_id,
-    device_stats_t *stats)
-{
-	fibril_rwlock_read_lock(&netif_globals.lock);
-	int res = netif_get_device_stats(device_id, stats);
-	fibril_rwlock_read_unlock(&netif_globals.lock);
-	
-	return res;
-}
-
-/** Return the device local hardware address.
- *
- * @param[in] netif_phone The network interface phone.
- * @param[in] device_id	The device identifier.
- * @param[out] address	The device local hardware address.
- * @param[out] data	The address data.
- * @return		EOK on success.
- * @return		EBADMEM if the address parameter is NULL.
- * @return		ENOENT if there no such device.
- * @return		Other error codes as defined for the
- *			netif_get_addr_message() function.
- */
-int netif_get_addr_req_local(int netif_phone, device_id_t device_id,
-    measured_string_t **address, char **data)
-{
-	int rc;
-	
-	if (!address || !data)
-		return EBADMEM;
-	
-	fibril_rwlock_read_lock(&netif_globals.lock);
-	
-	measured_string_t translation;
-	rc = netif_get_addr_message(device_id, &translation);
-	if (rc == EOK) {
-		*address = measured_string_copy(&translation);
-		rc = (*address) ? EOK : ENOMEM;
-	}
-	
-	fibril_rwlock_read_unlock(&netif_globals.lock);
-	
-	*data = (**address).value;
-	
-	return rc;
-}
-
-/** Find the device specific data.
- *
- * @param[in] device_id	The device identifier.
- * @param[out] device	The device specific data.
- * @return		EOK on success.
- * @return		ENOENT if device is not found.
- * @return		EPERM if the device is not initialized.
- */
-int find_device(device_id_t device_id, netif_device_t **device)
-{
-	if (!device)
-		return EBADMEM;
-	
-	*device = netif_device_map_find(&netif_globals.device_map, device_id);
-	if (*device == NULL)
-		return ENOENT;
-	
-	if ((*device)->state == NETIF_NULL)
-		return EPERM;
-	
-	return EOK;
-}
-
-/** Clear the usage statistics.
- *
- * @param[in] stats	The usage statistics.
- */
-void null_device_stats(device_stats_t *stats)
-{
-	bzero(stats, sizeof(device_stats_t));
-}
-
-/** Initialize the netif module.
- *
- * @param[in] client_connection The client connection functio to be registered.
- * @return		EOK on success.
- * @return		Other error codes as defined for each specific module
- *			message function.
- */
-int netif_init_module(async_client_conn_t client_connection)
-{
-	int rc;
-	
-	async_set_client_connection(client_connection);
-	
-	netif_globals.net_phone = connect_to_service(SERVICE_NETWORKING);
-	netif_device_map_initialize(&netif_globals.device_map);
-	
-	rc = pm_init();
-	if (rc != EOK)
-		return rc;
-	
-	fibril_rwlock_initialize(&netif_globals.lock);
-	
-	rc = netif_initialize();
-	if (rc != EOK) {
-		pm_destroy();
-		return rc;
-	}
-	
-	return EOK;
-}
-
-/** Release the given packet.
- *
- * Prepared for future optimization.
- *
- * @param[in] packet_id	The packet identifier.
- */
-void netif_pq_release(packet_id_t packet_id)
-{
-	pq_release_remote(netif_globals.net_phone, packet_id);
-}
-
-/** Allocate new packet to handle the given content size.
- *
- * @param[in] content	The minimum content size.
- * @return		The allocated packet.
- * @return		NULL if there is an error.
- *
- */
-packet_t *netif_packet_get_1(size_t content)
-{
-	return packet_get_1_remote(netif_globals.net_phone, content);
-}
-
-/** Register the device notification receiver, the network interface layer
- * module.
- *
- * @param[in] name	Module name.
- * @param[in] device_id	The device identifier.
- * @param[in] phone	The network interface layer module phone.
- * @return		EOK on success.
- * @return		ENOENT if there is no such device.
- * @return		ELIMIT if there is another module registered.
- */
-static int register_message(const char *name, device_id_t device_id, int phone)
-{
-	netif_device_t *device;
-	int rc;
-	
-	rc = find_device(device_id, &device);
-	if (rc != EOK)
-		return rc;
-	
-	if (device->nil_phone > 0)
-		return ELIMIT;
-	
-	device->nil_phone = phone;
-	printf("%s: Receiver of device %d registered (phone: %d)\n",
-	    name, device->device_id, device->nil_phone);
-	return EOK;
-}
-
-/** Process the netif module messages.
- *
- * @param[in] name 	Module name.
- * @param[in] callid	The message identifier.
- * @param[in] call	The message parameters.
- * @param[out] answer	The message answer parameters.
- * @param[out] answer_count The last parameter for the actual answer in the
- *			answer parameter.
- * @return		EOK on success.
- * @return		ENOTSUP if the message is not known.
- * @return		Other error codes as defined for each specific module
- *			message function.
- *
- * @see IS_NET_NETIF_MESSAGE()
- *
- */
-int netif_module_message_standalone(const char *name, ipc_callid_t callid,
-    ipc_call_t *call, ipc_call_t *answer, int *answer_count)
-{
-	size_t length;
-	device_stats_t stats;
-	packet_t *packet;
-	measured_string_t address;
-	int rc;
-	
-	*answer_count = 0;
-	switch (IPC_GET_IMETHOD(*call)) {
-	case IPC_M_PHONE_HUNGUP:
-		return EOK;
-	
-	case NET_NETIF_PROBE:
-		return netif_probe_req_local(0, IPC_GET_DEVICE(call),
-		    NETIF_GET_IRQ(call), NETIF_GET_IO(call));
-		    
-	case IPC_M_CONNECT_TO_ME:
-		fibril_rwlock_write_lock(&netif_globals.lock);
-		rc = register_message(name, 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,
-		    IPC_GET_PACKET(call));
-		if (rc != EOK)
-			return rc;
-		return netif_send_msg_local(0, IPC_GET_DEVICE(call), packet,
-		    IPC_GET_SENDER(call));
-		
-	case NET_NETIF_START:
-		return netif_start_req_local(0, IPC_GET_DEVICE(call));
-		
-	case NET_NETIF_STATS:
-		fibril_rwlock_read_lock(&netif_globals.lock);
-
-		rc = async_data_read_receive(&callid, &length);
-		if (rc != EOK) {
-			fibril_rwlock_read_unlock(&netif_globals.lock);
-			return rc;
-		}
-		if (length < sizeof(device_stats_t)) {
-			fibril_rwlock_read_unlock(&netif_globals.lock);
-			return EOVERFLOW;
-		}
-
-		rc = netif_get_device_stats(IPC_GET_DEVICE(call), &stats);
-		if (rc == EOK) {
-			rc = async_data_read_finalize(callid, &stats,
-			    sizeof(device_stats_t));
-		}
-
-		fibril_rwlock_read_unlock(&netif_globals.lock);
-		return rc;
-
-	case NET_NETIF_STOP:
-		return netif_stop_req_local(0, IPC_GET_DEVICE(call));
-		
-	case NET_NETIF_GET_ADDR:
-		fibril_rwlock_read_lock(&netif_globals.lock);
-		rc = netif_get_addr_message(IPC_GET_DEVICE(call), &address);
-		if (rc == EOK)
-			rc = measured_strings_reply(&address, 1);
-		fibril_rwlock_read_unlock(&netif_globals.lock);
-		return rc;
-	}
-	
-	return netif_specific_message(callid, call, answer, answer_count);
-}
-
-/** Start the network interface module.
- *
- * Initialize the client connection serving function, initialize the module,
- * registers the module service and start the async manager, processing IPC
- * messages in an infinite loop.
- *
- * @param[in] client_connection The client connection processing function.
- *			The module skeleton propagates its own one.
- * @return		EOK on success.
- * @return		Other error codes as defined for each specific module
- *			message function.
- */
-int netif_module_start_standalone(async_client_conn_t client_connection)
-{
-	int rc;
-	
-	rc = netif_init_module(client_connection);
-	if (rc != EOK)
-		return rc;
-	
-	async_manager();
-	
-	pm_destroy();
-	return EOK;
-}
-
-/** @}
- */
Index: uspace/lib/net/netif/netif_remote.c
===================================================================
--- uspace/lib/net/netif/netif_remote.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/net/netif/netif_remote.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup libnet 
+/** @addtogroup libnet
  * @{
  */
@@ -49,16 +49,18 @@
 /** Return the device local hardware address.
  *
- * @param[in] netif_phone The network interface phone.
- * @param[in] device_id	The device identifier.
- * @param[out] address	The device local hardware address.
- * @param[out] data	The address data.
- * @return		EOK on success.
- * @return		EBADMEM if the address parameter is NULL.
- * @return		ENOENT if there no such device.
- * @return		Other error codes as defined for the
- *			netif_get_addr_message() function.
+ * @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.
+ *
+ * @return EOK on success.
+ * @return EBADMEM if the address parameter is NULL.
+ * @return ENOENT if there no such device.
+ * @return Other error codes as defined for the
+ *         netif_get_addr_message() function.
+ *
  */
-int netif_get_addr_req_remote(int netif_phone, device_id_t device_id,
-    measured_string_t **address, char **data)
+int netif_get_addr_req(int netif_phone, 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,
@@ -68,30 +70,33 @@
 /** Probe the existence of the device.
  *
- * @param[in] netif_phone The network interface phone.
- * @param[in] device_id	The device identifier.
- * @param[in] irq	The device interrupt number.
- * @param[in] io	The device input/output address.
- * @return		EOK on success.
- * @return		Other error codes as defined for the
- *			netif_probe_message().
+ * @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.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the
+ *         netif_probe_message().
+ *
  */
-int
-netif_probe_req_remote(int netif_phone, device_id_t device_id, int irq, int io)
+int netif_probe_req(int netif_phone, device_id_t device_id, int irq, void *io)
 {
-	return async_req_3_0(netif_phone, NET_NETIF_PROBE, device_id, irq, io);
+	return async_req_3_0(netif_phone, NET_NETIF_PROBE, device_id, irq,
+	    (sysarg_t) io);
 }
 
 /** Send the packet queue.
  *
- * @param[in] netif_phone The network interface phone.
- * @param[in] device_id	The device identifier.
- * @param[in] packet	The packet queue.
- * @param[in] sender	The sending module service.
- * @return		EOK on success.
- * @return		Other error codes as defined for the generic_send_msg()
- *			function.
+ * @param[in] netif_phone Network interface phone.
+ * @param[in] device_id   Device identifier.
+ * @param[in] packet      Packet queue.
+ * @param[in] sender      Sending module service.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the generic_send_msg()
+ *         function.
+ *
  */
-int
-netif_send_msg_remote(int netif_phone, device_id_t device_id, packet_t *packet,
+int netif_send_msg(int netif_phone, device_id_t device_id, packet_t *packet,
     services_t sender)
 {
@@ -102,13 +107,15 @@
 /** Start the device.
  *
- * @param[in] netif_phone The network interface phone.
- * @param[in] device_id	The device identifier.
- * @return		EOK on success.
- * @return		Other error codes as defined for the find_device()
- *			function.
- * @return		Other error codes as defined for the
- *			netif_start_message() function.
+ * @param[in] netif_phone Network interface phone.
+ * @param[in] device_id   Device identifier.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the find_device()
+ *         function.
+ * @return Other error codes as defined for the
+ *         netif_start_message() function.
+ *
  */
-int netif_start_req_remote(int netif_phone, device_id_t device_id)
+int netif_start_req(int netif_phone, device_id_t device_id)
 {
 	return async_req_1_0(netif_phone, NET_NETIF_START, device_id);
@@ -117,13 +124,15 @@
 /** Stop the device.
  *
- * @param[in] netif_phone The network interface phone.
- * @param[in] device_id	The device identifier.
- * @return		EOK on success.
- * @return		Other error codes as defined for the find_device()
- *			function.
- * @return		Other error codes as defined for the
- *			netif_stop_message() function.
+ * @param[in] netif_phone Network interface phone.
+ * @param[in] device_id   Device identifier.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the find_device()
+ *         function.
+ * @return Other error codes as defined for the
+ *         netif_stop_message() function.
+ *
  */
-int netif_stop_req_remote(int netif_phone, device_id_t device_id)
+int netif_stop_req(int netif_phone, device_id_t device_id)
 {
 	return async_req_1_0(netif_phone, NET_NETIF_STOP, device_id);
@@ -132,10 +141,12 @@
 /** Return the device usage statistics.
  *
- * @param[in] netif_phone The network interface phone.
- * @param[in] device_id	The device identifier.
- * @param[out] stats	The device usage statistics.
+ * @param[in] netif_phone Network interface phone.
+ * @param[in] device_id   Device identifier.
+ * @param[out] stats      Device usage statistics.
+ *
  * @return EOK on success.
+ *
  */
-int netif_stats_req_remote(int netif_phone, device_id_t device_id,
+int netif_stats_req(int netif_phone, device_id_t device_id,
     device_stats_t *stats)
 {
@@ -153,6 +164,8 @@
 }
 
-/** Create bidirectional connection with the network interface module and
- * registers the message receiver.
+/** Create bidirectional connection with the network interface module
+ *
+ * Create bidirectional connection with the network interface module and
+ * register the message receiver.
  *
  * @param[in] service   The network interface module service.
@@ -161,11 +174,11 @@
  * @param[in] receiver  The 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 The phone of the needed service.
+ * @return EOK on success.
+ * @return Other error codes as defined for the bind_service()
+ *         function.
+ *
  */
-int
-netif_bind_service_remote(services_t service, device_id_t device_id,
+int 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 f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/lib/net/netif/netif_skel.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,434 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * 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 libnet
+ * @{
+ */
+
+/** @file
+ * Network interface module skeleton implementation.
+ * @see netif.h
+ */
+
+#include <async.h>
+#include <mem.h>
+#include <fibril_synch.h>
+#include <stdio.h>
+#include <ipc/ipc.h>
+#include <ipc/services.h>
+#include <ipc/netif.h>
+#include <errno.h>
+
+#include <generic.h>
+#include <net/modules.h>
+#include <net/packet.h>
+#include <packet_client.h>
+#include <packet_remote.h>
+#include <adt/measured_strings.h>
+#include <net/device.h>
+#include <nil_interface.h>
+#include <netif_skel.h>
+
+DEVICE_MAP_IMPLEMENT(netif_device_map, netif_device_t);
+
+/** Network interface global data. */
+netif_globals_t netif_globals;
+
+/** 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.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the
+ *         netif_probe_message().
+ *
+ */
+static int netif_probe_req_local(int netif_phone, device_id_t device_id,
+    int irq, void *io)
+{
+	fibril_rwlock_write_lock(&netif_globals.lock);
+	int result = netif_probe_message(device_id, irq, io);
+	fibril_rwlock_write_unlock(&netif_globals.lock);
+	
+	return result;
+}
+
+/** 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.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the generic_send_msg()
+ *         function.
+ *
+ */
+static int netif_send_msg_local(int netif_phone, device_id_t device_id,
+    packet_t *packet, services_t sender)
+{
+	fibril_rwlock_write_lock(&netif_globals.lock);
+	int result = netif_send_message(device_id, packet, sender);
+	fibril_rwlock_write_unlock(&netif_globals.lock);
+	
+	return result;
+}
+
+/** Start the device.
+ *
+ * @param[in] netif_phone Network interface phone.
+ * @param[in] device_id   Device identifier.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the find_device()
+ *         function.
+ * @return Other error codes as defined for the
+ *         netif_start_message() function.
+ *
+ */
+static int netif_start_req_local(int netif_phone, device_id_t device_id)
+{
+	fibril_rwlock_write_lock(&netif_globals.lock);
+	
+	netif_device_t *device;
+	int rc = find_device(device_id, &device);
+	if (rc != EOK) {
+		fibril_rwlock_write_unlock(&netif_globals.lock);
+		return rc;
+	}
+	
+	int result = netif_start_message(device);
+	if (result > NETIF_NULL) {
+		int phone = device->nil_phone;
+		fibril_rwlock_write_unlock(&netif_globals.lock);
+		nil_device_state_msg(phone, device_id, result);
+		return EOK;
+	}
+	
+	fibril_rwlock_write_unlock(&netif_globals.lock);
+	
+	return result;
+}
+
+/** Stop the device.
+ *
+ * @param[in] netif_phone Network interface phone.
+ * @param[in] device_id   Device identifier.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the find_device()
+ *         function.
+ * @return Other error codes as defined for the
+ *         netif_stop_message() function.
+ *
+ */
+static int netif_stop_req_local(int netif_phone, device_id_t device_id)
+{
+	fibril_rwlock_write_lock(&netif_globals.lock);
+	
+	netif_device_t *device;
+	int rc = find_device(device_id, &device);
+	if (rc != EOK) {
+		fibril_rwlock_write_unlock(&netif_globals.lock);
+		return rc;
+	}
+	
+	int result = netif_stop_message(device);
+	if (result > NETIF_NULL) {
+		int phone = device->nil_phone;
+		fibril_rwlock_write_unlock(&netif_globals.lock);
+		nil_device_state_msg(phone, device_id, result);
+		return EOK;
+	}
+	
+	fibril_rwlock_write_unlock(&netif_globals.lock);
+	
+	return result;
+}
+
+/** Find the device specific data.
+ *
+ * @param[in]  device_id Device identifier.
+ * @param[out] device    Device specific data.
+ *
+ * @return EOK on success.
+ * @return ENOENT if device is not found.
+ * @return EPERM if the device is not initialized.
+ *
+ */
+int find_device(device_id_t device_id, netif_device_t **device)
+{
+	if (!device)
+		return EBADMEM;
+	
+	*device = netif_device_map_find(&netif_globals.device_map, device_id);
+	if (*device == NULL)
+		return ENOENT;
+	
+	if ((*device)->state == NETIF_NULL)
+		return EPERM;
+	
+	return EOK;
+}
+
+/** Clear the usage statistics.
+ *
+ * @param[in] stats The usage statistics.
+ *
+ */
+void null_device_stats(device_stats_t *stats)
+{
+	bzero(stats, sizeof(device_stats_t));
+}
+
+/** Release the given packet.
+ *
+ * Prepared for future optimization.
+ *
+ * @param[in] packet_id The packet identifier.
+ *
+ */
+void netif_pq_release(packet_id_t packet_id)
+{
+	pq_release_remote(netif_globals.net_phone, packet_id);
+}
+
+/** Allocate new packet to handle the given content size.
+ *
+ * @param[in] content Minimum content size.
+ *
+ * @return The allocated packet.
+ * @return NULL on error.
+ *
+ */
+packet_t *netif_packet_get_1(size_t content)
+{
+	return packet_get_1_remote(netif_globals.net_phone, content);
+}
+
+/** Register the device notification receiver,
+ *
+ * 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.
+ * @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)
+		return ELIMIT;
+	
+	device->nil_phone = phone;
+	return EOK;
+}
+
+/** Process the netif module messages.
+ *
+ * @param[in]  callid Mmessage identifier.
+ * @param[in]  call   Message.
+ * @param[out] answer Answer.
+ * @param[out] count  Number of arguments of the answer.
+ *
+ * @return EOK on success.
+ * @return ENOTSUP if the message is unknown.
+ * @return Other error codes as defined for each specific module
+ *         message function.
+ *
+ * @see IS_NET_NETIF_MESSAGE()
+ *
+ */
+static int netif_module_message(ipc_callid_t callid, ipc_call_t *call,
+    ipc_call_t *answer, size_t *count)
+{
+	size_t length;
+	device_stats_t stats;
+	packet_t *packet;
+	measured_string_t address;
+	int rc;
+	
+	*count = 0;
+	
+	switch (IPC_GET_IMETHOD(*call)) {
+	case IPC_M_PHONE_HUNGUP:
+		return EOK;
+	
+	case NET_NETIF_PROBE:
+		return netif_probe_req_local(0, IPC_GET_DEVICE(*call),
+		    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,
+		    IPC_GET_PACKET(*call));
+		if (rc != EOK)
+			return rc;
+		
+		return netif_send_msg_local(0, IPC_GET_DEVICE(*call), packet,
+		    IPC_GET_SENDER(*call));
+	
+	case NET_NETIF_START:
+		return netif_start_req_local(0, IPC_GET_DEVICE(*call));
+	
+	case NET_NETIF_STATS:
+		fibril_rwlock_read_lock(&netif_globals.lock);
+		
+		rc = async_data_read_receive(&callid, &length);
+		if (rc != EOK) {
+			fibril_rwlock_read_unlock(&netif_globals.lock);
+			return rc;
+		}
+		
+		if (length < sizeof(device_stats_t)) {
+			fibril_rwlock_read_unlock(&netif_globals.lock);
+			return EOVERFLOW;
+		}
+		
+		rc = netif_get_device_stats(IPC_GET_DEVICE(*call), &stats);
+		if (rc == EOK) {
+			rc = async_data_read_finalize(callid, &stats,
+			    sizeof(device_stats_t));
+		}
+		
+		fibril_rwlock_read_unlock(&netif_globals.lock);
+		return rc;
+	
+	case NET_NETIF_STOP:
+		return netif_stop_req_local(0, IPC_GET_DEVICE(*call));
+	
+	case NET_NETIF_GET_ADDR:
+		fibril_rwlock_read_lock(&netif_globals.lock);
+		
+		rc = netif_get_addr_message(IPC_GET_DEVICE(*call), &address);
+		if (rc == EOK)
+			rc = measured_strings_reply(&address, 1);
+		
+		fibril_rwlock_read_unlock(&netif_globals.lock);
+		return rc;
+	}
+	
+	return netif_specific_message(callid, call, answer, count);
+}
+
+/** Default fibril for new module connections.
+ *
+ * @param[in] iid   Initial message identifier.
+ * @param[in] icall Initial message call structure.
+ *
+ */
+static void netif_client_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	/*
+	 * Accept the connection by answering
+	 * the initial IPC_M_CONNECT_ME_TO call.
+	 */
+	ipc_answer_0(iid, EOK);
+	
+	while (true) {
+		ipc_call_t answer;
+		size_t count;
+		
+		/* Clear the answer structure */
+		refresh_answer(&answer, &count);
+		
+		/* Fetch the next message */
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+		
+		/* Process the message */
+		int res = netif_module_message(callid, &call, &answer, &count);
+		
+		/* End if said to either by the message or the processing result */
+		if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
+		    (res == EHANGUP))
+			return;
+		
+		/* Answer the message */
+		answer_call(callid, res, &answer, count);
+	}
+}
+
+/** Start the network interface module.
+ *
+ * Initialize the client connection serving function, initialize the module,
+ * registers the module service and start the async manager, processing IPC
+ * messages in an infinite loop.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for each specific module
+ *         message function.
+ *
+ */
+int netif_module_start(void)
+{
+	async_set_client_connection(netif_client_connection);
+	
+	netif_globals.net_phone = connect_to_service(SERVICE_NETWORKING);
+	netif_device_map_initialize(&netif_globals.device_map);
+	
+	int rc = pm_init();
+	if (rc != EOK)
+		return rc;
+	
+	fibril_rwlock_initialize(&netif_globals.lock);
+	
+	rc = netif_initialize();
+	if (rc != EOK) {
+		pm_destroy();
+		return rc;
+	}
+	
+	async_manager();
+	
+	pm_destroy();
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/net/tl/socket_core.c
===================================================================
--- uspace/lib/net/tl/socket_core.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/net/tl/socket_core.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -161,5 +161,5 @@
 static int
 socket_port_add_core(socket_port_t *socket_port, socket_core_t *socket,
-    const char *key, size_t key_length)
+    const uint8_t *key, size_t key_length)
 {
 	socket_core_t **socket_ref;
@@ -216,6 +216,6 @@
 		goto fail;
 	
-	rc = socket_port_add_core(socket_port, socket, SOCKET_MAP_KEY_LISTENING,
-	    0);
+	rc = socket_port_add_core(socket_port, socket,
+	    (const uint8_t *) SOCKET_MAP_KEY_LISTENING, 0);
 	if (rc != EOK)
 		goto fail;
@@ -602,5 +602,5 @@
  */
 socket_core_t *
-socket_port_find(socket_ports_t *global_sockets, int port, const char *key,
+socket_port_find(socket_ports_t *global_sockets, int port, const uint8_t *key,
     size_t key_length)
 {
@@ -680,5 +680,5 @@
 int
 socket_port_add(socket_ports_t *global_sockets, int port,
-    socket_core_t *socket, const char *key, size_t key_length)
+    socket_core_t *socket, const uint8_t *key, size_t key_length)
 {
 	socket_port_t *socket_port;
Index: uspace/lib/packet/generic/packet_server.c
===================================================================
--- uspace/lib/packet/generic/packet_server.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/packet/generic/packet_server.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -322,5 +322,5 @@
 int
 packet_server_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
-    int *answer_count)
+    size_t *answer_count)
 {
 	packet_t *packet;
@@ -333,5 +333,5 @@
 	case NET_PACKET_CREATE_1:
 		packet = packet_get_local(DEFAULT_ADDR_LEN, DEFAULT_PREFIX,
-		    IPC_GET_CONTENT(call), DEFAULT_SUFFIX);
+		    IPC_GET_CONTENT(*call), DEFAULT_SUFFIX);
 		if (!packet)
 			return ENOMEM;
@@ -343,9 +343,9 @@
 	case NET_PACKET_CREATE_4:
 		packet = packet_get_local(
-		    ((DEFAULT_ADDR_LEN < IPC_GET_ADDR_LEN(call)) ?
-		    IPC_GET_ADDR_LEN(call) : DEFAULT_ADDR_LEN),
-		    DEFAULT_PREFIX + IPC_GET_PREFIX(call),
-		    IPC_GET_CONTENT(call),
-		    DEFAULT_SUFFIX + IPC_GET_SUFFIX(call));
+		    ((DEFAULT_ADDR_LEN < IPC_GET_ADDR_LEN(*call)) ?
+		    IPC_GET_ADDR_LEN(*call) : DEFAULT_ADDR_LEN),
+		    DEFAULT_PREFIX + IPC_GET_PREFIX(*call),
+		    IPC_GET_CONTENT(*call),
+		    DEFAULT_SUFFIX + IPC_GET_SUFFIX(*call));
 		if (!packet)
 			return ENOMEM;
@@ -356,5 +356,5 @@
 	
 	case NET_PACKET_GET:
-		packet = pm_find(IPC_GET_ID(call));
+		packet = pm_find(IPC_GET_ID(*call));
 		if (!packet_is_valid(packet))
 			return ENOENT;
@@ -362,5 +362,5 @@
 	
 	case NET_PACKET_GET_SIZE:
-		packet = pm_find(IPC_GET_ID(call));
+		packet = pm_find(IPC_GET_ID(*call));
 		if (!packet_is_valid(packet))
 			return ENOENT;
@@ -370,5 +370,5 @@
 	
 	case NET_PACKET_RELEASE:
-		return packet_release_wrapper(IPC_GET_ID(call));
+		return packet_release_wrapper(IPC_GET_ID(*call));
 	}
 	
Index: uspace/lib/packet/include/packet_server.h
===================================================================
--- uspace/lib/packet/include/packet_server.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/packet/include/packet_server.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -48,5 +48,5 @@
 
 extern int packet_server_message(ipc_callid_t, ipc_call_t *, ipc_call_t *,
-    int *);
+    size_t *);
 
 #endif
Index: uspace/lib/usb/include/usb/devreq.h
===================================================================
--- uspace/lib/usb/include/usb/devreq.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/usb/include/usb/devreq.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -85,5 +85,14 @@
 } __attribute__ ((packed)) usb_device_request_setup_packet_t;
 
+
+int usb_drv_req_get_status(int, usb_address_t, usb_request_recipient_t,
+    uint16_t, uint16_t *);
+int usb_drv_req_clear_feature(int, usb_address_t, usb_request_recipient_t,
+    uint16_t, uint16_t);
+int usb_drv_req_set_feature(int, usb_address_t, usb_request_recipient_t,
+    uint16_t, uint16_t);
 int usb_drv_req_set_address(int, usb_address_t, usb_address_t);
+int usb_drv_req_get_descriptor(int, usb_address_t, usb_request_type_t,
+    uint8_t, uint8_t, uint16_t, void *, size_t, size_t *);
 int usb_drv_req_get_device_descriptor(int, usb_address_t,
     usb_standard_device_descriptor_t *);
@@ -92,5 +101,10 @@
 int usb_drv_req_get_full_configuration_descriptor(int, usb_address_t, int,
     void *, size_t, size_t *);
-
+int usb_drv_req_set_descriptor(int, usb_address_t, uint8_t, uint8_t, uint16_t,
+    void *, size_t);
+int usb_drv_req_get_configuration(int, usb_address_t, uint8_t *);
+int usb_drv_req_set_configuration(int, usb_address_t, uint8_t);
+int usb_drv_req_get_interface(int, usb_address_t, uint16_t, uint8_t *);
+int usb_drv_req_set_interface(int, usb_address_t, uint16_t, uint8_t);
 
 #endif
Index: uspace/lib/usb/include/usb/usb.h
===================================================================
--- uspace/lib/usb/include/usb/usb.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/usb/include/usb/usb.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -54,4 +54,18 @@
 	USB_DIRECTION_OUT
 } usb_direction_t;
+
+/** USB request type target. */
+typedef enum {
+	USB_REQUEST_TYPE_STANDARD = 0,
+	USB_REQUEST_TYPE_CLASS = 1,
+	USB_REQUEST_TYPE_VENDOR = 2
+} usb_request_type_t;
+
+/** USB request recipient. */
+typedef enum {
+	USB_REQUEST_RECIPIENT_DEVICE = 0,
+	USB_REQUEST_RECIPIENT_INTERFACE = 1,
+	USB_REQUEST_RECIPIENT_ENDPOINT = 2
+} usb_request_recipient_t;
 
 /** USB transaction outcome. */
Index: uspace/lib/usb/include/usb/usbdrv.h
===================================================================
--- uspace/lib/usb/include/usb/usbdrv.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/usb/include/usb/usbdrv.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -96,4 +96,9 @@
 int usb_drv_async_wait_for(usb_handle_t);
 
+int usb_drv_create_match_ids_from_device_descriptor(match_id_list_t *,
+    const usb_standard_device_descriptor_t *);
+int usb_drv_create_match_ids_from_configuration_descriptor(match_id_list_t *,
+    const void *, size_t);
+
 int usb_drv_create_device_match_ids(int, match_id_list_t *, usb_address_t);
 int usb_drv_register_child_in_devman(int, device_t *, usb_address_t,
Index: uspace/lib/usb/src/addrkeep.c
===================================================================
--- uspace/lib/usb/src/addrkeep.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/usb/src/addrkeep.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -187,4 +187,8 @@
 		new_address_position = addresses->used_addresses.next;
 	} else {
+		usb_address_keeping_used_t *first
+		    = used_address_get_instance(addresses->used_addresses.next);
+		previous_address = first->address;
+		
 		for_all_used_addresses(new_address_position, addresses) {
 			usb_address_keeping_used_t *info
@@ -194,4 +198,5 @@
 				break;
 			}
+			previous_address = info->address;
 		}
 
Index: uspace/lib/usb/src/recognise.c
===================================================================
--- uspace/lib/usb/src/recognise.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/usb/src/recognise.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -129,4 +129,103 @@
 }
 
+/** Create DDF match ids from USB device descriptor.
+ *
+ * @param matches List of match ids to extend.
+ * @param device_descriptor Device descriptor returned by given device.
+ * @return Error code.
+ */
+int usb_drv_create_match_ids_from_device_descriptor(
+    match_id_list_t *matches,
+    const usb_standard_device_descriptor_t *device_descriptor)
+{
+	int rc;
+	
+	/*
+	 * Unless the vendor id is 0, the pair idVendor-idProduct
+	 * quite uniquely describes the device.
+	 */
+	if (device_descriptor->vendor_id != 0) {
+		/* First, with release number. */
+		rc = usb_add_match_id(matches, 100,
+		    "usb&vendor=%d&product=%d&release=" BCD_FMT,
+		    (int) device_descriptor->vendor_id,
+		    (int) device_descriptor->product_id,
+		    BCD_ARGS(device_descriptor->device_version));
+		if (rc != EOK) {
+			return rc;
+		}
+		
+		/* Next, without release number. */
+		rc = usb_add_match_id(matches, 90, "usb&vendor=%d&product=%d",
+		    (int) device_descriptor->vendor_id,
+		    (int) device_descriptor->product_id);
+		if (rc != EOK) {
+			return rc;
+		}
+	}	
+
+	/*
+	 * If the device class points to interface we skip adding
+	 * class directly.
+	 */
+	if (device_descriptor->device_class != USB_CLASS_USE_INTERFACE) {
+		rc = usb_add_match_id(matches, 50, "usb&class=%s",
+		    usb_str_class(device_descriptor->device_class));
+		if (rc != EOK) {
+			return rc;
+		}
+	}
+	
+	return EOK;
+}
+
+/** Create DDF match ids from USB configuration descriptor.
+ * The configuration descriptor is expected to be in the complete form,
+ * i.e. including interface, endpoint etc. descriptors.
+ *
+ * @param matches List of match ids to extend.
+ * @param config_descriptor Configuration descriptor returned by given device.
+ * @param total_size Size of the @p config_descriptor.
+ * @return Error code.
+ */
+int usb_drv_create_match_ids_from_configuration_descriptor(
+    match_id_list_t *matches,
+    const void *config_descriptor, size_t total_size)
+{
+	/*
+	 * Iterate through config descriptor to find the interface
+	 * descriptors.
+	 */
+	size_t position = sizeof(usb_standard_configuration_descriptor_t);
+	while (position + 1 < total_size) {
+		uint8_t *current_descriptor
+		    = ((uint8_t *) config_descriptor) + position;
+		uint8_t cur_descr_len = current_descriptor[0];
+		uint8_t cur_descr_type = current_descriptor[1];
+		
+		position += cur_descr_len;
+		
+		if (cur_descr_type != USB_DESCTYPE_INTERFACE) {
+			continue;
+		}
+		
+		/*
+		 * Finally, we found an interface descriptor.
+		 */
+		usb_standard_interface_descriptor_t *interface
+		    = (usb_standard_interface_descriptor_t *)
+		    current_descriptor;
+		
+		int rc = usb_add_match_id(matches, 50,
+		    "usb&interface&class=%s",
+		    usb_str_class(interface->interface_class));
+		if (rc != EOK) {
+			return rc;
+		}
+	}
+	
+	return EOK;
+}
+
 /** Add match ids based on configuration descriptor.
  *
@@ -169,36 +268,13 @@
 			continue;
 		}
-
-		/*
-		 * Iterate through config descriptor to find the interface
-		 * descriptors.
-		 */
-		size_t position = sizeof(config_descriptor);
-		while (position + 1 < full_config_descriptor_size) {
-			uint8_t *current_descriptor
-			    = ((uint8_t *) full_config_descriptor) + position;
-			uint8_t cur_descr_len = current_descriptor[0];
-			uint8_t cur_descr_type = current_descriptor[1];
-			
-			position += cur_descr_len;
-			
-			if (cur_descr_type != USB_DESCTYPE_INTERFACE) {
-				continue;
-			}
-			/*
-			 * Finally, we found an interface descriptor.
-			 */
-			usb_standard_interface_descriptor_t *interface
-			    = (usb_standard_interface_descriptor_t *)
-			    current_descriptor;
-			
-			rc = usb_add_match_id(matches, 50,
-			    "usb&interface&class=%s",
-			    usb_str_class(interface->interface_class));
-			if (rc != EOK) {
-				final_rc = rc;
-				break;
-			}
-		}
+		
+		rc = usb_drv_create_match_ids_from_configuration_descriptor(
+		    matches,
+		    full_config_descriptor, full_config_descriptor_size);
+		if (rc != EOK) {
+			final_rc = rc;
+			continue;
+		}
+		
 	}
 	
@@ -220,4 +296,8 @@
 {
 	int rc;
+	
+	/*
+	 * Retrieve device descriptor and add matches from it.
+	 */
 	usb_standard_device_descriptor_t device_descriptor;
 
@@ -227,41 +307,11 @@
 		return rc;
 	}
-
-	/*
-	 * Unless the vendor id is 0, the pair idVendor-idProduct
-	 * quite uniquely describes the device.
-	 */
-	if (device_descriptor.vendor_id != 0) {
-		/* First, with release number. */
-		rc = usb_add_match_id(matches, 100,
-		    "usb&vendor=%d&product=%d&release=" BCD_FMT,
-		    (int) device_descriptor.vendor_id,
-		    (int) device_descriptor.product_id,
-		    BCD_ARGS(device_descriptor.device_version));
-		if (rc != EOK) {
-			return rc;
-		}
-		
-		/* Next, without release number. */
-		rc = usb_add_match_id(matches, 90, "usb&vendor=%d&product=%d",
-		    (int) device_descriptor.vendor_id,
-		    (int) device_descriptor.product_id);
-		if (rc != EOK) {
-			return rc;
-		}
-
-	}	
-
-	/*
-	 * If the device class points to interface we skip adding
-	 * class directly.
-	 */
-	if (device_descriptor.device_class != USB_CLASS_USE_INTERFACE) {
-		rc = usb_add_match_id(matches, 50, "usb&class=%s",
-		    usb_str_class(device_descriptor.device_class));
-		if (rc != EOK) {
-			return rc;
-		}
-	}
+	
+	rc = usb_drv_create_match_ids_from_device_descriptor(matches,
+	    &device_descriptor);
+	if (rc != EOK) {
+		return rc;
+	}
+	
 	/*
 	 * Go through all configurations and add matches
Index: uspace/lib/usb/src/usbdrvreq.c
===================================================================
--- uspace/lib/usb/src/usbdrvreq.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/lib/usb/src/usbdrvreq.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -36,4 +36,146 @@
 #include <errno.h>
 
+/**  Prepare USB target for control endpoint.
+ *
+ * @param name Variable name with the USB target.
+ * @param target_address Target USB address.
+ */
+#define PREPARE_TARGET(name, target_address) \
+	usb_target_t name = { \
+		.address = target_address, \
+		.endpoint = 0 \
+	}
+
+/** Prepare setup packet.
+ *
+ * @param name Variable name with the setup packet.
+ * @param p_direction Data transfer direction.
+ * @param p_type Request type (standard/class/vendor)
+ * @param p_recipient Recipient of the request.
+ * @param p_request Request.
+ * @param p_value wValue field of setup packet.
+ * @param p_index wIndex field of setup packet.
+ * @param p_length Length of extra data.
+ */
+#define PREPARE_SETUP_PACKET(name, p_direction, p_type, p_recipient, \
+    p_request, p_value, p_index, p_length) \
+	usb_device_request_setup_packet_t setup_packet = { \
+		.request_type = \
+			((p_direction) == USB_DIRECTION_IN ? 128 : 0) \
+			| ((p_type) << 5) \
+			| (p_recipient), \
+		.request = (p_request), \
+		{ .value = (p_value) }, \
+		.index = (p_index), \
+		.length = (p_length) \
+	}
+
+/** Prepare setup packet.
+ *
+ * @param name Variable name with the setup packet.
+ * @param p_direction Data transfer direction.
+ * @param p_type Request type (standard/class/vendor)
+ * @param p_recipient Recipient of the request.
+ * @param p_request Request.
+ * @param p_value_low wValue field of setup packet (low byte).
+ * @param p_value_high wValue field of setup packet (high byte).
+ * @param p_index wIndex field of setup packet.
+ * @param p_length Length of extra data.
+ */
+#define PREPARE_SETUP_PACKET_LOHI(name, p_direction, p_type, p_recipient, \
+    p_request, p_value_low, p_value_high, p_index, p_length) \
+	PREPARE_SETUP_PACKET(name, p_direction, p_type, p_recipient, \
+	    p_request, (p_value_low) | ((p_value_high) << 8), \
+	    p_index, p_length)
+
+/** Retrieve status of a USB device.
+ *
+ * @param[in] hc_phone Open phone to HC driver.
+ * @param[in] address Device address.
+ * @param[in] recipient Recipient of the request.
+ * @param[in] recipient_index Index of @p recipient.
+ * @param[out] status Status (see figure 9-4 in USB 1.1 specification).
+ * @return Error code.
+ */
+int usb_drv_req_get_status(int hc_phone, usb_address_t address,
+    usb_request_recipient_t recipient, uint16_t recipient_index,
+    uint16_t *status)
+{
+	if (status == NULL) {
+		return EBADMEM;
+	}
+
+	PREPARE_TARGET(target, address);
+
+	PREPARE_SETUP_PACKET(setup_packet,
+	    USB_DIRECTION_IN, USB_REQUEST_TYPE_STANDARD,
+	    recipient, USB_DEVREQ_GET_STATUS, 0, recipient_index, 2);
+
+	size_t transfered;
+	uint16_t tmp_status;
+	int rc = usb_drv_psync_control_read(hc_phone, target,
+	    &setup_packet, sizeof(setup_packet), &tmp_status, 2, &transfered);
+	if (rc != EOK) {
+		return rc;
+	}
+	if (transfered != 2) {
+		return ERANGE;
+	}
+
+	*status = tmp_status;
+
+	return EOK;
+}
+
+/** Clear or disable USB device feature.
+ *
+ * @param[in] hc_phone Open phone to HC driver.
+ * @param[in] address Device address.
+ * @param[in] recipient Recipient of the request.
+ * @param[in] selector Feature selector.
+ * @param[in] index Index of @p recipient.
+ * @return Error code.
+ */
+int usb_drv_req_clear_feature(int hc_phone, usb_address_t address,
+    usb_request_recipient_t recipient,
+    uint16_t selector, uint16_t index)
+{
+	PREPARE_TARGET(target, address);
+
+	PREPARE_SETUP_PACKET(setup_packet,
+	    USB_DIRECTION_OUT, USB_REQUEST_TYPE_STANDARD,
+	    recipient, USB_DEVREQ_CLEAR_FEATURE, selector, index, 0);
+
+	int rc = usb_drv_psync_control_write(hc_phone, target,
+	    &setup_packet, sizeof(setup_packet), NULL, 0);
+
+	return rc;
+}
+
+/** Set or enable USB device feature.
+ *
+ * @param[in] hc_phone Open phone to HC driver.
+ * @param[in] address Device address.
+ * @param[in] recipient Recipient of the request.
+ * @param[in] selector Feature selector.
+ * @param[in] index Index of @p recipient.
+ * @return Error code.
+ */
+int usb_drv_req_set_feature(int hc_phone, usb_address_t address,
+    usb_request_recipient_t recipient,
+    uint16_t selector, uint16_t index)
+{
+	PREPARE_TARGET(target, address);
+
+	PREPARE_SETUP_PACKET(setup_packet,
+	    USB_DIRECTION_OUT, USB_REQUEST_TYPE_STANDARD,
+	    recipient, USB_DEVREQ_SET_FEATURE, selector, index, 0);
+
+	int rc = usb_drv_psync_control_write(hc_phone, target,
+	    &setup_packet, sizeof(setup_packet), NULL, 0);
+
+	return rc;
+}
+
 /** Change address of connected device.
  *
@@ -44,7 +186,7 @@
  * @see usb_drv_bind_address
  *
- * @param phone Open phone to HC driver.
- * @param old_address Current address.
- * @param address Address to be set.
+ * @param[in] phone Open phone to HC driver.
+ * @param[in] old_address Current address.
+ * @param[in] address Address to be set.
  * @return Error code.
  */
@@ -52,18 +194,9 @@
     usb_address_t new_address)
 {
-	/* Prepare the target. */
-	usb_target_t target = {
-		.address = old_address,
-		.endpoint = 0
-	};
-
-	/* Prepare the setup packet. */
-	usb_device_request_setup_packet_t setup_packet = {
-		.request_type = 0,
-		.request = USB_DEVREQ_SET_ADDRESS,
-		.index = 0,
-		.length = 0,
-	};
-	setup_packet.value = new_address;
+	PREPARE_TARGET(target, old_address);
+
+	PREPARE_SETUP_PACKET(setup_packet, USB_DIRECTION_OUT,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DEVREQ_SET_ADDRESS, new_address, 0, 0);
 
 	int rc = usb_drv_psync_control_write(phone, target,
@@ -73,8 +206,50 @@
 }
 
+/** Retrieve USB descriptor of connected USB device.
+ *
+ * @param[in] hc_phone Open phone to HC driver.
+ * @param[in] address Device address.
+ * @param[in] request_type Request type (standard/class/vendor).
+ * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
+ * @param[in] descriptor_index Descriptor index.
+ * @param[in] language Language index.
+ * @param[out] buffer Buffer where to store the retrieved descriptor.
+ * @param[in] size Size of the @p buffer.
+ * @param[out] actual_size Number of bytes actually transferred.
+ * @return Error code.
+ */
+int usb_drv_req_get_descriptor(int hc_phone, usb_address_t address,
+    usb_request_type_t request_type,
+    uint8_t descriptor_type, uint8_t descriptor_index,
+    uint16_t language,
+    void *buffer, size_t size, size_t *actual_size)
+{
+	if (buffer == NULL) {
+		return EBADMEM;
+	}
+	if (size == 0) {
+		return EINVAL;
+	}
+
+	// FIXME: check that size is not too big
+
+	PREPARE_TARGET(target, address);
+
+	PREPARE_SETUP_PACKET_LOHI(setup_packet, USB_DIRECTION_IN,
+	    request_type, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DEVREQ_GET_DESCRIPTOR, descriptor_index, descriptor_type,
+	    language, size);
+
+	int rc = usb_drv_psync_control_read(hc_phone, target,
+	    &setup_packet, sizeof(setup_packet),
+	    buffer, size, actual_size);
+	
+	return rc;
+}
+
 /** Retrieve device descriptor of connected USB device.
  *
  * @param[in] phone Open phone to HC driver.
- * @param[in] address Device USB address.
+ * @param[in] address Device address.
  * @param[out] descriptor Storage for the device descriptor.
  * @return Error code.
@@ -87,29 +262,13 @@
 		return EBADMEM;
 	}
-
-	/* Prepare the target. */
-	usb_target_t target = {
-		.address = address,
-		.endpoint = 0
-	};
-
-	/* Prepare the setup packet. */
-	usb_device_request_setup_packet_t setup_packet = {
-		.request_type = 128,
-		.request = USB_DEVREQ_GET_DESCRIPTOR,
-		.index = 0,
-		.length = sizeof(usb_standard_device_descriptor_t)
-	};
-	setup_packet.value_high = USB_DESCTYPE_DEVICE;
-	setup_packet.value_low = 0;
-
-	/* Prepare local descriptor. */
+	
 	size_t actually_transferred = 0;
 	usb_standard_device_descriptor_t descriptor_tmp;
-
-	/* Perform the control read transaction. */
-	int rc = usb_drv_psync_control_read(phone, target,
-	    &setup_packet, sizeof(setup_packet),
-	    &descriptor_tmp, sizeof(descriptor_tmp), &actually_transferred);
+	int rc = usb_drv_req_get_descriptor(phone, address,
+	    USB_REQUEST_TYPE_STANDARD,
+	    USB_DESCTYPE_DEVICE, 0,
+	    0,
+	    &descriptor_tmp, sizeof(descriptor_tmp),
+	    &actually_transferred);
 
 	if (rc != EOK) {
@@ -137,5 +296,5 @@
  *
  * @param[in] phone Open phone to HC driver.
- * @param[in] address Device USB address.
+ * @param[in] address Device address.
  * @param[in] index Configuration descriptor index.
  * @param[out] descriptor Storage for the configuration descriptor.
@@ -150,29 +309,13 @@
 		return EBADMEM;
 	}
-
-	/* Prepare the target. */
-	usb_target_t target = {
-		.address = address,
-		.endpoint = 0
-	};
-
-	/* Prepare the setup packet. */
-	usb_device_request_setup_packet_t setup_packet = {
-		.request_type = 128,
-		.request = USB_DEVREQ_GET_DESCRIPTOR,
-		.index = 0,
-		.length = sizeof(usb_standard_configuration_descriptor_t)
-	};
-	setup_packet.value_high = USB_DESCTYPE_CONFIGURATION;
-	setup_packet.value_low = index;
-
-	/* Prepare local descriptor. */
+	
 	size_t actually_transferred = 0;
 	usb_standard_configuration_descriptor_t descriptor_tmp;
-
-	/* Perform the control read transaction. */
-	int rc = usb_drv_psync_control_read(phone, target,
-	    &setup_packet, sizeof(setup_packet),
-	    &descriptor_tmp, sizeof(descriptor_tmp), &actually_transferred);
+	int rc = usb_drv_req_get_descriptor(phone, address,
+	    USB_REQUEST_TYPE_STANDARD,
+	    USB_DESCTYPE_CONFIGURATION, 0,
+	    0,
+	    &descriptor_tmp, sizeof(descriptor_tmp),
+	    &actually_transferred);
 
 	if (rc != EOK) {
@@ -195,8 +338,8 @@
  *
  * @warning The @p buffer might be touched (i.e. its contents changed)
- * even when error occurres.
+ * even when error occurs.
  *
  * @param[in] phone Open phone to HC driver.
- * @param[in] address Device USB address.
+ * @param[in] address Device address.
  * @param[in] index Configuration descriptor index.
  * @param[out] buffer Buffer for the whole configuration descriptor.
@@ -210,32 +353,169 @@
     void *buffer, size_t buffer_size, size_t *actual_buffer_size)
 {
-	if (buffer == NULL) {
+	int rc = usb_drv_req_get_descriptor(phone, address,
+	    USB_REQUEST_TYPE_STANDARD,
+	    USB_DESCTYPE_CONFIGURATION, 0,
+	    0,
+	    buffer, buffer_size,
+	    actual_buffer_size);
+
+	return rc;
+}
+
+/** Update existing descriptor of a USB device.
+ *
+ * @param[in] hc_phone Open phone to HC driver.
+ * @param[in] address Device address.
+ * @param[in] descriptor_type Descriptor type (device/configuration/...).
+ * @param[in] descriptor_index Descriptor index.
+ * @param[in] language Language index.
+ * @param[in] descriptor Actual descriptor data.
+ * @param[in] descriptor_size Descriptor size.
+ * @return Error code.
+ */
+int usb_drv_req_set_descriptor(int hc_phone, usb_address_t address,
+    uint8_t descriptor_type, uint8_t descriptor_index,
+    uint16_t language,
+    void *descriptor, size_t descriptor_size)
+{
+	// FIXME: check that descriptor is not too big
+
+	PREPARE_TARGET(target, address);
+
+	PREPARE_SETUP_PACKET_LOHI(setup_packet, USB_DIRECTION_OUT,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DEVREQ_SET_DESCRIPTOR, descriptor_index, descriptor_type,
+	    language, descriptor_size);
+
+	int rc = usb_drv_psync_control_write(hc_phone, target,
+	    &setup_packet, sizeof(setup_packet),
+	    descriptor, descriptor_size);
+
+	return rc;
+}
+
+/** Determine current configuration value of USB device.
+ *
+ * @param[in] hc_phone Open phone to HC driver.
+ * @param[in] address Device address.
+ * @param[out] configuration_value Current configuration value.
+ * @return Error code.
+ */
+int usb_drv_req_get_configuration(int hc_phone, usb_address_t address,
+    uint8_t *configuration_value)
+{
+	if (configuration_value == NULL) {
 		return EBADMEM;
 	}
 
-	/* Prepare the target. */
-	usb_target_t target = {
-		.address = address,
-		.endpoint = 0
-	};
-
-	/* Prepare the setup packet. */
-	usb_device_request_setup_packet_t setup_packet = {
-		.request_type = 128,
-		.request = USB_DEVREQ_GET_DESCRIPTOR,
-		.index = 0,
-		.length = buffer_size
-	};
-	setup_packet.value_high = USB_DESCTYPE_CONFIGURATION;
-	setup_packet.value_low = index;
-
-	/* Perform the control read transaction. */
-	int rc = usb_drv_psync_control_read(phone, target,
-	    &setup_packet, sizeof(setup_packet),
-	    buffer, buffer_size, actual_buffer_size);
-
-	return rc;
-}
-
+	PREPARE_TARGET(target, address);
+
+	PREPARE_SETUP_PACKET(setup_packet, USB_DIRECTION_IN,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DEVREQ_GET_CONFIGURATION, 0, 0, 1);
+
+	uint8_t value;
+	size_t transfered;
+	int rc = usb_drv_psync_control_read(hc_phone, target,
+	    &setup_packet, sizeof(setup_packet), &value, 1, &transfered);
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	if (transfered != 1) {
+		return ERANGE;
+	}
+
+	*configuration_value = value;
+
+	return EOK;
+}
+
+/** Set configuration of USB device.
+ *
+ * @param[in] hc_phone Open phone to HC driver.
+ * @param[in] address Device address.
+ * @param[in] configuration_value New configuration value.
+ * @return Error code.
+ */
+int usb_drv_req_set_configuration(int hc_phone, usb_address_t address,
+    uint8_t configuration_value)
+{
+	PREPARE_TARGET(target, address);
+
+	PREPARE_SETUP_PACKET_LOHI(setup_packet, USB_DIRECTION_OUT,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DEVREQ_SET_CONFIGURATION, configuration_value, 0,
+	    0, 0);
+
+	int rc = usb_drv_psync_control_write(hc_phone, target,
+	    &setup_packet, sizeof(setup_packet), NULL, 0);
+
+	return rc;
+}
+
+/** Determine alternate setting of USB device interface.
+ *
+ * @param[in] hc_phone Open phone to HC driver.
+ * @param[in] address Device address.
+ * @param[in] interface_index Interface index.
+ * @param[out] alternate_setting Value of alternate setting.
+ * @return Error code.
+ */
+int usb_drv_req_get_interface(int hc_phone, usb_address_t address,
+    uint16_t interface_index, uint8_t *alternate_setting)
+{
+	if (alternate_setting == NULL) {
+		return EBADMEM;
+	}
+
+	PREPARE_TARGET(target, address);
+
+	PREPARE_SETUP_PACKET(setup_packet, USB_DIRECTION_IN,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
+	    USB_DEVREQ_GET_INTERFACE, 0, interface_index, 1);
+
+	uint8_t alternate;
+	size_t transfered;
+	int rc = usb_drv_psync_control_read(hc_phone, target,
+	    &setup_packet, sizeof(setup_packet), &alternate, 1, &transfered);
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	if (transfered != 1) {
+		return ERANGE;
+	}
+
+	*alternate_setting = alternate;
+
+	return EOK;
+}
+
+/** Select an alternate setting of USB device interface.
+ *
+ * @param[in] hc_phone Open phone to HC driver.
+ * @param[in] address Device address.
+ * @param[in] interface_index Interface index.
+ * @param[in] alternate_setting Value of alternate setting.
+ * @return Error code.
+ */
+int usb_drv_req_set_interface(int hc_phone, usb_address_t address,
+    uint16_t interface_index, uint8_t alternate_setting)
+{
+	PREPARE_TARGET(target, address);
+
+	PREPARE_SETUP_PACKET_LOHI(setup_packet, USB_DIRECTION_OUT,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
+	    USB_DEVREQ_SET_INTERFACE, alternate_setting, 0,
+	    0, 0);
+
+	int rc = usb_drv_psync_control_write(hc_phone, target,
+	    &setup_packet, sizeof(setup_packet), NULL, 0);
+
+	return rc;
+}
 
 /**
Index: uspace/srv/bd/ata_bd/ata_bd.c
===================================================================
--- uspace/srv/bd/ata_bd/ata_bd.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/bd/ata_bd/ata_bd.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -171,5 +171,4 @@
 		rc = devmap_device_register(name, &disk[i].devmap_handle);
 		if (rc != EOK) {
-			devmap_hangup_phone(DEVMAP_DRIVER);
 			printf(NAME ": Unable to register device %s.\n", name);
 			return rc;
Index: uspace/srv/bd/file_bd/file_bd.c
===================================================================
--- uspace/srv/bd/file_bd/file_bd.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/bd/file_bd/file_bd.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -120,5 +120,4 @@
 	rc = devmap_device_register(device_name, &devmap_handle);
 	if (rc != EOK) {
-		devmap_hangup_phone(DEVMAP_DRIVER);
 		printf(NAME ": Unable to register device '%s'.\n",
 			device_name);
Index: uspace/srv/bd/gxe_bd/gxe_bd.c
===================================================================
--- uspace/srv/bd/gxe_bd/gxe_bd.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/bd/gxe_bd/gxe_bd.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -145,5 +145,4 @@
 		rc = devmap_device_register(name, &devmap_handle[i]);
 		if (rc != EOK) {
-			devmap_hangup_phone(DEVMAP_DRIVER);
 			printf(NAME ": Unable to register device %s.\n", name);
 			return rc;
Index: uspace/srv/bd/part/guid_part/guid_part.c
===================================================================
--- uspace/srv/bd/part/guid_part/guid_part.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/bd/part/guid_part/guid_part.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -191,5 +191,4 @@
 		rc = devmap_device_register(name, &dev);
 		if (rc != EOK) {
-			devmap_hangup_phone(DEVMAP_DRIVER);
 			printf(NAME ": Unable to register device %s.\n", name);
 			return rc;
Index: uspace/srv/bd/part/mbr_part/mbr_part.c
===================================================================
--- uspace/srv/bd/part/mbr_part/mbr_part.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/bd/part/mbr_part/mbr_part.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -242,5 +242,4 @@
 		rc = devmap_device_register(name, &dev);
 		if (rc != EOK) {
-			devmap_hangup_phone(DEVMAP_DRIVER);
 			printf(NAME ": Unable to register device %s.\n", name);
 			return rc;
Index: uspace/srv/bd/rd/rd.c
===================================================================
--- uspace/srv/bd/rd/rd.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/bd/rd/rd.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -241,5 +241,4 @@
 	devmap_handle_t devmap_handle;
 	if (devmap_device_register("bd/initrd", &devmap_handle) != EOK) {
-		devmap_hangup_phone(DEVMAP_DRIVER);
 		printf("%s: Unable to register device\n", NAME);
 		return false;
Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/devman/devman.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -793,5 +793,5 @@
 		/* Notify the driver about the new device. */
 		int phone = async_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);
-		if (phone > 0) {
+		if (phone >= 0) {
 			add_device(phone, drv, node, tree);
 			ipc_hangup(phone);
Index: uspace/srv/fs/devfs/devfs_ops.c
===================================================================
--- uspace/srv/fs/devfs/devfs_ops.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/fs/devfs/devfs_ops.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -454,7 +454,4 @@
 		return false;
 	
-	if (devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING) < 0)
-		return false;
-	
 	return true;
 }
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/hid/console/console.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -930,5 +930,4 @@
 			
 			if (devmap_device_register(vc, &consoles[i].devmap_handle) != EOK) {
-				devmap_hangup_phone(DEVMAP_DRIVER);
 				printf(NAME ": Unable to register device %s\n", vc);
 				return false;
Index: uspace/srv/hid/kbd/port/ns16550.c
===================================================================
--- uspace/srv/hid/kbd/port/ns16550.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/hid/kbd/port/ns16550.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -36,5 +36,5 @@
 
 #include <ipc/ipc.h>
-#include <ipc/bus.h>
+#include <ipc/irc.h>
 #include <async.h>
 #include <sysinfo.h>
@@ -122,5 +122,5 @@
 	
 	if (cir_service)
-		async_msg_1(cir_phone, BUS_CLEAR_INTERRUPT,
+		async_msg_1(cir_phone, IRC_CLEAR_INTERRUPT,
 		    IPC_GET_IMETHOD(*call));
 }
Index: uspace/srv/hid/kbd/port/z8530.c
===================================================================
--- uspace/srv/hid/kbd/port/z8530.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/hid/kbd/port/z8530.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -36,5 +36,5 @@
 
 #include <ipc/ipc.h>
-#include <ipc/bus.h>
+#include <ipc/irc.h>
 #include <async.h>
 #include <sysinfo.h>
@@ -110,5 +110,5 @@
 	
 	if (cir_service)
-		async_msg_1(cir_phone, BUS_CLEAR_INTERRUPT,
+		async_msg_1(cir_phone, IRC_CLEAR_INTERRUPT,
 		    IPC_GET_IMETHOD(*call));
 }
Index: uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c
===================================================================
--- uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -102,5 +102,4 @@
 	rc = devmap_device_register(NAMESPACE "/mouse", &ts->devmap_handle);
 	if (rc != EOK) {
-		devmap_hangup_phone(DEVMAP_DRIVER);
 		printf(NAME ": Unable to register device %s.\n",
 		    NAMESPACE "/mouse");
Index: uspace/srv/hw/bus/cuda_adb/cuda_adb.c
===================================================================
--- uspace/srv/hw/bus/cuda_adb/cuda_adb.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/hw/bus/cuda_adb/cuda_adb.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -162,5 +162,4 @@
 	rc = devmap_device_register("adb/kbd", &devmap_handle);
 	if (rc != EOK) {
-		devmap_hangup_phone(DEVMAP_DRIVER);
 		printf(NAME ": Unable to register device %s.\n", "adb/kdb");
 		return rc;
@@ -172,5 +171,4 @@
 	rc = devmap_device_register("adb/mouse", &devmap_handle);
 	if (rc != EOK) {
-		devmap_hangup_phone(DEVMAP_DRIVER);
 		printf(NAME ": Unable to register device %s.\n", "adb/mouse");
 		return rc;
Index: uspace/srv/hw/char/i8042/i8042.c
===================================================================
--- uspace/srv/hw/char/i8042/i8042.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/hw/char/i8042/i8042.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -148,5 +148,4 @@
 		rc = devmap_device_register(name, &i8042_port[i].devmap_handle);
 		if (rc != EOK) {
-			devmap_hangup_phone(DEVMAP_DRIVER);
 			printf(NAME ": Unable to register device %s.\n", name);
 			return rc;
Index: uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c
===================================================================
--- uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -95,5 +95,4 @@
 	rc = devmap_device_register(NAMESPACE "/" NAME, &uart->devmap_handle);
 	if (rc != EOK) {
-		devmap_hangup_phone(DEVMAP_DRIVER);
 		printf(NAME ": Unable to register device %s.\n",
 		    NAMESPACE "/" NAME);
Index: pace/srv/hw/cir/fhc/Makefile
===================================================================
--- uspace/srv/hw/cir/fhc/Makefile	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(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: pace/srv/hw/cir/fhc/fhc.c
===================================================================
--- uspace/srv/hw/cir/fhc/fhc.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,157 +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/ipc.h>
-#include <ipc/services.h>
-#include <ipc/bus.h>
-#include <ipc/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.
- */
-static void fhc_connection(ipc_callid_t iid, ipc_call_t *icall)
-{
-	ipc_callid_t callid;
-	ipc_call_t call;
-
-	/*
-	 * Answer the first IPC_M_CONNECT_ME_TO call.
-	 */
-	ipc_answer_0(iid, EOK);
-
-	while (1) {
-		int inr;
-	
-		callid = async_get_call(&call);
-		switch (IPC_GET_IMETHOD(call)) {
-		case BUS_CLEAR_INTERRUPT:
-			inr = IPC_GET_ARG1(call);
-			switch (inr) {
-			case FHC_UART_INR:
-				fhc_uart_virt[FHC_UART_ICLR] = 0;
-				ipc_answer_0(callid, EOK);
-				break;
-			default:
-				ipc_answer_0(callid, ENOTSUP);
-				break;
-			}
-			break;
-		default:
-			ipc_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(NAME ": Error mapping FHC UART registers\n");
-		return false;
-	}
-	
-	printf(NAME ": FHC UART registers at %p, %zu bytes\n", fhc_uart_phys,
-	    fhc_uart_size);
-	
-	async_set_client_connection(fhc_connection);
-	sysarg_t phonead;
-	ipc_connect_to_me(PHONE_NS, SERVICE_FHC, 0, 0, &phonead);
-	
-	return true;
-}
-
-int main(int argc, char **argv)
-{
-	printf(NAME ": HelenOS FHC bus controller driver\n");
-	
-	if (!fhc_init())
-		return -1;
-	
-	printf(NAME ": Accepting connections\n");
-	async_manager();
-
-	/* Never reached */
-	return 0;
-}
-
-/**
- * @}
- */ 
Index: pace/srv/hw/cir/obio/Makefile
===================================================================
--- uspace/srv/hw/cir/obio/Makefile	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(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 = obio
-
-SOURCES = \
-	obio.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/srv/hw/cir/obio/obio.c
===================================================================
--- uspace/srv/hw/cir/obio/obio.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,158 +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 obio 
- * @{
- */ 
-
-/**
- * @file	obio.c
- * @brief	OBIO driver.
- *
- * OBIO is a short for on-board I/O. On UltraSPARC IIi and systems with U2P,
- * there is a piece of the root PCI bus controller address space, which
- * contains interrupt mapping and clear registers for all on-board devices.
- * Although UltraSPARC IIi and U2P are different in general, these registers can
- * be found at the same addresses.
- */
-
-#include <ipc/ipc.h>
-#include <ipc/services.h>
-#include <ipc/bus.h>
-#include <ipc/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 "obio"
-
-#define OBIO_SIZE	0x1898	
-
-#define OBIO_IMR_BASE	0x200
-#define OBIO_IMR(ino)	(OBIO_IMR_BASE + ((ino) & INO_MASK))
-
-#define OBIO_CIR_BASE	0x300
-#define OBIO_CIR(ino)	(OBIO_CIR_BASE + ((ino) & INO_MASK))
-
-#define INO_MASK	0x1f
-
-static void *base_phys;
-static volatile uint64_t *base_virt;
-
-/** Handle one connection to obio.
- *
- * @param iid		Hash of the request that opened the connection.
- * @param icall		Call data of the request that opened the connection.
- */
-static void obio_connection(ipc_callid_t iid, ipc_call_t *icall)
-{
-	ipc_callid_t callid;
-	ipc_call_t call;
-
-	/*
-	 * Answer the first IPC_M_CONNECT_ME_TO call.
-	 */
-	ipc_answer_0(iid, EOK);
-
-	while (1) {
-		int inr;
-	
-		callid = async_get_call(&call);
-		switch (IPC_GET_IMETHOD(call)) {
-		case BUS_CLEAR_INTERRUPT:
-			inr = IPC_GET_ARG1(call);
-			base_virt[OBIO_CIR(inr & INO_MASK)] = 0;
-			ipc_answer_0(callid, EOK);
-			break;
-		default:
-			ipc_answer_0(callid, EINVAL);
-			break;
-		}
-	}
-}
-
-/** Initialize the OBIO driver.
- *
- * So far, the driver heavily depends on information provided by the kernel via
- * sysinfo. In the future, there should be a standalone OBIO driver.
- */
-static bool obio_init(void)
-{
-	sysarg_t paddr;
-	
-	if (sysinfo_get_value("obio.base.physical", &paddr) != EOK) {
-		printf(NAME ": no OBIO registers found\n");
-		return false;
-	}
-	
-	base_phys = (void *) paddr;
-	base_virt = as_get_mappable_page(OBIO_SIZE);
-	
-	int flags = AS_AREA_READ | AS_AREA_WRITE;
-	int retval = physmem_map(base_phys, (void *) base_virt,
-	    ALIGN_UP(OBIO_SIZE, PAGE_SIZE) >> PAGE_WIDTH, flags);
-	
-	if (retval < 0) {
-		printf(NAME ": Error mapping OBIO registers\n");
-		return false;
-	}
-	
-	printf(NAME ": OBIO registers with base at %p\n", base_phys);
-	
-	async_set_client_connection(obio_connection);
-	sysarg_t phonead;
-	ipc_connect_to_me(PHONE_NS, SERVICE_OBIO, 0, 0, &phonead);
-	
-	return true;
-}
-
-int main(int argc, char **argv)
-{
-	printf(NAME ": HelenOS OBIO driver\n");
-	
-	if (!obio_init())
-		return -1;
-	
-	printf(NAME ": Accepting connections\n");
-	async_manager();
-
-	/* Never reached */
-	return 0;
-}
-
-/**
- * @}
- */ 
Index: uspace/srv/hw/irc/apic/Makefile
===================================================================
--- uspace/srv/hw/irc/apic/Makefile	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/srv/hw/irc/apic/Makefile	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,35 @@
+#
+# 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.
+#
+
+USPACE_PREFIX = ../../../..
+BINARY = apic
+
+SOURCES = \
+	apic.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/hw/irc/apic/apic.c
===================================================================
--- uspace/srv/hw/irc/apic/apic.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/srv/hw/irc/apic/apic.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,132 @@
+/*
+ * 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 apic
+ * @{
+ */
+
+/**
+ * @file apic.c
+ * @brief APIC driver.
+ */
+
+#include <ipc/ipc.h>
+#include <ipc/services.h>
+#include <ipc/irc.h>
+#include <ipc/ns.h>
+#include <sysinfo.h>
+#include <as.h>
+#include <ddi.h>
+#include <libarch/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  "apic"
+
+static int apic_enable_irq(sysarg_t irq)
+{
+	// FIXME: TODO
+	return ENOTSUP;
+}
+
+/** Handle one connection to APIC.
+ *
+ * @param iid   Hash of the request that opened the connection.
+ * @param icall Call data of the request that opened the connection.
+ *
+ */
+static void apic_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipc_callid_t callid;
+	ipc_call_t call;
+	
+	/*
+	 * Answer the first IPC_M_CONNECT_ME_TO call.
+	 */
+	ipc_answer_0(iid, EOK);
+	
+	while (true) {
+		callid = async_get_call(&call);
+		
+		switch (IPC_GET_IMETHOD(call)) {
+		case IRC_ENABLE_INTERRUPT:
+			ipc_answer_0(callid, apic_enable_irq(IPC_GET_ARG1(call)));
+			break;
+		case IRC_CLEAR_INTERRUPT:
+			/* Noop */
+			ipc_answer_0(callid, EOK);
+			break;
+		default:
+			ipc_answer_0(callid, EINVAL);
+			break;
+		}
+	}
+}
+
+/** Initialize the APIC driver.
+ *
+ */
+static bool apic_init(void)
+{
+	sysarg_t apic;
+	
+	if ((sysinfo_get_value("apic", &apic) != EOK) || (!apic)) {
+		printf(NAME ": No APIC found\n");
+		return false;
+	}
+	
+	async_set_client_connection(apic_connection);
+	sysarg_t phonead;
+	ipc_connect_to_me(PHONE_NS, SERVICE_APIC, 0, 0, &phonead);
+	
+	return true;
+}
+
+int main(int argc, char **argv)
+{
+	printf(NAME ": HelenOS APIC driver\n");
+	
+	if (!apic_init())
+		return -1;
+	
+	printf(NAME ": Accepting connections\n");
+	async_manager();
+	
+	/* Never reached */
+	return 0;
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hw/irc/fhc/Makefile
===================================================================
--- uspace/srv/hw/irc/fhc/Makefile	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/srv/hw/irc/fhc/Makefile	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,36 @@
+#
+# 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 f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/srv/hw/irc/fhc/fhc.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,161 @@
+/*
+ * 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/ipc.h>
+#include <ipc/services.h>
+#include <ipc/irc.h>
+#include <ipc/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.
+ */
+static void fhc_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipc_callid_t callid;
+	ipc_call_t call;
+
+	/*
+	 * Answer the first IPC_M_CONNECT_ME_TO call.
+	 */
+	ipc_answer_0(iid, EOK);
+
+	while (1) {
+		int inr;
+	
+		callid = async_get_call(&call);
+		switch (IPC_GET_IMETHOD(call)) {
+		case IRC_ENABLE_INTERRUPT:
+			/* Noop */
+			ipc_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;
+				ipc_answer_0(callid, EOK);
+				break;
+			default:
+				ipc_answer_0(callid, ENOTSUP);
+				break;
+			}
+			break;
+		default:
+			ipc_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(NAME ": Error mapping FHC UART registers\n");
+		return false;
+	}
+	
+	printf(NAME ": FHC UART registers at %p, %zu bytes\n", fhc_uart_phys,
+	    fhc_uart_size);
+	
+	async_set_client_connection(fhc_connection);
+	sysarg_t phonead;
+	ipc_connect_to_me(PHONE_NS, SERVICE_FHC, 0, 0, &phonead);
+	
+	return true;
+}
+
+int main(int argc, char **argv)
+{
+	printf(NAME ": HelenOS FHC bus controller driver\n");
+	
+	if (!fhc_init())
+		return -1;
+	
+	printf(NAME ": Accepting connections\n");
+	async_manager();
+
+	/* Never reached */
+	return 0;
+}
+
+/**
+ * @}
+ */ 
Index: uspace/srv/hw/irc/i8259/Makefile
===================================================================
--- uspace/srv/hw/irc/i8259/Makefile	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/srv/hw/irc/i8259/Makefile	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,35 @@
+#
+# 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.
+#
+
+USPACE_PREFIX = ../../../..
+BINARY = i8259
+
+SOURCES = \
+	i8259.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/hw/irc/i8259/i8259.c
===================================================================
--- uspace/srv/hw/irc/i8259/i8259.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/srv/hw/irc/i8259/i8259.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,174 @@
+/*
+ * 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 i8259
+ * @{
+ */
+
+/**
+ * @file i8259.c
+ * @brief i8259 driver.
+ */
+
+#include <ipc/ipc.h>
+#include <ipc/services.h>
+#include <ipc/irc.h>
+#include <ipc/ns.h>
+#include <sysinfo.h>
+#include <as.h>
+#include <ddi.h>
+#include <libarch/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  "i8259"
+
+#define IO_RANGE0_START  ((ioport8_t *) 0x0020U)
+#define IO_RANGE0_SIZE   2
+
+#define IO_RANGE1_START  ((ioport8_t *) 0x00a0U)
+#define IO_RANGE1_SIZE   2
+
+static ioport8_t *io_range0;
+static ioport8_t *io_range1;
+
+#define PIC_PIC0PORT1  0
+#define PIC_PIC0PORT2  1
+
+#define PIC_PIC1PORT1  0
+#define PIC_PIC1PORT2  1
+
+#define PIC_MAX_IRQ  15
+
+static int pic_enable_irq(sysarg_t irq)
+{
+	if (irq > PIC_MAX_IRQ)
+		return ENOENT;
+	
+	uint16_t irqmask = 1 << irq;
+	uint8_t val;
+	
+	if (irqmask & 0xff) {
+		val = pio_read_8(io_range0 + PIC_PIC0PORT2);
+		pio_write_8(io_range0 + PIC_PIC0PORT2,
+		    (uint8_t) (val & (~(irqmask & 0xff))));
+	}
+	
+	if (irqmask >> 8) {
+		val = pio_read_8(io_range1 + PIC_PIC1PORT2);
+		pio_write_8(io_range1 + PIC_PIC1PORT2,
+		    (uint8_t) (val & (~(irqmask >> 8))));
+	}
+	
+	return EOK;
+}
+
+/** Handle one connection to i8259.
+ *
+ * @param iid   Hash of the request that opened the connection.
+ * @param icall Call data of the request that opened the connection.
+ *
+ */
+static void i8259_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipc_callid_t callid;
+	ipc_call_t call;
+	
+	/*
+	 * Answer the first IPC_M_CONNECT_ME_TO call.
+	 */
+	ipc_answer_0(iid, EOK);
+	
+	while (true) {
+		callid = async_get_call(&call);
+		
+		switch (IPC_GET_IMETHOD(call)) {
+		case IRC_ENABLE_INTERRUPT:
+			ipc_answer_0(callid, pic_enable_irq(IPC_GET_ARG1(call)));
+			break;
+		case IRC_CLEAR_INTERRUPT:
+			/* Noop */
+			ipc_answer_0(callid, EOK);
+			break;
+		default:
+			ipc_answer_0(callid, EINVAL);
+			break;
+		}
+	}
+}
+
+/** Initialize the i8259 driver.
+ *
+ */
+static bool i8259_init(void)
+{
+	sysarg_t i8259;
+	
+	if ((sysinfo_get_value("i8259", &i8259) != EOK) || (!i8259)) {
+		printf(NAME ": No i8259 found\n");
+		return false;
+	}
+	
+	if ((pio_enable((void *) IO_RANGE0_START, IO_RANGE0_SIZE,
+	    (void **) &io_range0) != EOK) ||
+	    (pio_enable((void *) IO_RANGE1_START, IO_RANGE1_SIZE,
+	    (void **) &io_range1) != EOK)) {
+		printf(NAME ": i8259 not accessible\n");
+		return false;
+	}
+	
+	async_set_client_connection(i8259_connection);
+	sysarg_t phonead;
+	ipc_connect_to_me(PHONE_NS, SERVICE_I8259, 0, 0, &phonead);
+	
+	return true;
+}
+
+int main(int argc, char **argv)
+{
+	printf(NAME ": HelenOS i8259 driver\n");
+	
+	if (!i8259_init())
+		return -1;
+	
+	printf(NAME ": Accepting connections\n");
+	async_manager();
+	
+	/* Never reached */
+	return 0;
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hw/irc/obio/Makefile
===================================================================
--- uspace/srv/hw/irc/obio/Makefile	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/srv/hw/irc/obio/Makefile	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,36 @@
+#
+# 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 = obio
+
+SOURCES = \
+	obio.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/hw/irc/obio/obio.c
===================================================================
--- uspace/srv/hw/irc/obio/obio.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
+++ uspace/srv/hw/irc/obio/obio.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -0,0 +1,162 @@
+/*
+ * 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 obio 
+ * @{
+ */ 
+
+/**
+ * @file	obio.c
+ * @brief	OBIO driver.
+ *
+ * OBIO is a short for on-board I/O. On UltraSPARC IIi and systems with U2P,
+ * there is a piece of the root PCI bus controller address space, which
+ * contains interrupt mapping and clear registers for all on-board devices.
+ * Although UltraSPARC IIi and U2P are different in general, these registers can
+ * be found at the same addresses.
+ */
+
+#include <ipc/ipc.h>
+#include <ipc/services.h>
+#include <ipc/irc.h>
+#include <ipc/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 "obio"
+
+#define OBIO_SIZE	0x1898	
+
+#define OBIO_IMR_BASE	0x200
+#define OBIO_IMR(ino)	(OBIO_IMR_BASE + ((ino) & INO_MASK))
+
+#define OBIO_CIR_BASE	0x300
+#define OBIO_CIR(ino)	(OBIO_CIR_BASE + ((ino) & INO_MASK))
+
+#define INO_MASK	0x1f
+
+static void *base_phys;
+static volatile uint64_t *base_virt;
+
+/** Handle one connection to obio.
+ *
+ * @param iid		Hash of the request that opened the connection.
+ * @param icall		Call data of the request that opened the connection.
+ */
+static void obio_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipc_callid_t callid;
+	ipc_call_t call;
+
+	/*
+	 * Answer the first IPC_M_CONNECT_ME_TO call.
+	 */
+	ipc_answer_0(iid, EOK);
+
+	while (1) {
+		int inr;
+	
+		callid = async_get_call(&call);
+		switch (IPC_GET_IMETHOD(call)) {
+		case IRC_ENABLE_INTERRUPT:
+			/* Noop */
+			ipc_answer_0(callid, EOK);
+			break;
+		case IRC_CLEAR_INTERRUPT:
+			inr = IPC_GET_ARG1(call);
+			base_virt[OBIO_CIR(inr & INO_MASK)] = 0;
+			ipc_answer_0(callid, EOK);
+			break;
+		default:
+			ipc_answer_0(callid, EINVAL);
+			break;
+		}
+	}
+}
+
+/** Initialize the OBIO driver.
+ *
+ * So far, the driver heavily depends on information provided by the kernel via
+ * sysinfo. In the future, there should be a standalone OBIO driver.
+ */
+static bool obio_init(void)
+{
+	sysarg_t paddr;
+	
+	if (sysinfo_get_value("obio.base.physical", &paddr) != EOK) {
+		printf(NAME ": no OBIO registers found\n");
+		return false;
+	}
+	
+	base_phys = (void *) paddr;
+	base_virt = as_get_mappable_page(OBIO_SIZE);
+	
+	int flags = AS_AREA_READ | AS_AREA_WRITE;
+	int retval = physmem_map(base_phys, (void *) base_virt,
+	    ALIGN_UP(OBIO_SIZE, PAGE_SIZE) >> PAGE_WIDTH, flags);
+	
+	if (retval < 0) {
+		printf(NAME ": Error mapping OBIO registers\n");
+		return false;
+	}
+	
+	printf(NAME ": OBIO registers with base at %p\n", base_phys);
+	
+	async_set_client_connection(obio_connection);
+	sysarg_t phonead;
+	ipc_connect_to_me(PHONE_NS, SERVICE_OBIO, 0, 0, &phonead);
+	
+	return true;
+}
+
+int main(int argc, char **argv)
+{
+	printf(NAME ": HelenOS OBIO driver\n");
+	
+	if (!obio_init())
+		return -1;
+	
+	printf(NAME ": Accepting connections\n");
+	async_manager();
+
+	/* Never reached */
+	return 0;
+}
+
+/**
+ * @}
+ */ 
Index: pace/srv/hw/netif/DRIVER_REMOVAL
===================================================================
--- uspace/srv/hw/netif/DRIVER_REMOVAL	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,5 +1,0 @@
-The netif drivers in this directory are subject to removal / replacement by
-prospective new drivers that meet our criteria for portability, follow our
-coding style and integrate with our device driver framework.
-
-DO NOT ADD ANY NEW DRIVERS HERE OR BASE NEW DRIVERS ON THOSE FOUND HERE.
Index: uspace/srv/hw/netif/dp8390/Makefile
===================================================================
--- uspace/srv/hw/netif/dp8390/Makefile	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/hw/netif/dp8390/Makefile	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -43,5 +43,4 @@
 SOURCES = \
 	dp8390.c \
-	dp8390_module.c \
 	ne2000.c
 
Index: uspace/srv/hw/netif/dp8390/dp8390.c
===================================================================
--- uspace/srv/hw/netif/dp8390/dp8390.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/hw/netif/dp8390/dp8390.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -38,10 +38,14 @@
  */
 
-/** @addtogroup dp8390
+/** @addtogroup ne2000
  *  @{
  */
 
 /** @file
- *  DP8390 network interface core implementation.
+ *
+ * NE2000 (based on DP8390) network interface core implementation.
+ * Only the basic NE2000 PIO (ISA) interface is supported, remote
+ * DMA is completely absent from this code for simplicity.
+ *
  */
 
@@ -49,222 +53,215 @@
 #include <byteorder.h>
 #include <errno.h>
-#include <netif_local.h>
+#include <libarch/ddi.h>
+#include <netif_skel.h>
 #include <net/packet.h>
 #include <nil_interface.h>
 #include <packet_client.h>
-#include "dp8390_drv.h"
-#include "dp8390_port.h"
 #include "dp8390.h"
-#include "ne2000.h"
-
-/** Read a memory block byte by byte.
- *
- *  @param[in] port The source address.
- *  @param[out] buf The destination buffer.
- *  @param[in] size The memory block size in bytes.
- *
- */
-static void outsb(port_t port, void * buf, size_t size);
+
+/** Page size */
+#define DP_PAGE  256
+
+/** 6 * DP_PAGE >= 1514 bytes */
+#define SQ_PAGES  6
+
+/* NE2000 implementation. */
+
+/** NE2000 Data Register */
+#define NE2K_DATA  0x0010
+
+/** NE2000 Reset register */
+#define NE2K_RESET  0x001f
+
+/** NE2000 data start */
+#define NE2K_START  0x4000
+
+/** NE2000 data size */
+#define NE2K_SIZE  0x4000
+
+/** NE2000 retry count */
+#define NE2K_RETRY  100
+
+/** NE2000 error messages rate limiting */
+#define NE2K_ERL  10
+
+/** Minimum Ethernet packet size in bytes */
+#define ETH_MIN_PACK_SIZE  60
+
+/** Maximum Ethernet packet size in bytes */
+#define ETH_MAX_PACK_SIZE_TAGGED  1518
+
+/** Type definition of the receive header
+ *
+ */
+typedef struct {
+	/** Copy of RSR */
+	uint8_t status;
+	
+	/** Pointer to next packet */
+	uint8_t next;
+	
+	/** Receive Byte Count Low */
+	uint8_t rbcl;
+	
+	/** Receive Byte Count High */
+	uint8_t rbch;
+} recv_header_t;
 
 /** Read a memory block word by word.
  *
- *  @param[in] port The source address.
- *  @param[out] buf The destination buffer.
- *  @param[in] size The memory block size in bytes.
- *
- */
-static void outsw(port_t port, void * buf, size_t size);
-
-/*
- * Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
- * on writes to the CR register. Additional CR_STAs do not appear to hurt
- * genuine dp8390s.
- */
-#define CR_EXTRA  CR_STA
-
-static void dp_init(dpeth_t *dep);
-static void dp_reinit(dpeth_t *dep);
-static void dp_reset(dpeth_t *dep);
-static void dp_recv(int nil_phone, device_id_t device_id, dpeth_t *dep);
-static int dp_pkt2user(int nil_phone, device_id_t device_id, dpeth_t *dep, int page, int length);
-static void conf_hw(dpeth_t *dep);
-static void insb(port_t port, void *buf, size_t size);
-static void insw(port_t port, void *buf, size_t size);
-
-int do_probe(dpeth_t *dep)
-{
-	/* This is the default, try to (re)locate the device. */
-	conf_hw(dep);
-	if (!dep->up)
-		/* Probe failed, or the device is configured off. */
+ * @param[in]  port Source address.
+ * @param[out] buf  Destination buffer.
+ * @param[in]  size Memory block size in bytes.
+ *
+ */
+static void pio_read_buf_16(void *port, void *buf, size_t size)
+{
+	size_t i;
+	
+	for (i = 0; (i << 1) < size; i++)
+		*((uint16_t *) buf + i) = pio_read_16((ioport16_t *) (port));
+}
+
+/** Write a memory block word by word.
+ *
+ * @param[in] port Destination address.
+ * @param[in] buf  Source buffer.
+ * @param[in] size Memory block size in bytes.
+ *
+ */
+static void pio_write_buf_16(void *port, void *buf, size_t size)
+{
+	size_t i;
+	
+	for (i = 0; (i << 1) < size; i++)
+		pio_write_16((ioport16_t *) port, *((uint16_t *) buf + i));
+}
+
+static void ne2k_download(ne2k_t *ne2k, void *buf, size_t addr, size_t size)
+{
+	size_t esize = size & ~1;
+	
+	pio_write_8(ne2k->port + DP_RBCR0, esize & 0xff);
+	pio_write_8(ne2k->port + DP_RBCR1, (esize >> 8) & 0xff);
+	pio_write_8(ne2k->port + DP_RSAR0, addr & 0xff);
+	pio_write_8(ne2k->port + DP_RSAR1, (addr >> 8) & 0xff);
+	pio_write_8(ne2k->port + DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
+	
+	if (esize != 0) {
+		pio_read_buf_16(ne2k->data_port, buf, esize);
+		size -= esize;
+		buf += esize;
+	}
+	
+	if (size) {
+		assert(size == 1);
+		
+		uint16_t word = pio_read_16(ne2k->data_port);
+		memcpy(buf, &word, 1);
+	}
+}
+
+static void ne2k_upload(ne2k_t *ne2k, void *buf, size_t addr, size_t size)
+{
+	size_t esize = size & ~1;
+	
+	pio_write_8(ne2k->port + DP_RBCR0, esize & 0xff);
+	pio_write_8(ne2k->port + DP_RBCR1, (esize >> 8) & 0xff);
+	pio_write_8(ne2k->port + DP_RSAR0, addr & 0xff);
+	pio_write_8(ne2k->port + DP_RSAR1, (addr >> 8) & 0xff);
+	pio_write_8(ne2k->port + DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
+	
+	if (esize != 0) {
+		pio_write_buf_16(ne2k->data_port, buf, esize);
+		size -= esize;
+		buf += esize;
+	}
+	
+	if (size) {
+		assert(size == 1);
+		
+		uint16_t word = 0;
+		
+		memcpy(&word, buf, 1);
+		pio_write_16(ne2k->data_port, word);
+	}
+}
+
+/** Probe and initialize the network interface.
+ *
+ * @param[in,out] ne2k Network interface structure.
+ * @param[in]     port Device address.
+ * @param[in]     irq  Device interrupt vector.
+ *
+ * @return EOK on success.
+ * @return EXDEV if the network interface was not recognized.
+ *
+ */
+int ne2k_probe(ne2k_t *ne2k, void *port, int irq)
+{
+	unsigned int i;
+	
+	/* General initialization */
+	ne2k->port = port;
+	ne2k->data_port = ne2k->port + NE2K_DATA;
+	ne2k->irq = irq;
+	ne2k->probed = false;
+	ne2k->up = false;
+	
+	/* Reset the ethernet card */
+	uint8_t val = pio_read_8(ne2k->port + NE2K_RESET);
+	usleep(2000);
+	pio_write_8(ne2k->port + NE2K_RESET, val);
+	usleep(2000);
+	
+	/* Reset the DP8390 */
+	pio_write_8(ne2k->port + DP_CR, CR_STP | CR_DM_ABORT);
+	for (i = 0; i < 0x1000; i++) {
+		if (pio_read_8(ne2k->port + DP_ISR) != 0)
+			break;
+	}
+	
+	/* Check if the DP8390 is really there */
+	val = pio_read_8(ne2k->port + DP_CR);
+	if ((val & (CR_STP | CR_DM_ABORT)) != (CR_STP | CR_DM_ABORT))
 		return EXDEV;
 	
-	if (dep->up)
-		dp_init(dep);
-	
-	return EOK;
-}
-
-/** Initialize and/or start the network interface.
- *
- *  @param[in,out] dep The network interface structure.
- *
- *  @return EOK on success.
- *  @return EXDEV if the network interface is disabled.
- *
- */
-int do_init(dpeth_t *dep)
-{
-	if (!dep->up)
-		/* FIXME: Perhaps call do_probe()? */
-		return EXDEV;
-	
-	assert(dep->up);
-	assert(dep->enabled);
-	
-	dp_reinit(dep);
-	return EOK;
-}
-
-void do_stop(dpeth_t *dep)
-{
-	if ((dep->up) && (dep->enabled)) {
-		outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
-		ne_stop(dep);
-		
-		dep->enabled = false;
-		dep->stopped = false;
-		dep->sending = false;
-		dep->send_avail = false;
-	}
-}
-
-static void dp_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size)
-{
-	size_t ecount = size & ~1;
-	
-	outb_reg0(dep, DP_ISR, ISR_RDC);
-	
-	if (dep->de_16bit) {
-		outb_reg0(dep, DP_RBCR0, ecount & 0xff);
-		outb_reg0(dep, DP_RBCR1, ecount >> 8);
-	} else {
-		outb_reg0(dep, DP_RBCR0, size & 0xff);
-		outb_reg0(dep, DP_RBCR1, size >> 8);
-	}
-	
-	outb_reg0(dep, DP_RSAR0, nic_addr & 0xff);
-	outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
-	outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
-	
-	if (dep->de_16bit) {
-		void *ptr = buf + offset;
-		
-		if (ecount != 0) {
-			outsw(dep->de_data_port, ptr, ecount);
-			size -= ecount;
-			offset += ecount;
-			ptr += ecount;
-		}
-		
-		if (size) {
-			assert(size == 1);
-			
-			uint16_t two_bytes;
-			
-			memcpy(&(((uint8_t *) &two_bytes)[0]), ptr, 1);
-			outw(dep->de_data_port, two_bytes);
-		}
-	} else
-		outsb(dep->de_data_port, buf + offset, size);
-	
-	unsigned int i;
-	for (i = 0; i < 100; i++) {
-		if (inb_reg0(dep, DP_ISR) & ISR_RDC)
-			break;
-	}
-	
-	if (i == 100)
-		fprintf(stderr, "Remote DMA failed to complete\n");
-}
-
-int do_pwrite(dpeth_t *dep, packet_t *packet, int from_int)
-{
-	int size;
-	int sendq_head;
-	
-	assert(dep->up);
-	assert(dep->enabled);
-	
-	if (dep->send_avail) {
-		fprintf(stderr, "Send already in progress\n");
-		return EBUSY;
-	}
-	
-	sendq_head = dep->de_sendq_head;
-	if (dep->de_sendq[sendq_head].sq_filled) {
-		if (from_int)
-			fprintf(stderr, "dp8390: should not be sending\n");
-		dep->send_avail = true;
-		dep->sending = false;
-		
-		return EBUSY;
-	}
-	
-	assert(!dep->sending);
-	
-	void *buf = packet_get_data(packet);
-	size = packet_get_data_length(packet);
-	
-	if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED) {
-		fprintf(stderr, "dp8390: invalid packet size\n");
-		return EINVAL;
-	}
-	
-	dp_user2nic(dep, buf, 0, dep->de_sendq[sendq_head].sq_sendpage
-	    * DP_PAGESIZE, size);
-	dep->de_sendq[sendq_head].sq_filled = true;
-	
-	if (dep->de_sendq_tail == sendq_head) {
-		outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
-		outb_reg0(dep, DP_TBCR1, size >> 8);
-		outb_reg0(dep, DP_TBCR0, size & 0xff);
-		outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);  /* there it goes .. */
-	} else
-		dep->de_sendq[sendq_head].sq_size = size;
-	
-	if (++sendq_head == dep->de_sendq_nr)
-		sendq_head = 0;
-	
-	assert(sendq_head < SENDQ_NR);
-	dep->de_sendq_head = sendq_head;
-	dep->sending = true;
-	
-	if (from_int)
-		return EOK;
-	
-	dep->sending = false;
-	
-	return EOK;
-}
-
-void dp_init(dpeth_t *dep)
-{
-	int dp_rcr_reg;
-	int i;
-	
-	/* General initialization */
-	dep->enabled = false;
-	dep->stopped = false;
-	dep->sending = false;
-	dep->send_avail = false;
-	ne_init(dep);
-	
-	printf("Ethernet address ");
-	for (i = 0; i < 6; i++)
-		printf("%x%c", dep->de_address.ea_addr[i], i < 5 ? ':' : '\n');
+	/* Disable the receiver and init TCR and DCR */
+	pio_write_8(ne2k->port + DP_RCR, RCR_MON);
+	pio_write_8(ne2k->port + DP_TCR, TCR_NORMAL);
+	pio_write_8(ne2k->port + DP_DCR, DCR_WORDWIDE | DCR_8BYTES | DCR_BMS);
+	
+	/* Setup a transfer to get the MAC address */
+	pio_write_8(ne2k->port + DP_RBCR0, ETH_ADDR << 1);
+	pio_write_8(ne2k->port + DP_RBCR1, 0);
+	pio_write_8(ne2k->port + DP_RSAR0, 0);
+	pio_write_8(ne2k->port + DP_RSAR1, 0);
+	pio_write_8(ne2k->port + DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
+	
+	for (i = 0; i < ETH_ADDR; i++)
+		ne2k->mac[i] = pio_read_16(ne2k->data_port);
 	
 	/*
-	 * Initialization of the dp8390 following the mandatory procedure
+	 * Setup send queue. Use the first
+	 * SQ_PAGES of NE2000 memory for the send
+	 * buffer.
+	 */
+	ne2k->sq.dirty = false;
+	ne2k->sq.page = NE2K_START / DP_PAGE;
+	fibril_mutex_initialize(&ne2k->sq_mutex);
+	fibril_condvar_initialize(&ne2k->sq_cv);
+	
+	/*
+	 * Setup receive ring buffer. Use all the rest
+	 * of the NE2000 memory (except the first SQ_PAGES
+	 * reserved for the send buffer) for the receive
+	 * ring buffer.
+	 */
+	ne2k->start_page = ne2k->sq.page + SQ_PAGES;
+	ne2k->stop_page = ne2k->sq.page + NE2K_SIZE / DP_PAGE;
+	
+	/*
+	 * Initialization of the DP8390 following the mandatory procedure
 	 * in reference manual ("DP8390D/NS32490D NIC Network Interface
 	 * Controller", National Semiconductor, July 1995, Page 29).
@@ -272,211 +269,356 @@
 	
 	/* Step 1: */
-	outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
+	pio_write_8(ne2k->port + DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
 	
 	/* Step 2: */
-	if (dep->de_16bit)
-		outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | DCR_BMS);
-	else
-		outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS);
+	pio_write_8(ne2k->port + DP_DCR, DCR_WORDWIDE | DCR_8BYTES | DCR_BMS);
 	
 	/* Step 3: */
-	outb_reg0(dep, DP_RBCR0, 0);
-	outb_reg0(dep, DP_RBCR1, 0);
+	pio_write_8(ne2k->port + DP_RBCR0, 0);
+	pio_write_8(ne2k->port + DP_RBCR1, 0);
 	
 	/* Step 4: */
-	dp_rcr_reg = RCR_AB;  /* Enable broadcasts */
-	
-	outb_reg0(dep, DP_RCR, dp_rcr_reg);
+	pio_write_8(ne2k->port + DP_RCR, RCR_AB);
 	
 	/* Step 5: */
-	outb_reg0(dep, DP_TCR, TCR_INTERNAL);
+	pio_write_8(ne2k->port + DP_TCR, TCR_INTERNAL);
 	
 	/* Step 6: */
-	outb_reg0(dep, DP_BNRY, dep->de_startpage);
-	outb_reg0(dep, DP_PSTART, dep->de_startpage);
-	outb_reg0(dep, DP_PSTOP, dep->de_stoppage);
+	pio_write_8(ne2k->port + DP_BNRY, ne2k->start_page);
+	pio_write_8(ne2k->port + DP_PSTART, ne2k->start_page);
+	pio_write_8(ne2k->port + DP_PSTOP, ne2k->stop_page);
 	
 	/* Step 7: */
-	outb_reg0(dep, DP_ISR, 0xFF);
+	pio_write_8(ne2k->port + DP_ISR, 0xff);
 	
 	/* Step 8: */
-	outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE |
-	    IMR_OVWE | IMR_CNTE);
+	pio_write_8(ne2k->port + DP_IMR,
+	    IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE | IMR_OVWE | IMR_CNTE);
 	
 	/* Step 9: */
-	outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP);
-	
-	outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]);
-	outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]);
-	outb_reg1(dep, DP_PAR2, dep->de_address.ea_addr[2]);
-	outb_reg1(dep, DP_PAR3, dep->de_address.ea_addr[3]);
-	outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]);
-	outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]);
-	
-	outb_reg1(dep, DP_MAR0, 0xff);
-	outb_reg1(dep, DP_MAR1, 0xff);
-	outb_reg1(dep, DP_MAR2, 0xff);
-	outb_reg1(dep, DP_MAR3, 0xff);
-	outb_reg1(dep, DP_MAR4, 0xff);
-	outb_reg1(dep, DP_MAR5, 0xff);
-	outb_reg1(dep, DP_MAR6, 0xff);
-	outb_reg1(dep, DP_MAR7, 0xff);
-	
-	outb_reg1(dep, DP_CURR, dep->de_startpage + 1);
+	pio_write_8(ne2k->port + DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP);
+	
+	pio_write_8(ne2k->port + DP_PAR0, ne2k->mac[0]);
+	pio_write_8(ne2k->port + DP_PAR1, ne2k->mac[1]);
+	pio_write_8(ne2k->port + DP_PAR2, ne2k->mac[2]);
+	pio_write_8(ne2k->port + DP_PAR3, ne2k->mac[3]);
+	pio_write_8(ne2k->port + DP_PAR4, ne2k->mac[4]);
+	pio_write_8(ne2k->port + DP_PAR5, ne2k->mac[5]);
+	
+	pio_write_8(ne2k->port + DP_MAR0, 0xff);
+	pio_write_8(ne2k->port + DP_MAR1, 0xff);
+	pio_write_8(ne2k->port + DP_MAR2, 0xff);
+	pio_write_8(ne2k->port + DP_MAR3, 0xff);
+	pio_write_8(ne2k->port + DP_MAR4, 0xff);
+	pio_write_8(ne2k->port + DP_MAR5, 0xff);
+	pio_write_8(ne2k->port + DP_MAR6, 0xff);
+	pio_write_8(ne2k->port + DP_MAR7, 0xff);
+	
+	pio_write_8(ne2k->port + DP_CURR, ne2k->start_page + 1);
 	
 	/* Step 10: */
-	outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA);
+	pio_write_8(ne2k->port + DP_CR, CR_DM_ABORT | CR_STA);
 	
 	/* Step 11: */
-	outb_reg0(dep, DP_TCR, TCR_NORMAL);
-	
-	inb_reg0(dep, DP_CNTR0);  /* Reset counters by reading */
-	inb_reg0(dep, DP_CNTR1);
-	inb_reg0(dep, DP_CNTR2);
-	
-	/* Finish the initialization. */
-	dep->enabled = true;
-	for (i = 0; i < dep->de_sendq_nr; i++)
-		dep->de_sendq[i].sq_filled= 0;
-	
-	dep->de_sendq_head = 0;
-	dep->de_sendq_tail = 0;
-}
-
-static void dp_reinit(dpeth_t *dep)
-{
-	int dp_rcr_reg;
-	
-	outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
-	
-	/* Enable broadcasts */
-	dp_rcr_reg = RCR_AB;
-	
-	outb_reg0(dep, DP_RCR, dp_rcr_reg);
-}
-
-static void dp_reset(dpeth_t *dep)
-{
-	int i;
-	
-	/* Stop chip */
-	outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
-	outb_reg0(dep, DP_RBCR0, 0);
-	outb_reg0(dep, DP_RBCR1, 0);
-	
-	for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
-		; /* Do nothing */
-	
-	outb_reg0(dep, DP_TCR, TCR_1EXTERNAL | TCR_OFST);
-	outb_reg0(dep, DP_CR, CR_STA | CR_DM_ABORT);
-	outb_reg0(dep, DP_TCR, TCR_NORMAL);
-	
-	/* Acknowledge the ISR_RDC (remote DMA) interrupt. */
-	for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RDC) == 0); i++)
-		; /* Do nothing */
-	
-	outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC);
+	pio_write_8(ne2k->port + DP_TCR, TCR_NORMAL);
+	
+	/* Reset counters by reading */
+	pio_read_8(ne2k->port + DP_CNTR0);
+	pio_read_8(ne2k->port + DP_CNTR1);
+	pio_read_8(ne2k->port + DP_CNTR2);
+	
+	/* Finish the initialization */
+	ne2k->probed = true;
+	return EOK;
+}
+
+/** Start the network interface.
+ *
+ * @param[in,out] ne2k Network interface structure.
+ *
+ * @return EOK on success.
+ * @return EXDEV if the network interface is disabled.
+ *
+ */
+int ne2k_up(ne2k_t *ne2k)
+{
+	if (!ne2k->probed)
+		return EXDEV;
+	
+	pio_write_8(ne2k->port + DP_CR, CR_PS_P0 | CR_STA);
+	pio_write_8(ne2k->port + DP_RCR, RCR_AB);
+	
+	ne2k->up = true;
+	return EOK;
+}
+
+/** Stop the network interface.
+ *
+ * @param[in,out] ne2k Network interface structure.
+ *
+ */
+void ne2k_down(ne2k_t *ne2k)
+{
+	if ((ne2k->probed) && (ne2k->up)) {
+		pio_write_8(ne2k->port + DP_CR, CR_STP | CR_DM_ABORT);
+		
+		/* Reset the ethernet card */
+		uint8_t val = pio_read_8(ne2k->port + NE2K_RESET);
+		usleep(2000);
+		pio_write_8(ne2k->port + NE2K_RESET, val);
+		
+		ne2k->up = false;
+	}
+}
+
+/** Send a frame.
+ *
+ * @param[in,out] ne2k   Network interface structure.
+ * @param[in]     packet Frame to be sent.
+ *
+ */
+void ne2k_send(ne2k_t *ne2k, packet_t *packet)
+{
+	assert(ne2k->probed);
+	assert(ne2k->up);
+	
+	fibril_mutex_lock(&ne2k->sq_mutex);
+	
+	while (ne2k->sq.dirty)
+		fibril_condvar_wait(&ne2k->sq_cv, &ne2k->sq_mutex);
+	
+	void *buf = packet_get_data(packet);
+	size_t size = packet_get_data_length(packet);
+	
+	if ((size < ETH_MIN_PACK_SIZE) || (size > ETH_MAX_PACK_SIZE_TAGGED)) {
+		fprintf(stderr, "%s: Frame dropped (invalid size %zu bytes)\n",
+		    NAME, size);
+		return;
+	}
+	
+	/* Upload the frame to the ethernet card */
+	ne2k_upload(ne2k, buf, ne2k->sq.page * DP_PAGE, size);
+	ne2k->sq.dirty = true;
+	ne2k->sq.size = size;
+	
+	/* Initialize the transfer */
+	pio_write_8(ne2k->port + DP_TPSR, ne2k->sq.page);
+	pio_write_8(ne2k->port + DP_TBCR0, size & 0xff);
+	pio_write_8(ne2k->port + DP_TBCR1, (size >> 8) & 0xff);
+	pio_write_8(ne2k->port + DP_CR, CR_TXP | CR_STA);
+	
+	fibril_mutex_unlock(&ne2k->sq_mutex);
+}
+
+static void ne2k_reset(ne2k_t *ne2k)
+{
+	unsigned int i;
+	
+	/* Stop the chip */
+	pio_write_8(ne2k->port + DP_CR, CR_STP | CR_DM_ABORT);
+	pio_write_8(ne2k->port + DP_RBCR0, 0);
+	pio_write_8(ne2k->port + DP_RBCR1, 0);
+	
+	for (i = 0; i < 0x1000; i++) {
+		if ((pio_read_8(ne2k->port + DP_ISR) & ISR_RST) != 0)
+			break;
+	}
+	
+	pio_write_8(ne2k->port + DP_TCR, TCR_1EXTERNAL | TCR_OFST);
+	pio_write_8(ne2k->port + DP_CR, CR_STA | CR_DM_ABORT);
+	pio_write_8(ne2k->port + DP_TCR, TCR_NORMAL);
+	
+	/* Acknowledge the ISR_RDC (remote DMA) interrupt */
+	for (i = 0; i < 0x1000; i++) {
+		if ((pio_read_8(ne2k->port + DP_ISR) & ISR_RDC) != 0)
+			break;
+	}
+	
+	uint8_t val = pio_read_8(ne2k->port + DP_ISR);
+	pio_write_8(ne2k->port + DP_ISR, val & ~ISR_RDC);
 	
 	/*
-	 * Reset the transmit ring. If we were transmitting a packet, we
-	 * pretend that the packet is processed. Higher layers will
+	 * Reset the transmit ring. If we were transmitting a frame,
+	 * we pretend that the packet is processed. Higher layers will
 	 * retransmit if the packet wasn't actually sent.
 	 */
-	dep->de_sendq_head = 0;
-	dep->de_sendq_tail = 0;
-	
-	for (i = 0; i < dep->de_sendq_nr; i++)
-		dep->de_sendq[i].sq_filled = 0;
-	
-	dep->send_avail = false;
-	dep->stopped = false;
-}
-
-static uint8_t isr_acknowledge(dpeth_t *dep)
-{
-	uint8_t isr = inb_reg0(dep, DP_ISR);
+	fibril_mutex_lock(&ne2k->sq_mutex);
+	ne2k->sq.dirty = false;
+	fibril_mutex_unlock(&ne2k->sq_mutex);
+}
+
+static uint8_t ne2k_isr_ack(ne2k_t *ne2k)
+{
+	uint8_t isr = pio_read_8(ne2k->port + DP_ISR);
 	if (isr != 0)
-		outb_reg0(dep, DP_ISR, isr);
+		pio_write_8(ne2k->port + DP_ISR, isr);
 	
 	return isr;
 }
 
-void dp_check_ints(int nil_phone, device_id_t device_id, dpeth_t *dep, uint8_t isr)
-{
-	int tsr;
-	int size, sendq_tail;
-	
-	for (; (isr & 0x7f) != 0; isr = isr_acknowledge(dep)) {
+static void ne2k_receive_frame(ne2k_t *ne2k, uint8_t page, size_t length,
+    int nil_phone, device_id_t device_id)
+{
+	packet_t *packet = netif_packet_get_1(length);
+	if (!packet)
+		return;
+	
+	void *buf = packet_suffix(packet, length);
+	bzero(buf, length);
+	uint8_t last = page + length / DP_PAGE;
+	
+	if (last >= ne2k->stop_page) {
+		size_t left = (ne2k->stop_page - page) * DP_PAGE
+		    - sizeof(recv_header_t);
+		
+		ne2k_download(ne2k, buf, page * DP_PAGE + sizeof(recv_header_t),
+		    left);
+		ne2k_download(ne2k, buf + left, ne2k->start_page * DP_PAGE,
+		    length - left);
+	} else
+		ne2k_download(ne2k, buf, page * DP_PAGE + sizeof(recv_header_t),
+		    length);
+	
+	ne2k->stats.receive_packets++;
+	nil_received_msg(nil_phone, device_id, packet, SERVICE_NONE);
+}
+
+static void ne2k_receive(ne2k_t *ne2k, int nil_phone, device_id_t device_id)
+{
+	while (true) {
+		uint8_t boundary = pio_read_8(ne2k->port + DP_BNRY) + 1;
+		
+		if (boundary == ne2k->stop_page)
+			boundary = ne2k->start_page;
+		
+		pio_write_8(ne2k->port + DP_CR, CR_PS_P1 | CR_STA);
+		uint8_t current = pio_read_8(ne2k->port + DP_CURR);
+		pio_write_8(ne2k->port + DP_CR, CR_PS_P0 | CR_STA);
+		
+		if (current == boundary)
+			/* No more frames to process */
+			break;
+		
+		recv_header_t header;
+		size_t size = sizeof(header);
+		size_t offset = boundary * DP_PAGE;
+		
+		/* Get the frame header */
+		pio_write_8(ne2k->port + DP_RBCR0, size & 0xff);
+		pio_write_8(ne2k->port + DP_RBCR1, (size >> 8) & 0xff);
+		pio_write_8(ne2k->port + DP_RSAR0, offset & 0xff);
+		pio_write_8(ne2k->port + DP_RSAR1, (offset >> 8) & 0xff);
+		pio_write_8(ne2k->port + DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
+		
+		pio_read_buf_16(ne2k->data_port, (void *) &header, size);
+		
+		size_t length =
+		    (((size_t) header.rbcl) | (((size_t) header.rbch) << 8)) - size;
+		uint8_t next = header.next;
+		
+		if ((length < ETH_MIN_PACK_SIZE)
+		    || (length > ETH_MAX_PACK_SIZE_TAGGED)) {
+			fprintf(stderr, "%s: Rant frame (%zu bytes)\n", NAME, length);
+			next = current;
+		} else if ((header.next < ne2k->start_page)
+		    || (header.next > ne2k->stop_page)) {
+			fprintf(stderr, "%s: Malformed next frame %u\n", NAME,
+			    header.next);
+			next = current;
+		} else if (header.status & RSR_FO) {
+			/*
+			 * This is very serious, so we issue a warning and
+			 * reset the buffers.
+			 */
+			fprintf(stderr, "%s: FIFO overrun\n", NAME);
+			ne2k->overruns++;
+			next = current;
+		} else if ((header.status & RSR_PRX) && (ne2k->up))
+			ne2k_receive_frame(ne2k, boundary, length, nil_phone, device_id);
+		
+		/*
+		 * Update the boundary pointer
+		 * to the value of the page
+		 * prior to the next packet to
+		 * be processed.
+		 */
+		if (next == ne2k->start_page)
+			next = ne2k->stop_page - 1;
+		else
+			next--;
+		
+		pio_write_8(ne2k->port + DP_BNRY, next);
+	}
+}
+
+void ne2k_interrupt(ne2k_t *ne2k, uint8_t isr, int nil_phone, device_id_t device_id)
+{
+	bool signal = false;
+	bool stopped = false;
+	
+	for (; (isr & 0x7f) != 0; isr = ne2k_isr_ack(ne2k)) {
 		if (isr & (ISR_PTX | ISR_TXE)) {
 			if (isr & ISR_TXE)
-				dep->de_stat.ets_sendErr++;
+				ne2k->stats.send_errors++;
 			else {
-				tsr = inb_reg0(dep, DP_TSR);
+				uint8_t tsr = pio_read_8(ne2k->port + DP_TSR);
 				
 				if (tsr & TSR_PTX)
-					dep->de_stat.ets_packetT++;
+					ne2k->stats.send_packets++;
 				
 				if (tsr & TSR_COL)
-					dep->de_stat.ets_collision++;
+					ne2k->stats.collisions++;
 				
 				if (tsr & TSR_ABT)
-					dep->de_stat.ets_transAb++;
+					ne2k->stats.send_aborted_errors++;
 				
 				if (tsr & TSR_CRS)
-					dep->de_stat.ets_carrSense++;
+					ne2k->stats.send_carrier_errors++;
 				
-				if ((tsr & TSR_FU) && (++dep->de_stat.ets_fifoUnder <= 10))
-					printf("FIFO underrun\n");
+				if (tsr & TSR_FU) {
+					ne2k->underruns++;
+					if (ne2k->underruns < NE2K_ERL)
+						fprintf(stderr, "%s: FIFO underrun\n", NAME);
+				}
 				
-				if ((tsr & TSR_CDH) && (++dep->de_stat.ets_CDheartbeat <= 10))
-					printf("CD heart beat failure\n");
+				if (tsr & TSR_CDH) {
+					ne2k->stats.send_heartbeat_errors++;
+					if (ne2k->stats.send_heartbeat_errors < NE2K_ERL)
+						fprintf(stderr, "%s: CD heartbeat failure\n", NAME);
+				}
 				
 				if (tsr & TSR_OWC)
-					dep->de_stat.ets_OWC++;
+					ne2k->stats.send_window_errors++;
 			}
 			
-			sendq_tail = dep->de_sendq_tail;
+			fibril_mutex_lock(&ne2k->sq_mutex);
 			
-			if (!(dep->de_sendq[sendq_tail].sq_filled)) {
-				printf("PTX interrupt, but no frame to send\n");
-				continue;
+			if (ne2k->sq.dirty) {
+				/* Prepare the buffer for next packet */
+				ne2k->sq.dirty = false;
+				ne2k->sq.size = 0;
+				signal = true;
+			} else {
+				ne2k->misses++;
+				if (ne2k->misses < NE2K_ERL)
+					fprintf(stderr, "%s: Spurious PTX interrupt\n", NAME);
 			}
 			
-			dep->de_sendq[sendq_tail].sq_filled = false;
-			
-			if (++sendq_tail == dep->de_sendq_nr)
-				sendq_tail = 0;
-			
-			dep->de_sendq_tail = sendq_tail;
-			
-			if (dep->de_sendq[sendq_tail].sq_filled) {
-				size = dep->de_sendq[sendq_tail].sq_size;
-				outb_reg0(dep, DP_TPSR,
-				    dep->de_sendq[sendq_tail].sq_sendpage);
-				outb_reg0(dep, DP_TBCR1, size >> 8);
-				outb_reg0(dep, DP_TBCR0, size & 0xff);
-				outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);
-			}
-			
-			dep->send_avail = false;
+			fibril_mutex_unlock(&ne2k->sq_mutex);
 		}
 		
 		if (isr & ISR_PRX)
-			dp_recv(nil_phone, device_id, dep);
+			ne2k_receive(ne2k, nil_phone, device_id);
 		
 		if (isr & ISR_RXE)
-			dep->de_stat.ets_recvErr++;
+			ne2k->stats.receive_errors++;
 		
 		if (isr & ISR_CNT) {
-			dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
-			dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
-			dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
-		}
-		
-		if (isr & ISR_OVW)
-			dep->de_stat.ets_OVW++;
-		
-		if (isr & ISR_RDC) {
-			/* Nothing to do */
+			ne2k->stats.receive_crc_errors +=
+			    pio_read_8(ne2k->port + DP_CNTR0);
+			ne2k->stats.receive_frame_errors +=
+			    pio_read_8(ne2k->port + DP_CNTR1);
+			ne2k->stats.receive_missed_errors +=
+			    pio_read_8(ne2k->port + DP_CNTR2);
 		}
 		
@@ -486,208 +628,21 @@
 			 * chip is shutdown. We set the flag 'stopped'
 			 * and continue processing arrived packets. When the
-			 * receive buffer is empty, we reset the dp8390.
+			 * receive buffer is empty, we reset the DP8390.
 			 */
-			dep->stopped = true;
-			break;
+			stopped = true;
 		}
 	}
 	
-	if (dep->stopped) {
+	if (stopped) {
 		/*
 		 * The chip is stopped, and all arrived
 		 * frames are delivered.
 		 */
-		dp_reset(dep);
-	}
-	
-	dep->sending = false;
-}
-
-static void dp_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst)
-{
-	offset = page * DP_PAGESIZE + offset;
-	
-	outb_reg0(dep, DP_RBCR0, size & 0xff);
-	outb_reg0(dep, DP_RBCR1, size >> 8);
-	outb_reg0(dep, DP_RSAR0, offset & 0xff);
-	outb_reg0(dep, DP_RSAR1, offset >> 8);
-	outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
-	
-	if (dep->de_16bit) {
-		assert((size % 2) == 0);
-		insw(dep->de_data_port, dst, size);
-	} else
-		insb(dep->de_data_port, dst, size);
-}
-
-static void dp_recv(int nil_phone, device_id_t device_id, dpeth_t *dep)
-{
-	dp_rcvhdr_t header;
-	int pageno, curr, next;
-	size_t length;
-	int packet_processed, r;
-	uint16_t eth_type;
-	
-	packet_processed = false;
-	pageno = inb_reg0(dep, DP_BNRY) + 1;
-	if (pageno == dep->de_stoppage)
-		pageno = dep->de_startpage;
-	
-	do {
-		outb_reg0(dep, DP_CR, CR_PS_P1 | CR_EXTRA);
-		curr = inb_reg1(dep, DP_CURR);
-		outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
-		
-		if (curr == pageno)
-			break;
-		
-		dp_getblock(dep, pageno, (size_t) 0, sizeof(header), &header);
-		dp_getblock(dep, pageno, sizeof(header) +
-		    2 * sizeof(ether_addr_t), sizeof(eth_type), &eth_type);
-		
-		length = (header.dr_rbcl | (header.dr_rbch << 8)) - sizeof(dp_rcvhdr_t);
-		next = header.dr_next;
-		if ((length < ETH_MIN_PACK_SIZE) || (length > ETH_MAX_PACK_SIZE_TAGGED)) {
-			printf("Packet with strange length arrived: %zu\n", length);
-			next= curr;
-		} else if ((next < dep->de_startpage) || (next >= dep->de_stoppage)) {
-			printf("Strange next page\n");
-			next= curr;
-		} else if (header.dr_status & RSR_FO) {
-			/*
-			 * This is very serious, so we issue a warning and
-			 * reset the buffers
-			 */
-			printf("FIFO overrun, resetting receive buffer\n");
-			dep->de_stat.ets_fifoOver++;
-			next = curr;
-		} else if ((header.dr_status & RSR_PRX) && (dep->enabled)) {
-			r = dp_pkt2user(nil_phone, device_id, dep, pageno, length);
-			if (r != EOK)
-				return;
-			
-			packet_processed = true;
-			dep->de_stat.ets_packetR++;
-		}
-		
-		if (next == dep->de_startpage)
-			outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);
-		else
-			outb_reg0(dep, DP_BNRY, next - 1);
-		
-		pageno = next;
-	} while (!packet_processed);
-}
-
-static void dp_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size)
-{
-	size_t ecount = size & ~1;
-	
-	if (dep->de_16bit) {
-		outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
-		outb_reg0(dep, DP_RBCR1, ecount >> 8);
-	} else {
-		outb_reg0(dep, DP_RBCR0, size & 0xff);
-		outb_reg0(dep, DP_RBCR1, size >> 8);
-	}
-	
-	outb_reg0(dep, DP_RSAR0, nic_addr & 0xff);
-	outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
-	outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
-	
-	if (dep->de_16bit) {
-		void *ptr = buf + offset;
-		
-		if (ecount != 0) {
-			insw(dep->de_data_port, ptr, ecount);
-			size -= ecount;
-			offset += ecount;
-			ptr += ecount;
-		}
-		
-		if (size) {
-			assert(size == 1);
-			
-			uint16_t two_bytes = inw(dep->de_data_port);
-			memcpy(ptr, &(((uint8_t *) &two_bytes)[0]), 1);
-		}
-	} else
-		insb(dep->de_data_port, buf + offset, size);
-}
-
-static int dp_pkt2user(int nil_phone, device_id_t device_id, dpeth_t *dep, int page, int length)
-{
-	int last, count;
-	packet_t *packet;
-	
-	packet = netif_packet_get_1(length);
-	if (!packet)
-		return ENOMEM;
-	
-	void *buf = packet_suffix(packet, length);
-	
-	last = page + (length - 1) / DP_PAGESIZE;
-	if (last >= dep->de_stoppage) {
-		count = (dep->de_stoppage - page) * DP_PAGESIZE - sizeof(dp_rcvhdr_t);
-		
-		dp_nic2user(dep, page * DP_PAGESIZE + sizeof(dp_rcvhdr_t),
-		    buf, 0, count);
-		dp_nic2user(dep, dep->de_startpage * DP_PAGESIZE,
-		    buf, count, length - count);
-	} else {
-		dp_nic2user(dep, page * DP_PAGESIZE + sizeof(dp_rcvhdr_t),
-		    buf, 0, length);
-	}
-	
-	nil_received_msg(nil_phone, device_id, packet, SERVICE_NONE);
-	
-	return EOK;
-}
-
-static void conf_hw(dpeth_t *dep)
-{
-	if (!ne_probe(dep)) {
-		printf("No ethernet card found at %#lx\n", dep->de_base_port);
-		dep->up = false;
-		return;
-	}
-	
-	dep->up = true;
-	dep->enabled = false;
-	dep->stopped = false;
-	dep->sending = false;
-	dep->send_avail = false;
-}
-
-static void insb(port_t port, void *buf, size_t size)
-{
-	size_t i;
-	
-	for (i = 0; i < size; i++)
-		*((uint8_t *) buf + i) = inb(port);
-}
-
-static void insw(port_t port, void *buf, size_t size)
-{
-	size_t i;
-	
-	for (i = 0; i * 2 < size; i++)
-		*((uint16_t *) buf + i) = inw(port);
-}
-
-static void outsb(port_t port, void *buf, size_t size)
-{
-	size_t i;
-	
-	for (i = 0; i < size; i++)
-		outb(port, *((uint8_t *) buf + i));
-}
-
-static void outsw(port_t port, void *buf, size_t size)
-{
-	size_t i;
-	
-	for (i = 0; i * 2 < size; i++)
-		outw(port, *((uint16_t *) buf + i));
+		ne2k_reset(ne2k);
+	}
+	
+	/* Signal a next frame to be sent */
+	if (signal)
+		fibril_condvar_broadcast(&ne2k->sq_cv);
 }
 
Index: uspace/srv/hw/netif/dp8390/dp8390.h
===================================================================
--- uspace/srv/hw/netif/dp8390/dp8390.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/hw/netif/dp8390/dp8390.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -38,5 +38,5 @@
  */
 
-/** @addtogroup dp8390
+/** @addtogroup ne2000
  *  @{
  */
@@ -49,9 +49,15 @@
 #define __NET_NETIF_DP8390_H__
 
+#include <fibril_synch.h>
 #include <net/packet.h>
-#include "dp8390_port.h"
+
+/** Module name */
+#define NAME  "ne2000"
 
 /** Input/output size */
-#define DP8390_IO_SIZE  0x0020
+#define NE2K_IO_SIZE  0x0020
+
+/** Ethernet address length */
+#define ETH_ADDR  6
 
 /* National Semiconductor DP8390 Network Interface Controller. */
@@ -105,187 +111,128 @@
 #define DP_MAR7  0x0f  /**< Multicast Address Register 7 */
 
-/* Bits in dp_cr */
-#define CR_STP		0x01	/* Stop: software reset              */
-#define CR_STA		0x02	/* Start: activate NIC               */
-#define CR_TXP		0x04	/* Transmit Packet                   */
-#define CR_DMA		0x38	/* Mask for DMA control              */
-#define CR_DM_NOP	0x00	/* DMA: No Operation                 */
-#define CR_DM_RR	0x08	/* DMA: Remote Read                  */
-#define CR_DM_RW	0x10	/* DMA: Remote Write                 */
-#define CR_DM_SP	0x18	/* DMA: Send Packet                  */
-#define CR_DM_ABORT	0x20	/* DMA: Abort Remote DMA Operation   */
-#define CR_PS		0xC0	/* Mask for Page Select              */
-#define CR_PS_P0	0x00	/* Register Page 0                   */
-#define CR_PS_P1	0x40	/* Register Page 1                   */
-#define CR_PS_P2	0x80	/* Register Page 2                   */
-#define CR_PS_T1	0xC0	/* Test Mode Register Map            */
-
-/* Bits in dp_isr */
-#define ISR_PRX		0x01	/* Packet Received with no errors    */
-#define ISR_PTX		0x02	/* Packet Transmitted with no errors */
-#define ISR_RXE		0x04	/* Receive Error                     */
-#define ISR_TXE		0x08	/* Transmit Error                    */
-#define ISR_OVW		0x10	/* Overwrite Warning                 */
-#define ISR_CNT		0x20	/* Counter Overflow                  */
-#define ISR_RDC		0x40	/* Remote DMA Complete               */
-#define ISR_RST		0x80	/* Reset Status                      */
-
-/* Bits in dp_imr */
-#define IMR_PRXE	0x01	/* Packet Received iEnable           */
-#define IMR_PTXE	0x02	/* Packet Transmitted iEnable        */
-#define IMR_RXEE	0x04	/* Receive Error iEnable             */
-#define IMR_TXEE	0x08	/* Transmit Error iEnable            */
-#define IMR_OVWE	0x10	/* Overwrite Warning iEnable         */
-#define IMR_CNTE	0x20	/* Counter Overflow iEnable          */
-#define IMR_RDCE	0x40	/* DMA Complete iEnable              */
-
-/* Bits in dp_dcr */
-#define DCR_WTS		0x01	/* Word Transfer Select              */
-#define DCR_BYTEWIDE	0x00	/* WTS: byte wide transfers          */
-#define DCR_WORDWIDE	0x01	/* WTS: word wide transfers          */
-#define DCR_BOS		0x02	/* Byte Order Select                 */
-#define DCR_LTLENDIAN	0x00	/* BOS: Little Endian                */
-#define DCR_BIGENDIAN	0x02	/* BOS: Big Endian                   */
-#define DCR_LAS		0x04	/* Long Address Select               */
-#define DCR_BMS		0x08	/* Burst Mode Select
-				 * Called Loopback Select (LS) in 
-				 * later manuals. Should be set.     */
-#define DCR_AR		0x10	/* Autoinitialize Remote             */
-#define DCR_FTS		0x60	/* Fifo Threshold Select             */
-#define DCR_2BYTES	0x00	/* 2 bytes                           */
-#define DCR_4BYTES	0x40	/* 4 bytes                           */
-#define DCR_8BYTES	0x20	/* 8 bytes                           */
-#define DCR_12BYTES	0x60	/* 12 bytes                          */
-
-/* Bits in dp_tcr */
-#define TCR_CRC		0x01	/* Inhibit CRC                       */
-#define TCR_ELC		0x06	/* Encoded Loopback Control          */
-#define TCR_NORMAL	0x00	/* ELC: Normal Operation             */
-#define TCR_INTERNAL	0x02	/* ELC: Internal Loopback            */
-#define TCR_0EXTERNAL	0x04	/* ELC: External Loopback LPBK=0     */
-#define TCR_1EXTERNAL	0x06	/* ELC: External Loopback LPBK=1     */
-#define TCR_ATD		0x08	/* Auto Transmit Disable             */
-#define TCR_OFST	0x10	/* Collision Offset Enable (be nice) */
-
-/* Bits in dp_tsr */
-#define TSR_PTX		0x01	/* Packet Transmitted (without error)*/
-#define TSR_DFR		0x02	/* Transmit Deferred, reserved in
-				 * later manuals.		     */
-#define TSR_COL		0x04	/* Transmit Collided                 */
-#define TSR_ABT		0x08	/* Transmit Aborted                  */
-#define TSR_CRS		0x10	/* Carrier Sense Lost                */
-#define TSR_FU		0x20	/* FIFO Underrun                     */
-#define TSR_CDH		0x40	/* CD Heartbeat                      */
-#define TSR_OWC		0x80	/* Out of Window Collision           */
-
-/* Bits in tp_rcr */
-#define RCR_SEP		0x01	/* Save Errored Packets              */
-#define RCR_AR		0x02	/* Accept Runt Packets               */
-#define RCR_AB		0x04	/* Accept Broadcast                  */
-#define RCR_AM		0x08	/* Accept Multicast                  */
-#define RCR_PRO		0x10	/* Physical Promiscuous              */
-#define RCR_MON		0x20	/* Monitor Mode                      */
-
-/* Bits in dp_rsr */
-#define RSR_PRX		0x01	/* Packet Received Intact            */
-#define RSR_CRC		0x02	/* CRC Error                         */
-#define RSR_FAE		0x04	/* Frame Alignment Error             */
-#define RSR_FO		0x08	/* FIFO Overrun                      */
-#define RSR_MPA		0x10	/* Missed Packet                     */
-#define RSR_PHY		0x20	/* Multicast Address Match           */
-#define RSR_DIS		0x40	/* Receiver Disabled                 */
-#define RSR_DFR		0x80	/* In later manuals: Deferring       */
-
-/** Type definition of the receive header
- *
- */
-typedef struct dp_rcvhdr {
-	/** Copy of rsr */
-	uint8_t dr_status;
-	
-	/** Pointer to next packet */
-	uint8_t dr_next;
-	
-	/** Receive Byte Count Low */
-	uint8_t dr_rbcl;
-	
-	/** Receive Byte Count High */
-	uint8_t dr_rbch;
-} dp_rcvhdr_t;
-
-/** Page size */
-#define DP_PAGESIZE  256
-
-/** Read 1 byte from the zero page register.
- *  @param[in] dep The network interface structure.
- *  @param[in] reg The register offset.
- *  @returns The read value.
- */
-#define inb_reg0(dep, reg)  (inb(dep->de_dp8390_port + reg))
-
-/** Write 1 byte zero page register.
- *  @param[in] dep The network interface structure.
- *  @param[in] reg The register offset.
- *  @param[in] data The value to be written.
- */
-#define outb_reg0(dep, reg, data)  (outb(dep->de_dp8390_port + reg, data))
-
-/** Read 1 byte from the first page register.
- *  @param[in] dep The network interface structure.
- *  @param[in] reg The register offset.
- *  @returns The read value.
- */
-#define inb_reg1(dep, reg)  (inb(dep->de_dp8390_port + reg))
-
-/** Write 1 byte first page register.
- *  @param[in] dep The network interface structure.
- *  @param[in] reg The register offset.
- *  @param[in] data The value to be written.
- */
-#define outb_reg1(dep, reg, data)  (outb(dep->de_dp8390_port + reg, data))
-
-#define SENDQ_NR     2  /* Maximum size of the send queue */
-#define SENDQ_PAGES  6  /* 6 * DP_PAGESIZE >= 1514 bytes */
-
-typedef struct dpeth {
-	/*
-	 * The de_base_port field is the starting point of the probe.
-	 * The conf routine also fills de_irq. If the probe
-	 * routine knows the irq and/or memory address because they are
-	 * hardwired in the board, the probe should modify these fields.
-	 */
-	port_t de_base_port;
-	int de_irq;
-	
-	ether_addr_t de_address;
-	port_t de_dp8390_port;
-	port_t de_data_port;
-	int de_16bit;
-	long de_ramsize;
-	int de_offset_page;
-	int de_startpage;
-	int de_stoppage;
-	
-	/* Do it yourself send queue */
-	struct sendq {
-		int sq_filled;    /* this buffer contains a packet */
-		int sq_size;      /* with this size */
-		int sq_sendpage;  /* starting page of the buffer */
-	} de_sendq[SENDQ_NR];
-	
-	int de_sendq_nr;
-	int de_sendq_head;  /* Enqueue at the head */
-	int de_sendq_tail;  /* Dequeue at the tail */
-	
-	/* Fields for internal use by the dp8390 driver. */
-	eth_stat_t de_stat;
-	
-	/* Driver flags */
+/* Bits in Command Register */
+#define CR_STP       0x01  /**< Stop (software reset) */
+#define CR_STA       0x02  /**< Start (activate NIC) */
+#define CR_TXP       0x04  /**< Transmit Packet */
+#define CR_DMA       0x38  /**< Mask for DMA control */
+#define CR_DM_NOP    0x00  /**< DMA: No Operation */
+#define CR_DM_RR     0x08  /**< DMA: Remote Read */
+#define CR_DM_RW     0x10  /**< DMA: Remote Write */
+#define CR_DM_SP     0x18  /**< DMA: Send Packet */
+#define CR_DM_ABORT  0x20  /**< DMA: Abort Remote DMA Operation */
+#define CR_PS        0xc0  /**< Mask for Page Select */
+#define CR_PS_P0     0x00  /**< Register Page 0 */
+#define CR_PS_P1     0x40  /**< Register Page 1 */
+#define CR_PS_P2     0x80  /**< Register Page 2 */
+#define CR_PS_T1     0xc0  /**< Test Mode Register Map */
+
+/* Bits in Interrupt State Register */
+#define ISR_PRX  0x01  /**< Packet Received with no errors */
+#define ISR_PTX  0x02  /**< Packet Transmitted with no errors */
+#define ISR_RXE  0x04  /**< Receive Error */
+#define ISR_TXE  0x08  /**< Transmit Error */
+#define ISR_OVW  0x10  /**< Overwrite Warning */
+#define ISR_CNT  0x20  /**< Counter Overflow */
+#define ISR_RDC  0x40  /**< Remote DMA Complete */
+#define ISR_RST  0x80  /**< Reset Status */
+
+/* Bits in Interrupt Mask Register */
+#define IMR_PRXE  0x01  /**< Packet Received Interrupt Enable */
+#define IMR_PTXE  0x02  /**< Packet Transmitted Interrupt Enable */
+#define IMR_RXEE  0x04  /**< Receive Error Interrupt Enable */
+#define IMR_TXEE  0x08  /**< Transmit Error Interrupt Enable */
+#define IMR_OVWE  0x10  /**< Overwrite Warning Interrupt Enable */
+#define IMR_CNTE  0x20  /**< Counter Overflow Interrupt Enable */
+#define IMR_RDCE  0x40  /**< DMA Complete Interrupt Enable */
+
+/* Bits in Data Configuration Register */
+#define DCR_WTS        0x01  /**< Word Transfer Select */
+#define DCR_BYTEWIDE   0x00  /**< WTS: byte wide transfers */
+#define DCR_WORDWIDE   0x01  /**< WTS: word wide transfers */
+#define DCR_BOS        0x02  /**< Byte Order Select */
+#define DCR_LTLENDIAN  0x00  /**< BOS: Little Endian */
+#define DCR_BIGENDIAN  0x02  /**< BOS: Big Endian */
+#define DCR_LAS        0x04  /**< Long Address Select */
+#define DCR_BMS        0x08  /**< Burst Mode Select */
+#define DCR_AR         0x10  /**< Autoinitialize Remote */
+#define DCR_FTS        0x60  /**< Fifo Threshold Select */
+#define DCR_2BYTES     0x00  /**< 2 bytes */
+#define DCR_4BYTES     0x40  /**< 4 bytes */
+#define DCR_8BYTES     0x20  /**< 8 bytes */
+#define DCR_12BYTES    0x60  /**< 12 bytes */
+
+/* Bits in Transmit Configuration Register */
+#define TCR_CRC        0x01  /**< Inhibit CRC */
+#define TCR_ELC        0x06  /**< Encoded Loopback Control */
+#define TCR_NORMAL     0x00  /**< ELC: Normal Operation */
+#define TCR_INTERNAL   0x02  /**< ELC: Internal Loopback */
+#define TCR_0EXTERNAL  0x04  /**< ELC: External Loopback LPBK=0 */
+#define TCR_1EXTERNAL  0x06  /**< ELC: External Loopback LPBK=1 */
+#define TCR_ATD        0x08  /**< Auto Transmit Disable */
+#define TCR_OFST       0x10  /**< Collision Offset Enable (be nice) */
+
+/* Bits in Interrupt Status Register */
+#define TSR_PTX  0x01  /**< Packet Transmitted (without error) */
+#define TSR_DFR  0x02  /**< Transmit Deferred (reserved) */
+#define TSR_COL  0x04  /**< Transmit Collided */
+#define TSR_ABT  0x08  /**< Transmit Aborted */
+#define TSR_CRS  0x10  /**< Carrier Sense Lost */
+#define TSR_FU   0x20  /**< FIFO Underrun */
+#define TSR_CDH  0x40  /**< CD Heartbeat */
+#define TSR_OWC  0x80  /**< Out of Window Collision */
+
+/* Bits in Receive Configuration Register */
+#define RCR_SEP  0x01  /**< Save Errored Packets */
+#define RCR_AR   0x02  /**< Accept Runt Packets */
+#define RCR_AB   0x04  /**< Accept Broadcast */
+#define RCR_AM   0x08  /**< Accept Multicast */
+#define RCR_PRO  0x10  /**< Physical Promiscuous */
+#define RCR_MON  0x20  /**< Monitor Mode */
+
+/* Bits in Receive Status Register */
+#define RSR_PRX  0x01  /**< Packet Received Intact */
+#define RSR_CRC  0x02  /**< CRC Error */
+#define RSR_FAE  0x04  /**< Frame Alignment Error */
+#define RSR_FO   0x08  /**< FIFO Overrun */
+#define RSR_MPA  0x10  /**< Missed Packet */
+#define RSR_PHY  0x20  /**< Multicast Address Match */
+#define RSR_DIS  0x40  /**< Receiver Disabled */
+#define RSR_DFR  0x80  /**< In later manuals: Deferring */
+
+typedef struct {
+	/* Device configuration */
+	void *port;
+	void *data_port;
+	int irq;
+	uint8_t mac[ETH_ADDR];
+	
+	uint8_t start_page;  /**< Ring buffer start page */
+	uint8_t stop_page;   /**< Ring buffer stop page */
+	
+	/* Send queue */
+	struct {
+		bool dirty;    /**< Buffer contains a packet */
+		size_t size;   /**< Packet size */
+		uint8_t page;  /**< Starting page of the buffer */
+	} sq;
+	fibril_mutex_t sq_mutex;
+	fibril_condvar_t sq_cv;
+	
+	/* Driver run-time variables */
+	bool probed;
 	bool up;
-	bool enabled;
-	bool stopped;
-	bool sending;
-	bool send_avail;
-} dpeth_t;
+	
+	/* Device statistics */
+	device_stats_t stats;
+	uint64_t misses;     /**< Receive frame misses */
+	uint64_t underruns;  /**< FIFO underruns */
+	uint64_t overruns;   /**< FIFO overruns */
+} ne2k_t;
+
+extern int ne2k_probe(ne2k_t *, void *, int);
+extern int ne2k_up(ne2k_t *);
+extern void ne2k_down(ne2k_t *);
+extern void ne2k_send(ne2k_t *, packet_t *);
+extern void ne2k_interrupt(ne2k_t *, uint8_t isr, int, device_id_t);
 
 #endif
Index: pace/srv/hw/netif/dp8390/dp8390_drv.h
===================================================================
--- uspace/srv/hw/netif/dp8390/dp8390_drv.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,72 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * 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 dp8390
- *  @{
- */
-
-/** @file
- *  DP8390 network interface driver interface.
- */
-
-#ifndef __NET_NETIF_DP8390_DRIVER_H__
-#define __NET_NETIF_DP8390_DRIVER_H__
-
-#include "dp8390.h"
-
-int do_init(dpeth_t *dep);
-
-/** Stops the network interface.
- *  @param[in,out] dep The network interface structure.
- */
-void do_stop(dpeth_t *dep);
-
-/** Processes the interrupt.
- *  @param[in,out] dep The network interface structure.
- */
-void dp_check_ints(int nil_phone, device_id_t device_id, dpeth_t *dep, uint8_t isr);
-
-/** Probes and initializes the network interface.
- *  @param[in,out] dep The network interface structure.
- *  @returns EOK on success.
- *  @returns EXDEV if the network interface was not recognized.
- */
-int do_probe(dpeth_t * dep);
-
-/** Sends a packet.
- *  @param[in,out] dep The network interface structure.
- *  @param[in] packet The packet t be sent.
- *  @param[in] from_int The value indicating whether the sending is initialized from the interrupt handler.
- *  @returns
- */
-int do_pwrite(dpeth_t * dep, packet_t *packet, int from_int);
-
-#endif
-
-/** @}
- */
Index: pace/srv/hw/netif/dp8390/dp8390_module.c
===================================================================
--- uspace/srv/hw/netif/dp8390/dp8390_module.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,395 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * 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 dp8390
- *  @{
- */
-
-/** @file
- *  DP8390 network interface implementation.
- */
-
-#include <assert.h>
-#include <async.h>
-#include <ddi.h>
-#include <errno.h>
-#include <err.h>
-#include <malloc.h>
-#include <ipc/ipc.h>
-#include <ipc/services.h>
-#include <net/modules.h>
-#include <packet_client.h>
-#include <adt/measured_strings.h>
-#include <net/device.h>
-#include <nil_interface.h>
-#include <netif_interface.h>
-#include <netif_local.h>
-#include "dp8390.h"
-#include "dp8390_drv.h"
-#include "dp8390_port.h"
-
-/** DP8390 module name.
- */
-#define NAME  "dp8390"
-
-/** Return the device from the interrupt call.
- *
- *  @param[in] call The interrupt call.
- *
- */
-#define IRQ_GET_DEVICE(call)  ((device_id_t) IPC_GET_IMETHOD(call))
-
-/** Return the ISR from the interrupt call.
- *
- *  @param[in] call The interrupt call.
- *
- */
-#define IRQ_GET_ISR(call)  ((int) IPC_GET_ARG2(call))
-
-/** DP8390 kernel interrupt command sequence.
- */
-static irq_cmd_t dp8390_cmds[] = {
-	{
-		.cmd = CMD_PIO_READ_8,
-		.addr = NULL,
-		.dstarg = 2
-	},
-	{
-		.cmd = CMD_BTEST,
-		.value = 0x7f,
-		.srcarg = 2,
-		.dstarg = 3,
-	},
-	{
-		.cmd = CMD_PREDICATE,
-		.value = 2,
-		.srcarg = 3
-	},
-	{
-		.cmd = CMD_PIO_WRITE_A_8,
-		.addr = NULL,
-		.srcarg = 3
-	},
-	{
-		.cmd = CMD_ACCEPT
-	}
-};
-
-/** DP8390 kernel interrupt code.
- */
-static irq_code_t dp8390_code = {
-	sizeof(dp8390_cmds) / sizeof(irq_cmd_t),
-	dp8390_cmds
-};
-
-/** Handles the interrupt messages.
- *  This is the interrupt handler callback function.
- *  @param[in] iid The interrupt message identifier.
- *  @param[in] call The interrupt message.
- */
-static void irq_handler(ipc_callid_t iid, ipc_call_t *call)
-{
-	device_id_t device_id = IRQ_GET_DEVICE(*call);
-	netif_device_t *device;
-	int nil_phone;
-	dpeth_t *dep;
-	
-	fibril_rwlock_write_lock(&netif_globals.lock);
-	
-	if (find_device(device_id, &device) == EOK) {
-		nil_phone = device->nil_phone;
-		dep = (dpeth_t *) device->specific;
-	} else
-		dep = NULL;
-	
-	fibril_rwlock_write_unlock(&netif_globals.lock);
-	
-	if ((dep != NULL) && (dep->up)) {
-		assert(dep->enabled);
-		dp_check_ints(nil_phone, device_id, dep, IRQ_GET_ISR(*call));
-	}
-}
-
-/** Changes the network interface state.
- *  @param[in,out] device The network interface.
- *  @param[in] state The new state.
- *  @returns The new state.
- */
-static int change_state(netif_device_t *device, device_state_t state)
-{
-	if (device->state != state) {
-		device->state = state;
-		
-		printf("%s: State changed to %s\n", NAME,
-		    (state == NETIF_ACTIVE) ? "active" : "stopped");
-		
-		return state;
-	}
-	
-	return EOK;
-}
-
-int netif_specific_message(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count)
-{
-	return ENOTSUP;
-}
-
-int netif_get_device_stats(device_id_t device_id, device_stats_t *stats)
-{
-	netif_device_t * device;
-	eth_stat_t * de_stat;
-	int rc;
-	
-	if (!stats)
-		return EBADMEM;
-	
-	rc = find_device(device_id, &device);
-	if (rc != EOK)
-		return rc;
-	
-	de_stat = &((dpeth_t *) device->specific)->de_stat;
-	
-	null_device_stats(stats);
-	stats->receive_errors = de_stat->ets_recvErr;
-	stats->send_errors = de_stat->ets_sendErr;
-	stats->receive_crc_errors = de_stat->ets_CRCerr;
-	stats->receive_frame_errors = de_stat->ets_frameAll;
-	stats->receive_missed_errors = de_stat->ets_missedP;
-	stats->receive_packets = de_stat->ets_packetR;
-	stats->send_packets = de_stat->ets_packetT;
-	stats->collisions = de_stat->ets_collision;
-	stats->send_aborted_errors = de_stat->ets_transAb;
-	stats->send_carrier_errors = de_stat->ets_carrSense;
-	stats->send_heartbeat_errors = de_stat->ets_CDheartbeat;
-	stats->send_window_errors = de_stat->ets_OWC;
-	
-	return EOK;
-}
-
-int netif_get_addr_message(device_id_t device_id, measured_string_t *address)
-{
-	netif_device_t *device;
-	int rc;
-	
-	if (!address)
-		return EBADMEM;
-	
-	rc = find_device(device_id, &device);
-	if (rc != EOK)
-		return rc;
-	
-	address->value = (char *) (&((dpeth_t *) device->specific)->de_address);
-	address->length = sizeof(ether_addr_t);
-	return EOK;
-}
-
-int netif_probe_message(device_id_t device_id, int irq, uintptr_t io)
-{
-	netif_device_t *device;
-	dpeth_t *dep;
-	int rc;
-	
-	device = (netif_device_t *) malloc(sizeof(netif_device_t));
-	if (!device)
-		return ENOMEM;
-	
-	dep = (dpeth_t *) malloc(sizeof(dpeth_t));
-	if (!dep) {
-		free(device);
-		return ENOMEM;
-	}
-	
-	bzero(device, sizeof(netif_device_t));
-	bzero(dep, sizeof(dpeth_t));
-	device->device_id = device_id;
-	device->nil_phone = -1;
-	device->specific = (void *) dep;
-	device->state = NETIF_STOPPED;
-	dep->de_irq = irq;
-	dep->up = false;
-	
-	//TODO address?
-	rc = pio_enable((void *) io, DP8390_IO_SIZE, (void **) &dep->de_base_port);
-	if (rc != EOK) {
-		free(dep);
-		free(device);
-		return rc;
-	}
-	
-	rc = do_probe(dep);
-	if (rc != EOK) {
-		free(dep);
-		free(device);
-		return rc;
-	}
-	
-	rc = netif_device_map_add(&netif_globals.device_map, device->device_id, device);
-	if (rc != EOK) {
-		free(dep);
-		free(device);
-		return rc;
-	}
-	
-	return EOK;
-}
-
-int netif_send_message(device_id_t device_id, packet_t *packet,
-    services_t sender)
-{
-	netif_device_t *device;
-	dpeth_t *dep;
-	packet_t *next;
-	int rc;
-	
-	rc = find_device(device_id, &device);
-	if (rc != EOK)
-		return rc;
-	
-	if (device->state != NETIF_ACTIVE){
-		netif_pq_release(packet_get_id(packet));
-		return EFORWARD;
-	}
-	
-	dep = (dpeth_t *) device->specific;
-	
-	/* Process packet queue */
-	do {
-		next = pq_detach(packet);
-		
-		if (do_pwrite(dep, packet, false) != EBUSY)
-			netif_pq_release(packet_get_id(packet));
-		
-		packet = next;
-	} while (packet);
-	
-	return EOK;
-}
-
-int netif_start_message(netif_device_t * device)
-{
-	dpeth_t *dep;
-	int rc;
-	
-	if (device->state != NETIF_ACTIVE) {
-		dep = (dpeth_t *) device->specific;
-		dp8390_cmds[0].addr = (void *) (uintptr_t) (dep->de_dp8390_port + DP_ISR);
-		dp8390_cmds[3].addr = dp8390_cmds[0].addr;
-		
-		rc = ipc_register_irq(dep->de_irq, device->device_id, device->device_id, &dp8390_code);
-		if (rc != EOK)
-			return rc;
-		
-		rc = do_init(dep);
-		if (rc != EOK) {
-			ipc_unregister_irq(dep->de_irq, device->device_id);
-			return rc;
-		}
-		
-		return change_state(device, NETIF_ACTIVE);
-	}
-	
-	return EOK;
-}
-
-int netif_stop_message(netif_device_t * device)
-{
-	dpeth_t *dep;
-	
-	if (device->state != NETIF_STOPPED) {
-		dep = (dpeth_t *) device->specific;
-		do_stop(dep);
-		ipc_unregister_irq(dep->de_irq, device->device_id);
-		return change_state(device, NETIF_STOPPED);
-	}
-	
-	return EOK;
-}
-
-int netif_initialize(void)
-{
-	sysarg_t phonehash;
-	async_set_interrupt_received(irq_handler);
-	return ipc_connect_to_me(PHONE_NS, SERVICE_DP8390, 0, 0, &phonehash);
-}
-
-/** Default thread for new connections.
- *
- *  @param[in] iid The initial message identifier.
- *  @param[in] icall The initial message call structure.
- *
- */
-static void netif_client_connection(ipc_callid_t iid, ipc_call_t *icall)
-{
-	/*
-	 * Accept the connection
-	 *  - Answer the first IPC_M_CONNECT_ME_TO call.
-	 */
-	ipc_answer_0(iid, EOK);
-	
-	while (true) {
-		ipc_call_t answer;
-		int answer_count;
-		
-		/* Clear the answer structure */
-		refresh_answer(&answer, &answer_count);
-		
-		/* Fetch the next message */
-		ipc_call_t call;
-		ipc_callid_t callid = async_get_call(&call);
-		
-		/* Process the message */
-		int res = netif_module_message(NAME, callid, &call, &answer,
-		    &answer_count);
-		
-		/* End if said to either by the message or the processing result */
-		if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))
-			return;
-		
-		/* Answer the message */
-		answer_call(callid, res, &answer, answer_count);
-	}
-}
-
-/** Start the module.
- *
- *  @param argc The count of the command line arguments. Ignored parameter.
- *  @param argv The command line parameters. Ignored parameter.
- *
- *  @returns EOK on success.
- *  @returns Other error codes as defined for each specific module start function.
- *
- */
-int main(int argc, char *argv[])
-{
-	/* Start the module */
-	return netif_module_start(netif_client_connection);
-}
-
-/** @}
- */
Index: pace/srv/hw/netif/dp8390/dp8390_port.h
===================================================================
--- uspace/srv/hw/netif/dp8390/dp8390_port.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,156 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * 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 dp8390
- *  @{
- */
-
-/** @file
- *  DP8390 network interface types and structures ports.
- */
-
-#ifndef __NET_NETIF_DP8390_PORT_H__
-#define __NET_NETIF_DP8390_PORT_H__
-
-#include <errno.h>
-#include <mem.h>
-#include <stdio.h>
-#include <libarch/ddi.h>
-#include <sys/types.h>
-
-/** Compares two memory blocks.
- *  @param[in] first The first memory block.
- *  @param[in] second The second memory block.
- *  @param[in] size The blocks size in bytes.
- *  @returns 0 if equeal.
- *  @returns -1 if the first is greater than the second.
- *  @returns 1 if the second is greater than the first.
- */
-#define memcmp(first, second, size)  bcmp((char *) (first), (char *) (second), (size))
-
-/** Reads 1 byte.
- *  @param[in] port The address to be read.
- *  @returns The read value.
- */
-#define inb(port)  pio_read_8((ioport8_t *) (port))
-
-/** Reads 1 word (2 bytes).
- *  @param[in] port The address to be read.
- *  @returns The read value.
- */
-#define inw(port)  pio_read_16((ioport16_t *) (port))
-
-/** Writes 1 byte.
- *  @param[in] port The address to be written.
- *  @param[in] value The value to be written.
- */
-#define outb(port, value)  pio_write_8((ioport8_t *) (port), (value))
-
-/** Writes 1 word (2 bytes).
- *  @param[in] port The address to be written.
- *  @param[in] value The value to be written.
- */
-#define outw(port, value)  pio_write_16((ioport16_t *) (port), (value))
-
-/** Type definition of a port.
- */
-typedef long port_t;
-
-/** Ethernet statistics.
- */
-typedef struct eth_stat {
-	/** Number of receive errors.
-	 */
-	unsigned long ets_recvErr;
-	/** Number of send error.
-	 */
-	unsigned long ets_sendErr;
-	/** Number of buffer overwrite warnings.
-	 */
-	unsigned long ets_OVW;
-	/** Number of crc errors of read.
-	 */
-	unsigned long ets_CRCerr;
-	/** Number of frames not alligned (number of bits % 8 != 0).
-	 */
-	unsigned long ets_frameAll;
-	/** Number of packets missed due to slow processing.
-	 */
-	unsigned long ets_missedP;
-	/** Number of packets received.
-	 */
-	unsigned long ets_packetR;
-	/** Number of packets transmitted.
-	 */
-	unsigned long ets_packetT;
-	/** Number of transmission defered (Tx was busy).
-	 */
-	unsigned long ets_transDef;
-	/** Number of collissions.
-	 */
-	unsigned long ets_collision;
-	/** Number of Tx aborted due to excess collisions.
-	 */
-	unsigned long ets_transAb;
-	/** Number of carrier sense lost.
-	 */
-	unsigned long ets_carrSense;
-	/** Number of FIFO underruns (processor too busy).
-	 */
-	unsigned long ets_fifoUnder;
-	/** Number of FIFO overruns (processor too busy).
-	 */
-	unsigned long ets_fifoOver;
-	/** Number of times unable to transmit collision sig.
-	 */
-	unsigned long ets_CDheartbeat;
-	/** Number of times out of window collision.
-	 */
-	unsigned long ets_OWC;
-} eth_stat_t;
-
-/** Minimum Ethernet packet size in bytes.
- */
-#define ETH_MIN_PACK_SIZE  60
-
-/** Maximum Ethernet packet size in bytes.
- */
-#define ETH_MAX_PACK_SIZE_TAGGED  1518
-
-/** Ethernet address type definition.
- */
-typedef struct ether_addr {
-	/** Address data.
-	 */
-	uint8_t ea_addr[6];
-} ether_addr_t;
-
-#endif
-
-/** @}
- */
Index: uspace/srv/hw/netif/dp8390/ne2000.c
===================================================================
--- uspace/srv/hw/netif/dp8390/ne2000.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/hw/netif/dp8390/ne2000.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -28,270 +28,332 @@
  */
 
-/*
- * This code is based upon the NE2000 driver for MINIX,
- * distributed according to a BSD-style license.
- *
- * Copyright (c) 1987, 1997, 2006 Vrije Universiteit
- * Copyright (c) 1992, 1994 Philip Homburg
- * Copyright (c) 1996 G. Falzoni
- *
- */
-
-/** @addtogroup ne2k
+/** @addtogroup ne2000
  *  @{
  */
 
 /** @file
- *  NE1000 and NE2000 network interface initialization and probe functions implementation.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include "dp8390_port.h"
+ *  NE2000 network interface implementation.
+ */
+
+#include <assert.h>
+#include <async.h>
+#include <ddi.h>
+#include <errno.h>
+#include <err.h>
+#include <malloc.h>
+#include <sysinfo.h>
+#include <ipc/ipc.h>
+#include <ipc/services.h>
+#include <ipc/irc.h>
+#include <net/modules.h>
+#include <packet_client.h>
+#include <adt/measured_strings.h>
+#include <net/device.h>
+#include <netif_skel.h>
+#include <nil_interface.h>
 #include "dp8390.h"
-#include "ne2000.h"
-
-/** Number of bytes to transfer */
-#define N  100
-
-typedef int (*testf_t)(dpeth_t *dep, int pos, uint8_t *pat);
-
-/** Data patterns */
-uint8_t pat0[] = {0x00, 0x00, 0x00, 0x00};
-uint8_t pat1[] = {0xFF, 0xFF, 0xFF, 0xFF};
-uint8_t pat2[] = {0xA5, 0x5A, 0x69, 0x96};
-uint8_t pat3[] = {0x96, 0x69, 0x5A, 0xA5};
-
-/** Tests 8 bit NE2000 network interface.
- *  @param[in,out] dep The network interface structure.
- *  @param[in] pos The starting position.
- *  @param[in] pat The data pattern to be written.
- *  @returns True on success.
- *  @returns false otherwise.
- */
-static int test_8(dpeth_t *dep, int pos, uint8_t *pat);
-
-/** Tests 16 bit NE2000 network interface.
- *  @param[in,out] dep The network interface structure.
- *  @param[in] pos The starting position.
- *  @param[in] pat The data pattern to be written.
- *  @returns True on success.
- *  @returns false otherwise.
- */
-static int test_16(dpeth_t *dep, int pos, uint8_t *pat);
-
-int ne_probe(dpeth_t *dep)
-{
-	int byte;
-	int i;
-	int loc1, loc2;
-	testf_t f;
-	
-	dep->de_dp8390_port = dep->de_base_port + NE_DP8390;
+
+/** Return the device from the interrupt call.
+ *
+ *  @param[in] call The interrupt call.
+ *
+ */
+#define IRQ_GET_DEVICE(call)  ((device_id_t) IPC_GET_IMETHOD(call))
+
+/** Return the ISR from the interrupt call.
+ *
+ * @param[in] call The interrupt call.
+ *
+ */
+#define IRQ_GET_ISR(call)  ((int) IPC_GET_ARG2(call))
+
+static int irc_service = 0;
+static int irc_phone = -1;
+
+/** DP8390 kernel interrupt command sequence.
+ *
+ */
+static irq_cmd_t ne2k_cmds[] = {
+	{
+		.cmd = CMD_PIO_READ_8,
+		.addr = NULL,
+		.dstarg = 2
+	},
+	{
+		.cmd = CMD_BTEST,
+		.value = 0x7f,
+		.srcarg = 2,
+		.dstarg = 3,
+	},
+	{
+		.cmd = CMD_PREDICATE,
+		.value = 2,
+		.srcarg = 3
+	},
+	{
+		.cmd = CMD_PIO_WRITE_A_8,
+		.addr = NULL,
+		.srcarg = 3
+	},
+	{
+		.cmd = CMD_ACCEPT
+	}
+};
+
+/** DP8390 kernel interrupt code.
+ *
+ */
+static irq_code_t ne2k_code = {
+	sizeof(ne2k_cmds) / sizeof(irq_cmd_t),
+	ne2k_cmds
+};
+
+/** Handle the interrupt notification.
+ *
+ * This is the interrupt notification function.
+ *
+ * @param[in] iid  Interrupt notification identifier.
+ * @param[in] call Interrupt notification.
+ *
+ */
+static void irq_handler(ipc_callid_t iid, ipc_call_t *call)
+{
+	device_id_t device_id = IRQ_GET_DEVICE(*call);
+	netif_device_t *device;
+	int nil_phone;
+	ne2k_t *ne2k;
+	
+	fibril_rwlock_read_lock(&netif_globals.lock);
+	
+	if (find_device(device_id, &device) == EOK) {
+		nil_phone = device->nil_phone;
+		ne2k = (ne2k_t *) device->specific;
+	} else
+		ne2k = NULL;
+	
+	fibril_rwlock_read_unlock(&netif_globals.lock);
+	
+	if (ne2k != NULL)
+		ne2k_interrupt(ne2k, IRQ_GET_ISR(*call), nil_phone, device_id);
+}
+
+/** Change the network interface state.
+ *
+ * @param[in,out] device Network interface.
+ * @param[in]     state  New state.
+ *
+ */
+static void change_state(netif_device_t *device, device_state_t state)
+{
+	if (device->state != state) {
+		device->state = state;
+		
+		const char *desc;
+		switch (state) {
+		case NETIF_ACTIVE:
+			desc = "active";
+			break;
+		case NETIF_STOPPED:
+			desc = "stopped";
+			break;
+		default:
+			desc = "unknown";
+		}
+		
+		printf("%s: State changed to %s\n", NAME, desc);
+	}
+}
+
+int netif_specific_message(ipc_callid_t callid, ipc_call_t *call,
+    ipc_call_t *answer, size_t *count)
+{
+	return ENOTSUP;
+}
+
+int netif_get_device_stats(device_id_t device_id, device_stats_t *stats)
+{
+	if (!stats)
+		return EBADMEM;
+	
+	netif_device_t *device;
+	int rc = find_device(device_id, &device);
+	if (rc != EOK)
+		return rc;
+	
+	ne2k_t *ne2k = (ne2k_t *) device->specific;
+	
+	memcpy(stats, &ne2k->stats, sizeof(device_stats_t));
+	return EOK;
+}
+
+int netif_get_addr_message(device_id_t device_id, measured_string_t *address)
+{
+	if (!address)
+		return EBADMEM;
+	
+	netif_device_t *device;
+	int rc = find_device(device_id, &device);
+	if (rc != EOK)
+		return rc;
+	
+	ne2k_t *ne2k = (ne2k_t *) device->specific;
+	
+	address->value = ne2k->mac;
+	address->length = ETH_ADDR;
+	return EOK;
+}
+
+int netif_probe_message(device_id_t device_id, int irq, void *io)
+{
+	netif_device_t *device =
+	    (netif_device_t *) malloc(sizeof(netif_device_t));
+	if (!device)
+		return ENOMEM;
+	
+	ne2k_t *ne2k = (ne2k_t *) malloc(sizeof(ne2k_t));
+	if (!ne2k) {
+		free(device);
+		return ENOMEM;
+	}
+	
+	void *port;
+	int rc = pio_enable((void *) io, NE2K_IO_SIZE, &port);
+	if (rc != EOK) {
+		free(ne2k);
+		free(device);
+		return rc;
+	}
+	
+	bzero(device, sizeof(netif_device_t));
+	bzero(ne2k, sizeof(ne2k_t));
+	
+	device->device_id = device_id;
+	device->nil_phone = -1;
+	device->specific = (void *) ne2k;
+	device->state = NETIF_STOPPED;
+	
+	rc = ne2k_probe(ne2k, port, irq);
+	if (rc != EOK) {
+		printf("%s: No ethernet card found at I/O address %p\n",
+		    NAME, port);
+		free(ne2k);
+		free(device);
+		return rc;
+	}
+	
+	rc = netif_device_map_add(&netif_globals.device_map, device->device_id, device);
+	if (rc != EOK) {
+		free(ne2k);
+		free(device);
+		return rc;
+	}
+	
+	printf("%s: Ethernet card at I/O address %p, IRQ %d, MAC ",
+	    NAME, port, irq);
+	
+	unsigned int i;
+	for (i = 0; i < ETH_ADDR; i++)
+		printf("%02x%c", ne2k->mac[i], i < 5 ? ':' : '\n');
+	
+	return EOK;
+}
+
+int netif_start_message(netif_device_t *device)
+{
+	if (device->state != NETIF_ACTIVE) {
+		ne2k_t *ne2k = (ne2k_t *) device->specific;
+		
+		ne2k_cmds[0].addr = ne2k->port + DP_ISR;
+		ne2k_cmds[3].addr = ne2k_cmds[0].addr;
+		
+		int rc = ipc_register_irq(ne2k->irq, device->device_id,
+		    device->device_id, &ne2k_code);
+		if (rc != EOK)
+			return rc;
+		
+		rc = ne2k_up(ne2k);
+		if (rc != EOK) {
+			ipc_unregister_irq(ne2k->irq, device->device_id);
+			return rc;
+		}
+		
+		if (irc_service)
+			async_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, ne2k->irq);
+		
+		change_state(device, NETIF_ACTIVE);
+	}
+	
+	return device->state;
+}
+
+int netif_stop_message(netif_device_t *device)
+{
+	if (device->state != NETIF_STOPPED) {
+		ne2k_t *ne2k = (ne2k_t *) device->specific;
+		
+		ne2k_down(ne2k);
+		ipc_unregister_irq(ne2k->irq, device->device_id);
+		change_state(device, NETIF_STOPPED);
+	}
+	
+	return EOK;
+}
+
+int netif_send_message(device_id_t device_id, packet_t *packet,
+    services_t sender)
+{
+	netif_device_t *device;
+	int rc = find_device(device_id, &device);
+	if (rc != EOK)
+		return rc;
+	
+	if (device->state != NETIF_ACTIVE) {
+		netif_pq_release(packet_get_id(packet));
+		return EFORWARD;
+	}
+	
+	ne2k_t *ne2k = (ne2k_t *) device->specific;
 	
 	/*
-	 * We probe for an ne1000 or an ne2000 by testing whether the
-	 * on board is reachable through the dp8390. Note that the
-	 * ne1000 is an 8bit card and has a memory region distict from
-	 * the 16bit ne2000
+	 * Process the packet queue
 	 */
 	
-	for (dep->de_16bit = 0; dep->de_16bit < 2; dep->de_16bit++) {
-		/* Reset the ethernet card */
-		byte= inb_ne(dep, NE_RESET);
-		usleep(2000);
-		outb_ne(dep, NE_RESET, byte);
-		usleep(2000);
-		
-		/* Reset the dp8390 */
-		outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
-		for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
-			; /* Do nothing */
-		
-		/* Check if the dp8390 is really there */
-		if ((inb_reg0(dep, DP_CR) & (CR_STP | CR_DM_ABORT)) !=
-		    (CR_STP | CR_DM_ABORT))
-			return 0;
-		
-		/* Disable the receiver and init TCR and DCR. */
-		outb_reg0(dep, DP_RCR, RCR_MON);
-		outb_reg0(dep, DP_TCR, TCR_NORMAL);
-		if (dep->de_16bit) {
-			outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES |
-			    DCR_BMS);
-		} else {
-			outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES |
-			    DCR_BMS);
+	do {
+		packet_t *next = pq_detach(packet);
+		ne2k_send(ne2k, packet);
+		netif_pq_release(packet_get_id(packet));
+		packet = next;
+	} while (packet);
+	
+	return EOK;
+}
+
+int netif_initialize(void)
+{
+	sysarg_t apic;
+	sysarg_t i8259;
+	
+	if ((sysinfo_get_value("apic", &apic) == EOK) && (apic))
+		irc_service = SERVICE_APIC;
+	else if ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259))
+		irc_service = SERVICE_I8259;
+	
+	if (irc_service) {
+		while (irc_phone < 0) {
+			irc_phone = ipc_connect_me_to_blocking(PHONE_NS, irc_service,
+			    0, 0);
 		}
-		
-		if (dep->de_16bit) {
-			loc1 = NE2000_START;
-			loc2 = NE2000_START + NE2000_SIZE - 4;
-			f = test_16;
-		} else {
-			loc1 = NE1000_START;
-			loc2 = NE1000_START + NE1000_SIZE - 4;
-			f = test_8;
-		}
-		
-		if (f(dep, loc1, pat0) && f(dep, loc1, pat1) &&
-		    f(dep, loc1, pat2) && f(dep, loc1, pat3) &&
-		    f(dep, loc2, pat0) && f(dep, loc2, pat1) &&
-		    f(dep, loc2, pat2) && f(dep, loc2, pat3)) {
-			return 1;
-		}
-	}
-	
-	return 0;
-}
-
-/** Initializes the NE2000 network interface.
- *
- *  @param[in,out] dep The network interface structure.
- *
- */
-void ne_init(dpeth_t *dep)
-{
-	int i;
-	int word, sendq_nr;
-	
-	/* Setup a transfer to get the ethernet address. */
-	if (dep->de_16bit)
-		outb_reg0(dep, DP_RBCR0, 6*2);
-	else
-		outb_reg0(dep, DP_RBCR0, 6);
-	
-	outb_reg0(dep, DP_RBCR1, 0);
-	outb_reg0(dep, DP_RSAR0, 0);
-	outb_reg0(dep, DP_RSAR1, 0);
-	outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
-	
-	for (i = 0; i < 6; i++) {
-		if (dep->de_16bit) {
-			word = inw_ne(dep, NE_DATA);
-			dep->de_address.ea_addr[i] = word;
-		} else
-			dep->de_address.ea_addr[i] = inb_ne(dep, NE_DATA);
-	}
-	
-	dep->de_data_port= dep->de_base_port + NE_DATA;
-	if (dep->de_16bit) {
-		dep->de_ramsize = NE2000_SIZE;
-		dep->de_offset_page = NE2000_START / DP_PAGESIZE;
-	} else {
-		dep->de_ramsize = NE1000_SIZE;
-		dep->de_offset_page = NE1000_START / DP_PAGESIZE;
-	}
-	
-	/* Allocate one send buffer (1.5KB) per 8KB of on board memory. */
-	sendq_nr = dep->de_ramsize / 0x2000;
-	
-	if (sendq_nr < 1)
-		sendq_nr = 1;
-	else if (sendq_nr > SENDQ_NR)
-		sendq_nr = SENDQ_NR;
-	
-	dep->de_sendq_nr = sendq_nr;
-	for (i = 0; i < sendq_nr; i++)
-		dep->de_sendq[i].sq_sendpage = dep->de_offset_page + i * SENDQ_PAGES;
-	
-	dep->de_startpage = dep->de_offset_page + i * SENDQ_PAGES;
-	dep->de_stoppage = dep->de_offset_page + dep->de_ramsize / DP_PAGESIZE;
-	
-	printf("Novell NE%d000 ethernet card at I/O address "
-	    "%#lx, memory size %#lx, irq %d\n",
-	    dep->de_16bit ? 2 : 1, dep->de_base_port, dep->de_ramsize,
-	    dep->de_irq);
-}
-
-static int test_8(dpeth_t *dep, int pos, uint8_t *pat)
-{
-	uint8_t buf[4];
-	int i;
-	
-	outb_reg0(dep, DP_ISR, 0xff);
-	
-	/* Setup a transfer to put the pattern. */
-	outb_reg0(dep, DP_RBCR0, 4);
-	outb_reg0(dep, DP_RBCR1, 0);
-	outb_reg0(dep, DP_RSAR0, pos & 0xff);
-	outb_reg0(dep, DP_RSAR1, pos >> 8);
-	outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
-	
-	for (i = 0; i < 4; i++)
-		outb_ne(dep, NE_DATA, pat[i]);
-	
-	for (i = 0; i < N; i++) {
-		if (inb_reg0(dep, DP_ISR) & ISR_RDC)
-			break;
-	}
-	
-	if (i == N) {
-		printf("NE1000 remote DMA test failed\n");
-		return 0;
-	}
-	
-	outb_reg0(dep, DP_RBCR0, 4);
-	outb_reg0(dep, DP_RBCR1, 0);
-	outb_reg0(dep, DP_RSAR0, pos & 0xff);
-	outb_reg0(dep, DP_RSAR1, pos >> 8);
-	outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
-	
-	for (i = 0; i < 4; i++)
-		buf[i] = inb_ne(dep, NE_DATA);
-	
-	return (memcmp(buf, pat, 4) == 0);
-}
-
-static int test_16(dpeth_t *dep, int pos, uint8_t *pat)
-{
-	uint8_t buf[4];
-	int i;
-	
-	outb_reg0(dep, DP_ISR, 0xff);
-	
-	/* Setup a transfer to put the pattern. */
-	outb_reg0(dep, DP_RBCR0, 4);
-	outb_reg0(dep, DP_RBCR1, 0);
-	outb_reg0(dep, DP_RSAR0, pos & 0xff);
-	outb_reg0(dep, DP_RSAR1, pos >> 8);
-	outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
-	
-	for (i = 0; i < 4; i += 2)
-		outw_ne(dep, NE_DATA, *(uint16_t *)(pat + i));
-	
-	for (i = 0; i < N; i++) {
-		if (inb_reg0(dep, DP_ISR) &ISR_RDC)
-			break;
-	}
-	
-	if (i == N) {
-		printf("NE2000 remote DMA test failed\n");
-		return 0;
-	}
-	
-	outb_reg0(dep, DP_RBCR0, 4);
-	outb_reg0(dep, DP_RBCR1, 0);
-	outb_reg0(dep, DP_RSAR0, pos & 0xff);
-	outb_reg0(dep, DP_RSAR1, pos >> 8);
-	outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
-	
-	for (i = 0; i < 4; i += 2)
-		*(uint16_t *)(buf + i) = inw_ne(dep, NE_DATA);
-	
-	return (memcmp(buf, pat, 4) == 0);
-}
-
-/** Stop the NE2000 network interface.
- *
- *  @param[in,out] dep The network interface structure.
- *
- */
-void ne_stop(dpeth_t *dep)
-{
-	/* Reset the ethernet card */
-	int byte = inb_ne(dep, NE_RESET);
-	usleep(2000);
-	outb_ne(dep, NE_RESET, byte);
+	}
+	
+	async_set_interrupt_received(irq_handler);
+	
+	sysarg_t phonehash;
+	return ipc_connect_to_me(PHONE_NS, SERVICE_DP8390, 0, 0, &phonehash);
+}
+
+int main(int argc, char *argv[])
+{
+	/* Start the module */
+	return netif_module_start();
 }
 
Index: pace/srv/hw/netif/dp8390/ne2000.h
===================================================================
--- uspace/srv/hw/netif/dp8390/ne2000.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ 	(revision )
@@ -1,119 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * 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.
- */
-
-/*
- * This code is based upon the NE2000 driver for MINIX,
- * distributed according to a BSD-style license.
- *
- * Copyright (c) 1987, 1997, 2006 Vrije Universiteit
- * Copyright (c) 1992, 1994 Philip Homburg
- * Copyright (c) 1996 G. Falzoni
- *
- */
-
-/** @addtogroup ne2k
- *  @{
- */
-
-/** @file
- *  NE1000 and NE2000 network interface definitions.
- */
-
-#ifndef __NET_NETIF_NE2000_H__
-#define __NET_NETIF_NE2000_H__
-
-#include <libarch/ddi.h>
-#include "dp8390_port.h"
-
-/** DP8390 register offset.
- */
-#define NE_DP8390  0x00
-
-/** Data register.
- */
-#define NE_DATA  0x10
-
-/** Reset register.
- */
-#define NE_RESET  0x1f
-
-/** NE1000 data start.
- */
-#define NE1000_START  0x2000
-
-/** NE1000 data size.
- */
-#define NE1000_SIZE  0x2000
-
-/** NE2000 data start.
- */
-#define NE2000_START  0x4000
-
-/** NE2000 data size.
- */
-#define NE2000_SIZE  0x4000
-
-/** Reads 1 byte register.
- *  @param[in] dep The network interface structure.
- *  @param[in] reg The register offset.
- *  @returns The read value.
- */
-#define inb_ne(dep, reg)  (inb(dep->de_base_port + reg))
-
-/** Writes 1 byte register.
- *  @param[in] dep The network interface structure.
- *  @param[in] reg The register offset.
- *  @param[in] data The value to be written.
- */
-#define outb_ne(dep, reg, data)  (outb(dep->de_base_port + reg, data))
-
-/** Reads 1 word (2 bytes) register.
- *  @param[in] dep The network interface structure.
- *  @param[in] reg The register offset.
- *  @returns The read value.
- */
-#define inw_ne(dep, reg)  (inw(dep->de_base_port + reg))
-
-/** Writes 1 word (2 bytes) register.
- *  @param[in] dep The network interface structure.
- *  @param[in] reg The register offset.
- *  @param[in] data The value to be written.
- */
-#define outw_ne(dep, reg, data)  (outw(dep->de_base_port + reg, data))
-
-struct dpeth;
-
-extern int ne_probe(struct dpeth *);
-extern void ne_init(struct dpeth *);
-extern void ne_stop(struct dpeth *);
-
-#endif
-
-/** @}
- */
Index: uspace/srv/net/cfg/ne2k
===================================================================
--- uspace/srv/net/cfg/ne2k	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/cfg/ne2k	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -22,3 +22,3 @@
 ARP=arp
 
-MTU=1492
+MTU=1500
Index: uspace/srv/net/il/arp/arp.c
===================================================================
--- uspace/srv/net/il/arp/arp.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/il/arp/arp.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -457,5 +457,5 @@
 	uint8_t *des_proto;
 	int rc;
-
+	
 	length = packet_get_data_length(packet);
 	if (length <= sizeof(arp_header_t))
@@ -482,5 +482,5 @@
 	des_hw = src_proto + header->protocol_length;
 	des_proto = des_hw + header->hardware_length;
-	trans = arp_addr_find(&proto->addresses, (char *) src_proto,
+	trans = arp_addr_find(&proto->addresses, src_proto,
 	    header->protocol_length);
 	/* Exists? */
@@ -493,6 +493,6 @@
 	if (proto->addr->length != header->protocol_length)
 		return EINVAL;
-	if (!str_lcmp(proto->addr->value, (char *) des_proto,
-	    proto->addr->length)) {
+	
+	if (!bcmp(proto->addr->value, des_proto, proto->addr->length)) {
 		/* Not already updated? */
 		if (!trans) {
@@ -502,5 +502,5 @@
 			trans->hw_addr = NULL;
 			fibril_condvar_initialize(&trans->cv);
-			rc = arp_addr_add(&proto->addresses, (char *) src_proto,
+			rc = arp_addr_add(&proto->addresses, src_proto,
 			    header->protocol_length, trans);
 			if (rc != EOK) {
@@ -510,9 +510,9 @@
 		}
 		if (!trans->hw_addr) {
-			trans->hw_addr = measured_string_create_bulk(
-			    (char *) src_hw, header->hardware_length);
+			trans->hw_addr = measured_string_create_bulk(src_hw,
+			    header->hardware_length);
 			if (!trans->hw_addr)
 				return ENOMEM;
-
+			
 			/* Notify the fibrils that wait for the translation. */
 			fibril_condvar_broadcast(&trans->cv);
@@ -677,9 +677,9 @@
 int
 arp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count)
+    ipc_call_t *answer, size_t *answer_count)
 {
 	measured_string_t *address;
 	measured_string_t *translation;
-	char *data;
+	uint8_t *data;
 	packet_t *packet;
 	packet_t *next;
@@ -696,6 +696,6 @@
 			return rc;
 		
-		rc = arp_device_message(IPC_GET_DEVICE(call),
-		    IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address);
+		rc = arp_device_message(IPC_GET_DEVICE(*call),
+		    IPC_GET_SERVICE(*call), ARP_GET_NETIF(*call), address);
 		if (rc != EOK) {
 			free(address);
@@ -710,6 +710,6 @@
 		
 		fibril_mutex_lock(&arp_globals.lock);
-		rc = arp_translate_message(IPC_GET_DEVICE(call),
-		    IPC_GET_SERVICE(call), address, &translation);
+		rc = arp_translate_message(IPC_GET_DEVICE(*call),
+		    IPC_GET_SERVICE(*call), address, &translation);
 		free(address);
 		free(data);
@@ -727,5 +727,5 @@
 
 	case NET_ARP_CLEAR_DEVICE:
-		return arp_clear_device_req(0, IPC_GET_DEVICE(call));
+		return arp_clear_device_req(0, IPC_GET_DEVICE(*call));
 
 	case NET_ARP_CLEAR_ADDRESS:
@@ -734,6 +734,6 @@
 			return rc;
 		
-		arp_clear_address_req(0, IPC_GET_DEVICE(call),
-		    IPC_GET_SERVICE(call), address);
+		arp_clear_address_req(0, IPC_GET_DEVICE(*call),
+		    IPC_GET_SERVICE(*call), address);
 		free(address);
 		free(data);
@@ -748,6 +748,7 @@
 	
 	case NET_IL_RECEIVED:
+		
 		rc = packet_translate_remote(arp_globals.net_phone, &packet,
-		    IPC_GET_PACKET(call));
+		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
@@ -756,5 +757,5 @@
 		do {
 			next = pq_detach(packet);
-			rc = arp_receive_message(IPC_GET_DEVICE(call), packet);
+			rc = arp_receive_message(IPC_GET_DEVICE(*call), packet);
 			if (rc != 1) {
 				pq_release_remote(arp_globals.net_phone,
@@ -768,6 +769,6 @@
 	
 	case NET_IL_MTU_CHANGED:
-		return arp_mtu_changed_message(IPC_GET_DEVICE(call),
-		    IPC_GET_MTU(call));
+		return arp_mtu_changed_message(IPC_GET_DEVICE(*call),
+		    IPC_GET_MTU(*call));
 	}
 	
@@ -790,8 +791,8 @@
 	while (true) {
 		ipc_call_t answer;
-		int answer_count;
+		size_t count;
 		
 		/* Clear the answer structure */
-		refresh_answer(&answer, &answer_count);
+		refresh_answer(&answer, &count);
 		
 		/* Fetch the next message */
@@ -801,5 +802,5 @@
 		/* Process the message */
 		int res = il_module_message_standalone(callid, &call, &answer,
-		    &answer_count);
+		    &count);
 		
 		/*
@@ -812,5 +813,5 @@
 		
 		/* Answer the message */
-		answer_call(callid, res, &answer, answer_count);
+		answer_call(callid, res, &answer, count);
 	}
 }
Index: uspace/srv/net/il/arp/arp.h
===================================================================
--- uspace/srv/net/il/arp/arp.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/il/arp/arp.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -96,9 +96,9 @@
 	measured_string_t *addr;
 	/** Actual device hardware address data. */
-	char *addr_data;
+	uint8_t *addr_data;
 	/** Broadcast device hardware address. */
 	measured_string_t *broadcast_addr;
 	/** Broadcast device hardware address data. */
-	char *broadcast_data;
+	uint8_t *broadcast_data;
 	/** Device identifier. */
 	device_id_t device_id;
@@ -142,5 +142,5 @@
 	measured_string_t *addr;
 	/** Actual device protocol address data. */
-	char *addr_data;
+	uint8_t *addr_data;
 	/** Address map. */
 	arp_addr_t addresses;
@@ -154,5 +154,5 @@
 	 * Hardware address for the translation. NULL denotes an incomplete
 	 * record with possible waiters.
-	 */ 
+	 */
 	measured_string_t *hw_addr;
 	/** Condition variable used for waiting for completion of the record. */
Index: uspace/srv/net/il/arp/arp_module.c
===================================================================
--- uspace/srv/net/il/arp/arp_module.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/il/arp/arp_module.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -58,7 +58,7 @@
 
 int il_module_message_standalone(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count)
+    ipc_call_t *answer, size_t *count)
 {
-	return arp_message_standalone(callid, call, answer, answer_count);
+	return arp_message_standalone(callid, call, answer, count);
 }
 
Index: uspace/srv/net/il/arp/arp_module.h
===================================================================
--- uspace/srv/net/il/arp/arp_module.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/il/arp/arp_module.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -44,5 +44,5 @@
 extern int arp_initialize(async_client_conn_t);
 extern int arp_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *,
-    int *);
+    size_t *);
 
 #endif
Index: uspace/srv/net/il/ip/ip.c
===================================================================
--- uspace/srv/net/il/ip/ip.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/il/ip/ip.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -275,6 +275,6 @@
 	if (rc != EOK)
 		goto out;
-	rc = add_module(NULL, &ip_globals.modules, ARP_NAME, ARP_FILENAME,
-	    SERVICE_ARP, 0, arp_connect_module);
+	rc = add_module(NULL, &ip_globals.modules, (uint8_t *) ARP_NAME,
+	    (uint8_t *) ARP_FILENAME, SERVICE_ARP, 0, arp_connect_module);
 
 out:
@@ -312,33 +312,33 @@
 	measured_string_t names[] = {
 		{
-			(char *) "IPV",
+			(uint8_t *) "IPV",
 			3
 		},
 		{
-			(char *) "IP_CONFIG",
+			(uint8_t *) "IP_CONFIG",
 			9
 		},
 		{
-			(char *) "IP_ADDR",
+			(uint8_t *) "IP_ADDR",
 			7
 		},
 		{
-			(char *) "IP_NETMASK",
+			(uint8_t *) "IP_NETMASK",
 			10
 		},
 		{
-			(char *) "IP_GATEWAY",
+			(uint8_t *) "IP_GATEWAY",
 			10
 		},
 		{
-			(char *) "IP_BROADCAST",
+			(uint8_t *) "IP_BROADCAST",
 			12
 		},
 		{
-			(char *) "ARP",
+			(uint8_t *) "ARP",
 			3
 		},
 		{
-			(char *) "IP_ROUTING",
+			(uint8_t *) "IP_ROUTING",
 			10
 		}
@@ -346,5 +346,5 @@
 	measured_string_t *configuration;
 	size_t count = sizeof(names) / sizeof(measured_string_t);
-	char *data;
+	uint8_t *data;
 	measured_string_t address;
 	ip_route_t *route;
@@ -368,7 +368,7 @@
 	if (configuration) {
 		if (configuration[0].value)
-			ip_netif->ipv = strtol(configuration[0].value, NULL, 0);
-
-		ip_netif->dhcp = !str_lcmp(configuration[1].value, "dhcp",
+			ip_netif->ipv = strtol((char *) configuration[0].value, NULL, 0);
+		
+		ip_netif->dhcp = !str_lcmp((char *) configuration[1].value, "dhcp",
 		    configuration[1].length);
 		
@@ -394,11 +394,11 @@
 			}
 			
-			if ((inet_pton(AF_INET, configuration[2].value,
+			if ((inet_pton(AF_INET, (char *) configuration[2].value,
 			    (uint8_t *) &route->address.s_addr) != EOK) ||
-			    (inet_pton(AF_INET, configuration[3].value,
+			    (inet_pton(AF_INET, (char *) configuration[3].value,
 			    (uint8_t *) &route->netmask.s_addr) != EOK) ||
-			    (inet_pton(AF_INET, configuration[4].value,
+			    (inet_pton(AF_INET, (char *) configuration[4].value,
 			    (uint8_t *) &gateway.s_addr) == EINVAL) ||
-			    (inet_pton(AF_INET, configuration[5].value,
+			    (inet_pton(AF_INET, (char *) configuration[5].value,
 			    (uint8_t *) &ip_netif->broadcast.s_addr) == EINVAL))
 			    {
@@ -441,5 +441,5 @@
 	if (ip_netif->arp) {
 		if (route) {
-			address.value = (char *) &route->address.s_addr;
+			address.value = (uint8_t *) &route->address.s_addr;
 			address.length = sizeof(in_addr_t);
 			
@@ -477,4 +477,9 @@
 		ip_globals.gateway.gateway.s_addr = gateway.s_addr;
 		ip_globals.gateway.netif = ip_netif;
+		
+		char defgateway[INET_ADDRSTRLEN];
+		inet_ntop(AF_INET, (uint8_t *) &gateway.s_addr,
+		    defgateway, INET_ADDRSTRLEN);
+		printf("%s: Default gateway (%s)\n", NAME, defgateway);
 	}
 
@@ -997,5 +1002,5 @@
 	measured_string_t destination;
 	measured_string_t *translation;
-	char *data;
+	uint8_t *data;
 	int phone;
 	int rc;
@@ -1004,5 +1009,5 @@
 	if (netif->arp && (route->address.s_addr != dest.s_addr)) {
 		destination.value = route->gateway.s_addr ?
-		    (char *) &route->gateway.s_addr : (char *) &dest.s_addr;
+		    (uint8_t *) &route->gateway.s_addr : (uint8_t *) &dest.s_addr;
 		destination.length = sizeof(dest.s_addr);
 
@@ -1069,16 +1074,15 @@
 	int index;
 	ip_route_t *route;
-
+	
 	if (!netif)
 		return NULL;
-
-	// start with the first one - the direct route
+	
+	/* Start with the first one (the direct route) */
 	for (index = 0; index < ip_routes_count(&netif->routes); index++) {
 		route = ip_routes_get_index(&netif->routes, index);
-		if (route &&
+		if ((route) &&
 		    ((route->address.s_addr & route->netmask.s_addr) ==
-		    (destination.s_addr & route->netmask.s_addr))) {
+		    (destination.s_addr & route->netmask.s_addr)))
 			return route;
-		}
 	}
 
@@ -1288,5 +1292,5 @@
 	if (device_id > 0) {
 		netif = ip_netifs_find(&ip_globals.netifs, device_id);
-		route = ip_netif_find_route(netif, * dest);
+		route = ip_netif_find_route(netif, *dest);
 		if (netif && !route && (ip_globals.gateway.netif == netif))
 			route = &ip_globals.gateway;
@@ -1318,5 +1322,5 @@
 		}
 	}
-
+	
 	// if the local host is the destination
 	if ((route->address.s_addr == dest->s_addr) &&
@@ -1562,5 +1566,5 @@
 	socklen_t addrlen;
 	int rc;
-
+	
 	header = (ip_header_t *) packet_get_data(packet);
 	if (!header)
@@ -1588,5 +1592,5 @@
 		return EINVAL;
 	}
-
+	
 	// process ipopt and get destination
 	dest = ip_get_destination(header);
@@ -1609,5 +1613,5 @@
 	if (rc != EOK)
 		return rc;
-
+	
 	route = ip_find_route(dest);
 	if (!route) {
@@ -1756,5 +1760,5 @@
 		    (header->destination_address & route->netmask.s_addr))) {
 			// clear the ARP mapping if any
-			address.value = (char *) &header->destination_address;
+			address.value = (uint8_t *) &header->destination_address;
 			address.length = sizeof(header->destination_address);
 			arp_clear_address_req(netif->arp->phone,
@@ -1886,5 +1890,5 @@
 int
 ip_message_standalone(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
-    int *answer_count)
+    size_t *answer_count)
 {
 	packet_t *packet;
@@ -1905,46 +1909,46 @@
 	
 	case IPC_M_CONNECT_TO_ME:
-		return ip_register(IL_GET_PROTO(call), IL_GET_SERVICE(call),
-		    IPC_GET_PHONE(call), NULL);
+		return ip_register(IL_GET_PROTO(*call), IL_GET_SERVICE(*call),
+		    IPC_GET_PHONE(*call), NULL);
 	
 	case NET_IL_DEVICE:
-		return ip_device_req_local(0, IPC_GET_DEVICE(call),
-		    IPC_GET_SERVICE(call));
+		return ip_device_req_local(0, IPC_GET_DEVICE(*call),
+		    IPC_GET_SERVICE(*call));
 	
 	case NET_IL_SEND:
 		rc = packet_translate_remote(ip_globals.net_phone, &packet,
-		    IPC_GET_PACKET(call));
+		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
-		return ip_send_msg_local(0, IPC_GET_DEVICE(call), packet, 0,
-		    IPC_GET_ERROR(call));
+		return ip_send_msg_local(0, IPC_GET_DEVICE(*call), packet, 0,
+		    IPC_GET_ERROR(*call));
 	
 	case NET_IL_DEVICE_STATE:
-		return ip_device_state_message(IPC_GET_DEVICE(call),
-		    IPC_GET_STATE(call));
+		return ip_device_state_message(IPC_GET_DEVICE(*call),
+		    IPC_GET_STATE(*call));
 	
 	case NET_IL_RECEIVED:
 		rc = packet_translate_remote(ip_globals.net_phone, &packet,
-		    IPC_GET_PACKET(call));
+		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
-		return ip_receive_message(IPC_GET_DEVICE(call), packet);
+		return ip_receive_message(IPC_GET_DEVICE(*call), packet);
 	
 	case NET_IP_RECEIVED_ERROR:
 		rc = packet_translate_remote(ip_globals.net_phone, &packet,
-		    IPC_GET_PACKET(call));
+		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
-		return ip_received_error_msg_local(0, IPC_GET_DEVICE(call),
-		    packet, IPC_GET_TARGET(call), IPC_GET_ERROR(call));
+		return ip_received_error_msg_local(0, 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),
-		    IP_GET_ADDRESS(call), IP_GET_NETMASK(call),
-		    IP_GET_GATEWAY(call));
+		return ip_add_route_req_local(0, 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),
-		    IP_GET_GATEWAY(call));
+		return ip_set_gateway_req_local(0, IPC_GET_DEVICE(*call),
+		    IP_GET_GATEWAY(*call));
 
 	case NET_IP_GET_ROUTE:
@@ -1954,11 +1958,11 @@
 			return rc;
 		
-		rc = ip_get_route_req_local(0, IP_GET_PROTOCOL(call), addr,
+		rc = ip_get_route_req_local(0, IP_GET_PROTOCOL(*call), addr,
 		    (socklen_t) addrlen, &device_id, &header, &headerlen);
 		if (rc != EOK)
 			return rc;
 		
-		IPC_SET_DEVICE(answer, device_id);
-		IP_SET_HEADERLEN(answer, headerlen);
+		IPC_SET_DEVICE(*answer, device_id);
+		IP_SET_HEADERLEN(*answer, headerlen);
 		
 		*answer_count = 2;
@@ -1972,19 +1976,19 @@
 	
 	case NET_IL_PACKET_SPACE:
-		rc = ip_packet_size_message(IPC_GET_DEVICE(call), &addrlen,
+		rc = ip_packet_size_message(IPC_GET_DEVICE(*call), &addrlen,
 		    &prefix, &content, &suffix);
 		if (rc != EOK)
 			return rc;
 		
-		IPC_SET_ADDR(answer, addrlen);
-		IPC_SET_PREFIX(answer, prefix);
-		IPC_SET_CONTENT(answer, content);
-		IPC_SET_SUFFIX(answer, suffix);
+		IPC_SET_ADDR(*answer, addrlen);
+		IPC_SET_PREFIX(*answer, prefix);
+		IPC_SET_CONTENT(*answer, content);
+		IPC_SET_SUFFIX(*answer, suffix);
 		*answer_count = 4;
 		return EOK;
 	
 	case NET_IL_MTU_CHANGED:
-		return ip_mtu_changed_message(IPC_GET_DEVICE(call),
-		    IPC_GET_MTU(call));
+		return ip_mtu_changed_message(IPC_GET_DEVICE(*call),
+		    IPC_GET_MTU(*call));
 	}
 	
@@ -2007,8 +2011,8 @@
 	while (true) {
 		ipc_call_t answer;
-		int answer_count;
+		size_t count;
 		
 		/* Clear the answer structure */
-		refresh_answer(&answer, &answer_count);
+		refresh_answer(&answer, &count);
 		
 		/* Fetch the next message */
@@ -2018,5 +2022,5 @@
 		/* Process the message */
 		int res = il_module_message_standalone(callid, &call, &answer,
-		    &answer_count);
+		    &count);
 		
 		/*
@@ -2030,5 +2034,5 @@
 		
 		/* Answer the message */
-		answer_call(callid, res, &answer, answer_count);
+		answer_call(callid, res, &answer, count);
 	}
 }
Index: uspace/srv/net/il/ip/ip_module.c
===================================================================
--- uspace/srv/net/il/ip/ip_module.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/il/ip/ip_module.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -59,7 +59,7 @@
 int
 il_module_message_standalone(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count)
+    ipc_call_t *answer, size_t *count)
 {
-	return ip_message_standalone(callid, call, answer, answer_count);
+	return ip_message_standalone(callid, call, answer, count);
 }
 
Index: uspace/srv/net/il/ip/ip_module.h
===================================================================
--- uspace/srv/net/il/ip/ip_module.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/il/ip/ip_module.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -43,5 +43,5 @@
 extern int ip_initialize(async_client_conn_t);
 extern int ip_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *,
-    int *);
+    size_t *);
 
 #endif
Index: uspace/srv/net/net/net.c
===================================================================
--- uspace/srv/net/net/net.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/net/net.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -90,6 +90,6 @@
  *
  */
-int add_configuration(measured_strings_t *configuration, const char *name,
-    const char *value)
+int add_configuration(measured_strings_t *configuration, const uint8_t *name,
+    const uint8_t *value)
 {
 	int rc;
@@ -119,10 +119,10 @@
 }
 
-static int parse_line(measured_strings_t *configuration, char *line)
+static int parse_line(measured_strings_t *configuration, uint8_t *line)
 {
 	int rc;
 	
 	/* From the beginning */
-	char *name = line;
+	uint8_t *name = line;
 	
 	/* Skip comments and blank lines */
@@ -135,5 +135,5 @@
 	
 	/* Remember the name start */
-	char *value = name;
+	uint8_t *value = name;
 	
 	/* Skip the name */
@@ -186,10 +186,10 @@
 	
 	/* Construct the full filename */
-	char line[BUFFER_SIZE];
-	if (snprintf(line, BUFFER_SIZE, "%s/%s", directory, filename) > BUFFER_SIZE)
+	char fname[BUFFER_SIZE];
+	if (snprintf(fname, BUFFER_SIZE, "%s/%s", directory, filename) > BUFFER_SIZE)
 		return EOVERFLOW;
 	
 	/* Open the file */
-	FILE *cfg = fopen(line, "r");
+	FILE *cfg = fopen(fname, "r");
 	if (!cfg)
 		return ENOENT;
@@ -201,4 +201,6 @@
 	unsigned int line_number = 0;
 	size_t index = 0;
+	uint8_t line[BUFFER_SIZE];
+	
 	while (!ferror(cfg) && !feof(cfg)) {
 		int read = fgetc(cfg);
@@ -207,5 +209,5 @@
 				line[BUFFER_SIZE - 1] = '\0';
 				fprintf(stderr, "%s: Configuration line %u too "
-				    "long: %s\n", NAME, line_number, line);
+				    "long: %s\n", NAME, line_number, (char *) line);
 				
 				/* No space left in the line buffer */
@@ -213,5 +215,5 @@
 			}
 			/* Append the character */
-			line[index] = (char) read;
+			line[index] = (uint8_t) read;
 			index++;
 		} else {
@@ -221,5 +223,5 @@
 			if (parse_line(configuration, line) != EOK) {
 				fprintf(stderr, "%s: Configuration error on "
-				    "line %u: %s\n", NAME, line_number, line);
+				    "line %u: %s\n", NAME, line_number, (char *) line);
 			}
 			
@@ -282,18 +284,18 @@
 		return rc;
 	
-	rc = add_module(NULL, &net_globals.modules, LO_NAME, LO_FILENAME,
-	    SERVICE_LO, 0, connect_to_service);
-	if (rc != EOK)
-		return rc;
-	rc = add_module(NULL, &net_globals.modules, DP8390_NAME,
-	    DP8390_FILENAME, SERVICE_DP8390, 0, connect_to_service);
-	if (rc != EOK)
-		return rc;
-	rc = add_module(NULL, &net_globals.modules, ETHERNET_NAME,
-	    ETHERNET_FILENAME, SERVICE_ETHERNET, 0, connect_to_service);
-	if (rc != EOK)
-		return rc;
-	rc = add_module(NULL, &net_globals.modules, NILDUMMY_NAME,
-	    NILDUMMY_FILENAME, SERVICE_NILDUMMY, 0, connect_to_service);
+	rc = add_module(NULL, &net_globals.modules, (uint8_t *) LO_NAME,
+	    (uint8_t *) LO_FILENAME, SERVICE_LO, 0, connect_to_service);
+	if (rc != EOK)
+		return rc;
+	rc = add_module(NULL, &net_globals.modules, (uint8_t *) DP8390_NAME,
+	    (uint8_t *) DP8390_FILENAME, SERVICE_DP8390, 0, connect_to_service);
+	if (rc != EOK)
+		return rc;
+	rc = add_module(NULL, &net_globals.modules, (uint8_t *) ETHERNET_NAME,
+	    (uint8_t *) ETHERNET_FILENAME, SERVICE_ETHERNET, 0, connect_to_service);
+	if (rc != EOK)
+		return rc;
+	rc = add_module(NULL, &net_globals.modules, (uint8_t *) NILDUMMY_NAME,
+	    (uint8_t *) NILDUMMY_FILENAME, SERVICE_NILDUMMY, 0, connect_to_service);
 	if (rc != EOK)
 		return rc;
@@ -364,5 +366,5 @@
  */
 static int net_get_conf(measured_strings_t *netif_conf,
-    measured_string_t *configuration, size_t count, char **data)
+    measured_string_t *configuration, size_t count, uint8_t **data)
 {
 	if (data)
@@ -390,5 +392,5 @@
 
 int net_get_conf_req(int net_phone, measured_string_t **configuration,
-    size_t count, char **data)
+    size_t count, uint8_t **data)
 {
 	if (!configuration || (count <= 0))
@@ -399,5 +401,5 @@
 
 int net_get_device_conf_req(int net_phone, device_id_t device_id,
-    measured_string_t **configuration, size_t count, char **data)
+    measured_string_t **configuration, size_t count, uint8_t **data)
 {
 	if ((!configuration) || (count == 0))
@@ -411,5 +413,5 @@
 }
 
-void net_free_settings(measured_string_t *settings, char *data)
+void net_free_settings(measured_string_t *settings, uint8_t *data)
 {
 }
@@ -437,5 +439,5 @@
 	/* Mandatory netif */
 	measured_string_t *setting =
-	    measured_strings_find(&netif->configuration, CONF_NETIF, 0);
+	    measured_strings_find(&netif->configuration, (uint8_t *) CONF_NETIF, 0);
 	
 	netif->driver = get_running_module(&net_globals.modules, setting->value);
@@ -447,5 +449,5 @@
 	
 	/* Optional network interface layer */
-	setting = measured_strings_find(&netif->configuration, CONF_NIL, 0);
+	setting = measured_strings_find(&netif->configuration, (uint8_t *) CONF_NIL, 0);
 	if (setting) {
 		netif->nil = get_running_module(&net_globals.modules, setting->value);
@@ -459,5 +461,5 @@
 	
 	/* Mandatory internet layer */
-	setting = measured_strings_find(&netif->configuration, CONF_IL, 0);
+	setting = measured_strings_find(&netif->configuration, (uint8_t *) CONF_IL, 0);
 	netif->il = get_running_module(&net_globals.modules, setting->value);
 	if (!netif->il) {
@@ -468,11 +470,11 @@
 	
 	/* Hardware configuration */
-	setting = measured_strings_find(&netif->configuration, CONF_IRQ, 0);
-	int irq = setting ? strtol(setting->value, NULL, 10) : 0;
-	
-	setting = measured_strings_find(&netif->configuration, CONF_IO, 0);
-	int io = setting ? strtol(setting->value, NULL, 16) : 0;
-	
-	rc = netif_probe_req_remote(netif->driver->phone, netif->id, irq, io);
+	setting = measured_strings_find(&netif->configuration, (uint8_t *) CONF_IRQ, 0);
+	int irq = setting ? strtol((char *) setting->value, NULL, 10) : 0;
+	
+	setting = measured_strings_find(&netif->configuration, (uint8_t *) CONF_IO, 0);
+	uintptr_t io = setting ? strtol((char *) setting->value, NULL, 16) : 0;
+	
+	rc = netif_probe_req(netif->driver->phone, netif->id, irq, (void *) io);
 	if (rc != EOK)
 		return rc;
@@ -481,10 +483,10 @@
 	services_t internet_service;
 	if (netif->nil) {
-		setting = measured_strings_find(&netif->configuration, CONF_MTU, 0);
+		setting = measured_strings_find(&netif->configuration, (uint8_t *) CONF_MTU, 0);
 		if (!setting)
 			setting = measured_strings_find(&net_globals.configuration,
-			    CONF_MTU, 0);
-		
-		int mtu = setting ? strtol(setting->value, NULL, 10) : 0;
+			    (uint8_t *) CONF_MTU, 0);
+		
+		int mtu = setting ? strtol((char *) setting->value, NULL, 10) : 0;
 		
 		rc = nil_device_req(netif->nil->phone, netif->id, mtu,
@@ -509,5 +511,5 @@
 	}
 	
-	return netif_start_req_remote(netif->driver->phone, netif->id);
+	return netif_start_req(netif->driver->phone, netif->id);
 }
 
@@ -558,5 +560,5 @@
 		/* Mandatory name */
 		measured_string_t *setting =
-		    measured_strings_find(&netif->configuration, CONF_NAME, 0);
+		    measured_strings_find(&netif->configuration, (uint8_t *) CONF_NAME, 0);
 		if (!setting) {
 			fprintf(stderr, "%s: Network interface name is missing\n", NAME);
@@ -602,5 +604,5 @@
 		printf("%s: Network interface started (name: %s, id: %d, driver: %s, "
 		    "nil: %s, il: %s)\n", NAME, netif->name, netif->id,
-		    netif->driver->name,  netif->nil ? netif->nil->name : "[none]",
+		    netif->driver->name, netif->nil ? (char *) netif->nil->name : "[none]",
 		    netif->il->name);
 	}
@@ -611,6 +613,6 @@
 /** Process the networking message.
  *
- * @param[in] callid        The message identifier.
- * @param[in] call          The message parameters.
+ * @param[in]  callid       The message identifier.
+ * @param[in]  call         The message parameters.
  * @param[out] answer       The message answer parameters.
  * @param[out] answer_count The last parameter for the actual answer
@@ -625,8 +627,8 @@
  */
 int net_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
-    int *answer_count)
+    size_t *answer_count)
 {
 	measured_string_t *strings;
-	char *data;
+	uint8_t *data;
 	int rc;
 	
@@ -637,27 +639,27 @@
 	case NET_NET_GET_DEVICE_CONF:
 		rc = measured_strings_receive(&strings, &data,
-		    IPC_GET_COUNT(call));
+		    IPC_GET_COUNT(*call));
 		if (rc != EOK)
 			return rc;
-		net_get_device_conf_req(0, IPC_GET_DEVICE(call), &strings,
-		    IPC_GET_COUNT(call), NULL);
+		net_get_device_conf_req(0, IPC_GET_DEVICE(*call), &strings,
+		    IPC_GET_COUNT(*call), NULL);
 		
 		/* Strings should not contain received data anymore */
 		free(data);
 		
-		rc = measured_strings_reply(strings, IPC_GET_COUNT(call));
+		rc = measured_strings_reply(strings, IPC_GET_COUNT(*call));
 		free(strings);
 		return rc;
 	case NET_NET_GET_CONF:
 		rc = measured_strings_receive(&strings, &data,
-		    IPC_GET_COUNT(call));
+		    IPC_GET_COUNT(*call));
 		if (rc != EOK)
 			return rc;
-		net_get_conf_req(0, &strings, IPC_GET_COUNT(call), NULL);
+		net_get_conf_req(0, &strings, IPC_GET_COUNT(*call), NULL);
 		
 		/* Strings should not contain received data anymore */
 		free(data);
 		
-		rc = measured_strings_reply(strings, IPC_GET_COUNT(call));
+		rc = measured_strings_reply(strings, IPC_GET_COUNT(*call));
 		free(strings);
 		return rc;
@@ -686,5 +688,5 @@
 		/* Clear the answer structure */
 		ipc_call_t answer;
-		int answer_count;
+		size_t answer_count;
 		refresh_answer(&answer, &answer_count);
 		
Index: uspace/srv/net/net/net.h
===================================================================
--- uspace/srv/net/net/net.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/net/net.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -105,8 +105,8 @@
 	module_t *driver;
 	
-	device_id_t id;	/**< System-unique network interface identifier. */
-	module_t *il;	/**< Serving internet layer module index. */
-	char *name;	/**< System-unique network interface name. */
-	module_t *nil;	/**< Serving link layer module index. */
+	device_id_t id;  /**< System-unique network interface identifier. */
+	module_t *il;    /**< Serving internet layer module index. */
+	uint8_t *name;   /**< System-unique network interface name. */
+	module_t *nil;   /**< Serving link layer module index. */
 } netif_t;
 
@@ -133,8 +133,9 @@
 } net_globals_t;
 
-extern int add_configuration(measured_strings_t *, const char *, const char *);
-extern int net_module_message(ipc_callid_t, ipc_call_t *, ipc_call_t *, int *);
+extern int add_configuration(measured_strings_t *, const uint8_t *,
+    const uint8_t *);
+extern int net_module_message(ipc_callid_t, ipc_call_t *, ipc_call_t *, size_t *);
 extern int net_initialize_build(async_client_conn_t);
-extern int net_message(ipc_callid_t, ipc_call_t *, ipc_call_t *, int *);
+extern int net_message(ipc_callid_t, ipc_call_t *, ipc_call_t *, size_t *);
 
 #endif
Index: uspace/srv/net/net/net_standalone.c
===================================================================
--- uspace/srv/net/net/net_standalone.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/net/net_standalone.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -63,20 +63,20 @@
 	int rc;
 	
-	task_id_t task_id = spawn("/srv/ip");
+	task_id_t task_id = net_spawn((uint8_t *) "/srv/ip");
 	if (!task_id)
 		return EINVAL;
 	
-	rc = add_module(NULL, &net_globals.modules, IP_NAME,
-	    IP_FILENAME, SERVICE_IP, task_id, ip_connect_module);
+	rc = add_module(NULL, &net_globals.modules, (uint8_t *) IP_NAME,
+	    (uint8_t *) IP_FILENAME, SERVICE_IP, task_id, ip_connect_module);
 	if (rc != EOK)
 		return rc;
 	
-	if (!spawn("/srv/icmp"))
+	if (!net_spawn((uint8_t *) "/srv/icmp"))
 		return EINVAL;
 	
-	if (!spawn("/srv/udp"))
+	if (!net_spawn((uint8_t *) "/srv/udp"))
 		return EINVAL;
 	
-	if (!spawn("/srv/tcp"))
+	if (!net_spawn((uint8_t *) "/srv/tcp"))
 		return EINVAL;
 	
@@ -100,10 +100,10 @@
  */
 int net_module_message(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count)
+    ipc_call_t *answer, size_t *count)
 {
-	if (IS_NET_PACKET_MESSAGE(call))
-		return packet_server_message(callid, call, answer, answer_count);
+	if (IS_NET_PACKET_MESSAGE(*call))
+		return packet_server_message(callid, call, answer, count);
 	
-	return net_message(callid, call, answer, answer_count);
+	return net_message(callid, call, answer, count);
 }
 
Index: uspace/srv/net/netif/lo/lo.c
===================================================================
--- uspace/srv/net/netif/lo/lo.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/netif/lo/lo.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -49,12 +49,11 @@
 #include <net/device.h>
 #include <nil_interface.h>
-#include <netif_interface.h>
-#include <netif_local.h>
+#include <netif_skel.h>
 
 /** Default hardware address. */
-#define DEFAULT_ADDR		"\0\0\0\0\0\0"
+#define DEFAULT_ADDR  0
 
 /** Default address length. */
-#define DEFAULT_ADDR_LEN	(sizeof(DEFAULT_ADDR) / sizeof(char))
+#define DEFAULT_ADDR_LEN  6
 
 /** Loopback module name. */
@@ -62,8 +61,8 @@
 
 /** Network interface global data. */
-netif_globals_t	netif_globals;
+netif_globals_t netif_globals;
 
 int netif_specific_message(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count)
+    ipc_call_t *answer, size_t *count)
 {
 	return ENOTSUP;
@@ -74,8 +73,11 @@
 	if (!address)
 		return EBADMEM;
-
-	address->value = str_dup(DEFAULT_ADDR);
+	
+	uint8_t *addr = (uint8_t *) malloc(DEFAULT_ADDR_LEN);
+	memset(addr, DEFAULT_ADDR, DEFAULT_ADDR_LEN);
+	
+	address->value = addr;
 	address->length = DEFAULT_ADDR_LEN;
-
+	
 	return EOK;
 }
@@ -169,5 +171,5 @@
 }
 
-int netif_probe_message(device_id_t device_id, int irq, uintptr_t io)
+int netif_probe_message(device_id_t device_id, int irq, void *io)
 {
 	netif_device_t *device;
@@ -230,52 +232,8 @@
 }
 
-/** Default thread for new connections.
- *
- * @param[in] iid	The initial message identifier.
- * @param[in] icall	The initial message call structure.
- */
-static void netif_client_connection(ipc_callid_t iid, ipc_call_t *icall)
-{
-	/*
-	 * Accept the connection
-	 *  - Answer the first IPC_M_CONNECT_ME_TO call.
-	 */
-	ipc_answer_0(iid, EOK);
-	
-	while (true) {
-		ipc_call_t answer;
-		int answer_count;
-		
-		/* Clear the answer structure */
-		refresh_answer(&answer, &answer_count);
-		
-		/* Fetch the next message */
-		ipc_call_t call;
-		ipc_callid_t callid = async_get_call(&call);
-		
-		/* Process the message */
-		int res = netif_module_message(NAME, callid, &call, &answer,
-		    &answer_count);
-		
-		/*
-		 * End if told to either by the message or the processing
-		 * result.
-		 */
-		if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
-		    (res == EHANGUP))
-			return;
-		
-		/* Answer the message */
-		answer_call(callid, res, &answer, answer_count);
-	}
-}
-
 int main(int argc, char *argv[])
 {
-	int rc;
-	
 	/* Start the module */
-	rc = netif_module_start(netif_client_connection);
-	return rc;
+	return netif_module_start();
 }
 
Index: uspace/srv/net/nil/eth/eth.c
===================================================================
--- uspace/srv/net/nil/eth/eth.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/nil/eth/eth.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -54,5 +54,5 @@
 #include <protocol_map.h>
 #include <net/device.h>
-#include <netif_interface.h>
+#include <netif_remote.h>
 #include <net_interface.h>
 #include <nil_interface.h>
@@ -201,5 +201,5 @@
 
 	eth_globals.broadcast_addr =
-	    measured_string_create_bulk("\xFF\xFF\xFF\xFF\xFF\xFF", ETH_ADDR);
+	    measured_string_create_bulk((uint8_t *) "\xFF\xFF\xFF\xFF\xFF\xFF", ETH_ADDR);
 	if (!eth_globals.broadcast_addr) {
 		rc = ENOMEM;
@@ -239,14 +239,14 @@
 		switch (IPC_GET_IMETHOD(*icall)) {
 		case NET_NIL_DEVICE_STATE:
-			nil_device_state_msg_local(0, IPC_GET_DEVICE(icall),
-			    IPC_GET_STATE(icall));
+			nil_device_state_msg_local(0, IPC_GET_DEVICE(*icall),
+			    IPC_GET_STATE(*icall));
 			ipc_answer_0(iid, EOK);
 			break;
 		case NET_NIL_RECEIVED:
 			rc = packet_translate_remote(eth_globals.net_phone,
-			    &packet, IPC_GET_PACKET(icall));
+			    &packet, IPC_GET_PACKET(*icall));
 			if (rc == EOK) {
 				rc = nil_received_msg_local(0,
-				    IPC_GET_DEVICE(icall), packet, 0);
+				    IPC_GET_DEVICE(*icall), packet, 0);
 			}
 			ipc_answer_0(iid, (sysarg_t) rc);
@@ -284,9 +284,9 @@
 	measured_string_t names[2] = {
 		{
-			(char *) "ETH_MODE",
+			(uint8_t *) "ETH_MODE",
 			8
 		},
 		{
-			(char *) "ETH_DUMMY",
+			(uint8_t *) "ETH_DUMMY",
 			9
 		}
@@ -294,5 +294,5 @@
 	measured_string_t *configuration;
 	size_t count = sizeof(names) / sizeof(measured_string_t);
-	char *data;
+	uint8_t *data;
 	eth_proto_t *proto;
 	int rc;
@@ -358,8 +358,8 @@
 
 	if (configuration) {
-		if (!str_lcmp(configuration[0].value, "DIX",
+		if (!str_lcmp((char *) configuration[0].value, "DIX",
 		    configuration[0].length)) {
 			device->flags |= ETH_DIX;
-		} else if(!str_lcmp(configuration[0].value, "8023_2_LSAP",
+		} else if(!str_lcmp((char *) configuration[0].value, "8023_2_LSAP",
 		    configuration[0].length)) {
 			device->flags |= ETH_8023_2_LSAP;
@@ -407,5 +407,5 @@
 	
 	printf("%s: Device registered (id: %d, service: %d: mtu: %zu, "
-	    "mac: %x:%x:%x:%x:%x:%x, flags: 0x%x)\n",
+	    "mac: %02x:%02x:%02x:%02x:%02x:%02x, flags: 0x%x)\n",
 	    NAME, device->device_id, device->service, device->mtu,
 	    device->addr_data[0], device->addr_data[1],
@@ -837,5 +837,5 @@
 
 int nil_message_standalone(const char *name, ipc_callid_t callid,
-    ipc_call_t *call, ipc_call_t *answer, int *answer_count)
+    ipc_call_t *call, ipc_call_t *answer, size_t *answer_count)
 {
 	measured_string_t *address;
@@ -853,26 +853,26 @@
 	
 	case NET_NIL_DEVICE:
-		return eth_device_message(IPC_GET_DEVICE(call),
-		    IPC_GET_SERVICE(call), IPC_GET_MTU(call));
+		return eth_device_message(IPC_GET_DEVICE(*call),
+		    IPC_GET_SERVICE(*call), IPC_GET_MTU(*call));
 	case NET_NIL_SEND:
 		rc = packet_translate_remote(eth_globals.net_phone, &packet,
-		    IPC_GET_PACKET(call));
+		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
-		return eth_send_message(IPC_GET_DEVICE(call), packet,
-		    IPC_GET_SERVICE(call));
+		return eth_send_message(IPC_GET_DEVICE(*call), packet,
+		    IPC_GET_SERVICE(*call));
 	case NET_NIL_PACKET_SPACE:
-		rc = eth_packet_space_message(IPC_GET_DEVICE(call), &addrlen,
+		rc = eth_packet_space_message(IPC_GET_DEVICE(*call), &addrlen,
 		    &prefix, &content, &suffix);
 		if (rc != EOK)
 			return rc;
-		IPC_SET_ADDR(answer, addrlen);
-		IPC_SET_PREFIX(answer, prefix);
-		IPC_SET_CONTENT(answer, content);
-		IPC_SET_SUFFIX(answer, suffix);
+		IPC_SET_ADDR(*answer, addrlen);
+		IPC_SET_PREFIX(*answer, prefix);
+		IPC_SET_CONTENT(*answer, content);
+		IPC_SET_SUFFIX(*answer, suffix);
 		*answer_count = 4;
 		return EOK;
 	case NET_NIL_ADDR:
-		rc = eth_addr_message(IPC_GET_DEVICE(call), ETH_LOCAL_ADDR,
+		rc = eth_addr_message(IPC_GET_DEVICE(*call), ETH_LOCAL_ADDR,
 		    &address);
 		if (rc != EOK)
@@ -880,5 +880,5 @@
 		return measured_strings_reply(address, 1);
 	case NET_NIL_BROADCAST_ADDR:
-		rc = eth_addr_message(IPC_GET_DEVICE(call), ETH_BROADCAST_ADDR,
+		rc = eth_addr_message(IPC_GET_DEVICE(*call), ETH_BROADCAST_ADDR,
 		    &address);
 		if (rc != EOK)
@@ -886,6 +886,6 @@
 		return measured_strings_reply(address, 1);
 	case IPC_M_CONNECT_TO_ME:
-		return eth_register_message(NIL_GET_PROTO(call),
-		    IPC_GET_PHONE(call));
+		return eth_register_message(NIL_GET_PROTO(*call),
+		    IPC_GET_PHONE(*call));
 	}
 	
@@ -908,8 +908,8 @@
 	while (true) {
 		ipc_call_t answer;
-		int answer_count;
+		size_t count;
 		
 		/* Clear the answer structure */
-		refresh_answer(&answer, &answer_count);
+		refresh_answer(&answer, &count);
 		
 		/* Fetch the next message */
@@ -919,5 +919,5 @@
 		/* Process the message */
 		int res = nil_module_message_standalone(NAME, callid, &call,
-		    &answer, &answer_count);
+		    &answer, &count);
 		
 		/*
@@ -930,5 +930,5 @@
 		
 		/* Answer the message */
-		answer_call(callid, res, &answer, answer_count);
+		answer_call(callid, res, &answer, count);
 	}
 }
Index: uspace/srv/net/nil/eth/eth.h
===================================================================
--- uspace/srv/net/nil/eth/eth.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/nil/eth/eth.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -91,6 +91,7 @@
 	/** Actual device hardware address. */
 	measured_string_t *addr;
+	
 	/** Actual device hardware address data. */
-	char *addr_data;
+	uint8_t *addr_data;
 };
 
Index: uspace/srv/net/nil/eth/eth_header.h
===================================================================
--- uspace/srv/net/nil/eth/eth_header.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/nil/eth/eth_header.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -42,14 +42,14 @@
 
 /** Ethernet address length. */
-#define ETH_ADDR	6
+#define ETH_ADDR  6
 
 /** Ethernet header preamble value. */
-#define ETH_PREAMBLE	0x55
+#define ETH_PREAMBLE  0x55
 
 /** Ethernet header start of frame value. */
-#define ETH_SFD		0xD5
+#define ETH_SFD  0xD5
 
 /** IEEE 802.2 unordered information control field. */
-#define IEEE_8023_2_UI	0x03
+#define IEEE_8023_2_UI  0x03
 
 /** Type definition of the Ethernet header IEEE 802.3 + 802.2 + SNAP extensions.
Index: uspace/srv/net/nil/eth/eth_module.c
===================================================================
--- uspace/srv/net/nil/eth/eth_module.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/nil/eth/eth_module.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -78,7 +78,7 @@
 
 int nil_module_message_standalone(const char *name, ipc_callid_t callid,
-    ipc_call_t *call, ipc_call_t *answer, int *answer_count)
+    ipc_call_t *call, ipc_call_t *answer, size_t *count)
 {
-	return nil_message_standalone(name, callid, call, answer, answer_count);
+	return nil_message_standalone(name, callid, call, answer, count);
 }
 
Index: uspace/srv/net/nil/nildummy/nildummy.c
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/nil/nildummy/nildummy.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -47,5 +47,4 @@
 #include <net/modules.h>
 #include <net/device.h>
-#include <netif_interface.h>
 #include <nil_interface.h>
 #include <il_interface.h>
@@ -53,4 +52,5 @@
 #include <net/packet.h>
 #include <packet_remote.h>
+#include <netif_remote.h>
 #include <nil_local.h>
 
@@ -113,5 +113,5 @@
 		case NET_NIL_DEVICE_STATE:
 			rc = nil_device_state_msg_local(0,
-			    IPC_GET_DEVICE(icall), IPC_GET_STATE(icall));
+			    IPC_GET_DEVICE(*icall), IPC_GET_STATE(*icall));
 			ipc_answer_0(iid, (sysarg_t) rc);
 			break;
@@ -119,8 +119,8 @@
 		case NET_NIL_RECEIVED:
 			rc = packet_translate_remote(nildummy_globals.net_phone,
-			    &packet, IPC_GET_PACKET(icall));
+			    &packet, IPC_GET_PACKET(*icall));
 			if (rc == EOK) {
 				rc = nil_received_msg_local(0,
-				    IPC_GET_DEVICE(icall), packet, 0);
+				    IPC_GET_DEVICE(*icall), packet, 0);
 			}
 			ipc_answer_0(iid, (sysarg_t) rc);
@@ -375,5 +375,5 @@
 
 int nil_message_standalone(const char *name, ipc_callid_t callid,
-    ipc_call_t *call, ipc_call_t *answer, int *answer_count)
+    ipc_call_t *call, ipc_call_t *answer, size_t *answer_count)
 {
 	measured_string_t *address;
@@ -391,29 +391,29 @@
 	
 	case NET_NIL_DEVICE:
-		return nildummy_device_message(IPC_GET_DEVICE(call),
-		    IPC_GET_SERVICE(call), IPC_GET_MTU(call));
+		return nildummy_device_message(IPC_GET_DEVICE(*call),
+		    IPC_GET_SERVICE(*call), IPC_GET_MTU(*call));
 	
 	case NET_NIL_SEND:
 		rc = packet_translate_remote(nildummy_globals.net_phone,
-		    &packet, IPC_GET_PACKET(call));
+		    &packet, IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
-		return nildummy_send_message(IPC_GET_DEVICE(call), packet,
-		    IPC_GET_SERVICE(call));
+		return nildummy_send_message(IPC_GET_DEVICE(*call), packet,
+		    IPC_GET_SERVICE(*call));
 	
 	case NET_NIL_PACKET_SPACE:
-		rc = nildummy_packet_space_message(IPC_GET_DEVICE(call),
+		rc = nildummy_packet_space_message(IPC_GET_DEVICE(*call),
 		    &addrlen, &prefix, &content, &suffix);
 		if (rc != EOK)
 			return rc;
-		IPC_SET_ADDR(answer, addrlen);
-		IPC_SET_PREFIX(answer, prefix);
-		IPC_SET_CONTENT(answer, content);
-		IPC_SET_SUFFIX(answer, suffix);
+		IPC_SET_ADDR(*answer, addrlen);
+		IPC_SET_PREFIX(*answer, prefix);
+		IPC_SET_CONTENT(*answer, content);
+		IPC_SET_SUFFIX(*answer, suffix);
 		*answer_count = 4;
 		return EOK;
 	
 	case NET_NIL_ADDR:
-		rc = nildummy_addr_message(IPC_GET_DEVICE(call), &address);
+		rc = nildummy_addr_message(IPC_GET_DEVICE(*call), &address);
 		if (rc != EOK)
 			return rc;
@@ -421,5 +421,5 @@
 	
 	case NET_NIL_BROADCAST_ADDR:
-		rc = nildummy_addr_message(IPC_GET_DEVICE(call), &address);
+		rc = nildummy_addr_message(IPC_GET_DEVICE(*call), &address);
 		if (rc != EOK)
 			return rc;
@@ -427,6 +427,6 @@
 	
 	case IPC_M_CONNECT_TO_ME:
-		return nildummy_register_message(NIL_GET_PROTO(call),
-		    IPC_GET_PHONE(call));
+		return nildummy_register_message(NIL_GET_PROTO(*call),
+		    IPC_GET_PHONE(*call));
 	}
 	
@@ -449,8 +449,8 @@
 	while (true) {
 		ipc_call_t answer;
-		int answer_count;
+		size_t count;
 		
 		/* Clear the answer structure */
-		refresh_answer(&answer, &answer_count);
+		refresh_answer(&answer, &count);
 		
 		/* Fetch the next message */
@@ -460,5 +460,5 @@
 		/* Process the message */
 		int res = nil_module_message_standalone(NAME, callid, &call,
-		    &answer, &answer_count);
+		    &answer, &count);
 		
 		/*
@@ -471,5 +471,5 @@
 		
 		/* Answer the message */
-		answer_call(callid, res, &answer, answer_count);
+		answer_call(callid, res, &answer, count);
 	}
 }
Index: uspace/srv/net/nil/nildummy/nildummy.h
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/nil/nildummy/nildummy.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -78,5 +78,5 @@
 	measured_string_t *addr;
 	/** Actual device hardware address data. */
-	char *addr_data;
+	uint8_t *addr_data;
 };
 
Index: uspace/srv/net/nil/nildummy/nildummy_module.c
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy_module.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/nil/nildummy/nildummy_module.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -79,7 +79,7 @@
 
 int nil_module_message_standalone(const char *name, ipc_callid_t callid,
-    ipc_call_t *call, ipc_call_t *answer, int *answer_count)
+    ipc_call_t *call, ipc_call_t *answer, size_t *count)
 {
-	return nil_message_standalone(name, callid, call, answer, answer_count);
+	return nil_message_standalone(name, callid, call, answer, count);
 }
 
Index: uspace/srv/net/tl/icmp/icmp.c
===================================================================
--- uspace/srv/net/tl/icmp/icmp.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/tl/icmp/icmp.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -405,9 +405,9 @@
 	measured_string_t names[] = {
 		{
-			(char *) "ICMP_ERROR_REPORTING",
+			(uint8_t *) "ICMP_ERROR_REPORTING",
 			20
 		},
 		{
-			(char *) "ICMP_ECHO_REPLYING",
+			(uint8_t *) "ICMP_ECHO_REPLYING",
 			18
 		}
@@ -415,5 +415,5 @@
 	measured_string_t *configuration;
 	size_t count = sizeof(names) / sizeof(measured_string_t);
-	char *data;
+	uint8_t *data;
 	int rc;
 
@@ -696,12 +696,12 @@
 	case NET_ICMP_DEST_UNREACH:
 		rc = packet_translate_remote(icmp_globals.net_phone, &packet,
-		    IPC_GET_PACKET(call));
+		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
 		return icmp_destination_unreachable_msg_local(0,
-		    ICMP_GET_CODE(call), ICMP_GET_MTU(call), packet);
+		    ICMP_GET_CODE(*call), ICMP_GET_MTU(*call), packet);
 	case NET_ICMP_SOURCE_QUENCH:
 		rc = packet_translate_remote(icmp_globals.net_phone, &packet,
-		    IPC_GET_PACKET(call));
+		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
@@ -709,16 +709,16 @@
 	case NET_ICMP_TIME_EXCEEDED:
 		rc = packet_translate_remote(icmp_globals.net_phone, &packet,
-		    IPC_GET_PACKET(call));
+		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
-		return icmp_time_exceeded_msg_local(0, ICMP_GET_CODE(call),
+		return icmp_time_exceeded_msg_local(0, ICMP_GET_CODE(*call),
 		    packet);
 	case NET_ICMP_PARAMETERPROB:
 		rc = packet_translate_remote(icmp_globals.net_phone, &packet,
-		    IPC_GET_PACKET(call));
+		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
-		return icmp_parameter_problem_msg_local(0, ICMP_GET_CODE(call),
-		    ICMP_GET_POINTER(call), packet);
+		return icmp_parameter_problem_msg_local(0, ICMP_GET_CODE(*call),
+		    ICMP_GET_POINTER(*call), packet);
 	default:
 		return ENOTSUP;
@@ -787,5 +787,5 @@
 	bool keep_on_going = true;
 	ipc_call_t answer;
-	int answer_count;
+	size_t answer_count;
 	size_t length;
 	struct sockaddr *addr;
@@ -894,5 +894,5 @@
  */
 int icmp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count)
+    ipc_call_t *answer, size_t *answer_count)
 {
 	packet_t *packet;
@@ -903,12 +903,12 @@
 	case NET_TL_RECEIVED:
 		rc = packet_translate_remote(icmp_globals.net_phone, &packet,
-		    IPC_GET_PACKET(call));
+		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
-		return icmp_received_msg_local(IPC_GET_DEVICE(call), packet,
-		    SERVICE_ICMP, IPC_GET_ERROR(call));
+		return icmp_received_msg_local(IPC_GET_DEVICE(*call), packet,
+		    SERVICE_ICMP, IPC_GET_ERROR(*call));
 	
 	case NET_ICMP_INIT:
-		return icmp_process_client_messages(callid, * call);
+		return icmp_process_client_messages(callid, *call);
 	
 	default:
@@ -936,5 +936,5 @@
 	while (true) {
 		ipc_call_t answer;
-		int answer_count;
+		size_t answer_count;
 		
 		/* Clear the answer structure */
Index: uspace/srv/net/tl/icmp/icmp_module.c
===================================================================
--- uspace/srv/net/tl/icmp/icmp_module.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/tl/icmp/icmp_module.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -86,7 +86,7 @@
 
 int tl_module_message_standalone(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count)
+    ipc_call_t *answer, size_t *count)
 {
-	return icmp_message_standalone(callid, call, answer, answer_count);
+	return icmp_message_standalone(callid, call, answer, count);
 }
 
Index: uspace/srv/net/tl/icmp/icmp_module.h
===================================================================
--- uspace/srv/net/tl/icmp/icmp_module.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/tl/icmp/icmp_module.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -44,5 +44,5 @@
 extern int icmp_initialize(async_client_conn_t);
 extern int icmp_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *,
-    int *);
+    size_t *);
 
 #endif
Index: uspace/srv/net/tl/tcp/tcp.c
===================================================================
--- uspace/srv/net/tl/tcp/tcp.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/tl/tcp/tcp.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -154,5 +154,5 @@
 
 	/** Port map key. */
-	char *key;
+	uint8_t *key;
 
 	/** Port map key length. */
@@ -358,10 +358,10 @@
 	/* Find the destination socket */
 	socket = socket_port_find(&tcp_globals.sockets,
-	    ntohs(header->destination_port), (const char *) src, addrlen);
+	    ntohs(header->destination_port), (uint8_t *) src, addrlen);
 	if (!socket) {
 		/* Find the listening destination socket */
 		socket = socket_port_find(&tcp_globals.sockets,
-		    ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING,
-		    0);
+		    ntohs(header->destination_port),
+		    (uint8_t *) SOCKET_MAP_KEY_LISTENING, 0);
 	}
 
@@ -998,5 +998,5 @@
 	/* Find the destination socket */
 	listening_socket = socket_port_find(&tcp_globals.sockets,
-	    listening_port, SOCKET_MAP_KEY_LISTENING, 0);
+	    listening_port, (uint8_t *) SOCKET_MAP_KEY_LISTENING, 0);
 	if (!listening_socket ||
 	    (listening_socket->socket_id != listening_socket_id)) {
@@ -1022,7 +1022,7 @@
 
 	rc = socket_port_add(&tcp_globals.sockets, listening_port, socket,
-	    (const char *) socket_data->addr, socket_data->addrlen);
+	    (uint8_t *) socket_data->addr, socket_data->addrlen);
 	assert(socket == socket_port_find(&tcp_globals.sockets, listening_port,
-	    (const char *) socket_data->addr, socket_data->addrlen));
+	    (uint8_t *) socket_data->addr, socket_data->addrlen));
 
 //	rc = socket_bind_free_port(&tcp_globals.sockets, socket,
@@ -1262,5 +1262,5 @@
 int
 tcp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count)
+    ipc_call_t *answer, size_t *answer_count)
 {
 	packet_t *packet;
@@ -1276,11 +1276,11 @@
 //		fibril_rwlock_read_lock(&tcp_globals.lock);
 		rc = packet_translate_remote(tcp_globals.net_phone, &packet,
-		    IPC_GET_PACKET(call));
+		    IPC_GET_PACKET(*call));
 		if (rc != EOK) {
 //			fibril_rwlock_read_unlock(&tcp_globals.lock);
 			return rc;
 		}
-		rc = tcp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_TCP,
-		    IPC_GET_ERROR(call));
+		rc = tcp_received_msg(IPC_GET_DEVICE(*call), packet, SERVICE_TCP,
+		    IPC_GET_ERROR(*call));
 //		fibril_rwlock_read_unlock(&tcp_globals.lock);
 		return rc;
@@ -1323,5 +1323,5 @@
 	bool keep_on_going = true;
 	socket_cores_t local_sockets;
-	int app_phone = IPC_GET_PHONE(&call);
+	int app_phone = IPC_GET_PHONE(call);
 	struct sockaddr *addr;
 	int socket_id;
@@ -1330,5 +1330,5 @@
 	fibril_rwlock_t lock;
 	ipc_call_t answer;
-	int answer_count;
+	size_t answer_count;
 	tcp_socket_data_t *socket_data;
 	socket_core_t *socket;
@@ -2109,5 +2109,5 @@
 
 	/* Copy the key */
-	operation_timeout->key = ((char *) operation_timeout) +
+	operation_timeout->key = ((uint8_t *) operation_timeout) +
 	    sizeof(*operation_timeout);
 	operation_timeout->key_length = socket->key_length;
@@ -2502,5 +2502,5 @@
 	while (true) {
 		ipc_call_t answer;
-		int answer_count;
+		size_t answer_count;
 
 		/* Clear the answer structure */
Index: uspace/srv/net/tl/tcp/tcp_module.c
===================================================================
--- uspace/srv/net/tl/tcp/tcp_module.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/tl/tcp/tcp_module.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -87,7 +87,7 @@
 
 int tl_module_message_standalone(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count)
+    ipc_call_t *answer, size_t *count)
 {
-	return tcp_message_standalone(callid, call, answer, answer_count);
+	return tcp_message_standalone(callid, call, answer, count);
 }
 
Index: uspace/srv/net/tl/tcp/tcp_module.h
===================================================================
--- uspace/srv/net/tl/tcp/tcp_module.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/tl/tcp/tcp_module.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -44,5 +44,5 @@
 extern int tcp_initialize(async_client_conn_t);
 extern int tcp_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *,
-    int *);
+    size_t *);
 
 #endif
Index: uspace/srv/net/tl/udp/udp.c
===================================================================
--- uspace/srv/net/tl/udp/udp.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/tl/udp/udp.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -104,9 +104,9 @@
 	measured_string_t names[] = {
 		{
-			(char *) "UDP_CHECKSUM_COMPUTING",
+			(uint8_t *) "UDP_CHECKSUM_COMPUTING",
 			22
 		},
 		{
-			(char *) "UDP_AUTOBINDING",
+			(uint8_t *) "UDP_AUTOBINDING",
 			15
 		}
@@ -114,5 +114,5 @@
 	measured_string_t *configuration;
 	size_t count = sizeof(names) / sizeof(measured_string_t);
-	char *data;
+	uint8_t *data;
 	int rc;
 
@@ -283,5 +283,5 @@
 	/* Find the destination socket */
 	socket = socket_port_find(&udp_globals.sockets,
-	ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING, 0);
+	    ntohs(header->destination_port), (uint8_t *) SOCKET_MAP_KEY_LISTENING, 0);
 	if (!socket) {
 		if (tl_prepare_icmp_packet(udp_globals.net_phone,
@@ -707,5 +707,5 @@
 	bool keep_on_going = true;
 	socket_cores_t local_sockets;
-	int app_phone = IPC_GET_PHONE(&call);
+	int app_phone = IPC_GET_PHONE(call);
 	struct sockaddr *addr;
 	int socket_id;
@@ -713,5 +713,5 @@
 	size_t size = 0;
 	ipc_call_t answer;
-	int answer_count;
+	size_t answer_count;
 	packet_dimension_t *packet_dimension;
 
@@ -861,5 +861,5 @@
  */
 int udp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count)
+    ipc_call_t *answer, size_t *answer_count)
 {
 	packet_t *packet;
@@ -871,11 +871,11 @@
 	case NET_TL_RECEIVED:
 		rc = packet_translate_remote(udp_globals.net_phone, &packet,
-		    IPC_GET_PACKET(call));
+		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
-		return udp_received_msg(IPC_GET_DEVICE(call), packet,
-		    SERVICE_UDP, IPC_GET_ERROR(call));
+		return udp_received_msg(IPC_GET_DEVICE(*call), packet,
+		    SERVICE_UDP, IPC_GET_ERROR(*call));
 	case IPC_M_CONNECT_TO_ME:
-		return udp_process_client_messages(callid, * call);
+		return udp_process_client_messages(callid, *call);
 	}
 
@@ -898,5 +898,5 @@
 	while (true) {
 		ipc_call_t answer;
-		int answer_count;
+		size_t answer_count;
 		
 		/* Clear the answer structure */
Index: uspace/srv/net/tl/udp/udp_module.c
===================================================================
--- uspace/srv/net/tl/udp/udp_module.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/tl/udp/udp_module.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -87,7 +87,7 @@
 
 int tl_module_message_standalone(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count)
+    ipc_call_t *answer, size_t *count)
 {
-	return udp_message_standalone(callid, call, answer, answer_count);
+	return udp_message_standalone(callid, call, answer, count);
 }
 
Index: uspace/srv/net/tl/udp/udp_module.h
===================================================================
--- uspace/srv/net/tl/udp/udp_module.h	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/net/tl/udp/udp_module.h	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -44,5 +44,5 @@
 extern int udp_initialize(async_client_conn_t);
 extern int udp_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *,
-    int *);
+    size_t *);
 
 #endif
Index: uspace/srv/vfs/vfs_register.c
===================================================================
--- uspace/srv/vfs/vfs_register.c	(revision b2a6fcfe62e491c8d0a4c86810869e9bcff954a5)
+++ uspace/srv/vfs/vfs_register.c	(revision f40131243ad1635ce6cd59eaf5a91902710c0306)
@@ -188,5 +188,5 @@
 	
 	phone = IPC_GET_ARG5(call);
-	async_session_create(&fs_info->session, phone);
+	async_session_create(&fs_info->session, phone, 0);
 	ipc_answer_0(callid, EOK);
 	
