Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ HelenOS.config	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -522,7 +522,4 @@
 ! CONFIG_WRITE_CORE_FILES (n/y)
 
-% Networking architecture
-@ "modular" Modular
-@ "module" One module
-! CONFIG_NETWORKING (choice)
-
+% Bundle netif/nil network layer
+! CONFIG_NETIF_NIL_BUNDLE (n/y)
Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ boot/Makefile.common	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -40,7 +40,9 @@
 	$(USPACEDIR)/srv/bd/rd/rd \
 	$(USPACEDIR)/srv/vfs/vfs
+
 ifeq ($(RDFMT),tmpfs)
 	INIT_TASKS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
 endif
+
 ifeq ($(RDFMT),fat)
 	INIT_TASKS += $(USPACEDIR)/srv/fs/fat/fat
@@ -60,9 +62,18 @@
 	$(USPACEDIR)/srv/taskmon/taskmon \
 	$(USPACEDIR)/srv/hw/netif/dp8390/dp8390 \
+	$(USPACEDIR)/srv/net/netif/lo/lo \
+	$(USPACEDIR)/srv/net/il/arp/arp \
+	$(USPACEDIR)/srv/net/il/ip/ip \
+	$(USPACEDIR)/srv/net/tl/icmp/icmp \
+	$(USPACEDIR)/srv/net/tl/udp/udp \
+	$(USPACEDIR)/srv/net/tl/tcp/tcp \
 	$(USPACEDIR)/srv/net/net/net \
 	$(USPACEDIR)/srv/net/netstart/netstart \
-	$(USPACEDIR)/srv/net/netif/lo/lo \
-	$(USPACEDIR)/srv/net/nil/eth/eth \
-	$(USPACEDIR)/srv/net/nil/nildummy/nildummy
+
+ifneq ($(CONFIG_NETIF_NIL_BUNDLE),y)
+	RD_SRVS += \
+		$(USPACEDIR)/srv/net/nil/eth/eth \
+		$(USPACEDIR)/srv/net/nil/nildummy/nildummy
+endif
 
 RD_APPS = \
@@ -78,8 +89,12 @@
 	$(USPACEDIR)/app/tetris/tetris \
 	$(USPACEDIR)/app/trace/trace \
+	$(USPACEDIR)/app/nettest1/nettest1 \
+	$(USPACEDIR)/app/nettest2/nettest2 \
 	$(USPACEDIR)/app/netecho/netecho \
 	$(USPACEDIR)/app/ping/ping \
-	$(USPACEDIR)/app/nettest1/nettest1 \
-	$(USPACEDIR)/app/nettest2/nettest2
+	$(USPACEDIR)/app/stats/stats \
+	$(USPACEDIR)/app/tasks/tasks \
+	$(USPACEDIR)/app/top/top
+#	$(USPACEDIR)/app/dummy_load/dummy_load
 
 COMPONENTS = \
@@ -91,7 +106,9 @@
 	$(USPACEDIR)/srv/bd/rd/rd \
 	$(USPACEDIR)/srv/vfs/vfs
+
 ifeq ($(RDFMT),tmpfs)
 	COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
 endif
+
 ifeq ($(RDFMT),fat)
 	COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat
@@ -99,14 +116,5 @@
 
 NET_CFG = \
-	$(USPACEDIR)/srv/net/cfg/$(CONFIG_NETWORKING)/general \
-	$(USPACEDIR)/srv/net/cfg/$(CONFIG_NETWORKING)/lo \
-	$(USPACEDIR)/srv/net/cfg/$(CONFIG_NETWORKING)/ne2k
-
-ifeq ($(CONFIG_NETWORKING),modular)
-	RD_SRVS += \
-		$(USPACEDIR)/srv/net/il/ip/ip \
-		$(USPACEDIR)/srv/net/il/arp/arp \
-		$(USPACEDIR)/srv/net/tl/udp/udp \
-		$(USPACEDIR)/srv/net/tl/tcp/tcp \
-		$(USPACEDIR)/srv/net/tl/icmp/icmp
-endif
+	$(USPACEDIR)/srv/net/cfg/general \
+	$(USPACEDIR)/srv/net/cfg/lo \
+	$(USPACEDIR)/srv/net/cfg/ne2k
Index: boot/arch/amd64/Makefile.inc
===================================================================
--- boot/arch/amd64/Makefile.inc	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ boot/arch/amd64/Makefile.inc	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -39,5 +39,5 @@
 build: $(BASE)/image.iso
 
-$(BASE)/image.iso: arch/$(BARCH)/grub/stage2_eltorito $(KERNELDIR)/kernel.bin $(INIT_TASKS) $(RD_SRVS) $(RD_APPS) $(CFG)
+$(BASE)/image.iso: arch/$(BARCH)/grub/stage2_eltorito $(COMPONENTS) $(INIT_TASKS) $(RD_SRVS) $(RD_APPS) $(CFG)
 	mkdir -p $(TMP)/boot/grub
 	cp arch/$(BARCH)/grub/stage2_eltorito $(TMP)/boot/grub/
Index: boot/arch/arm32/Makefile.inc
===================================================================
--- boot/arch/arm32/Makefile.inc	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ boot/arch/arm32/Makefile.inc	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -27,7 +27,9 @@
 #
 
+include Makefile.common
+
 build: $(BASE)/image.boot
 
-$(BASE)/image.boot:
+$(BASE)/image.boot: $(COMPONENTS) $(INIT_TASKS) $(RD_SRVS) $(RD_APPS) $(CFG)
 	$(MAKE) -C arch/$(BARCH)/loader PRECHECK=$(PRECHECK)
 	cp arch/$(BARCH)/loader/image.boot $@
Index: boot/arch/arm32/loader/main.c
===================================================================
--- boot/arch/arm32/loader/main.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ boot/arch/arm32/loader/main.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -48,5 +48,5 @@
 
 /** Kernel entry point address. */
-#define KERNEL_VIRTUAL_ADDRESS 0x80200000
+#define KERNEL_VIRTUAL_ADDRESS 0x80800000
 
 
Index: boot/arch/ia64/Makefile.inc
===================================================================
--- boot/arch/ia64/Makefile.inc	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ boot/arch/ia64/Makefile.inc	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -27,7 +27,9 @@
 #
 
+include Makefile.common
+
 build: $(BASE)/image.boot
 
-$(BASE)/image.boot:
+$(BASE)/image.boot: $(COMPONENTS) $(INIT_TASKS) $(RD_SRVS) $(RD_APPS) $(CFG)
 	$(MAKE) -C arch/$(BARCH)/loader PRECHECK=$(PRECHECK)
 	cp arch/$(BARCH)/loader/image.boot $@
Index: boot/arch/mips32/Makefile.inc
===================================================================
--- boot/arch/mips32/Makefile.inc	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ boot/arch/mips32/Makefile.inc	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -27,7 +27,9 @@
 #
 
+include Makefile.common
+
 build: $(BASE)/image.boot
 
-$(BASE)/image.boot:
+$(BASE)/image.boot: $(COMPONENTS) $(INIT_TASKS) $(RD_SRVS) $(RD_APPS) $(CFG)
 	$(MAKE) -C arch/$(BARCH)/loader PRECHECK=$(PRECHECK)
 	cp arch/$(BARCH)/loader/image.boot $@
Index: boot/arch/ppc32/Makefile.inc
===================================================================
--- boot/arch/ppc32/Makefile.inc	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ boot/arch/ppc32/Makefile.inc	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -41,5 +41,5 @@
 	mkisofs -hfs -part -map arch/$(BARCH)/yaboot/maps -no-desktop -hfs-volid "HelenOS" -hfs-bless $(TMP)/boot -r -o $@ $(TMP)/
 
-arch/$(BARCH)/loader/image.boot:
+arch/$(BARCH)/loader/image.boot: $(COMPONENTS) $(INIT_TASKS) $(RD_SRVS) $(RD_APPS) $(CFG)
 	$(MAKE) -C arch/$(BARCH)/loader PRECHECK=$(PRECHECK)
 
Index: boot/arch/ppc32/loader/asm.h
===================================================================
--- boot/arch/ppc32/loader/asm.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ boot/arch/ppc32/loader/asm.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -33,5 +33,5 @@
 #define PAGE_SIZE   (1 << PAGE_WIDTH)
 
-#define TRANS_SIZE   1024
+#define TRANS_SIZE   2048
 #define BOOT_OFFSET  0x8000
 
Index: boot/arch/sparc64/Makefile.inc
===================================================================
--- boot/arch/sparc64/Makefile.inc	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ boot/arch/sparc64/Makefile.inc	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -54,5 +54,5 @@
 	mkisofs -f -G $(TMP)/boot/isofs.b -B ... -r -o $@ $(TMP)/
 
-arch/$(BARCH)/loader/image.boot:
+arch/$(BARCH)/loader/image.boot: $(COMPONENTS) $(INIT_TASKS) $(RD_SRVS) $(RD_APPS) $(CFG)
 	$(MAKE) -C arch/$(BARCH)/loader PRECHECK=$(PRECHECK)
 
Index: defaults/amd64/Makefile.config
===================================================================
--- defaults/amd64/Makefile.config	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ defaults/amd64/Makefile.config	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -62,4 +62,4 @@
 CONFIG_MOUNT_DATA = n
 
-# Default networking architecture
-CONFIG_NETWORKING = modular
+# Bundle netif/nil network layer
+CONFIG_NETIF_NIL_BUNDLE = n
Index: defaults/arm32/Makefile.config
===================================================================
--- defaults/arm32/Makefile.config	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ defaults/arm32/Makefile.config	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -38,4 +38,4 @@
 CONFIG_MOUNT_DATA = n
 
-# Default networking architecture
-CONFIG_NETWORKING = modular
+# Bundle netif/nil network layer
+CONFIG_NETIF_NIL_BUNDLE = n
Index: defaults/ia32/Makefile.config
===================================================================
--- defaults/ia32/Makefile.config	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ defaults/ia32/Makefile.config	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -68,4 +68,4 @@
 CONFIG_MOUNT_DATA = n
 
-# Default networking architecture
-CONFIG_NETWORKING = modular
+# Bundle netif/nil network layer
+CONFIG_NETIF_NIL_BUNDLE = n
Index: defaults/ia64/Makefile.config
===================================================================
--- defaults/ia64/Makefile.config	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ defaults/ia64/Makefile.config	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -50,4 +50,4 @@
 CONFIG_MOUNT_DATA = n
 
-# Default networking architecture
-CONFIG_NETWORKING = modular
+# Bundle netif/nil network layer
+CONFIG_NETIF_NIL_BUNDLE = n
Index: defaults/mips32/Makefile.config
===================================================================
--- defaults/mips32/Makefile.config	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ defaults/mips32/Makefile.config	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -44,4 +44,4 @@
 CONFIG_MOUNT_DATA = n
 
-# Default networking architecture
-CONFIG_NETWORKING = modular
+# Bundle netif/nil network layer
+CONFIG_NETIF_NIL_BUNDLE = n
Index: defaults/ppc32/Makefile.config
===================================================================
--- defaults/ppc32/Makefile.config	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ defaults/ppc32/Makefile.config	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -44,4 +44,4 @@
 CONFIG_MOUNT_DATA = n
 
-# Default networking architecture
-CONFIG_NETWORKING = modular
+# Bundle netif/nil network layer
+CONFIG_NETIF_NIL_BUNDLE = n
Index: defaults/sparc64/Makefile.config
===================================================================
--- defaults/sparc64/Makefile.config	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ defaults/sparc64/Makefile.config	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -62,4 +62,4 @@
 CONFIG_MOUNT_DATA = n
 
-# Default networking architecture
-CONFIG_NETWORKING = modular
+# Bundle netif/nil network layer
+CONFIG_NETIF_NIL_BUNDLE = n
Index: defaults/special/Makefile.config
===================================================================
--- defaults/special/Makefile.config	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ defaults/special/Makefile.config	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -29,4 +29,4 @@
 CONFIG_START_BD = n
 
-# Default networking architecture
-CONFIG_NETWORKING = modular
+# Bundle netif/nil network layer
+CONFIG_NETIF_NIL_BUNDLE = n
Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -229,5 +229,6 @@
 	generic/src/ipc/event.c \
 	generic/src/security/cap.c \
-	generic/src/sysinfo/sysinfo.c
+	generic/src/sysinfo/sysinfo.c \
+	generic/src/sysinfo/stats.c
 
 ## Kernel console support
@@ -278,6 +279,5 @@
 		test/print/print3.c \
 		test/print/print4.c \
-		test/thread/thread1.c \
-		test/sysinfo/sysinfo1.c
+		test/thread/thread1.c
 	
 	ifeq ($(KARCH),mips32)
@@ -344,6 +344,4 @@
 endif
 
-
-
 $(BIN): $(RAW)
 	$(OBJCOPY) -O $(BFD) $< $@
@@ -353,5 +351,5 @@
 
 $(RAW): $(LINK) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(SYMTAB_OBJECTS)
-	$(LD) $(LFLAGS) -T $(LINK) -M -Map $(MAP) -o $@  $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SYMTAB_OBJECTS)
+	$(LD) -N $(LFLAGS) -T $(LINK) -M -Map $(MAP) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SYMTAB_OBJECTS)
 
 $(LINK): $(LINK).in $(DEPEND)
@@ -396,5 +394,5 @@
 $(REAL_MAP).bin: $(LINK) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS)
 	echo $(SYMTAB_SECTION) | $(AS) $(AFLAGS) -o $(EMPTY_MAP)
-	$(LD) $(LFLAGS) -T $(LINK) -M -Map $(MAP_PREV) -o $@  $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(EMPTY_MAP)
+	$(LD) -N $(LFLAGS) -T $(LINK) -M -Map $(MAP_PREV) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(EMPTY_MAP)
 	$(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > $(DUMP)
 	$(GENMAP) $(MAP_PREV) $(DUMP) $@
@@ -404,5 +402,5 @@
 	
 	echo $(SYMTAB_SECTION)" .incbin \"$@\"" | $(AS) $(AFLAGS) -o $(SIZEOK_MAP)
-	$(LD) $(LFLAGS) -T $(LINK) -M -Map $(MAP_PREV) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SIZEOK_MAP)
+	$(LD) -N $(LFLAGS) -T $(LINK) -M -Map $(MAP_PREV) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SIZEOK_MAP)
 	$(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > $(DUMP)
 	$(GENMAP) $(MAP_PREV) $(DUMP) $@
Index: kernel/arch/arm32/_link.ld.in
===================================================================
--- kernel/arch/arm32/_link.ld.in	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/arch/arm32/_link.ld.in	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -7,5 +7,5 @@
  */
 
-#define KERNEL_LOAD_ADDRESS 0x80200000
+#define KERNEL_LOAD_ADDRESS 0x80800000
 
 OUTPUT_ARCH(arm)
Index: kernel/arch/mips32/include/arch.h
===================================================================
--- kernel/arch/mips32/include/arch.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/arch/mips32/include/arch.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -36,10 +36,9 @@
 #define KERN_mips32_ARCH_H_
 
-#define TASKMAP_MAX_RECORDS  32
-#define CPUMAP_MAX_RECORDS   32
+#include <typedefs.h>
 
-#define BOOTINFO_TASK_NAME_BUFLEN 32
-
-#include <typedefs.h>
+#define TASKMAP_MAX_RECORDS        32
+#define CPUMAP_MAX_RECORDS         32
+#define BOOTINFO_TASK_NAME_BUFLEN  32
 
 extern size_t cpu_count;
@@ -47,5 +46,5 @@
 typedef struct {
 	uintptr_t addr;
-	uint32_t size;
+	size_t size;
 	char name[BOOTINFO_TASK_NAME_BUFLEN];
 } utask_t;
@@ -53,5 +52,5 @@
 typedef struct {
 	uint32_t cpumap;
-	uint32_t cnt;
+	size_t cnt;
 	utask_t tasks[TASKMAP_MAX_RECORDS];
 } bootinfo_t;
Index: kernel/arch/mips32/include/asm/boot.h
===================================================================
--- kernel/arch/mips32/include/asm/boot.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/arch/mips32/include/asm/boot.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -36,7 +36,6 @@
 #define KERN_mips32_BOOT_H_
 
-
 /* Temporary stack size for boot process */
-#define TEMP_STACK_SIZE 0x100
+#define TEMP_STACK_SIZE  0x100
 
 #endif
Index: kernel/arch/mips32/include/asm/regname.h
===================================================================
--- kernel/arch/mips32/include/asm/regname.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/arch/mips32/include/asm/regname.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup mips32	
+/** @addtogroup mips32
  * @{
  */
@@ -69,28 +69,28 @@
 #define ra      31
 
-#define rindex		0
-#define rrandom		1
-#define entrylo0	2
-#define entrylo1	3
-#define context		4
-#define pagemask	5
-#define wired		6
-#define badvaddr	8
-#define count		9
-#define entryhi		10
-#define compare		11
-#define status		12
-#define cause		13
-#define epc		14
-#define rconfig		16
-#define lladdr		17
-#define watchlo		18
-#define watchhi		19
-#define xcontext	20
-#define rdebug		23
-#define depc		24
-#define eepc		30
+#define rindex    0
+#define rrandom   1
+#define entrylo0  2
+#define entrylo1  3
+#define context   4
+#define pagemask  5
+#define wired     6
+#define badvaddr  8
+#define count     9
+#define entryhi   10
+#define compare   11
+#define status    12
+#define cause     13
+#define epc       14
+#define rconfig   16
+#define lladdr    17
+#define watchlo   18
+#define watchhi   19
+#define xcontext  20
+#define rdebug    23
+#define depc      24
+#define eepc      30
 
-#endif /* KERN_mips32_REGNAME_H_ */
+#endif
 
 /** @}
Index: kernel/generic/include/cpu.h
===================================================================
--- kernel/generic/include/cpu.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/include/cpu.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -68,4 +68,8 @@
 					     are disabled. */
 
+	bool idle;
+	uint64_t idle_ticks;
+	uint64_t busy_ticks;
+
 	/**
 	 * Processor ID assigned by kernel.
@@ -73,5 +77,5 @@
 	unsigned int id;
 	
-	int active;
+	bool active;
 	int tlb_active;
 
Index: kernel/generic/include/func.h
===================================================================
--- kernel/generic/include/func.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/include/func.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -43,5 +43,4 @@
 extern void halt(void) __attribute__((noreturn));
 extern unative_t atoi(const char *text);
-extern void order(const uint64_t val, uint64_t *rv, char *suffix);
 
 #endif
Index: kernel/generic/include/ipc/sysipc.h
===================================================================
--- kernel/generic/include/ipc/sysipc.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/include/ipc/sysipc.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -57,5 +57,5 @@
 unative_t sys_ipc_forward_slow(unative_t callid, unative_t phoneid,
     ipc_data_t *data, int mode);
-unative_t sys_ipc_hangup(int phoneid);
+unative_t sys_ipc_hangup(unative_t phoneid);
 unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method,
     irq_code_t *ucode);
Index: kernel/generic/include/mm/frame.h
===================================================================
--- kernel/generic/include/mm/frame.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/include/mm/frame.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -169,10 +169,11 @@
 extern bool zone_merge(size_t, size_t);
 extern void zone_merge_all(void);
-extern uint64_t zone_total_size(void);
+extern uint64_t zones_total_size(void);
+extern void zones_stats(uint64_t *, uint64_t *, uint64_t *, uint64_t *);
 
 /*
  * Console functions
  */
-extern void zone_print_list(void);
+extern void zones_print_list(void);
 extern void zone_print_one(size_t);
 
Index: kernel/generic/include/print.h
===================================================================
--- kernel/generic/include/print.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/include/print.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -39,5 +39,5 @@
 #include <stdarg.h>
 
-#define EOF (-1)
+#define EOF  (-1)
 
 extern int puts(const char *s);
Index: kernel/generic/include/printf/printf_core.h
===================================================================
--- kernel/generic/include/printf/printf_core.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/include/printf/printf_core.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -51,5 +51,5 @@
 } printf_spec_t;
 
-int printf_core(const char *fmt, printf_spec_t *ps, va_list ap);
+extern int printf_core(const char *fmt, printf_spec_t *ps, va_list ap);
 
 #endif
Index: kernel/generic/include/proc/task.h
===================================================================
--- kernel/generic/include/proc/task.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/include/proc/task.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -56,6 +56,5 @@
 #include <ipc/kbox.h>
 #include <mm/as.h>
-
-#define TASK_NAME_BUFLEN	20
+#include <sysinfo/abi.h>
 
 struct thread;
@@ -81,5 +80,5 @@
 	task_id_t taskid;
 	/** Task security context. */
-	context_id_t context;	
+	context_id_t context;
 
 	/** Number of references (i.e. threads). */
@@ -89,9 +88,10 @@
 
 	/** Task capabilities. */
-	cap_t capabilities;	
+	cap_t capabilities;
 
 	/* IPC stuff */
 	answerbox_t answerbox;  /**< Communication endpoint */
 	phone_t phones[IPC_MAX_PHONES];
+	stats_ipc_t ipc_info;   /**< IPC statistics */
 	/**
 	 * Active asynchronous messages. It is used for limiting uspace to
@@ -119,8 +119,9 @@
 	mutex_t futexes_lock;
 	/** B+tree of futexes referenced by this task. */
-	btree_t futexes;	
+	btree_t futexes;
 	
 	/** Accumulated accounting. */
-	uint64_t cycles;
+	uint64_t ucycles;
+	uint64_t kcycles;
 } task_t;
 
@@ -134,5 +135,5 @@
 extern task_t *task_find_by_id(task_id_t id);
 extern int task_kill(task_id_t id);
-extern uint64_t task_get_accounting(task_t *t);
+extern void task_get_accounting(task_t *t, uint64_t *ucycles, uint64_t *kcycles);
 extern void task_print_list(void);
 
Index: kernel/generic/include/proc/thread.h
===================================================================
--- kernel/generic/include/proc/thread.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/include/proc/thread.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -48,4 +48,5 @@
 #include <proc/uarg.h>
 #include <udebug/udebug.h>
+#include <sysinfo/abi.h>
 
 #define THREAD_STACK_SIZE	STACK_SIZE
@@ -69,22 +70,4 @@
 #define THREAD_FLAG_NOATTACH	(1 << 3)
 
-/** Thread states. */
-typedef enum {
-	/** It is an error, if thread is found in this state. */
-	Invalid,
-	/** State of a thread that is currently executing on some CPU. */
-	Running,
-	/** Thread in this state is waiting for an event. */
-	Sleeping,
-	/** State of threads in a run queue. */
-	Ready,
-	/** Threads are in this state before they are first readied. */
-	Entering,
-	/** After a thread calls thread_exit(), it is put into Exiting state. */
-	Exiting,
-	/** Threads that were not detached but exited are Lingering. */
-	Lingering
-} state_t;
-
 /** Thread structure. There is one per thread. */
 typedef struct thread {
@@ -189,5 +172,6 @@
 	
 	/** Thread accounting. */
-	uint64_t cycles;
+	uint64_t ucycles;
+	uint64_t kcycles;
 	/** Last sampled cycle. */
 	uint64_t last_cycle;
@@ -252,5 +236,6 @@
 extern void thread_print_list(void);
 extern void thread_destroy(thread_t *);
-extern void thread_update_accounting(void);
+extern thread_t *thread_find_by_id(thread_id_t);
+extern void thread_update_accounting(bool);
 extern bool thread_exists(thread_t *);
 
Index: kernel/generic/include/str.h
===================================================================
--- kernel/generic/include/str.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/include/str.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -89,4 +89,7 @@
 extern void wstr_to_str(char *dest, size_t size, const wchar_t *src);
 
+extern char *str_dup(const char *src);
+extern char *str_ndup(const char *src, size_t n);
+
 extern char *str_chr(const char *str, wchar_t ch);
 
@@ -94,4 +97,8 @@
 extern bool wstr_remove(wchar_t *str, size_t pos);
 
+extern int str_uint64(const char *, char **, unsigned int, bool, uint64_t *);
+
+extern void order_suffix(const uint64_t val, uint64_t *rv, char *suffix);
+
 #endif
 
Index: kernel/generic/include/syscall/syscall.h
===================================================================
--- kernel/generic/include/syscall/syscall.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/include/syscall/syscall.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -71,5 +71,5 @@
 	SYS_IPC_REGISTER_IRQ,
 	SYS_IPC_UNREGISTER_IRQ,
-
+	
 	SYS_EVENT_SUBSCRIBE,
 	
@@ -82,9 +82,12 @@
 	SYS_PREEMPT_CONTROL,
 	
-	SYS_SYSINFO_VALID,
-	SYS_SYSINFO_VALUE,
+	SYS_SYSINFO_GET_TAG,
+	SYS_SYSINFO_GET_VALUE,
+	SYS_SYSINFO_GET_DATA_SIZE,
+	SYS_SYSINFO_GET_DATA,
 	
 	SYS_DEBUG_ENABLE_CONSOLE,
 	SYS_DEBUG_DISABLE_CONSOLE,
+	
 	SYS_IPC_CONNECT_KBOX,
 	SYSCALL_END
Index: kernel/generic/include/sysinfo/abi.h
===================================================================
--- kernel/generic/include/sysinfo/abi.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ kernel/generic/include/sysinfo/abi.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2010 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 generic
+ * @{
+ */
+/** @file
+ * Data structures passed between kernel sysinfo and user space.
+ */
+
+#ifndef KERN_ABI_H_
+#define KERN_ABI_H_
+
+/** Number of load components */
+#define LOAD_STEPS        3
+
+/** Maximum task name size */
+#define TASK_NAME_BUFLEN  20
+
+/** Thread states */
+typedef enum {
+	/** It is an error, if thread is found in this state. */
+	Invalid,
+	/** State of a thread that is currently executing on some CPU. */
+	Running,
+	/** Thread in this state is waiting for an event. */
+	Sleeping,
+	/** State of threads in a run queue. */
+	Ready,
+	/** Threads are in this state before they are first readied. */
+	Entering,
+	/** After a thread calls thread_exit(), it is put into Exiting state. */
+	Exiting,
+	/** Threads that were not detached but exited are Lingering. */
+	Lingering
+} state_t;
+
+/** Statistics about a single CPU
+ *
+ */
+typedef struct {
+	unsigned int id;         /**< CPU ID as stored by kernel */
+	bool active;             /**< CPU is activate */
+	uint16_t frequency_mhz;  /**< Frequency in MHz */
+	uint64_t idle_ticks;     /**< Number of idle kernel quanta */
+	uint64_t busy_ticks;     /**< Number of busy kernel quanta */
+} stats_cpu_t;
+
+/** Physical memory statistics
+ *
+ */
+typedef struct {
+	uint64_t total;    /**< Total physical memory (bytes) */
+	uint64_t unavail;  /**< Unavailable (reserved, firmware) bytes */
+	uint64_t used;     /**< Allocated physical memory (bytes) */
+	uint64_t free;     /**< Free physical memory (bytes) */
+} stats_physmem_t;
+
+/** IPC statistics
+ *
+ * Associated with a task.
+ *
+ */
+typedef struct {
+	uint64_t call_sent;           /**< IPC calls sent */
+	uint64_t call_recieved;       /**< IPC calls received */
+	uint64_t answer_sent;         /**< IPC answers sent */
+	uint64_t answer_recieved;     /**< IPC answers received */
+	uint64_t irq_notif_recieved;  /**< IPC IRQ notifications */
+	uint64_t forwarded;           /**< IPC messages forwarded */
+} stats_ipc_t;
+
+/** Statistics about a single task
+ *
+ */
+typedef struct {
+	task_id_t task_id;            /**< Task ID */
+	char name[TASK_NAME_BUFLEN];  /**< Task name (in kernel) */
+	size_t virtmem;               /**< Size of VAS (bytes) */
+	size_t threads;               /**< Number of threads */
+	uint64_t ucycles;             /**< Number of CPU cycles in user space */
+	uint64_t kcycles;             /**< Number of CPU cycles in kernel */
+	stats_ipc_t ipc_info;         /**< IPC statistics */
+} stats_task_t;
+
+/** Statistics about a single thread
+ *
+ */
+typedef struct {
+	thread_id_t thread_id;  /**< Thread ID */
+	task_id_t task_id;      /**< Associated task ID */
+	state_t state;          /**< Thread state */
+	int priority;           /**< Thread priority */
+	uint64_t ucycles;       /**< Number of CPU cycles in user space */
+	uint64_t kcycles;       /**< Number of CPU cycles in kernel */
+	bool on_cpu;            /**< Associated with a CPU */
+	unsigned int cpu;       /**< Associated CPU ID (if on_cpu is true) */
+} stats_thread_t;
+
+/** Load fixed-point value */
+typedef uint32_t load_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/include/sysinfo/stats.h
===================================================================
--- kernel/generic/include/sysinfo/stats.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ kernel/generic/include/sysinfo/stats.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 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 generic
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_STATS_H_
+#define KERN_STATS_H_
+
+extern void kload(void *arg);
+extern void stats_init(void);
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/include/sysinfo/sysinfo.h
===================================================================
--- kernel/generic/include/sysinfo/sysinfo.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/include/sysinfo/sysinfo.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -39,53 +39,114 @@
 #include <str.h>
 
+/** Framebuffer info exported flags */
 extern bool fb_exported;
 
-typedef union sysinfo_item_val {
-	unative_t val;
-	void *fn; 
+/** Item value type
+ *
+ */
+typedef enum {
+	SYSINFO_VAL_UNDEFINED = 0,     /**< Undefined value */
+	SYSINFO_VAL_VAL = 1,           /**< Constant numeric value */
+	SYSINFO_VAL_DATA = 2,          /**< Constant binary data */
+	SYSINFO_VAL_FUNCTION_VAL = 3,  /**< Generated numeric value */
+	SYSINFO_VAL_FUNCTION_DATA = 4  /**< Generated binary data */
+} sysinfo_item_val_type_t;
+
+/** Subtree type
+ *
+ */
+typedef enum {
+	SYSINFO_SUBTREE_NONE = 0,     /**< No subtree (leaf item) */
+	SYSINFO_SUBTREE_TABLE = 1,    /**< Fixed subtree */
+	SYSINFO_SUBTREE_FUNCTION = 2  /**< Generated subtree */
+} sysinfo_subtree_type_t;
+
+struct sysinfo_item;
+
+/** Gerated numeric value function */
+typedef unative_t (*sysinfo_fn_val_t)(struct sysinfo_item *);
+
+/** Generated binary data function */
+typedef void *(*sysinfo_fn_data_t)(struct sysinfo_item *, size_t *, bool);
+
+/** Sysinfo item binary data
+ *
+ */
+typedef struct {
+	void *data;   /**< Data */
+	size_t size;  /**< Size (bytes) */
+} sysinfo_data_t;
+
+/** Sysinfo item value (union)
+ *
+ */
+typedef union {
+	unative_t val;              /**< Constant numberic value */
+	sysinfo_fn_val_t fn_val;    /**< Generated numeric value function */
+	sysinfo_fn_data_t fn_data;  /**< Generated binary data function */
+	sysinfo_data_t data;        /**< Constant binary data */
 } sysinfo_item_val_t;
 
+/** Sysinfo return holder
+ *
+ * This structure is generated from the constant
+ * items or by the generating functions. Note that
+ * the validity of the data is limited by the scope
+ * of single sysinfo invocation guarded by sysinfo_lock.
+ *
+ */
+typedef struct {
+	sysinfo_item_val_type_t tag;  /**< Return value type */
+	union {
+		unative_t val;            /**< Numberic value */
+		sysinfo_data_t data;      /**< Binary data */
+	};
+} sysinfo_return_t;
+
+/** Generated subtree function */
+typedef sysinfo_return_t (*sysinfo_fn_subtree_t)(const char *, bool);
+
+/** Sysinfo subtree (union)
+ *
+ */
+typedef union {
+	struct sysinfo_item *table;     /**< Fixed subtree (list of subitems) */
+	sysinfo_fn_subtree_t get_data;  /**< Generated subtree function */
+} sysinfo_subtree_t;
+
+/** Sysinfo item
+ *
+ */
 typedef struct sysinfo_item {
-	char *name;
-	union {
-		unative_t val;
-		void *fn; 
-	} val;
-
-	union {
-		struct sysinfo_item *table;
-		void *fn;
-	} subinfo;
-
-	struct sysinfo_item *next;
-	int val_type;
-	int subinfo_type;
+	char *name;                           /**< Item name */
+	
+	sysinfo_item_val_type_t val_type;     /**< Item value type */
+	sysinfo_item_val_t val;               /**< Item value */
+	
+	sysinfo_subtree_type_t subtree_type;  /**< Subtree type */
+	sysinfo_subtree_t subtree;            /**< Subtree */
+	
+	struct sysinfo_item *next;            /**< Sibling item */
 } sysinfo_item_t;
 
-#define SYSINFO_VAL_VAL        0
-#define SYSINFO_VAL_FUNCTION   1
-#define SYSINFO_VAL_UNDEFINED  U_SPECIAL
+extern void sysinfo_set_item_val(const char *, sysinfo_item_t **, unative_t);
+extern void sysinfo_set_item_data(const char *, sysinfo_item_t **, void *,
+    size_t);
+extern void sysinfo_set_item_fn_val(const char *, sysinfo_item_t **,
+    sysinfo_fn_val_t);
+extern void sysinfo_set_item_fn_data(const char *, sysinfo_item_t **,
+    sysinfo_fn_data_t);
+extern void sysinfo_set_item_undefined(const char *, sysinfo_item_t **);
 
-#define SYSINFO_SUBINFO_NONE      0
-#define SYSINFO_SUBINFO_TABLE     1
-#define SYSINFO_SUBINFO_FUNCTION  2
+extern void sysinfo_set_subtree_fn(const char *, sysinfo_item_t **,
+    sysinfo_fn_subtree_t);
 
-typedef unative_t (*sysinfo_val_fn_t)(sysinfo_item_t *root);
-typedef unative_t (*sysinfo_subinfo_fn_t)(const char *subname);
+extern void sysinfo_init(void);
+extern void sysinfo_dump(sysinfo_item_t *);
 
-typedef struct sysinfo_rettype {
-	unative_t val;
-	unative_t valid;
-} sysinfo_rettype_t;
-
-void sysinfo_set_item_val(const char *name, sysinfo_item_t **root, unative_t val);
-void sysinfo_dump(sysinfo_item_t **root, int depth);
-void sysinfo_set_item_function(const char *name, sysinfo_item_t **root, sysinfo_val_fn_t fn);
-void sysinfo_set_item_undefined(const char *name, sysinfo_item_t **root);
-
-sysinfo_rettype_t sysinfo_get_val(const char *name, sysinfo_item_t **root);
-
-unative_t sys_sysinfo_valid(unative_t ptr, unative_t len);
-unative_t sys_sysinfo_value(unative_t ptr, unative_t len);
+extern unative_t sys_sysinfo_get_tag(void *, size_t);
+extern unative_t sys_sysinfo_get_value(void *, size_t, void *);
+extern unative_t sys_sysinfo_get_data_size(void *, size_t, void *);
+extern unative_t sys_sysinfo_get_data(void *, size_t, void *, size_t);
 
 #endif
Index: kernel/generic/include/time/clock.h
===================================================================
--- kernel/generic/include/time/clock.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/include/time/clock.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -38,5 +38,5 @@
 #include <typedefs.h>
 
-#define HZ		100
+#define HZ  100
 
 /** Uptime structure */
Index: kernel/generic/src/console/cmd.c
===================================================================
--- kernel/generic/src/console/cmd.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/console/cmd.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -66,4 +66,5 @@
 #include <ipc/irq.h>
 #include <ipc/event.h>
+#include <sysinfo/sysinfo.h>
 #include <symtab.h>
 #include <errno.h>
@@ -387,4 +388,12 @@
 };
 
+static int cmd_sysinfo(cmd_arg_t *argv);
+static cmd_info_t sysinfo_info = {
+	.name = "sysinfo",
+	.description = "Dump sysinfo.",
+	.func = cmd_sysinfo,
+	.argc = 0
+};
+
 /* Data and methods for 'zones' command */
 static int cmd_zones(cmd_arg_t *argv);
@@ -475,4 +484,5 @@
 	&set4_info,
 	&slabs_info,
+	&sysinfo_info,
 	&symaddr_info,
 	&sched_info,
@@ -868,4 +878,16 @@
 }
 
+/** Command for dumping sysinfo
+ *
+ * @param argv Ignores
+ *
+ * @return Always 1
+ */
+int cmd_sysinfo(cmd_arg_t * argv)
+{
+	sysinfo_dump(NULL);
+	return 1;
+}
+
 
 /** Command for listings Thread information
@@ -913,5 +935,5 @@
 int cmd_zones(cmd_arg_t * argv)
 {
-	zone_print_list();
+	zones_print_list();
 	return 1;
 }
@@ -1027,5 +1049,6 @@
 	ipl_t ipl = interrupts_disable();
 	spinlock_lock(&TASK->lock);
-	uint64_t t0 = task_get_accounting(TASK);
+	uint64_t ucycles0, kcycles0;
+	task_get_accounting(TASK, &ucycles0, &kcycles0);
 	spinlock_unlock(&TASK->lock);
 	interrupts_restore(ipl);
@@ -1036,15 +1059,18 @@
 	
 	/* Update and read thread accounting */
+	uint64_t ucycles1, kcycles1; 
 	ipl = interrupts_disable();
 	spinlock_lock(&TASK->lock);
-	uint64_t dt = task_get_accounting(TASK) - t0;
+	task_get_accounting(TASK, &ucycles1, &kcycles1);
 	spinlock_unlock(&TASK->lock);
 	interrupts_restore(ipl);
 	
-	uint64_t cycles;
-	char suffix;
-	order(dt, &cycles, &suffix);
-		
-	printf("Time: %" PRIu64 "%c cycles\n", cycles, suffix);
+	uint64_t ucycles, kcycles;
+	char usuffix, ksuffix;
+	order_suffix(ucycles1 - ucycles0, &ucycles, &usuffix);
+	order_suffix(kcycles1 - kcycles0, &kcycles, &ksuffix);
+		
+	printf("Time: %" PRIu64 "%c user cycles, %" PRIu64 "%c kernel cycles\n",
+			ucycles, usuffix, kcycles, ksuffix);
 	
 	if (ret == NULL) {
@@ -1061,6 +1087,6 @@
 	uint32_t i;
 	bool ret = true;
-	uint64_t cycles;
-	char suffix;
+	uint64_t ucycles, kcycles;
+	char usuffix, ksuffix;
 	
 	if (cnt < 1)
@@ -1080,5 +1106,6 @@
 		ipl_t ipl = interrupts_disable();
 		spinlock_lock(&TASK->lock);
-		uint64_t t0 = task_get_accounting(TASK);
+		uint64_t ucycles0, kcycles0;
+		task_get_accounting(TASK, &ucycles0, &kcycles0);
 		spinlock_unlock(&TASK->lock);
 		interrupts_restore(ipl);
@@ -1091,8 +1118,9 @@
 		ipl = interrupts_disable();
 		spinlock_lock(&TASK->lock);
-		uint64_t dt = task_get_accounting(TASK) - t0;
+		uint64_t ucycles1, kcycles1;
+		task_get_accounting(TASK, &ucycles1, &kcycles1);
 		spinlock_unlock(&TASK->lock);
 		interrupts_restore(ipl);
-		
+
 		if (ret != NULL) {
 			printf("%s\n", ret);
@@ -1101,7 +1129,9 @@
 		}
 		
-		data[i] = dt;
-		order(dt, &cycles, &suffix);
-		printf("OK (%" PRIu64 "%c cycles)\n", cycles, suffix);
+		data[i] = ucycles1 - ucycles0 + kcycles1 - kcycles0;
+		order_suffix(ucycles1 - ucycles0, &ucycles, &usuffix);
+		order_suffix(kcycles1 - kcycles0, &kcycles, &ksuffix);
+		printf("OK (%" PRIu64 "%c user cycles, %" PRIu64 "%c kernel cycles)\n",
+				ucycles, usuffix, kcycles, ksuffix);
 	}
 	
@@ -1115,6 +1145,6 @@
 		}
 		
-		order(sum / (uint64_t) cnt, &cycles, &suffix);
-		printf("Average\t\t%" PRIu64 "%c\n", cycles, suffix);
+		order_suffix(sum / (uint64_t) cnt, &ucycles, &usuffix);
+		printf("Average\t\t%" PRIu64 "%c\n", ucycles, usuffix);
 	}
 	
Index: kernel/generic/src/cpu/cpu.c
===================================================================
--- kernel/generic/src/cpu/cpu.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/cpu/cpu.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -48,4 +48,5 @@
 #include <adt/list.h>
 #include <print.h>
+#include <sysinfo/sysinfo.h>
 
 cpu_t *cpus;
Index: kernel/generic/src/interrupt/interrupt.c
===================================================================
--- kernel/generic/src/interrupt/interrupt.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/interrupt/interrupt.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -51,4 +51,5 @@
 #include <print.h>
 #include <symtab.h>
+#include <proc/thread.h>
 
 static struct {
@@ -91,4 +92,8 @@
 	ASSERT(n < IVT_ITEMS);
 
+	/* Account user cycles */
+	if (THREAD)
+		thread_update_accounting(true);
+
 #ifdef CONFIG_UDEBUG
 	if (THREAD) THREAD->udebug.uspace_state = istate;
@@ -104,4 +109,7 @@
 	if (THREAD && THREAD->interrupted && istate_from_uspace(istate))
 		thread_exit();
+
+	if (THREAD)
+		thread_update_accounting(false);
 }
 
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/ipc/ipc.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -219,4 +219,9 @@
 	bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox));
 
+	/* Count sent answer */
+	spinlock_lock(&TASK->lock);
+	TASK->ipc_info.answer_sent++;
+	spinlock_unlock(&TASK->lock);
+
 	call->flags |= IPC_CALL_ANSWERED;
 
@@ -276,4 +281,9 @@
 static void _ipc_call(phone_t *phone, answerbox_t *box, call_t *call)
 {
+	/* Count sent ipc call */
+	spinlock_lock(&TASK->lock);
+	TASK->ipc_info.call_sent++;
+	spinlock_unlock(&TASK->lock);
+
 	if (!(call->flags & IPC_CALL_FORWARDED)) {
 		atomic_inc(&phone->active_calls);
@@ -376,4 +386,9 @@
 int ipc_forward(call_t *call, phone_t *newphone, answerbox_t *oldbox, int mode)
 {
+	/* Count forwarded calls */
+	spinlock_lock(&TASK->lock);
+	TASK->ipc_info.forwarded++;
+	spinlock_unlock(&TASK->lock);
+
 	spinlock_lock(&oldbox->lock);
 	list_remove(&call->link);
@@ -416,4 +431,10 @@
 	spinlock_lock(&box->lock);
 	if (!list_empty(&box->irq_notifs)) {
+
+		/* Count recieved IRQ notification */
+		spinlock_lock(&TASK->lock);
+		TASK->ipc_info.irq_notif_recieved++;
+		spinlock_unlock(&TASK->lock);
+
 		ipl = interrupts_disable();
 		spinlock_lock(&box->irq_lock);
@@ -425,4 +446,9 @@
 		interrupts_restore(ipl);
 	} else if (!list_empty(&box->answers)) {
+		/* Count recieved answer */
+		spinlock_lock(&TASK->lock);
+		TASK->ipc_info.answer_recieved++;
+		spinlock_unlock(&TASK->lock);
+
 		/* Handle asynchronous answers */
 		request = list_get_instance(box->answers.next, call_t, link);
@@ -430,4 +456,9 @@
 		atomic_dec(&request->data.phone->active_calls);
 	} else if (!list_empty(&box->calls)) {
+		/* Count recieved call */
+		spinlock_lock(&TASK->lock);
+		TASK->ipc_info.call_recieved++;
+		spinlock_unlock(&TASK->lock);
+
 		/* Handle requests */
 		request = list_get_instance(box->calls.next, call_t, link);
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/ipc/sysipc.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -58,10 +58,17 @@
 #define DATA_XFER_LIMIT		(64 * 1024)
 
-#define GET_CHECK_PHONE(phone, phoneid, err) \
-{ \
-	if (phoneid > IPC_MAX_PHONES) { \
-		err \
-	} \
-	phone = &TASK->phones[phoneid]; \
+/** Get phone from the current task by ID.
+ *
+ * @param phoneid	Phone ID.
+ * @param phone		Place to store pointer to phone.
+ * @return		EOK on success, EINVAL if ID is invalid.
+ */
+static int phone_get(unative_t phoneid, phone_t **phone)
+{
+	if (phoneid >= IPC_MAX_PHONES)
+		return EINVAL;
+
+	*phone = &TASK->phones[phoneid];
+	return EOK;
 }
 
@@ -374,7 +381,9 @@
 	case IPC_M_CONNECTION_CLONE: {
 		phone_t *cloned_phone;
-		GET_CHECK_PHONE(cloned_phone, IPC_GET_ARG1(call->data),
-		    return ENOENT;);
+
+		if (phone_get(IPC_GET_ARG1(call->data), &cloned_phone) != EOK)
+			return ENOENT;
 		phones_lock(cloned_phone, phone);
+
 		if ((cloned_phone->state != IPC_PHONE_CONNECTED) ||
 		    phone->state != IPC_PHONE_CONNECTED) {
@@ -534,6 +543,7 @@
 	int res;
 	int rc;
-	
-	GET_CHECK_PHONE(phone, phoneid, return ENOENT;);
+
+	if (phone_get(phoneid, &phone) != EOK)
+		return ENOENT;
 
 	call = ipc_call_alloc(0);
@@ -591,5 +601,6 @@
 	int rc;
 
-	GET_CHECK_PHONE(phone, phoneid, return ENOENT;);
+	if (phone_get(phoneid, &phone) != EOK)
+		return ENOENT;
 
 	call = ipc_call_alloc(0);
@@ -666,5 +677,6 @@
 		return IPC_CALLRET_TEMPORARY;
 
-	GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL;);
+	if (phone_get(phoneid, &phone) != EOK)
+		return IPC_CALLRET_FATAL;
 
 	call = ipc_call_alloc(0);
@@ -705,5 +717,6 @@
 		return IPC_CALLRET_TEMPORARY;
 
-	GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL;);
+	if (phone_get(phoneid, &phone) != EOK)
+		return IPC_CALLRET_FATAL;
 
 	call = ipc_call_alloc(0);
@@ -755,9 +768,9 @@
 	call->flags |= IPC_CALL_FORWARDED;
 
-	GET_CHECK_PHONE(phone, phoneid, {
+	if (phone_get(phoneid, &phone) != EOK) {
 		IPC_SET_RETVAL(call->data, EFORWARD);
 		ipc_answer(&TASK->answerbox, call);
 		return ENOENT;
-	});
+	}
 
 	if (!method_is_forwardable(IPC_GET_METHOD(call->data))) {
@@ -956,9 +969,10 @@
  * @return		Return 0 on success or an error code.
  */
-unative_t sys_ipc_hangup(int phoneid)
+unative_t sys_ipc_hangup(unative_t phoneid)
 {
 	phone_t *phone;
 
-	GET_CHECK_PHONE(phone, phoneid, return ENOENT;);
+	if (phone_get(phoneid, &phone) != EOK)
+		return ENOENT;
 
 	if (ipc_phone_hangup(phone))
Index: kernel/generic/src/lib/func.c
===================================================================
--- kernel/generic/src/lib/func.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/lib/func.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -123,31 +123,4 @@
 }
 
-
-void order(const uint64_t val, uint64_t *rv, char *suffix)
-{
-	if (val > 10000000000000000000ULL) {
-		*rv = val / 1000000000000000000ULL;
-		*suffix = 'Z';
-	} else if (val > 1000000000000000000ULL) {
-		*rv = val / 1000000000000000ULL;
-		*suffix = 'E';
-	} else if (val > 1000000000000000ULL) {
-		*rv = val / 1000000000000ULL;
-		*suffix = 'T';
-	} else if (val > 1000000000000ULL) {
-		*rv = val / 1000000000ULL;
-		*suffix = 'G';
-	} else if (val > 1000000000ULL) {
-		*rv = val / 1000000ULL;
-		*suffix = 'M';
-	} else if (val > 1000000ULL) {
-		*rv = val / 1000ULL;
-		*suffix = 'k';
-	} else {
-		*rv = val;
-		*suffix = ' ';
-	}
-}
-
 /** @}
  */
Index: kernel/generic/src/lib/str.c
===================================================================
--- kernel/generic/src/lib/str.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/lib/str.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -110,4 +110,5 @@
 #include <align.h>
 #include <debug.h>
+#include <macros.h>
 
 /** Byte mask consisting of lowest @n bits (out of 8) */
@@ -537,25 +538,23 @@
  * null-terminated and containing only complete characters.
  *
- * @param dest   Destination buffer.
+ * @param dest  Destination buffer.
  * @param count Size of the destination buffer (must be > 0).
  * @param src   Source string.
+ *
  */
 void str_cpy(char *dest, size_t size, const char *src)
 {
-	wchar_t ch;
-	size_t src_off;
-	size_t dest_off;
-
 	/* There must be space for a null terminator in the buffer. */
 	ASSERT(size > 0);
 	
-	src_off = 0;
-	dest_off = 0;
-
+	size_t src_off = 0;
+	size_t dest_off = 0;
+	
+	wchar_t ch;
 	while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) {
 		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
 			break;
 	}
-
+	
 	dest[dest_off] = '\0';
 }
@@ -571,27 +570,84 @@
  * have to be null-terminated.
  *
- * @param dest   Destination buffer.
+ * @param dest  Destination buffer.
  * @param count Size of the destination buffer (must be > 0).
  * @param src   Source string.
- * @param n	Maximum number of bytes to read from @a src.
+ * @param n     Maximum number of bytes to read from @a src.
+ *
  */
 void str_ncpy(char *dest, size_t size, const char *src, size_t n)
 {
-	wchar_t ch;
-	size_t src_off;
-	size_t dest_off;
-
 	/* There must be space for a null terminator in the buffer. */
 	ASSERT(size > 0);
 	
-	src_off = 0;
-	dest_off = 0;
-
+	size_t src_off = 0;
+	size_t dest_off = 0;
+	
+	wchar_t ch;
 	while ((ch = str_decode(src, &src_off, n)) != 0) {
 		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
 			break;
 	}
-
+	
 	dest[dest_off] = '\0';
+}
+
+/** Duplicate string.
+ *
+ * Allocate a new string and copy characters from the source
+ * string into it. The duplicate string is allocated via sleeping
+ * malloc(), thus this function can sleep in no memory conditions.
+ *
+ * The allocation cannot fail and the return value is always
+ * a valid pointer. The duplicate string is always a well-formed
+ * null-terminated UTF-8 string, but it can differ from the source
+ * string on the byte level.
+ *
+ * @param src Source string.
+ *
+ * @return Duplicate string.
+ *
+ */
+char *str_dup(const char *src)
+{
+	size_t size = str_size(src) + 1;
+	char *dest = malloc(size, 0);
+	ASSERT(dest);
+	
+	str_cpy(dest, size, src);
+	return dest;
+}
+
+/** Duplicate string with size limit.
+ *
+ * Allocate a new string and copy up to @max_size bytes from the source
+ * string into it. The duplicate string is allocated via sleeping
+ * malloc(), thus this function can sleep in no memory conditions.
+ * No more than @max_size + 1 bytes is allocated, but if the size
+ * occupied by the source string is smaller than @max_size + 1,
+ * less is allocated.
+ *
+ * The allocation cannot fail and the return value is always
+ * a valid pointer. The duplicate string is always a well-formed
+ * null-terminated UTF-8 string, but it can differ from the source
+ * string on the byte level.
+ *
+ * @param src Source string.
+ * @param n   Maximum number of bytes to duplicate.
+ *
+ * @return Duplicate string.
+ *
+ */
+char *str_ndup(const char *src, size_t n)
+{
+	size_t size = str_size(src);
+	if (size > n)
+		size = n;
+	
+	char *dest = malloc(size + 1, 0);
+	ASSERT(dest);
+	
+	str_ncpy(dest, size + 1, src, size);
+	return dest;
 }
 
@@ -705,4 +761,187 @@
 }
 
+/** Convert string to uint64_t (internal variant).
+ *
+ * @param nptr   Pointer to string.
+ * @param endptr Pointer to the first invalid character is stored here.
+ * @param base   Zero or number between 2 and 36 inclusive.
+ * @param neg    Indication of unary minus is stored here.
+ * @apram result Result of the conversion.
+ *
+ * @return EOK if conversion was successful.
+ *
+ */
+static int str_uint(const char *nptr, char **endptr, unsigned int base,
+    bool *neg, uint64_t *result)
+{
+	ASSERT(endptr != NULL);
+	ASSERT(neg != NULL);
+	ASSERT(result != NULL);
+	
+	*neg = false;
+	const char *str = nptr;
+	
+	/* Ignore leading whitespace */
+	while (isspace(*str))
+		str++;
+	
+	if (*str == '-') {
+		*neg = true;
+		str++;
+	} else if (*str == '+')
+		str++;
+	
+	if (base == 0) {
+		/* Decode base if not specified */
+		base = 10;
+		
+		if (*str == '0') {
+			base = 8;
+			str++;
+			
+			switch (*str) {
+			case 'b':
+			case 'B':
+				base = 2;
+				str++;
+				break;
+			case 'o':
+			case 'O':
+				base = 8;
+				str++;
+				break;
+			case 'd':
+			case 'D':
+			case 't':
+			case 'T':
+				base = 10;
+				str++;
+				break;
+			case 'x':
+			case 'X':
+				base = 16;
+				str++;
+				break;
+			}
+		}
+	} else {
+		/* Check base range */
+		if ((base < 2) || (base > 36)) {
+			*endptr = (char *) str;
+			return EINVAL;
+		}
+	}
+	
+	*result = 0;
+	const char *startstr = str;
+	
+	while (*str != 0) {
+		unsigned int digit;
+		
+		if ((*str >= 'a') && (*str <= 'z'))
+			digit = *str - 'a' + 10;
+		else if ((*str >= 'A') && (*str <= 'Z'))
+			digit = *str - 'A' + 10;
+		else if ((*str >= '0') && (*str <= '9'))
+			digit = *str - '0';
+		else
+			break;
+		
+		if (digit >= base)
+			break;
+		
+		uint64_t prev = *result;
+		*result = (*result) * base + digit;
+		
+		if (*result < prev) {
+			/* Overflow */
+			*endptr = (char *) str;
+			return EOVERFLOW;
+		}
+		
+		str++;
+	}
+	
+	if (str == startstr) {
+		/*
+		 * No digits were decoded => first invalid character is
+		 * the first character of the string.
+		 */
+		str = nptr;
+	}
+	
+	*endptr = (char *) str;
+	
+	if (str == nptr)
+		return EINVAL;
+	
+	return EOK;
+}
+
+/** Convert string to uint64_t.
+ *
+ * @param nptr   Pointer to string.
+ * @param endptr If not NULL, pointer to the first invalid character
+ *               is stored here.
+ * @param base   Zero or number between 2 and 36 inclusive.
+ * @param strict Do not allow any trailing characters.
+ * @apram result Result of the conversion.
+ *
+ * @return EOK if conversion was successful.
+ *
+ */
+int str_uint64(const char *nptr, char **endptr, unsigned int base,
+    bool strict, uint64_t *result)
+{
+	ASSERT(result != NULL);
+	
+	bool neg;
+	char *lendptr;
+	int ret = str_uint(nptr, &lendptr, base, &neg, result);
+	
+	if (endptr != NULL)
+		*endptr = (char *) lendptr;
+	
+	if (ret != EOK)
+		return ret;
+	
+	/* Do not allow negative values */
+	if (neg)
+		return EINVAL;
+	
+	/* Check whether we are at the end of
+	   the string in strict mode */
+	if ((strict) && (*lendptr != 0))
+		return EINVAL;
+	
+	return EOK;
+}
+
+void order_suffix(const uint64_t val, uint64_t *rv, char *suffix)
+{
+	if (val > 10000000000000000000ULL) {
+		*rv = val / 1000000000000000000ULL;
+		*suffix = 'Z';
+	} else if (val > 1000000000000000000ULL) {
+		*rv = val / 1000000000000000ULL;
+		*suffix = 'E';
+	} else if (val > 1000000000000000ULL) {
+		*rv = val / 1000000000000ULL;
+		*suffix = 'T';
+	} else if (val > 1000000000000ULL) {
+		*rv = val / 1000000000ULL;
+		*suffix = 'G';
+	} else if (val > 1000000000ULL) {
+		*rv = val / 1000000ULL;
+		*suffix = 'M';
+	} else if (val > 1000000ULL) {
+		*rv = val / 1000ULL;
+		*suffix = 'k';
+	} else {
+		*rv = val;
+		*suffix = ' ';
+	}
+}
+
 /** @}
  */
Index: kernel/generic/src/main/kinit.c
===================================================================
--- kernel/generic/src/main/kinit.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/main/kinit.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -67,4 +67,5 @@
 #include <debug.h>
 #include <str.h>
+#include <sysinfo/stats.h>
 
 #ifdef CONFIG_SMP
@@ -122,4 +123,5 @@
 		} else
 			panic("Unable to create kmp thread.");
+		
 		thread_join(thread);
 		thread_detach(thread);
@@ -149,4 +151,11 @@
 	 */
 	arch_post_smp_init();
+	
+	/* Start thread computing system load */
+	thread = thread_create(kload, NULL, TASK, 0, "kload", false);
+	if (thread != NULL)
+		thread_ready(thread);
+	else
+		printf("Unable to create kload thread\n");
 	
 #ifdef CONFIG_KCONSOLE
Index: kernel/generic/src/main/main.c
===================================================================
--- kernel/generic/src/main/main.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/main/main.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -84,4 +84,6 @@
 #include <main/main.h>
 #include <ipc/event.h>
+#include <sysinfo/sysinfo.h>
+#include <sysinfo/stats.h>
 
 /** Global configuration structure. */
@@ -209,4 +211,5 @@
 	/* Initialize at least 1 memory segment big enough for slab to work. */
 	LOG_EXEC(slab_cache_init());
+	LOG_EXEC(sysinfo_init());
 	LOG_EXEC(btree_init());
 	LOG_EXEC(as_init());
@@ -223,6 +226,6 @@
 	
 	printf("Detected %" PRIs " CPU(s), %" PRIu64" MiB free memory\n",
-	    config.cpu_count, SIZE2MB(zone_total_size()));
-	
+	    config.cpu_count, SIZE2MB(zones_total_size()));
+
 	LOG_EXEC(cpu_init());
 	
@@ -247,4 +250,5 @@
 	LOG_EXEC(event_init());
 	LOG_EXEC(klog_init());
+	LOG_EXEC(stats_init());
 	
 	/*
Index: kernel/generic/src/main/version.c
===================================================================
--- kernel/generic/src/main/version.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/main/version.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -59,5 +59,5 @@
 {
 	printf("%s, release %s (%s)%s\nBuilt%s for %s\n%s\n",
-		project, release, name, revision, timestamp, arch, copyright);
+	    project, release, name, revision, timestamp, arch, copyright);
 }
 
Index: kernel/generic/src/mm/frame.c
===================================================================
--- kernel/generic/src/mm/frame.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/mm/frame.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -1202,5 +1202,5 @@
 
 /** Return total size of all zones. */
-uint64_t zone_total_size(void)
+uint64_t zones_total_size(void)
 {
 	ipl_t ipl = interrupts_disable();
@@ -1218,6 +1218,37 @@
 }
 
+void zones_stats(uint64_t *total, uint64_t *unavail, uint64_t *busy,
+    uint64_t *free)
+{
+	ASSERT(total != NULL);
+	ASSERT(unavail != NULL);
+	ASSERT(busy != NULL);
+	ASSERT(free != NULL);
+	
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&zones.lock);
+	
+	*total = 0;
+	*unavail = 0;
+	*busy = 0;
+	*free = 0;
+	
+	size_t i;
+	for (i = 0; i < zones.count; i++) {
+		*total += (uint64_t) FRAMES2SIZE(zones.info[i].count);
+		
+		if (zone_flags_available(zones.info[i].flags)) {
+			*busy += (uint64_t) FRAMES2SIZE(zones.info[i].busy_count);
+			*free += (uint64_t) FRAMES2SIZE(zones.info[i].free_count);
+		} else
+			*unavail += (uint64_t) FRAMES2SIZE(zones.info[i].count);
+	}
+	
+	spinlock_unlock(&zones.lock);
+	interrupts_restore(ipl);
+}
+
 /** Prints list of zones. */
-void zone_print_list(void)
+void zones_print_list(void)
 {
 #ifdef __32_BITS__
Index: kernel/generic/src/printf/printf.c
===================================================================
--- kernel/generic/src/printf/printf.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/printf/printf.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -34,4 +34,5 @@
 
 #include <print.h>
+#include <stdarg.h>
 
 int printf(const char *fmt, ...)
Index: kernel/generic/src/printf/printf_core.c
===================================================================
--- kernel/generic/src/printf/printf_core.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/printf/printf_core.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -46,16 +46,23 @@
 /** show prefixes 0x or 0 */
 #define __PRINTF_FLAG_PREFIX       0x00000001
+
 /** signed / unsigned number */
 #define __PRINTF_FLAG_SIGNED       0x00000002
+
 /** print leading zeroes */
 #define __PRINTF_FLAG_ZEROPADDED   0x00000004
+
 /** align to left */
 #define __PRINTF_FLAG_LEFTALIGNED  0x00000010
+
 /** always show + sign */
 #define __PRINTF_FLAG_SHOWPLUS     0x00000020
+
 /** print space instead of plus */
 #define __PRINTF_FLAG_SPACESIGN    0x00000040
+
 /** show big characters */
 #define __PRINTF_FLAG_BIGCHARS     0x00000080
+
 /** number has - sign */
 #define __PRINTF_FLAG_NEGATIVE     0x00000100
@@ -79,8 +86,8 @@
 } qualifier_t;
 
-static char nullstr[] = "(NULL)";
-static char digits_small[] = "0123456789abcdef";
-static char digits_big[] = "0123456789ABCDEF";
-static char invalch = U_SPECIAL;
+static const char *nullstr = "(NULL)";
+static const char *digits_small = "0123456789abcdef";
+static const char *digits_big = "0123456789ABCDEF";
+static const char invalch = U_SPECIAL;
 
 /** Print one or more characters without adding newline.
@@ -351,5 +358,5 @@
     uint32_t flags, printf_spec_t *ps)
 {
-	char *digits;
+	const char *digits;
 	if (flags & __PRINTF_FLAG_BIGCHARS)
 		digits = digits_big;
Index: kernel/generic/src/proc/scheduler.c
===================================================================
--- kernel/generic/src/proc/scheduler.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/proc/scheduler.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -202,4 +202,7 @@
 		 */
 
+		 spinlock_lock(&CPU->lock);
+		 CPU->idle = true;
+		 spinlock_unlock(&CPU->lock);
 		 cpu_sleep();
 		 goto loop;
@@ -313,6 +316,6 @@
 		spinlock_lock(&THREAD->lock);
 		
-		/* Update thread accounting */
-		THREAD->cycles += get_cycle() - THREAD->last_cycle;
+		/* Update thread kernel accounting */
+		THREAD->kcycles += get_cycle() - THREAD->last_cycle;
 		
 #ifndef CONFIG_FPU_LAZY
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/proc/task.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief	Task management.
+ * @brief Task management.
  */
 
@@ -66,4 +66,5 @@
  * The task is guaranteed to exist after it was found in the tasks_tree as
  * long as:
+ *
  * @li the tasks_lock is held,
  * @li the task's lock is held when task's lock is acquired before releasing
@@ -99,5 +100,5 @@
 	task_t *t = avltree_get_instance(node, task_t, tasks_tree_node);
 	unsigned *cnt = (unsigned *) arg;
-
+	
 	if (t != TASK) {
 		(*cnt)++;
@@ -107,6 +108,7 @@
 		task_kill_internal(t);
 	}
-
-	return true;	/* continue the walk */
+	
+	/* Continue the walk */
+	return true;
 }
 
@@ -115,5 +117,5 @@
 {
 	unsigned tasks_left;
-
+	
 	do { /* Repeat until there are any tasks except TASK */
 		/* Messing with task structures, avoid deadlock */
@@ -138,19 +140,19 @@
 	task_t *ta = obj;
 	int i;
-
+	
 	atomic_set(&ta->refcount, 0);
 	atomic_set(&ta->lifecount, 0);
 	atomic_set(&ta->active_calls, 0);
-
+	
 	spinlock_initialize(&ta->lock, "task_ta_lock");
 	mutex_initialize(&ta->futexes_lock, MUTEX_PASSIVE);
-
+	
 	list_initialize(&ta->th_head);
 	list_initialize(&ta->sync_box_head);
-
+	
 	ipc_answerbox_init(&ta->answerbox, ta);
 	for (i = 0; i < IPC_MAX_PHONES; i++)
 		ipc_phone_init(&ta->phones[i]);
-
+	
 #ifdef CONFIG_UDEBUG
 	/* Init kbox stuff */
@@ -159,5 +161,5 @@
 	mutex_initialize(&ta->kb.cleanup_lock, MUTEX_PASSIVE);
 #endif
-
+	
 	return 0;
 }
@@ -165,8 +167,8 @@
 /** Create new task with no threads.
  *
- * @param as		Task's address space.
- * @param name		Symbolic name (a copy is made).
- *
- * @return		New task's structure.
+ * @param as   Task's address space.
+ * @param name Symbolic name (a copy is made).
+ *
+ * @return New task's structure.
  *
  */
@@ -181,21 +183,29 @@
 	memcpy(ta->name, name, TASK_NAME_BUFLEN);
 	ta->name[TASK_NAME_BUFLEN - 1] = 0;
-
+	
 	ta->context = CONTEXT;
 	ta->capabilities = 0;
-	ta->cycles = 0;
+	ta->ucycles = 0;
+	ta->kcycles = 0;
+
+	ta->ipc_info.call_sent = 0;
+	ta->ipc_info.call_recieved = 0;
+	ta->ipc_info.answer_sent = 0;
+	ta->ipc_info.answer_recieved = 0;
+	ta->ipc_info.irq_notif_recieved = 0;
+	ta->ipc_info.forwarded = 0;
 
 #ifdef CONFIG_UDEBUG
 	/* Init debugging stuff */
 	udebug_task_init(&ta->udebug);
-
+	
 	/* Init kbox stuff */
 	ta->kb.finished = false;
 #endif
-
+	
 	if ((ipc_phone_0) &&
 	    (context_check(ipc_phone_0->task->context, ta->context)))
 		ipc_phone_connect(&ta->phones[0], ipc_phone_0);
-
+	
 	btree_create(&ta->futexes);
 	
@@ -215,5 +225,6 @@
 /** Destroy task.
  *
- * @param t		Task to be destroyed.
+ * @param t Task to be destroyed.
+ *
  */
 void task_destroy(task_t *t)
@@ -225,15 +236,15 @@
 	avltree_delete(&tasks_tree, &t->tasks_tree_node);
 	spinlock_unlock(&tasks_lock);
-
+	
 	/*
 	 * Perform architecture specific task destruction.
 	 */
 	task_destroy_arch(t);
-
+	
 	/*
 	 * Free up dynamically allocated state.
 	 */
 	btree_destroy(&t->futexes);
-
+	
 	/*
 	 * Drop our reference to the address space.
@@ -248,8 +259,9 @@
 /** Syscall for reading task ID from userspace.
  *
- * @param		uspace_task_id userspace address of 8-byte buffer
- * 			where to store current task ID.
- *
- * @return		Zero on success or an error code from @ref errno.h.
+ * @param uspace_task_id Userspace address of 8-byte buffer
+ *                       where to store current task ID.
+ *
+ * @return Zero on success or an error code from @ref errno.h.
+ *
  */
 unative_t sys_task_get_id(task_id_t *uspace_task_id)
@@ -267,8 +279,9 @@
  * The name simplifies identifying the task in the task list.
  *
- * @param name	The new name for the task. (typically the same
- *		as the command used to execute it).
+ * @param name The new name for the task. (typically the same
+ *             as the command used to execute it).
  *
  * @return 0 on success or an error code from @ref errno.h.
+ *
  */
 unative_t sys_task_set_name(const char *uspace_name, size_t name_len)
@@ -276,17 +289,17 @@
 	int rc;
 	char namebuf[TASK_NAME_BUFLEN];
-
+	
 	/* Cap length of name and copy it from userspace. */
-
+	
 	if (name_len > TASK_NAME_BUFLEN - 1)
 		name_len = TASK_NAME_BUFLEN - 1;
-
+	
 	rc = copy_from_uspace(namebuf, uspace_name, name_len);
 	if (rc != 0)
 		return (unative_t) rc;
-
+	
 	namebuf[name_len] = '\0';
 	str_cpy(TASK->name, TASK_NAME_BUFLEN, namebuf);
-
+	
 	return EOK;
 }
@@ -297,15 +310,17 @@
  * interrupts must be disabled.
  *
- * @param id		Task ID.
- *
- * @return		Task structure address or NULL if there is no such task
- * 			ID.
- */
-task_t *task_find_by_id(task_id_t id) { avltree_node_t *node;
-	
-	node = avltree_search(&tasks_tree, (avltree_key_t) id);
-
+ * @param id Task ID.
+ *
+ * @return Task structure address or NULL if there is no such task ID.
+ *
+ */
+task_t *task_find_by_id(task_id_t id)
+{
+	avltree_node_t *node =
+	    avltree_search(&tasks_tree, (avltree_key_t) id);
+	
 	if (node)
 		return avltree_get_instance(node, task_t, tasks_tree_node); 
+	
 	return NULL;
 }
@@ -316,13 +331,14 @@
  * already disabled.
  *
- * @param t		Pointer to thread.
- *
- * @return		Number of cycles used by the task and all its threads
- * 			so far.
- */
-uint64_t task_get_accounting(task_t *t)
-{
-	/* Accumulated value of task */
-	uint64_t ret = t->cycles;
+ * @param t       Pointer to thread.
+ * @param ucycles Out pointer to sum of all user cycles.
+ * @param kcycles Out pointer to sum of all kernel cycles.
+ *
+ */
+void task_get_accounting(task_t *t, uint64_t *ucycles, uint64_t *kcycles)
+{
+	/* Accumulated values of task */
+	uint64_t uret = t->ucycles;
+	uint64_t kret = t->kcycles;
 	
 	/* Current values of threads */
@@ -336,12 +352,14 @@
 			if (thr == THREAD) {
 				/* Update accounting of current thread */
-				thread_update_accounting();
+				thread_update_accounting(false);
 			} 
-			ret += thr->cycles;
+			uret += thr->ucycles;
+			kret += thr->kcycles;
 		}
 		spinlock_unlock(&thr->lock);
 	}
 	
-	return ret;
+	*ucycles = uret;
+	*kcycles = kret;
 }
 
@@ -349,5 +367,5 @@
 {
 	link_t *cur;
-
+	
 	/*
 	 * Interrupt all threads.
@@ -377,7 +395,8 @@
  * It signals all the task's threads to bail it out.
  *
- * @param id		ID of the task to be killed.
- *
- * @return		Zero on success or an error code from errno.h.
+ * @param id ID of the task to be killed.
+ *
+ * @return Zero on success or an error code from errno.h.
+ *
  */
 int task_kill(task_id_t id)
@@ -406,23 +425,28 @@
 	task_t *t = avltree_get_instance(node, task_t, tasks_tree_node);
 	int j;
-		
+	
 	spinlock_lock(&t->lock);
-			
-	uint64_t cycles;
-	char suffix;
-	order(task_get_accounting(t), &cycles, &suffix);
-
+	
+	uint64_t ucycles;
+	uint64_t kcycles;
+	char usuffix, ksuffix;
+	task_get_accounting(t, &ucycles, &kcycles);
+	order_suffix(ucycles, &ucycles, &usuffix);
+	order_suffix(kcycles, &kcycles, &ksuffix);
+	
 #ifdef __32_BITS__	
-	printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %10p %10p %9" PRIu64
-	    "%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as, cycles,
-	    suffix, atomic_get(&t->refcount), atomic_get(&t->active_calls));
-#endif
-
+	printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %10p %10p %9" PRIu64 "%c %9"
+		PRIu64 "%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as,
+		ucycles, usuffix, kcycles, ksuffix, atomic_get(&t->refcount),
+		atomic_get(&t->active_calls));
+#endif
+	
 #ifdef __64_BITS__
-	printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %18p %18p %9" PRIu64
-	    "%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as, cycles,
-	    suffix, atomic_get(&t->refcount), atomic_get(&t->active_calls));
-#endif
-
+	printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %18p %18p %9" PRIu64 "%c %9"
+		PRIu64 "%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as,
+		ucycles, usuffix, kcycles, ksuffix, atomic_get(&t->refcount),
+		atomic_get(&t->active_calls));
+#endif
+	
 	for (j = 0; j < IPC_MAX_PHONES; j++) {
 		if (t->phones[j].callee)
@@ -430,5 +454,5 @@
 	}
 	printf("\n");
-			
+	
 	spinlock_unlock(&t->lock);
 	return true;
@@ -443,21 +467,21 @@
 	ipl = interrupts_disable();
 	spinlock_lock(&tasks_lock);
-
-#ifdef __32_BITS__	
-	printf("taskid name         ctx address    as         "
-	    "cycles     threads calls  callee\n");
-	printf("------ ------------ --- ---------- ---------- "
-	    "---------- ------- ------ ------>\n");
-#endif
-
+	
+#ifdef __32_BITS__
+	printf("taskid name         ctx address    as        "
+	    " ucycles    kcycles    threads calls  callee\n");
+	printf("------ ------------ --- ---------- ----------"
+	    " ---------- ---------- ------- ------ ------>\n");
+#endif
+	
 #ifdef __64_BITS__
-	printf("taskid name         ctx address            as                 "
-	    "cycles     threads calls  callee\n");
-	printf("------ ------------ --- ------------------ ------------------ "
-	    "---------- ------- ------ ------>\n");
-#endif
-
+	printf("taskid name         ctx address            as                "
+	    " ucycles    kcycles    threads calls  callee\n");
+	printf("------ ------------ --- ------------------ ------------------"
+	    " ---------- ---------- ---------- ------- ------ ------>\n");
+#endif
+	
 	avltree_walk(&tasks_tree, task_print_walker, NULL);
-
+	
 	spinlock_unlock(&tasks_lock);
 	interrupts_restore(ipl);
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/proc/thread.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -50,5 +50,5 @@
 #include <synch/rwlock.h>
 #include <cpu.h>
-#include <func.h>
+#include <str.h>
 #include <context.h>
 #include <adt/avl.h>
@@ -84,5 +84,10 @@
 	"Exiting",
 	"Lingering"
-}; 
+};
+
+typedef struct {
+	thread_id_t thread_id;
+	thread_t *thread;
+} thread_iterator_t;
 
 /** Lock protecting the threads_tree AVL tree.
@@ -132,11 +137,15 @@
 	spinlock_lock(&THREAD->lock);
 	if (!THREAD->uncounted) {
-		thread_update_accounting();
-		uint64_t cycles = THREAD->cycles;
-		THREAD->cycles = 0;
+		thread_update_accounting(true);
+		uint64_t ucycles = THREAD->ucycles;
+		THREAD->ucycles = 0;
+		uint64_t kcycles = THREAD->kcycles;
+		THREAD->kcycles = 0;
+
 		spinlock_unlock(&THREAD->lock);
 		
 		spinlock_lock(&TASK->lock);
-		TASK->cycles += cycles;
+		TASK->ucycles += ucycles;
+		TASK->kcycles += kcycles;
 		spinlock_unlock(&TASK->lock);
 	} else
@@ -323,5 +332,6 @@
 	t->thread_arg = arg;
 	t->ticks = -1;
-	t->cycles = 0;
+	t->ucycles = 0;
+	t->kcycles = 0;
 	t->uncounted = uncounted;
 	t->priority = -1;		/* start in rq[0] */
@@ -614,18 +624,21 @@
 	thread_t *t = avltree_get_instance(node, thread_t, threads_tree_node);
 	
-	uint64_t cycles;
-	char suffix;
-	order(t->cycles, &cycles, &suffix);
+	uint64_t ucycles, kcycles;
+	char usuffix, ksuffix;
+	order_suffix(t->ucycles, &ucycles, &usuffix);
+	order_suffix(t->kcycles, &kcycles, &ksuffix);
 
 #ifdef __32_BITS__
-	printf("%-6" PRIu64" %-10s %10p %-8s %10p %-3" PRIu32 " %10p %10p %9" PRIu64 "%c ",
-	    t->tid, t->name, t, thread_states[t->state], t->task,
-    	t->task->context, t->thread_code, t->kstack, cycles, suffix);
+	printf("%-6" PRIu64" %-10s %10p %-8s %10p %-3" PRIu32 " %10p %10p %9"
+		PRIu64 "%c %9" PRIu64 "%c ", t->tid, t->name, t,
+		thread_states[t->state], t->task, t->task->context, t->thread_code,
+		t->kstack, ucycles, usuffix, kcycles, ksuffix);
 #endif
 
 #ifdef __64_BITS__
-	printf("%-6" PRIu64" %-10s %18p %-8s %18p %-3" PRIu32 " %18p %18p %9" PRIu64 "%c ",
-	    t->tid, t->name, t, thread_states[t->state], t->task,
-    	t->task->context, t->thread_code, t->kstack, cycles, suffix);
+	printf("%-6" PRIu64" %-10s %18p %-8s %18p %-3" PRIu32 " %18p %18p %9"
+		PRIu64 "%c %9" PRIu64 "%c ", t->tid, t->name, t,
+		thread_states[t->state], t->task, t->task->context, t->thread_code,
+		t->kstack, ucycles, usuffix, kcycles, ksuffix);
 #endif
 			
@@ -661,8 +674,8 @@
 #ifdef __32_BITS__	
 	printf("tid    name       address    state    task       "
-		"ctx code       stack      cycles     cpu  "
+		"ctx code       stack      ucycles    kcycles    cpu  "
 		"waitqueue\n");
 	printf("------ ---------- ---------- -------- ---------- "
-		"--- ---------- ---------- ---------- ---- "
+		"--- ---------- ---------- ---------- ---------- ---- "
 		"----------\n");
 #endif
@@ -670,8 +683,8 @@
 #ifdef __64_BITS__
 	printf("tid    name       address            state    task               "
-		"ctx code               stack              cycles     cpu  "
+		"ctx code               stack              ucycles    kcycles    cpu  "
 		"waitqueue\n");
 	printf("------ ---------- ------------------ -------- ------------------ "
-		"--- ------------------ ------------------ ---------- ---- "
+		"--- ------------------ ------------------ ---------- ---------- ---- "
 		"------------------\n");
 #endif
@@ -706,11 +719,53 @@
  * interrupts must be already disabled.
  *
- */
-void thread_update_accounting(void)
+ * @param user	True to update user accounting, false for kernel.
+ */
+void thread_update_accounting(bool user)
 {
 	uint64_t time = get_cycle();
-	THREAD->cycles += time - THREAD->last_cycle;
+	if (user) {
+		THREAD->ucycles += time - THREAD->last_cycle;
+	} else {
+		THREAD->kcycles += time - THREAD->last_cycle;
+	}
 	THREAD->last_cycle = time;
 }
+
+static bool thread_search_walker(avltree_node_t *node, void *arg)
+{
+	thread_t *thread =
+	    (thread_t *) avltree_get_instance(node, thread_t, threads_tree_node);
+	thread_iterator_t *iterator = (thread_iterator_t *) arg;
+	
+	if (thread->tid == iterator->thread_id) {
+		iterator->thread = thread;
+		return false;
+	}
+	
+	return true;
+}
+
+/** Find thread structure corresponding to thread ID.
+ *
+ * The threads_lock must be already held by the caller of this function and
+ * interrupts must be disabled.
+ *
+ * @param id Thread ID.
+ *
+ * @return Thread structure address or NULL if there is no such thread ID.
+ *
+ */
+thread_t *thread_find_by_id(thread_id_t thread_id)
+{
+	thread_iterator_t iterator;
+	
+	iterator.thread_id = thread_id;
+	iterator.thread = NULL;
+	
+	avltree_walk(&threads_tree, thread_search_walker, (void *) &iterator);
+	
+	return iterator.thread;
+}
+
 
 /** Process syscall to create new thread.
Index: kernel/generic/src/synch/waitq.c
===================================================================
--- kernel/generic/src/synch/waitq.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/synch/waitq.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -54,4 +54,5 @@
 #include <context.h>
 #include <adt/list.h>
+#include <arch/cycle.h>
 
 static void waitq_sleep_timed_out(void *data);
@@ -373,4 +374,5 @@
 		if (!context_save(&THREAD->sleep_interruption_context)) {
 			/* Short emulation of scheduler() return code. */
+			THREAD->last_cycle = get_cycle();
 			spinlock_unlock(&THREAD->lock);
 			return ESYNCH_INTERRUPTED;
@@ -385,4 +387,5 @@
 		if (!context_save(&THREAD->sleep_timeout_context)) {
 			/* Short emulation of scheduler() return code. */
+			THREAD->last_cycle = get_cycle();
 			spinlock_unlock(&THREAD->lock);
 			return ESYNCH_TIMEOUT;
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/syscall/syscall.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -61,4 +61,7 @@
 	unative_t rc;
 
+	/* Do userpace accounting */
+	thread_update_accounting(true);
+
 #ifdef CONFIG_UDEBUG
 	/*
@@ -95,4 +98,7 @@
 	}
 #endif
+
+	/* Do kernel accounting */
+	thread_update_accounting(false);
 	
 	return rc;
@@ -138,5 +144,5 @@
 	(syshandler_t) sys_ipc_register_irq,
 	(syshandler_t) sys_ipc_unregister_irq,
-
+	
 	/* Event notification syscalls. */
 	(syshandler_t) sys_event_subscribe,
@@ -153,6 +159,8 @@
 	
 	/* Sysinfo syscalls */
-	(syshandler_t) sys_sysinfo_valid,
-	(syshandler_t) sys_sysinfo_value,
+	(syshandler_t) sys_sysinfo_get_tag,
+	(syshandler_t) sys_sysinfo_get_value,
+	(syshandler_t) sys_sysinfo_get_data_size,
+	(syshandler_t) sys_sysinfo_get_data,
 	
 	/* Debug calls */
Index: kernel/generic/src/sysinfo/stats.c
===================================================================
--- kernel/generic/src/sysinfo/stats.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ kernel/generic/src/sysinfo/stats.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,674 @@
+/*
+ * Copyright (c) 2010 Stanislav Kozina
+ * Copyright (c) 2010 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 generic
+ * @{
+ */
+/** @file
+ */
+
+#include <typedefs.h>
+#include <sysinfo/abi.h>
+#include <sysinfo/stats.h>
+#include <sysinfo/sysinfo.h>
+#include <time/clock.h>
+#include <mm/frame.h>
+#include <proc/task.h>
+#include <proc/thread.h>
+#include <str.h>
+#include <errno.h>
+#include <cpu.h>
+#include <arch.h>
+
+/** Bits of fixed-point precision for load */
+#define LOAD_FIXED_SHIFT  11
+
+/** 1.0 as fixed-point for load */
+#define LOAD_FIXED_1  (1 << LOAD_FIXED_SHIFT)
+
+/** Compute load in 5 second intervals */
+#define LOAD_INTERVAL  5
+
+/** Fixed-point representation of
+ *
+ * 1 / exp(5 sec / 1 min)
+ * 1 / exp(5 sec / 5 min)
+ * 1 / exp(5 sec / 15 min)
+ *
+ */
+static load_t load_exp[LOAD_STEPS] = {1884, 2014, 2037};
+
+/** Running average of the number of ready threads */
+static load_t avenrdy[LOAD_STEPS] = {0, 0, 0};
+
+/** Load calculation spinlock */
+SPINLOCK_STATIC_INITIALIZE_NAME(load_lock, "load_lock");
+
+/** Get system uptime
+ *
+ * @param item Sysinfo item (unused).
+ *
+ * @return System uptime (in secords).
+ *
+ */
+static unative_t get_stats_uptime(struct sysinfo_item *item)
+{
+	/* This doesn't have to be very accurate */
+	return uptime->seconds1;
+}
+
+/** Get statistics of all CPUs
+ *
+ * @param item    Sysinfo item (unused).
+ * @param size    Size of the returned data.
+ * @param dry_run Do not get the data, just calculate the size.
+ *
+ * @return Data containing several stats_cpu_t structures.
+ *         If the return value is not NULL, it should be freed
+ *         in the context of the sysinfo request.
+ */
+static void *get_stats_cpus(struct sysinfo_item *item, size_t *size,
+    bool dry_run)
+{
+	*size = sizeof(stats_cpu_t) * config.cpu_count;
+	if (dry_run)
+		return NULL;
+	
+	/* Assumption: config.cpu_count is constant */
+	stats_cpu_t *stats_cpus = (stats_cpu_t *) malloc(*size, FRAME_ATOMIC);
+	if (stats_cpus == NULL) {
+		*size = 0;
+		return NULL;
+	}
+	
+	/* Each CPU structure is locked separatelly */
+	ipl_t ipl = interrupts_disable();
+	
+	size_t i;
+	for (i = 0; i < config.cpu_count; i++) {
+		spinlock_lock(&cpus[i].lock);
+		
+		stats_cpus[i].id = cpus[i].id;
+		stats_cpus[i].active = cpus[i].active;
+		stats_cpus[i].frequency_mhz = cpus[i].frequency_mhz;
+		stats_cpus[i].busy_ticks = cpus[i].busy_ticks;
+		stats_cpus[i].idle_ticks = cpus[i].idle_ticks;
+		
+		spinlock_unlock(&cpus[i].lock);
+	}
+	
+	interrupts_restore(ipl);
+	
+	return ((void *) stats_cpus);
+}
+
+/** Count number of nodes in an AVL tree
+ *
+ * AVL tree walker for counting nodes.
+ *
+ * @param node AVL tree node (unused).
+ * @param arg  Pointer to the counter (size_t).
+ *
+ * @param Always true (continue the walk).
+ *
+ */
+static bool avl_count_walker(avltree_node_t *node, void *arg)
+{
+	size_t *count = (size_t *) arg;
+	(*count)++;
+	
+	return true;
+}
+
+/** Get the size of a virtual address space
+ *
+ * @param as Address space.
+ *
+ * @return Size of the mapped virtual address space (bytes).
+ *
+ */
+static size_t get_task_virtmem(as_t *as)
+{
+	mutex_lock(&as->lock);
+	
+	size_t result = 0;
+	
+	/* Walk the B+ tree and count pages */
+	link_t *cur;
+	for (cur = as->as_area_btree.leaf_head.next;
+	    cur != &as->as_area_btree.leaf_head; cur = cur->next) {
+		btree_node_t *node =
+		    list_get_instance(cur, btree_node_t, leaf_link);
+		
+		unsigned int i;
+		for (i = 0; i < node->keys; i++) {
+			as_area_t *area = node->value[i];
+			
+			mutex_lock(&area->lock);
+			result += area->pages;
+			mutex_unlock(&area->lock);
+		}
+	}
+	
+	mutex_unlock(&as->lock);
+	
+	return result * PAGE_SIZE;
+}
+
+/* Produce task statistics
+ *
+ * Summarize task information into task statistics.
+ * Task lock should be held and interrupts disabled
+ * before executing this function.
+ *
+ * @param task       Task.
+ * @param stats_task Task statistics.
+ *
+ */
+static void produce_stats_task(task_t *task, stats_task_t *stats_task)
+{
+	stats_task->task_id = task->taskid;
+	str_cpy(stats_task->name, TASK_NAME_BUFLEN, task->name);
+	stats_task->virtmem = get_task_virtmem(task->as);
+	stats_task->threads = atomic_get(&task->refcount);
+	task_get_accounting(task, &(stats_task->ucycles),
+	    &(stats_task->kcycles));
+	stats_task->ipc_info = task->ipc_info;
+}
+
+/** Gather statistics of all tasks
+ *
+ * AVL task tree walker for gathering task statistics. Interrupts should
+ * be already disabled while walking the tree.
+ *
+ * @param node AVL task tree node.
+ * @param arg  Pointer to the iterator into the array of stats_task_t.
+ *
+ * @param Always true (continue the walk).
+ *
+ */
+static bool task_serialize_walker(avltree_node_t *node, void *arg)
+{
+	stats_task_t **iterator = (stats_task_t **) arg;
+	task_t *task = avltree_get_instance(node, task_t, tasks_tree_node);
+	
+	/* Interrupts are already disabled */
+	spinlock_lock(&(task->lock));
+	
+	/* Record the statistics and increment the iterator */
+	produce_stats_task(task, *iterator);
+	(*iterator)++;
+	
+	spinlock_unlock(&(task->lock));
+	
+	return true;
+}
+
+/** Get task statistics
+ *
+ * @param item    Sysinfo item (unused).
+ * @param size    Size of the returned data.
+ * @param dry_run Do not get the data, just calculate the size.
+ *
+ * @return Data containing several stats_task_t structures.
+ *         If the return value is not NULL, it should be freed
+ *         in the context of the sysinfo request.
+ */
+static void *get_stats_tasks(struct sysinfo_item *item, size_t *size,
+    bool dry_run)
+{
+	/* Messing with task structures, avoid deadlock */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&tasks_lock);
+	
+	/* First walk the task tree to count the tasks */
+	size_t count = 0;
+	avltree_walk(&tasks_tree, avl_count_walker, (void *) &count);
+	
+	if (count == 0) {
+		/* No tasks found (strange) */
+		spinlock_unlock(&tasks_lock);
+		interrupts_restore(ipl);
+		
+		*size = 0;
+		return NULL;
+	}
+	
+	*size = sizeof(stats_task_t) * count;
+	if (dry_run) {
+		spinlock_unlock(&tasks_lock);
+		interrupts_restore(ipl);
+		return NULL;
+	}
+	
+	stats_task_t *stats_tasks = (stats_task_t *) malloc(*size, FRAME_ATOMIC);
+	if (stats_tasks == NULL) {
+		/* No free space for allocation */
+		spinlock_unlock(&tasks_lock);
+		interrupts_restore(ipl);
+		
+		*size = 0;
+		return NULL;
+	}
+	
+	/* Walk tha task tree again to gather the statistics */
+	stats_task_t *iterator = stats_tasks;
+	avltree_walk(&tasks_tree, task_serialize_walker, (void *) &iterator);
+	
+	spinlock_unlock(&tasks_lock);
+	interrupts_restore(ipl);
+	
+	return ((void *) stats_tasks);
+}
+
+/* Produce thread statistics
+ *
+ * Summarize thread information into thread statistics.
+ * Thread lock should be held and interrupts disabled
+ * before executing this function.
+ *
+ * @param thread       Thread.
+ * @param stats_thread Thread statistics.
+ *
+ */
+static void produce_stats_thread(thread_t *thread, stats_thread_t *stats_thread)
+{
+	stats_thread->thread_id = thread->tid;
+	stats_thread->task_id = thread->task->taskid;
+	stats_thread->state = thread->state;
+	stats_thread->priority = thread->priority;
+	stats_thread->ucycles = thread->ucycles;
+	stats_thread->kcycles = thread->kcycles;
+	
+	if (thread->cpu != NULL) {
+		stats_thread->on_cpu = true;
+		stats_thread->cpu = thread->cpu->id;
+	} else
+		stats_thread->on_cpu = false;
+}
+
+/** Gather statistics of all threads
+ *
+ * AVL three tree walker for gathering thread statistics. Interrupts should
+ * be already disabled while walking the tree.
+ *
+ * @param node AVL thread tree node.
+ * @param arg  Pointer to the iterator into the array of thread statistics.
+ *
+ * @param Always true (continue the walk).
+ *
+ */
+static bool thread_serialize_walker(avltree_node_t *node, void *arg)
+{
+	stats_thread_t **iterator = (stats_thread_t **) arg;
+	thread_t *thread = avltree_get_instance(node, thread_t, threads_tree_node);
+	
+	/* Interrupts are already disabled */
+	spinlock_lock(&(thread->lock));
+	
+	/* Record the statistics and increment the iterator */
+	produce_stats_thread(thread, *iterator);
+	(*iterator)++;
+	
+	spinlock_unlock(&(thread->lock));
+	
+	return true;
+}
+
+/** Get thread statistics
+ *
+ * @param item    Sysinfo item (unused).
+ * @param size    Size of the returned data.
+ * @param dry_run Do not get the data, just calculate the size.
+ *
+ * @return Data containing several stats_task_t structures.
+ *         If the return value is not NULL, it should be freed
+ *         in the context of the sysinfo request.
+ */
+static void *get_stats_threads(struct sysinfo_item *item, size_t *size,
+    bool dry_run)
+{
+	/* Messing with threads structures, avoid deadlock */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&threads_lock);
+	
+	/* First walk the thread tree to count the threads */
+	size_t count = 0;
+	avltree_walk(&threads_tree, avl_count_walker, (void *) &count);
+	
+	if (count == 0) {
+		/* No threads found (strange) */
+		spinlock_unlock(&threads_lock);
+		interrupts_restore(ipl);
+		
+		*size = 0;
+		return NULL;
+	}
+	
+	*size = sizeof(stats_thread_t) * count;
+	if (dry_run) {
+		spinlock_unlock(&threads_lock);
+		interrupts_restore(ipl);
+		return NULL;
+	}
+	
+	stats_thread_t *stats_threads = (stats_thread_t *) malloc(*size, FRAME_ATOMIC);
+	if (stats_threads == NULL) {
+		/* No free space for allocation */
+		spinlock_unlock(&threads_lock);
+		interrupts_restore(ipl);
+		
+		*size = 0;
+		return NULL;
+	}
+	
+	/* Walk tha thread tree again to gather the statistics */
+	stats_thread_t *iterator = stats_threads;
+	avltree_walk(&threads_tree, thread_serialize_walker, (void *) &iterator);
+	
+	spinlock_unlock(&threads_lock);
+	interrupts_restore(ipl);
+	
+	return ((void *) stats_threads);
+}
+
+/** Get a single task statistics
+ *
+ * Get statistics of a given task. The task ID is passed
+ * as a string (current limitation of the sysinfo interface,
+ * but it is still reasonable for the given purpose).
+ *
+ * @param name    Task ID (string-encoded number).
+ * @param dry_run Do not get the data, just calculate the size.
+ *
+ * @return Sysinfo return holder. The type of the returned
+ *         data is either SYSINFO_VAL_UNDEFINED (unknown
+ *         task ID or memory allocation error) or
+ *         SYSINFO_VAL_FUNCTION_DATA (in that case the
+ *         generated data should be freed within the
+ *         sysinfo request context).
+ *
+ */
+static sysinfo_return_t get_stats_task(const char *name, bool dry_run)
+{
+	/* Initially no return value */
+	sysinfo_return_t ret;
+	ret.tag = SYSINFO_VAL_UNDEFINED;
+	
+	/* Parse the task ID */
+	task_id_t task_id;
+	if (str_uint64(name, NULL, 0, true, &task_id) != EOK)
+		return ret;
+	
+	/* Messing with task structures, avoid deadlock */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&tasks_lock);
+	
+	task_t *task = task_find_by_id(task_id);
+	if (task == NULL) {
+		/* No task with this ID */
+		spinlock_unlock(&tasks_lock);
+		interrupts_restore(ipl);
+		return ret;
+	}
+	
+	if (dry_run) {
+		ret.tag = SYSINFO_VAL_FUNCTION_DATA;
+		ret.data.data = NULL;
+		ret.data.size = sizeof(stats_task_t);
+		
+		spinlock_unlock(&tasks_lock);
+	} else {
+		/* Allocate stats_task_t structure */
+		stats_task_t *stats_task =
+		    (stats_task_t *) malloc(sizeof(stats_task_t), FRAME_ATOMIC);
+		if (stats_task == NULL) {
+			spinlock_unlock(&tasks_lock);
+			interrupts_restore(ipl);
+			return ret;
+		}
+		
+		/* Correct return value */
+		ret.tag = SYSINFO_VAL_FUNCTION_DATA;
+		ret.data.data = (void *) stats_task;
+		ret.data.size = sizeof(stats_task_t);
+	
+		/* Hand-over-hand locking */
+		spinlock_lock(&task->lock);
+		spinlock_unlock(&tasks_lock);
+		
+		produce_stats_task(task, stats_task);
+		
+		spinlock_unlock(&task->lock);
+	}
+	
+	interrupts_restore(ipl);
+	
+	return ret;
+}
+
+/** Get thread statistics
+ *
+ * Get statistics of a given thread. The thread ID is passed
+ * as a string (current limitation of the sysinfo interface,
+ * but it is still reasonable for the given purpose).
+ *
+ * @param name    Thread ID (string-encoded number).
+ * @param dry_run Do not get the data, just calculate the size.
+ *
+ * @return Sysinfo return holder. The type of the returned
+ *         data is either SYSINFO_VAL_UNDEFINED (unknown
+ *         thread ID or memory allocation error) or
+ *         SYSINFO_VAL_FUNCTION_DATA (in that case the
+ *         generated data should be freed within the
+ *         sysinfo request context).
+ *
+ */
+static sysinfo_return_t get_stats_thread(const char *name, bool dry_run)
+{
+	/* Initially no return value */
+	sysinfo_return_t ret;
+	ret.tag = SYSINFO_VAL_UNDEFINED;
+	
+	/* Parse the thread ID */
+	thread_id_t thread_id;
+	if (str_uint64(name, NULL, 0, true, &thread_id) != EOK)
+		return ret;
+	
+	/* Messing with threads structures, avoid deadlock */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&threads_lock);
+	
+	thread_t *thread = thread_find_by_id(thread_id);
+	if (thread == NULL) {
+		/* No thread with this ID */
+		spinlock_unlock(&threads_lock);
+		interrupts_restore(ipl);
+		return ret;
+	}
+	
+	if (dry_run) {
+		ret.tag = SYSINFO_VAL_FUNCTION_DATA;
+		ret.data.data = NULL;
+		ret.data.size = sizeof(stats_thread_t);
+		
+		spinlock_unlock(&threads_lock);
+	} else {
+		/* Allocate stats_thread_t structure */
+		stats_thread_t *stats_thread =
+		    (stats_thread_t *) malloc(sizeof(stats_thread_t), FRAME_ATOMIC);
+		if (stats_thread == NULL) {
+			spinlock_unlock(&threads_lock);
+			interrupts_restore(ipl);
+			return ret;
+		}
+		
+		/* Correct return value */
+		ret.tag = SYSINFO_VAL_FUNCTION_DATA;
+		ret.data.data = (void *) stats_thread;
+		ret.data.size = sizeof(stats_thread_t);
+		
+		/* Hand-over-hand locking */
+		spinlock_lock(&thread->lock);
+		spinlock_unlock(&threads_lock);
+		
+		produce_stats_thread(thread, stats_thread);
+		
+		spinlock_unlock(&thread->lock);
+	}
+	
+	interrupts_restore(ipl);
+	
+	return ret;
+}
+
+/** Get physical memory statistics
+ *
+ * @param item    Sysinfo item (unused).
+ * @param size    Size of the returned data.
+ * @param dry_run Do not get the data, just calculate the size.
+ *
+ * @return Data containing stats_physmem_t.
+ *         If the return value is not NULL, it should be freed
+ *         in the context of the sysinfo request.
+ */
+static void *get_stats_physmem(struct sysinfo_item *item, size_t *size,
+    bool dry_run)
+{
+	*size = sizeof(stats_physmem_t);
+	if (dry_run)
+		return NULL;
+	
+	stats_physmem_t *stats_physmem =
+	    (stats_physmem_t *) malloc(*size, FRAME_ATOMIC);
+	if (stats_physmem == NULL) {
+		*size = 0;
+		return NULL;
+	}
+	
+	zones_stats(&(stats_physmem->total), &(stats_physmem->unavail),
+	    &(stats_physmem->used), &(stats_physmem->free));
+	
+	return ((void *) stats_physmem);
+}
+
+/** Get system load
+ *
+ * @param item    Sysinfo item (unused).
+ * @param size    Size of the returned data.
+ * @param dry_run Do not get the data, just calculate the size.
+ *
+ * @return Data several load_t values.
+ *         If the return value is not NULL, it should be freed
+ *         in the context of the sysinfo request.
+ */
+static void *get_stats_load(struct sysinfo_item *item, size_t *size,
+    bool dry_run)
+{
+	*size = sizeof(load_t) * LOAD_STEPS;
+	if (dry_run)
+		return NULL;
+	
+	load_t *stats_load = (load_t *) malloc(*size, FRAME_ATOMIC);
+	if (stats_load == NULL) {
+		*size = 0;
+		return NULL;
+	}
+	
+	/* To always get consistent values acquire the spinlock */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&load_lock);
+	
+	unsigned int i;
+	for (i = 0; i < LOAD_STEPS; i++)
+		stats_load[i] = avenrdy[i] << LOAD_FIXED_SHIFT;
+	
+	spinlock_unlock(&load_lock);
+	interrupts_restore(ipl);
+	
+	return ((void *) stats_load);
+}
+
+/** Calculate load
+ *
+ */
+static inline load_t load_calc(load_t load, load_t exp, atomic_count_t ready)
+{
+	load *= exp;
+	load += (ready << LOAD_FIXED_SHIFT) * (LOAD_FIXED_1 - exp);
+	
+	return (load >> LOAD_FIXED_SHIFT);
+}
+
+/** Load computation thread.
+ *
+ * Compute system load every few seconds.
+ *
+ * @param arg Unused.
+ *
+ */
+void kload(void *arg)
+{
+	thread_detach(THREAD);
+	
+	while (true) {
+		atomic_count_t ready = atomic_get(&nrdy);
+		
+		/* Mutually exclude with get_stats_load() */
+		ipl_t ipl = interrupts_disable();
+		spinlock_lock(&load_lock);
+		
+		unsigned int i;
+		for (i = 0; i < LOAD_STEPS; i++)
+			avenrdy[i] = load_calc(avenrdy[i], load_exp[i], ready);
+		
+		spinlock_unlock(&load_lock);
+		interrupts_restore(ipl);
+		
+		thread_sleep(LOAD_INTERVAL);
+	}
+}
+
+/** Register sysinfo statistical items
+ *
+ */
+void stats_init(void)
+{
+	sysinfo_set_item_fn_val("system.uptime", NULL, get_stats_uptime);
+	sysinfo_set_item_fn_data("system.cpus", NULL, get_stats_cpus);
+	sysinfo_set_item_fn_data("system.physmem", NULL, get_stats_physmem);
+	sysinfo_set_item_fn_data("system.load", NULL, get_stats_load);
+	sysinfo_set_item_fn_data("system.tasks", NULL, get_stats_tasks);
+	sysinfo_set_item_fn_data("system.threads", NULL, get_stats_threads);
+	sysinfo_set_subtree_fn("system.tasks", NULL, get_stats_task);
+	sysinfo_set_subtree_fn("system.threads", NULL, get_stats_thread);
+}
+
+/** @}
+ */
Index: kernel/generic/src/sysinfo/sysinfo.c
===================================================================
--- kernel/generic/src/sysinfo/sysinfo.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/sysinfo/sysinfo.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -37,281 +37,802 @@
 #include <print.h>
 #include <syscall/copy.h>
+#include <synch/spinlock.h>
+#include <arch/asm.h>
+#include <errno.h>
+
+/** Maximal sysinfo path length */
+#define SYSINFO_MAX_PATH  2048
 
 bool fb_exported = false;
-sysinfo_item_t *_root = NULL;
-
-static sysinfo_item_t *sysinfo_find_item(const char *name, sysinfo_item_t *subtree)
-{
-	if (subtree == NULL)
-		return NULL;
-	
-	while (subtree != NULL) {
-		int i = 0;
-		char *a = (char *) name;
-		char *b = subtree->name;
-		
-		while ((a[i] == b[i]) && (b[i]))
+
+/** Global sysinfo tree root item */
+static sysinfo_item_t *global_root = NULL;
+
+/** Sysinfo SLAB cache */
+static slab_cache_t *sysinfo_item_slab;
+
+/** Sysinfo spinlock */
+SPINLOCK_STATIC_INITIALIZE_NAME(sysinfo_lock, "sysinfo_lock");
+
+/** Sysinfo item constructor
+ *
+ */
+static int sysinfo_item_constructor(void *obj, int kmflag)
+{
+	sysinfo_item_t *item = (sysinfo_item_t *) obj;
+	
+	item->name = NULL;
+	item->val_type = SYSINFO_VAL_UNDEFINED;
+	item->subtree_type = SYSINFO_SUBTREE_NONE;
+	item->subtree.table = NULL;
+	item->next = NULL;
+	
+	return 0;
+}
+
+/** Sysinfo item destructor
+ *
+ * Note that the return value is not perfectly correct
+ * since more space might get actually freed thanks
+ * to the disposal of item->name
+ *
+ */
+static int sysinfo_item_destructor(void *obj)
+{
+	sysinfo_item_t *item = (sysinfo_item_t *) obj;
+	
+	if (item->name != NULL)
+		free(item->name);
+	
+	return 0;
+}
+
+/** Initialize sysinfo subsystem
+ *
+ * Create SLAB cache for sysinfo items.
+ *
+ */
+void sysinfo_init(void)
+{
+	sysinfo_item_slab = slab_cache_create("sysinfo_item_slab",
+	    sizeof(sysinfo_item_t), 0, sysinfo_item_constructor,
+	    sysinfo_item_destructor, SLAB_CACHE_MAGDEFERRED);
+}
+
+/** Recursively find an item in sysinfo tree
+ *
+ * Should be called with interrupts disabled
+ * and sysinfo_lock held.
+ *
+ * @param name    Current sysinfo path suffix.
+ * @param subtree Current sysinfo (sub)tree root item.
+ * @param ret     If the return value is NULL, this argument
+ *                can be either also NULL (i.e. no item was
+ *                found and no data was generated) or the
+ *                original pointer is used to store the value
+ *                generated by a generated subtree function.
+ * @param dry_run Do not actually get any generated
+ *                binary data, just calculate the size.
+ *
+ * @return Found item or NULL if no item in the fixed tree
+ *         was found (N.B. ret).
+ *
+ */
+static sysinfo_item_t *sysinfo_find_item(const char *name,
+    sysinfo_item_t *subtree, sysinfo_return_t **ret, bool dry_run)
+{
+	ASSERT(subtree != NULL);
+	ASSERT(ret != NULL);
+	
+	sysinfo_item_t *cur = subtree;
+	
+	/* Walk all siblings */
+	while (cur != NULL) {
+		size_t i = 0;
+		
+		/* Compare name with path */
+		while ((cur->name[i] != 0) && (name[i] == cur->name[i]))
 			i++;
 		
-		if ((!a[i]) && (!b[i]))  /* Last name in path matches */
-			return subtree;
-		
-		if ((a[i] == '.') && (!b[i])) { /* Middle name in path matches */
-			if (subtree->subinfo_type == SYSINFO_SUBINFO_TABLE)
-				return sysinfo_find_item(a + i + 1, subtree->subinfo.table);
+		/* Check for perfect name and path match */
+		if ((name[i] == 0) && (cur->name[i] == 0))
+			return cur;
+		
+		/* Partial match up to the delimiter */
+		if ((name[i] == '.') && (cur->name[i] == 0)) {
+			/* Look into the subtree */
+			switch (cur->subtree_type) {
+			case SYSINFO_SUBTREE_TABLE:
+				/* Recursively find in subtree */
+				return sysinfo_find_item(name + i + 1,
+				    cur->subtree.table, ret, dry_run);
+			case SYSINFO_SUBTREE_FUNCTION:
+				/* Get generated data */
+				**ret = cur->subtree.get_data(name + i + 1, dry_run);
+				return NULL;
+			default:
+				/* Not found, no data generated */
+				*ret = NULL;
+				return NULL;
+			}
+		}
+		
+		cur = cur->next;
+	}
+	
+	/* Not found, no data generated */
+	*ret = NULL;
+	return NULL;
+}
+
+/** Recursively create items in sysinfo tree
+ *
+ * Should be called with interrupts disabled
+ * and sysinfo_lock held.
+ *
+ * @param name     Current sysinfo path suffix.
+ * @param psubtree Pointer to an already existing (sub)tree root
+ *                 item or where to store a new tree root item.
+ *
+ * @return Existing or newly allocated sysinfo item or NULL
+ *         if the current tree configuration does not allow to
+ *         create a new item.
+ *
+ */
+static sysinfo_item_t *sysinfo_create_path(const char *name,
+    sysinfo_item_t **psubtree)
+{
+	ASSERT(psubtree != NULL);
+	
+	if (*psubtree == NULL) {
+		/* No parent */
+		
+		size_t i = 0;
+		
+		/* Find the first delimiter in name */
+		while ((name[i] != 0) && (name[i] != '.'))
+			i++;
+		
+		*psubtree =
+		    (sysinfo_item_t *) slab_alloc(sysinfo_item_slab, 0);
+		ASSERT(*psubtree);
+		
+		/* Fill in item name up to the delimiter */
+		(*psubtree)->name = str_ndup(name, i);
+		ASSERT((*psubtree)->name);
+		
+		/* Create subtree items */
+		if (name[i] == '.') {
+			(*psubtree)->subtree_type = SYSINFO_SUBTREE_TABLE;
+			return sysinfo_create_path(name + i + 1,
+			    &((*psubtree)->subtree.table));
+		}
+		
+		/* No subtree needs to be created */
+		return *psubtree;
+	}
+	
+	sysinfo_item_t *cur = *psubtree;
+	
+	/* Walk all siblings */
+	while (cur != NULL) {
+		size_t i = 0;
+		
+		/* Compare name with path */
+		while ((cur->name[i] != 0) && (name[i] == cur->name[i]))
+			i++;
+		
+		/* Check for perfect name and path match
+		 * -> item is already present.
+		 */
+		if ((name[i] == 0) && (cur->name[i] == 0))
+			return cur;
+		
+		/* Partial match up to the delimiter */
+		if ((name[i] == '.') && (cur->name[i] == 0)) {
+			switch (cur->subtree_type) {
+			case SYSINFO_SUBTREE_NONE:
+				/* No subtree yet, create one */
+				cur->subtree_type = SYSINFO_SUBTREE_TABLE;
+				return sysinfo_create_path(name + i + 1,
+				    &(cur->subtree.table));
+			case SYSINFO_SUBTREE_TABLE:
+				/* Subtree already created, add new sibling */
+				return sysinfo_create_path(name + i + 1,
+				    &(cur->subtree.table));
+			default:
+				/* Subtree items handled by a function, this
+				 * cannot be overriden by a constant item.
+				 */
+				return NULL;
+			}
+		}
+		
+		/* No match and no more siblings to check
+		 * -> create a new sibling item.
+		 */
+		if (cur->next == NULL) {
+			/* Find the first delimiter in name */
+			i = 0;
+			while ((name[i] != 0) && (name[i] != '.'))
+				i++;
 			
-			//if (subtree->subinfo_type == SYSINFO_SUBINFO_FUNCTION) /* Subinfo managed by subsystem */
-			//	return NULL; 
+			sysinfo_item_t *item =
+			    (sysinfo_item_t *) slab_alloc(sysinfo_item_slab, 0);
+			ASSERT(item);
 			
-			return NULL; /* No subinfo */
-		}
-		/* No matches try next */
-		subtree = subtree->next;
-	}
-	return NULL;
-}
-
-static sysinfo_item_t *sysinfo_create_path(const char *name, sysinfo_item_t **psubtree)
-{
-	sysinfo_item_t *subtree;
-	subtree = *psubtree;
-	
-	if (subtree == NULL) {
-		sysinfo_item_t *item = malloc(sizeof(sysinfo_item_t), 0);
-		int i = 0, j;
+			cur->next = item;
 			
-		ASSERT(item);
-		*psubtree = item;
-		item->next = NULL;
-		item->val_type = SYSINFO_VAL_UNDEFINED;
-		item->subinfo.table = NULL;
-
-		while (name[i] && (name[i] != '.'))
-			i++;
+			/* Fill in item name up to the delimiter */
+			item->name = str_ndup(name, i);
+			ASSERT(item->name);
 			
-		item->name = malloc(i, 0);
-		ASSERT(item->name);
-
-		for (j = 0; j < i; j++)
-			item->name[j] = name[j];
-		item->name[j] = 0;
-			
-		if (name[i]) { /* =='.' */
-			item->subinfo_type = SYSINFO_SUBINFO_TABLE;
-			return sysinfo_create_path(name + i + 1, &(item->subinfo.table));
-		}
-		item->subinfo_type = SYSINFO_SUBINFO_NONE;
-		return item;
-	}
-
-	while (subtree != NULL) {
-		int i = 0, j;
-		char *a = (char *) name;
-		char *b = subtree->name;
-		
-		while ((a[i] == b[i]) && (b[i]))
-			i++;
-		
-		if ((!a[i]) && (!b[i])) /* Last name in path matches */
-			return subtree;
-		
-		if ((a[i] == '.') && (!b[i])) { /* Middle name in path matches */
-			if (subtree->subinfo_type == SYSINFO_SUBINFO_TABLE)
-				return sysinfo_create_path(a + i + 1, &(subtree->subinfo.table));
-			
-			if (subtree->subinfo_type == SYSINFO_SUBINFO_NONE) {
-				subtree->subinfo_type = SYSINFO_SUBINFO_TABLE;
-				return sysinfo_create_path(a + i + 1,&(subtree->subinfo.table));
+			/* Create subtree items */
+			if (name[i] == '.') {
+				item->subtree_type = SYSINFO_SUBTREE_TABLE;
+				return sysinfo_create_path(name + i + 1,
+				    &(item->subtree.table));
 			}
 			
-			//if (subtree->subinfo_type == SYSINFO_SUBINFO_FUNCTION) /* Subinfo managed by subsystem */
-			//	return NULL; 
-			
-			return NULL;
+			/* No subtree needs to be created */
+			return item;
 		}
-		/* No matches try next or create new*/
-		if (subtree->next == NULL) {
-			sysinfo_item_t *item = malloc(sizeof(sysinfo_item_t), 0);
-			
-			ASSERT(item);
-			subtree->next = item;
-			item->next = NULL;
-			item->val_type = SYSINFO_VAL_UNDEFINED;
-			item->subinfo.table = NULL;
-
-			i = 0;
-			while (name[i] && (name[i] != '.'))
-				i++;
-
-			item->name = malloc(i, 0);
-			ASSERT(item->name);
-			
-			for (j = 0; j < i; j++)
-				item->name[j] = name[j];
-			
-			item->name[j] = 0;
-
-			if(name[i]) { /* =='.' */
-				item->subinfo_type = SYSINFO_SUBINFO_TABLE;
-				return sysinfo_create_path(name + i + 1, &(item->subinfo.table));
-			}
-			item->subinfo_type = SYSINFO_SUBINFO_NONE;
-			return item;
-		} else
-			subtree = subtree->next;
-	}
-
-	panic("Not reached.");
+		
+		cur = cur->next;
+	}
+	
+	/* Unreachable */
+	ASSERT(false);
 	return NULL;
 }
 
-void sysinfo_set_item_val(const char *name, sysinfo_item_t **root, unative_t val)
-{
+/** Set sysinfo item with a constant numeric value
+ *
+ * @param name Sysinfo path.
+ * @param root Pointer to the root item or where to store
+ *             a new root item (NULL for global sysinfo root).
+ * @param val  Value to store in the item.
+ *
+ */
+void sysinfo_set_item_val(const char *name, sysinfo_item_t **root,
+    unative_t val)
+{
+	/* Protect sysinfo tree consistency */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&sysinfo_lock);
+	
 	if (root == NULL)
-		root = &_root;
-	
-	/* If already created create only returns pointer 
-	   If not, create it */
+		root = &global_root;
+	
 	sysinfo_item_t *item = sysinfo_create_path(name, root);
-	
-	if (item != NULL) { /* If in subsystem, unable to create or return so unable to set */
-		item->val.val = val;                   
+	if (item != NULL) {
 		item->val_type = SYSINFO_VAL_VAL;
-	}
-}
-
-void sysinfo_set_item_function(const char *name, sysinfo_item_t **root, sysinfo_val_fn_t fn)
-{
+		item->val.val = val;
+	}
+	
+	spinlock_unlock(&sysinfo_lock);
+	interrupts_restore(ipl);
+}
+
+/** Set sysinfo item with a constant binary data
+ *
+ * Note that sysinfo only stores the pointer to the
+ * binary data and does not touch it in any way. The
+ * data should be static and immortal.
+ *
+ * @param name Sysinfo path.
+ * @param root Pointer to the root item or where to store
+ *             a new root item (NULL for global sysinfo root).
+ * @param data Binary data.
+ * @param size Size of the binary data.
+ *
+ */
+void sysinfo_set_item_data(const char *name, sysinfo_item_t **root,
+    void *data, size_t size)
+{
+	/* Protect sysinfo tree consistency */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&sysinfo_lock);
+	
 	if (root == NULL)
-		root = &_root;
-	
-	/* If already created create only returns pointer 
-	   If not, create it */
+		root = &global_root;
+	
 	sysinfo_item_t *item = sysinfo_create_path(name, root);
-	
-	if (item != NULL) { /* If in subsystem, unable to create or return so  unable to set */
-		item->val.fn = fn;                   
-		item->val_type = SYSINFO_VAL_FUNCTION;
-	}
-}
-
-
+	if (item != NULL) {
+		item->val_type = SYSINFO_VAL_DATA;
+		item->val.data.data = data;
+		item->val.data.size = size;
+	}
+	
+	spinlock_unlock(&sysinfo_lock);
+	interrupts_restore(ipl);
+}
+
+/** Set sysinfo item with a generated numeric value
+ *
+ * @param name Sysinfo path.
+ * @param root Pointer to the root item or where to store
+ *             a new root item (NULL for global sysinfo root).
+ * @param fn   Numeric value generator function.
+ *
+ */
+void sysinfo_set_item_fn_val(const char *name, sysinfo_item_t **root,
+    sysinfo_fn_val_t fn)
+{
+	/* Protect sysinfo tree consistency */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&sysinfo_lock);
+	
+	if (root == NULL)
+		root = &global_root;
+	
+	sysinfo_item_t *item = sysinfo_create_path(name, root);
+	if (item != NULL) {
+		item->val_type = SYSINFO_VAL_FUNCTION_VAL;
+		item->val.fn_val = fn;
+	}
+	
+	spinlock_unlock(&sysinfo_lock);
+	interrupts_restore(ipl);
+}
+
+/** Set sysinfo item with a generated binary data
+ *
+ * Note that each time the generator function is called
+ * it is supposed to return a new dynamically allocated
+ * data. This data is then freed by sysinfo in the context
+ * of the current sysinfo request.
+ *
+ * @param name Sysinfo path.
+ * @param root Pointer to the root item or where to store
+ *             a new root item (NULL for global sysinfo root).
+ * @param fn   Binary data generator function.
+ *
+ */
+void sysinfo_set_item_fn_data(const char *name, sysinfo_item_t **root,
+    sysinfo_fn_data_t fn)
+{
+	/* Protect sysinfo tree consistency */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&sysinfo_lock);
+	
+	if (root == NULL)
+		root = &global_root;
+	
+	sysinfo_item_t *item = sysinfo_create_path(name, root);
+	if (item != NULL) {
+		item->val_type = SYSINFO_VAL_FUNCTION_DATA;
+		item->val.fn_data = fn;
+	}
+	
+	spinlock_unlock(&sysinfo_lock);
+	interrupts_restore(ipl);
+}
+
+/** Set sysinfo item with an undefined value
+ *
+ * @param name Sysinfo path.
+ * @param root Pointer to the root item or where to store
+ *             a new root item (NULL for global sysinfo root).
+ *
+ */
 void sysinfo_set_item_undefined(const char *name, sysinfo_item_t **root)
 {
+	/* Protect sysinfo tree consistency */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&sysinfo_lock);
+	
 	if (root == NULL)
-		root = &_root;
-	
-	/* If already created create only returns pointer 
-	   If not, create it */
+		root = &global_root;
+	
 	sysinfo_item_t *item = sysinfo_create_path(name, root);
-	
 	if (item != NULL)
 		item->val_type = SYSINFO_VAL_UNDEFINED;
-}
-
-
-void sysinfo_dump(sysinfo_item_t **proot, int depth)
-{
-	sysinfo_item_t *root;
-	if (proot == NULL)
-		proot = &_root;
-	
-	root = *proot;
-	
-	while (root != NULL) {
-		int i;
-		unative_t val = 0;
-		const char *vtype = NULL;
-		
-		
-		for (i = 0; i < depth; i++)
-			printf("  ");
-		
-		switch (root->val_type) {
+	
+	spinlock_unlock(&sysinfo_lock);
+	interrupts_restore(ipl);
+}
+
+/** Set sysinfo item with a generated subtree
+ *
+ * @param name Sysinfo path.
+ * @param root Pointer to the root item or where to store
+ *             a new root item (NULL for global sysinfo root).
+ * @param fn   Subtree generator function.
+ *
+ */
+void sysinfo_set_subtree_fn(const char *name, sysinfo_item_t **root,
+    sysinfo_fn_subtree_t fn)
+{
+	/* Protect sysinfo tree consistency */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&sysinfo_lock);
+	
+	if (root == NULL)
+		root = &global_root;
+	
+	sysinfo_item_t *item = sysinfo_create_path(name, root);
+	
+	/* Change the type of the subtree only if it is not already
+	   a fixed subtree */
+	if ((item != NULL) && (item->subtree_type != SYSINFO_SUBTREE_TABLE)) {
+		item->subtree_type = SYSINFO_SUBTREE_FUNCTION;
+		item->subtree.get_data = fn;
+	}
+	
+	spinlock_unlock(&sysinfo_lock);
+	interrupts_restore(ipl);
+}
+
+/** Sysinfo dump indentation helper routine
+ *
+ * @param depth Number of indentation characters to print.
+ *
+ */
+static void sysinfo_indent(unsigned int depth)
+{
+	unsigned int i;
+	for (i = 0; i < depth; i++)
+		printf("  ");
+}
+
+/** Dump the structure of sysinfo tree
+ *
+ * Should be called with interrupts disabled
+ * and sysinfo_lock held. Because this routine
+ * might take a reasonable long time to proceed,
+ * having the spinlock held is not optimal, but
+ * there is no better simple solution.
+ *
+ * @param root  Root item of the current (sub)tree.
+ * @param depth Current depth in the sysinfo tree.
+ *
+ */
+static void sysinfo_dump_internal(sysinfo_item_t *root, unsigned int depth)
+{
+	sysinfo_item_t *cur = root;
+	
+	/* Walk all siblings */
+	while (cur != NULL) {
+		sysinfo_indent(depth);
+		
+		unative_t val;
+		size_t size;
+		
+		/* Display node value and type */
+		switch (cur->val_type) {
 		case SYSINFO_VAL_UNDEFINED:
-			val = 0;
-			vtype = "UND";
+			printf("+ %s\n", cur->name);
 			break;
 		case SYSINFO_VAL_VAL:
-			val = root->val.val;
-			vtype = "VAL";
-			break;
-		case SYSINFO_VAL_FUNCTION:
-			val = ((sysinfo_val_fn_t) (root->val.fn)) (root);
-			vtype = "FUN";
-			break;
+			printf("+ %s -> %" PRIun" (%#" PRIxn ")\n", cur->name,
+			    cur->val.val, cur->val.val);
+			break;
+		case SYSINFO_VAL_DATA:
+			printf("+ %s (%" PRIs" bytes)\n", cur->name,
+			    cur->val.data.size);
+			break;
+		case SYSINFO_VAL_FUNCTION_VAL:
+			val = cur->val.fn_val(cur);
+			printf("+ %s -> %" PRIun" (%#" PRIxn ") [generated]\n",
+			    cur->name, val, val);
+			break;
+		case SYSINFO_VAL_FUNCTION_DATA:
+			/* N.B.: No data was actually returned (only a dry run) */
+			(void) cur->val.fn_data(cur, &size, true);
+			printf("+ %s (%" PRIs" bytes) [generated]\n", cur->name,
+			    size);
+			break;
+		default:
+			printf("+ %s [unknown]\n", cur->name);
 		}
 		
-		printf("%s    %s val:%" PRIun "(%" PRIxn ") sub:%s\n", root->name, vtype, val,
-			val, (root->subinfo_type == SYSINFO_SUBINFO_NONE) ?
-			"NON" : ((root->subinfo_type == SYSINFO_SUBINFO_TABLE) ?
-			"TAB" : "FUN"));
-		
-		if (root->subinfo_type == SYSINFO_SUBINFO_TABLE)
-			sysinfo_dump(&(root -> subinfo.table), depth + 1);
-		
-		root = root->next;
-	}
-}
-
-sysinfo_rettype_t sysinfo_get_val(const char *name, sysinfo_item_t **root)
-{
-	// TODO: Implement Subsystem subinfo (by function implemented subinfo)
-
-	sysinfo_rettype_t ret = {0, false};
-
+		/* Recursivelly nest into the subtree */
+		switch (cur->subtree_type) {
+		case SYSINFO_SUBTREE_NONE:
+			break;
+		case SYSINFO_SUBTREE_TABLE:
+			sysinfo_dump_internal(cur->subtree.table, depth + 1);
+			break;
+		case SYSINFO_SUBTREE_FUNCTION:
+			sysinfo_indent(depth + 1);
+			printf("+ [generated subtree]\n");
+			break;
+		default:
+			sysinfo_indent(depth + 1);
+			printf("+ [unknown subtree]\n");
+		}
+		
+		cur = cur->next;
+	}
+}
+
+/** Dump the structure of sysinfo tree
+ *
+ * @param root  Root item of the sysinfo (sub)tree.
+ *              If it is NULL then consider the global
+ *              sysinfo tree.
+ *
+ */
+void sysinfo_dump(sysinfo_item_t *root)
+{
+	/* Avoid other functions to mess with sysinfo
+	   while we are dumping it */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&sysinfo_lock);
+	
 	if (root == NULL)
-		root = &_root;
-	
-	sysinfo_item_t *item = sysinfo_find_item(name, *root);
+		sysinfo_dump_internal(global_root, 0);
+	else
+		sysinfo_dump_internal(root, 0);
+	
+	spinlock_unlock(&sysinfo_lock);
+	interrupts_restore(ipl);
+}
+
+/** Return sysinfo item value determined by name
+ *
+ * Should be called with interrupts disabled
+ * and sysinfo_lock held.
+ *
+ * @param name    Sysinfo path.
+ * @param root    Root item of the sysinfo (sub)tree.
+ *                If it is NULL then consider the global
+ *                sysinfo tree.
+ * @param dry_run Do not actually get any generated
+ *                binary data, just calculate the size.
+ *
+ * @return Item value (constant or generated).
+ *
+ */
+static sysinfo_return_t sysinfo_get_item(const char *name,
+    sysinfo_item_t **root, bool dry_run)
+{
+	if (root == NULL)
+		root = &global_root;
+	
+	/* Try to find the item or generate data */
+	sysinfo_return_t ret;
+	sysinfo_return_t *ret_ptr = &ret;
+	sysinfo_item_t *item = sysinfo_find_item(name, *root, &ret_ptr,
+	    dry_run);
 	
 	if (item != NULL) {
-		if (item->val_type == SYSINFO_VAL_UNDEFINED) 
-			return ret;
+		/* Item found in the fixed sysinfo tree */
+		
+		ret.tag = item->val_type;
+		switch (item->val_type) {
+		case SYSINFO_VAL_UNDEFINED:
+			break;
+		case SYSINFO_VAL_VAL:
+			ret.val = item->val.val;
+			break;
+		case SYSINFO_VAL_DATA:
+			ret.data = item->val.data;
+			break;
+		case SYSINFO_VAL_FUNCTION_VAL:
+			ret.val = item->val.fn_val(item);
+			break;
+		case SYSINFO_VAL_FUNCTION_DATA:
+			ret.data.data = item->val.fn_data(item, &ret.data.size,
+			    dry_run);
+			break;
+		}
+	} else {
+		/* No item in the fixed sysinfo tree */
+		if (ret_ptr == NULL) {
+			/* Even no data was generated */
+			ret.tag = SYSINFO_VAL_UNDEFINED;
+		}
+	}
+	
+	return ret;
+}
+
+/** Return sysinfo item determined by name from user space
+ *
+ * Should be called with interrupts disabled
+ * and sysinfo_lock held. The path string passed from
+ * the user space has to be properly null-terminated
+ * (the last passed character must be null).
+ *
+ * @param ptr     Sysinfo path in the user address space.
+ * @param size    Size of the path string.
+ * @param dry_run Do not actually get any generated
+ *                binary data, just calculate the size.
+ *
+ */
+static sysinfo_return_t sysinfo_get_item_uspace(void *ptr, size_t size,
+    bool dry_run)
+{
+	sysinfo_return_t ret;
+	ret.tag = SYSINFO_VAL_UNDEFINED;
+	
+	if (size > SYSINFO_MAX_PATH)
+		return ret;
+	
+	char *path = (char *) malloc(size + 1, 0);
+	ASSERT(path);
+	
+	if ((copy_from_uspace(path, ptr, size + 1) == 0)
+	    && (path[size] == 0))
+		ret = sysinfo_get_item(path, NULL, dry_run);
+	
+	free(path);
+	return ret;
+}
+
+/** Get the sysinfo value type (syscall)
+ *
+ * The path string passed from the user space has
+ * to be properly null-terminated (the last passed
+ * character must be null).
+ *
+ * @param path_ptr  Sysinfo path in the user address space.
+ * @param path_size Size of the path string.
+ *
+ * @return Item value type.
+ *
+ */
+unative_t sys_sysinfo_get_tag(void *path_ptr, size_t path_size)
+{
+	/* Avoid other functions to mess with sysinfo
+	   while we are reading it */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&sysinfo_lock);
+	
+	/* Get the item.
+	
+	   N.B.: There is no need to free any potential generated
+	   binary data since we request a dry run */
+	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, true);
+	
+	/* Map generated value types to constant types
+	   (user space does not care whether the
+	   value is constant or generated) */
+	if (ret.tag == SYSINFO_VAL_FUNCTION_VAL)
+		ret.tag = SYSINFO_VAL_VAL;
+	else if (ret.tag == SYSINFO_VAL_FUNCTION_DATA)
+		ret.tag = SYSINFO_VAL_DATA;
+	
+	spinlock_unlock(&sysinfo_lock);
+	interrupts_restore(ipl);
+	
+	return (unative_t) ret.tag;
+}
+
+/** Get the sysinfo numerical value (syscall)
+ *
+ * The path string passed from the user space has
+ * to be properly null-terminated (the last passed
+ * character must be null).
+ *
+ * @param path_ptr  Sysinfo path in the user address space.
+ * @param path_size Size of the path string.
+ * @param value_ptr User space pointer where to store the
+ *                  numberical value.
+ *
+ * @return Error code (EOK in case of no error).
+ *
+ */
+unative_t sys_sysinfo_get_value(void *path_ptr, size_t path_size,
+    void *value_ptr)
+{
+	/* Avoid other functions to mess with sysinfo
+	   while we are reading it */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&sysinfo_lock);
+	
+	/* Get the item.
+	
+	   N.B.: There is no need to free any potential generated
+	   binary data since we request a dry run */
+	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, true);
+	int rc;
+	
+	/* Only constant or generated numerical value is returned */
+	if ((ret.tag == SYSINFO_VAL_VAL) || (ret.tag == SYSINFO_VAL_FUNCTION_VAL))
+		rc = copy_to_uspace(value_ptr, &ret.val, sizeof(ret.val));
+	else
+		rc = EINVAL;
+	
+	spinlock_unlock(&sysinfo_lock);
+	interrupts_restore(ipl);
+	
+	return (unative_t) rc;
+}
+
+/** Get the sysinfo binary data size (syscall)
+ *
+ * The path string passed from the user space has
+ * to be properly null-terminated (the last passed
+ * character must be null).
+ *
+ * @param path_ptr  Sysinfo path in the user address space.
+ * @param path_size Size of the path string.
+ * @param size_ptr  User space pointer where to store the
+ *                  binary data size.
+ *
+ * @return Error code (EOK in case of no error).
+ *
+ */
+unative_t sys_sysinfo_get_data_size(void *path_ptr, size_t path_size,
+    void *size_ptr)
+{
+	/* Avoid other functions to mess with sysinfo
+	   while we are reading it */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&sysinfo_lock);
+	
+	/* Get the item.
+	
+	   N.B.: There is no need to free any potential generated
+	   binary data since we request a dry run */
+	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, true);
+	int rc;
+	
+	/* Only the size of constant or generated binary data is considered */
+	if ((ret.tag == SYSINFO_VAL_DATA) || (ret.tag == SYSINFO_VAL_FUNCTION_DATA))
+		rc = copy_to_uspace(size_ptr, &ret.data.size,
+		    sizeof(ret.data.size));
+	else
+		rc = EINVAL;
+	
+	spinlock_unlock(&sysinfo_lock);
+	interrupts_restore(ipl);
+	
+	return (unative_t) rc;
+}
+
+/** Get the sysinfo binary data (syscall)
+ *
+ * The path string passed from the user space has
+ * to be properly null-terminated (the last passed
+ * character must be null).
+ *
+ * The user space buffer must be sized exactly according
+ * to the size of the binary data, otherwise the request
+ * fails.
+ *
+ * @param path_ptr    Sysinfo path in the user address space.
+ * @param path_size   Size of the path string.
+ * @param buffer_ptr  User space pointer to the buffer where
+ *                    to store the binary data.
+ * @param buffer_size User space buffer size.
+ *
+ * @return Error code (EOK in case of no error).
+ *
+ */
+unative_t sys_sysinfo_get_data(void *path_ptr, size_t path_size,
+    void *buffer_ptr, size_t buffer_size)
+{
+	/* Avoid other functions to mess with sysinfo
+	   while we are reading it */
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&sysinfo_lock);
+	
+	/* Get the item */
+	sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, false);
+	int rc;
+	
+	/* Only constant or generated binary data is considered */
+	if ((ret.tag == SYSINFO_VAL_DATA) || (ret.tag == SYSINFO_VAL_FUNCTION_DATA)) {
+		/* Check destination buffer size */
+		if (ret.data.size == buffer_size)
+			rc = copy_to_uspace(buffer_ptr, ret.data.data,
+			    ret.data.size);
 		else
-			ret.valid = true;
-		
-		if (item->val_type == SYSINFO_VAL_VAL)
-			ret.val = item->val.val;
-		else
-			ret.val = ((sysinfo_val_fn_t) (item->val.fn)) (item);
-	}
-	return ret;
-}
-
-#define SYSINFO_MAX_LEN	1024
-
-unative_t sys_sysinfo_valid(unative_t ptr, unative_t len)
-{
-	char *str;
-	sysinfo_rettype_t ret = {0, 0};
-
-	if (len > SYSINFO_MAX_LEN)
-		return ret.valid;
-	str = malloc(len + 1, 0);
-	
-	ASSERT(str);
-	if (!((copy_from_uspace(str, (void *) ptr, len + 1)) || (str[len])))
-		ret = sysinfo_get_val(str, NULL);
-	
-	free(str);
-	return ret.valid;
-}
-
-unative_t sys_sysinfo_value(unative_t ptr, unative_t len)
-{
-	char *str;
-	sysinfo_rettype_t ret = {0, 0};
-	
-	if (len > SYSINFO_MAX_LEN)
-		return ret.val;
-	str = malloc(len + 1, 0);
-	
-	ASSERT(str);
-	if (!((copy_from_uspace(str, (void *) ptr, len + 1)) || (str[len]))) 
-		ret = sysinfo_get_val(str, NULL);
-	
-	free(str);
-	return ret.val;
+			rc = ENOMEM;
+	} else
+		rc = EINVAL;
+	
+	/* N.B.: The generated binary data should be freed */
+	if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL))
+		free(ret.data.data);
+	
+	spinlock_unlock(&sysinfo_lock);
+	interrupts_restore(ipl);
+	
+	return (unative_t) rc;
 }
 
Index: kernel/generic/src/time/clock.c
===================================================================
--- kernel/generic/src/time/clock.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/generic/src/time/clock.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -86,5 +86,5 @@
 	uptime->seconds1 = 0;
 	uptime->seconds2 = 0;
-	uptime->useconds = 0; 
+	uptime->useconds = 0;
 
 	clock_parea.pbase = (uintptr_t) faddr;
@@ -137,4 +137,13 @@
 	size_t missed_clock_ticks = CPU->missed_clock_ticks;
 	unsigned int i;
+
+	/* Account lost ticks to CPU usage */
+	if (CPU->idle) {
+		ASSERT(missed_clock_ticks == 0);
+		CPU->idle_ticks++;
+	} else {
+		CPU->busy_ticks += missed_clock_ticks + 1;
+	}
+	CPU->idle = false;
 
 	/*
Index: rnel/test/sysinfo/sysinfo1.c
===================================================================
--- kernel/test/sysinfo/sysinfo1.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,40 +1,0 @@
-/*
- * Copyright (c) 2005 Jakub Vana
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <print.h>
-#include <debug.h>
-
-#include <test.h>
-#include <sysinfo/sysinfo.h>
-
-const char *test_sysinfo1(void)
-{
-	if (!test_quiet)
-		sysinfo_dump(NULL, 0);
-	return NULL;
-}
Index: rnel/test/sysinfo/sysinfo1.def
===================================================================
--- kernel/test/sysinfo/sysinfo1.def	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,6 +1,0 @@
-{
-	"sysinfo1",
-	"Sysinfo test",
-	&test_sysinfo1,
-	true
-},
Index: kernel/test/test.c
===================================================================
--- kernel/test/test.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/test/test.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -63,5 +63,4 @@
 #include <print/print4.def>
 #include <thread/thread1.def>
-#include <sysinfo/sysinfo1.def>
 	{
 		.name = NULL,
Index: kernel/test/test.h
===================================================================
--- kernel/test/test.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ kernel/test/test.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -82,5 +82,4 @@
 extern const char *test_print4(void);
 extern const char *test_thread1(void);
-extern const char *test_sysinfo1(void);
 
 extern test_t tests[];
Index: tools/toolchain.sh
===================================================================
--- tools/toolchain.sh	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ tools/toolchain.sh	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -142,5 +142,5 @@
 	
 	BINUTILS_VERSION="2.20"
-	GCC_VERSION="4.4.3"
+	GCC_VERSION="4.5.0"
 	
 	BINUTILS="binutils-${BINUTILS_VERSION}.tar.bz2"
@@ -165,7 +165,7 @@
 	echo ">>> Downloading tarballs"
 	download_check "${BINUTILS_SOURCE}" "${BINUTILS}" "ee2d3e996e9a2d669808713360fa96f8"
-	download_check "${GCC_SOURCE}" "${GCC_CORE}" "054b66f315b3d04ad06544ce26e72365"
-	download_check "${GCC_SOURCE}" "${GCC_OBJC}" "34711c4de46eaf79aa018206dbec4389"
-	download_check "${GCC_SOURCE}" "${GCC_CPP}" "cd179ec4f05ee17ce76464da25a2674c"
+	download_check "${GCC_SOURCE}" "${GCC_CORE}" "58eda33c3184303628f91c42a7ab15b5"
+	download_check "${GCC_SOURCE}" "${GCC_OBJC}" "8d8c01b6631b020cc6c167860fde2398"
+	download_check "${GCC_SOURCE}" "${GCC_CPP}" "5ab93605af40def4844eda09ca769c2d"
 	
 	echo ">>> Removing previous content"
@@ -196,5 +196,5 @@
 	cd "${OBJDIR}"
 	check_error $? "Change directory failed."
-	"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared
+	"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared --enable-lto
 	check_error $? "Error configuring GCC."
 	PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -42,8 +42,12 @@
 	app/redir \
 	app/sbi \
+	app/stats \
 	app/taskdump \
+	app/tasks \
 	app/tester \
 	app/tetris \
 	app/trace \
+	app/top \
+	app/dummy_load \
 	srv/clip \
 	srv/devmap \
@@ -66,5 +70,31 @@
 	srv/hid/kbd \
 	srv/hw/char/i8042 \
-	srv/hw/netif/dp8390
+	srv/hw/netif/dp8390 \
+	srv/net/cfg \
+	srv/net/netif/lo \
+	srv/net/il/arp \
+	srv/net/il/ip \
+	srv/net/tl/icmp \
+	srv/net/tl/udp \
+	srv/net/tl/tcp \
+	srv/net/net \
+	srv/net/netstart \
+	app/netecho \
+	app/nettest1 \
+	app/nettest2 \
+	app/ping
+
+## Networking
+#
+
+ifeq ($(CONFIG_NETIF_NIL_BUNDLE),y)
+	LIBN = \
+		srv/net/nil/eth \
+		srv/net/nil/nildummy
+else
+	DIRS += \
+		srv/net/nil/eth \
+		srv/net/nil/nildummy
+endif
 
 ## Platform-specific hardware support
@@ -93,25 +123,4 @@
 endif
 
-## Networking
-#
-
-NETWORKING_COMMON = \
-	srv/net/netif/lo \
-	srv/net/nil/eth \
-	srv/net/nil/nildummy \
-	srv/net/net \
-	srv/net/netstart \
-	app/netecho \
-	app/nettest1 \
-	app/nettest2 \
-	app/ping
-
-NETWORKING_MODULAR = \
-	srv/net/il/arp \
-	srv/net/il/ip \
-	srv/net/tl/icmp \
-	srv/net/tl/udp \
-	srv/net/tl/tcp
-
 ## System libraries
 #
@@ -125,6 +134,5 @@
 	lib/softfloat \
 	lib/socket \
-	lib/net \
-	lib/netif
+	lib/net
 
 ifeq ($(UARCH),amd64)
@@ -139,16 +147,10 @@
 LIBC_BUILD = $(addsuffix .build,$(LIBC))
 LIBS_BUILD = $(addsuffix .build,$(LIBS))
+LIBN_BUILD = $(addsuffix .build,$(LIBN))
+BUILDS := $(addsuffix .build,$(DIRS))
 
-ifeq ($(CONFIG_NETWORKING),modular)
-	BUILDS := $(addsuffix .build,$(DIRS)) $(addsuffix .build,$(NETWORKING_COMMON)) $(addsuffix .build,$(NETWORKING_MODULAR))
-endif
+CLEANS := $(addsuffix .clean,$(DIRS)) $(addsuffix .clean,$(LIBN)) $(addsuffix .clean,$(LIBS)) $(addsuffix .clean,$(LIBC))
 
-ifeq ($(CONFIG_NETWORKING),module)
-	BUILDS := $(addsuffix .build,$(DIRS)) $(addsuffix .build,$(NETWORKING_COMMON))
-endif
-
-CLEANS := $(addsuffix .clean,$(DIRS)) $(addsuffix .clean,$(NETWORKING_COMMON)) $(addsuffix .clean,$(NETWORKING_MODULAR)) $(addsuffix .clean,$(LIBS)) $(addsuffix .clean,$(LIBC))
-
-.PHONY: all $(LIBC_BUILD) $(LIBS_BUILD) $(BUILDS) $(CLEANS) clean
+.PHONY: all $(LIBC_BUILD) $(LIBS_BUILD) $(LIBN_BUILD) $(BUILDS) $(CLEANS) clean
 
 all: $(BUILDS)
@@ -159,5 +161,8 @@
 	-$(MAKE) -C $(basename $@) clean
 
-$(BUILDS): $(LIBC_BUILD) $(LIBS_BUILD)
+$(BUILDS): $(LIBC_BUILD) $(LIBS_BUILD) $(LIBN_BUILD)
+	$(MAKE) -C $(basename $@) all PRECHECK=$(PRECHECK)
+
+$(LIBN_BUILD): $(LIBC_BUILD) $(LIBS_BUILD)
 	$(MAKE) -C $(basename $@) all PRECHECK=$(PRECHECK)
 
Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/Makefile.common	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -90,5 +90,4 @@
 LIBSOCKET_PREFIX = $(LIB_PREFIX)/socket
 LIBNET_PREFIX = $(LIB_PREFIX)/net
-LIBNETIF_PREFIX = $(LIB_PREFIX)/netif
 
 BASE_LIBS = $(LIBC_PREFIX)/libc.a $(LIBSOFTINT_PREFIX)/libsoftint.a
Index: uspace/app/bdsh/exec.c
===================================================================
--- uspace/app/bdsh/exec.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/bdsh/exec.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -40,4 +40,5 @@
 #include <str.h>
 #include <fcntl.h>
+#include <str_error.h>
 
 #include "config.h"
@@ -120,9 +121,10 @@
 	free(found);
 
-	tid = task_spawn(tmp, (const char **) argv);
+	tid = task_spawn(tmp, (const char **) argv, &retval);
 	free(tmp);
 
 	if (tid == 0) {
-		cli_error(CL_EEXEC, "Cannot spawn `%s'.", cmd);
+		cli_error(CL_EEXEC, "%s: Cannot spawn `%s' (%s)", progname, cmd,
+		    str_error(retval));
 		return 1;
 	}
@@ -130,7 +132,8 @@
 	task_wait(tid, &texit, &retval);
 	if (texit != TASK_EXIT_NORMAL) {
-		printf("Command failed (unexpectedly terminated).\n");
+		printf("%s: Command failed (unexpectedly terminated)\n", progname);
 	} else if (retval != 0) {
-		printf("Command failed (return value %d).\n", retval);
+		printf("%s: Command failed (%s)\n",
+		    progname, str_error(retval));
 	}
 
Index: uspace/app/bdsh/scli.h
===================================================================
--- uspace/app/bdsh/scli.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/bdsh/scli.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -13,3 +13,5 @@
 } cliuser_t;
 
+extern const char *progname;
+
 #endif
Index: uspace/app/dummy_load/Makefile
===================================================================
--- uspace/app/dummy_load/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/app/dummy_load/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,37 @@
+#
+# 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 = dummy_load
+
+SOURCES = \
+	dummy_load.c \
+	input.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/dummy_load/dummy_load.c
===================================================================
--- uspace/app/dummy_load/dummy_load.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/app/dummy_load/dummy_load.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2010 Stanislav Kozina
+ * 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 dummy_load
+ * @brief Dummy application to make some system load.
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <task.h>
+#include <malloc.h>
+#include <ps.h>
+#include <str.h>
+#include <stdlib.h>
+#include "input.h"
+
+#define TASK_COUNT 50
+#define USPACE_CYCLES (1 << 26)
+#define SYSTEM_CYCLES (1 << 16)
+
+static void uspace_load()
+{
+	puts("u");
+	uint64_t volatile i;
+	for (i = 0; i < USPACE_CYCLES; ++i)
+		;
+}
+
+static int task_count;
+
+static void system_init()
+{
+	task_count = TASK_COUNT;
+	task_id_t *tasks = malloc(task_count * sizeof(task_id_t));
+	int result = get_task_ids(tasks, sizeof(task_id_t) * task_count);
+
+	while (result > task_count) {
+		task_count *= 2;
+		tasks = realloc(tasks, task_count * sizeof(task_id_t));
+		result = get_task_ids(tasks, sizeof(task_id_t) * task_count);
+	}
+
+	free(tasks);
+}
+
+static void system_load()
+{
+	puts("s");
+	task_id_t *tasks = malloc(task_count * sizeof(task_id_t));
+	int result;
+
+	uint64_t i;
+	for (i = 0; i < SYSTEM_CYCLES; ++i) {
+		result = get_task_ids(tasks, sizeof(task_id_t) * task_count);
+	}
+
+	free(tasks);
+}
+
+static void usage()
+{
+	printf("Usage: dummy_load [-u|-s|-r]\n");
+}
+
+int main(int argc, char *argv[])
+{
+	--argc; ++argv;
+	system_init();
+
+	char mode = 'r';
+	if (argc > 1) {
+		printf("Bad argument count!\n");
+		usage();
+		exit(1);
+	}
+
+	if (argc > 0) {
+		if (str_cmp(*argv, "-r") == 0) {
+			printf("Doing random load\n");
+			mode = 'r';
+		} else if (str_cmp(*argv, "-u") == 0) {
+			printf("Doing uspace load\n");
+			mode = 'u';
+		} else if (str_cmp(*argv, "-s") == 0) {
+			printf("Doing system load\n");
+			mode = 's';
+		} else {
+			usage();
+			exit(1);
+		}
+	} else {
+		mode = 'r';
+		printf("Doing random load\n");
+	}
+
+	bool system = false;
+	while (true) {
+		char c = tgetchar(0);
+		switch (c) {
+			case 'r':
+				mode = 'r';
+				break;
+			case 'u':
+				mode = 'u';
+				break;
+			case 's':
+				mode = 's';
+				break;
+			case 'q':
+				exit(0);
+				break;
+		}
+		switch (mode) {
+			case 'r':
+				if (system) {
+					system_load();
+				} else {
+					uspace_load();
+				}
+				system = !system;
+				break;
+			case 'u':
+				uspace_load();
+				break;
+			case 's':
+				system_load();
+				break;
+		}
+		fflush(stdout);
+	}
+
+	puts("\n");
+	fflush(stdout);
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/dummy_load/input.c
===================================================================
--- uspace/app/dummy_load/input.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/app/dummy_load/input.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,200 @@
+/*	$OpenBSD: input.c,v 1.12 2005/04/13 02:33:08 deraadt Exp $	*/
+/*    $NetBSD: input.c,v 1.3 1996/02/06 22:47:33 jtc Exp $    */
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)input.c	8.1 (Berkeley) 5/31/93
+ */
+
+/** @addtogroup dummy_load
+ * @{
+ */
+/** @file
+ */
+
+/*
+ * Top input.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdio.h>
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <str.h>
+
+#include "input.h"
+
+#include <async.h>
+#include <vfs/vfs.h>
+#include <io/console.h>
+#include <ipc/console.h>
+
+#define USEC_COUNT 1000000
+
+/* return true iff the given timeval is positive */
+#define	TV_POS(tv) \
+	((tv)->tv_sec > 0 || ((tv)->tv_sec == 0 && (tv)->tv_usec > 0))
+
+/* subtract timeval `sub' from `res' */
+#define	TV_SUB(res, sub) \
+	(res)->tv_sec -= (sub)->tv_sec; \
+	(res)->tv_usec -= (sub)->tv_usec; \
+	if ((res)->tv_usec < 0) { \
+		(res)->tv_usec += 1000000; \
+		(res)->tv_sec--; \
+	}
+
+/* We will use a hack here - if lastchar is non-zero, it is
+ * the last character read. We will somehow simulate the select
+ * semantics.
+ */
+static aid_t getchar_inprog = 0;
+static char lastchar = '\0';
+
+/*
+ * Do a `read wait': select for reading from stdin, with timeout *tvp.
+ * On return, modify *tvp to reflect the amount of time spent waiting.
+ * It will be positive only if input appeared before the time ran out;
+ * otherwise it will be zero or perhaps negative.
+ *
+ * If tvp is nil, wait forever, but return if select is interrupted.
+ *
+ * Return 0 => no input, 1 => can read() from stdin
+ *
+ */
+int rwait(struct timeval *tvp)
+{
+	struct timeval starttv, endtv, *s;
+	static ipc_call_t charcall;
+	ipcarg_t rc;
+	
+	/*
+	 * Someday, select() will do this for us.
+	 * Just in case that day is now, and no one has
+	 * changed this, we use a temporary.
+	 */
+	if (tvp) {
+		(void) gettimeofday(&starttv, NULL);
+		endtv = *tvp;
+		s = &endtv;
+	} else
+		s = NULL;
+	
+	if (!lastchar) {
+again:
+		if (!getchar_inprog) {
+			getchar_inprog = async_send_0(fphone(stdin),
+			    CONSOLE_GET_EVENT, &charcall);
+		}
+		
+		if (!s)
+			async_wait_for(getchar_inprog, &rc);
+		else if (async_wait_timeout(getchar_inprog, &rc, s->tv_usec) == ETIMEOUT) {
+			tvp->tv_sec = 0;
+			tvp->tv_usec = 0;
+			return (0);
+		}
+		
+		getchar_inprog = 0;
+		if (rc) {
+			printf("End of file, bug?\n");
+			exit(1);
+		}
+		
+		if (IPC_GET_ARG1(charcall) == KEY_RELEASE)
+			goto again;
+		
+		lastchar = IPC_GET_ARG4(charcall);
+	}
+	
+	if (tvp) {
+		/* since there is input, we may not have timed out */
+		(void) gettimeofday(&endtv, NULL);
+		TV_SUB(&endtv, &starttv);
+		TV_SUB(tvp, &endtv);  /* adjust *tvp by elapsed time */
+	}
+	
+	return 1;
+}
+
+/*
+ * `sleep' for the current turn time (using select).
+ * Eat any input that might be available.
+ */
+void tsleep(unsigned int sec)
+{
+	struct timeval tv;
+	
+	tv.tv_sec = 0;
+	tv.tv_usec = sec * USEC_COUNT;
+	while (TV_POS(&tv))
+		if (rwait(&tv)) {
+			lastchar = '\0';
+		} else
+			break;
+}
+
+/*
+ * getchar with timeout.
+ */
+int tgetchar(unsigned int sec)
+{
+	static struct timeval timeleft;
+	char c;
+	
+	/*
+	 * Reset timeleft to USEC_COUNT whenever it is not positive.
+	 * In any case, wait to see if there is any input.  If so,
+	 * take it, and update timeleft so that the next call to
+	 * tgetchar() will not wait as long.  If there is no input,
+	 * make timeleft zero or negative, and return -1.
+	 *
+	 * Most of the hard work is done by rwait().
+	 */
+	if (!TV_POS(&timeleft)) {
+		timeleft.tv_sec = 0;
+		timeleft.tv_usec = sec * USEC_COUNT;
+	}
+	
+	if (!rwait(&timeleft))
+		return -1;
+	
+	c = lastchar;
+	lastchar = '\0';
+	return ((int) (unsigned char) c);
+}
+
+/** @}
+ */
Index: uspace/app/dummy_load/input.h
===================================================================
--- uspace/app/dummy_load/input.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/app/dummy_load/input.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,56 @@
+/*	$OpenBSD: input.h,v 1.5 2003/06/03 03:01:41 millert Exp $	*/
+/*	$NetBSD: input.h,v 1.2 1995/04/22 07:42:36 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)input.h	8.1 (Berkeley) 5/31/93
+ */
+
+/** @addtogroup dummy_load
+ * @{
+ */
+/** @file
+ */
+
+#ifndef TOP_INPUT_
+#define TOP_INPUT_
+
+#include <sys/time.h>
+
+extern int rwait(struct timeval *);
+extern int tgetchar(unsigned int sec);
+extern void tsleep(unsigned int sec);
+
+#endif
+
+/** @}
+ */
Index: uspace/app/edit/edit.c
===================================================================
--- uspace/app/edit/edit.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/edit/edit.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -40,5 +40,5 @@
 #include <vfs/vfs.h>
 #include <io/console.h>
-#include <io/color.h>
+#include <io/style.h>
 #include <io/keycode.h>
 #include <errno.h>
@@ -100,5 +100,6 @@
 static bool cursor_visible;
 
-static int scr_rows, scr_columns;
+static ipcarg_t scr_rows;
+static ipcarg_t scr_columns;
 
 #define ROW_BUF_SIZE 4096
@@ -505,8 +506,8 @@
 	asprintf(&str, "%s: %s", prompt, init_value);
 	status_display(str);
-	console_goto(con, 1 + str_length(str), scr_rows - 1);
+	console_set_pos(con, 1 + str_length(str), scr_rows - 1);
 	free(str);
 
-	console_set_color(con, COLOR_WHITE, COLOR_BLACK, 0);
+	console_set_style(con, STYLE_INVERTED);
 
 	max_len = min(INFNAME_MAX_LEN, scr_columns - 4 - str_length(prompt));
@@ -552,5 +553,5 @@
 	str = wstr_to_astr(buffer);
 
-	console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
+	console_set_style(con, STYLE_NORMAL);
 
 	return str;
@@ -671,5 +672,4 @@
 {
 	int sh_rows, rows;
-	int i, j;
 
 	sheet_get_num_rows(&doc.sh, &sh_rows);
@@ -678,11 +678,13 @@
 	/* Draw rows from the sheet. */
 
-	console_goto(con, 0, 0);
+	console_set_pos(con, 0, 0);
 	pane_row_range_display(0, rows);
 
 	/* Clear the remaining rows if file is short. */
-
+	
+	int i;
+	ipcarg_t j;
 	for (i = rows; i < pane.rows; ++i) {
-		console_goto(con, 0, i);
+		console_set_pos(con, 0, i);
 		for (j = 0; j < scr_columns; ++j)
 			putchar(' ');
@@ -736,5 +738,5 @@
 	/* Draw rows from the sheet. */
 
-	console_goto(con, 0, 0);
+	console_set_pos(con, 0, 0);
 	for (i = r0; i < r1; ++i) {
 		/* Starting point for row display */
@@ -756,9 +758,9 @@
 		    coord_cmp(&rbc, &csel_end) < 0) {
 			fflush(stdout);
-			console_set_color(con, COLOR_BLACK, COLOR_RED, 0);
+			console_set_style(con, STYLE_SELECTED);
 			fflush(stdout);
 		}
 
-		console_goto(con, 0, i);
+		console_set_pos(con, 0, i);
 		size = str_size(row_buf);
 		pos = 0;
@@ -767,5 +769,5 @@
 			if ((csel_start.row == rbc.row) && (csel_start.column == s_column)) {
 				fflush(stdout);
-				console_set_color(con, COLOR_BLACK, COLOR_RED, 0);
+				console_set_style(con, STYLE_SELECTED);
 				fflush(stdout);
 			}
@@ -773,5 +775,5 @@
 			if ((csel_end.row == rbc.row) && (csel_end.column == s_column)) {
 				fflush(stdout);
-				console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
+				console_set_style(con, STYLE_NORMAL);
 				fflush(stdout);
 			}
@@ -793,5 +795,5 @@
 		if ((csel_end.row == rbc.row) && (csel_end.column == s_column)) {
 			fflush(stdout);
-			console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
+			console_set_style(con, STYLE_NORMAL);
 			fflush(stdout);
 		}
@@ -807,5 +809,5 @@
 			putchar(' ');
 		fflush(stdout);
-		console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
+		console_set_style(con, STYLE_NORMAL);
 	}
 
@@ -824,11 +826,11 @@
 	const char *fname = (doc.file_name != NULL) ? doc.file_name : "<unnamed>";
 
-	console_goto(con, 0, scr_rows - 1);
-	console_set_color(con, COLOR_WHITE, COLOR_BLACK, 0);
+	console_set_pos(con, 0, scr_rows - 1);
+	console_set_style(con, STYLE_INVERTED);
 	int n = printf(" %d, %d: File '%s'. Ctrl-Q Quit  Ctrl-S Save  "
 	    "Ctrl-E Save As", coord.row, coord.column, fname);
 	printf("%*s", scr_columns - 1 - n, "");
 	fflush(stdout);
-	console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
+	console_set_style(con, STYLE_NORMAL);
 
 	pane.rflags |= REDRAW_CARET;
@@ -844,5 +846,5 @@
 
 	spt_get_coord(&caret_pt, &coord);
-	console_goto(con, coord.column - pane.sh_column,
+	console_set_pos(con, coord.column - pane.sh_column,
 	    coord.row - pane.sh_row);
 }
@@ -1149,9 +1151,9 @@
 static void status_display(char const *str)
 {
-	console_goto(con, 0, scr_rows - 1);
-	console_set_color(con, COLOR_WHITE, COLOR_BLACK, 0);
+	console_set_pos(con, 0, scr_rows - 1);
+	console_set_style(con, STYLE_INVERTED);
 	printf(" %*s ", -(scr_columns - 3), str);
 	fflush(stdout);
-	console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
+	console_set_style(con, STYLE_NORMAL);
 
 	pane.rflags |= REDRAW_CARET;
Index: uspace/app/getterm/getterm.c
===================================================================
--- uspace/app/getterm/getterm.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/getterm/getterm.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -40,9 +40,12 @@
 #include <stdio.h>
 #include <task.h>
+#include <str_error.h>
 #include "version.h"
+
+#define APP_NAME  "getterm"
 
 static void usage(void)
 {
-	printf("Usage: getterm <terminal> <path>\n");
+	printf("Usage: %s <terminal> <path>\n", APP_NAME);
 }
 
@@ -76,8 +79,10 @@
 	args[1] = NULL;
 	
-	task_id_t id = task_spawn(fname, args);
+	int err;
+	task_id_t id = task_spawn(fname, args, &err);
 	
 	if (id == 0)
-		printf("Error spawning %s\n", fname);
+		printf("%s: Error spawning %s (%s)\n", APP_NAME, fname,
+		    str_error(err));
 	
 	return id;
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/init/init.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -48,7 +48,19 @@
 #include <str.h>
 #include <devmap.h>
+#include <str_error.h>
 #include "init.h"
 
+#define ROOT_DEVICE       "bd/initrd"
+#define ROOT_MOUNT_POINT  "/"
+
+#define DEVFS_FS_TYPE      "devfs"
 #define DEVFS_MOUNT_POINT  "/dev"
+
+#define SCRATCH_FS_TYPE      "tmpfs"
+#define SCRATCH_MOUNT_POINT  "/scratch"
+
+#define DATA_FS_TYPE      "fat"
+#define DATA_DEVICE       "bd/disk0"
+#define DATA_MOUNT_POINT  "/data"
 
 #define SRV_CONSOLE  "/srv/console"
@@ -57,5 +69,34 @@
 static void info_print(void)
 {
-	printf(NAME ": HelenOS init\n");
+	printf("%s: HelenOS init\n", NAME);
+}
+
+static bool mount_report(const char *desc, const char *mntpt,
+    const char *fstype, const char *dev, int rc)
+{
+	switch (rc) {
+	case EOK:
+		if (dev != NULL)
+			printf("%s: %s mounted on %s (%s at %s)\n", NAME, desc, mntpt,
+			    fstype, dev);
+		else
+			printf("%s: %s mounted on %s (%s)\n", NAME, desc, mntpt, fstype);
+		break;
+	case EBUSY:
+		printf("%s: %s already mounted on %s\n", NAME, desc, mntpt);
+		return false;
+	case ELIMIT:
+		printf("%s: %s limit exceeded\n", NAME, desc);
+		return false;
+	case ENOENT:
+		printf("%s: %s unknown type (%s)\n", NAME, desc, fstype);
+		return false;
+	default:
+		printf("%s: %s not mounted on %s (%s)\n", NAME, desc, mntpt,
+		    str_error(rc));
+		return false;
+	}
+	
+	return true;
 }
 
@@ -63,56 +104,20 @@
 {
 	const char *opts = "";
-	const char *root_dev = "bd/initrd";
 	
 	if (str_cmp(fstype, "tmpfs") == 0)
 		opts = "restore";
 	
-	int rc = mount(fstype, "/", root_dev, opts, IPC_FLAG_BLOCKING);
-	
-	switch (rc) {
-	case EOK:
-		printf(NAME ": Root filesystem mounted, %s at %s\n",
-		    fstype, root_dev);
-		break;
-	case EBUSY:
-		printf(NAME ": Root filesystem already mounted\n");
-		return false;
-	case ELIMIT:
-		printf(NAME ": Unable to mount root filesystem\n");
-		return false;
-	case ENOENT:
-		printf(NAME ": Unknown filesystem type (%s)\n", fstype);
-		return false;
-	default:
-		printf(NAME ": Error mounting root filesystem (%d)\n", rc);
-		return false;
-	}
-	
-	return true;
+	int rc = mount(fstype, ROOT_MOUNT_POINT, ROOT_DEVICE, opts,
+	    IPC_FLAG_BLOCKING);
+	return mount_report("Root filesystem", ROOT_MOUNT_POINT, fstype,
+	    ROOT_DEVICE, rc);
 }
 
 static bool mount_devfs(void)
 {
-	int rc = mount("devfs", DEVFS_MOUNT_POINT, "", "", IPC_FLAG_BLOCKING);
-	
-	switch (rc) {
-	case EOK:
-		printf(NAME ": Device filesystem mounted\n");
-		break;
-	case EBUSY:
-		printf(NAME ": Device filesystem already mounted\n");
-		return false;
-	case ELIMIT:
-		printf(NAME ": Unable to mount device filesystem\n");
-		return false;
-	case ENOENT:
-		printf(NAME ": Unknown filesystem type (devfs)\n");
-		return false;
-	default:
-		printf(NAME ": Error mounting device filesystem (%d)\n", rc);
-		return false;
-	}
-	
-	return true;
+	int rc = mount(DEVFS_FS_TYPE, DEVFS_MOUNT_POINT, "", "",
+	    IPC_FLAG_BLOCKING);
+	return mount_report("Device filesystem", DEVFS_MOUNT_POINT, DEVFS_FS_TYPE,
+	    NULL, rc);
 }
 
@@ -125,11 +130,13 @@
 		return;
 	
-	printf(NAME ": Spawning %s\n", fname);
+	printf("%s: Spawning %s\n", NAME, fname);
 	
 	argv[0] = fname;
 	argv[1] = NULL;
 	
-	if (!task_spawn(fname, argv))
-		printf(NAME ": Error spawning %s\n", fname);
+	int err;
+	if (!task_spawn(fname, argv, &err))
+		printf("%s: Error spawning %s (%s)\n", NAME, fname,
+		    str_error(err));
 }
 
@@ -145,24 +152,26 @@
 		return;
 	
-	printf(NAME ": Starting %s\n", fname);
+	printf("%s: Starting %s\n", NAME, fname);
 	
 	argv[0] = fname;
 	argv[1] = NULL;
 	
-	id = task_spawn(fname, argv);
+	id = task_spawn(fname, argv, &retval);
 	if (!id) {
-		printf(NAME ": Error spawning %s\n", fname);
+		printf("%s: Error spawning %s (%s)\n", NAME, fname,
+		    str_error(retval));
 		return;
 	}
-
+	
 	rc = task_wait(id, &texit, &retval);
 	if (rc != EOK) {
-		printf(NAME ": Error waiting for %s\n", fname);
+		printf("%s: Error waiting for %s (%s(\n", NAME, fname,
+		    str_error(retval));
 		return;
 	}
-
+	
 	if ((texit != TASK_EXIT_NORMAL) || (retval != 0)) {
-		printf(NAME ": Server %s failed to start (returned %d)\n",
-			fname, retval);
+		printf("%s: Server %s failed to start (%s)\n", NAME,
+			fname, str_error(retval));
 	}
 }
@@ -176,5 +185,5 @@
 	snprintf(hid_in, DEVMAP_NAME_MAXLEN, "%s/%s", DEVFS_MOUNT_POINT, dev);
 	
-	printf(NAME ": Spawning %s with %s\n", SRV_CONSOLE, hid_in);
+	printf("%s: Spawning %s %s\n", NAME, SRV_CONSOLE, hid_in);
 	
 	/* Wait for the input device to be ready */
@@ -187,8 +196,10 @@
 		argv[2] = NULL;
 		
-		if (!task_spawn(SRV_CONSOLE, argv))
-			printf(NAME ": Error spawning %s with %s\n", SRV_CONSOLE, hid_in);
+		if (!task_spawn(SRV_CONSOLE, argv, &rc))
+			printf("%s: Error spawning %s %s (%s)\n", NAME, SRV_CONSOLE,
+			    hid_in, str_error(rc));
 	} else
-		printf(NAME ": Error waiting on %s\n", hid_in);
+		printf("%s: Error waiting on %s (%s)\n", NAME, hid_in,
+		    str_error(rc));
 }
 
@@ -201,5 +212,5 @@
 	snprintf(term, DEVMAP_NAME_MAXLEN, "%s/%s", DEVFS_MOUNT_POINT, dev);
 	
-	printf(NAME ": Spawning %s with %s %s\n", APP_GETTERM, term, app);
+	printf("%s: Spawning %s %s %s\n", NAME, APP_GETTERM, term, app);
 	
 	/* Wait for the terminal device to be ready */
@@ -213,37 +224,24 @@
 		argv[3] = NULL;
 		
-		if (!task_spawn(APP_GETTERM, argv))
-			printf(NAME ": Error spawning %s with %s %s\n", APP_GETTERM,
-			    term, app);
+		if (!task_spawn(APP_GETTERM, argv, &rc))
+			printf("%s: Error spawning %s %s %s (%s)\n", NAME, APP_GETTERM,
+			    term, app, str_error(rc));
 	} else
-		printf(NAME ": Error waiting on %s\n", term);
-}
-
-static void mount_scratch(void)
-{
-	int rc;
-
-	printf("Trying to mount null/0 on /scratch... ");
-	fflush(stdout);
-
-	rc = mount("tmpfs", "/scratch", "null/0", "", 0);
-	if (rc == EOK)
-		printf("OK\n");
-	else
-		printf("Failed\n");
-}
-
-static void mount_data(void)
-{
-	int rc;
-
-	printf("Trying to mount bd/disk0 on /data... ");
-	fflush(stdout);
-
-	rc = mount("fat", "/data", "bd/disk0", "wtcache", 0);
-	if (rc == EOK)
-		printf("OK\n");
-	else
-		printf("Failed\n");
+		printf("%s: Error waiting on %s (%s)\n", NAME, term,
+		    str_error(rc));
+}
+
+static bool mount_scratch(void)
+{
+	int rc = mount(SCRATCH_FS_TYPE, SCRATCH_MOUNT_POINT, "", "", 0);
+	return mount_report("Scratch filesystem", SCRATCH_MOUNT_POINT,
+	    SCRATCH_FS_TYPE, NULL, rc);
+}
+
+static bool mount_data(void)
+{
+	int rc = mount(DATA_FS_TYPE, DATA_MOUNT_POINT, DATA_DEVICE, "wtcache", 0);
+	return mount_report("Data filesystem", DATA_MOUNT_POINT, DATA_FS_TYPE,
+	    DATA_DEVICE, rc);
 }
 
@@ -253,8 +251,8 @@
 	
 	if (!mount_root(STRING(RDFMT))) {
-		printf(NAME ": Exiting\n");
+		printf("%s: Exiting\n", NAME);
 		return -1;
 	}
-
+	
 	/* Make sure tmpfs is running. */
 	if (str_cmp(STRING(RDFMT), "tmpfs") != 0) {
@@ -266,8 +264,8 @@
 	
 	if (!mount_devfs()) {
-		printf(NAME ": Exiting\n");
+		printf("%s: Exiting\n", NAME);
 		return -2;
 	}
-
+	
 	mount_scratch();
 	
@@ -278,5 +276,5 @@
 	srv_start("/srv/adb_ms");
 	srv_start("/srv/char_ms");
-
+	
 	spawn("/srv/fb");
 	spawn("/srv/kbd");
@@ -284,5 +282,5 @@
 	
 	spawn("/srv/clip");
-
+	
 	/*
 	 * Start these synchronously so that mount_data() can be
@@ -295,5 +293,5 @@
 	(void) srv_start;
 #endif
-
+	
 #ifdef CONFIG_MOUNT_DATA
 	mount_data();
@@ -301,5 +299,5 @@
 	(void) mount_data;
 #endif
-
+	
 	getterm("term/vc0", "/app/bdsh");
 	getterm("term/vc1", "/app/bdsh");
@@ -309,5 +307,5 @@
 	getterm("term/vc5", "/app/bdsh");
 	getterm("term/vc6", "/app/klog");
-
+	
 	return 0;
 }
Index: uspace/app/klog/klog.c
===================================================================
--- uspace/app/klog/klog.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/klog/klog.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -64,5 +64,10 @@
 int main(int argc, char *argv[])
 {
-	size_t klog_pages = sysinfo_value("klog.pages");
+	size_t klog_pages;
+	if (sysinfo_get_value("klog.pages", &klog_pages) != EOK) {
+		printf("%s: Error getting klog address\n", NAME);
+		return -1;
+	}
+	
 	size_t klog_size = klog_pages * PAGE_SIZE;
 	klog_length = klog_size / sizeof(wchar_t);
@@ -70,5 +75,5 @@
 	klog = (wchar_t *) as_get_mappable_page(klog_size);
 	if (klog == NULL) {
-		printf(NAME ": Error allocating memory area\n");
+		printf("%s: Error allocating memory area\n", NAME);
 		return -1;
 	}
@@ -77,10 +82,10 @@
 	    klog_size, SERVICE_MEM_KLOG);
 	if (res != EOK) {
-		printf(NAME ": Error initializing memory area\n");
+		printf("%s: Error initializing memory area\n", NAME);
 		return -1;
 	}
 	
 	if (event_subscribe(EVENT_KLOG, 0) != EOK) {
-		printf(NAME ": Error registering klog notifications\n");
+		printf("%s: Error registering klog notifications\n", NAME);
 		return -1;
 	}
Index: uspace/app/netecho/Makefile
===================================================================
--- uspace/app/netecho/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/netecho/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -35,5 +35,4 @@
 SOURCES = \
 	netecho.c \
-	parse.c \
 	print_error.c
 
Index: uspace/app/netecho/netecho.c
===================================================================
--- uspace/app/netecho/netecho.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/netecho/netecho.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -40,4 +40,5 @@
 #include <str.h>
 #include <task.h>
+#include <arg_parse.h>
 
 #include <in.h>
@@ -46,6 +47,6 @@
 #include <socket.h>
 #include <net_err.h>
-
-#include "parse.h"
+#include <socket_parse.h>
+
 #include "print_error.h"
 
@@ -128,8 +129,4 @@
 	int value;
 
-	// print the program label
-	printf("Task %d - ", task_get_id());
-	printf("%s\n", NAME);
-
 	// parse the command line arguments
 	for(index = 1; index < argc; ++ index){
@@ -137,11 +134,11 @@
 			switch(argv[index][1]){
 				case 'b':
-					ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &backlog, "accepted sockets queue size", 0));
+					ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &backlog, 0));
 					break;
 				case 'c':
-					ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "message count", 0));
+					ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &count, 0));
 					break;
 				case 'f':
-					ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family));
+					ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family));
 					break;
 				case 'h':
@@ -150,16 +147,16 @@
 					break;
 				case 'p':
-					ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 0));
+					ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
 					port = (uint16_t) value;
 					break;
 				case 'r':
-					ERROR_PROPAGATE(parse_parameter_string(argc, argv, &index, &reply, "reply string", 0));
+					ERROR_PROPAGATE(arg_parse_string(argc, argv, &index, &reply, 0));
 					break;
 				case 's':
-					ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "receive size", 0));
+					ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
 					size = (value >= 0) ? (size_t) value : 0;
 					break;
 				case 't':
-					ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, parse_socket_type));
+					ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type));
 					type = (sock_type_t) value;
 					break;
@@ -170,27 +167,26 @@
 				case '-':
 					if(str_lcmp(argv[index] + 2, "backlog=", 6) == 0){
-						ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &backlog, "accepted sockets queue size", 8));
+						ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &backlog, 8));
 					}else if(str_lcmp(argv[index] + 2, "count=", 6) == 0){
-						ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "message count", 8));
+						ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &count, 8));
 					}else if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
-						ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family));
+						ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family));
 					}else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
 						echo_print_help();
 						return EOK;
 					}else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){
-						ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 7));
+						ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7));
 						port = (uint16_t) value;
 					}else if(str_lcmp(argv[index] + 2, "reply=", 6) == 0){
-						ERROR_PROPAGATE(parse_parameter_string(argc, argv, &index, &reply, "reply string", 8));
+						ERROR_PROPAGATE(arg_parse_string(argc, argv, &index, &reply, 8));
 					}else if(str_lcmp(argv[index] + 2, "size=", 5) == 0){
-						ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "receive size", 7));
+						ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7));
 						size = (value >= 0) ? (size_t) value : 0;
 					}else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
-						ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, parse_socket_type));
+						ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type));
 						type = (sock_type_t) value;
 					}else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
 						verbose = 1;
 					}else{
-						print_unrecognized(index, argv[index] + 2);
 						echo_print_help();
 						return EINVAL;
@@ -198,10 +194,8 @@
 					break;
 				default:
-					print_unrecognized(index, argv[index] + 1);
 					echo_print_help();
 					return EINVAL;
 			}
 		}else{
-			print_unrecognized(index, argv[index]);
 			echo_print_help();
 			return EINVAL;
Index: pace/app/netecho/parse.c
===================================================================
--- uspace/app/netecho/parse.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,123 +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 net_app
- *  @{
- */
-
-/** @file
- *  Generic application parsing functions implementation.
- */
-
-#include <stdio.h>
-#include <str.h>
-
-#include <socket.h>
-#include <net_err.h>
-
-#include "parse.h"
-
-int parse_address_family(const char * name){
-	if(str_lcmp(name, "AF_INET", 7) == 0){
-		return AF_INET;
-	}else if(str_lcmp(name, "AF_INET6", 8) == 0){
-		return AF_INET6;
-	}
-	return EAFNOSUPPORT;
-}
-
-int parse_parameter_int(int argc, char ** argv, int * index, int * value, const char * name, int offset){
-	char * rest;
-
-	if(offset){
-		*value = strtol(argv[*index] + offset, &rest, 10);
-	}else if((*index) + 1 < argc){
-		++ (*index);
-		*value = strtol(argv[*index], &rest, 10);
-	}else{
-		fprintf(stderr, "Command line error: missing %s\n", name);
-		return EINVAL;
-	}
-	if(rest && (*rest)){
-		fprintf(stderr, "Command line error: %s unrecognized (%d: %s)\n", name, * index, argv[*index]);
-		return EINVAL;
-	}
-	return EOK;
-}
-
-int parse_parameter_name_int(int argc, char ** argv, int * index, int * value, const char * name, int offset, int (*parse_value)(const char * value)){
-	ERROR_DECLARE;
-
-	char * parameter;
-
-	ERROR_PROPAGATE(parse_parameter_string(argc, argv, index, &parameter, name, offset));
-	*value = (*parse_value)(parameter);
-	if((*value) == ENOENT){
-		fprintf(stderr, "Command line error: unrecognized %s value (%d: %s)\n", name, * index, parameter);
-		return ENOENT;
-	}
-	return EOK;
-}
-
-int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset){
-	if(offset){
-		*value = argv[*index] + offset;
-	}else if((*index) + 1 < argc){
-		++ (*index);
-		*value = argv[*index];
-	}else{
-		fprintf(stderr, "Command line error: missing %s\n", name);
-		return EINVAL;
-	}
-	return EOK;
-}
-
-int parse_protocol_family(const char * name){
-	if(str_lcmp(name, "PF_INET", 7) == 0){
-		return PF_INET;
-	}else if(str_lcmp(name, "PF_INET6", 8) == 0){
-		return PF_INET6;
-	}
-	return EPFNOSUPPORT;
-}
-
-int parse_socket_type(const char * name){
-	if(str_lcmp(name, "SOCK_DGRAM", 11) == 0){
-		return SOCK_DGRAM;
-	}else if(str_lcmp(name, "SOCK_STREAM", 12) == 0){
-		return SOCK_STREAM;
-	}
-	return ESOCKTNOSUPPORT;
-}
-
-void print_unrecognized(int index, const char * parameter){
-	fprintf(stderr, "Command line error: unrecognized argument (%d: %s)\n", index, parameter);
-}
-
-/** @}
- */
Index: pace/app/netecho/parse.h
===================================================================
--- uspace/app/netecho/parse.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,120 +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 net_app
- *  @{
- */
-
-/** @file
- *  Generic command line arguments parsing functions.
- */
-
-#ifndef __NET_APP_PARSE__
-#define __NET_APP_PARSE__
-
-#include <socket.h>
-
-/** Translates the character string to the address family number.
- *  @param[in] name The address family name.
- *  @returns The corresponding address family number.
- *  @returns EAFNOSUPPORTED if the address family is not supported.
- */
-extern int parse_address_family(const char * name);
-
-/** Parses the next parameter as an integral number.
- *  The actual parameter is pointed by the index.
- *  Parses the offseted actual parameter value if the offset is set or the next one if not.
- *  @param[in] argc The total number of the parameters.
- *  @param[in] argv The parameters.
- *  @param[in,out] index The actual parameter index. The index is incremented by the number of processed parameters.
- *  @param[out] value The parsed parameter value.
- *  @param[in] name The parameter name to be printed on errors.
- *  @param[in] offset The value offset in the actual parameter. If not set, the next parameter is parsed instead.
- *  @returns EOK on success.
- *  @returns EINVAL if the parameter is missing.
- *  @returns EINVAL if the parameter is in wrong format.
- */
-extern int parse_parameter_int(int argc, char ** argv, int * index, int * value, const char * name, int offset);
-
-/** Parses the next named parameter as an integral number.
- *  The actual parameter is pointed by the index.
- *  Uses the offseted actual parameter if the offset is set or the next one if not.
- *  Translates the parameter using the parse_value function.
- *  Increments the actual index by the number of processed parameters.
- *  @param[in] argc The total number of the parameters.
- *  @param[in] argv The parameters.
- *  @param[in,out] index The actual parameter index. The index is incremented by the number of processed parameters.
- *  @param[out] value The parsed parameter value.
- *  @param[in] name The parameter name to be printed on errors.
- *  @param[in] offset The value offset in the actual parameter. If not set, the next parameter is parsed instead.
- *  @param[in] parse_value The translation function to parse the named value.
- *  @returns EOK on success.
- *  @returns EINVAL if the parameter is missing.
- *  @returns ENOENT if the parameter name has not been found.
- */
-extern int parse_parameter_name_int(int argc, char ** argv, int * index, int * value, const char * name, int offset, int (*parse_value)(const char * value));
-
-/** Parses the next parameter as a character string.
- *  The actual parameter is pointed by the index.
- *  Uses the offseted actual parameter value if the offset is set or the next one if not.
- *  Increments the actual index by the number of processed parameters.
- *  @param[in] argc The total number of the parameters.
- *  @param[in] argv The parameters.
- *  @param[in,out] index The actual parameter index. The index is incremented by the number of processed parameters.
- *  @param[out] value The parsed parameter value.
- *  @param[in] name The parameter name to be printed on errors.
- *  @param[in] offset The value offset in the actual parameter. If not set, the next parameter is parsed instead.
- *  @returns EOK on success.
- *  @returns EINVAL if the parameter is missing.
- */
-extern int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset);
-
-/** Translates the character string to the protocol family number.
- *  @param[in] name The protocol family name.
- *  @returns The corresponding protocol family number.
- *  @returns EPFNOSUPPORTED if the protocol family is not supported.
- */
-extern int parse_protocol_family(const char * name);
-
-/** Translates the character string to the socket type number.
- *  @param[in] name The socket type name.
- *  @returns The corresponding socket type number.
- *  @returns ESOCKNOSUPPORTED if the socket type is not supported.
- */
-extern int parse_socket_type(const char * name);
-
-/** Prints the parameter unrecognized message and the application help.
- *  @param[in] index The index of the parameter.
- *  @param[in] parameter The parameter name.
- */
-extern void print_unrecognized(int index, const char * parameter);
-
-#endif
-
-/** @}
- */
Index: uspace/app/nettest1/Makefile
===================================================================
--- uspace/app/nettest1/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/nettest1/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -36,5 +36,4 @@
 	nettest1.c \
 	nettest.c \
-	parse.c \
 	print_error.c
 
Index: uspace/app/nettest1/nettest1.c
===================================================================
--- uspace/app/nettest1/nettest1.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/nettest1/nettest1.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -40,4 +40,5 @@
 #include <task.h>
 #include <time.h>
+#include <arg_parse.h>
 
 #include <in.h>
@@ -46,7 +47,7 @@
 #include <socket.h>
 #include <net_err.h>
+#include <socket_parse.h>
 
 #include "nettest.h"
-#include "parse.h"
 #include "print_error.h"
 
@@ -105,8 +106,4 @@
 	struct timeval time_after;
 
-	// print the program label
-	printf("Task %d - ", task_get_id());
-	printf("%s\n", NAME);
-
 	// parse the command line arguments
 	// stop before the last argument if it does not start with the minus sign ('-')
@@ -117,5 +114,5 @@
 				// short options with only one letter
 				case 'f':
-					ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family));
+					ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family));
 					break;
 				case 'h':
@@ -124,19 +121,19 @@
 					break;
 				case 'm':
-					ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &messages, "message count", 0));
+					ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 0));
 					break;
 				case 'n':
-					ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &sockets, "socket count", 0));
+					ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 0));
 					break;
 				case 'p':
-					ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 0));
+					ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
 					port = (uint16_t) value;
 					break;
 				case 's':
-					ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "packet size", 0));
+					ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
 					size = (value >= 0) ? (size_t) value : 0;
 					break;
 				case 't':
-					ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, parse_socket_type));
+					ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type));
 					type = (sock_type_t) value;
 					break;
@@ -147,22 +144,21 @@
 				case '-':
 					if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
-						ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family));
+						ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family));
 					}else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
 						nettest1_print_help();
 						return EOK;
 					}else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){
-						ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &messages, "message count", 8));
+						ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 8));
 					}else if(str_lcmp(argv[index] + 2, "sockets=", 6) == 0){
-						ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &sockets, "socket count", 8));
+						ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 8));
 					}else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){
-						ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 7));
+						ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7));
 						port = (uint16_t) value;
 					}else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
-						ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, parse_socket_type));
+						ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type));
 						type = (sock_type_t) value;
 					}else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
 						verbose = 1;
 					}else{
-						print_unrecognized(index, argv[index] + 2);
 						nettest1_print_help();
 						return EINVAL;
@@ -170,10 +166,8 @@
 					break;
 				default:
-					print_unrecognized(index, argv[index] + 1);
 					nettest1_print_help();
 					return EINVAL;
 			}
 		}else{
-			print_unrecognized(index, argv[index]);
 			nettest1_print_help();
 			return EINVAL;
Index: pace/app/nettest1/parse.c
===================================================================
--- uspace/app/nettest1/parse.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,1 +1,0 @@
-../netecho/parse.c
Index: pace/app/nettest1/parse.h
===================================================================
--- uspace/app/nettest1/parse.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,1 +1,0 @@
-../netecho/parse.h
Index: uspace/app/nettest2/Makefile
===================================================================
--- uspace/app/nettest2/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/nettest2/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -36,5 +36,4 @@
 	nettest2.c \
 	nettest.c \
-	parse.c \
 	print_error.c
 
Index: uspace/app/nettest2/nettest2.c
===================================================================
--- uspace/app/nettest2/nettest2.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/nettest2/nettest2.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -40,4 +40,5 @@
 #include <task.h>
 #include <time.h>
+#include <arg_parse.h>
 
 #include <in.h>
@@ -46,7 +47,7 @@
 #include <socket.h>
 #include <net_err.h>
+#include <socket_parse.h>
 
 #include "nettest.h"
-#include "parse.h"
 #include "print_error.h"
 
@@ -105,7 +106,4 @@
 	struct timeval time_after;
 
-	printf("Task %d - ", task_get_id());
-	printf("%s\n", NAME);
-
 	// parse the command line arguments
 	// stop before the last argument if it does not start with the minus sign ('-')
@@ -116,5 +114,5 @@
 				// short options with only one letter
 				case 'f':
-					ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family));
+					ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family));
 					break;
 				case 'h':
@@ -123,19 +121,19 @@
 					break;
 				case 'm':
-					ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &messages, "message count", 0));
+					ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 0));
 					break;
 				case 'n':
-					ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &sockets, "socket count", 0));
+					ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 0));
 					break;
 				case 'p':
-					ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 0));
+					ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
 					port = (uint16_t) value;
 					break;
 				case 's':
-					ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "packet size", 0));
+					ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
 					size = (value >= 0) ? (size_t) value : 0;
 					break;
 				case 't':
-					ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, parse_socket_type));
+					ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type));
 					type = (sock_type_t) value;
 					break;
@@ -146,22 +144,21 @@
 				case '-':
 					if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
-						ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family));
+						ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family));
 					}else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
 						nettest2_print_help();
 						return EOK;
 					}else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){
-						ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &messages, "message count", 8));
+						ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 8));
 					}else if(str_lcmp(argv[index] + 2, "sockets=", 6) == 0){
-						ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &sockets, "socket count", 8));
+						ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 8));
 					}else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){
-						ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 7));
+						ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7));
 						port = (uint16_t) value;
 					}else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
-						ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, parse_socket_type));
+						ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type));
 						type = (sock_type_t) value;
 					}else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
 						verbose = 1;
 					}else{
-						print_unrecognized(index, argv[index] + 2);
 						nettest2_print_help();
 						return EINVAL;
@@ -169,10 +166,8 @@
 					break;
 				default:
-					print_unrecognized(index, argv[index] + 1);
 					nettest2_print_help();
 					return EINVAL;
 			}
 		}else{
-			print_unrecognized(index, argv[index]);
 			nettest2_print_help();
 			return EINVAL;
Index: pace/app/nettest2/parse.c
===================================================================
--- uspace/app/nettest2/parse.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,1 +1,0 @@
-../netecho/parse.c
Index: pace/app/nettest2/parse.h
===================================================================
--- uspace/app/nettest2/parse.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,1 +1,0 @@
-../netecho/parse.h
Index: uspace/app/ping/Makefile
===================================================================
--- uspace/app/ping/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/ping/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -35,5 +35,4 @@
 SOURCES = \
 	ping.c \
-	parse.c \
 	print_error.c
 
Index: pace/app/ping/parse.c
===================================================================
--- uspace/app/ping/parse.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,1 +1,0 @@
-../netecho/parse.c
Index: pace/app/ping/parse.h
===================================================================
--- uspace/app/ping/parse.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,1 +1,0 @@
-../netecho/parse.h
Index: uspace/app/ping/ping.c
===================================================================
--- uspace/app/ping/ping.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/ping/ping.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -28,9 +28,9 @@
 
 /** @addtogroup ping
- *  @{
+ * @{
  */
 
 /** @file
- *  Ping application.
+ * Packet Internet Network Grouper.
  */
 
@@ -41,4 +41,6 @@
 #include <ipc/ipc.h>
 #include <ipc/services.h>
+#include <str_error.h>
+#include <arg_parse.h>
 
 #include <icmp_api.h>
@@ -48,254 +50,349 @@
 #include <ip_codes.h>
 #include <socket_errno.h>
-#include <net_err.h>
-
-#include "parse.h"
+#include <socket_parse.h>
+
 #include "print_error.h"
 
-/** Echo module name.
- */
-#define NAME	"Ping"
-
-/** Module entry point.
- *  Reads command line parameters and pings.
- *  @param[in] argc The number of command line parameters.
- *  @param[in] argv The command line parameters.
- *  @returns EOK on success.
- */
-int main(int argc, char * argv[]);
-
-/** Prints the application help.
- */
-void ping_print_help(void);
-
-int main(int argc, char * argv[]){
-	ERROR_DECLARE;
-
-	size_t size			= 38;
-	int verbose			= 0;
-	int dont_fragment	= 0;
-	ip_ttl_t ttl		= 0;
-	ip_tos_t tos		= 0;
-	int count			= 3;
-	suseconds_t timeout	= 3000;
-	int family			= AF_INET;
-
-	socklen_t max_length				= sizeof(struct sockaddr_in6);
-	uint8_t address_data[max_length];
-	struct sockaddr * address			= (struct sockaddr *) address_data;
-	struct sockaddr_in * address_in		= (struct sockaddr_in *) address;
-	struct sockaddr_in6 * address_in6	= (struct sockaddr_in6 *) address;
-	socklen_t addrlen;
-	char address_string[INET6_ADDRSTRLEN];
-	uint8_t * address_start;
-	int icmp_phone;
-	struct timeval time_before;
-	struct timeval time_after;
-	int result;
-	int value;
-	int index;
-
-	// print the program label
-	printf("Task %d - ", task_get_id());
-	printf("%s\n", NAME);
-
-	// parse the command line arguments
-	// stop before the last argument if it does not start with the minus sign ('-')
-	for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){
-		// options should start with the minus sign ('-')
-		if(argv[index][0] == '-'){
-			switch(argv[index][1]){
-				// short options with only one letter
-				case 'c':
-					ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "count", 0));
-					break;
-				case 'f':
-					ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "address family", 0, parse_address_family));
-					break;
-				case 'h':
-					ping_print_help();
-					return EOK;
-					break;
-				case 's':
-					ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "packet size", 0));
-					size = (value >= 0) ? (size_t) value : 0;
-					break;
-				case 't':
-					ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "timeout", 0));
-					timeout = (value >= 0) ? (suseconds_t) value : 0;
-					break;
-				case 'v':
-					verbose = 1;
-					break;
-				// long options with the double minus sign ('-')
-				case '-':
-					if(str_lcmp(argv[index] + 2, "count=", 6) == 0){
-						ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "received count", 8));
-					}else if(str_lcmp(argv[index] + 2, "dont_fragment", 13) == 0){
-						dont_fragment = 1;
-					}else if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
-						ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "address family", 9, parse_address_family));
-					}else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
-						ping_print_help();
-						return EOK;
-					}else if(str_lcmp(argv[index] + 2, "size=", 5) == 0){
-						ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "packet size", 7));
-						size = (value >= 0) ? (size_t) value : 0;
-					}else if(str_lcmp(argv[index] + 2, "timeout=", 8) == 0){
-						ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "timeout", 7));
-						timeout = (value >= 0) ? (suseconds_t) value : 0;
-					}else if(str_lcmp(argv[index] + 2, "tos=", 4) == 0){
-						ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "type of service", 7));
-						tos = (value >= 0) ? (ip_tos_t) value : 0;
-					}else if(str_lcmp(argv[index] + 2, "ttl=", 4) == 0){
-						ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "time to live", 7));
-						ttl = (value >= 0) ? (ip_ttl_t) value : 0;
-					}else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
-						verbose = 1;
-					}else{
-						print_unrecognized(index, argv[index] + 2);
-						ping_print_help();
-						return EINVAL;
-					}
-					break;
-				default:
-					print_unrecognized(index, argv[index] + 1);
-					ping_print_help();
-					return EINVAL;
-			}
-		}else{
-			print_unrecognized(index, argv[index]);
-			ping_print_help();
-			return EINVAL;
-		}
-	}
-
-	// if not before the last argument containing the address
-	if(index >= argc){
-		printf("Command line error: missing address\n");
-		ping_print_help();
-		return EINVAL;
-	}
-
-	// prepare the address buffer
-	bzero(address_data, max_length);
-	switch(family){
-		case AF_INET:
-			address_in->sin_family = AF_INET;
-			address_start = (uint8_t *) &address_in->sin_addr.s_addr;
-			addrlen = sizeof(struct sockaddr_in);
+#define NAME  "ping"
+
+#define CL_OK           0
+#define CL_USAGE        -1
+#define CL_MISSING      -2
+#define CL_INVALID      -3
+#define CL_UNSUPPORTED  -4
+#define CL_ERROR        -5
+
+/** Ping configuration
+ *
+ */
+typedef struct {
+	bool verbose;               /**< Verbose printouts. */
+	size_t size;                /**< Outgoing packet size. */
+	unsigned int count;         /**< Number of packets to send. */
+	suseconds_t timeout;        /**< Reply wait timeout. */
+	int af;                     /**< Address family. */
+	ip_tos_t tos;               /**< Type of service. */
+	ip_ttl_t ttl;               /**< Time-to-live. */
+	bool fragments;             /**< Fragmentation. */
+	
+	char *dest_addr;            /**< Destination address. */
+	struct sockaddr_in dest;    /**< IPv4 destionation. */
+	struct sockaddr_in6 dest6;  /**< IPv6 destionation. */
+	
+	struct sockaddr *dest_raw;  /**< Raw destination address. */
+	socklen_t dest_len;         /**< Raw destination address length. */
+	
+	/** Converted address string. */
+	char dest_str[INET6_ADDRSTRLEN];
+} ping_config_t;
+
+
+static void usage(void)
+{
+	printf(
+	    "Usage: ping [-c count] [-s size] [-W timeout] [-f family] [-t ttl]\n" \
+	    "            [-Q tos] [--dont_fragment] destination\n" \
+	    "\n" \
+	    "Options:\n" \
+	    "\t-c count\n" \
+	    "\t--count=count\n" \
+	    "\t\tNumber of outgoing packets (default: 4)\n" \
+	    "\n" \
+	    "\t-s size\n" \
+	    "\t--size=bytes\n" \
+	    "\t\tOutgoing packet size (default: 56 bytes)\n" \
+	    "\n" \
+	    "\t-W timeout\n" \
+	    "\t--timeout=ms\n" \
+	    "\t\tReply wait timeout (default: 3000 ms)\n" \
+	    "\n" \
+	    "\t-f family\n" \
+	    "\t--family=family\n" \
+	    "\t\tDestination address family, AF_INET or AF_INET6 (default: AF_INET)\n" \
+	    "\n" \
+	    "\t-t ttl\n" \
+	    "\t--ttl=ttl\n" \
+	    "\t\tOutgoing packet time-to-live (default: 0)\n" \
+	    "\n" \
+	    "\t-Q tos\n" \
+	    "\t--tos=tos\n" \
+	    "\t\tOutgoing packet type of service (default: 0)\n" \
+	    "\n" \
+	    "\t--dont_fragment\n" \
+	    "\t\tDisable packet fragmentation (default: enabled)\n" \
+	    "\n" \
+	    "\t-v\n" \
+	    "\t--verbose\n" \
+	    "\t\tVerbose operation\n" \
+	    "\n" \
+	    "\t-h\n" \
+	    "\t--help\n" \
+	    "\t\tPrint this usage information\n"
+	);
+}
+
+static int args_parse(int argc, char *argv[], ping_config_t *config)
+{
+	if (argc < 2)
+		return CL_USAGE;
+	
+	int i;
+	int ret;
+	
+	for (i = 1; i < argc; i++) {
+		
+		/* Not an option */
+		if (argv[i][0] != '-')
 			break;
-		case AF_INET6:
-			address_in6->sin6_family = AF_INET6;
-			address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
-			addrlen = sizeof(struct sockaddr_in6);
+		
+		/* Options terminator */
+		if (str_cmp(argv[i], "--") == 0) {
+			i++;
+			break;
+		}
+		
+		int off;
+		
+		/* Usage */
+		if ((off = arg_parse_short_long(argv[i], "-h", "--help")) != -1)
+			return CL_USAGE;
+		
+		/* Verbose */
+		if ((off = arg_parse_short_long(argv[i], "-v", "--verbose")) != -1) {
+			config->verbose = true;
+			continue;
+		}
+		
+		/* Don't fragment */
+		if (str_cmp(argv[i], "--dont_fragment") == 0) {
+			config->fragments = false;
+			continue;
+		}
+		
+		/* Count */
+		if ((off = arg_parse_short_long(argv[i], "-c", "--count=")) != -1) {
+			int tmp;
+			ret = arg_parse_int(argc, argv, &i, &tmp, off);
+			
+			if ((ret != EOK) || (tmp < 0))
+				return i;
+			
+			config->count = (unsigned int) tmp;
+			continue;
+		}
+		
+		/* Outgoing packet size */
+		if ((off = arg_parse_short_long(argv[i], "-s", "--size=")) != -1) {
+			int tmp;
+			ret = arg_parse_int(argc, argv, &i, &tmp, off);
+			
+			if ((ret != EOK) || (tmp < 0))
+				return i;
+			
+			config->size = (size_t) tmp;
+			continue;
+		}
+		
+		/* Reply wait timeout */
+		if ((off = arg_parse_short_long(argv[i], "-W", "--timeout=")) != -1) {
+			int tmp;
+			ret = arg_parse_int(argc, argv, &i, &tmp, off);
+			
+			if ((ret != EOK) || (tmp < 0))
+				return i;
+			
+			config->timeout = (suseconds_t) tmp;
+			continue;
+		}
+		
+		/* Address family */
+		if ((off = arg_parse_short_long(argv[i], "-f", "--family=")) != -1) {
+			ret = arg_parse_name_int(argc, argv, &i, &config->af, off,
+			    socket_parse_address_family);
+			
+			if (ret != EOK)
+				return i;
+			
+			continue;
+		}
+		
+		/* Type of service */
+		if ((off = arg_parse_short_long(argv[i], "-Q", "--tos=")) != -1) {
+			int tmp;
+			ret = arg_parse_name_int(argc, argv, &i, &tmp, off,
+			    socket_parse_address_family);
+			
+			if ((ret != EOK) || (tmp < 0))
+				return i;
+			
+			config->tos = (ip_tos_t) tmp;
+			continue;
+		}
+		
+		/* Time to live */
+		if ((off = arg_parse_short_long(argv[i], "-t", "--ttl=")) != -1) {
+			int tmp;
+			ret = arg_parse_name_int(argc, argv, &i, &tmp, off,
+			    socket_parse_address_family);
+			
+			if ((ret != EOK) || (tmp < 0))
+				return i;
+			
+			config->ttl = (ip_ttl_t) tmp;
+			continue;
+		}
+	}
+	
+	if (i >= argc)
+		return CL_MISSING;
+	
+	config->dest_addr = argv[i];
+	
+	/* Resolve destionation address */
+	switch (config->af) {
+	case AF_INET:
+		config->dest_raw = (struct sockaddr *) &config->dest;
+		config->dest_len = sizeof(config->dest);
+		config->dest.sin_family = config->af;
+		ret = inet_pton(config->af, config->dest_addr,
+		    (uint8_t *) &config->dest.sin_addr.s_addr);
+		break;
+	case AF_INET6:
+		config->dest_raw = (struct sockaddr *) &config->dest6;
+		config->dest_len = sizeof(config->dest6);
+		config->dest6.sin6_family = config->af;
+		ret = inet_pton(config->af, config->dest_addr,
+		    (uint8_t *) &config->dest6.sin6_addr.s6_addr);
+		break;
+	default:
+		return CL_UNSUPPORTED;
+	}
+	
+	if (ret != EOK)
+		return CL_INVALID;
+	
+	/* Convert destination address back to string */
+	switch (config->af) {
+	case AF_INET:
+		ret = inet_ntop(config->af,
+		    (uint8_t *) &config->dest.sin_addr.s_addr,
+		    config->dest_str, sizeof(config->dest_str));
+		break;
+	case AF_INET6:
+		ret = inet_ntop(config->af,
+		    (uint8_t *) &config->dest6.sin6_addr.s6_addr,
+		    config->dest_str, sizeof(config->dest_str));
+		break;
+	default:
+		return CL_UNSUPPORTED;
+	}
+	
+	if (ret != EOK)
+		return CL_ERROR;
+	
+	return CL_OK;
+}
+
+int main(int argc, char *argv[])
+{
+	ping_config_t config;
+	
+	/* Default configuration */
+	config.verbose = false;
+	config.size = 56;
+	config.count = 4;
+	config.timeout = 3000;
+	config.af = AF_INET;
+	config.tos = 0;
+	config.ttl = 0;
+	config.fragments = true;
+	
+	int ret = args_parse(argc, argv, &config);
+	
+	switch (ret) {
+	case CL_OK:
+		break;
+	case CL_USAGE:
+		usage();
+		return 0;
+	case CL_MISSING:
+		fprintf(stderr, "%s: Destination address missing\n", NAME);
+		return 1;
+	case CL_INVALID:
+		fprintf(stderr, "%s: Destination address '%s' invalid or malformed\n",
+		    NAME, config.dest_addr);
+		return 2;
+	case CL_UNSUPPORTED:
+		fprintf(stderr, "%s: Destination address '%s' unsupported\n",
+		    NAME, config.dest_addr);
+		return 3;
+	case CL_ERROR:
+		fprintf(stderr, "%s: Destination address '%s' error\n",
+		    NAME, config.dest_addr);
+		return 4;
+	default:
+		fprintf(stderr, "%s: Unknown or invalid option '%s'\n", NAME,
+		    argv[ret]);
+		return 5;
+	}
+	
+	printf("PING %s (%s) %u(%u) bytes of data\n", config.dest_addr,
+	    config.dest_str, config.size, config.size);
+	
+	int icmp_phone = icmp_connect_module(SERVICE_ICMP, ICMP_CONNECT_TIMEOUT);
+	if (icmp_phone < 0) {
+		fprintf(stderr, "%s: Unable to connect to ICMP service (%s)\n", NAME,
+		    str_error(icmp_phone));
+		return icmp_phone;
+	}
+	
+	unsigned int seq;
+	for (seq = 0; seq < config.count; seq++) {
+		struct timeval t0;
+		ret = gettimeofday(&t0, NULL);
+		if (ret != EOK) {
+			fprintf(stderr, "%s: gettimeofday failed (%s)\n", NAME,
+			    str_error(ret));
+			
+			ipc_hangup(icmp_phone);
+			return ret;
+		}
+		
+		/* Ping! */
+		int result = icmp_echo_msg(icmp_phone, config.size, config.timeout,
+		    config.ttl, config.tos, !config.fragments, config.dest_raw,
+		    config.dest_len);
+		
+		struct timeval t1;
+		ret = gettimeofday(&t1, NULL);
+		if (ret != EOK) {
+			fprintf(stderr, "%s: gettimeofday failed (%s)\n", NAME,
+			    str_error(ret));
+			
+			ipc_hangup(icmp_phone);
+			return ret;
+		}
+		
+		suseconds_t elapsed = tv_sub(&t1, &t0);
+		
+		switch (result) {
+		case ICMP_ECHO:
+			printf("%u bytes from ? (?): icmp_seq=%u ttl=? time=%u.%04u\n",
+				config.size, seq, elapsed / 1000, elapsed % 1000);
+			break;
+		case ETIMEOUT:
+			printf("%u bytes from ? (?): icmp_seq=%u Timed out\n",
+				config.size, seq);
 			break;
 		default:
-			fprintf(stderr, "Address family is not supported\n");
-			return EAFNOSUPPORT;
-	}
-
-	// parse the last argument which should contain the address
-	if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){
-		fprintf(stderr, "Address parse error %d\n", ERROR_CODE);
-		return ERROR_CODE;
-	}
-
-	// connect to the ICMP module
-	icmp_phone = icmp_connect_module(SERVICE_ICMP, ICMP_CONNECT_TIMEOUT);
-	if(icmp_phone < 0){
-		fprintf(stderr, "ICMP connect error %d\n", icmp_phone);
-		return icmp_phone;
-	}
-
-	// print the ping header
-	printf("PING %d bytes of data\n", size);
-	if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){
-		fprintf(stderr, "Address error %d\n", ERROR_CODE);
-	}else{
-		printf("Address %s:\n", address_string);
-	}
-
-	// do count times
-	while(count > 0){
-
-		// get the starting time
-		if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){
-			fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
-			// release the ICMP phone
-			ipc_hangup(icmp_phone);
-			return ERROR_CODE;
-		}
-
-		// request the ping
-		result = icmp_echo_msg(icmp_phone, size, timeout, ttl, tos, dont_fragment, address, addrlen);
-
-		// get the ending time
-		if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){
-			fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
-			// release the ICMP phone
-			ipc_hangup(icmp_phone);
-			return ERROR_CODE;
-		}
-
-		// print the result
-		switch(result){
-			case ICMP_ECHO:
-				printf("Ping round trip time %d miliseconds\n", tv_sub(&time_after, &time_before) / 1000);
-				break;
-			case ETIMEOUT:
-				printf("Timed out.\n");
-				break;
-			default:
-				print_error(stdout, result, NULL, "\n");
-		}
-		-- count;
-	}
-
-	if(verbose){
-		printf("Exiting\n");
-	}
-
-	// release the ICMP phone
+			print_error(stdout, result, NULL, "\n");
+		}
+	}
+	
 	ipc_hangup(icmp_phone);
-
-	return EOK;
+	
+	return 0;
 }
 
-void ping_print_help(void){
-	printf(
-		"Network Ping aplication\n" \
-		"Usage: ping [options] numeric_address\n" \
-		"Where options are:\n" \
-		"\n" \
-		"-c request_count | --count=request_count\n" \
-		"\tThe number of packets the application sends. The default is three (3).\n" \
-		"\n" \
-		"--dont_fragment\n" \
-		"\tDisable packet fragmentation.\n"
-		"\n" \
-		"-f address_family | --family=address_family\n" \
-		"\tThe given address family. Only the AF_INET and AF_INET6 are supported.\n"
-		"\n" \
-		"-h | --help\n" \
-		"\tShow this application help.\n"
-		"\n" \
-		"-s packet_size | --size=packet_size\n" \
-		"\tThe packet data size the application sends. The default is 38 bytes.\n" \
-		"\n" \
-		"-t timeout | --timeout=timeout\n" \
-		"\tThe number of miliseconds the application waits for a reply. The default is three thousands (3 000).\n" \
-		"\n" \
-		"--tos=tos\n" \
-		"\tThe type of service to be used.\n" \
-		"\n" \
-		"--ttl=ttl\n" \
-		"\tThe time to live to be used.\n" \
-		"\n" \
-		"-v | --verbose\n" \
-		"\tShow all output messages.\n"
-	);
-}
-
 /** @}
  */
Index: uspace/app/redir/redir.c
===================================================================
--- uspace/app/redir/redir.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/redir/redir.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -42,8 +42,12 @@
 #include <stdio.h>
 #include <task.h>
+#include <str_error.h>
+
+#define NAME  "redir"
 
 static void usage(void)
 {
-	printf("Usage: redir [-i <stdin>] [-o <stdout>] [-e <stderr>] -- <cmd> [args ...]\n");
+	printf("Usage: %s [-i <stdin>] [-o <stdout>] [-e <stderr>] -- <cmd> [args ...]\n",
+	    NAME);
 }
 
@@ -84,10 +88,12 @@
 	args[argc] = NULL;
 	
-	task_id_t id = task_spawn(argv[0], args);
+	int err;
+	task_id_t id = task_spawn(argv[0], args, &err);
 	
 	free(args);
 	
 	if (id == 0)
-		printf("Error spawning %s\n", argv[0]);
+		printf("%s: Error spawning %s (%s)\n", NAME, argv[0],
+		    str_error(err));
 	
 	return id;
Index: uspace/app/sbi/src/os/helenos.c
===================================================================
--- uspace/app/sbi/src/os/helenos.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/sbi/src/os/helenos.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -35,4 +35,5 @@
 #include <task.h>
 #include <tinput.h>
+#include <str_error.h>
 
 #include "os.h"
@@ -186,7 +187,8 @@
 	int retval;
 
-	tid = task_spawn(cmd[0], (char const * const *) cmd);
+	tid = task_spawn(cmd[0], (char const * const *) cmd, &retval);
 	if (tid == 0) {
-		printf("Error: Failed spawning '%s'.\n", cmd[0]);
+		printf("Error: Failed spawning '%s' (%s).\n", cmd[0],
+		    str_error(retval));
 		exit(1);
 	}
Index: uspace/app/sbi/src/run_expr.c
===================================================================
--- uspace/app/sbi/src/run_expr.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/sbi/src/run_expr.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -1434,4 +1434,6 @@
 		addr_prop->u.named->prop_d = deleg_p;
 		break;
+	default:
+		ritem = NULL;
 	}
 
Index: uspace/app/stats/Makefile
===================================================================
--- uspace/app/stats/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/app/stats/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -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 = stats
+
+SOURCES = \
+	stats.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/stats/stats.c
===================================================================
--- uspace/app/stats/stats.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/app/stats/stats.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010 Stanislav Kozina
+ * 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 stats
+ * @brief Print system statistics.
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <stats.h>
+#include <sys/time.h>
+#include <inttypes.h>
+#include <malloc.h>
+
+#define NAME  "sysstat"
+
+#define DAY     86400
+#define HOUR    3600
+#define MINUTE  60
+
+int main(int argc, char *argv[])
+{
+	struct timeval time;
+	if (gettimeofday(&time, NULL) != 0) {
+		fprintf(stderr, "%s: Cannot get time of day\n", NAME);
+		return -1;
+	}
+	
+	uint64_t sec = time.tv_sec;
+	printf("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64, (sec % DAY) / HOUR,
+	    (sec % HOUR) / MINUTE, sec % MINUTE);
+	
+	sysarg_t uptime = stats_get_uptime();
+	printf(", up %u days, %u hours, %u minutes, %u seconds", uptime / DAY,
+	    (uptime % DAY) / HOUR, (uptime % HOUR) / MINUTE, uptime % MINUTE);
+	
+	size_t count;
+	load_t *load = stats_get_load(&count);
+	if (load != NULL) {
+		printf(", load average: ");
+		
+		size_t i;
+		for (i = 0; i < count; i++) {
+			if (i > 0)
+				printf(" ");
+			
+			stats_print_load_fragment(load[i], 2);
+		}
+		
+		free(load);
+	}
+	
+	printf("\n");
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/tasks/Makefile
===================================================================
--- uspace/app/tasks/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/app/tasks/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -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 = tasks
+
+SOURCES = \
+	tasks.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/tasks/tasks.c
===================================================================
--- uspace/app/tasks/tasks.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/app/tasks/tasks.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2010 Stanislav Kozina
+ * Copyright (c) 2010 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 tasks
+ * @brief Task lister.
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <task.h>
+#include <thread.h>
+#include <stats.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <inttypes.h>
+#include <bool.h>
+#include <str.h>
+#include <arg_parse.h>
+
+#define NAME  "tasks"
+
+#define TASK_COUNT    10
+#define THREAD_COUNT  50
+
+#define PRINT_LOAD1(x)  ((x) >> 11)
+#define PRINT_LOAD2(x)  (((x) & 0x7ff) / 2)
+
+static void list_tasks(void)
+{
+	size_t count;
+	stats_task_t *stats_tasks = stats_get_tasks(&count);
+	
+	if (stats_tasks == NULL) {
+		fprintf(stderr, "%s: Unable to get tasks\n", NAME);
+		return;
+	}
+	
+	printf("      ID  Threads      Mem       uCycles       kCycles   Name\n");
+	
+	size_t i;
+	for (i = 0; i < count; i++) {
+		uint64_t virtmem, ucycles, kcycles;
+		char vmsuffix, usuffix, ksuffix;
+		
+		order_suffix(stats_tasks[i].virtmem, &virtmem, &vmsuffix);
+		order_suffix(stats_tasks[i].ucycles, &ucycles, &usuffix);
+		order_suffix(stats_tasks[i].kcycles, &kcycles, &ksuffix);
+		
+		printf("%8" PRIu64 "%8u %8" PRIu64"%c %12"
+		    PRIu64 "%c %12" PRIu64 "%c %s\n", stats_tasks[i].task_id,
+		    stats_tasks[i].threads, virtmem, vmsuffix, ucycles, usuffix,
+		    kcycles, ksuffix, stats_tasks[i].name);
+	}
+	
+	free(stats_tasks);
+}
+
+static void list_threads(task_id_t task_id, bool all)
+{
+	size_t count;
+	stats_thread_t *stats_threads = stats_get_threads(&count);
+	
+	if (stats_threads == NULL) {
+		fprintf(stderr, "%s: Unable to get threads\n", NAME);
+		return;
+	}
+	
+	printf("    ID    State  CPU   Prio    [k]uCycles    [k]kcycles   Cycle fault\n");
+	size_t i;
+	for (i = 0; i < count; i++) {
+		if ((all) || (stats_threads[i].task_id == task_id)) {
+			uint64_t ucycles, kcycles;
+			char usuffix, ksuffix;
+			
+			order_suffix(stats_threads[i].ucycles, &ucycles, &usuffix);
+			order_suffix(stats_threads[i].kcycles, &kcycles, &ksuffix);
+			
+			if (stats_threads[i].on_cpu) {
+				printf("%8" PRIu64 " %-8s %4u %6d %12"
+				    PRIu64"%c %12" PRIu64"%c\n", stats_threads[i].thread_id,
+				    thread_get_state(stats_threads[i].state),
+				    stats_threads[i].cpu, stats_threads[i].priority,
+				    ucycles, usuffix, kcycles, ksuffix);
+			} else {
+				printf("%8" PRIu64 " %-8s ---- %6d %12"
+				    PRIu64"%c %12" PRIu64"%c\n", stats_threads[i].thread_id,
+				    thread_get_state(stats_threads[i].state),
+				    stats_threads[i].priority,
+				    ucycles, usuffix, kcycles, ksuffix);
+			}
+		}
+	}
+	
+	free(stats_threads);
+}
+
+static void print_load(void)
+{
+	size_t count;
+	load_t *load = stats_get_load(&count);
+	
+	if (load == NULL) {
+		fprintf(stderr, "%s: Unable to get load\n", NAME);
+		return;
+	}
+	
+	printf("%s: Load average: ", NAME);
+	
+	size_t i;
+	for (i = 0; i < count; i++) {
+		if (i > 0)
+			printf(" ");
+		
+		stats_print_load_fragment(load[i], 2);
+	}
+	
+	printf("\n");
+	
+	free(load);
+}
+
+static void list_cpus(void)
+{
+	size_t count;
+	stats_cpu_t *cpus = stats_get_cpus(&count);
+	
+	if (cpus == NULL) {
+		fprintf(stderr, "%s: Unable to get CPU statistics\n", NAME);
+		return;
+	}
+	
+	printf("%s: %u CPU(s) detected\n", NAME, count);
+	
+	size_t i;
+	for (i = 0; i < count; i++) {
+		if (cpus[i].active) {
+			printf("cpu%u: %" PRIu16 " MHz, busy ticks: "
+			    "%" PRIu64 ", idle ticks: %" PRIu64 "\n",
+			    cpus[i].id, cpus[i].frequency_mhz, cpus[i].busy_ticks,
+			    cpus[i].idle_ticks);
+		} else {
+			printf("cpu%u: inactive\n", cpus[i].id);
+		}
+	}
+	
+	free(cpus);
+}
+
+static void usage()
+{
+	printf(
+	    "Usage: tasks [-t task_id] [-a] [-l] [-c]\n" \
+	    "\n" \
+	    "Options:\n" \
+	    "\t-t task_id\n" \
+	    "\t--task=task_id\n" \
+	    "\t\tList threads of the given task\n" \
+	    "\n" \
+	    "\t-a\n" \
+	    "\t--all\n" \
+	    "\t\tList all threads\n" \
+	    "\n" \
+	    "\t-l\n" \
+	    "\t--load\n" \
+	    "\t\tPrint system load\n" \
+	    "\n" \
+	    "\t-c\n" \
+	    "\t--cpu\n" \
+	    "\t\tList CPUs\n" \
+	    "\n" \
+	    "\t-h\n" \
+	    "\t--help\n" \
+	    "\t\tPrint this usage information\n"
+	    "\n" \
+	    "Without any options all tasks are listed\n"
+	);
+}
+
+int main(int argc, char *argv[])
+{
+	bool toggle_tasks = true;
+	bool toggle_threads = false;
+	bool toggle_all = false;
+	bool toggle_load = false;
+	bool toggle_cpus = false;
+	
+	task_id_t task_id = 0;
+	
+	int i;
+	for (i = 1; i < argc; i++) {
+		int off;
+		
+		/* Usage */
+		if ((off = arg_parse_short_long(argv[i], "-h", "--help")) != -1) {
+			usage();
+			return 0;
+		}
+		
+		/* All threads */
+		if ((off = arg_parse_short_long(argv[i], "-a", "--all")) != -1) {
+			toggle_tasks = false;
+			toggle_threads = true;
+			toggle_all = true;
+			continue;
+		}
+		
+		/* Load */
+		if ((off = arg_parse_short_long(argv[i], "-l", "--load")) != -1) {
+			toggle_tasks = false;
+			toggle_load = true;
+			continue;
+		}
+		
+		/* CPUs */
+		if ((off = arg_parse_short_long(argv[i], "-c", "--cpus")) != -1) {
+			toggle_tasks = false;
+			toggle_cpus = true;
+			continue;
+		}
+		
+		/* Threads */
+		if ((off = arg_parse_short_long(argv[i], "-t", "--task=")) != -1) {
+			// TODO: Support for 64b range
+			int tmp;
+			int ret = arg_parse_int(argc, argv, &i, &tmp, off);
+			if (ret != EOK) {
+				printf("%s: Malformed task_id '%s'\n", NAME, argv[i]);
+				return -1;
+			}
+			
+			task_id = tmp;
+			
+			toggle_tasks = false;
+			toggle_threads = true;
+			continue;
+		}
+	}
+	
+	if (toggle_tasks)
+		list_tasks();
+	
+	if (toggle_threads)
+		list_threads(task_id, toggle_all);
+	
+	if (toggle_load)
+		print_load();
+	
+	if (toggle_cpus)
+		list_cpus();
+	
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/tester/console/console1.c
===================================================================
--- uspace/app/tester/console/console1.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/tester/console/console1.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -53,11 +53,17 @@
 		fflush(stdout);
 		console_set_style(fphone(stdout), STYLE_NORMAL);
-		printf("normal ");
+		printf(" normal ");
 		fflush(stdout);
 		console_set_style(fphone(stdout), STYLE_EMPHASIS);
-		printf("emphasized");
+		printf(" emphasized ");
+		fflush(stdout);
+		console_set_style(fphone(stdout), STYLE_INVERTED);
+		printf(" inverted ");
+		fflush(stdout);
+		console_set_style(fphone(stdout), STYLE_SELECTED);
+		printf(" selected ");
 		fflush(stdout);
 		console_set_style(fphone(stdout), STYLE_NORMAL);
-		printf(".\n");
+		printf("\n");
 		
 		unsigned int i;
@@ -73,5 +79,5 @@
 			}
 			fflush(stdout);
-			console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
+			console_set_style(fphone(stdout), STYLE_NORMAL);
 			putchar('\n');
 		}
@@ -86,5 +92,5 @@
 			}
 			fflush(stdout);
-			console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
+			console_set_style(fphone(stdout), STYLE_NORMAL);
 			putchar('\n');
 		}
@@ -94,5 +100,5 @@
 		for (i = 0; i < 255; i += 16) {
 			fflush(stdout);
-			console_set_rgb_color(fphone(stdout), 0xffffff, i << 16);
+			console_set_rgb_color(fphone(stdout), (255 - i) << 16, i << 16);
 			putchar('X');
 		}
@@ -103,5 +109,5 @@
 		for (i = 0; i < 255; i += 16) {
 			fflush(stdout);
-			console_set_rgb_color(fphone(stdout), 0xffffff, i << 8);
+			console_set_rgb_color(fphone(stdout), (255 - i) << 8, i << 8);
 			putchar('X');
 		}
@@ -112,9 +118,9 @@
 		for (i = 0; i < 255; i += 16) {
 			fflush(stdout);
-			console_set_rgb_color(fphone(stdout), 0xffffff, i);
+			console_set_rgb_color(fphone(stdout), 255 - i, i);
 			putchar('X');
 		}
 		fflush(stdout);
-		console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
+		console_set_style(fphone(stdout), STYLE_NORMAL);
 		putchar('\n');
 	}
Index: uspace/app/tetris/screen.c
===================================================================
--- uspace/app/tetris/screen.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/tetris/screen.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -53,7 +53,9 @@
 #include <vfs/vfs.h>
 #include <async.h>
+#include <bool.h>
+#include <io/console.h>
+#include <io/style.h>
 #include "screen.h"
 #include "tetris.h"
-#include <io/console.h>
 
 #define STOP  (B_COLS - 3)
@@ -63,5 +65,5 @@
 static int isset;               /* true => terminal is in game mode */
 
-static int use_color;		/* true => use colors */
+static bool use_color;          /* true => use colors */
 
 static const struct shape *lastshape;
@@ -81,5 +83,5 @@
 {
 	fflush(stdout);
-	console_set_rgb_color(fphone(stdout), 0xf0f0f0,
+	console_set_rgb_color(fphone(stdout), 0xffffff,
 	    use_color ? color : 0x000000);
 }
@@ -88,5 +90,5 @@
 {
 	fflush(stdout);
-	console_set_rgb_color(fphone(stdout), 0, 0xf0f0f0);
+	console_set_style(fphone(stdout), STYLE_NORMAL);
 }
 
@@ -118,8 +120,8 @@
 }
 
-void moveto(int r, int c)
+void moveto(ipcarg_t r, ipcarg_t c)
 {
 	fflush(stdout);
-	console_goto(fphone(stdout), c, r);
+	console_set_pos(fphone(stdout), c, r);
 }
 
@@ -131,13 +133,12 @@
 }
 
-static int get_display_color_sup(void)
-{
-	int rc;
-	int ccap;
-
-	rc = console_get_color_cap(fphone(stdout), &ccap);
+static bool get_display_color_sup(void)
+{
+	ipcarg_t ccap;
+	int rc = console_get_color_cap(fphone(stdout), &ccap);
+	
 	if (rc != 0)
-		return 0;
-
+		return false;
+	
 	return (ccap >= CONSOLE_CCAP_RGB);
 }
@@ -308,5 +309,5 @@
  * (We need its length in case we have to overwrite with blanks.)
  */
-void scr_msg(char *s, int set)
+void scr_msg(char *s, bool set)
 {
 	int l = str_size(s);
Index: uspace/app/tetris/screen.h
===================================================================
--- uspace/app/tetris/screen.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/tetris/screen.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -48,14 +48,16 @@
 
 #include <sys/types.h>
+#include <ipc/ipc.h>
 #include <async.h>
+#include <bool.h>
 
 typedef struct {
-	int ws_row;
-	int ws_col;
+	ipcarg_t ws_row;
+	ipcarg_t ws_col;
 } winsize_t;
 
 extern winsize_t winsize;
 
-extern void moveto(int r, int c);
+extern void moveto(ipcarg_t r, ipcarg_t c);
 extern void clear_screen(void);
 
@@ -65,5 +67,5 @@
 extern void scr_end(void);
 extern void scr_init(void);
-extern void scr_msg(char *, int);
+extern void scr_msg(char *, bool);
 extern void scr_set(void);
 extern void scr_update(void);
Index: uspace/app/top/Makefile
===================================================================
--- uspace/app/top/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/app/top/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,38 @@
+#
+# 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 = top
+
+SOURCES = \
+	top.c \
+	screen.c \
+	input.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/top/input.c
===================================================================
--- uspace/app/top/input.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/app/top/input.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,200 @@
+/*	$OpenBSD: input.c,v 1.12 2005/04/13 02:33:08 deraadt Exp $	*/
+/*    $NetBSD: input.c,v 1.3 1996/02/06 22:47:33 jtc Exp $    */
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)input.c	8.1 (Berkeley) 5/31/93
+ */
+
+/** @addtogroup top
+ * @{
+ */
+/** @file
+ */
+
+/*
+ * Top input.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdio.h>
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <str.h>
+
+#include "input.h"
+
+#include <async.h>
+#include <vfs/vfs.h>
+#include <io/console.h>
+#include <ipc/console.h>
+
+#define USEC_COUNT 1000000
+
+/* return true iff the given timeval is positive */
+#define	TV_POS(tv) \
+	((tv)->tv_sec > 0 || ((tv)->tv_sec == 0 && (tv)->tv_usec > 0))
+
+/* subtract timeval `sub' from `res' */
+#define	TV_SUB(res, sub) \
+	(res)->tv_sec -= (sub)->tv_sec; \
+	(res)->tv_usec -= (sub)->tv_usec; \
+	if ((res)->tv_usec < 0) { \
+		(res)->tv_usec += 1000000; \
+		(res)->tv_sec--; \
+	}
+
+/* We will use a hack here - if lastchar is non-zero, it is
+ * the last character read. We will somehow simulate the select
+ * semantics.
+ */
+static aid_t getchar_inprog = 0;
+static char lastchar = '\0';
+
+/*
+ * Do a `read wait': select for reading from stdin, with timeout *tvp.
+ * On return, modify *tvp to reflect the amount of time spent waiting.
+ * It will be positive only if input appeared before the time ran out;
+ * otherwise it will be zero or perhaps negative.
+ *
+ * If tvp is nil, wait forever, but return if select is interrupted.
+ *
+ * Return 0 => no input, 1 => can read() from stdin
+ *
+ */
+int rwait(struct timeval *tvp)
+{
+	struct timeval starttv, endtv, *s;
+	static ipc_call_t charcall;
+	ipcarg_t rc;
+	
+	/*
+	 * Someday, select() will do this for us.
+	 * Just in case that day is now, and no one has
+	 * changed this, we use a temporary.
+	 */
+	if (tvp) {
+		(void) gettimeofday(&starttv, NULL);
+		endtv = *tvp;
+		s = &endtv;
+	} else
+		s = NULL;
+	
+	if (!lastchar) {
+again:
+		if (!getchar_inprog) {
+			getchar_inprog = async_send_0(fphone(stdin),
+			    CONSOLE_GET_EVENT, &charcall);
+		}
+		
+		if (!s)
+			async_wait_for(getchar_inprog, &rc);
+		else if (async_wait_timeout(getchar_inprog, &rc, s->tv_usec) == ETIMEOUT) {
+			tvp->tv_sec = 0;
+			tvp->tv_usec = 0;
+			return (0);
+		}
+		
+		getchar_inprog = 0;
+		if (rc) {
+			printf("End of file, bug?\n");
+			exit(1);
+		}
+		
+		if (IPC_GET_ARG1(charcall) == KEY_RELEASE)
+			goto again;
+		
+		lastchar = IPC_GET_ARG4(charcall);
+	}
+	
+	if (tvp) {
+		/* since there is input, we may not have timed out */
+		(void) gettimeofday(&endtv, NULL);
+		TV_SUB(&endtv, &starttv);
+		TV_SUB(tvp, &endtv);  /* adjust *tvp by elapsed time */
+	}
+	
+	return 1;
+}
+
+/*
+ * `sleep' for the current turn time (using select).
+ * Eat any input that might be available.
+ */
+void tsleep(unsigned int sec)
+{
+	struct timeval tv;
+	
+	tv.tv_sec = 0;
+	tv.tv_usec = sec * USEC_COUNT;
+	while (TV_POS(&tv))
+		if (rwait(&tv)) {
+			lastchar = '\0';
+		} else
+			break;
+}
+
+/*
+ * getchar with timeout.
+ */
+int tgetchar(unsigned int sec)
+{
+	static struct timeval timeleft;
+	char c;
+	
+	/*
+	 * Reset timeleft to USEC_COUNT whenever it is not positive.
+	 * In any case, wait to see if there is any input.  If so,
+	 * take it, and update timeleft so that the next call to
+	 * tgetchar() will not wait as long.  If there is no input,
+	 * make timeleft zero or negative, and return -1.
+	 *
+	 * Most of the hard work is done by rwait().
+	 */
+	if (!TV_POS(&timeleft)) {
+		timeleft.tv_sec = 0;
+		timeleft.tv_usec = sec * USEC_COUNT;
+	}
+	
+	if (!rwait(&timeleft))
+		return -1;
+	
+	c = lastchar;
+	lastchar = '\0';
+	return ((int) (unsigned char) c);
+}
+
+/** @}
+ */
Index: uspace/app/top/input.h
===================================================================
--- uspace/app/top/input.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/app/top/input.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,56 @@
+/*	$OpenBSD: input.h,v 1.5 2003/06/03 03:01:41 millert Exp $	*/
+/*	$NetBSD: input.h,v 1.2 1995/04/22 07:42:36 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)input.h	8.1 (Berkeley) 5/31/93
+ */
+
+/** @addtogroup top
+ * @{
+ */
+/** @file
+ */
+
+#ifndef TOP_INPUT_
+#define TOP_INPUT_
+
+#include <sys/time.h>
+
+extern int rwait(struct timeval *);
+extern int tgetchar(unsigned int sec);
+extern void tsleep(unsigned int sec);
+
+#endif
+
+/** @}
+ */
Index: uspace/app/top/screen.c
===================================================================
--- uspace/app/top/screen.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/app/top/screen.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2010 Stanislav Kozina
+ * Copyright (c) 2010 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 top
+ * @brief Top utility.
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <ipc/ipc.h>
+#include <io/console.h>
+#include <io/style.h>
+#include <vfs/vfs.h>
+#include <stdarg.h>
+#include <stats.h>
+#include <inttypes.h>
+#include "screen.h"
+#include "top.h"
+
+static ipcarg_t warn_col = 0;
+static ipcarg_t warn_row = 0;
+
+static void screen_style_normal(void)
+{
+	fflush(stdout);
+	console_set_style(fphone(stdout), STYLE_NORMAL);
+}
+
+static void screen_style_inverted(void)
+{
+	fflush(stdout);
+	console_set_style(fphone(stdout), STYLE_INVERTED);
+}
+
+static void screen_moveto(ipcarg_t col, ipcarg_t row)
+{
+	fflush(stdout);
+	console_set_pos(fphone(stdout), col, row);
+}
+
+static void screen_get_pos(ipcarg_t *col, ipcarg_t *row)
+{
+	fflush(stdout);
+	console_get_pos(fphone(stdout), col, row);
+}
+
+static void screen_get_size(ipcarg_t *col, ipcarg_t *row)
+{
+	fflush(stdout);
+	console_get_size(fphone(stdout), col, row);
+}
+
+static void screen_restart(bool clear)
+{
+	screen_style_normal();
+	
+	if (clear) {
+		fflush(stdout);
+		console_clear(fphone(stdout));
+	}
+	
+	screen_moveto(0, 0);
+}
+
+static void screen_newline(void)
+{
+	ipcarg_t cols;
+	ipcarg_t rows;
+	screen_get_size(&cols, &rows);
+	
+	ipcarg_t c;
+	ipcarg_t r;
+	screen_get_pos(&c, &r);
+	
+	ipcarg_t i;
+	for (i = c + 1; i < cols; i++)
+		puts(" ");
+	
+	if (r + 1 < rows)
+		puts("\n");
+}
+
+void screen_init(void)
+{
+	fflush(stdout);
+	console_cursor_visibility(fphone(stdout), false);
+	
+	screen_restart(true);
+}
+
+void screen_done(void)
+{
+	screen_restart(true);
+	
+	fflush(stdout);
+	console_cursor_visibility(fphone(stdout), true);
+}
+
+static void print_float(fixed_float ffloat, unsigned int precision)
+{
+	printf("%2" PRIu64 ".", ffloat.upper / ffloat.lower);
+	
+	unsigned int i;
+	uint64_t rest = (ffloat.upper % ffloat.lower) * 10;
+	for (i = 0; i < precision; i++) {
+		printf("%" PRIu64, rest / ffloat.lower);
+		rest = (rest % ffloat.lower) * 10;
+	}
+}
+
+static inline void print_global_head(data_t *data)
+{
+	printf("top - %02lu:%02lu:%02lu up %u days, %02u:%02u:%02u, load average:",
+	    data->hours, data->minutes, data->seconds,
+	    data->udays, data->uhours, data->uminutes, data->useconds);
+	
+	size_t i;
+	for (i = 0; i < data->load_count; i++) {
+		puts(" ");
+		stats_print_load_fragment(data->load[i], 2);
+	}
+	
+	screen_newline();
+}
+
+static inline void print_task_summary(data_t *data)
+{
+	printf("tasks: %u total", data->tasks_count);
+	screen_newline();
+}
+
+static inline void print_thread_summary(data_t *data)
+{
+	size_t total = 0;
+	size_t running = 0;
+	size_t ready = 0;
+	size_t sleeping = 0;
+	size_t lingering = 0;
+	size_t other = 0;
+	size_t invalid = 0;
+	
+	size_t i;
+	for (i = 0; i < data->threads_count; i++) {
+		total++;
+		
+		switch (data->threads[i].state) {
+		case Running:
+			running++;
+			break;
+		case Ready:
+			ready++;
+			break;
+		case Sleeping:
+			sleeping++;
+			break;
+		case Lingering:
+			lingering++;
+			break;
+		case Entering:
+		case Exiting:
+			other++;
+			break;
+		default:
+			invalid++;
+		}
+	}
+	
+	printf("threads: %u total, %u running, %u ready, %u sleeping, %u lingering, "
+	    "%u other, %u invalid",
+	    total, running, ready, sleeping, lingering, other, invalid);
+	screen_newline();
+}
+
+static inline void print_cpu_info(data_t *data)
+{
+	size_t i;
+	for (i = 0; i < data->cpus_count; i++) {
+		if (data->cpus[i].active) {
+			printf("cpu%u (%4" PRIu16 " MHz): busy ticks: "
+			    "%" PRIu64 ", idle ticks: %" PRIu64,
+			    data->cpus[i].id, data->cpus[i].frequency_mhz,
+			    data->cpus[i].busy_ticks, data->cpus[i].idle_ticks);
+			puts(", idle: ");
+			print_float(data->cpus_perc[i].idle, 2);
+			puts("%, busy: ");
+			print_float(data->cpus_perc[i].busy, 2);
+			puts("%");
+		} else
+			printf("cpu%u inactive", data->cpus[i].id);
+		
+		screen_newline();
+	}
+}
+
+static inline void print_physmem_info(data_t *data)
+{
+	uint64_t total;
+	uint64_t unavail;
+	uint64_t used;
+	uint64_t free;
+	char total_suffix;
+	char unavail_suffix;
+	char used_suffix;
+	char free_suffix;
+	
+	order_suffix(data->physmem->total, &total, &total_suffix);
+	order_suffix(data->physmem->unavail, &unavail, &unavail_suffix);
+	order_suffix(data->physmem->used, &used, &used_suffix);
+	order_suffix(data->physmem->free, &free, &free_suffix);
+	
+	printf("memory: %" PRIu64 "%c total, %" PRIu64 "%c unavail, %"
+	    PRIu64 "%c used, %" PRIu64 "%c free", total, total_suffix,
+	    unavail, unavail_suffix, used, used_suffix, free, free_suffix);
+	screen_newline();
+}
+
+static inline void print_task_head(void)
+{
+	screen_style_inverted();
+	printf("      ID  Threads      Mem      %%Mem %%uCycles %%kCycles  Name");
+	screen_newline();
+	screen_style_normal();
+}
+
+static inline void print_tasks(data_t *data)
+{
+	ipcarg_t cols;
+	ipcarg_t rows;
+	screen_get_size(&cols, &rows);
+	
+	ipcarg_t col;
+	ipcarg_t row;
+	screen_get_pos(&col, &row);
+	
+	size_t i;
+	for (i = 0; (i < data->tasks_count) && (row < rows); i++, row++) {
+		uint64_t virtmem;
+		char virtmem_suffix;
+		order_suffix(data->tasks[i].virtmem, &virtmem, &virtmem_suffix);
+		
+		printf("%8" PRIu64 " %8u %8" PRIu64 "%c ", data->tasks[i].task_id,
+		    data->tasks[i].threads, virtmem, virtmem_suffix);
+		puts("   ");
+		print_float(data->tasks_perc[i].virtmem, 2);
+		puts("%   ");
+		print_float(data->tasks_perc[i].ucycles, 2);
+		puts("%   ");
+		print_float(data->tasks_perc[i].kcycles, 2);
+		printf("%% %s", data->tasks[i].name);
+		
+		screen_newline();
+	}
+	
+	while (row < rows) {
+		screen_newline();
+		row++;
+	}
+}
+
+static inline void print_ipc_head(void)
+{
+	screen_style_inverted();
+	printf("      ID Calls sent Calls recv Answs sent Answs recv  IRQn recv       Forw Name");
+	screen_newline();
+	screen_style_normal();
+}
+
+static inline void print_ipc(data_t *data)
+{
+	ipcarg_t cols;
+	ipcarg_t rows;
+	screen_get_size(&cols, &rows);
+	
+	ipcarg_t col;
+	ipcarg_t row;
+	screen_get_pos(&col, &row);
+	
+	size_t i;
+	for (i = 0; (i < data->tasks_count) && (row < rows); i++, row++) {
+		printf("%8" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64
+		     " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %s",
+		     data->tasks[i].task_id, data->tasks[i].ipc_info.call_sent,
+		     data->tasks[i].ipc_info.call_recieved,
+		     data->tasks[i].ipc_info.answer_sent,
+		     data->tasks[i].ipc_info.answer_recieved,
+		     data->tasks[i].ipc_info.irq_notif_recieved,
+		     data->tasks[i].ipc_info.forwarded, data->tasks[i].name);
+		
+		screen_newline();
+	}
+	
+	while (row < rows) {
+		screen_newline();
+		row++;
+	}
+}
+
+void print_data(data_t *data)
+{
+	screen_restart(false);
+	print_global_head(data);
+	print_task_summary(data);
+	print_thread_summary(data);
+	print_cpu_info(data);
+	print_physmem_info(data);
+	
+	/* Empty row for warnings */
+	screen_get_pos(&warn_col, &warn_row);
+	screen_newline();
+	
+	if (operation_type == OP_IPC) {
+		print_ipc_head();
+		print_ipc(data);
+	} else {
+		print_task_head();
+		print_tasks(data);
+	}
+	
+	fflush(stdout);
+}
+
+void print_warning(const char *fmt, ...)
+{
+	screen_moveto(warn_col, warn_row);
+	
+	va_list args;
+	va_start(args, fmt);
+	vprintf(fmt, args);
+	va_end(args);
+	
+	screen_newline();
+	fflush(stdout);
+}
+
+/** @}
+ */
Index: uspace/app/top/screen.h
===================================================================
--- uspace/app/top/screen.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/app/top/screen.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 Stanislav Kozina
+ * Copyright (c) 2010 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 top
+ * @{
+ */
+
+#ifndef TOP_SCREEN_H_
+#define TOP_SCREEN_H_
+
+#include "top.h"
+
+extern void screen_init(void);
+extern void screen_done(void);
+extern void print_data(data_t *);
+extern void print_warning(const char *, ...);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/app/top/top.c
===================================================================
--- uspace/app/top/top.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/app/top/top.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2010 Stanislav Kozina
+ * Copyright (c) 2010 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 top
+ * @brief Top utility.
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <task.h>
+#include <thread.h>
+#include <sys/time.h>
+#include <arch/barrier.h>
+#include <errno.h>
+#include "screen.h"
+#include "input.h"
+#include "top.h"
+
+#define NAME  "top"
+
+#define UPDATE_INTERVAL  1
+
+#define DAY     86400
+#define HOUR    3600
+#define MINUTE  60
+
+int operation_type;
+
+static const char *read_data(data_t *target)
+{
+	/* Initialize data */
+	target->load = NULL;
+	target->cpus = NULL;
+	target->cpus_perc = NULL;
+	target->tasks = NULL;
+	target->tasks_perc = NULL;
+	target->threads = NULL;
+	target->physmem = NULL;
+	
+	/* Get current time */
+	struct timeval time;
+	if (gettimeofday(&time, NULL) != EOK)
+		return "Cannot get time of day";
+	
+	target->hours = (time.tv_sec % DAY) / HOUR;
+	target->minutes = (time.tv_sec % HOUR) / MINUTE;
+	target->seconds = time.tv_sec % MINUTE;
+	
+	/* Get uptime */
+	sysarg_t uptime = stats_get_uptime();
+	target->udays = uptime / DAY;
+	target->uhours = (uptime % DAY) / HOUR;
+	target->uminutes = (uptime % HOUR) / MINUTE;
+	target->useconds = uptime % MINUTE;
+	
+	/* Get load */
+	target->load = stats_get_load(&(target->load_count));
+	if (target->load == NULL)
+		return "Cannot get system load";
+	
+	/* Get CPUs */
+	target->cpus = stats_get_cpus(&(target->cpus_count));
+	if (target->cpus == NULL)
+		return "Cannot get CPUs";
+	
+	target->cpus_perc =
+	    (perc_cpu_t *) calloc(target->cpus_count, sizeof(perc_cpu_t));
+	if (target->cpus_perc == NULL)
+		return "Not enough memory for CPU utilization";
+	
+	/* Get tasks */
+	target->tasks = stats_get_tasks(&(target->tasks_count));
+	if (target->tasks == NULL)
+		return "Cannot get tasks";
+	
+	target->tasks_perc =
+	    (perc_task_t *) calloc(target->tasks_count, sizeof(perc_task_t));
+	if (target->tasks_perc == NULL)
+		return "Not enough memory for task utilization";
+	
+	/* Get threads */
+	target->threads = stats_get_threads(&(target->threads_count));
+	if (target->threads == NULL)
+		return "Cannot get threads";
+	
+	/* Get physical memory */
+	target->physmem = stats_get_physmem();
+	if (target->physmem == NULL)
+		return "Cannot get physical memory";
+	
+	return NULL;
+}
+
+/** Computes percentage differencies from old_data to new_data
+ *
+ * @param old_data Pointer to old data strucutre.
+ * @param new_data Pointer to actual data where percetages are stored.
+ *
+ */
+static const char *compute_percentages(data_t *old_data, data_t *new_data)
+{
+	/* Allocate memory */
+	
+	uint64_t *ucycles_diff = calloc(new_data->tasks_count, sizeof(uint64_t));
+	if (ucycles_diff == NULL)
+		return "Not enough memory for user utilization";
+	
+	uint64_t *kcycles_diff = calloc(new_data->tasks_count, sizeof(uint64_t));
+	if (kcycles_diff == NULL) {
+		free(ucycles_diff);
+		return "Not enough memory for kernel utilization";
+	}
+	
+	/* For each CPU: Compute total ticks and divide it between
+	   user and kernel */
+	
+	size_t i;
+	for (i = 0; i < new_data->cpus_count; i++) {
+		uint64_t idle =
+		    new_data->cpus[i].idle_ticks - old_data->cpus[i].idle_ticks;
+		uint64_t busy =
+		    new_data->cpus[i].busy_ticks - old_data->cpus[i].busy_ticks;
+		uint64_t sum = idle + busy;
+		
+		FRACTION_TO_FLOAT(new_data->cpus_perc[i].idle, idle * 100, sum);
+		FRACTION_TO_FLOAT(new_data->cpus_perc[i].busy, busy * 100, sum);
+	}
+	
+	/* For all tasks compute sum and differencies of all cycles */
+	
+	uint64_t virtmem_total = 1;  /* Must NOT be zero */
+	uint64_t ucycles_total = 1;  /* Must NOT be zero */
+	uint64_t kcycles_total = 1;  /* Must NOT be zero */
+	
+	for (i = 0; i < new_data->tasks_count; i++) {
+		/* Match task with the previous instance */
+		
+		bool found = false;
+		size_t j;
+		for (j = 0; j < old_data->tasks_count; j++) {
+			if (new_data->tasks[i].task_id == old_data->tasks[j].task_id) {
+				found = true;
+				break;
+			}
+		}
+		
+		if (!found) {
+			/* This is newly borned task, ignore it */
+			ucycles_diff[i] = 0;
+			kcycles_diff[i] = 0;
+			continue;
+		}
+		
+		ucycles_diff[i] =
+		    new_data->tasks[i].ucycles - old_data->tasks[j].ucycles;
+		kcycles_diff[i] =
+		    new_data->tasks[i].kcycles - old_data->tasks[j].kcycles;
+		
+		virtmem_total += new_data->tasks[i].virtmem;
+		ucycles_total += ucycles_diff[i];
+		kcycles_total += kcycles_diff[i];
+	}
+	
+	/* For each task: Compute percential change */
+	
+	for (i = 0; i < new_data->tasks_count; i++) {
+		FRACTION_TO_FLOAT(new_data->tasks_perc[i].virtmem,
+		    new_data->tasks[i].virtmem * 100, virtmem_total);
+		FRACTION_TO_FLOAT(new_data->tasks_perc[i].ucycles,
+		    ucycles_diff[i] * 100, ucycles_total);
+		FRACTION_TO_FLOAT(new_data->tasks_perc[i].kcycles,
+		    kcycles_diff[i] * 100, kcycles_total);
+	}
+	
+	/* Cleanup */
+	
+	free(ucycles_diff);
+	free(kcycles_diff);
+	
+	return NULL;
+}
+
+static void free_data(data_t *target)
+{
+	if (target->load != NULL)
+		free(target->load);
+	
+	if (target->cpus != NULL)
+		free(target->cpus);
+	
+	if (target->cpus_perc != NULL)
+		free(target->cpus_perc);
+	
+	if (target->tasks != NULL)
+		free(target->tasks);
+	
+	if (target->tasks_perc != NULL)
+		free(target->tasks_perc);
+	
+	if (target->threads != NULL)
+		free(target->threads);
+	
+	if (target->physmem != NULL)
+		free(target->physmem);
+}
+
+int main(int argc, char *argv[])
+{
+	data_t data;
+	data_t data_prev;
+	const char *ret = NULL;
+	
+	screen_init();
+	printf("Reading initial data...\n");
+	
+	if ((ret = read_data(&data_prev)) != NULL)
+		goto out;
+	
+	/* Compute some rubbish to have initialised values */
+	if ((ret = compute_percentages(&data_prev, &data_prev)) != NULL)
+		goto out;
+	
+	/* And paint screen until death */
+	operation_type = OP_TASKS;
+	while (true) {
+		int c = tgetchar(UPDATE_INTERVAL);
+		if (c < 0) {
+			if ((ret = read_data(&data)) != NULL) {
+				free_data(&data);
+				goto out;
+			}
+			
+			if ((ret = compute_percentages(&data_prev, &data)) != NULL) {
+				free_data(&data);
+				goto out;
+			}
+			
+			print_data(&data);
+			free_data(&data_prev);
+			data_prev = data;
+			
+			continue;
+		}
+		
+		switch (c) {
+			case 'q':
+				goto out;
+			case 'i':
+				print_warning("Showing IPC statistics");
+				operation_type = OP_IPC;
+				break;
+			case 't':
+				print_warning("Showing task statistics");
+				operation_type = OP_TASKS;
+				break;
+			default:
+				print_warning("Unknown command: %c", c);
+				break;
+		}
+	}
+	
+out:
+	screen_done();
+	free_data(&data_prev);
+	
+	if (ret != NULL) {
+		fprintf(stderr, "%s: %s\n", NAME, ret);
+		return 1;
+	}
+	
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/top/top.h
===================================================================
--- uspace/app/top/top.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/app/top/top.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2010 Stanislav Kozina
+ * Copyright (c) 2010 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 top
+ * @{
+ */
+
+#ifndef TOP_TOP_H_
+#define TOP_TOP_H_
+
+#include <task.h>
+#include <stats.h>
+#include <time.h>
+
+#define FRACTION_TO_FLOAT(float, a, b) { \
+	(float).upper = (a); \
+	(float).lower = (b); \
+}
+
+#define OP_TASKS  1
+#define OP_IPC    2
+
+extern int operation_type;
+
+typedef struct {
+	uint64_t upper;
+	uint64_t lower;
+} fixed_float;
+
+typedef struct {
+	fixed_float idle;
+	fixed_float busy;
+} perc_cpu_t;
+
+typedef struct {
+	fixed_float ucycles;
+	fixed_float kcycles;
+	fixed_float virtmem;
+} perc_task_t;
+
+typedef struct {
+	time_t hours;
+	time_t minutes;
+	time_t seconds;
+	
+	sysarg_t udays;
+	sysarg_t uhours;
+	sysarg_t uminutes;
+	sysarg_t useconds;
+	
+	size_t load_count;
+	load_t *load;
+	
+	size_t cpus_count;
+	stats_cpu_t *cpus;
+	perc_cpu_t *cpus_perc;
+	
+	size_t tasks_count;
+	stats_task_t *tasks;
+	perc_task_t *tasks_perc;
+	
+	size_t threads_count;
+	stats_thread_t *threads;
+	
+	stats_physmem_t *physmem;
+} data_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/app/trace/syscalls.c
===================================================================
--- uspace/app/trace/syscalls.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/app/trace/syscalls.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -75,6 +75,9 @@
     [SYS_PREEMPT_CONTROL] = { "preempt_control",	1,	V_ERRNO },
 
-    [SYS_SYSINFO_VALID] = { "sysinfo_valid",		2,	V_HASH },
-    [SYS_SYSINFO_VALUE] = { "sysinfo_value",		2,	V_HASH },
+    [SYS_SYSINFO_GET_TAG] = { "sysinfo_get_tag",		2,	V_INTEGER },
+    [SYS_SYSINFO_GET_VALUE] = { "sysinfo_get_value",		3,	V_ERRNO },
+    [SYS_SYSINFO_GET_DATA_SIZE] = { "sysinfo_get_data_size",	3,	V_ERRNO },
+    [SYS_SYSINFO_GET_DATA] = { "sysinfo_get_data",		4,	V_ERRNO },
+
     [SYS_DEBUG_ENABLE_CONSOLE] = { "debug_enable_console", 0,	V_ERRNO },
     [SYS_IPC_CONNECT_KBOX] = { "ipc_connect_kbox",	1,	V_ERRNO }
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -35,11 +35,14 @@
 INCLUDE_LIBARCH = include/libarch
 
-PRE_DEPEND = $(INCLUDE_KERNEL) $(INCLUDE_ARCH) $(INCLUDE_LIBARCH)
+COMMON_MAKEFILE = $(ROOT_PATH)/Makefile.common
+COMMON_HEADER = $(ROOT_PATH)/common.h
+COMMON_HEADER_ARCH = arch/$(UARCH)/include/common.h
+
+CONFIG_MAKEFILE = $(ROOT_PATH)/Makefile.config
+
+PRE_DEPEND = $(INCLUDE_KERNEL) $(INCLUDE_ARCH) $(INCLUDE_LIBARCH) $(COMMON_HEADER_ARCH)
 EXTRA_OUTPUT = $(LINKER_SCRIPT)
-EXTRA_CLEAN = $(INCLUDE_KERNEL) $(INCLUDE_ARCH) $(INCLUDE_LIBARCH) $(LINKER_SCRIPT)
+EXTRA_CLEAN = $(INCLUDE_KERNEL) $(INCLUDE_ARCH) $(INCLUDE_LIBARCH) $(COMMON_HEADER_ARCH) $(LINKER_SCRIPT)
 LIBRARY = libc
-
-COMMON_MAKEFILE = $(ROOT_PATH)/Makefile.common
-CONFIG_MAKEFILE = $(ROOT_PATH)/Makefile.config
 
 -include $(COMMON_MAKEFILE)
@@ -58,4 +61,5 @@
 	generic/mem.c \
 	generic/str.c \
+	generic/str_error.c \
 	generic/fibril.c \
 	generic/fibril_synch.c \
@@ -75,4 +79,5 @@
 	generic/io/printf_core.c \
 	generic/io/console.c \
+	generic/io/screenbuffer.c \
 	generic/malloc.c \
 	generic/sysinfo.c \
@@ -90,5 +95,7 @@
 	generic/vfs/vfs.c \
 	generic/vfs/canonify.c \
-	generic/stacktrace.c
+	generic/stacktrace.c \
+	generic/arg_parse.c \
+	generic/stats.c
 
 SOURCES = \
@@ -111,2 +118,5 @@
 $(LINKER_SCRIPT): $(LINKER_SCRIPT).in
 	$(GCC) $(DEFS) $(CFLAGS) -DLIBC_PATH=$(CURDIR) -E -x c $< | grep -v "^\#" > $@
+
+$(COMMON_HEADER_ARCH): $(COMMON_HEADER)
+	ln -sfn ../../../$< $@
Index: uspace/lib/c/arch/abs32le/include/types.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/types.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/arch/abs32le/include/types.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -38,15 +38,7 @@
 #define __32_BITS__
 
-typedef unsigned int sysarg_t;
+#include <libarch/common.h>
 
-typedef char int8_t;
-typedef short int int16_t;
-typedef int int32_t;
-typedef long long int int64_t;
-
-typedef unsigned char uint8_t;
-typedef unsigned short int uint16_t;
-typedef unsigned int uint32_t;
-typedef unsigned long long int uint64_t;
+typedef uint32_t sysarg_t;
 
 typedef int32_t ssize_t;
Index: uspace/lib/c/arch/amd64/include/types.h
===================================================================
--- uspace/lib/c/arch/amd64/include/types.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/arch/amd64/include/types.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -38,15 +38,7 @@
 #define __64_BITS__
 
-typedef unsigned long long sysarg_t;
+#include <libarch/common.h>
 
-typedef signed char int8_t;
-typedef short int int16_t;
-typedef int int32_t;
-typedef long long int int64_t;
-
-typedef unsigned char uint8_t;
-typedef unsigned short int uint16_t;
-typedef unsigned int uint32_t;
-typedef unsigned long long int uint64_t;
+typedef uint64_t sysarg_t;
 
 typedef int64_t ssize_t;
Index: uspace/lib/c/arch/arm32/include/types.h
===================================================================
--- uspace/lib/c/arch/arm32/include/types.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/arch/arm32/include/types.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -27,8 +27,8 @@
  */
 
-/** @addtogroup libcarm32	
+/** @addtogroup libcarm32
  * @{
  */
-/** @file 
+/** @file
  *  @brief Definitions of basic types like #uintptr_t.
  */
@@ -39,15 +39,7 @@
 #define __32_BITS__
 
-typedef unsigned int sysarg_t;
+#include <libarch/common.h>
 
-typedef char int8_t;
-typedef short int int16_t;
-typedef long int int32_t;
-typedef long long int int64_t;
-
-typedef unsigned char uint8_t;
-typedef unsigned short int uint16_t;
-typedef unsigned long int uint32_t;
-typedef unsigned long long int uint64_t;
+typedef uint32_t sysarg_t;
 
 typedef int32_t ssize_t;
Index: uspace/lib/c/arch/ia32/include/types.h
===================================================================
--- uspace/lib/c/arch/ia32/include/types.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/arch/ia32/include/types.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -38,15 +38,7 @@
 #define __32_BITS__
 
-typedef unsigned int sysarg_t;
+#include <libarch/common.h>
 
-typedef char int8_t;
-typedef short int int16_t;
-typedef int int32_t;
-typedef long long int int64_t;
-
-typedef unsigned char uint8_t;
-typedef unsigned short int uint16_t;
-typedef unsigned int uint32_t;
-typedef unsigned long long int uint64_t;
+typedef uint32_t sysarg_t;
 
 typedef int32_t ssize_t;
Index: uspace/lib/c/arch/ia64/include/types.h
===================================================================
--- uspace/lib/c/arch/ia64/include/types.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/arch/ia64/include/types.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -38,15 +38,10 @@
 #define __64_BITS__
 
-typedef unsigned long sysarg_t;
+#include <libarch/common.h>
 
-typedef char int8_t;
-typedef short int int16_t;
-typedef int int32_t;
-typedef long int int64_t;
-
-typedef unsigned char uint8_t;
-typedef unsigned short int uint16_t;
-typedef unsigned int uint32_t;
-typedef unsigned long int uint64_t;
+typedef struct {
+	uint64_t lo;
+	int64_t hi;
+} int128_t;
 
 typedef struct {
@@ -54,4 +49,6 @@
 	uint64_t hi;
 } uint128_t;
+
+typedef uint64_t sysarg_t;
 
 typedef int64_t ssize_t;
Index: uspace/lib/c/arch/ia64/src/ddi.c
===================================================================
--- uspace/lib/c/arch/ia64/src/ddi.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/arch/ia64/src/ddi.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -2,12 +2,13 @@
 #include <sysinfo.h>
 
-uint64_t ia64_iospace_address=0;
-
+uint64_t ia64_iospace_address = 0;
 
 uint64_t get_ia64_iospace_address(void)
 {
-
-	return sysinfo_value("ia64_iospace.address.virtual");
-
+	sysarg_t addr;
+	if (sysinfo_get_value("ia64_iospace.address.virtual", &addr) != 0)
+		addr = 0;
+	
+	return addr;
 }
 
Index: uspace/lib/c/arch/mips32/include/types.h
===================================================================
--- uspace/lib/c/arch/mips32/include/types.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/arch/mips32/include/types.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -39,15 +39,7 @@
 #define __32_BITS__
 
-typedef unsigned int sysarg_t;
+#include <libarch/common.h>
 
-typedef char int8_t;
-typedef short int int16_t;
-typedef long int int32_t;
-typedef long long int int64_t;
-
-typedef unsigned char uint8_t;
-typedef unsigned short int uint16_t;
-typedef unsigned long int uint32_t;
-typedef unsigned long long int uint64_t;
+typedef uint32_t sysarg_t;
 
 typedef int32_t ssize_t;
Index: uspace/lib/c/arch/ppc32/include/types.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/types.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/arch/ppc32/include/types.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -38,15 +38,7 @@
 #define __32_BITS__
 
-typedef unsigned int sysarg_t;
+#include <libarch/common.h>
 
-typedef char int8_t;
-typedef short int int16_t;
-typedef int int32_t;
-typedef long long int int64_t;
-
-typedef unsigned char uint8_t;
-typedef unsigned short int uint16_t;
-typedef unsigned int uint32_t;
-typedef unsigned long long int uint64_t;
+typedef uint32_t sysarg_t;
 
 typedef int32_t ssize_t;
Index: uspace/lib/c/arch/sparc64/include/types.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/types.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/arch/sparc64/include/types.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -38,15 +38,7 @@
 #define __64_BITS__
 
-typedef unsigned long sysarg_t;
+#include <libarch/common.h>
 
-typedef signed char int8_t;
-typedef short int int16_t;
-typedef int int32_t;
-typedef long int int64_t;
-
-typedef unsigned char uint8_t;
-typedef unsigned short int uint16_t;
-typedef unsigned int uint32_t;
-typedef unsigned long int uint64_t;
+typedef uint64_t sysarg_t;
 
 typedef int64_t ssize_t;
Index: uspace/lib/c/generic/adt/hash_table.c
===================================================================
--- uspace/lib/c/generic/adt/hash_table.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/generic/adt/hash_table.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -42,20 +42,19 @@
 #include <malloc.h>
 #include <assert.h>
-#include <stdio.h>
 #include <str.h>
 
 /** Create chained hash table.
  *
- * @param h		Hash table structure. Will be initialized by this call.
- * @param m		Number of hash table buckets.
- * @param max_keys	Maximal number of keys needed to identify an item.
- * @param op		Hash table operations structure.
- * @return		True on success
+ * @param h        Hash table structure. Will be initialized by this call.
+ * @param m        Number of hash table buckets.
+ * @param max_keys Maximal number of keys needed to identify an item.
+ * @param op       Hash table operations structure.
+ *
+ * @return True on success
+ *
  */
 int hash_table_create(hash_table_t *h, hash_count_t m, hash_count_t max_keys,
     hash_table_operations_t *op)
 {
-	hash_count_t i;
-
 	assert(h);
 	assert(op && op->hash && op->compare);
@@ -63,10 +62,10 @@
 	
 	h->entry = malloc(m * sizeof(link_t));
-	if (!h->entry) {
-		printf("cannot allocate memory for hash table\n");
+	if (!h->entry)
 		return false;
-	}
+	
 	memset((void *) h->entry, 0,  m * sizeof(link_t));
 	
+	hash_count_t i;
 	for (i = 0; i < m; i++)
 		list_initialize(&h->entry[i]);
@@ -75,4 +74,5 @@
 	h->max_keys = max_keys;
 	h->op = op;
+	
 	return true;
 }
@@ -80,5 +80,6 @@
 /** Destroy a hash table instance.
  *
- * @param h		Hash table to be destroyed.
+ * @param h Hash table to be destroyed.
+ *
  */
 void hash_table_destroy(hash_table_t *h)
@@ -86,4 +87,5 @@
 	assert(h);
 	assert(h->entry);
+	
 	free(h->entry);
 }
@@ -91,16 +93,14 @@
 /** Insert item into a hash table.
  *
- * @param h		Hash table.
- * @param key		Array of all keys necessary to compute hash index.
- * @param item		Item to be inserted into the hash table.
+ * @param h    Hash table.
+ * @param key  Array of all keys necessary to compute hash index.
+ * @param item Item to be inserted into the hash table.
  */
 void hash_table_insert(hash_table_t *h, unsigned long key[], link_t *item)
 {
-	hash_index_t chain;
-
 	assert(item);
 	assert(h && h->op && h->op->hash && h->op->compare);
-
-	chain = h->op->hash(key);
+	
+	hash_index_t chain = h->op->hash(key);
 	assert(chain < h->entries);
 	
@@ -110,19 +110,18 @@
 /** Search hash table for an item matching keys.
  *
- * @param h		Hash table.
- * @param key		Array of all keys needed to compute hash index.
- *
- * @return		Matching item on success, NULL if there is no such item.
+ * @param h   Hash table.
+ * @param key Array of all keys needed to compute hash index.
+ *
+ * @return Matching item on success, NULL if there is no such item.
+ *
  */
 link_t *hash_table_find(hash_table_t *h, unsigned long key[])
 {
+	assert(h && h->op && h->op->hash && h->op->compare);
+	
+	hash_index_t chain = h->op->hash(key);
+	assert(chain < h->entries);
+	
 	link_t *cur;
-	hash_index_t chain;
-
-	assert(h && h->op && h->op->hash && h->op->compare);
-
-	chain = h->op->hash(key);
-	assert(chain < h->entries);
-	
 	for (cur = h->entry[chain].next; cur != &h->entry[chain];
 	    cur = cur->next) {
@@ -142,25 +141,24 @@
  * For each removed item, h->remove_callback() is called.
  *
- * @param h		Hash table.
- * @param key		Array of keys that will be compared against items of
- * 			the hash table.
- * @param keys		Number of keys in the 'key' array.
+ * @param h    Hash table.
+ * @param key  Array of keys that will be compared against items of
+ *             the hash table.
+ * @param keys Number of keys in the 'key' array.
+ *
  */
 void hash_table_remove(hash_table_t *h, unsigned long key[], hash_count_t keys)
 {
-	hash_index_t chain;
-	link_t *cur;
-
 	assert(h && h->op && h->op->hash && h->op->compare &&
 	    h->op->remove_callback);
 	assert(keys <= h->max_keys);
 	
+	link_t *cur;
+	
 	if (keys == h->max_keys) {
-
 		/*
 		 * All keys are known, hash_table_find() can be used to find the
 		 * entry.
 		 */
-	
+		
 		cur = hash_table_find(h, key);
 		if (cur) {
@@ -168,4 +166,5 @@
 			h->op->remove_callback(cur);
 		}
+		
 		return;
 	}
@@ -175,4 +174,5 @@
 	 * Any partially matching entries are to be removed.
 	 */
+	hash_index_t chain;
 	for (chain = 0; chain < h->entries; chain++) {
 		for (cur = h->entry[chain].next; cur != &h->entry[chain];
@@ -195,14 +195,14 @@
 /** Apply fucntion to all items in hash table.
  *
- * @param h		Hash table.
- * @param f		Function to be applied.
- * @param arg		Argument to be passed to the function.
- */
-void
-hash_table_apply(hash_table_t *h, void (*f)(link_t *, void *), void *arg)
+ * @param h   Hash table.
+ * @param f   Function to be applied.
+ * @param arg Argument to be passed to the function.
+ *
+ */
+void hash_table_apply(hash_table_t *h, void (*f)(link_t *, void *), void *arg)
 {
 	hash_index_t bucket;
 	link_t *cur;
-
+	
 	for (bucket = 0; bucket < h->entries; bucket++) {
 		for (cur = h->entry[bucket].next; cur != &h->entry[bucket];
Index: uspace/lib/c/generic/arg_parse.c
===================================================================
--- uspace/lib/c/generic/arg_parse.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/c/generic/arg_parse.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+/** @file
+ * Command-line arguments parsing functions
+ */
+
+#include <arg_parse.h>
+#include <errno.h>
+#include <str.h>
+
+int arg_parse_short_long(const char *arg, const char *ashort, const char *along)
+{
+	if (str_cmp(arg, ashort) == 0)
+		return 0;
+	
+	if (str_lcmp(arg, along, str_length(along)) == 0)
+		return str_length(along);
+	
+	return -1;
+}
+
+/** Parse the next argument as an integer.
+ *
+ * The actual argument is pointed by the index.
+ * Parse the offseted argument value if the offset is set
+ * or the next one if not.
+ *
+ * @param[in]     argc   The total number of arguments.
+ * @param[in]     argv   The arguments.
+ * @param[in,out] index  The actual argument index. The index is incremented
+ *                       by the number of processed arguments.
+ * @param[out]    value  The parsed argument value.
+ * @param[in]     offset The value offset in the actual argument. If not set,
+ *                       the next argument is parsed instead.
+ *
+ * @return EOK on success.
+ * @return ENOENT if the argument is missing.
+ * @return EINVAL if the argument is in wrong format.
+ *
+ */
+int arg_parse_int(int argc, char *argv[], int *index, int *value,
+    int offset)
+{
+	char *rest;
+	
+	if (offset)
+		*value = strtol(argv[*index] + offset, &rest, 10);
+	else if ((*index) + 1 < argc) {
+		(*index)++;
+		*value = strtol(argv[*index], &rest, 10);
+	} else
+		return ENOENT;
+	
+	if ((rest) && (*rest))
+		return EINVAL;
+	
+	return EOK;
+}
+
+/** Parse the next named argument as an integral number.
+ *
+ * The actual argument is pointed by the index.
+ * Parse the offseted actual argument if the offset is set or the next
+ * one if not. Translate the argument using the parse_value function.
+ * Increment the actual index by the number of processed arguments.
+ *
+ * @param[in]     argc        The total number of arguments.
+ * @param[in]     argv        The arguments.
+ * @param[in,out] index       The actual argument index. The index is
+ *                            incremented by the number of processed arguments.
+ * @param[out]    value       The parsed argument value.
+ * @param[in]     offset      The value offset in the actual argument. If not
+ *                            set, the next argument is parsed instead.
+ * @param[in]     parse_value The translation function to parse the named value.
+ *
+ * @return EOK on success.
+ * @return ENOENT if the argument is missing.
+ * @return EINVAL if the argument name has not been found.
+ *
+ */
+int arg_parse_name_int(int argc, char *argv[], int *index, int *value,
+    int offset, arg_parser parser)
+{
+	char *arg;
+	
+	int ret = arg_parse_string(argc, argv, index, &arg, offset);
+	if (ret != EOK)
+		return ret;
+	
+	return parser(arg, value);
+}
+
+/** Parse the next argument as a character string.
+ *
+ * The actual argument is pointed by the index.
+ * Parse the offseted actual argument value if the offset is set or the next
+ * one if not. Increment the actual index by the number of processed arguments.
+ *
+ * @param[in]     argc   The total number of arguments.
+ * @param[in]     argv   The arguments.
+ * @param[in,out] index  The actual argument index. The index is
+ *                       incremented by the number of processed arguments.
+ * @param[out]    value  The parsed argument value.
+ * @param[in]     offset The value offset in the actual argument. If not set,
+ *                       the next argument is parsed instead.
+ *
+ * @return EOK on success.
+ * @return ENOENT if the parameter is missing.
+ *
+ */
+int arg_parse_string(int argc, char **argv, int *index, char **value,
+    int offset)
+{
+	if (offset)
+		*value = argv[*index] + offset;
+	else if ((*index) + 1 < argc) {
+		(*index)++;
+		*value = argv[*index];
+	} else
+		return ENOENT;
+	
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/async.c
===================================================================
--- uspace/lib/c/generic/async.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/generic/async.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -746,5 +746,5 @@
 	if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_CHAINS, 1,
 	    &conn_hash_table_ops)) {
-		printf("%s: cannot create hash table\n", "async");
+		printf("%s: Cannot create async hash table\n", "libc");
 		return ENOMEM;
 	}
Index: uspace/lib/c/generic/fibril.c
===================================================================
--- uspace/lib/c/generic/fibril.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/generic/fibril.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -48,10 +48,11 @@
 
 #ifndef FIBRIL_INITIAL_STACK_PAGES_NO
-#define FIBRIL_INITIAL_STACK_PAGES_NO	1
+	#define FIBRIL_INITIAL_STACK_PAGES_NO  1
 #endif
 
 /**
- * This futex serializes access to ready_list, serialized_list and manager_list.
- */ 
+ * This futex serializes access to ready_list,
+ * serialized_list and manager_list.
+ */
 static atomic_t fibril_futex = FUTEX_INITIALIZER;
 
@@ -60,47 +61,15 @@
 static LIST_INITIALIZE(manager_list);
 
-static void fibril_main(void);
-
 /** Number of threads that are executing a manager fibril. */
 static int threads_in_manager;
-/** Number of threads that are executing a manager fibril and are serialized. */
-static int serialized_threads;	/* Protected by async_futex */
+
+/**
+ * Number of threads that are executing a manager fibril
+ * and are serialized. Protected by async_futex.
+ */
+static int serialized_threads;
+
 /** Fibril-local count of serialization. If > 0, we must not preempt */
 static fibril_local int serialization_count;
-
-/** Setup fibril information into TCB structure */
-fibril_t *fibril_setup(void)
-{
-	fibril_t *f;
-	tcb_t *tcb;
-
-	tcb = __make_tls();
-	if (!tcb)
-		return NULL;
-
-	f = malloc(sizeof(fibril_t));
-	if (!f) {
-		__free_tls(tcb);
-		return NULL;
-	}
-
-	tcb->fibril_data = f;
-	f->tcb = tcb;
-
-	f->func = NULL;
-	f->arg = NULL;
-	f->stack = NULL;
-	f->clean_after_me = NULL;
-	f->retval = 0;
-	f->flags = 0;
-
-	return f;
-}
-
-void fibril_teardown(fibril_t *f)
-{
-	__free_tls(f->tcb);
-	free(f);
-}
 
 /** Function that spans the whole life-cycle of a fibril.
@@ -109,14 +78,49 @@
  * the fibril logic is called.  After its return, the return value is saved.
  * The fibril then switches to another fibril, which cleans up after it.
- */
-void fibril_main(void)
-{
-	fibril_t *f = __tcb_get()->fibril_data;
-
+ *
+ */
+static void fibril_main(void)
+{
+	fibril_t *fibril = __tcb_get()->fibril_data;
+	
 	/* Call the implementing function. */
-	f->retval = f->func(f->arg);
-
+	fibril->retval = fibril->func(fibril->arg);
+	
 	fibril_switch(FIBRIL_FROM_DEAD);
-	/* not reached */
+	/* Not reached */
+}
+
+/** Setup fibril information into TCB structure
+ *
+ */
+fibril_t *fibril_setup(void)
+{
+	tcb_t *tcb = __make_tls();
+	if (!tcb)
+		return NULL;
+	
+	fibril_t *fibril = malloc(sizeof(fibril_t));
+	if (!fibril) {
+		__free_tls(tcb);
+		return NULL;
+	}
+	
+	tcb->fibril_data = fibril;
+	fibril->tcb = tcb;
+	
+	fibril->func = NULL;
+	fibril->arg = NULL;
+	fibril->stack = NULL;
+	fibril->clean_after_me = NULL;
+	fibril->retval = 0;
+	fibril->flags = 0;
+	
+	return fibril;
+}
+
+void fibril_teardown(fibril_t *fibril)
+{
+	__free_tls(fibril->tcb);
+	free(fibril);
 }
 
@@ -126,9 +130,11 @@
  * held.
  *
- * @param stype		Switch type. One of FIBRIL_PREEMPT, FIBRIL_TO_MANAGER,
- * 			FIBRIL_FROM_MANAGER, FIBRIL_FROM_DEAD. The parameter
- * 			describes the circumstances of the switch.
- * @return		Return 0 if there is no ready fibril,
- * 			return 1 otherwise.
+ * @param stype Switch type. One of FIBRIL_PREEMPT, FIBRIL_TO_MANAGER,
+ *              FIBRIL_FROM_MANAGER, FIBRIL_FROM_DEAD. The parameter
+ *              describes the circumstances of the switch.
+ *
+ * @return 0 if there is no ready fibril,
+ * @return 1 otherwise.
+ *
  */
 int fibril_switch(fibril_switch_type_t stype)
@@ -246,48 +252,52 @@
 /** Create a new fibril.
  *
- * @param func		Implementing function of the new fibril.
- * @param arg		Argument to pass to func.
- *
- * @return		Return 0 on failure or TLS of the new fibril.
+ * @param func Implementing function of the new fibril.
+ * @param arg Argument to pass to func.
+ *
+ * @return 0 on failure or TLS of the new fibril.
+ *
  */
 fid_t fibril_create(int (*func)(void *), void *arg)
 {
-	fibril_t *f;
-
-	f = fibril_setup();
-	if (!f) 
+	fibril_t *fibril;
+	
+	fibril = fibril_setup();
+	if (fibril == NULL)
 		return 0;
-	f->stack = (char *) malloc(FIBRIL_INITIAL_STACK_PAGES_NO *
-	    getpagesize());
-	if (!f->stack) {
-		fibril_teardown(f);
+	
+	fibril->stack =
+	    (char *) malloc(FIBRIL_INITIAL_STACK_PAGES_NO * getpagesize());
+	if (!fibril->stack) {
+		fibril_teardown(fibril);
 		return 0;
 	}
 	
-	f->func = func;
-	f->arg = arg;
-
-	context_save(&f->ctx);
-	context_set(&f->ctx, FADDR(fibril_main), f->stack,
-	    FIBRIL_INITIAL_STACK_PAGES_NO * getpagesize(), f->tcb);
-
-	return (fid_t) f;
+	fibril->func = func;
+	fibril->arg = arg;
+	
+	context_save(&fibril->ctx);
+	context_set(&fibril->ctx, FADDR(fibril_main), fibril->stack,
+	    FIBRIL_INITIAL_STACK_PAGES_NO * getpagesize(), fibril->tcb);
+
+	return (fid_t) fibril;
 }
 
 /** Add a fibril to the ready list.
  *
- * @param fid		Pointer to the fibril structure of the fibril to be
- *			added.
+ * @param fid Pointer to the fibril structure of the fibril to be
+ *            added.
+ *
  */
 void fibril_add_ready(fid_t fid)
 {
-	fibril_t *f;
-
-	f = (fibril_t *) fid;
+	fibril_t *fibril = (fibril_t *) fid;
+	
 	futex_down(&fibril_futex);
-	if ((f->flags & FIBRIL_SERIALIZED))
-		list_append(&f->link, &serialized_list);
+	
+	if ((fibril->flags & FIBRIL_SERIALIZED))
+		list_append(&fibril->link, &serialized_list);
 	else
-		list_append(&f->link, &ready_list);
+		list_append(&fibril->link, &ready_list);
+	
 	futex_up(&fibril_futex);
 }
@@ -295,15 +305,14 @@
 /** Add a fibril to the manager list.
  *
- * @param fid		Pointer to the fibril structure of the fibril to be
- *			added.
+ * @param fid Pointer to the fibril structure of the fibril to be
+ *            added.
+ *
  */
 void fibril_add_manager(fid_t fid)
 {
-	fibril_t *f;
-
-	f = (fibril_t *) fid;
-
+	fibril_t *fibril = (fibril_t *) fid;
+	
 	futex_down(&fibril_futex);
-	list_append(&f->link, &manager_list);
+	list_append(&fibril->link, &manager_list);
 	futex_up(&fibril_futex);
 }
@@ -313,9 +322,8 @@
 {
 	futex_down(&fibril_futex);
-	if (list_empty(&manager_list)) {
-		futex_up(&fibril_futex);
-		return;
-	}
-	list_remove(manager_list.next);
+	
+	if (!list_empty(&manager_list))
+		list_remove(manager_list.next);
+	
 	futex_up(&fibril_futex);
 }
Index: uspace/lib/c/generic/futex.c
===================================================================
--- uspace/lib/c/generic/futex.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/generic/futex.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -31,5 +31,5 @@
  */
 /** @file
- */ 
+ */
 
 #include <futex.h>
@@ -40,6 +40,7 @@
 /** Initialize futex counter.
  *
- * @param futex		Futex.
- * @param val		Initialization value.
+ * @param futex Futex.
+ * @param val   Initialization value.
+ *
  */
 void futex_initialize(futex_t *futex, int val)
@@ -50,7 +51,9 @@
 /** Try to down the futex.
  *
- * @param futex		Futex.
- * @return		Non-zero if the futex was acquired.
- * @return		Zero if the futex was not acquired.
+ * @param futex Futex.
+ *
+ * @return Non-zero if the futex was acquired.
+ * @return Zero if the futex was not acquired.
+ *
  */
 int futex_trydown(futex_t *futex)
@@ -61,8 +64,10 @@
 /** Down the futex.
  *
- * @param futex		Futex.
- * @return		ENOENT if there is no such virtual address.
- * @return		Zero in the uncontended case. 
- * @return		Otherwise one of ESYNCH_OK_ATOMIC or ESYNCH_OK_BLOCKED.
+ * @param futex Futex.
+ *
+ * @return ENOENT if there is no such virtual address.
+ * @return Zero in the uncontended case.
+ * @return Otherwise one of ESYNCH_OK_ATOMIC or ESYNCH_OK_BLOCKED.
+ *
  */
 int futex_down(futex_t *futex)
@@ -70,5 +75,5 @@
 	if ((atomic_signed_t) atomic_predec(futex) < 0)
 		return __SYSCALL1(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count);
-
+	
 	return 0;
 }
@@ -76,7 +81,9 @@
 /** Up the futex.
  *
- * @param futex		Futex.
- * @return		ENOENT if there is no such virtual address.
- * @return		Zero in the uncontended case.
+ * @param futex Futex.
+ *
+ * @return ENOENT if there is no such virtual address.
+ * @return Zero in the uncontended case.
+ *
  */
 int futex_up(futex_t *futex)
@@ -84,5 +91,5 @@
 	if ((atomic_signed_t) atomic_postinc(futex) < 0)
 		return __SYSCALL1(SYS_FUTEX_WAKEUP, (sysarg_t) &futex->count);
-		
+	
 	return 0;
 }
Index: uspace/lib/c/generic/io/asprintf.c
===================================================================
--- uspace/lib/c/generic/io/asprintf.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/generic/io/asprintf.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -61,5 +61,5 @@
 int asprintf(char **strp, const char *fmt, ...)
 {
-	struct printf_spec ps = {
+	printf_spec_t ps = {
 		asprintf_str_write,
 		asprintf_wstr_write,
Index: uspace/lib/c/generic/io/console.c
===================================================================
--- uspace/lib/c/generic/io/console.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/generic/io/console.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -45,28 +45,21 @@
 }
 
-int console_get_size(int phone, int *cols, int *rows)
+int console_get_size(int phone, ipcarg_t *cols, ipcarg_t *rows)
 {
-	ipcarg_t cols_v;
-	ipcarg_t rows_v;
-	int rc;
-
-	rc = async_req_0_2(phone, CONSOLE_GET_SIZE, &cols_v, &rows_v);
-
-	*cols = (int) cols_v;
-	*rows = (int) rows_v;
-	return rc;
+	return async_req_0_2(phone, CONSOLE_GET_SIZE, cols, rows);
 }
 
-void console_set_style(int phone, int style)
+void console_set_style(int phone, uint8_t style)
 {
 	async_msg_1(phone, CONSOLE_SET_STYLE, style);
 }
 
-void console_set_color(int phone, int fg_color, int bg_color, int flags)
+void console_set_color(int phone, uint8_t fg_color, uint8_t bg_color,
+    uint8_t flags)
 {
 	async_msg_3(phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
 }
 
-void console_set_rgb_color(int phone, int fg_color, int bg_color)
+void console_set_rgb_color(int phone, uint32_t fg_color, uint32_t bg_color)
 {
 	async_msg_2(phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
@@ -75,16 +68,10 @@
 void console_cursor_visibility(int phone, bool show)
 {
-	async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, show != false);
+	async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, (show != false));
 }
 
-int console_get_color_cap(int phone, int *ccap)
+int console_get_color_cap(int phone, ipcarg_t *ccap)
 {
-	ipcarg_t ccap_tmp;
-	int rc;
-
-	rc = async_req_0_1(phone, CONSOLE_GET_COLOR_CAP, &ccap_tmp);
-	*ccap = ccap_tmp;
-
-	return rc;
+	return async_req_0_1(phone, CONSOLE_GET_COLOR_CAP, ccap);
 }
 
@@ -94,18 +81,10 @@
 }
 
-int console_get_pos(int phone, int *col, int *row)
+int console_get_pos(int phone, ipcarg_t *col, ipcarg_t *row)
 {
-	ipcarg_t col_v;
-	ipcarg_t row_v;
-	int rc;
-
-	rc = async_req_0_2(phone, CONSOLE_GET_POS, &col_v, &row_v);
-
-	*col = (int) col_v;
-	*row = (int) row_v;
-	return rc;
+	return async_req_0_2(phone, CONSOLE_GET_POS, col, row);
 }
 
-void console_goto(int phone, int col, int row)
+void console_set_pos(int phone, ipcarg_t col, ipcarg_t row)
 {
 	async_msg_2(phone, CONSOLE_GOTO, col, row);
Index: uspace/lib/c/generic/io/printf_core.c
===================================================================
--- uspace/lib/c/generic/io/printf_core.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/generic/io/printf_core.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -45,16 +45,23 @@
 /** show prefixes 0x or 0 */
 #define __PRINTF_FLAG_PREFIX       0x00000001
+
 /** signed / unsigned number */
 #define __PRINTF_FLAG_SIGNED       0x00000002
+
 /** print leading zeroes */
 #define __PRINTF_FLAG_ZEROPADDED   0x00000004
+
 /** align to left */
 #define __PRINTF_FLAG_LEFTALIGNED  0x00000010
+
 /** always show + sign */
 #define __PRINTF_FLAG_SHOWPLUS     0x00000020
+
 /** print space instead of plus */
 #define __PRINTF_FLAG_SPACESIGN    0x00000040
+
 /** show big characters */
 #define __PRINTF_FLAG_BIGCHARS     0x00000080
+
 /** number has - sign */
 #define __PRINTF_FLAG_NEGATIVE     0x00000100
@@ -78,8 +85,8 @@
 } qualifier_t;
 
-static char nullstr[] = "(NULL)";
-static char digits_small[] = "0123456789abcdef";
-static char digits_big[] = "0123456789ABCDEF";
-static char invalch = U_SPECIAL;
+static const char *nullstr = "(NULL)";
+static const char *digits_small = "0123456789abcdef";
+static const char *digits_big = "0123456789ABCDEF";
+static const char invalch = U_SPECIAL;
 
 /** Print one or more characters without adding newline.
@@ -350,5 +357,5 @@
     uint32_t flags, printf_spec_t *ps)
 {
-	char *digits;
+	const char *digits;
 	if (flags & __PRINTF_FLAG_BIGCHARS)
 		digits = digits_big;
Index: uspace/lib/c/generic/io/screenbuffer.c
===================================================================
--- uspace/lib/c/generic/io/screenbuffer.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/c/generic/io/screenbuffer.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup console
+ * @{
+ */
+/** @file
+ */
+
+#include <io/style.h>
+#include <io/screenbuffer.h>
+#include <malloc.h>
+#include <unistd.h>
+
+/** Store one character to screenbuffer.
+ *
+ * Its position is determined by scr->position_x
+ * and scr->position_y.
+ *
+ * @param scr Screenbuffer
+ * @param c   Stored character
+ *
+ */
+void screenbuffer_putchar(screenbuffer_t *scr, wchar_t ch)
+{
+	keyfield_t *field =
+	    get_field_at(scr, scr->position_x, scr->position_y);
+	
+	field->character = ch;
+	field->attrs = scr->attrs;
+}
+
+/** Initilize screenbuffer.
+ *
+ * Allocate space for screen content in accordance to given size.
+ *
+ * @param scr    Initialized screenbuffer
+ * @param size_x Width in characters
+ * @param size_y Height in characters
+ *
+ * @return Pointer to screenbuffer (same as scr parameter) or NULL
+ *
+ */
+screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, ipcarg_t size_x,
+    ipcarg_t size_y)
+{
+	scr->buffer = (keyfield_t *) malloc(sizeof(keyfield_t) * size_x * size_y);
+	if (!scr->buffer)
+		return NULL;
+	
+	scr->size_x = size_x;
+	scr->size_y = size_y;
+	scr->attrs.t = at_style;
+	scr->attrs.a.s.style = STYLE_NORMAL;
+	scr->is_cursor_visible = 1;
+	
+	screenbuffer_clear(scr);
+	
+	return scr;
+}
+
+/** Clear screenbuffer.
+ *
+ * @param scr Screenbuffer
+ *
+ */
+void screenbuffer_clear(screenbuffer_t *scr)
+{
+	size_t i;
+	
+	for (i = 0; i < (scr->size_x * scr->size_y); i++) {
+		scr->buffer[i].character = ' ';
+		scr->buffer[i].attrs = scr->attrs;
+	}
+	
+	scr->top_line = 0;
+	scr->position_x = 0;
+	scr->position_y = 0;
+}
+
+/** Clear one buffer line.
+ *
+ * @param scr
+ * @param line One buffer line (not a screen line!)
+ *
+ */
+void screenbuffer_clear_line(screenbuffer_t *scr, ipcarg_t line)
+{
+	ipcarg_t x;
+	
+	for (x = 0; x < scr->size_x; x++) {
+		scr->buffer[x + line * scr->size_x].character = ' ';
+		scr->buffer[x + line * scr->size_x].attrs = scr->attrs;
+	}
+}
+
+/** Copy content buffer from screenbuffer to given memory.
+ *
+ * @param scr  Source screenbuffer
+ * @param dest Destination
+ *
+ */
+void screenbuffer_copy_buffer(screenbuffer_t *scr, keyfield_t *dest)
+{
+	size_t i;
+	
+	for (i = 0; i < (scr->size_x * scr->size_y); i++)
+		dest[i] = scr->buffer[i];
+}
+
+/** Set new cursor position in screenbuffer.
+ *
+ * @param scr
+ * @param x
+ * @param y
+ *
+ */
+void screenbuffer_goto(screenbuffer_t *scr, ipcarg_t x, ipcarg_t y)
+{
+	scr->position_x = x % scr->size_x;
+	scr->position_y = y % scr->size_y;
+}
+
+/** Set new style.
+ *
+ * @param scr
+ * @param fg_color
+ * @param bg_color
+ *
+ */
+void screenbuffer_set_style(screenbuffer_t *scr, uint8_t style)
+{
+	scr->attrs.t = at_style;
+	scr->attrs.a.s.style = style;
+}
+
+/** Set new color.
+ *
+ * @param scr
+ * @param fg_color
+ * @param bg_color
+ *
+ */
+void screenbuffer_set_color(screenbuffer_t *scr, uint8_t fg_color,
+    uint8_t bg_color, uint8_t flags)
+{
+	scr->attrs.t = at_idx;
+	scr->attrs.a.i.fg_color = fg_color;
+	scr->attrs.a.i.bg_color = bg_color;
+	scr->attrs.a.i.flags = flags;
+}
+
+/** Set new RGB color.
+ *
+ * @param scr
+ * @param fg_color
+ * @param bg_color
+ *
+ */
+void screenbuffer_set_rgb_color(screenbuffer_t *scr, uint32_t fg_color,
+    uint32_t bg_color)
+{
+	scr->attrs.t = at_rgb;
+	scr->attrs.a.r.fg_color = fg_color;
+	scr->attrs.a.r.bg_color = bg_color;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/io/vprintf.c
===================================================================
--- uspace/lib/c/generic/io/vprintf.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/generic/io/vprintf.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -76,5 +76,5 @@
 int vfprintf(FILE *stream, const char *fmt, va_list ap)
 {
-	struct printf_spec ps = {
+	printf_spec_t ps = {
 		vprintf_str_write,
 		vprintf_wstr_write,
Index: uspace/lib/c/generic/libc.c
===================================================================
--- uspace/lib/c/generic/libc.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/generic/libc.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -62,6 +62,5 @@
 void __main(void *pcb_ptr)
 {
-	int retval;
-
+	/* Initialize user task run-time environment */
 	__heap_init();
 	__async_init();
@@ -75,4 +74,6 @@
 	char **argv;
 	
+	/* Get command line arguments and initialize
+	   standard input and output */
 	if (__pcb == NULL) {
 		argc = 0;
@@ -86,12 +87,12 @@
 	}
 	
-	retval = main(argc, argv);
-
-	__stdio_done();
-	(void) task_retval(retval);
+	/* Run main() and set task return value
+	   according the result */
+	(void) task_retval(main(argc, argv));
 }
 
 void __exit(void)
 {
+	__stdio_done();
 	fibril_teardown(__tcb_get()->fibril_data);
 	_exit(0);
Index: uspace/lib/c/generic/malloc.c
===================================================================
--- uspace/lib/c/generic/malloc.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/generic/malloc.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -43,4 +43,5 @@
 #include <bitops.h>
 #include <mem.h>
+#include <futex.h>
 #include <adt/gcdlcm.h>
 
@@ -75,5 +76,4 @@
 #define NET_SIZE(size)  ((size) - STRUCT_OVERHEAD)
 
-
 /** Header of a heap block
  *
@@ -104,4 +104,7 @@
 extern char _heap;
 
+/** Futex for thread-safe heap manipulation */
+static futex_t malloc_futex = FUTEX_INITIALIZER;
+
 /** Address of heap start */
 static void *heap_start = 0;
@@ -119,4 +122,5 @@
  *
  * Fills in the structures related to a heap block.
+ * Should be called only inside the critical section.
  *
  * @param addr Address of the block.
@@ -144,4 +148,5 @@
  * Verifies that the structures related to a heap block still contain
  * the magic constants. This helps detect heap corruption early on.
+ * Should be called only inside the critical section.
  *
  * @param addr Address of the block.
@@ -161,4 +166,11 @@
 }
 
+/** Increase the heap area size
+ *
+ * Should be called only inside the critical section.
+ *
+ * @param size Number of bytes to grow the heap by.
+ *
+ */
 static bool grow_heap(size_t size)
 {
@@ -189,4 +201,11 @@
 }
 
+/** Decrease the heap area
+ *
+ * Should be called only inside the critical section.
+ *
+ * @param size Number of bytes to shrink the heap by.
+ *
+ */
 static void shrink_heap(void)
 {
@@ -196,5 +215,5 @@
 /** Initialize the heap allocator
  *
- * Finds how much physical memory we have and creates
+ * Find how much physical memory we have and create
  * the heap management structures that mark the whole
  * physical memory as a single free block.
@@ -203,4 +222,6 @@
 void __heap_init(void)
 {
+	futex_down(&malloc_futex);
+	
 	if (as_area_create((void *) &_heap, PAGE_SIZE,
 	    AS_AREA_WRITE | AS_AREA_READ)) {
@@ -213,15 +234,35 @@
 		block_init(heap_start, heap_end - heap_start, true);
 	}
-}
-
+	
+	futex_up(&malloc_futex);
+}
+
+/** Get maximum heap address
+ *
+ */
 uintptr_t get_max_heap_addr(void)
 {
+	futex_down(&malloc_futex);
+	
 	if (max_heap_size == (size_t) -1)
 		max_heap_size =
 		    max((size_t) (heap_end - heap_start), MAX_HEAP_SIZE);
 	
-	return ((uintptr_t) heap_start + max_heap_size);
-}
-
+	uintptr_t max_heap_addr = (uintptr_t) heap_start + max_heap_size;
+	
+	futex_up(&malloc_futex);
+	
+	return max_heap_addr;
+}
+
+/** Split heap block and mark it as used.
+ *
+ * Should be called only inside the critical section.
+ *
+ * @param cur  Heap block to split.
+ * @param size Number of bytes to split and mark from the beginning
+ *             of the block.
+ *
+ */
 static void split_mark(heap_block_head_t *cur, const size_t size)
 {
@@ -243,4 +284,6 @@
 
 /** Allocate a memory block
+ *
+ * Should be called only inside the critical section.
  *
  * @param size  The size of the block to allocate.
@@ -356,4 +399,12 @@
 }
 
+/** Allocate memory by number of elements
+ *
+ * @param nmemb Number of members to allocate.
+ * @param size  Size of one member in bytes.
+ *
+ * @return Allocated memory or NULL.
+ *
+ */
 void *calloc(const size_t nmemb, const size_t size)
 {
@@ -361,14 +412,33 @@
 	if (block == NULL)
 		return NULL;
-
+	
 	memset(block, 0, nmemb * size);
 	return block;
 }
 
+/** Allocate memory
+ *
+ * @param size Number of bytes to allocate.
+ *
+ * @return Allocated memory or NULL.
+ *
+ */
 void *malloc(const size_t size)
 {
-	return malloc_internal(size, BASE_ALIGN);
-}
-
+	futex_down(&malloc_futex);
+	void *block = malloc_internal(size, BASE_ALIGN);
+	futex_up(&malloc_futex);
+	
+	return block;
+}
+
+/** Allocate memory with specified alignment
+ *
+ * @param align Alignment in byes.
+ * @param size  Number of bytes to allocate.
+ *
+ * @return Allocated memory or NULL.
+ *
+ */
 void *memalign(const size_t align, const size_t size)
 {
@@ -379,11 +449,25 @@
 	    1 << (fnzb(max(sizeof(void *), align) - 1) + 1);
 	
-	return malloc_internal(size, palign);
-}
-
+	futex_down(&malloc_futex);
+	void *block = malloc_internal(size, palign);
+	futex_up(&malloc_futex);
+	
+	return block;
+}
+
+/** Reallocate memory block
+ *
+ * @param addr Already allocated memory or NULL.
+ * @param size New size of the memory block.
+ *
+ * @return Reallocated memory or NULL.
+ *
+ */
 void *realloc(const void *addr, const size_t size)
 {
 	if (addr == NULL)
 		return malloc(size);
+	
+	futex_down(&malloc_futex);
 	
 	/* Calculate the position of the header. */
@@ -398,4 +482,5 @@
 	
 	void *ptr = NULL;
+	bool reloc = false;
 	size_t real_size = GROSS_SIZE(ALIGN_UP(size, BASE_ALIGN));
 	size_t orig_size = head->size;
@@ -415,5 +500,7 @@
 	} else {
 		/* Look at the next block. If it is free and the size is
-		   sufficient then merge the two. */
+		   sufficient then merge the two. Otherwise just allocate
+		   a new block, copy the original data into it and
+		   free the original block. */
 		heap_block_head_t *next_head =
 		    (heap_block_head_t *) (((void *) head) + head->size);
@@ -427,10 +514,15 @@
 			
 			ptr = ((void *) head) + sizeof(heap_block_head_t);
-		} else {
-			ptr = malloc(size);
-			if (ptr != NULL) {
-				memcpy(ptr, addr, NET_SIZE(orig_size));
-				free(addr);
-			}
+		} else
+			reloc = true;
+	}
+	
+	futex_up(&malloc_futex);
+	
+	if (reloc) {
+		ptr = malloc(size);
+		if (ptr != NULL) {
+			memcpy(ptr, addr, NET_SIZE(orig_size));
+			free(addr);
 		}
 	}
@@ -442,7 +534,10 @@
  *
  * @param addr The address of the block.
+ *
  */
 void free(const void *addr)
 {
+	futex_down(&malloc_futex);
+	
 	/* Calculate the position of the header. */
 	heap_block_head_t *head
@@ -483,4 +578,6 @@
 	
 	shrink_heap();
+	
+	futex_up(&malloc_futex);
 }
 
Index: uspace/lib/c/generic/stats.c
===================================================================
--- uspace/lib/c/generic/stats.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/c/generic/stats.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2010 Stanislav Kozina
+ * Copyright (c) 2010 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#include <stats.h>
+#include <sysinfo.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <inttypes.h>
+
+#define SYSINFO_STATS_MAX_PATH  64
+
+/** Thread states
+ *
+ */
+static const char *thread_states[] = {
+	"Invalid",
+	"Running",
+	"Sleeping",
+	"Ready",
+	"Entering",
+	"Exiting",
+	"Lingering"
+};
+
+/** Get CPUs statistics
+ *
+ * @param count Number of records returned.
+ *
+ * @return Array of stats_cpu_t structures.
+ *         If non-NULL then it should be eventually freed
+ *         by free().
+ *
+ */
+stats_cpu_t *stats_get_cpus(size_t *count)
+{
+	size_t size = 0;
+	stats_cpu_t *stats_cpus =
+	    (stats_cpu_t *) sysinfo_get_data("system.cpus", &size);
+	
+	assert((size % sizeof(stats_cpu_t)) == 0);
+	
+	*count = size / sizeof(stats_cpu_t);
+	return stats_cpus;
+}
+
+/** Get physical memory statistics
+ *
+ *
+ * @return Pointer to the stats_physmem_t structure.
+ *         If non-NULL then it should be eventually freed
+ *         by free().
+ *
+ */
+stats_physmem_t *stats_get_physmem(void)
+{
+	size_t size = 0;
+	stats_physmem_t *stats_physmem =
+	    (stats_physmem_t *) sysinfo_get_data("system.physmem", &size);
+	
+	assert((size == sizeof(stats_physmem_t)) || (size == 0));
+	
+	return stats_physmem;
+}
+
+/** Get task statistics
+ *
+ * @param count Number of records returned.
+ *
+ * @return Array of stats_task_t structures.
+ *         If non-NULL then it should be eventually freed
+ *         by free().
+ *
+ */
+stats_task_t *stats_get_tasks(size_t *count)
+{
+	size_t size = 0;
+	stats_task_t *stats_tasks =
+	    (stats_task_t *) sysinfo_get_data("system.tasks", &size);
+	
+	assert((size % sizeof(stats_task_t)) == 0);
+	
+	*count = size / sizeof(stats_task_t);
+	return stats_tasks;
+}
+
+/** Get single task statistics
+ *
+ * @param task_id Task ID we are interested in.
+ *
+ * @return Pointer to the stats_task_t structure.
+ *         If non-NULL then it should be eventually freed
+ *         by free().
+ *
+ */
+stats_task_t *stats_get_task(task_id_t task_id)
+{
+	char name[SYSINFO_STATS_MAX_PATH];
+	snprintf(name, SYSINFO_STATS_MAX_PATH, "system.tasks.%" PRIu64, task_id);
+	
+	size_t size = 0;
+	stats_task_t *stats_task =
+	    (stats_task_t *) sysinfo_get_data(name, &size);
+	
+	assert((size == sizeof(stats_task_t)) || (size == 0));
+	
+	return stats_task;
+}
+
+/** Get thread statistics.
+ *
+ * @param count Number of records returned.
+ *
+ * @return Array of stats_thread_t structures.
+ *         If non-NULL then it should be eventually freed
+ *         by free().
+ *
+ */
+stats_thread_t *stats_get_threads(size_t *count)
+{
+	size_t size = 0;
+	stats_thread_t *stats_threads =
+	    (stats_thread_t *) sysinfo_get_data("system.threads", &size);
+	
+	assert((size % sizeof(stats_thread_t)) == 0);
+	
+	*count = size / sizeof(stats_thread_t);
+	return stats_threads;
+}
+
+/** Get single thread statistics
+ *
+ * @param thread_id Thread ID we are interested in.
+ *
+ * @return Pointer to the stats_thread_t structure.
+ *         If non-NULL then it should be eventually freed
+ *         by free().
+ *
+ */
+stats_thread_t *stats_get_thread(thread_id_t thread_id)
+{
+	char name[SYSINFO_STATS_MAX_PATH];
+	snprintf(name, SYSINFO_STATS_MAX_PATH, "system.threads.%" PRIu64, thread_id);
+	
+	size_t size = 0;
+	stats_thread_t *stats_thread =
+	    (stats_thread_t *) sysinfo_get_data(name, &size);
+	
+	assert((size == sizeof(stats_thread_t)) || (size == 0));
+	
+	return stats_thread;
+}
+
+/** Get system load
+ *
+ * @param count Number of load records returned.
+ *
+ * @return Array of load records (load_t).
+ *         If non-NULL then it should be eventually freed
+ *         by free().
+ *
+ */
+load_t *stats_get_load(size_t *count)
+{
+	size_t size = 0;
+	load_t *load =
+	    (load_t *) sysinfo_get_data("system.load", &size);
+	
+	assert((size % sizeof(load_t)) == 0);
+	
+	*count = size / sizeof(load_t);
+	return load;
+}
+
+/** Get system uptime
+ *
+ * @return System uptime (in seconds).
+ *
+ */
+sysarg_t stats_get_uptime(void)
+{
+	sysarg_t uptime;
+	if (sysinfo_get_value("system.uptime", &uptime) != EOK)
+		uptime = 0;
+	
+	return uptime;
+}
+
+/** Print load fixed-point value
+ *
+ * Print the load record fixed-point value in decimal
+ * representation on stdout.
+ *
+ * @param upper      Load record.
+ * @param dec_length Number of decimal digits to print.
+ *
+ */
+void stats_print_load_fragment(load_t upper, unsigned int dec_length)
+{
+	/* Magic value from BSD */
+	load_t lower = 65536;
+	
+	/* Print the whole part */
+	printf("%u.", upper / lower);
+	
+	load_t rest = (upper % lower) * 10;
+	
+	unsigned int i;
+	for (i = 0; i < dec_length; i++) {
+		printf("%u", rest / lower);
+		rest = (rest % lower) * 10;
+	}
+}
+
+const char *thread_get_state(state_t state)
+{
+	if (state <= Lingering)
+		return thread_states[state];
+	
+	return thread_states[Invalid];
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/str.c
===================================================================
--- uspace/lib/c/generic/str.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/generic/str.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -471,5 +471,5 @@
  * null-terminated and containing only complete characters.
  *
- * @param dest   Destination buffer.
+ * @param dest  Destination buffer.
  * @param count Size of the destination buffer (must be > 0).
  * @param src   Source string.
@@ -477,19 +477,16 @@
 void str_cpy(char *dest, size_t size, const char *src)
 {
-	wchar_t ch;
-	size_t src_off;
-	size_t dest_off;
-
 	/* There must be space for a null terminator in the buffer. */
 	assert(size > 0);
 	
-	src_off = 0;
-	dest_off = 0;
-
+	size_t src_off = 0;
+	size_t dest_off = 0;
+	
+	wchar_t ch;
 	while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) {
 		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
 			break;
 	}
-
+	
 	dest[dest_off] = '\0';
 }
@@ -505,26 +502,23 @@
  * have to be null-terminated.
  *
- * @param dest   Destination buffer.
+ * @param dest  Destination buffer.
  * @param count Size of the destination buffer (must be > 0).
  * @param src   Source string.
- * @param n	Maximum number of bytes to read from @a src.
+ * @param n     Maximum number of bytes to read from @a src.
  */
 void str_ncpy(char *dest, size_t size, const char *src, size_t n)
 {
-	wchar_t ch;
-	size_t src_off;
-	size_t dest_off;
-
 	/* There must be space for a null terminator in the buffer. */
 	assert(size > 0);
 	
-	src_off = 0;
-	dest_off = 0;
-
+	size_t src_off = 0;
+	size_t dest_off = 0;
+	
+	wchar_t ch;
 	while ((ch = str_decode(src, &src_off, n)) != 0) {
 		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
 			break;
 	}
-
+	
 	dest[dest_off] = '\0';
 }
@@ -896,28 +890,62 @@
 }
 
+/** Duplicate string.
+ *
+ * Allocate a new string and copy characters from the source
+ * string into it. The duplicate string is allocated via sleeping
+ * malloc(), thus this function can sleep in no memory conditions.
+ *
+ * The allocation cannot fail and the return value is always
+ * a valid pointer. The duplicate string is always a well-formed
+ * null-terminated UTF-8 string, but it can differ from the source
+ * string on the byte level.
+ *
+ * @param src Source string.
+ *
+ * @return Duplicate string.
+ *
+ */
 char *str_dup(const char *src)
 {
-	size_t size = str_size(src);
-	void *dest = malloc(size + 1);
-	
+	size_t size = str_size(src) + 1;
+	char *dest = (char *) malloc(size);
 	if (dest == NULL)
 		return (char *) NULL;
 	
-	return (char *) memcpy(dest, src, size + 1);
-}
-
-char *str_ndup(const char *src, size_t max_size)
+	str_cpy(dest, size, src);
+	return dest;
+}
+
+/** Duplicate string with size limit.
+ *
+ * Allocate a new string and copy up to @max_size bytes from the source
+ * string into it. The duplicate string is allocated via sleeping
+ * malloc(), thus this function can sleep in no memory conditions.
+ * No more than @max_size + 1 bytes is allocated, but if the size
+ * occupied by the source string is smaller than @max_size + 1,
+ * less is allocated.
+ *
+ * The allocation cannot fail and the return value is always
+ * a valid pointer. The duplicate string is always a well-formed
+ * null-terminated UTF-8 string, but it can differ from the source
+ * string on the byte level.
+ *
+ * @param src Source string.
+ * @param n   Maximum number of bytes to duplicate.
+ *
+ * @return Duplicate string.
+ *
+ */
+char *str_ndup(const char *src, size_t n)
 {
 	size_t size = str_size(src);
-	if (size > max_size)
-		size = max_size;
+	if (size > n)
+		size = n;
 	
 	char *dest = (char *) malloc(size + 1);
-	
 	if (dest == NULL)
 		return (char *) NULL;
 	
-	memcpy(dest, src, size);
-	dest[size] = 0;
+	str_ncpy(dest, size + 1, src, size);
 	return dest;
 }
@@ -979,4 +1007,30 @@
 }
 
+void order_suffix(const uint64_t val, uint64_t *rv, char *suffix)
+{
+	if (val > 10000000000000000000ULL) {
+		*rv = val / 1000000000000000000ULL;
+		*suffix = 'Z';
+	} else if (val > 1000000000000000000ULL) {
+		*rv = val / 1000000000000000ULL;
+		*suffix = 'E';
+	} else if (val > 1000000000000000ULL) {
+		*rv = val / 1000000000000ULL;
+		*suffix = 'T';
+	} else if (val > 1000000000000ULL) {
+		*rv = val / 1000000000ULL;
+		*suffix = 'G';
+	} else if (val > 1000000000ULL) {
+		*rv = val / 1000000ULL;
+		*suffix = 'M';
+	} else if (val > 1000000ULL) {
+		*rv = val / 1000ULL;
+		*suffix = 'k';
+	} else {
+		*rv = val;
+		*suffix = ' ';
+	}
+}
+
 /** @}
  */
Index: uspace/lib/c/generic/str_error.c
===================================================================
--- uspace/lib/c/generic/str_error.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/c/generic/str_error.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#include <str_error.h>
+#include <stdio.h>
+#include <fibril.h>
+
+#define MIN_ERRNO  -17
+#define NOERR_LEN  64
+
+static const char* err_desc[] = {
+	"No error",
+	"No such entry",
+	"Not enough memory",
+	"Limit exceeded", 
+	"Connection refused",
+	"Forwarding error",
+	"Permission denied",
+	"Answerbox closed connection",
+	"Other party error",
+	"Entry already exists",
+	"Bad memory pointer",
+	"Not supported",
+	"Address not available",
+	"Timeout expired",
+	"Invalid value",
+	"Resource is busy",
+	"Result does not fit its size",
+	"Operation interrupted"
+};
+
+static fibril_local char noerr[NOERR_LEN];
+
+const char *str_error(const int errno)
+{
+	if ((errno <= 0) && (errno >= MIN_ERRNO))
+		return err_desc[-errno];
+	
+	snprintf(noerr, NOERR_LEN, "Unkown error code %d", errno);
+	return noerr;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/sysinfo.c
===================================================================
--- uspace/lib/c/generic/sysinfo.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/generic/sysinfo.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -31,14 +31,109 @@
  */
 /** @file
- */ 
+ */
 
 #include <libc.h>
 #include <sysinfo.h>
 #include <str.h>
+#include <errno.h>
+#include <malloc.h>
+#include <bool.h>
 
-sysarg_t sysinfo_value(const char *name)
+/** Get sysinfo item type
+ *
+ * @param path Sysinfo path.
+ *
+ * @return Sysinfo item type.
+ *
+ */
+sysinfo_item_tag_t sysinfo_get_tag(const char *path)
 {
-	return __SYSCALL2(SYS_SYSINFO_VALUE, (sysarg_t) name,
-	    (sysarg_t) str_size(name));
+	return (sysinfo_item_tag_t) __SYSCALL2(SYS_SYSINFO_GET_TAG,
+	    (sysarg_t) path, (sysarg_t) str_size(path));
+}
+
+/** Get sysinfo numerical value
+ *
+ * @param path  Sysinfo path.
+ * @param value Pointer to store the numerical value to.
+ *
+ * @return EOK if the value was successfully read and
+ *         is of SYSINFO_VAL_VAL type.
+ *
+ */
+int sysinfo_get_value(const char *path, sysarg_t *value)
+{
+	return (int) __SYSCALL3(SYS_SYSINFO_GET_VALUE, (sysarg_t) path,
+	    (sysarg_t) str_size(path), (sysarg_t) value);
+}
+
+/** Get sysinfo binary data size
+ *
+ * @param path  Sysinfo path.
+ * @param value Pointer to store the binary data size.
+ *
+ * @return EOK if the value was successfully read and
+ *         is of SYSINFO_VAL_DATA type.
+ *
+ */
+static int sysinfo_get_data_size(const char *path, size_t *size)
+{
+	return (int) __SYSCALL3(SYS_SYSINFO_GET_DATA_SIZE, (sysarg_t) path,
+	    (sysarg_t) str_size(path), (sysarg_t) size);
+}
+
+/** Get sysinfo binary data
+ *
+ * @param path  Sysinfo path.
+ * @param value Pointer to store the binary data size.
+ *
+ * @return Binary data read from sysinfo or NULL if the
+ *         sysinfo item value type is not binary data.
+ *         The returned non-NULL pointer should be
+ *         freed by free().
+ *
+ */
+void *sysinfo_get_data(const char *path, size_t *size)
+{
+	/* The binary data size might change during time.
+	   Unfortunatelly we cannot allocate the buffer
+	   and transfer the data as a single atomic operation.
+	
+	   Let's hope that the number of iterations is bounded
+	   in common cases. */
+	
+	void *data = NULL;
+	
+	while (true) {
+		/* Get the binary data size */
+		int ret = sysinfo_get_data_size(path, size);
+		if ((ret != EOK) || (size == 0)) {
+			/* Not a binary data item
+			   or an empty item */
+			break;
+		}
+		
+		data = realloc(data, *size);
+		if (data == NULL)
+			break;
+		
+		/* Get the data */
+		ret = __SYSCALL4(SYS_SYSINFO_GET_DATA, (sysarg_t) path,
+		    (sysarg_t) str_size(path), (sysarg_t) data, (sysarg_t) *size);
+		if (ret == EOK)
+			return data;
+		
+		if (ret != ENOMEM) {
+			/* The failure to get the data was not caused
+			   by wrong buffer size */
+			break;
+		}
+	}
+	
+	if (data != NULL)
+		free(data);
+	
+	*size = 0;
+	return NULL;
 }
 
Index: uspace/lib/c/generic/task.c
===================================================================
--- uspace/lib/c/generic/task.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/generic/task.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -70,16 +70,21 @@
  * loader API.
  *
- * @param path pathname of the binary to execute
- * @param argv command-line arguments
+ * @param path Pathname of the binary to execute.
+ * @param argv Command-line arguments.
+ * @param err  If not NULL, the error value is stored here.
  *
  * @return ID of the newly created task or zero on error.
  *
  */
-task_id_t task_spawn(const char *path, const char *const args[])
+task_id_t task_spawn(const char *path, const char *const args[], int *err)
 {
 	/* Connect to a program loader. */
 	loader_t *ldr = loader_connect();
-	if (ldr == NULL)
+	if (ldr == NULL) {
+		if (err != NULL)
+			*err = EREFUSED;
+		
 		return 0;
+	}
 	
 	/* Get task ID. */
@@ -143,4 +148,8 @@
 	/* Success */
 	free(ldr);
+	
+	if (err != NULL)
+		*err = EOK;
+	
 	return task_id;
 	
@@ -149,4 +158,7 @@
 	loader_abort(ldr);
 	free(ldr);
+	
+	if (err != NULL)
+		*err = rc;
 	
 	return 0;
Index: uspace/lib/c/include/arg_parse.h
===================================================================
--- uspace/lib/c/include/arg_parse.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/c/include/arg_parse.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,48 @@
+/*
+ * 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_ARG_PARSE_H_
+#define LIBC_ARG_PARSE_H_
+
+typedef int (*arg_parser)(const char *, int *);
+
+extern int arg_parse_short_long(const char *, const char *, const char *);
+extern int arg_parse_int(int, char **, int *, int *, int);
+extern int arg_parse_name_int(int, char **, int *, int *, int, arg_parser);
+extern int arg_parse_string(int, char **, int *, char **, int);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/bool.h
===================================================================
--- uspace/lib/c/include/bool.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/include/bool.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -36,8 +36,10 @@
 #define LIBC_BOOL_H_
 
-#define false 0
-#define true 1
+#include <libarch/types.h>
 
-typedef short bool;
+#define false  0
+#define true   1
+
+typedef uint8_t bool;
 
 #endif
Index: uspace/lib/c/include/errno.h
===================================================================
--- uspace/lib/c/include/errno.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/include/errno.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -43,5 +43,5 @@
 #define errno _errno
 
-#define EMFILE        (-17)
+#define EMFILE        (-18)
 #define ENAMETOOLONG  (-256)
 #define EISDIR        (-257)
Index: uspace/lib/c/include/futex.h
===================================================================
--- uspace/lib/c/include/futex.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/include/futex.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -39,5 +39,5 @@
 #include <sys/types.h>
 
-#define FUTEX_INITIALIZER     {1}
+#define FUTEX_INITIALIZER  {1}
 
 typedef atomic_t futex_t;
Index: uspace/lib/c/include/io/color.h
===================================================================
--- uspace/lib/c/include/io/color.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/include/io/color.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -36,5 +36,5 @@
 #define LIBC_IO_COLOR_H_
 
-enum console_color {
+typedef enum {
 	COLOR_BLACK   = 0,
 	COLOR_BLUE    = 1,
@@ -48,5 +48,5 @@
 	CATTR_BRIGHT  = 8,
 	CATTR_BLINK   = 8
-};
+} console_color_t;
 
 #endif
Index: uspace/lib/c/include/io/console.h
===================================================================
--- uspace/lib/c/include/io/console.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/include/io/console.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -44,10 +44,10 @@
 } console_ev_type_t;
 
-enum {
+typedef enum {
 	CONSOLE_CCAP_NONE = 0,
 	CONSOLE_CCAP_STYLE,
 	CONSOLE_CCAP_INDEXED,
 	CONSOLE_CCAP_RGB
-};
+} console_caps_t;
 
 /** Console event structure. */
@@ -68,14 +68,15 @@
 extern void console_clear(int phone);
 
-extern int console_get_size(int phone, int *cols, int *rows);
-extern int console_get_pos(int phone, int *col, int *row);
-extern void console_goto(int phone, int col, int row);
+extern int console_get_size(int phone, ipcarg_t *cols, ipcarg_t *rows);
+extern int console_get_pos(int phone, ipcarg_t *col, ipcarg_t *row);
+extern void console_set_pos(int phone, ipcarg_t col, ipcarg_t row);
 
-extern void console_set_style(int phone, int style);
-extern void console_set_color(int phone, int fg_color, int bg_color, int flags);
-extern void console_set_rgb_color(int phone, int fg_color, int bg_color);
+extern void console_set_style(int phone, uint8_t style);
+extern void console_set_color(int phone, uint8_t fg_color, uint8_t bg_color,
+    uint8_t flags);
+extern void console_set_rgb_color(int phone, uint32_t fg_color, uint32_t bg_color);
 
 extern void console_cursor_visibility(int phone, bool show);
-extern int console_get_color_cap(int phone, int *ccap);
+extern int console_get_color_cap(int phone, ipcarg_t *ccap);
 extern void console_kcon_enable(int phone);
 
Index: uspace/lib/c/include/io/keycode.h
===================================================================
--- uspace/lib/c/include/io/keycode.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/include/io/keycode.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -51,5 +51,5 @@
  * they really are organized here by position, rather than by label.
  */
-enum keycode {
+typedef enum {
 
 	/* Main block row 1 */
@@ -199,5 +199,5 @@
 } keycode_t;
 
-enum keymod {
+typedef enum {
 	KM_LSHIFT      = 0x001,
 	KM_RSHIFT      = 0x002,
Index: uspace/lib/c/include/io/klog.h
===================================================================
--- uspace/lib/c/include/io/klog.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/include/io/klog.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -33,10 +33,10 @@
  */
 
-#ifndef LIBC_STREAM_H_
-#define LIBC_STREAM_H_
+#ifndef LIBC_IO_KLOG_H_
+#define LIBC_IO_KLOG_H_
 
 #include <sys/types.h>
 
-extern size_t klog_write(const void *buf, size_t size);
+extern size_t klog_write(const void *, size_t);
 extern void klog_update(void);
 
Index: uspace/lib/c/include/io/printf_core.h
===================================================================
--- uspace/lib/c/include/io/printf_core.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/include/io/printf_core.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -40,5 +40,5 @@
 
 /** Structure for specifying output methods for different printf clones. */
-typedef struct printf_spec {
+typedef struct {
 	/* String output function, returns number of printed characters or EOF */
 	int (*str_write)(const char *, size_t, void *);
@@ -51,5 +51,5 @@
 } printf_spec_t;
 
-int printf_core(const char *fmt, printf_spec_t *ps, va_list ap);
+extern int printf_core(const char *, printf_spec_t *, va_list);
 
 #endif
Index: uspace/lib/c/include/io/screenbuffer.h
===================================================================
--- uspace/lib/c/include/io/screenbuffer.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/c/include/io/screenbuffer.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup console
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_SCREENBUFFER_H__
+#define LIBC_SCREENBUFFER_H__
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <ipc/ipc.h>
+#include <bool.h>
+
+typedef enum {
+	at_style,
+	at_idx,
+	at_rgb
+} attr_type_t;
+
+typedef struct {
+	uint8_t style;
+} attr_style_t;
+
+typedef struct {
+	uint8_t fg_color;
+	uint8_t bg_color;
+	uint8_t flags;
+} attr_idx_t;
+
+typedef struct {
+	uint32_t bg_color;  /**< background color */
+	uint32_t fg_color;  /**< foreground color */
+} attr_rgb_t;
+
+typedef union {
+	attr_style_t s;
+	attr_idx_t i;
+	attr_rgb_t r;
+} attr_val_t;
+
+typedef struct {
+	attr_type_t t;
+	attr_val_t a;
+} attrs_t;
+
+/** One field on screen. It contain one character and its attributes. */
+typedef struct {
+	wchar_t character;  /**< Character itself */
+	attrs_t attrs;      /**< Character attributes */
+} keyfield_t;
+
+/** Structure for buffering state of one virtual console.
+ */
+typedef struct {
+	keyfield_t *buffer;      /**< Screen content - characters and
+	                              their attributes (used as a circular buffer) */
+	ipcarg_t size_x;         /**< Number of columns  */
+	ipcarg_t size_y;         /**< Number of rows */
+	
+	/** Coordinates of last printed character for determining cursor position */
+	ipcarg_t position_x;
+	ipcarg_t position_y;
+	
+	attrs_t attrs;           /**< Current attributes. */
+	size_t top_line;         /**< Points to buffer[][] line that will
+	                              be printed at screen as the first line */
+	bool is_cursor_visible;  /**< Cursor state - default is visible */
+} screenbuffer_t;
+
+/** Returns keyfield for position on screen
+ *
+ * Screenbuffer->buffer is cyclic buffer so we
+ * must couted in index of the topmost line.
+ *
+ * @param scr Screenbuffer
+ * @param x   Position on screen
+ * @param y   Position on screen
+ *
+ * @return Keyfield structure with character and its attributes on x, y
+ *
+ */
+static inline keyfield_t *get_field_at(screenbuffer_t *scr, ipcarg_t x, ipcarg_t y)
+{
+	return scr->buffer + x + ((y + scr->top_line) % scr->size_y) * scr->size_x;
+}
+
+/** Compares two sets of attributes.
+ *
+ * @param s1 First style
+ * @param s2 Second style
+ *
+ * @return Nonzero on equality
+ *
+ */
+static inline bool attrs_same(attrs_t a1, attrs_t a2)
+{
+	if (a1.t != a2.t)
+		return false;
+	
+	switch (a1.t) {
+	case at_style:
+		return (a1.a.s.style == a2.a.s.style);
+	case at_idx:
+		return (a1.a.i.fg_color == a2.a.i.fg_color)
+		    && (a1.a.i.bg_color == a2.a.i.bg_color)
+		    && (a1.a.i.flags == a2.a.i.flags);
+	case at_rgb:
+		return (a1.a.r.fg_color == a2.a.r.fg_color)
+		    && (a1.a.r.bg_color == a2.a.r.bg_color);
+	}
+	
+	return false;
+}
+
+extern void screenbuffer_putchar(screenbuffer_t *, wchar_t);
+extern screenbuffer_t *screenbuffer_init(screenbuffer_t *, ipcarg_t, ipcarg_t);
+
+extern void screenbuffer_clear(screenbuffer_t *);
+extern void screenbuffer_clear_line(screenbuffer_t *, ipcarg_t);
+extern void screenbuffer_copy_buffer(screenbuffer_t *, keyfield_t *);
+extern void screenbuffer_goto(screenbuffer_t *, ipcarg_t, ipcarg_t);
+extern void screenbuffer_set_style(screenbuffer_t *, uint8_t);
+extern void screenbuffer_set_color(screenbuffer_t *, uint8_t, uint8_t, uint8_t);
+extern void screenbuffer_set_rgb_color(screenbuffer_t *, uint32_t, uint32_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/io/style.h
===================================================================
--- uspace/lib/c/include/io/style.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/include/io/style.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -36,8 +36,10 @@
 #define LIBC_IO_STYLE_H_
 
-enum console_style {
+typedef enum {
 	STYLE_NORMAL   = 0,
-	STYLE_EMPHASIS = 1
-};
+	STYLE_EMPHASIS = 1,
+	STYLE_INVERTED = 2,
+	STYLE_SELECTED = 3
+} console_style_t;
 
 #endif
Index: uspace/lib/c/include/stats.h
===================================================================
--- uspace/lib/c/include/stats.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/c/include/stats.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010 Stanislav Kozina
+ * 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_STATS_H_
+#define LIBC_STATS_H_
+
+#include <task.h>
+#include <thread.h>
+#include <stdint.h>
+#include <bool.h>
+#include <kernel/sysinfo/abi.h>
+
+extern stats_cpu_t *stats_get_cpus(size_t *);
+extern stats_physmem_t *stats_get_physmem(void);
+extern load_t *stats_get_load(size_t *);
+extern sysarg_t stats_get_uptime(void);
+
+extern stats_task_t *stats_get_tasks(size_t *);
+extern stats_task_t *stats_get_task(task_id_t);
+
+extern stats_thread_t *stats_get_threads(size_t *);
+extern stats_thread_t *stats_get_thread(thread_id_t);
+
+extern void stats_print_load_fragment(load_t, unsigned int);
+extern const char *thread_get_state(state_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/str.h
===================================================================
--- uspace/lib/c/include/str.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/include/str.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -86,4 +86,6 @@
 extern char *str_ndup(const char *, size_t max_size);
 
+extern void order_suffix(const uint64_t val, uint64_t *rv, char *suffix);
+
 /*
  * TODO: Get rid of this.
Index: uspace/lib/c/include/str_error.h
===================================================================
--- uspace/lib/c/include/str_error.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/c/include/str_error.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_STRERROR_H_
+#define LIBC_STRERROR_H_
+
+const char *str_error(const int);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/sysinfo.h
===================================================================
--- uspace/lib/c/include/sysinfo.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/include/sysinfo.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -31,5 +31,5 @@
  */
 /** @file
- */ 
+ */
 
 #ifndef LIBC_SYSINFO_H_
@@ -37,8 +37,17 @@
 
 #include <libc.h>
-#include <sysinfo.h>
-#include <str.h>
 
-sysarg_t sysinfo_value(const char *name);
+/** Sysinfo value types
+ *
+ */
+typedef enum {
+	SYSINFO_VAL_UNDEFINED = 0,
+	SYSINFO_VAL_VAL = 1,
+	SYSINFO_VAL_DATA = 2
+} sysinfo_item_tag_t;
+
+extern sysinfo_item_tag_t sysinfo_get_tag(const char *);
+extern int sysinfo_get_value(const char *, sysarg_t *);
+extern void *sysinfo_get_data(const char *, size_t *);
 
 #endif
Index: uspace/lib/c/include/task.h
===================================================================
--- uspace/lib/c/include/task.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/c/include/task.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -46,9 +46,8 @@
 
 extern task_id_t task_get_id(void);
-extern int task_set_name(const char *name);
-extern task_id_t task_spawn(const char *path, const char *const argv[]);
-extern int task_wait(task_id_t id, task_exit_t *texit, int *retval);
-extern int task_retval(int val);
-
+extern int task_set_name(const char *);
+extern task_id_t task_spawn(const char *, const char *const[], int *);
+extern int task_wait(task_id_t id, task_exit_t *, int *);
+extern int task_retval(int);
 
 #endif
Index: uspace/lib/clui/Makefile
===================================================================
--- uspace/lib/clui/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/clui/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -28,4 +28,5 @@
 
 USPACE_PREFIX = ../..
+EXTRA_CFLAGS = -I.
 LIBRARY = libclui
 
Index: uspace/lib/clui/tinput.c
===================================================================
--- uspace/lib/clui/tinput.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/clui/tinput.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -40,6 +40,5 @@
 #include <assert.h>
 #include <bool.h>
-
-#include "tinput.h"
+#include <tinput.h>
 
 /** Seek direction */
@@ -49,16 +48,16 @@
 } seek_dir_t;
 
-static void tinput_init(tinput_t *ti);
-static void tinput_insert_string(tinput_t *ti, const char *str);
-static void tinput_sel_get_bounds(tinput_t *ti, int *sa, int *sb);
-static bool tinput_sel_active(tinput_t *ti);
-static void tinput_sel_all(tinput_t *ti);
-static void tinput_sel_delete(tinput_t *ti);
-static void tinput_key_ctrl(tinput_t *ti, console_event_t *ev);
-static void tinput_key_shift(tinput_t *ti, console_event_t *ev);
-static void tinput_key_ctrl_shift(tinput_t *ti, console_event_t *ev);
-static void tinput_key_unmod(tinput_t *ti, console_event_t *ev);
-static void tinput_pre_seek(tinput_t *ti, bool shift_held);
-static void tinput_post_seek(tinput_t *ti, bool shift_held);
+static void tinput_init(tinput_t *);
+static void tinput_insert_string(tinput_t *, const char *);
+static void tinput_sel_get_bounds(tinput_t *, size_t *, size_t *);
+static bool tinput_sel_active(tinput_t *);
+static void tinput_sel_all(tinput_t *);
+static void tinput_sel_delete(tinput_t *);
+static void tinput_key_ctrl(tinput_t *, console_event_t *);
+static void tinput_key_shift(tinput_t *, console_event_t *);
+static void tinput_key_ctrl_shift(tinput_t *, console_event_t *);
+static void tinput_key_unmod(tinput_t *, console_event_t *);
+static void tinput_pre_seek(tinput_t *, bool);
+static void tinput_post_seek(tinput_t *, bool);
 
 /** Create a new text input field. */
@@ -66,9 +65,9 @@
 {
 	tinput_t *ti;
-
+	
 	ti = malloc(sizeof(tinput_t));
 	if (ti == NULL)
 		return NULL;
-
+	
 	tinput_init(ti);
 	return ti;
@@ -81,17 +80,17 @@
 }
 
-static void tinput_display_tail(tinput_t *ti, int start, int pad)
-{
-	static wchar_t dbuf[INPUT_MAX_SIZE + 1];
-	int sa, sb;
-	int i, p;
-
+static void tinput_display_tail(tinput_t *ti, size_t start, size_t pad)
+{
+	wchar_t dbuf[INPUT_MAX_SIZE + 1];
+	
+	size_t sa;
+	size_t sb;
 	tinput_sel_get_bounds(ti, &sa, &sb);
-
-	console_goto(fphone(stdout), (ti->col0 + start) % ti->con_cols,
+	
+	console_set_pos(fphone(stdout), (ti->col0 + start) % ti->con_cols,
 	    ti->row0 + (ti->col0 + start) / ti->con_cols);
-	console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
-
-	p = start;
+	console_set_style(fphone(stdout), STYLE_NORMAL);
+	
+	size_t p = start;
 	if (p < sa) {
 		memcpy(dbuf, ti->buffer + p, (sa - p) * sizeof(wchar_t));
@@ -100,8 +99,8 @@
 		p = sa;
 	}
-
+	
 	if (p < sb) {
 		fflush(stdout);
-		console_set_color(fphone(stdout), COLOR_BLACK, COLOR_RED, 0);
+		console_set_style(fphone(stdout), STYLE_SELECTED);
 		memcpy(dbuf, ti->buffer + p,
 		    (sb - p) * sizeof(wchar_t));
@@ -110,8 +109,8 @@
 		p = sb;
 	}
-
+	
 	fflush(stdout);
-	console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
-
+	console_set_style(fphone(stdout), STYLE_NORMAL);
+	
 	if (p < ti->nc) {
 		memcpy(dbuf, ti->buffer + p,
@@ -120,7 +119,8 @@
 		printf("%ls", dbuf);
 	}
-
-	for (i = 0; i < pad; ++i)
+	
+	for (p = 0; p < pad; p++)
 		putchar(' ');
+	
 	fflush(stdout);
 }
@@ -133,5 +133,5 @@
 static void tinput_position_caret(tinput_t *ti)
 {
-	console_goto(fphone(stdout), (ti->col0 + ti->pos) % ti->con_cols,
+	console_set_pos(fphone(stdout), (ti->col0 + ti->pos) % ti->con_cols,
 	    ti->row0 + (ti->col0 + ti->pos) / ti->con_cols);
 }
@@ -140,33 +140,31 @@
 static void tinput_update_origin(tinput_t *ti)
 {
-	int width, rows;
-
-	width = ti->col0 + ti->nc;
-	rows = (width / ti->con_cols) + 1;
-
+	ipcarg_t width = ti->col0 + ti->nc;
+	ipcarg_t rows = (width / ti->con_cols) + 1;
+	
 	/* Update row0 if the screen scrolled. */
 	if (ti->row0 + rows > ti->con_rows)
-		ti->row0 = ti->con_rows - rows;	
+		ti->row0 = ti->con_rows - rows;
 }
 
 static void tinput_insert_char(tinput_t *ti, wchar_t c)
 {
-	int i;
-	int new_width, new_height;
-
 	if (ti->nc == INPUT_MAX_SIZE)
 		return;
-
-	new_width = ti->col0 + ti->nc + 1;
+	
+	ipcarg_t new_width = ti->col0 + ti->nc + 1;
 	if (new_width % ti->con_cols == 0) {
 		/* Advancing to new line. */
-		new_height = (new_width / ti->con_cols) + 1;
-		if (new_height >= ti->con_rows)
-			return; /* Disallow text longer than 1 page for now. */
-	}
-
-	for (i = ti->nc; i > ti->pos; --i)
+		ipcarg_t new_height = (new_width / ti->con_cols) + 1;
+		if (new_height >= ti->con_rows) {
+			/* Disallow text longer than 1 page for now. */
+			return;
+		}
+	}
+	
+	size_t i;
+	for (i = ti->nc; i > ti->pos; i--)
 		ti->buffer[i] = ti->buffer[i - 1];
-
+	
 	ti->buffer[ti->pos] = c;
 	ti->pos += 1;
@@ -174,5 +172,5 @@
 	ti->buffer[ti->nc] = '\0';
 	ti->sel_start = ti->pos;
-
+	
 	tinput_display_tail(ti, ti->pos - 1, 0);
 	tinput_update_origin(ti);
@@ -182,41 +180,41 @@
 static void tinput_insert_string(tinput_t *ti, const char *str)
 {
-	int i;
-	int new_width, new_height;
-	int ilen;
-	wchar_t c;
-	size_t off;
-
-	ilen = min((ssize_t) str_length(str), INPUT_MAX_SIZE - ti->nc);
+	size_t ilen = min(str_length(str), INPUT_MAX_SIZE - ti->nc);
 	if (ilen == 0)
 		return;
-
-	new_width = ti->col0 + ti->nc + ilen;
-	new_height = (new_width / ti->con_cols) + 1;
-	if (new_height >= ti->con_rows)
-		return; /* Disallow text longer than 1 page for now. */
-
-	for (i = ti->nc - 1; i >= ti->pos; --i)
-		ti->buffer[i + ilen] = ti->buffer[i];
-
-	off = 0; i = 0;
+	
+	ipcarg_t new_width = ti->col0 + ti->nc + ilen;
+	ipcarg_t new_height = (new_width / ti->con_cols) + 1;
+	if (new_height >= ti->con_rows) {
+		/* Disallow text longer than 1 page for now. */
+		return;
+	}
+	
+	if (ti->nc > 0) {
+		size_t i;
+		for (i = ti->nc; i > ti->pos; i--)
+			ti->buffer[i + ilen - 1] = ti->buffer[i - 1];
+	}
+	
+	size_t off = 0;
+	size_t i = 0;
 	while (i < ilen) {
-		c = str_decode(str, &off, STR_NO_LIMIT);
+		wchar_t c = str_decode(str, &off, STR_NO_LIMIT);
 		if (c == '\0')
 			break;
-
+		
 		/* Filter out non-printable chars. */
 		if (c < 32)
 			c = 32;
-
+		
 		ti->buffer[ti->pos + i] = c;
-		++i;
-	}
-
+		i++;
+	}
+	
 	ti->pos += ilen;
 	ti->nc += ilen;
 	ti->buffer[ti->nc] = '\0';
 	ti->sel_start = ti->pos;
-
+	
 	tinput_display_tail(ti, ti->pos - ilen, 0);
 	tinput_update_origin(ti);
@@ -226,21 +224,21 @@
 static void tinput_backspace(tinput_t *ti)
 {
-	int i;
-
 	if (tinput_sel_active(ti)) {
 		tinput_sel_delete(ti);
 		return;
 	}
-
+	
 	if (ti->pos == 0)
 		return;
-
-	for (i = ti->pos; i < ti->nc; ++i)
+	
+	size_t i;
+	for (i = ti->pos; i < ti->nc; i++)
 		ti->buffer[i - 1] = ti->buffer[i];
+	
 	ti->pos -= 1;
 	ti->nc -= 1;
 	ti->buffer[ti->nc] = '\0';
 	ti->sel_start = ti->pos;
-
+	
 	tinput_display_tail(ti, ti->pos, 1);
 	tinput_position_caret(ti);
@@ -253,11 +251,11 @@
 		return;
 	}
-
+	
 	if (ti->pos == ti->nc)
 		return;
-
+	
 	ti->pos += 1;
 	ti->sel_start = ti->pos;
-
+	
 	tinput_backspace(ti);
 }
@@ -266,5 +264,5 @@
 {
 	tinput_pre_seek(ti, shift_held);
-
+	
 	if (dir == seek_forward) {
 		if (ti->pos < ti->nc)
@@ -274,5 +272,5 @@
 			ti->pos -= 1;
 	}
-
+	
 	tinput_post_seek(ti, shift_held);
 }
@@ -281,17 +279,17 @@
 {
 	tinput_pre_seek(ti, shift_held);
-
+	
 	if (dir == seek_forward) {
 		if (ti->pos == ti->nc)
 			return;
-
-		while (1) {
+		
+		while (true) {
 			ti->pos += 1;
-
+			
 			if (ti->pos == ti->nc)
 				break;
-
-			if (ti->buffer[ti->pos - 1] == ' ' &&
-			    ti->buffer[ti->pos] != ' ')
+			
+			if ((ti->buffer[ti->pos - 1] == ' ') &&
+			    (ti->buffer[ti->pos] != ' '))
 				break;
 		}
@@ -299,18 +297,18 @@
 		if (ti->pos == 0)
 			return;
-
-		while (1) {
+		
+		while (true) {
 			ti->pos -= 1;
-
+			
 			if (ti->pos == 0)
 				break;
-
+			
 			if (ti->buffer[ti->pos - 1] == ' ' &&
 			    ti->buffer[ti->pos] != ' ')
 				break;
 		}
-
-	}
-
+	
+	}
+	
 	tinput_post_seek(ti, shift_held);
 }
@@ -319,13 +317,13 @@
 {
 	tinput_pre_seek(ti, shift_held);
-
+	
 	if (dir == seek_forward) {
 		if (ti->pos + ti->con_cols <= ti->nc)
 			ti->pos = ti->pos + ti->con_cols;
 	} else {
-		if (ti->pos - ti->con_cols >= 0)
+		if (ti->pos >= ti->con_cols)
 			ti->pos = ti->pos - ti->con_cols;
 	}
-
+	
 	tinput_post_seek(ti, shift_held);
 }
@@ -334,10 +332,10 @@
 {
 	tinput_pre_seek(ti, shift_held);
-
+	
 	if (dir == seek_backward)
 		ti->pos = 0;
 	else
 		ti->pos = ti->nc;
-
+	
 	tinput_post_seek(ti, shift_held);
 }
@@ -345,5 +343,5 @@
 static void tinput_pre_seek(tinput_t *ti, bool shift_held)
 {
-	if (tinput_sel_active(ti) && !shift_held) {
+	if ((tinput_sel_active(ti)) && (!shift_held)) {
 		/* Unselect and redraw. */
 		ti->sel_start = ti->pos;
@@ -362,4 +360,5 @@
 		ti->sel_start = ti->pos;
 	}
+	
 	tinput_position_caret(ti);
 }
@@ -367,6 +366,4 @@
 static void tinput_history_insert(tinput_t *ti, char *str)
 {
-	int i;
-
 	if (ti->hnum < HISTORY_LEN) {
 		ti->hnum += 1;
@@ -375,10 +372,11 @@
 			free(ti->history[HISTORY_LEN]);
 	}
-
-	for (i = ti->hnum; i > 1; --i)
+	
+	size_t i;
+	for (i = ti->hnum; i > 1; i--)
 		ti->history[i] = ti->history[i - 1];
-
+	
 	ti->history[1] = str_dup(str);
-
+	
 	if (ti->history[0] != NULL) {
 		free(ti->history[0]);
@@ -395,5 +393,5 @@
 }
 
-static void tinput_sel_get_bounds(tinput_t *ti, int *sa, int *sb)
+static void tinput_sel_get_bounds(tinput_t *ti, size_t *sa, size_t *sb)
 {
 	if (ti->sel_start < ti->pos) {
@@ -408,5 +406,5 @@
 static bool tinput_sel_active(tinput_t *ti)
 {
-	return ti->sel_start != ti->pos;
+	return (ti->sel_start != ti->pos);
 }
 
@@ -421,16 +419,18 @@
 static void tinput_sel_delete(tinput_t *ti)
 {
-	int sa, sb;
-
+	size_t sa;
+	size_t sb;
+	
 	tinput_sel_get_bounds(ti, &sa, &sb);
 	if (sa == sb)
 		return;
-
+	
 	memmove(ti->buffer + sa, ti->buffer + sb,
 	    (ti->nc - sb) * sizeof(wchar_t));
+	
 	ti->pos = ti->sel_start = sa;
 	ti->nc -= (sb - sa);
 	ti->buffer[ti->nc] = '\0';
-
+	
 	tinput_display_tail(ti, sa, sb - sa);
 	tinput_position_caret(ti);
@@ -439,9 +439,11 @@
 static void tinput_sel_copy_to_cb(tinput_t *ti)
 {
-	int sa, sb;
+	size_t sa;
+	size_t sb;
+	
+	tinput_sel_get_bounds(ti, &sa, &sb);
+	
 	char *str;
-
-	tinput_sel_get_bounds(ti, &sa, &sb);
-
+	
 	if (sb < ti->nc) {
 		wchar_t tmp_c = ti->buffer[sb];
@@ -454,13 +456,14 @@
 	if (str == NULL)
 		goto error;
-
+	
 	if (clipboard_put_str(str) != EOK)
 		goto error;
-
+	
 	free(str);
 	return;
+	
 error:
+	/* TODO: Give the user some kind of warning. */
 	return;
-	/* TODO: Give the user some warning. */
 }
 
@@ -468,10 +471,11 @@
 {
 	char *str;
-	int rc;
-
-	rc = clipboard_get_str(&str);
-	if (rc != EOK || str == NULL)
-		return; /* TODO: Give the user some warning. */
-
+	int rc = clipboard_get_str(&str);
+	
+	if ((rc != EOK) || (str == NULL)) {
+		/* TODO: Give the user some kind of warning. */
+		return;
+	}
+	
 	tinput_insert_string(ti, str);
 	free(str);
@@ -480,20 +484,24 @@
 static void tinput_history_seek(tinput_t *ti, int offs)
 {
-	int pad;
-
-	if (ti->hpos + offs < 0 || ti->hpos + offs > ti->hnum)
-		return;
-
+	if (offs >= 0) {
+		if (ti->hpos + offs > ti->hnum)
+			return;
+	} else {
+		if (ti->hpos < (size_t) -offs)
+			return;
+	}
+	
 	if (ti->history[ti->hpos] != NULL) {
 		free(ti->history[ti->hpos]);
 		ti->history[ti->hpos] = NULL;
 	}
-
+	
 	ti->history[ti->hpos] = tinput_get_str(ti);
 	ti->hpos += offs;
-
-	pad = ti->nc - str_length(ti->history[ti->hpos]);
-	if (pad < 0) pad = 0;
-
+	
+	int pad = (int) ti->nc - str_length(ti->history[ti->hpos]);
+	if (pad < 0)
+		pad = 0;
+	
 	tinput_set_str(ti, ti->history[ti->hpos]);
 	tinput_display_tail(ti, 0, pad);
@@ -515,55 +523,54 @@
 /** Read in one line of input.
  *
- * @param ti	Text input.
- * @param dstr	Place to save pointer to new string.
- * @return	EOK on success, ENOENT if user requested abort, EIO
- *		if communication with console failed.
+ * @param ti   Text input.
+ * @param dstr Place to save pointer to new string.
+ *
+ * @return EOK on success
+ * @return ENOENT if user requested abort
+ * @return EIO if communication with console failed
+ *
  */
 int tinput_read(tinput_t *ti, char **dstr)
 {
-	console_event_t ev;
-	char *str;
-
 	fflush(stdout);
-
 	if (console_get_size(fphone(stdin), &ti->con_cols, &ti->con_rows) != EOK)
 		return EIO;
+	
 	if (console_get_pos(fphone(stdin), &ti->col0, &ti->row0) != EOK)
 		return EIO;
-
-	ti->pos = ti->sel_start = 0;
+	
+	ti->pos = 0;
+	ti->sel_start = 0;
 	ti->nc = 0;
 	ti->buffer[0] = '\0';
 	ti->done = false;
 	ti->exit_clui = false;
-
+	
 	while (!ti->done) {
 		fflush(stdout);
+		
+		console_event_t ev;
 		if (!console_get_event(fphone(stdin), &ev))
 			return EIO;
-
+		
 		if (ev.type != KEY_PRESS)
 			continue;
-
-		if ((ev.mods & KM_CTRL) != 0 &&
-		    (ev.mods & (KM_ALT | KM_SHIFT)) == 0) {
+		
+		if (((ev.mods & KM_CTRL) != 0) &&
+		    ((ev.mods & (KM_ALT | KM_SHIFT)) == 0))
 			tinput_key_ctrl(ti, &ev);
-		}
-
-		if ((ev.mods & KM_SHIFT) != 0 &&
-		    (ev.mods & (KM_CTRL | KM_ALT)) == 0) {
+		
+		if (((ev.mods & KM_SHIFT) != 0) &&
+		    ((ev.mods & (KM_CTRL | KM_ALT)) == 0))
 			tinput_key_shift(ti, &ev);
-		}
-
-		if ((ev.mods & KM_CTRL) != 0 &&
-		    (ev.mods & KM_SHIFT) != 0 &&
-		    (ev.mods & KM_ALT) == 0) {
+		
+		if (((ev.mods & KM_CTRL) != 0) &&
+		    ((ev.mods & KM_SHIFT) != 0) &&
+		    ((ev.mods & KM_ALT) == 0))
 			tinput_key_ctrl_shift(ti, &ev);
-		}
-
-		if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) {
+		
+		if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0)
 			tinput_key_unmod(ti, &ev);
-		}
-
+		
 		if (ev.c >= ' ') {
 			tinput_sel_delete(ti);
@@ -571,18 +578,18 @@
 		}
 	}
-
+	
 	if (ti->exit_clui)
 		return ENOENT;
-
+	
 	ti->pos = ti->nc;
 	tinput_position_caret(ti);
 	putchar('\n');
-
-	str = tinput_get_str(ti);
+	
+	char *str = tinput_get_str(ti);
 	if (str_cmp(str, "") != 0)
 		tinput_history_insert(ti, str);
-
+	
 	ti->hpos = 0;
-
+	
 	*dstr = str;
 	return EOK;
@@ -700,5 +707,5 @@
 		break;
 	case KC_UP:
-		tinput_history_seek(ti, +1);
+		tinput_history_seek(ti, 1);
 		break;
 	case KC_DOWN:
Index: uspace/lib/clui/tinput.h
===================================================================
--- uspace/lib/clui/tinput.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/clui/tinput.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -29,5 +29,5 @@
 /** @addtogroup libclui
  * @{
- */ 
+ */
 /**
  * @file
@@ -37,6 +37,8 @@
 #define LIBCLUI_TINPUT_H_
 
-#define HISTORY_LEN 10
-#define INPUT_MAX_SIZE 1024
+#include <ipc/ipc.h>
+
+#define HISTORY_LEN     10
+#define INPUT_MAX_SIZE  1024
 
 /** Text input field (command line).
@@ -47,23 +49,34 @@
 	/** Buffer holding text currently being edited */
 	wchar_t buffer[INPUT_MAX_SIZE + 1];
+	
 	/** Screen coordinates of the top-left corner of the text field */
-	int col0, row0;
+	ipcarg_t col0;
+	ipcarg_t row0;
+	
 	/** Screen dimensions */
-	int con_cols, con_rows;
+	ipcarg_t con_cols;
+	ipcarg_t con_rows;
+	
 	/** Number of characters in @c buffer */
-	int nc;
+	size_t nc;
+	
 	/** Caret position within buffer */
-	int pos;
+	size_t pos;
+	
 	/** Selection mark position within buffer */
-	int sel_start;
-
+	size_t sel_start;
+	
 	/** History (dynamically allocated strings) */
-	char *history[1 + HISTORY_LEN];
+	char *history[HISTORY_LEN + 1];
+	
 	/** Number of entries in @c history, not counting [0] */
-	int hnum;
+	size_t hnum;
+	
 	/** Current position in history */
-	int hpos;
+	size_t hpos;
+	
 	/** @c true if finished with this line (return to caller) */
 	bool done;
+	
 	/** @c true if user requested to abort interactive loop */
 	bool exit_clui;
@@ -71,6 +84,6 @@
 
 extern tinput_t *tinput_new(void);
-extern void tinput_destroy(tinput_t *ti);
-extern int tinput_read(tinput_t *ti, char **str);
+extern void tinput_destroy(tinput_t *);
+extern int tinput_read(tinput_t *, char **);
 
 #endif
@@ -78,3 +91,2 @@
 /** @}
  */
-
Index: uspace/lib/net/Makefile
===================================================================
--- uspace/lib/net/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -37,6 +37,6 @@
 	generic/packet_remote.c \
 	adt/module_map.c \
-	netif/netif.c \
-	netif/netif_standalone.c \
+	netif/netif_local.c \
+	netif/netif_remote.c \
 	netif/netif_nil_bundle.c \
 	nil/nil_remote.c \
Index: uspace/lib/net/adt/module_map.c
===================================================================
--- uspace/lib/net/adt/module_map.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/adt/module_map.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -94,12 +94,13 @@
 }
 
-task_id_t spawn(const char * fname){
-	const char * argv[2];
+task_id_t spawn(const char *fname)
+{
+	const char *argv[2];
 	task_id_t res;
-
+	
 	argv[0] = fname;
 	argv[1] = NULL;
-	res = task_spawn(fname, argv);
-
+	res = task_spawn(fname, argv, NULL);
+	
 	return res;
 }
Index: uspace/lib/net/generic/net_remote.c
===================================================================
--- uspace/lib/net/generic/net_remote.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/generic/net_remote.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -32,5 +32,5 @@
 
 /** @file
- *  Networking interface implementation for standalone remote modules.
+ *  Networking interface implementation for remote modules.
  *  @see net_interface.h
  */
Index: uspace/lib/net/generic/packet_remote.c
===================================================================
--- uspace/lib/net/generic/packet_remote.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/generic/packet_remote.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -32,5 +32,5 @@
 
 /** @file
- *  Packet client interface implementation for standalone remote modules.
+ *  Packet client interface implementation for remote modules.
  *  @see packet_client.h
  */
@@ -47,94 +47,107 @@
 #include <packet/packet_header.h>
 #include <packet/packet_messages.h>
+#include <packet_remote.h>
 
-/** Obtains the packet from the packet server as the shared memory block.
- *  Creates the local packet mapping as well.
- *  @param[in] phone The packet server module phone.
- *  @param[out] packet The packet reference pointer to store the received packet reference.
- *  @param[in] packet_id The packet identifier.
- *  @param[in] size The packet total size in bytes.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the pm_add() function.
- *  @returns Other error codes as defined for the async_share_in_start() function.
+/** Obtain the packet from the packet server as the shared memory block.
+ *
+ * Create the local packet mapping as well.
+ *
+ * @param[in]  phone     The packet server module phone.
+ * @param[out] packet    The packet reference pointer to store the received
+ *                       packet reference.
+ * @param[in]  packet_id The packet identifier.
+ * @param[in]  size      The packet total size in bytes.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the pm_add() function.
+ * @return Other error codes as defined for the async_share_in_start() function.
+ *
  */
-int packet_return(int phone, packet_ref packet, packet_id_t packet_id, size_t size);
-
-int packet_translate(int phone, packet_ref packet, packet_id_t packet_id){
+static int packet_return(int phone, packet_ref packet, packet_id_t packet_id, size_t size){
 	ERROR_DECLARE;
-
-	ipcarg_t size;
-	packet_t next;
-
-	if(! packet){
-		return EINVAL;
-	}
-	*packet = pm_find(packet_id);
-	if(!(*packet)){
-		ERROR_PROPAGATE(async_req_1_1(phone, NET_PACKET_GET_SIZE, packet_id, &size));
-		ERROR_PROPAGATE(packet_return(phone, packet, packet_id, size));
-	}
-	if((** packet).next){
-		return packet_translate(phone, &next, (** packet).next);
-	}else return EOK;
-}
-
-int packet_return(int phone, packet_ref packet, packet_id_t packet_id, size_t size){
-	ERROR_DECLARE;
-
-	aid_t message;
+	
 	ipc_call_t answer;
-	ipcarg_t result;
-
-	message = async_send_1(phone, NET_PACKET_GET, packet_id, &answer);
+	aid_t message = async_send_1(phone, NET_PACKET_GET, packet_id, &answer);
 	*packet = (packet_t) as_get_mappable_page(size);
-	if(ERROR_OCCURRED(async_share_in_start_0_0(phone, * packet, size))
-		|| ERROR_OCCURRED(pm_add(*packet))){
+	if (ERROR_OCCURRED(async_share_in_start_0_0(phone, *packet, size))
+	    || ERROR_OCCURRED(pm_add(*packet))) {
 		munmap(*packet, size);
 		async_wait_for(message, NULL);
 		return ERROR_CODE;
 	}
+	
+	ipcarg_t result;
 	async_wait_for(message, &result);
+	
 	return result;
 }
 
-packet_t packet_get_4(int phone, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix){
+int packet_translate_remote(int phone, packet_ref packet, packet_id_t packet_id)
+{
 	ERROR_DECLARE;
+	
+	if (!packet)
+		return EINVAL;
+	
+	*packet = pm_find(packet_id);
+	if (!(*packet)) {
+		ipcarg_t size;
+		
+		ERROR_PROPAGATE(async_req_1_1(phone, NET_PACKET_GET_SIZE, packet_id, &size));
+		ERROR_PROPAGATE(packet_return(phone, packet, packet_id, size));
+	}
+	if ((** packet).next) {
+		packet_t next;
+		
+		return packet_translate_remote(phone, &next, (** packet).next);
+	}
+	
+	return EOK;
+}
 
+packet_t packet_get_4_remote(int phone, size_t max_content, size_t addr_len,
+    size_t max_prefix, size_t max_suffix)
+{
+	ERROR_DECLARE;
+	
 	ipcarg_t packet_id;
 	ipcarg_t size;
-	packet_t packet;
-
-	if(ERROR_OCCURRED(async_req_4_2(phone, NET_PACKET_CREATE_4, max_content, addr_len, max_prefix, max_suffix, &packet_id, &size))){
+	
+	if (ERROR_OCCURRED(async_req_4_2(phone, NET_PACKET_CREATE_4, max_content,
+	    addr_len, max_prefix, max_suffix, &packet_id, &size)))
 		return NULL;
+	
+	
+	packet_t packet = pm_find(packet_id);
+	if (!packet) {
+		if (ERROR_OCCURRED(packet_return(phone, &packet, packet_id, size)))
+			return NULL;
 	}
-	packet = pm_find(packet_id);
-	if(! packet){
-		if(ERROR_OCCURRED(packet_return(phone, &packet, packet_id, size))){
-			return NULL;
-		}
-	}
+	
 	return packet;
 }
 
-packet_t packet_get_1(int phone, size_t content){
+packet_t packet_get_1_remote(int phone, size_t content)
+{
 	ERROR_DECLARE;
-
+	
 	ipcarg_t packet_id;
 	ipcarg_t size;
-	packet_t packet;
-
-	if(ERROR_OCCURRED(async_req_1_2(phone, NET_PACKET_CREATE_1, content, &packet_id, &size))){
+	
+	if (ERROR_OCCURRED(async_req_1_2(phone, NET_PACKET_CREATE_1, content,
+	    &packet_id, &size)))
 		return NULL;
+	
+	packet_t packet = pm_find(packet_id);
+	if (!packet) {
+		if (ERROR_OCCURRED(packet_return(phone, &packet, packet_id, size)))
+			return NULL;
 	}
-	packet = pm_find(packet_id);
-	if(! packet){
-		if(ERROR_OCCURRED(packet_return(phone, &packet, packet_id, size))){
-			return NULL;
-		}
-	}
+	
 	return packet;
 }
 
-void pq_release(int phone, packet_id_t packet_id){
+void pq_release_remote(int phone, packet_id_t packet_id)
+{
 	async_msg_1(phone, NET_PACKET_RELEASE, packet_id);
 }
Index: uspace/lib/net/il/arp_remote.c
===================================================================
--- uspace/lib/net/il/arp_remote.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/il/arp_remote.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -32,5 +32,5 @@
 
 /** @file
- *  ARP interface implementation for standalone remote modules.
+ *  ARP interface implementation for remote modules.
  *  @see arp_interface.h
  */
Index: uspace/lib/net/il/ip_client.c
===================================================================
--- uspace/lib/net/il/ip_client.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/il/ip_client.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -56,5 +56,5 @@
 }
 
-int ip_client_get_pseudo_header(ip_protocol_t protocol, struct sockaddr * src, socklen_t srclen, struct sockaddr * dest, socklen_t destlen, size_t data_length, ip_pseudo_header_ref * header, size_t * headerlen){
+int ip_client_get_pseudo_header(ip_protocol_t protocol, struct sockaddr * src, socklen_t srclen, struct sockaddr * dest, socklen_t destlen, size_t data_length, void **header, size_t * headerlen){
 	ipv4_pseudo_header_ref header_in;
 	struct sockaddr_in * address_in;
@@ -84,5 +84,5 @@
 			header_in->protocol = protocol;
 			header_in->data_length = htons(data_length);
-			*header = (ip_pseudo_header_ref) header_in;
+			*header = header_in;
 			return EOK;
 		// TODO IPv6
@@ -164,5 +164,5 @@
 }
 
-int ip_client_set_pseudo_header_data_length(ip_pseudo_header_ref header, size_t headerlen, size_t data_length){
+int ip_client_set_pseudo_header_data_length(void *header, size_t headerlen, size_t data_length){
 	ipv4_pseudo_header_ref header_in;
 
Index: uspace/lib/net/il/ip_remote.c
===================================================================
--- uspace/lib/net/il/ip_remote.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/il/ip_remote.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -28,11 +28,14 @@
 
 /** @addtogroup ip
- *  @{
+ * @{
  */
 
 /** @file
- *  IP interface implementation for standalone remote modules.
- *  @see ip_interface.h
- *  @see il_interface.h
+ *
+ * IP interface implementation for remote modules.
+ *
+ * @see ip_interface.h
+ * @see il_interface.h
+ *
  */
 
@@ -47,69 +50,187 @@
 #include <il_messages.h>
 #include <ip_messages.h>
-
-int ip_add_route_req(int ip_phone, device_id_t device_id, in_addr_t address, in_addr_t netmask, in_addr_t gateway){
-	return (int) async_req_4_0(ip_phone, NET_IP_ADD_ROUTE, (ipcarg_t) device_id, (ipcarg_t) gateway.s_addr, (ipcarg_t) address.s_addr, (ipcarg_t) netmask.s_addr);
-}
-
-int ip_bind_service(services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t tl_received_msg){
-	return (int) bind_service(service, (ipcarg_t) protocol, me, service, receiver);
-}
-
-int ip_connect_module(services_t service){
+#include <ip_remote.h>
+
+/** Add a route to the device routing table.
+ *
+ * The target network is routed using this device.
+ *
+ * @param[in] ip_phone  The IP module phone used for (semi)remote calls.
+ * @param[in] device_id The device identifier.
+ * @param[in] address   The target network address.
+ * @param[in] netmask   The target network mask.
+ * @param[in] gateway   The target network gateway. Not used if zero.
+ *
+ */
+int ip_add_route_req_remote(int ip_phone, device_id_t device_id,
+    in_addr_t address, in_addr_t netmask, in_addr_t gateway)
+{
+	return (int) async_req_4_0(ip_phone, NET_IP_ADD_ROUTE,
+	    (ipcarg_t) device_id, (ipcarg_t) gateway.s_addr,
+	    (ipcarg_t) address.s_addr, (ipcarg_t) netmask.s_addr);
+}
+
+int ip_bind_service(services_t service, int protocol, services_t me,
+    async_client_conn_t receiver, tl_received_msg_t tl_received_msg)
+{
+	return (int) bind_service(service, (ipcarg_t) protocol, me, service,
+	    receiver);
+}
+
+int ip_connect_module(services_t service)
+{
 	return connect_to_service(SERVICE_IP);
 }
 
-int ip_device_req(int ip_phone, device_id_t device_id, services_t service){
-	return generic_device_req(ip_phone, NET_IL_DEVICE, device_id, 0, service);
-}
-
-int ip_get_route_req(int ip_phone, ip_protocol_t protocol, const struct sockaddr * destination, socklen_t addrlen, device_id_t * device_id, ip_pseudo_header_ref * header, size_t * headerlen){
-	aid_t message_id;
-	ipcarg_t result;
+/** Register the new device.
+ *
+ * Register itself as the ip packet receiver.
+ * If the device uses ARP registers also the new ARP device.
+ *
+ * @param[in] ip_phone  The IP module phone used for (semi)remote calls.
+ * @param[in] device_id The new device identifier.
+ * @param[in] netif     The underlying device network interface layer service.
+ *
+ * @return EOK on success.
+ * @return ENOMEM if there is not enough memory left.
+ * @return EINVAL if the device configuration is invalid.
+ * @return ENOTSUP if the device uses IPv6.
+ * @return ENOTSUP if the device uses DHCP.
+ * @return Other error codes as defined for the net_get_device_conf_req()
+ *         function.
+ * @return Other error codes as defined for the arp_device_req() function.
+ *
+ */
+int ip_device_req_remote(int ip_phone, device_id_t device_id,
+    services_t service)
+{
+	return generic_device_req_remote(ip_phone, NET_IL_DEVICE, device_id, 0,
+	    service);
+}
+
+/** Return the device identifier and the IP pseudo header based on the destination address.
+ *
+ * @param[in]  ip_phone    The IP module phone used for (semi)remote calls.
+ * @param[in]  protocol    The transport protocol.
+ * @param[in]  destination The destination address.
+ * @param[in]  addrlen     The destination address length.
+ * @param[out] device_id   The device identifier.
+ * @param[out] header      The constructed IP pseudo header.
+ * @param[out] headerlen   The IP pseudo header length.
+ *
+ */
+int ip_get_route_req_remote(int ip_phone, ip_protocol_t protocol,
+    const struct sockaddr *destination, socklen_t addrlen,
+    device_id_t *device_id, void **header, size_t *headerlen)
+{
+	if ((!destination) || (addrlen == 0))
+		return EINVAL;
+	
+	if ((!device_id) || (header) || (headerlen))
+		return EBADMEM;
+	
+	*header = NULL;
+	
 	ipc_call_t answer;
-
-	if(!(destination && (addrlen > 0))){
-		return EINVAL;
-	}
-	if(!(device_id && header && headerlen)){
-		return EBADMEM;
-	}
-
-	*header = NULL;
-	message_id = async_send_1(ip_phone, NET_IP_GET_ROUTE, (ipcarg_t) protocol, &answer);
-	if((async_data_write_start(ip_phone, destination, addrlen) == EOK)
-		&& (async_data_read_start(ip_phone, headerlen, sizeof(*headerlen)) == EOK)
-		&& (*headerlen > 0)){
-		*header = (ip_pseudo_header_ref) malloc(*headerlen);
-		if(*header){
-			if(async_data_read_start(ip_phone, * header, * headerlen) != EOK){
+	aid_t message_id = async_send_1(ip_phone, NET_IP_GET_ROUTE,
+	    (ipcarg_t) protocol, &answer);
+	
+	if ((async_data_write_start(ip_phone, destination, addrlen) == EOK)
+	    && (async_data_read_start(ip_phone, headerlen, sizeof(*headerlen)) == EOK)
+	    && (*headerlen > 0)) {
+		*header = malloc(*headerlen);
+		if (*header) {
+			if (async_data_read_start(ip_phone, *header, *headerlen) != EOK)
 				free(*header);
-			}
 		}
 	}
+	
+	ipcarg_t result;
 	async_wait_for(message_id, &result);
-
-	if((result != EOK) && (*header)){
+	
+	if ((result != EOK) && (*header))
 		free(*header);
-	}else{
+	else
 		*device_id = IPC_GET_DEVICE(&answer);
-	}
+	
 	return (int) result;
 }
 
-int ip_packet_size_req(int ip_phone, device_id_t device_id, packet_dimension_ref packet_dimension){
-	return generic_packet_size_req(ip_phone, NET_IL_PACKET_SPACE, device_id, packet_dimension);
-}
-
-int ip_received_error_msg(int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error){
-	return generic_received_msg(ip_phone, NET_IP_RECEIVED_ERROR, device_id, packet_get_id(packet), target, error);
-}
-
-int ip_send_msg(int ip_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error){
-	return generic_send_msg(ip_phone, NET_IL_SEND, device_id, packet_get_id(packet), sender, error);
-}
-
-int ip_set_gateway_req(int ip_phone, device_id_t device_id, in_addr_t gateway){
-	return (int) async_req_2_0(ip_phone, NET_IP_SET_GATEWAY, (ipcarg_t) device_id, (ipcarg_t) gateway.s_addr);
+/** Return the device packet dimension for sending.
+ *
+ * @param[in]  ip_phone         The IP module phone used for (semi)remote calls.
+ * @param[in]  device_id        The device identifier.
+ * @param[out] packet_dimension The packet dimension.
+ *
+ * @return EOK on success.
+ * @return ENOENT if there is no such device.
+ * @return Other error codes as defined for the
+ *         generic_packet_size_req_remote() function.
+ *
+ */
+int ip_packet_size_req_remote(int ip_phone, device_id_t device_id,
+    packet_dimension_ref packet_dimension)
+{
+	return generic_packet_size_req_remote(ip_phone, NET_IL_PACKET_SPACE, device_id,
+	    packet_dimension);
+}
+
+/** Notify the IP module about the received error notification packet.
+ *
+ * @param[in] ip_phone  The IP module phone used for (semi)remote calls.
+ * @param[in] device_id The device identifier.
+ * @param[in] packet    The received packet or the received packet queue.
+ * @param[in] target    The target internetwork module service to be
+ *                      delivered to.
+ * @param[in] error     The packet error reporting service. Prefixes the
+ *                      received packet.
+ *
+ * @return EOK on success.
+ *
+ */
+int ip_received_error_msg_remote(int ip_phone, device_id_t device_id,
+    packet_t packet, services_t target, services_t error)
+{
+	return generic_received_msg_remote(ip_phone, NET_IP_RECEIVED_ERROR,
+	    device_id, packet_get_id(packet), target, error);
+}
+
+/** Send the packet queue.
+ *
+ * The packets may get fragmented if needed.
+ *
+ * @param[in] ip_phone  The IP module phone used for (semi)remote calls.
+ * @param[in] device_id The device identifier.
+ * @param[in] packet    The packet fragments as a packet queue. All the
+ *                      packets have to have the same destination address.
+ * @param[in] sender    The sending module service.
+ * @param[in] error     The packet error reporting service. Prefixes the
+ *                      received packet.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the generic_send_msg() function.
+ *
+ */
+int ip_send_msg_remote(int ip_phone, device_id_t device_id, packet_t packet,
+    services_t sender, services_t error)
+{
+	return generic_send_msg_remote(ip_phone, NET_IL_SEND, device_id,
+	    packet_get_id(packet), sender, error);
+}
+
+/** Set the default gateway.
+ *
+ * This gateway is used if no other route is found.
+ *
+ * @param[in] ip_phone  The IP module phone used for (semi)remote calls.
+ * @param[in] device_id The device identifier.
+ * @param[in] gateway   The default gateway.
+ *
+ */
+int ip_set_gateway_req_remote(int ip_phone, device_id_t device_id,
+    in_addr_t gateway)
+{
+	return (int) async_req_2_0(ip_phone, NET_IP_SET_GATEWAY,
+	    (ipcarg_t) device_id, (ipcarg_t) gateway.s_addr);
 }
 
Index: uspace/lib/net/include/arp_interface.h
===================================================================
--- uspace/lib/net/include/arp_interface.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/include/arp_interface.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -29,11 +29,4 @@
 /** @addtogroup arp
  *  @{
- */
-
-/** @file
- *  ARP module interface.
- *  The same interface is used for standalone remote modules as well as for bundle modules.
- *  The standalone remote modules have to be compiled with the arp_remote.c source file.
- *  The bundle modules with the arp.c source file.
  */
 
Index: uspace/lib/net/include/icmp_interface.h
===================================================================
--- uspace/lib/net/include/icmp_interface.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/include/icmp_interface.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -29,11 +29,4 @@
 /** @addtogroup icmp
  *  @{
- */
-
-/** @file
- *  ICMP module interface.
- *  The same interface is used for standalone remote modules as well as for bundle modules.
- *  The standalone remote modules have to be compiled with the icmp_remote.c source file.
- *  The bundle modules with the icmp.c source file.
  */
 
Index: uspace/lib/net/include/il_interface.h
===================================================================
--- uspace/lib/net/include/il_interface.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/include/il_interface.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -32,6 +32,6 @@
 
 /** @file
- *  Internetwork layer module interface for the underlying network interface layer.
- *  This interface is always called by the standalone remote modules.
+ * Internetwork layer module interface for the underlying network interface layer.
+ * This interface is always called by the remote modules.
  */
 
@@ -50,39 +50,63 @@
 
 /** @name Internetwork layer module interface
- *  This interface is used by other modules.
+ * This interface is used by other modules.
  */
 /*@{*/
 
-/** Notifies the internetwork layer modules about the device state change.
- *  @param[in] il_phone The internetwork layer module phone used for (semi)remote calls.
- *  @param[in] device_id The device identifier.
- *  @param[in] state The new device state.
- *  @param[in] target The target internetwork module service to be delivered to.
- *  @returns EOK on success.
+/** Notify the internetwork layer modules about the device state change.
+ *
+ * @param[in] il_phone  The internetwork layer module phone used for
+ *                      (semi)remote calls.
+ * @param[in] device_id The device identifier.
+ * @param[in] state     The new device state.
+ * @param[in] target    The target internetwork module service to be
+ *                      delivered to.
+ *
+ * @return EOK on success.
+ *
  */
-static inline int il_device_state_msg(int il_phone, device_id_t device_id, device_state_t state, services_t target){
-	return generic_device_state_msg(il_phone, NET_IL_DEVICE_STATE, device_id, state, target);
+static inline int il_device_state_msg(int il_phone, device_id_t device_id,
+    device_state_t state, services_t target)
+{
+	return generic_device_state_msg_remote(il_phone, NET_IL_DEVICE_STATE,
+	    device_id, state, target);
 }
 
-/** Notifies the internetwork layer modules about the received packet/s.
- *  @param[in] il_phone The internetwork layer module phone used for (semi)remote calls.
- *  @param[in] device_id The device identifier.
- *  @param[in] packet The received packet or the received packet queue.
- *  @param[in] target The target internetwork module service to be delivered to.
- *  @returns EOK on success.
+/** Notify the internetwork layer modules about the received packet/s.
+ *
+ * @param[in] il_phone  The internetwork layer module phone used for
+ *                      (semi)remote calls.
+ * @param[in] device_id The device identifier.
+ * @param[in] packet    The received packet or the received packet queue.
+ * @param[in] target    The target internetwork module service to be
+ *                      delivered to.
+ *
+ * @return EOK on success.
+ *
  */
-inline static int il_received_msg(int il_phone, device_id_t device_id, packet_t packet, services_t target){
-	return generic_received_msg(il_phone, NET_IL_RECEIVED, device_id, packet_get_id(packet), target, 0);
+inline static int il_received_msg(int il_phone, device_id_t device_id,
+    packet_t packet, services_t target)
+{
+	return generic_received_msg_remote(il_phone, NET_IL_RECEIVED, device_id,
+	    packet_get_id(packet), target, 0);
 }
 
-/** Notifies the internetwork layer modules about the mtu change.
- *  @param[in] il_phone The internetwork layer module phone used for (semi)remote calls.
- *  @param[in] device_id The device identifier.
- *  @param[in] mtu The new mtu value.
- *  @param[in] target The target internetwork module service to be delivered to.
- *  @returns EOK on success.
+/** Notify the internetwork layer modules about the mtu change.
+ *
+ * @param[in] il_phone  The internetwork layer module phone used for
+ *                      (semi)remote calls.
+ * @param[in] device_id The device identifier.
+ * @param[in] mtu       The new mtu value.
+ * @param[in] target    The target internetwork module service to be
+ *                      delivered to.
+ *
+ * @return EOK on success.
+ *
  */
-inline static int il_mtu_changed_msg(int il_phone, device_id_t device_id, size_t mtu, services_t target){
-	return generic_device_state_msg(il_phone, NET_IL_MTU_CHANGED, device_id, (int) mtu, target);
+inline static int il_mtu_changed_msg(int il_phone, device_id_t device_id,
+    size_t mtu, services_t target)
+{
+	return generic_device_state_msg_remote(il_phone, NET_IL_MTU_CHANGED,
+	    device_id, (int) mtu, target);
 }
 
Index: uspace/lib/net/include/il_local.h
===================================================================
--- uspace/lib/net/include/il_local.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/net/include/il_local.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 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 il_local
+ *  @{
+ */
+
+#ifndef __IL_LOCAL_H__
+#define __IL_LOCAL_H__
+
+#include <ipc/ipc.h>
+#include <async.h>
+
+extern int il_module_message_standalone(ipc_callid_t callid, ipc_call_t *call,
+    ipc_call_t *answer, int *answer_count);
+extern int il_module_start_standalone(async_client_conn_t client_connection);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/net/include/il_messages.h
===================================================================
--- uspace/lib/net/include/il_messages.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/include/il_messages.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -28,11 +28,11 @@
 
 /** @addtogroup net_il
- *  @{
+ * @{
  */
 
 /** @file
- *  Internetwork layer modules messages.
- *  @see il_interface.h
- *  @see ip_interface.h
+ * Internetwork layer modules messages.
+ * @see il_interface.h
+ * @see ip_interface.h
  */
 
@@ -44,5 +44,5 @@
 /** Internet layer modules messages.
  */
-typedef enum{
+typedef enum {
 	/** New device message.
 	 *  @see ip_device_req()
@@ -72,16 +72,19 @@
 
 /** @name Internetwork layer specific message parameters definitions
+ *
  */
 /*@{*/
 
-/** Returns the protocol number message parameter.
- *  @param[in] call The message call structure.
+/** Return the protocol number message parameter.
+ * @param[in] call The message call structure.
+ *
  */
-#define IL_GET_PROTO(call)		(int) IPC_GET_ARG1(*call)
+#define IL_GET_PROTO(call)  (int) IPC_GET_ARG1(*call)
 
-/** Returns the registering service message parameter.
- *  @param[in] call The message call structure.
+/** Return the registering service message parameter.
+ * @param[in] call The 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: pace/lib/net/include/il_standalone.h
===================================================================
--- uspace/lib/net/include/il_standalone.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
- * Copyright (c) 2010 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 il_standalone
- *  @{
- */
-
-#ifndef __IL_STANDALONE_H__
-#define __IL_STANDALONE_H__
-
-#include <ipc/ipc.h>
-#include <async.h>
-
-extern int il_module_message(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count);
-extern int il_module_start(async_client_conn_t client_connection);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/net/include/ip_client.h
===================================================================
--- uspace/lib/net/include/ip_client.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/include/ip_client.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -87,5 +87,5 @@
  *  @returns EINVAL if the headerlen parameter is not IPv4 pseudo header length.
  */
-extern int ip_client_set_pseudo_header_data_length(ip_pseudo_header_ref header, size_t headerlen, size_t data_length);
+extern int ip_client_set_pseudo_header_data_length(void *header, size_t headerlen, size_t data_length);
 
 /** Constructs the IPv4 pseudo header.
@@ -107,5 +107,5 @@
  *  @returns ENOMEM if there is not enough memory left.
  */
-extern int ip_client_get_pseudo_header(ip_protocol_t protocol, struct sockaddr * src, socklen_t srclen, struct sockaddr * dest, socklen_t destlen, size_t data_length, ip_pseudo_header_ref * header, size_t * headerlen);
+extern int ip_client_get_pseudo_header(ip_protocol_t protocol, struct sockaddr * src, socklen_t srclen, struct sockaddr * dest, socklen_t destlen, size_t data_length, void **header, size_t * headerlen);
 
 // TODO ipopt manipulation
Index: uspace/lib/net/include/ip_interface.h
===================================================================
--- uspace/lib/net/include/ip_interface.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/include/ip_interface.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -31,11 +31,4 @@
  */
 
-/** @file
- *  IP module interface.
- *  The same interface is used for standalone remote modules as well as for bundle modules.
- *  The standalone remote modules have to be compiled with the ip_remote.c source file.
- *  The bundle modules with the ip.c source file.
- */
-
 #ifndef __NET_IP_INTERFACE_H__
 #define __NET_IP_INTERFACE_H__
@@ -51,12 +44,34 @@
 #include <socket_codes.h>
 
+#ifdef CONFIG_IL_TL_BUNDLE
+
+#include <ip_local.h>
+
+#define ip_received_error_msg  ip_received_error_msg_local
+#define ip_set_gateway_req     ip_set_gateway_req_local
+#define ip_packet_size_req     ip_packet_size_req_local
+#define ip_device_req          ip_device_req_local
+#define ip_add_route_req       ip_add_route_req_local
+#define ip_send_msg            ip_send_msg_local
+#define ip_get_route_req       ip_get_route_req_local
+
+#else
+
+#include <ip_remote.h>
+
+#define ip_received_error_msg  ip_received_error_msg_remote
+#define ip_set_gateway_req     ip_set_gateway_req_remote
+#define ip_packet_size_req     ip_packet_size_req_remote
+#define ip_device_req          ip_device_req_remote
+#define ip_add_route_req       ip_add_route_req_remote
+#define ip_send_msg            ip_send_msg_remote
+#define ip_get_route_req       ip_get_route_req_remote
+
+#endif
+
 /** @name IP module interface
  *  This interface is used by other modules.
  */
 /*@{*/
-
-/** Type definition of the internet pseudo header pointer.
- */
-typedef void *		ip_pseudo_header_ref;
 
 /** The transport layer notification function type definition.
@@ -82,32 +97,4 @@
 extern int ip_bind_service(services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t tl_received_msg);
 
-/** Registers the new device.
- *  Registers itself as the ip packet receiver.
- *  If the device uses ARP registers also the new ARP device.
- *  @param[in] ip_phone The IP module phone used for (semi)remote calls.
- *  @param[in] device_id The new device identifier.
- *  @param[in] netif The underlying device network interface layer service.
- *  @returns EOK on success.
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns EINVAL if the device configuration is invalid.
- *  @returns ENOTSUP if the device uses IPv6.
- *  @returns ENOTSUP if the device uses DHCP.
- *  @returns Other error codes as defined for the net_get_device_conf_req() function.
- *  @returns Other error codes as defined for the arp_device_req() function.
- */
-extern int ip_device_req(int ip_phone, device_id_t device_id, services_t netif);
-
-/** Sends the packet queue.
- *  The packets may get fragmented if needed.
- *  @param[in] ip_phone The IP module phone used for (semi)remote calls.
- *  @param[in] device_id The device identifier.
- *  @param[in] packet The packet fragments as a~packet queue. All the packets have to have the same destination address.
- *  @param[in] sender The sending module service.
- *  @param[in] error The packet error reporting service. Prefixes the received packet.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the generic_send_msg() function.
- */
-extern int ip_send_msg(int ip_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error);
-
 /** Connects to the IP module.
  *  @param service The IP module service. Ignored parameter.
@@ -117,53 +104,4 @@
 extern int ip_connect_module(services_t service);
 
-/** Adds a route to the device routing table.
- *  The target network is routed using this device.
- *  @param[in] ip_phone The IP module phone used for (semi)remote calls.
- *  @param[in] device_id The device identifier.
- *  @param[in] address The target network address.
- *  @param[in] netmask The target network mask.
- *  @param[in] gateway The target network gateway. Not used if zero.
- */
-extern int ip_add_route_req(int ip_phone, device_id_t device_id, in_addr_t address, in_addr_t netmask, in_addr_t gateway);
-
-/** Sets the default gateway.
- *  This gateway is used if no other route is found.
- *  @param[in] ip_phone The IP module phone used for (semi)remote calls.
- *  @param[in] device_id The device identifier.
- *  @param[in] gateway The default gateway.
- */
-extern int ip_set_gateway_req(int ip_phone, device_id_t device_id, in_addr_t gateway);
-
-/** Returns the device packet dimension for sending.
- *  @param[in] ip_phone The IP module phone used for (semi)remote calls.
- *  @param[in] device_id The device identifier.
- *  @param[out] packet_dimension The packet dimension.
- *  @returns EOK on success.
- *  @returns ENOENT if there is no such device.
- *  @returns Other error codes as defined for the generic_packet_size_req() function.
- */
-extern int ip_packet_size_req(int ip_phone, device_id_t device_id, packet_dimension_ref packet_dimension);
-
-/** Notifies the IP module about the received error notification packet.
- *  @param[in] ip_phone The IP module phone used for (semi)remote calls.
- *  @param[in] device_id The device identifier.
- *  @param[in] packet The received packet or the received packet queue.
- *  @param[in] target The target internetwork module service to be delivered to.
- *  @param[in] error The packet error reporting service. Prefixes the received packet.
- *  @returns EOK on success.
- */
-extern int ip_received_error_msg(int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error);
-
-/** Returns the device identifier and the IP pseudo header based on the destination address.
- *  @param[in] ip_phone The IP module phone used for (semi)remote calls.
- *  @param[in] protocol The transport protocol.
- *  @param[in] destination The destination address.
- *  @param[in] addrlen The destination address length.
- *  @param[out] device_id The device identifier.
- *  @param[out] header The constructed IP pseudo header.
- *  @param[out] headerlen The IP pseudo header length.
- */
-extern int ip_get_route_req(int ip_phone, ip_protocol_t protocol, const struct sockaddr * destination, socklen_t addrlen, device_id_t * device_id, ip_pseudo_header_ref * header, size_t * headerlen);
-
 /*@}*/
 
Index: uspace/lib/net/include/ip_local.h
===================================================================
--- uspace/lib/net/include/ip_local.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/net/include/ip_local.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,61 @@
+/*
+ * 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 ip
+ * @{
+ */
+
+#ifndef __NET_IP_LOCAL_H__
+#define __NET_IP_LOCAL_H__
+
+#include <async.h>
+#include <ipc/services.h>
+
+#include <ip_codes.h>
+#include <inet.h>
+#include <in.h>
+#include <socket.h>
+
+extern int ip_received_error_msg_local(int, device_id_t, packet_t, services_t,
+    services_t);
+extern int ip_set_gateway_req_local(int, device_id_t, in_addr_t);
+extern int ip_packet_size_req_local(int, device_id_t, packet_dimension_ref);
+extern int ip_received_error_msg_local(int, device_id_t, packet_t, services_t,
+    services_t);
+extern int ip_device_req_local(int, device_id_t, services_t);
+extern int ip_add_route_req_local(int, device_id_t, in_addr_t, in_addr_t,
+    in_addr_t);
+extern int ip_send_msg_local(int, device_id_t, packet_t, services_t,
+    services_t);
+extern int ip_get_route_req_local(int, ip_protocol_t, const struct sockaddr *,
+    socklen_t, device_id_t *, void **, size_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/net/include/ip_remote.h
===================================================================
--- uspace/lib/net/include/ip_remote.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/net/include/ip_remote.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,59 @@
+/*
+ * 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 ip
+ * @{
+ */
+
+#ifndef __NET_IP_REMOTE_H__
+#define __NET_IP_REMOTE_H__
+
+#include <async.h>
+#include <ipc/services.h>
+
+#include <ip_codes.h>
+#include <inet.h>
+#include <in.h>
+#include <socket.h>
+
+extern int ip_set_gateway_req_remote(int, device_id_t, in_addr_t);
+extern int ip_packet_size_req_remote(int, device_id_t, packet_dimension_ref);
+extern int ip_received_error_msg_remote(int, device_id_t, packet_t, services_t,
+    services_t);
+extern int ip_device_req_remote(int, device_id_t, services_t);
+extern int ip_add_route_req_remote(int, device_id_t, in_addr_t, in_addr_t,
+    in_addr_t);
+extern int ip_send_msg_remote(int, device_id_t, packet_t, services_t,
+    services_t);
+extern int ip_get_route_req_remote(int, ip_protocol_t, const struct sockaddr *,
+    socklen_t, device_id_t *, void **, size_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/net/include/net_interface.h
===================================================================
--- uspace/lib/net/include/net_interface.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/include/net_interface.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -29,11 +29,4 @@
 /** @addtogroup net
  *  @{
- */
-
-/** @file
- *  Networking module interface.
- *  The same interface is used for standalone remote modules as well as for bundle modules.
- *  The standalone remote modules have to be compiled with the net_remote.c source file.
- *  The bundle networking module is compiled with the net_bundle.c source file and the choosen bundle module implementation source files.
  */
 
Index: pace/lib/net/include/netif.h
===================================================================
--- uspace/lib/net/include/netif.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,161 +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 netif
- *  @{
- */
-
-/** @file
- *  Network interface module skeleton.
- *  The skeleton has to be part of each network interface module.
- *  The skeleton can be also part of the module bundled with the network interface layer.
- */
-
-#ifndef __NET_NETIF_H__
-#define __NET_NETIF_H__
-
-#include <async.h>
-#include <fibril_synch.h>
-
-#include <ipc/ipc.h>
-
-#include <net_err.h>
-#include <net_device.h>
-#include <packet/packet.h>
-
-/** Network interface module skeleton global data.
- */
-typedef struct netif_globals	netif_globals_t;
-
-/** Type definition of the device specific data.
- *  @see netif_device
- */
-typedef struct netif_device	device_t;
-
-/** Type definition of the device specific data pointer.
- *  @see netif_device
- */
-typedef device_t *			device_ref;
-
-/** Device map.
- *  Maps device identifiers to the network interface device specific data.
- *  @see device.h
- */
-DEVICE_MAP_DECLARE(device_map, device_t);
-
-/** Network interface device specific data.
- */
-struct	netif_device{
-	/** Device identifier.
-	 */
-	device_id_t device_id;
-	/** Receiving network interface layer phone.
-	 */
-	int nil_phone;
-	/** Actual device state.
-	 */
-	device_state_t state;
-	/** Driver specific data.
-	 */
-	void * specific;
-};
-
-/** Network interface module skeleton global data.
- */
-struct	netif_globals{
-	/** Networking module phone.
-	 */
-	int net_phone;
-	/**	Device map.
-	 */
-	device_map_t device_map;
-	/** Safety lock.
-	 */
-	fibril_rwlock_t lock;
-};
-
-extern netif_globals_t netif_globals;
-
-/**	Finds the device specific data.
- *  @param[in] device_id The device identifier.
- *  @param[out] device The device specific data.
- *  @returns EOK on success.
- *  @returns ENOENT if device is not found.
- *  @returns EPERM if the device is not initialized.
- */
-extern int find_device(device_id_t device_id, device_ref * device);
-
-/** Clears the usage statistics.
- *  @param[in] stats The usage statistics.
- */
-extern void null_device_stats(device_stats_ref stats);
-
-// prepared for future optimalizations
-/** Releases the given packet.
- *  @param[in] packet_id The packet identifier.
- */
-extern void netif_pq_release(packet_id_t packet_id);
-
-/** Allocates new packet to handle the given content size.
- *  @param[in] content The minimum content size.
- *  @returns The allocated packet.
- *  @returns NULL if there is an error.
- */
-extern packet_t netif_packet_get_1(size_t content);
-
-/** Processes the netif module messages.
- *  @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.
- *  @returns EOK on success.
- *  @returns ENOTSUP if the message is not known.
- *  @returns Other error codes as defined for each specific module message function.
- *  @see netif_interface.h
- *  @see IS_NET_NETIF_MESSAGE()
- */
-extern int netif_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
-
-/** Initializes the netif module.
- *  The function has to be defined in each module.
- *  @param[in] net_client_connection The client connection functio to be registered.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for each specific module message function.
- */
-extern int netif_init_module(async_client_conn_t client_connection);
-
-/** Starts and maintains the netif module until terminated.
- *  @returns EOK after the module is terminated.
- */
-extern int netif_run_module(void);
-
-#endif
-
-/** @}
- */
-
Index: uspace/lib/net/include/netif_interface.h
===================================================================
--- uspace/lib/net/include/netif_interface.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/include/netif_interface.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -28,12 +28,5 @@
 
 /** @addtogroup netif
- *  @{
- */
-
-/** @file
- *  Network interface module interface.
- *  The same interface is used for standalone remote modules as well as for bundle network interface layer modules.
- *  The standalone remote modules have to be compiled with the netif_remote.c source file.
- *  The bundle network interface layer modules are compiled with the netif_nil_bundle.c source file and the choosen network interface layer implementation source file.
+ * @{
  */
 
@@ -41,86 +34,36 @@
 #define __NET_NETIF_INTERFACE_H__
 
-#include <ipc/services.h>
+#ifdef CONFIG_NETIF_NIL_BUNDLE
 
-#include <net_messages.h>
-#include <adt/measured_strings.h>
-#include <packet/packet.h>
-#include <net_device.h>
+#include <netif_local.h>
+#include <netif_nil_bundle.h>
+#include <packet/packet_server.h>
 
-/** @name Network interface module interface
- *  This interface is used by other modules.
- */
-/*@{*/
+#define netif_module_message    netif_nil_module_message
+#define netif_module_start      netif_nil_module_start
+#define netif_get_addr_req      netif_get_addr_req_local
+#define netif_probe_req         netif_probe_req_local
+#define netif_send_msg          netif_send_msg_local
+#define netif_start_req         netif_start_req_local
+#define netif_stop_req          netif_stop_req_local
+#define netif_stats_req         netif_stats_req_local
+#define netif_bind_service      netif_bind_service_local
 
-/** Returns 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.
- *  @returns EOK on success.
- *  @returns EBADMEM if the address parameter is NULL.
- *  @returns ENOENT if there no such device.
- *  @returns Other error codes as defined for the netif_get_addr_message() function.
- */
-extern int netif_get_addr_req(int netif_phone, device_id_t device_id, measured_string_ref * address, char ** data);
+#else /* CONFIG_NETIF_NIL_BUNDLE */
 
-/** Probes 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.
- *  @returns EOK on success.
- *  @returns Other errro codes as defined for the netif_probe_message().
- */
-extern int netif_probe_req(int netif_phone, device_id_t device_id, int irq, int io);
+#include <netif_remote.h>
+#include <packet/packet_client.h>
 
-/** Sends 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.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the generic_send_msg() function.
- */
-extern int netif_send_msg(int netif_phone, device_id_t device_id, packet_t packet, services_t sender);
+#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
 
-/** Starts the device.
- *  @param[in] netif_phone The network interface phone.
- *  @param[in] device_id The device identifier.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the find_device() function.
- *  @returns Other error codes as defined for the netif_start_message() function.
- */
-extern int netif_start_req(int netif_phone, device_id_t device_id);
-
-/** Stops the device.
- *  @param[in] netif_phone The network interface phone.
- *  @param[in] device_id The device identifier.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the find_device() function.
- *  @returns Other error codes as defined for the netif_stop_message() function.
- */
-extern int netif_stop_req(int netif_phone, device_id_t device_id);
-
-/** Returns 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.
- *  @returns EOK on success.
- */
-extern int netif_stats_req(int netif_phone, device_id_t device_id, device_stats_ref stats);
-
-/** Creates bidirectional connection with the network interface module and registers the message receiver.
- *  @param[in] service The network interface module service.
- *  @param[in] device_id The device identifier.
- *  @param[in] me The requesting module service.
- *  @param[in] receiver The message receiver.
- *  @returns The phone of the needed service.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the bind_service() function.
- */
-extern int netif_bind_service(services_t service, device_id_t device_id, services_t me, async_client_conn_t receiver);
-
-/*@}*/
+#endif /* CONFIG_NETIF_NIL_BUNDLE */
 
 #endif
Index: uspace/lib/net/include/netif_local.h
===================================================================
--- uspace/lib/net/include/netif_local.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/net/include/netif_local.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,227 @@
+/*
+ * 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 netif
+ * @{
+ */
+
+/** @file
+ * Network interface module skeleton.
+ * The skeleton has to be part of each network interface module.
+ * The skeleton can be also part of the module bundled with the network interface layer.
+ */
+
+#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_err.h>
+#include <net_device.h>
+#include <packet/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_ref 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_ref stats);
+
+extern int netif_get_addr_req_local(int, device_id_t, measured_string_ref *,
+    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_ref);
+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_ref);
+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_messages.h
===================================================================
--- uspace/lib/net/include/netif_messages.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/include/netif_messages.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -28,10 +28,9 @@
 
 /** @addtogroup netif
- *  @{
+ * @{
  */
 
 /** @file
- *  Network interface common module messages.
- *  @see netif_interface.h
+ * Network interface common module messages.
  */
 
@@ -76,12 +75,12 @@
 /*@{*/
 
-/** Returns the interrupt number message parameter.
- *  @param[in] call The message call structure.
+/** Return the interrupt number message parameter.
+ * @param[in] call The message call structure.
  */
 #define NETIF_GET_IRQ(call) \
 	({int irq = (int) IPC_GET_ARG2(*call); irq;})
 
-/** Returns the input/output address message parameter.
- *  @param[in] call The message call structure.
+/** Return the input/output address message parameter.
+ * @param[in] call The message call structure.
  */
 #define NETIF_GET_IO(call) \
Index: pace/lib/net/include/netif_module.h
===================================================================
--- uspace/lib/net/include/netif_module.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,125 +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 netif
- *  @{
- */
-
-/** @file
- *  Network interface module interface.
- *  The interface has to be implemented by each network interface module.
- *  The interface is used by the network interface module skeleton.
- */
-
-#ifndef __NET_NETIF_MODULE_H__
-#define __NET_NETIF_MODULE_H__
-
-#include <ipc/ipc.h>
-#include <ipc/services.h>
-
-#include <adt/measured_strings.h>
-#include <packet/packet.h>
-#include <net_device.h>
-
-/** Initializes the specific module.
- */
-extern int netif_initialize(void);
-
-/** Probes the existence of the device.
- *  @param[in] device_id The device identifier.
- *  @param[in] irq The device interrupt number.
- *  @param[in] io The device input/output address.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the find_device() function.
- *  @returns 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);
-
-/** Sends the packet queue.
- *  @param[in] device_id The device identifier.
- *  @param[in] packet The packet queue.
- *  @param[in] sender The sending module service.
- *  @returns EOK on success.
- *  @returns EFORWARD if the device is not active (in the NETIF_ACTIVE state).
- *  @returns Other error codes as defined for the find_device() function.
- *  @returns 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);
-
-/** Starts the device.
- *  @param[in] device The device structure.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the find_device() function.
- *  @returns Other error codes as defined for the specific module message implementation.
- */
-extern int netif_start_message(device_ref device);
-
-/** Stops the device.
- *  @param[in] device The device structure.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the find_device() function.
- *  @returns Other error codes as defined for the specific module message implementation.
- */
-extern int netif_stop_message(device_ref device);
-
-/** Returns the device local hardware address.
- *  @param[in] device_id The device identifier.
- *  @param[out] address The device local hardware address.
- *  @returns EOK on success.
- *  @returns EBADMEM if the address parameter is NULL.
- *  @returns ENOENT if there no such device.
- *  @returns Other error codes as defined for the find_device() function.
- *  @returns Other error codes as defined for the specific module message implementation.
- */
-extern int netif_get_addr_message(device_id_t device_id, measured_string_ref address);
-
-/** Processes the netif driver specific message.
- *  This function is called for uncommon messages received by the netif skeleton.
- *  @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.
- *  @returns EOK on success.
- *  @returns ENOTSUP if the message is not known.
- *  @returns 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);
-
-/** Returns the device usage statistics.
- *  @param[in] device_id The device identifier.
- *  @param[out] stats The device usage statistics.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the find_device() function.
- *  @returns Other error codes as defined for the specific module message implementation.
- */
-extern int netif_get_device_stats(device_id_t device_id, device_stats_ref stats);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/net/include/netif_nil_bundle.h
===================================================================
--- uspace/lib/net/include/netif_nil_bundle.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/include/netif_nil_bundle.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -37,7 +37,7 @@
 #include <async.h>
 
-extern int netif_nil_module_message(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count);
-extern int netif_nil_module_start(async_client_conn_t client_connection);
+extern int netif_nil_module_message(const char *, ipc_callid_t, ipc_call_t *,
+    ipc_call_t *, int *);
+extern int netif_nil_module_start(async_client_conn_t);
 
 #endif
Index: uspace/lib/net/include/netif_remote.h
===================================================================
--- uspace/lib/net/include/netif_remote.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/net/include/netif_remote.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,53 @@
+/*
+ * 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 netif
+ * @{
+ */
+
+#ifndef __NET_NETIF_REMOTE_H__
+#define __NET_NETIF_REMOTE_H__
+
+#include <async.h>
+#include <fibril_synch.h>
+#include <ipc/ipc.h>
+
+extern int netif_get_addr_req_remote(int, device_id_t, measured_string_ref *,
+    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_ref);
+extern int netif_bind_service_remote(services_t, device_id_t, services_t,
+    async_client_conn_t);
+
+#endif
+
+/** @}
+ */
Index: pace/lib/net/include/netif_standalone.h
===================================================================
--- uspace/lib/net/include/netif_standalone.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
- * Copyright (c) 2010 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 netif_standalone
- *  @{
- */
-
-#ifndef __NETIF_STANDALONE_H__
-#define __NETIF_STANDALONE_H__
-
-#include <ipc/ipc.h>
-#include <async.h>
-
-extern int netif_module_message(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count);
-extern int netif_module_start(async_client_conn_t client_connection);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/net/include/nil_interface.h
===================================================================
--- uspace/lib/net/include/nil_interface.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/include/nil_interface.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -31,12 +31,4 @@
  */
 
-/** @file
- *  Network interface layer module interface.
- *  The same interface is used for standalone remote device modules as well as for bundle device modules.
- *  The standalone remote device modules have to be compiled with the nil_remote.c source file.
- *  The bundle device modules with the appropriate network interface layer source file (eth.c etc.).
- *  The upper layers cannot be bundled with the network interface layer.
- */
-
 #ifndef __NET_NIL_INTERFACE_H__
 #define __NET_NIL_INTERFACE_H__
@@ -53,102 +45,44 @@
 #include <net_device.h>
 
-/** @name Network interface layer module interface
- *  This interface is used by other modules.
- */
-/*@{*/
+#define nil_bind_service(service, device_id, me, receiver) \
+	bind_service(service, device_id, me, 0, receiver)
 
-/** Returns the device local hardware address.
- *  @param[in] nil_phone The network interface layer phone.
- *  @param[in] device_id The device identifier.
- *  @param[out] address The device local hardware address.
- *  @param[out] data The address data.
- *  @returns EOK on success.
- *  @returns EBADMEM if the address parameter and/or the data parameter is NULL.
- *  @returns ENOENT if there no such device.
- *  @returns Other error codes as defined for the generic_get_addr_req() function.
- */
-#define nil_get_addr_req(nil_phone, device_id, address, data)	\
+#define nil_packet_size_req(nil_phone, device_id, packet_dimension) \
+	generic_packet_size_req_remote(nil_phone, NET_NIL_PACKET_SPACE, device_id, \
+	    packet_dimension)
+
+#define nil_get_addr_req(nil_phone, device_id, address, data) \
 	generic_get_addr_req(nil_phone, NET_NIL_ADDR, device_id, address, data)
 
-/** Returns the device broadcast hardware address.
- *  @param[in] nil_phone The network interface layer phone.
- *  @param[in] device_id The device identifier.
- *  @param[out] address The device broadcast hardware address.
- *  @param[out] data The address data.
- *  @returns EOK on success.
- *  @returns EBADMEM if the address parameter is NULL.
- *  @returns ENOENT if there no such device.
- *  @returns Other error codes as defined for the generic_get_addr_req() function.
- */
-#define nil_get_broadcast_addr_req(nil_phone, device_id, address, data)	\
-	generic_get_addr_req(nil_phone, NET_NIL_BROADCAST_ADDR, device_id, address, data)
+#define nil_get_broadcast_addr_req(nil_phone, device_id, address, data) \
+	generic_get_addr_req(nil_phone, NET_NIL_BROADCAST_ADDR, device_id, \
+	    address, data)
 
-/** Sends the packet queue.
- *  @param[in] nil_phone The network interface layer phone.
- *  @param[in] device_id The device identifier.
- *  @param[in] packet The packet queue.
- *  @param[in] sender The sending module service.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the generic_send_msg() function.
- */
-#define nil_send_msg(nil_phone, device_id, packet, sender)	\
-	generic_send_msg(nil_phone, NET_NIL_SEND, device_id, packet_get_id(packet), sender, 0)
+#define nil_send_msg(nil_phone, device_id, packet, sender) \
+	generic_send_msg_remote(nil_phone, NET_NIL_SEND, device_id, \
+	    packet_get_id(packet), sender, 0)
 
-/** Returns the device packet dimension for sending.
- *  @param[in] nil_phone The network interface layer phone.
- *  @param[in] device_id The device identifier.
- *  @param[out] packet_dimension The packet dimensions.
- *  @returns EOK on success.
- *  @returns ENOENT if there is no such device.
- *  @returns Other error codes as defined for the generic_packet_size_req() function.
- */
-#define nil_packet_size_req(nil_phone, device_id, packet_dimension)	\
-	generic_packet_size_req(nil_phone, NET_NIL_PACKET_SPACE, device_id, packet_dimension)
+#define nil_device_req(nil_phone, device_id, mtu, netif_service) \
+	generic_device_req_remote(nil_phone, NET_NIL_DEVICE, device_id, mtu, \
+	    netif_service)
 
-/** Registers new device or updates the MTU of an existing one.
- *  @param[in] nil_phone The network interface layer phone.
- *  @param[in] device_id The new device identifier.
- *  @param[in] mtu The device maximum transmission unit.
- *  @param[in] netif_service The device driver service.
- *  @returns EOK on success.
- *  @returns EEXIST if the device with the different service exists.
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns Other error codes as defined for the generic_device_req() function.
- */
-#define nil_device_req(nil_phone, device_id, mtu, netif_service)	\
-	generic_device_req(nil_phone, NET_NIL_DEVICE, device_id, mtu, netif_service)
 
-/** Notifies the network interface layer about the device state change.
- *  @param[in] nil_phone The network interface layer phone.
- *  @param[in] device_id The device identifier.
- *  @param[in] state The new device state.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for each specific module device state function.
- */
-extern int nil_device_state_msg(int nil_phone, device_id_t device_id, int state);
+#ifdef CONFIG_NETIF_NIL_BUNDLE
 
-/** Passes the packet queue to the network interface layer.
- *  Processes and redistributes the received packet queue to the registered upper layers.
- *  @param[in] nil_phone The network interface layer phone.
- *  @param[in] device_id The source device identifier.
- *  @param[in] packet The received packet or the received packet queue.
- *  @param target The target service. Ignored parameter.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for each specific module received function.
- */
-extern int nil_received_msg(int nil_phone, device_id_t device_id, packet_t packet, services_t target);
+#include <nil_local.h>
+#include <packet/packet_server.h>
 
-/** Creates bidirectional connection with the network interface layer module and registers the message receiver.
- *  @param[in] service The network interface layer module service.
- *  @param[in] device_id The device identifier.
- *  @param[in] me The requesting module service.
- *  @param[in] receiver The message receiver.
- *  @returns The phone of the needed service.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the bind_service() function.
- */
-#define	nil_bind_service(service, device_id, me, receiver)	\
-	bind_service(service, device_id, me, 0, receiver);
-/*@}*/
+#define nil_device_state_msg  nil_device_state_msg_local
+#define nil_received_msg      nil_received_msg_local
+
+#else /* CONFIG_NETIF_NIL_BUNDLE */
+
+#include <nil_remote.h>
+#include <packet/packet_server.h>
+
+#define nil_device_state_msg  nil_device_state_msg_remote
+#define nil_received_msg      nil_received_msg_remote
+
+#endif /* CONFIG_NETIF_NIL_BUNDLE */
 
 #endif
Index: uspace/lib/net/include/nil_local.h
===================================================================
--- uspace/lib/net/include/nil_local.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/net/include/nil_local.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,86 @@
+/*
+ * 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 net_nil
+ *  @{
+ */
+
+/** @file
+ * Network interface layer modules common skeleton.
+ * All network interface layer modules have to implement this interface.
+ */
+
+#ifndef __NET_NIL_LOCAL_H__
+#define __NET_NIL_LOCAL_H__
+
+#include <ipc/ipc.h>
+
+/** Module initialization.
+ *
+ * Is called by the module_start() function.
+ *
+ * @param[in] net_phone The networking moduel phone.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for each specific module initialize function.
+ *
+ */
+extern int nil_initialize(int);
+
+extern int nil_device_state_msg_local(int, device_id_t, int);
+extern int nil_received_msg_local(int, device_id_t, packet_t, services_t);
+
+/** Message processing function.
+ *
+ * @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 nil_interface.h
+ * @see IS_NET_NIL_MESSAGE()
+ *
+ */
+extern int nil_message_standalone(const char *, ipc_callid_t, ipc_call_t *, ipc_call_t *,
+    int *);
+
+extern int nil_module_message_standalone(const char *, ipc_callid_t,
+    ipc_call_t *, ipc_call_t *, int *);
+extern int nil_module_start_standalone(async_client_conn_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/net/include/nil_messages.h
===================================================================
--- uspace/lib/net/include/nil_messages.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/include/nil_messages.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -28,10 +28,9 @@
 
 /** @addtogroup net_nil
- *  @{
+ * @{
  */
 
 /** @file
- *  Network interface layer module messages.
- *  @see nil_interface.h
+ * Network interface layer module messages.
  */
 
@@ -43,5 +42,5 @@
 #include <net_messages.h>
 
-/**  Network interface layer module messages.
+/** Network interface layer module messages.
  */
 typedef enum {
@@ -80,5 +79,5 @@
 /*@{*/
 
-/** Returns the protocol service message parameter.
+/** Return the protocol service message parameter.
  */
 #define NIL_GET_PROTO(call) \
Index: pace/lib/net/include/nil_module.h
===================================================================
--- uspace/lib/net/include/nil_module.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,67 +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 net_nil
- *  @{
- */
-
-/** @file
- *  Network interface layer modules common skeleton.
- *  All network interface layer modules have to implement this interface.
- */
-
-#ifndef __NET_NIL_MODULE_H__
-#define __NET_NIL_MODULE_H__
-
-#include <ipc/ipc.h>
-
-/** Module initialization.
- *  Is called by the module_start() function.
- *  @param[in] net_phone The networking moduel phone.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for each specific module initialize function.
- */
-extern int nil_initialize(int net_phone);
-
-/** Message processing function.
- *  @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.
- *  @returns EOK on success.
- *  @returns ENOTSUP if the message is not known.
- *  @returns Other error codes as defined for each specific module message function.
- *  @see nil_interface.h
- *  @see IS_NET_NIL_MESSAGE()
- */
-extern int nil_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/net/include/nil_remote.h
===================================================================
--- uspace/lib/net/include/nil_remote.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/net/include/nil_remote.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,46 @@
+/*
+ * 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 netif
+ * @{
+ */
+
+#ifndef __NET_NIL_REMOTE_H__
+#define __NET_NIL_REMOTE_H__
+
+#include <async.h>
+#include <fibril_synch.h>
+#include <ipc/ipc.h>
+
+extern int nil_device_state_msg_remote(int, device_id_t, int);
+extern int nil_received_msg_remote(int, device_id_t, packet_t, services_t);
+
+#endif
+
+/** @}
+ */
Index: pace/lib/net/include/nil_standalone.h
===================================================================
--- uspace/lib/net/include/nil_standalone.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
- * Copyright (c) 2010 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 nil_standalone
- *  @{
- */
-
-#ifndef __NIL_STANDALONE_H__
-#define __NIL_STANDALONE_H__
-
-#include <ipc/ipc.h>
-#include <async.h>
-
-extern int nil_module_message(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count);
-extern int nil_module_start(async_client_conn_t client_connection);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/net/include/packet_remote.h
===================================================================
--- uspace/lib/net/include/packet_remote.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/net/include/packet_remote.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,46 @@
+/*
+ * 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 packet
+ * @{
+ */
+
+#ifndef __NET_PACKET_REMOTE_H__
+#define __NET_PACKET_REMOTE_H__
+
+#include <packet/packet.h>
+
+extern int packet_translate_remote(int, packet_ref, packet_id_t);
+extern packet_t packet_get_4_remote(int, size_t, size_t, size_t, size_t);
+extern packet_t packet_get_1_remote(int, size_t);
+extern void pq_release_remote(int, packet_id_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/net/include/tl_common.h
===================================================================
--- uspace/lib/net/include/tl_common.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/include/tl_common.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -49,4 +49,7 @@
 DEVICE_MAP_DECLARE(packet_dimensions, packet_dimension_t);
 
+extern int tl_get_ip_packet_dimension(int, packet_dimensions_ref,
+    device_id_t, packet_dimension_ref *);
+
 /** Gets the address port.
  *  Supports AF_INET and AF_INET6 address families.
@@ -59,19 +62,4 @@
  */
 extern int tl_get_address_port(const struct sockaddr * addr, int addrlen, uint16_t * port);
-
-/** Gets IP packet dimensions.
- *  Tries to search a cache and queries the IP module if not found.
- *  The reply is cached then.
- *  @param[in] ip_phone The IP moduel phone for (semi)remote calls.
- *  @param[in] packet_dimensions The packet dimensions cache.
- *  @param[in] device_id The device identifier.
- *  @param[out] packet_dimension The IP packet dimensions.
- *  @returns EOK on success.
- *  @returns EBADMEM if the packet_dimension parameter is NULL.
- *  @return ENOMEM if there is not enough memory left.
- *  @returns EINVAL if the packet_dimensions cache is not valid.
- *  @returns Other codes as defined for the ip_packet_size_req() function.
- */
-extern int tl_get_ip_packet_dimension(int ip_phone, packet_dimensions_ref packet_dimensions, device_id_t device_id, packet_dimension_ref * packet_dimension);
 
 /** Updates IP device packet dimensions cache.
Index: uspace/lib/net/include/tl_interface.h
===================================================================
--- uspace/lib/net/include/tl_interface.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/include/tl_interface.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -32,5 +32,5 @@
 
 /** @file
- *  Transport layer module interface for the underlying internetwork layer.
+ * Transport layer module interface for the underlying internetwork layer.
  */
 
@@ -48,18 +48,29 @@
 
 /** @name Transport layer module interface
- *  This interface is used by other modules.
+ * This interface is used by other modules.
  */
 /*@{*/
 
-/** Notifies the remote transport layer modules about the received packet/s.
- *  @param[in] tl_phone The transport layer module phone used for remote calls.
- *  @param[in] device_id The device identifier.
- *  @param[in] packet The received packet or the received packet queue. The packet queue is used to carry a~fragmented datagram. The first packet contains the headers, the others contain only data.
- *  @param[in] target The target transport layer module service to be delivered to.
- *  @param[in] error The packet error reporting service. Prefixes the received packet.
- *  @returns EOK on success.
+/** Notify the remote transport layer modules about the received packet/s.
+ *
+ * @param[in] tl_phone  The transport layer module phone used for remote calls.
+ * @param[in] device_id The device identifier.
+ * @param[in] packet    The received packet or the received packet queue.
+ *                      The packet queue is used to carry a fragmented
+ *                      datagram. The first packet contains the headers,
+ *                      the others contain only data.
+ * @param[in] target    The target transport layer module service to be
+ *                      delivered to.
+ * @param[in] error     The packet error reporting service. Prefixes the
+ *                      received packet.
+ *
+ * @return EOK on success.
+ *
  */
-inline static int tl_received_msg(int tl_phone, device_id_t device_id, packet_t packet, services_t target, services_t error){
-	return generic_received_msg(tl_phone, NET_TL_RECEIVED, device_id, packet_get_id(packet), target, error);
+inline static int tl_received_msg(int tl_phone, device_id_t device_id,
+    packet_t packet, services_t target, services_t error)
+{
+	return generic_received_msg_remote(tl_phone, NET_TL_RECEIVED, device_id,
+	    packet_get_id(packet), target, error);
 }
 
Index: uspace/lib/net/include/tl_local.h
===================================================================
--- uspace/lib/net/include/tl_local.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/net/include/tl_local.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 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 tl_local
+ *  @{
+ */
+
+#ifndef __TL_LOCAL_H__
+#define __TL_LOCAL_H__
+
+#include <ipc/ipc.h>
+#include <async.h>
+
+extern int tl_module_message_standalone(ipc_callid_t, ipc_call_t *,
+    ipc_call_t *, int *);
+extern int tl_module_start_standalone(async_client_conn_t);
+
+#endif
+
+/** @}
+ */
Index: pace/lib/net/include/tl_standalone.h
===================================================================
--- uspace/lib/net/include/tl_standalone.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
- * Copyright (c) 2010 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 tl_standalone
- *  @{
- */
-
-#ifndef __TL_STANDALONE_H__
-#define __TL_STANDALONE_H__
-
-#include <ipc/ipc.h>
-#include <async.h>
-
-extern int tl_module_message(ipc_callid_t callid, ipc_call_t *call,
-    ipc_call_t *answer, int *answer_count);
-extern int tl_module_start(async_client_conn_t client_connection);
-
-#endif
-
-/** @}
- */
Index: pace/lib/net/netif/netif.c
===================================================================
--- uspace/lib/net/netif/netif.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,281 +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 netif
- *  @{
- */
-
-/** @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 <net_err.h>
-#include <net_messages.h>
-#include <net_modules.h>
-#include <packet/packet.h>
-#include <packet/packet_client.h>
-#include <adt/measured_strings.h>
-#include <net_device.h>
-#include <netif_interface.h>
-#include <nil_interface.h>
-#include <netif.h>
-#include <netif_messages.h>
-#include <netif_module.h>
-
-DEVICE_MAP_IMPLEMENT(device_map, device_t)
-
-/** Network interface global data.
- */
-netif_globals_t netif_globals;
-
-int netif_probe_req(int netif_phone, device_id_t device_id, int irq, int io){
-	int result;
-
-	fibril_rwlock_write_lock(&netif_globals.lock);
-	result = netif_probe_message(device_id, irq, io);
-	fibril_rwlock_write_unlock(&netif_globals.lock);
-	return result;
-}
-
-int netif_send_msg(int netif_phone, device_id_t device_id, packet_t packet, services_t sender){
-	int result;
-
-	fibril_rwlock_write_lock(&netif_globals.lock);
-	result = netif_send_message(device_id, packet, sender);
-	fibril_rwlock_write_unlock(&netif_globals.lock);
-	return result;
-}
-
-int netif_start_req(int netif_phone, device_id_t device_id){
-	ERROR_DECLARE;
-
-	device_ref device;
-	int result;
-	int phone;
-
-	fibril_rwlock_write_lock(&netif_globals.lock);
-	if(ERROR_OCCURRED(find_device(device_id, &device))){
-		fibril_rwlock_write_unlock(&netif_globals.lock);
-		return ERROR_CODE;
-	}
-	result = netif_start_message(device);
-	if(result > NETIF_NULL){
-		phone = device->nil_phone;
-		fibril_rwlock_write_unlock(&netif_globals.lock);
-		nil_device_state_msg(phone, device_id, result);
-		return EOK;
-	}else{
-		fibril_rwlock_write_unlock(&netif_globals.lock);
-	}
-	return result;
-}
-
-int netif_stop_req(int netif_phone, device_id_t device_id){
-	ERROR_DECLARE;
-
-	device_ref device;
-	int result;
-	int phone;
-
-	fibril_rwlock_write_lock(&netif_globals.lock);
-	if(ERROR_OCCURRED(find_device(device_id, &device))){
-		fibril_rwlock_write_unlock(&netif_globals.lock);
-		return ERROR_CODE;
-	}
-	result = netif_stop_message(device);
-	if(result > NETIF_NULL){
-		phone = device->nil_phone;
-		fibril_rwlock_write_unlock(&netif_globals.lock);
-		nil_device_state_msg(phone, device_id, result);
-		return EOK;
-	}else{
-		fibril_rwlock_write_unlock(&netif_globals.lock);
-	}
-	return result;
-}
-
-int netif_stats_req(int netif_phone, device_id_t device_id, device_stats_ref stats){
-	int res;
-
-	fibril_rwlock_read_lock(&netif_globals.lock);
-	res = netif_get_device_stats(device_id, stats);
-	fibril_rwlock_read_unlock(&netif_globals.lock);
-	return res;
-}
-
-int netif_get_addr_req(int netif_phone, device_id_t device_id, measured_string_ref * address, char ** data){
-	ERROR_DECLARE;
-
-	measured_string_t translation;
-
-	if(!(address && data)){
-		return EBADMEM;
-	}
-	fibril_rwlock_read_lock(&netif_globals.lock);
-	if(! ERROR_OCCURRED(netif_get_addr_message(device_id, &translation))){
-		*address = measured_string_copy(&translation);
-		ERROR_CODE = (*address) ? EOK : ENOMEM;
-	}
-	fibril_rwlock_read_unlock(&netif_globals.lock);
-	*data = (** address).value;
-	return ERROR_CODE;
-}
-
-int netif_bind_service(services_t service, device_id_t device_id, services_t me, async_client_conn_t receiver){
-	return EOK;
-}
-
-int find_device(device_id_t device_id, device_ref * device){
-	if(! device){
-		return EBADMEM;
-	}
-	*device = device_map_find(&netif_globals.device_map, device_id);
-	if(! * device){
-		return ENOENT;
-	}
-	if((** device).state == NETIF_NULL) return EPERM;
-	return EOK;
-}
-
-void null_device_stats(device_stats_ref stats){
-	bzero(stats, sizeof(device_stats_t));
-}
-
-/** Registers the device notification receiver, the network interface layer module.
- *  @param[in] device_id The device identifier.
- *  @param[in] phone The network interface layer module phone.
- *  @returns EOK on success.
- *  @returns ENOENT if there is no such device.
- *  @returns ELIMIT if there is another module registered.
- */
-static int register_message(device_id_t device_id, int phone){
-	ERROR_DECLARE;
-
-	device_ref device;
-
-	ERROR_PROPAGATE(find_device(device_id, &device));
-	if(device->nil_phone > 0){
-		return ELIMIT;
-	}
-	device->nil_phone = phone;
-	printf("New receiver of the device %d registered:\n\tphone\t= %d\n", device->device_id, device->nil_phone);
-	return EOK;
-}
-
-int netif_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
-	ERROR_DECLARE;
-
-	size_t length;
-	device_stats_t stats;
-	packet_t packet;
-	measured_string_t address;
-
-//	printf("message %d - %d\n", IPC_GET_METHOD(*call), NET_NETIF_FIRST);
-	*answer_count = 0;
-	switch(IPC_GET_METHOD(*call)){
-		case IPC_M_PHONE_HUNGUP:
-			return EOK;
-		case NET_NETIF_PROBE:
-			return netif_probe_req(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);
-			ERROR_CODE = register_message(IPC_GET_DEVICE(call), IPC_GET_PHONE(call));
-			fibril_rwlock_write_unlock(&netif_globals.lock);
-			return ERROR_CODE;
-		case NET_NETIF_SEND:
-			ERROR_PROPAGATE(packet_translate(netif_globals.net_phone, &packet, IPC_GET_PACKET(call)));
-			return netif_send_msg(0, IPC_GET_DEVICE(call), packet, IPC_GET_SENDER(call));
-		case NET_NETIF_START:
-			return netif_start_req(0, IPC_GET_DEVICE(call));
-		case NET_NETIF_STATS:
-			fibril_rwlock_read_lock(&netif_globals.lock);
-			if(! ERROR_OCCURRED(async_data_read_receive(&callid, &length))){
-				if(length < sizeof(device_stats_t)){
-					ERROR_CODE = EOVERFLOW;
-				}else{
-					if(! ERROR_OCCURRED(netif_get_device_stats(IPC_GET_DEVICE(call), &stats))){
-						ERROR_CODE = async_data_read_finalize(callid, &stats, sizeof(device_stats_t));
-					}
-				}
-			}
-			fibril_rwlock_read_unlock(&netif_globals.lock);
-			return ERROR_CODE;
-		case NET_NETIF_STOP:
-			return netif_stop_req(0, IPC_GET_DEVICE(call));
-		case NET_NETIF_GET_ADDR:
-			fibril_rwlock_read_lock(&netif_globals.lock);
-			if(! ERROR_OCCURRED(netif_get_addr_message(IPC_GET_DEVICE(call), &address))){
-				ERROR_CODE = measured_strings_reply(&address, 1);
-			}
-			fibril_rwlock_read_unlock(&netif_globals.lock);
-			return ERROR_CODE;
-	}
-	return netif_specific_message(callid, call, answer, answer_count);
-}
-
-int netif_init_module(async_client_conn_t client_connection){
-	ERROR_DECLARE;
-
-	async_set_client_connection(client_connection);
-	netif_globals.net_phone = connect_to_service(SERVICE_NETWORKING);
-	device_map_initialize(&netif_globals.device_map);
-	ERROR_PROPAGATE(pm_init());
-	fibril_rwlock_initialize(&netif_globals.lock);
-	if(ERROR_OCCURRED(netif_initialize())){
-		pm_destroy();
-		return ERROR_CODE;
-	}
-	return EOK;
-}
-
-int netif_run_module(void){
-	async_manager();
-
-	pm_destroy();
-	return EOK;
-}
-
-void netif_pq_release(packet_id_t packet_id){
-	pq_release(netif_globals.net_phone, packet_id);
-}
-
-packet_t netif_packet_get_1(size_t content){
-	return packet_get_1(netif_globals.net_phone, content);
-}
-
-/** @}
- */
Index: uspace/lib/net/netif/netif_local.c
===================================================================
--- uspace/lib/net/netif/netif_local.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/net/netif/netif_local.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,468 @@
+/*
+ * 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 netif
+ * @{
+ */
+
+/** @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 <net_err.h>
+#include <net_messages.h>
+#include <net_modules.h>
+#include <packet/packet.h>
+#include <packet/packet_client.h>
+#include <packet/packet_server.h>
+#include <packet_remote.h>
+#include <adt/measured_strings.h>
+#include <net_device.h>
+#include <nil_interface.h>
+#include <netif_local.h>
+#include <netif_messages.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 errro 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)
+{
+	ERROR_DECLARE;
+	
+	fibril_rwlock_write_lock(&netif_globals.lock);
+	
+	netif_device_t *device;
+	if (ERROR_OCCURRED(find_device(device_id, &device))) {
+		fibril_rwlock_write_unlock(&netif_globals.lock);
+		return ERROR_CODE;
+	}
+	
+	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)
+{
+	ERROR_DECLARE;
+	
+	fibril_rwlock_write_lock(&netif_globals.lock);
+	
+	netif_device_t *device;
+	if (ERROR_OCCURRED(find_device(device_id, &device))) {
+		fibril_rwlock_write_unlock(&netif_globals.lock);
+		return ERROR_CODE;
+	}
+	
+	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_ref 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_ref *address, char **data)
+{
+	ERROR_DECLARE;
+	
+	if ((!address) || (!data))
+		return EBADMEM;
+	
+	fibril_rwlock_read_lock(&netif_globals.lock);
+	
+	measured_string_t translation;
+	if (!ERROR_OCCURRED(netif_get_addr_message(device_id, &translation))) {
+		*address = measured_string_copy(&translation);
+		ERROR_CODE = (*address) ? EOK : ENOMEM;
+	}
+	
+	fibril_rwlock_read_unlock(&netif_globals.lock);
+	
+	*data = (**address).value;
+	
+	return ERROR_CODE;
+}
+
+/** Create bidirectional connection with the network interface module and registers the message receiver.
+ *
+ * @param[in] service   The network interface module service.
+ * @param[in] device_id The device identifier.
+ * @param[in] me        The requesting module service.
+ * @param[in] receiver  The message receiver.
+ *
+ * @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_local(services_t service, device_id_t device_id,
+    services_t me, async_client_conn_t receiver)
+{
+	return EOK;
+}
+
+/** 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_ref 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)
+{
+	ERROR_DECLARE;
+	
+	async_set_client_connection(client_connection);
+	
+	netif_globals.net_phone = connect_to_service(SERVICE_NETWORKING);
+	netif_device_map_initialize(&netif_globals.device_map);
+	
+	ERROR_PROPAGATE(pm_init());
+	
+	fibril_rwlock_initialize(&netif_globals.lock);
+	if (ERROR_OCCURRED(netif_initialize())) {
+		pm_destroy();
+		return ERROR_CODE;
+	}
+	
+	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)
+{
+	ERROR_DECLARE;
+	
+	netif_device_t *device;
+	ERROR_PROPAGATE(find_device(device_id, &device));
+	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)
+{
+	ERROR_DECLARE;
+	
+	size_t length;
+	device_stats_t stats;
+	packet_t packet;
+	measured_string_t address;
+	
+	*answer_count = 0;
+	switch (IPC_GET_METHOD(*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);
+			ERROR_CODE = register_message(name, IPC_GET_DEVICE(call),
+			    IPC_GET_PHONE(call));
+			fibril_rwlock_write_unlock(&netif_globals.lock);
+			return ERROR_CODE;
+		case NET_NETIF_SEND:
+			ERROR_PROPAGATE(packet_translate_remote(netif_globals.net_phone,
+			    &packet, IPC_GET_PACKET(call)));
+			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);
+			if (!ERROR_OCCURRED(async_data_read_receive(&callid, &length))) {
+				if (length < sizeof(device_stats_t))
+					ERROR_CODE = EOVERFLOW;
+				else {
+					if (!ERROR_OCCURRED(netif_get_device_stats(
+					    IPC_GET_DEVICE(call), &stats)))
+						ERROR_CODE = async_data_read_finalize(callid, &stats,
+						    sizeof(device_stats_t));
+				}
+			}
+			fibril_rwlock_read_unlock(&netif_globals.lock);
+			return ERROR_CODE;
+		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);
+			if (!ERROR_OCCURRED(netif_get_addr_message(IPC_GET_DEVICE(call),
+			    &address)))
+				ERROR_CODE = measured_strings_reply(&address, 1);
+			fibril_rwlock_read_unlock(&netif_globals.lock);
+			return ERROR_CODE;
+	}
+	
+	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)
+{
+	ERROR_DECLARE;
+	
+	ERROR_PROPAGATE(netif_init_module(client_connection));
+	
+	async_manager();
+	
+	pm_destroy();
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/net/netif/netif_nil_bundle.c
===================================================================
--- uspace/lib/net/netif/netif_nil_bundle.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/netif/netif_nil_bundle.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -41,40 +41,63 @@
 #include <net_messages.h>
 #include <packet/packet.h>
-#include <nil_module.h>
 #include <netif_nil_bundle.h>
-#include <netif.h>
+#include <netif_local.h>
+#include <nil_local.h>
 
-/** Distributes the messages between the module parts.
- *  @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.
- *  @returns EOK on success.
- *  @returns ENOTSUP if the message is not known.
- *  @returns Other error codes as defined for each specific module message function.
+/** Distribute the messages between the module parts.
+ *
+ * @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.
+ *
  */
-int netif_nil_module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
-	if(IS_NET_NIL_MESSAGE(call) || (IPC_GET_METHOD(*call) == IPC_M_CONNECT_TO_ME)){
-		return nil_message(callid, call, answer, answer_count);
-	}else{
-		return netif_message(callid, call, answer, answer_count);
-	}
+int netif_nil_module_message(const char *name, ipc_callid_t callid,
+    ipc_call_t *call, ipc_call_t *answer, int *answer_count)
+{
+	if ((IS_NET_NIL_MESSAGE(call))
+	    || (IPC_GET_METHOD(*call) == IPC_M_CONNECT_TO_ME))
+		return nil_message_standalone(name, callid, call, answer,
+		    answer_count);
+	else
+		return netif_module_message_standalone(name, callid, call, answer,
+		    answer_count);
 }
 
-/** Starts the bundle network interface module.
- *  Initializes the client connection serving function, initializes both module parts, registers the module service and starts 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.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for each specific module message function.
+/** Start the bundle network interface module.
+ *
+ * Initialize the client connection serving function, initialize
+ * both module parts, register 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_nil_module_start(async_client_conn_t client_connection){
+int netif_nil_module_start(async_client_conn_t client_connection)
+{
 	ERROR_DECLARE;
-
+	
 	ERROR_PROPAGATE(netif_init_module(client_connection));
-	if(ERROR_OCCURRED(nil_initialize(netif_globals.net_phone))){
+	if (ERROR_OCCURRED(nil_initialize(netif_globals.net_phone))) {
 		pm_destroy();
 		return ERROR_CODE;
 	}
-	return netif_run_module();
+	
+	async_manager();
+	
+	pm_destroy();
+	return EOK;
 }
 
Index: uspace/lib/net/netif/netif_remote.c
===================================================================
--- uspace/lib/net/netif/netif_remote.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/net/netif/netif_remote.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,99 @@
+/*
+ * 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 netif
+ * @{
+ */
+
+/** @file
+ * Network interface module interface implementation for remote modules.
+ */
+
+#include <ipc/services.h>
+
+#include <net_modules.h>
+#include <adt/measured_strings.h>
+#include <packet/packet.h>
+#include <packet/packet_client.h>
+#include <net_device.h>
+#include <netif_remote.h>
+#include <netif_messages.h>
+
+int netif_get_addr_req_remote(int netif_phone, device_id_t device_id,
+    measured_string_ref *address, char **data)
+{
+	return generic_get_addr_req(netif_phone, NET_NETIF_GET_ADDR, device_id,
+	    address, data);
+}
+
+int netif_probe_req_remote(int netif_phone, device_id_t device_id, int irq, int io)
+{
+	return async_req_3_0(netif_phone, NET_NETIF_PROBE, device_id, irq, io);
+}
+
+int netif_send_msg_remote(int netif_phone, device_id_t device_id, packet_t packet,
+    services_t sender)
+{
+	return generic_send_msg_remote(netif_phone, NET_NETIF_SEND, device_id,
+	    packet_get_id(packet), sender, 0);
+}
+
+int netif_start_req_remote(int netif_phone, device_id_t device_id)
+{
+	return async_req_1_0(netif_phone, NET_NETIF_START, device_id);
+}
+
+int netif_stop_req_remote(int netif_phone, device_id_t device_id)
+{
+	return async_req_1_0(netif_phone, NET_NETIF_STOP, device_id);
+}
+
+int netif_stats_req_remote(int netif_phone, device_id_t device_id,
+    device_stats_ref stats)
+{
+	if (!stats)
+		return EBADMEM;
+	
+	aid_t message_id = async_send_1(netif_phone, NET_NETIF_STATS,
+	    (ipcarg_t) device_id, NULL);
+	async_data_read_start(netif_phone, stats, sizeof(*stats));
+	
+	ipcarg_t result;
+	async_wait_for(message_id, &result);
+	
+	return (int) result;
+}
+
+int netif_bind_service_remote(services_t service, device_id_t device_id, services_t me,
+    async_client_conn_t receiver)
+{
+	return bind_service(service, device_id, me, 0, receiver);
+}
+
+/** @}
+ */
Index: pace/lib/net/netif/netif_standalone.c
===================================================================
--- uspace/lib/net/netif/netif_standalone.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,70 +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 netif
- *  @{
- */
-
-/** @file
- *  Wrapper for the standalone network interface module.
- */
-
-#include <async.h>
-#include <ipc/ipc.h>
-
-#include <netif.h>
-#include <netif_standalone.h>
-
-/** Delegates the messages to the netif_message() function.
- *  @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.
- *  @returns EOK on success.
- *  @returns ENOTSUP if the message is not known.
- *  @returns Other error codes as defined for each specific module message function.
- */
-int netif_module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
-	return netif_message(callid, call, answer, answer_count);
-}
-
-/** Starts the network interface module.
- *  Initializes the client connection serving function, initializes the module, registers the module service and starts 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.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for each specific module message function.
- */
-int netif_module_start(async_client_conn_t client_connection){
-	ERROR_DECLARE;
-
-	ERROR_PROPAGATE(netif_init_module(client_connection));
-	return netif_run_module();
-}
-
-/** @}
- */
Index: uspace/lib/net/nil/nil_remote.c
===================================================================
--- uspace/lib/net/nil/nil_remote.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/nil/nil_remote.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -28,10 +28,10 @@
 
 /** @addtogroup net_nil
- *  @{
+ * @{
  */
 
 /** @file
- *  Network interface layer interface implementation for standalone remote modules.
- *  @see nil_interface.h
+ * Network interface layer interface implementation for remote modules.
+ * @see nil_interface.h
  */
 
@@ -42,11 +42,43 @@
 #include <packet/packet_client.h>
 #include <nil_messages.h>
+#include <nil_remote.h>
 
-int nil_device_state_msg(int nil_phone, device_id_t device_id, int state){
-	return generic_device_state_msg(nil_phone, NET_NIL_DEVICE_STATE, device_id, state, 0);
+/** Notify the network interface layer about the device state change.
+ *
+ * @param[in] nil_phone The network interface layer phone.
+ * @param[in] device_id The device identifier.
+ * @param[in] state     The new device state.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for each specific module device
+ *         state function.
+ *
+ */
+int nil_device_state_msg_remote(int nil_phone, device_id_t device_id, int state)
+{
+	return generic_device_state_msg_remote(nil_phone, NET_NIL_DEVICE_STATE,
+	    device_id, state, 0);
 }
 
-int nil_received_msg(int nil_phone, device_id_t device_id, packet_t packet, services_t target){
-	return generic_received_msg(nil_phone, NET_NIL_RECEIVED, device_id, packet_get_id(packet), target, 0);
+/** Pass the packet queue to the network interface layer.
+ *
+ * Process and redistribute the received packet queue to the registered
+ * upper layers.
+ *
+ * @param[in] nil_phone The network interface layer phone.
+ * @param[in] device_id The source device identifier.
+ * @param[in] packet    The received packet or the received packet queue.
+ * @param     target    The target service. Ignored parameter.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for each specific module
+ *         received function.
+ *
+ */
+int nil_received_msg_remote(int nil_phone, device_id_t device_id,
+    packet_t packet, services_t target)
+{
+	return generic_received_msg_remote(nil_phone, NET_NIL_RECEIVED, device_id,
+	    packet_get_id(packet), target, 0);
 }
 
Index: uspace/lib/net/tl/icmp_remote.c
===================================================================
--- uspace/lib/net/tl/icmp_remote.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/tl/icmp_remote.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -32,5 +32,5 @@
 
 /** @file
- *  ICMP interface implementation for standalone remote modules.
+ *  ICMP interface implementation for remote modules.
  *  @see icmp_interface.h
  */
Index: uspace/lib/net/tl/tl_common.c
===================================================================
--- uspace/lib/net/tl/tl_common.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/net/tl/tl_common.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -42,4 +42,5 @@
 #include <packet/packet.h>
 #include <packet/packet_client.h>
+#include <packet_remote.h>
 #include <net_device.h>
 #include <icmp_interface.h>
@@ -47,7 +48,10 @@
 #include <in6.h>
 #include <inet.h>
-#include <ip_interface.h>
+#include <ip_local.h>
+#include <ip_remote.h>
 #include <socket_codes.h>
 #include <socket_errno.h>
+#include <ip_interface.h>
+#include <tl_interface.h>
 #include <tl_common.h>
 
@@ -82,28 +86,51 @@
 }
 
-int tl_get_ip_packet_dimension(int ip_phone, packet_dimensions_ref packet_dimensions, device_id_t device_id, packet_dimension_ref * packet_dimension){
+/** Get IP packet dimensions.
+ *
+ * Try to search a cache and query the IP module if not found.
+ * The reply is cached then.
+ *
+ * @param[in]  ip_phone          The IP moduel phone for (semi)remote calls.
+ * @param[in]  packet_dimensions The packet dimensions cache.
+ * @param[in]  device_id         The device identifier.
+ * @param[out] packet_dimension  The IP packet dimensions.
+ *
+ * @return EOK on success.
+ * @return EBADMEM if the packet_dimension parameter is NULL.
+ * @return ENOMEM if there is not enough memory left.
+ * @return EINVAL if the packet_dimensions cache is not valid.
+ * @return Other codes as defined for the ip_packet_size_req() function.
+ *
+ */
+int tl_get_ip_packet_dimension(int ip_phone,
+    packet_dimensions_ref packet_dimensions, device_id_t device_id,
+    packet_dimension_ref *packet_dimension)
+{
 	ERROR_DECLARE;
-
-	if(! packet_dimension){
+	
+	if (!packet_dimension)
 		return EBADMEM;
-	}
-
+	
 	*packet_dimension = packet_dimensions_find(packet_dimensions, device_id);
-	if(! * packet_dimension){
-		// ask for and remember them if not found
-		*packet_dimension = malloc(sizeof(** packet_dimension));
-		if(! * packet_dimension){
+	if (!*packet_dimension) {
+		/* Ask for and remember them if not found */
+		*packet_dimension = malloc(sizeof(**packet_dimension));
+		if(!*packet_dimension)
 			return ENOMEM;
-		}
-		if(ERROR_OCCURRED(ip_packet_size_req(ip_phone, device_id, * packet_dimension))){
+		
+		if (ERROR_OCCURRED(ip_packet_size_req(ip_phone, device_id,
+		    *packet_dimension))) {
 			free(*packet_dimension);
 			return ERROR_CODE;
 		}
-		ERROR_CODE = packet_dimensions_add(packet_dimensions, device_id, * packet_dimension);
-		if(ERROR_CODE < 0){
+		
+		ERROR_CODE = packet_dimensions_add(packet_dimensions, device_id,
+		    *packet_dimension);
+		if (ERROR_CODE < 0) {
 			free(*packet_dimension);
 			return ERROR_CODE;
 		}
 	}
+	
 	return EOK;
 }
@@ -169,7 +196,7 @@
 	// detach the first packet and release the others
 	next = pq_detach(packet);
-	if(next){
-		pq_release(packet_phone, packet_get_id(next));
-	}
+	if (next)
+		pq_release_remote(packet_phone, packet_get_id(next));
+	
 	length = packet_get_addr(packet, &src, NULL);
 	if((length > 0)
@@ -180,5 +207,5 @@
 		return EOK;
 	}else{
-		pq_release(packet_phone, packet_get_id(packet));
+		pq_release_remote(packet_phone, packet_get_id(packet));
 	}
 	return ENOENT;
@@ -200,5 +227,5 @@
 	}
 	// get a new packet
-	*packet = packet_get_4(packet_phone, length, dimension->addr_len, prefix + dimension->prefix, dimension->suffix);
+	*packet = packet_get_4_remote(packet_phone, length, dimension->addr_len, prefix + dimension->prefix, dimension->suffix);
 	if(! packet){
 		return ENOMEM;
@@ -207,5 +234,5 @@
 	data = packet_suffix(*packet, length);
 	if(! data){
-		pq_release(packet_phone, packet_get_id(*packet));
+		pq_release_remote(packet_phone, packet_get_id(*packet));
 		return ENOMEM;
 	}
@@ -214,5 +241,5 @@
 	// set the packet destination address
 		|| ERROR_OCCURRED(packet_set_addr(*packet, NULL, (uint8_t *) addr, addrlen))){
-		pq_release(packet_phone, packet_get_id(*packet));
+		pq_release_remote(packet_phone, packet_get_id(*packet));
 		return ERROR_CODE;
 	}
Index: pace/lib/netif/Makefile
===================================================================
--- uspace/lib/netif/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,37 +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 = ../..
-EXTRA_CFLAGS = -Iinclude -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
-LIBRARY = libnetif
-
-SOURCES = \
-	generic/netif_remote.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/lib/netif/generic/netif_remote.c
===================================================================
--- uspace/lib/netif/generic/netif_remote.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,86 +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 netif
- *  @{
- */
-
-/** @file
- *  Network interface module interface implementation for standalone remote modules.
- *  @see netif_interface.h
- */
-
-#include <ipc/services.h>
-
-#include <net_modules.h>
-#include <adt/measured_strings.h>
-#include <packet/packet.h>
-#include <packet/packet_client.h>
-#include <net_device.h>
-#include <netif_interface.h>
-#include <netif_messages.h>
-
-int netif_get_addr_req(int netif_phone, device_id_t device_id, measured_string_ref * address, char ** data){
-	return generic_get_addr_req(netif_phone, NET_NETIF_GET_ADDR, device_id, address, data);
-}
-
-int netif_probe_req(int netif_phone, device_id_t device_id, int irq, int io){
-	return async_req_3_0(netif_phone, NET_NETIF_PROBE, device_id, irq, io);
-}
-
-int netif_send_msg(int netif_phone, device_id_t device_id, packet_t packet, services_t sender){
-	return generic_send_msg(netif_phone, NET_NETIF_SEND, device_id, packet_get_id(packet), sender, 0);
-}
-
-int netif_start_req(int netif_phone, device_id_t device_id){
-	return async_req_1_0(netif_phone, NET_NETIF_START, 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);
-}
-
-int netif_stats_req(int netif_phone, device_id_t device_id, device_stats_ref stats){
-	aid_t message_id;
-	ipcarg_t result;
-
-	if(! stats){
-		return EBADMEM;
-	}
-	message_id = async_send_1(netif_phone, NET_NETIF_STATS, (ipcarg_t) device_id, NULL);
-	async_data_read_start(netif_phone, stats, sizeof(*stats));
-	async_wait_for(message_id, &result);
-	return (int) result;
-}
-
-int netif_bind_service(services_t service, device_id_t device_id, services_t me, async_client_conn_t receiver){
-	return bind_service(service, device_id, me, 0, receiver);
-}
-
-/** @}
- */
Index: uspace/lib/socket/Makefile
===================================================================
--- uspace/lib/socket/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/socket/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -35,4 +35,5 @@
 	generic/socket_client.c \
 	generic/socket_core.c \
+	generic/socket_parse.c \
 	generic/inet.c \
 	generic/net_modules.c \
Index: uspace/lib/socket/generic/net_modules.c
===================================================================
--- uspace/lib/socket/generic/net_modules.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/socket/generic/net_modules.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -77,20 +77,49 @@
 }
 
-int bind_service(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, async_client_conn_t client_receiver){
+/** Create bidirectional connection with the needed module service and registers the message receiver.
+ *
+ * @param[in] need            The needed module service.
+ * @param[in] arg1            The first parameter.
+ * @param[in] arg2            The second parameter.
+ * @param[in] arg3            The third parameter.
+ * @param[in] client_receiver The message receiver.
+ *
+ * @return The phone of the needed service.
+ * @return Other error codes as defined for the ipc_connect_to_me() function.
+ *
+ */
+int bind_service(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3,
+    async_client_conn_t client_receiver)
+{
 	return bind_service_timeout(need, arg1, arg2, arg3, client_receiver, 0);
 }
 
-int bind_service_timeout(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout){
+/** Create bidirectional connection with the needed module service and registers the message receiver.
+ *
+ * @param[in] need            The needed module service.
+ * @param[in] arg1            The first parameter.
+ * @param[in] arg2            The second parameter.
+ * @param[in] arg3            The third parameter.
+ * @param[in] client_receiver The message receiver.
+ * @param[in] timeout         The connection timeout in microseconds.
+ *                            No timeout if set to zero (0).
+ *
+ * @return The phone of the needed service.
+ * @return ETIMEOUT if the connection timeouted.
+ * @return Other error codes as defined for the ipc_connect_to_me() function.
+ *
+ */
+int bind_service_timeout(services_t need, ipcarg_t arg1, ipcarg_t arg2,
+    ipcarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout)
+{
 	ERROR_DECLARE;
-
-	int phone;
-	ipcarg_t phonehash;
-
-	// connect to the needed service
-	phone = connect_to_service_timeout(need, timeout);
-	// if connected
-	if(phone >= 0){
-		// request the bidirectional connection
-		if(ERROR_OCCURRED(ipc_connect_to_me(phone, arg1, arg2, arg3, &phonehash))){
+	
+	/* Connect to the needed service */
+	int phone = connect_to_service_timeout(need, timeout);
+	if (phone >= 0) {
+		/* Request the bidirectional connection */
+		ipcarg_t phonehash;
+		if (ERROR_OCCURRED(ipc_connect_to_me(phone, arg1, arg2, arg3,
+		    &phonehash))) {
 			ipc_hangup(phone);
 			return ERROR_CODE;
@@ -98,4 +127,5 @@
 		async_new_connection(phonehash, 0, NULL, client_receiver);
 	}
+	
 	return phone;
 }
Index: uspace/lib/socket/generic/socket_client.c
===================================================================
--- uspace/lib/socket/generic/socket_client.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/socket/generic/socket_client.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -299,5 +299,5 @@
 static int socket_generate_new_id(void){
 	sockets_ref sockets;
-	int socket_id;
+	int socket_id = 0;
 	int count;
 
Index: uspace/lib/socket/generic/socket_core.c
===================================================================
--- uspace/lib/socket/generic/socket_core.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/socket/generic/socket_core.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -90,5 +90,5 @@
 	// release all received packets
 	while((packet_id = dyn_fifo_pop(&socket->received)) >= 0){
-		pq_release(packet_phone, packet_id);
+		pq_release_local(packet_phone, packet_id);
 	}
 	dyn_fifo_destroy(&socket->received);
Index: uspace/lib/socket/generic/socket_parse.c
===================================================================
--- uspace/lib/socket/generic/socket_parse.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/socket/generic/socket_parse.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,122 @@
+/*
+ * 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 socket
+ * @{
+ */
+
+/** @file
+ * Command-line argument parsing functions related to networking.
+ */
+
+#include <socket_parse.h>
+#include <arg_parse.h>
+#include <errno.h>
+#include <str.h>
+#include <socket.h>
+
+/** Translate the character string to the address family number.
+ *
+ * @param[in]  name The address family name.
+ * @param[out] af   The corresponding address family number
+ *                  or EAFNOSUPPORTED.
+ *
+ * @return EOK on success.
+ * @return ENOTSUP on unsupported address family.
+ *
+ */
+int socket_parse_address_family(const char *name, int *af)
+{
+	if (str_lcmp(name, "AF_INET", 7) == 0) {
+		*af = AF_INET;
+		return EOK;
+	}
+	
+	if (str_lcmp(name, "AF_INET6", 8) == 0) {
+		*af = AF_INET6;
+		return EOK;
+	}
+	
+	*af = EAFNOSUPPORT;
+	return ENOTSUP;
+}
+
+/** Translate the character string to the protocol family number.
+ *
+ * @param[in]  name The protocol family name.
+ * @param[out] pf   The corresponding protocol family number
+ *                  or EPFNOSUPPORTED.
+ *
+ * @return EOK on success.
+ * @return ENOTSUP on unsupported protocol family.
+ *
+ */
+int socket_parse_protocol_family(const char *name, int *pf)
+{
+	if (str_lcmp(name, "PF_INET", 7) == 0) {
+		*pf = PF_INET;
+		return EOK;
+	}
+	
+	if (str_lcmp(name, "PF_INET6", 8) == 0) {
+		*pf = PF_INET6;
+		return EOK;
+	}
+	
+	*pf = EPFNOSUPPORT;
+	return ENOTSUP;
+}
+
+/** Translate the character string to the socket type number.
+ *
+ * @param[in]  name  The socket type name.
+ * @param[out] sockt The corresponding socket type number
+ *                   or ESOCKTNOSUPPORT.
+ *
+ * @return EOK on success.
+ * @return ENOTSUP on unsupported socket type.
+ *
+ */
+int socket_parse_socket_type(const char *name, int *sockt)
+{
+	if (str_lcmp(name, "SOCK_DGRAM", 11) == 0) {
+		*sockt = SOCK_DGRAM;
+		return EOK;
+	}
+	
+	if (str_lcmp(name, "SOCK_STREAM", 12) == 0) {
+		*sockt = SOCK_STREAM;
+		return EOK;
+	}
+	
+	*sockt = ESOCKTNOSUPPORT;
+	return ENOTSUP;
+}
+
+/** @}
+ */
Index: uspace/lib/socket/include/net_err.h
===================================================================
--- uspace/lib/socket/include/net_err.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/socket/include/net_err.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -28,9 +28,9 @@
 
 /** @addtogroup net
- *  @{
+ * @{
  */
 
 /** @file
- *  Common error processing codes and routines.
+ * Common error processing codes and routines.
  */
 
@@ -41,40 +41,56 @@
 
 #ifdef CONFIG_DEBUG
+	#include <stdio.h>
+	#include <str_error.h>
+#endif
 
-#include <stdio.h>
+/** An actual stored error code.
+ *
+ */
+#define ERROR_CODE  error_check_return_value
+
+/** An error processing routines declaration.
+ *
+ * This has to be declared in the block where the error processing
+ * is desired.
+ *
+ */
+#define ERROR_DECLARE  int ERROR_CODE
+
+/** Store the value as an error code and checks if an error occurred.
+ *
+ * @param[in] value The value to be checked. May be a function call.
+ * @return False if the value indicates success (EOK).
+ * @return True otherwise.
+ *
+ */
+#ifdef CONFIG_DEBUG
+
+#define ERROR_OCCURRED(value) \
+	(((ERROR_CODE = (value)) != EOK) \
+	&& ({ \
+		fprintf(stderr, "libsocket error at %s:%d (%s)\n", \
+		__FILE__, __LINE__, str_error(ERROR_CODE)); \
+		1; \
+	}))
+
+#else
+
+#define ERROR_OCCURRED(value)  ((ERROR_CODE = (value)) != EOK)
 
 #endif
 
-/** An actual stored error code.
- */
-#define ERROR_CODE					error_check_return_value
-
-/** An error processing routines declaration.
- *  This has to be declared in the block where the error processing is desired.
- */
-#define ERROR_DECLARE				int ERROR_CODE
-
-/** Stores the value as an error code and checks if an error occurred.
- *  @param[in] value The value to be checked. May be a function call.
- *  @returns FALSE if the value indicates success (EOK).
- *  @returns TRUE otherwise.
- */
-#ifdef CONFIG_DEBUG
-
-#define ERROR_OCCURRED(value)												\
-	(((ERROR_CODE = (value)) != EOK)										\
-	&& ({printf("error at %s:%d %d\n", __FILE__, __LINE__, ERROR_CODE); 1;}))
-
-#else
-
-#define ERROR_OCCURRED(value)		((ERROR_CODE = (value)) != EOK)
-
-#endif
-
-/** Checks if an error occurred and immediately exits the actual function returning the error code.
- *  @param[in] value The value to be checked. May be a function call.
+/** Error propagation
+ *
+ * Check if an error occurred and immediately exit the actual
+ * function returning the error code.
+ *
+ * @param[in] value The value to be checked. May be a function call.
+ *
  */
 
-#define ERROR_PROPAGATE(value)	if(ERROR_OCCURRED(value)) return ERROR_CODE
+#define ERROR_PROPAGATE(value) \
+	if (ERROR_OCCURRED(value)) \
+		return ERROR_CODE
 
 #endif
Index: uspace/lib/socket/include/net_messages.h
===================================================================
--- uspace/lib/socket/include/net_messages.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/socket/include/net_messages.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -462,28 +462,41 @@
 /*@}*/
 
-/** Notifies the module about the device state change.
- *  @param[in] phone The service module phone.
- *  @param[in] message The service specific message.
- *  @param[in] device_id The device identifier.
- *  @param[in] state The new device state.
- *  @param[in] target The target module service.
- *  @returns EOK on success.
- */
-static inline int generic_device_state_msg(int phone, int message, device_id_t device_id, int state, services_t target){
-	async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) state, target);
+/** Notify the module about the device state change.
+ *
+ * @param[in] phone     The service module phone.
+ * @param[in] message   The service specific message.
+ * @param[in] device_id The device identifier.
+ * @param[in] state     The new device state.
+ * @param[in] target    The target module service.
+ *
+ * @return EOK on success.
+ *
+ */
+static inline int generic_device_state_msg_remote(int phone, int message,
+    device_id_t device_id, int state, services_t target)
+{
+	async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id,
+	    (ipcarg_t) state, target);
+	
 	return EOK;
 }
 
-/** Notifies a module about the device.
- *  @param[in] phone The service module phone.
- *  @param[in] message The service specific message.
- *  @param[in] device_id The device identifier.
- *  @param[in] arg2 The second argument of the message.
- *  @param[in] service The device module service.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the specific service message.
- */
-static inline int generic_device_req(int phone, int message, device_id_t device_id, int arg2, services_t service){
-	return (int) async_req_3_0(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) arg2, (ipcarg_t) service);
+/** Notify a module about the device.
+ *
+ * @param[in] phone     The service module phone.
+ * @param[in] message   The service specific message.
+ * @param[in] device_id The device identifier.
+ * @param[in] arg2      The second argument of the message.
+ * @param[in] service   The device module service.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the specific service message.
+ *
+ */
+static inline int generic_device_req_remote(int phone, int message,
+    device_id_t device_id, int arg2, services_t service)
+{
+	return (int) async_req_3_0(phone, (ipcarg_t) message, (ipcarg_t) device_id,
+	    (ipcarg_t) arg2, (ipcarg_t) service);
 }
 
@@ -521,64 +534,88 @@
 }
 
-/** Returns the device packet dimension for sending.
- *  @param[in] phone The service module phone.
- *  @param[in] message The service specific message.
- *  @param[in] device_id The device identifier.
- *  @param[out] packet_dimension The packet dimension.
- *  @returns EOK on success.
- *  @returns EBADMEM if the packet_dimension parameter is NULL.
- *  @returns Other error codes as defined for the specific service message.
- */
-static inline int generic_packet_size_req(int phone, int message, device_id_t device_id, packet_dimension_ref packet_dimension){
-	ipcarg_t result;
+/** Return the device packet dimension for sending.
+ *
+ * @param[in]  phone            The service module phone.
+ * @param[in]  message          The service specific message.
+ * @param[in]  device_id        The device identifier.
+ * @param[out] packet_dimension The packet dimension.
+ *
+ * @return EOK on success.
+ * @return EBADMEM if the packet_dimension parameter is NULL.
+ * @return Other error codes as defined for the specific service message.
+ *
+ */
+static inline int generic_packet_size_req_remote(int phone, int message,
+    device_id_t device_id, packet_dimension_ref packet_dimension)
+{
+	if (!packet_dimension)
+		return EBADMEM;
+	
+	ipcarg_t addr_len;
 	ipcarg_t prefix;
 	ipcarg_t content;
 	ipcarg_t suffix;
-	ipcarg_t addr_len;
-
-	if(! packet_dimension){
-		return EBADMEM;
-	}
-	result = async_req_1_4(phone, (ipcarg_t) message, (ipcarg_t) device_id, &addr_len, &prefix, &content, &suffix);
+	
+	ipcarg_t result = async_req_1_4(phone, (ipcarg_t) message,
+	    (ipcarg_t) device_id, &addr_len, &prefix, &content, &suffix);
+	
 	packet_dimension->prefix = (size_t) prefix;
 	packet_dimension->content = (size_t) content;
 	packet_dimension->suffix = (size_t) suffix;
 	packet_dimension->addr_len = (size_t) addr_len;
+	
 	return (int) result;
 }
 
-/** Passes the packet queue to the module.
- *  @param[in] phone The service module phone.
- *  @param[in] message The service specific message.
- *  @param[in] device_id The device identifier.
- *  @param[in] packet_id The received packet or the received packet queue identifier.
- *  @param[in] target The target module service.
- *  @param[in] error The error module service.
- *  @returns EOK on success.
- */
-static inline int generic_received_msg(int phone, int message, device_id_t device_id, packet_id_t packet_id, services_t target, services_t error){
-	if(error){
-		async_msg_4(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) packet_id, (ipcarg_t) target, (ipcarg_t) error);
-	}else{
-		async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) packet_id, (ipcarg_t) target);
-	}
+/** Pass the packet queue to the module.
+ *
+ * @param[in] phone     The service module phone.
+ * @param[in] message   The service specific message.
+ * @param[in] device_id The device identifier.
+ * @param[in] packet_id The received packet or the received packet queue
+ *                      identifier.
+ * @param[in] target    The target module service.
+ * @param[in] error     The error module service.
+ *
+ * @return EOK on success.
+ *
+ */
+static inline int generic_received_msg_remote(int phone, int message,
+    device_id_t device_id, packet_id_t packet_id, services_t target,
+    services_t error)
+{
+	if (error)
+		async_msg_4(phone, (ipcarg_t) message, (ipcarg_t) device_id,
+		    (ipcarg_t) packet_id, (ipcarg_t) target, (ipcarg_t) error);
+	else
+		async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id,
+		    (ipcarg_t) packet_id, (ipcarg_t) target);
+	
 	return EOK;
 }
 
-/** Sends the packet queue.
- *  @param[in] phone The service module phone.
- *  @param[in] message The service specific message.
- *  @param[in] device_id The device identifier.
- *  @param[in] packet_id The packet or the packet queue identifier.
- *  @param[in] sender The sending module service.
- *  @param[in] error The error module service.
- *  @returns EOK on success.
- */
-static inline int generic_send_msg(int phone, int message, device_id_t device_id, packet_id_t packet_id, services_t sender, services_t error){
-	if(error){
-		async_msg_4(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) packet_id, (ipcarg_t) sender, (ipcarg_t) error);
-	}else{
-		async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) packet_id, (ipcarg_t) sender);
-	}
+/** Send the packet queue.
+ *
+ * @param[in] phone     The service module phone.
+ * @param[in] message   The service specific message.
+ * @param[in] device_id The device identifier.
+ * @param[in] packet_id The packet or the packet queue identifier.
+ * @param[in] sender    The sending module service.
+ * @param[in] error     The error module service.
+ *
+ * @return EOK on success.
+ *
+ */
+static inline int generic_send_msg_remote(int phone, int message,
+    device_id_t device_id, packet_id_t packet_id, services_t sender,
+    services_t error)
+{
+	if (error)
+		async_msg_4(phone, (ipcarg_t) message, (ipcarg_t) device_id,
+		    (ipcarg_t) packet_id, (ipcarg_t) sender, (ipcarg_t) error);
+	else
+		async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id,
+		    (ipcarg_t) packet_id, (ipcarg_t) sender);
+	
 	return EOK;
 }
Index: uspace/lib/socket/include/net_modules.h
===================================================================
--- uspace/lib/socket/include/net_modules.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/socket/include/net_modules.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -72,27 +72,8 @@
 extern void answer_call(ipc_callid_t callid, int result, ipc_call_t * answer, int answer_count);
 
-/** Creates bidirectional connection with the needed module service and registers the message receiver.
- *  @param[in] need The needed module service.
- *  @param[in] arg1 The first parameter.
- *  @param[in] arg2 The second parameter.
- *  @param[in] arg3 The third parameter.
- *  @param[in] client_receiver The message receiver.
- *  @returns The phone of the needed service.
- *  @returns Other error codes as defined for the ipc_connect_to_me() function.
- */
-extern int bind_service(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, async_client_conn_t client_receiver);
-
-/** Creates bidirectional connection with the needed module service and registers the message receiver.
- *  @param[in] need The needed module service.
- *  @param[in] arg1 The first parameter.
- *  @param[in] arg2 The second parameter.
- *  @param[in] arg3 The third parameter.
- *  @param[in] client_receiver The message receiver.
- *  @param[in] timeout The connection timeout in microseconds. No timeout if set to zero (0).
- *  @returns The phone of the needed service.
- *  @returns ETIMEOUT if the connection timeouted.
- *  @returns Other error codes as defined for the ipc_connect_to_me() function.
- */
-extern int bind_service_timeout(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout);
+extern int bind_service(services_t, ipcarg_t, ipcarg_t, ipcarg_t,
+    async_client_conn_t);
+extern int bind_service_timeout(services_t, ipcarg_t, ipcarg_t, ipcarg_t,
+    async_client_conn_t, suseconds_t);
 
 /** Connects to the needed module.
Index: uspace/lib/socket/include/packet/packet_client.h
===================================================================
--- uspace/lib/socket/include/packet/packet_client.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/socket/include/packet/packet_client.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -45,5 +45,5 @@
 #define __NET_PACKET_CLIENT_H__
 
-#include "packet.h"
+#include <packet/packet.h>
 
 /** @name Packet client interface
@@ -172,5 +172,5 @@
  *  @returns Other error codes as defined for the packet_return() function.
  */
-extern int packet_translate(int phone, packet_ref packet, packet_id_t packet_id);
+extern int packet_translate_local(int phone, packet_ref packet, packet_id_t packet_id);
 
 /** Obtains the packet of the given dimensions.
@@ -184,5 +184,5 @@
  *  @returns NULL on error.
  */
-extern packet_t packet_get_4(int phone, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix);
+extern packet_t packet_get_4_local(int phone, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix);
 
 /** Obtains the packet of the given content size.
@@ -193,5 +193,5 @@
  *  @returns NULL on error.
  */
-extern packet_t packet_get_1(int phone, size_t content);
+extern packet_t packet_get_1_local(int phone, size_t content);
 
 /** Releases the packet queue.
@@ -202,5 +202,5 @@
  *  @param[in] packet_id The packet identifier.
  */
-extern void pq_release(int phone, packet_id_t packet_id);
+extern void pq_release_local(int phone, packet_id_t packet_id);
 
 /** Returns the packet copy.
Index: uspace/lib/socket/include/socket_parse.h
===================================================================
--- uspace/lib/socket/include/socket_parse.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/lib/socket/include/socket_parse.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,42 @@
+/*
+ * 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 socket
+ * @{
+ */
+
+/** @file
+ * Command-line argument parsing functions related to networking.
+ */
+
+extern int socket_parse_address_family(const char *, int *);
+extern int socket_parse_protocol_family(const char *, int *);
+extern int socket_parse_socket_type(const char *, int *);
+
+/** @}
+ */
Index: uspace/lib/socket/packet/packet_client.c
===================================================================
--- uspace/lib/socket/packet/packet_client.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/socket/packet/packet_client.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -156,6 +156,6 @@
 packet_t packet_get_copy(int phone, packet_t packet){
 	packet_t copy;
-	uint8_t * src;
-	uint8_t * dest;
+	uint8_t * src = NULL;
+	uint8_t * dest = NULL;
 	size_t addrlen;
 
@@ -164,5 +164,5 @@
 	}
 	// get a new packet
-	copy = packet_get_4(phone, PACKET_DATA_LENGTH(packet), PACKET_MAX_ADDRESS_LENGTH(packet), packet->max_prefix, PACKET_MIN_SUFFIX(packet));
+	copy = packet_get_4_local(phone, PACKET_DATA_LENGTH(packet), PACKET_MAX_ADDRESS_LENGTH(packet), packet->max_prefix, PACKET_MIN_SUFFIX(packet));
 	if(! copy){
 		return NULL;
@@ -178,5 +178,5 @@
 		return copy;
 	}else{
-		pq_release(phone, copy->packet_id);
+		pq_release_local(phone, copy->packet_id);
 		return NULL;
 	}
Index: uspace/lib/socket/packet/packet_server.c
===================================================================
--- uspace/lib/socket/packet/packet_server.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/lib/socket/packet/packet_server.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -97,8 +97,9 @@
 };
 
-int packet_translate(int phone, packet_ref packet, packet_id_t packet_id){
-	if(! packet){
+int packet_translate_local(int phone, packet_ref packet, packet_id_t packet_id)
+{
+	if (!packet)
 		return EINVAL;
-	}
+	
 	*packet = pm_find(packet_id);
 	return (*packet) ? EOK : ENOENT;
@@ -161,60 +162,79 @@
 }
 
-/** Returns the packet of dimensions at least as given.
- *  Tries to reuse free packets first.
- *  Creates a&nbsp;new packet aligned to the memory page size if none available.
- *  Locks the global data during its processing.
- *  @param[in] addr_len The source and destination addresses maximal length in bytes.
- *  @param[in] max_prefix The maximal prefix length in bytes.
- *  @param[in] max_content The maximal content length in bytes.
- *  @param[in] max_suffix The maximal suffix length in bytes.
- *  @returns The packet of dimensions at least as given.
- *  @returns NULL if there is not enough memory left.
- */
-static packet_t packet_get(size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){
-	int index;
+/** Return the packet of dimensions at least as given.
+ *
+ * Try to reuse free packets first.
+ * Create a new packet aligned to the memory page size if none available.
+ * Lock the global data during its processing.
+ *
+ * @param[in] addr_len    The source and destination addresses
+ *                        maximal length in bytes.
+ * @param[in] max_prefix  The maximal prefix length in bytes.
+ * @param[in] max_content The maximal content length in bytes.
+ * @param[in] max_suffix  The maximal suffix length in bytes.
+ *
+ * @return The packet of dimensions at least as given.
+ * @return NULL if there is not enough memory left.
+ *
+ */
+static packet_t packet_get_local(size_t addr_len, size_t max_prefix,
+    size_t max_content, size_t max_suffix)
+{
+	size_t length = ALIGN_UP(sizeof(struct packet) + 2 * addr_len + max_prefix
+	    + max_content + max_suffix, PAGE_SIZE);
+	
+	fibril_mutex_lock(&ps_globals.lock);
+	
 	packet_t packet;
-	size_t length;
-
-	length = ALIGN_UP(sizeof(struct packet) + 2 * addr_len + max_prefix + max_content + max_suffix, PAGE_SIZE);
-	fibril_mutex_lock(&ps_globals.lock);
-	for(index = 0; index < FREE_QUEUES_COUNT - 1; ++ index){
-		if(length <= ps_globals.sizes[index]){
+	unsigned int index;
+	
+	for (index = 0; index < FREE_QUEUES_COUNT - 1; index++) {
+		if (length <= ps_globals.sizes[index]) {
 			packet = ps_globals.free[index];
-			while(packet_is_valid(packet) && (packet->length < length)){
+			
+			while (packet_is_valid(packet) && (packet->length < length))
 				packet = pm_find(packet->next);
-			}
-			if(packet_is_valid(packet)){
-				if(packet == ps_globals.free[index]){
+			
+			if (packet_is_valid(packet)) {
+				if (packet == ps_globals.free[index])
 					ps_globals.free[index] = pq_detach(packet);
-				}else{
+				else
 					pq_detach(packet);
-				}
-				packet_init(packet, addr_len, max_prefix, max_content, max_suffix);
+				
+				packet_init(packet, addr_len, max_prefix, max_content,
+				    max_suffix);
 				fibril_mutex_unlock(&ps_globals.lock);
-				// remove debug dump
-//				printf("packet %d got\n", packet->packet_id);
+				
 				return packet;
 			}
 		}
 	}
-	packet = packet_create(length, addr_len, max_prefix, max_content, max_suffix);
+	
+	packet = packet_create(length, addr_len, max_prefix, max_content,
+	    max_suffix);
+	
 	fibril_mutex_unlock(&ps_globals.lock);
-	// remove debug dump
-//	printf("packet %d created\n", packet->packet_id);
+	
 	return packet;
 }
 
-packet_t packet_get_4(int phone, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix){
-	return packet_get(addr_len, max_prefix, max_content, max_suffix);
-}
-
-packet_t packet_get_1(int phone, size_t content){
-	return packet_get(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, content, DEFAULT_SUFFIX);
-}
-
-/** Releases the packet and returns it to the appropriate free packet queue.
+packet_t packet_get_4_local(int phone, size_t max_content, size_t addr_len,
+    size_t max_prefix, size_t max_suffix)
+{
+	return packet_get_local(addr_len, max_prefix, max_content, max_suffix);
+}
+
+packet_t packet_get_1_local(int phone, size_t content)
+{
+	return packet_get_local(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, content,
+	    DEFAULT_SUFFIX);
+}
+
+/** Release the packet and returns it to the appropriate free packet queue.
+ *
  *  Should be used only when the global data are locked.
+ *
  *  @param[in] packet The packet to be released.
+ *
  */
 static void packet_release(packet_t packet){
@@ -247,5 +267,6 @@
 }
 
-void pq_release(int phone, packet_id_t packet_id){
+void pq_release_local(int phone, packet_id_t packet_id)
+{
 	(void) packet_release_wrapper(packet_id);
 }
@@ -281,5 +302,5 @@
 			return EOK;
 		case NET_PACKET_CREATE_1:
-			packet = packet_get(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, IPC_GET_CONTENT(call), DEFAULT_SUFFIX);
+			packet = packet_get_local(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, IPC_GET_CONTENT(call), DEFAULT_SUFFIX);
 			if(! packet){
 				return ENOMEM;
@@ -290,5 +311,5 @@
 			return EOK;
 		case NET_PACKET_CREATE_4:
-			packet = packet_get(((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));
+			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));
 			if(! packet){
 				return ENOMEM;
Index: uspace/srv/bd/rd/rd.c
===================================================================
--- uspace/srv/bd/rd/rd.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/bd/rd/rd.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -32,9 +32,9 @@
 /** @addtogroup rd
  * @{
- */ 
+ */
 
 /**
- * @file	rd.c
- * @brief	Initial RAM disk for HelenOS.
+ * @file rd.c
+ * @brief Initial RAM disk for HelenOS.
  */
 
@@ -61,4 +61,5 @@
 /** Pointer to the ramdisk's image */
 static void *rd_addr;
+
 /** Size of the ramdisk */
 static size_t rd_size;
@@ -70,16 +71,17 @@
 static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf);
 
-/**
- * This rwlock protects the ramdisk's data.
+/** This rwlock protects the ramdisk's data.
+ *
  * If we were to serve multiple requests (read + write or several writes)
- * concurrently (i.e. from two or more threads), each read and write needs to be
- * protected by this rwlock.
- */ 
+ * concurrently (i.e. from two or more threads), each read and write needs to
+ * be protected by this rwlock.
+ *
+ */
 fibril_rwlock_t rd_lock;
 
 /** Handle one connection to ramdisk.
  *
- * @param iid		Hash of the request that opened the connection.
- * @param icall		Call data of the request that opened the connection.
+ * @param iid   Hash of the request that opened the connection.
+ * @param icall Call data of the request that opened the connection.
  */
 static void rd_connection(ipc_callid_t iid, ipc_call_t *icall)
@@ -92,10 +94,10 @@
 	size_t cnt;
 	size_t comm_size;
-
+	
 	/*
 	 * Answer the first IPC_M_CONNECT_ME_TO call.
 	 */
 	ipc_answer_0(iid, EOK);
-
+	
 	/*
 	 * Now we wait for the client to send us its communication as_area.
@@ -108,5 +110,5 @@
 		} else {
 			ipc_answer_0(callid, EHANGUP);
-			return;		
+			return;
 		}
 	} else {
@@ -178,9 +180,9 @@
 		return ELIMIT;
 	}
-
+	
 	fibril_rwlock_read_lock(&rd_lock);
 	memcpy(buf, rd_addr + ba * block_size, block_size * cnt);
 	fibril_rwlock_read_unlock(&rd_lock);
-
+	
 	return EOK;
 }
@@ -193,9 +195,9 @@
 		return ELIMIT;
 	}
-
+	
 	fibril_rwlock_write_lock(&rd_lock);
 	memcpy(rd_addr + ba * block_size, buf, block_size * cnt);
 	fibril_rwlock_write_unlock(&rd_lock);
-
+	
 	return EOK;
 }
@@ -204,9 +206,14 @@
 static bool rd_init(void)
 {
-	rd_size = sysinfo_value("rd.size");
-	void *rd_ph_addr = (void *) sysinfo_value("rd.address.physical");
-	
-	if (rd_size == 0) {
-		printf(NAME ": No RAM disk found\n");
+	int ret = sysinfo_get_value("rd.size", &rd_size);
+	if ((ret != EOK) || (rd_size == 0)) {
+		printf("%s: No RAM disk found\n", NAME);
+		return false;
+	}
+	
+	sysarg_t rd_ph_addr;
+	ret = sysinfo_get_value("rd.address.physical", &rd_ph_addr);
+	if ((ret != EOK) || (rd_ph_addr == 0)) {
+		printf("%s: Invalid RAM disk physical address\n", NAME);
 		return false;
 	}
@@ -215,17 +222,17 @@
 	
 	int flags = AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE;
-	int retval = physmem_map(rd_ph_addr, rd_addr,
+	int retval = physmem_map((void *) rd_ph_addr, rd_addr,
 	    ALIGN_UP(rd_size, PAGE_SIZE) >> PAGE_WIDTH, flags);
 	
 	if (retval < 0) {
-		printf(NAME ": Error mapping RAM disk\n");
-		return false;
-	}
-	
-	printf(NAME ": Found RAM disk at %p, %d bytes\n", rd_ph_addr, rd_size);
+		printf("%s: Error mapping RAM disk\n", NAME);
+		return false;
+	}
+	
+	printf("%s: Found RAM disk at %p, %d bytes\n", NAME, rd_ph_addr, rd_size);
 	
 	int rc = devmap_driver_register(NAME, rd_connection);
 	if (rc < 0) {
-		printf(NAME ": Unable to register driver (%d)\n", rc);
+		printf("%s: Unable to register driver (%d)\n", NAME, rc);
 		return false;
 	}
@@ -234,5 +241,5 @@
 	if (devmap_device_register("bd/initrd", &dev_handle) != EOK) {
 		devmap_hangup_phone(DEVMAP_DRIVER);
-		printf(NAME ": Unable to register device\n");
+		printf("%s: Unable to register device\n", NAME);
 		return false;
 	}
@@ -245,10 +252,10 @@
 int main(int argc, char **argv)
 {
-	printf(NAME ": HelenOS RAM disk server\n");
+	printf("%s: HelenOS RAM disk server\n", NAME);
 	
 	if (!rd_init())
 		return -1;
 	
-	printf(NAME ": Accepting connections\n");
+	printf("%s: Accepting connections\n", NAME);
 	async_manager();
 
Index: uspace/srv/devmap/devmap.c
===================================================================
--- uspace/srv/devmap/devmap.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/devmap/devmap.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -172,5 +172,11 @@
 		
 		*name = str_dup(fqdn);
-		if ((*name == NULL) || (str_cmp(*name, "") == 0)) {
+		if (*name == NULL) {
+			free(*ns_name);
+			return false;
+		}
+		
+		if (str_cmp(*name, "") == 0) {
+			free(*name);
 			free(*ns_name);
 			return false;
@@ -186,9 +192,15 @@
 	
 	*name = str_dup(fqdn + slash_after);
-	if ((*name == NULL) || (str_cmp(*name, "") == 0)) {
+	if (*name == NULL) {
 		free(*ns_name);
 		return false;
 	}
 	
+	if (str_cmp(*name, "") == 0) {
+		free(*name);
+		free(*ns_name);
+		return false;
+	}
+	
 	return true;
 }
@@ -202,11 +214,10 @@
 static devmap_namespace_t *devmap_namespace_find_name(const char *name)
 {
-	link_t *item = namespaces_list.next;
-	
-	while (item != &namespaces_list) {
-		devmap_namespace_t *namespace = list_get_instance(item, devmap_namespace_t, namespaces);
+	link_t *item;
+	for (item = namespaces_list.next; item != &namespaces_list; item = item->next) {
+		devmap_namespace_t *namespace =
+		    list_get_instance(item, devmap_namespace_t, namespaces);
 		if (str_cmp(namespace->name, name) == 0)
 			return namespace;
-		item = item->next;
 	}
 	
@@ -224,12 +235,10 @@
 static devmap_namespace_t *devmap_namespace_find_handle(dev_handle_t handle)
 {
-	link_t *item = namespaces_list.next;
-	
-	while (item != &namespaces_list) {
-		devmap_namespace_t *namespace = list_get_instance(item, devmap_namespace_t, namespaces);
+	link_t *item;
+	for (item = namespaces_list.next; item != &namespaces_list; item = item->next) {
+		devmap_namespace_t *namespace =
+		    list_get_instance(item, devmap_namespace_t, namespaces);
 		if (namespace->handle == handle)
 			return namespace;
-		
-		item = item->next;
 	}
 	
@@ -246,11 +255,11 @@
     const char *name)
 {
-	link_t *item = devices_list.next;
-	
-	while (item != &devices_list) {
-		devmap_device_t *device = list_get_instance(item, devmap_device_t, devices);
-		if ((str_cmp(device->namespace->name, ns_name) == 0) && (str_cmp(device->name, name) == 0))
+	link_t *item;
+	for (item = devices_list.next; item != &devices_list; item = item->next) {
+		devmap_device_t *device =
+		    list_get_instance(item, devmap_device_t, devices);
+		if ((str_cmp(device->namespace->name, ns_name) == 0)
+		    && (str_cmp(device->name, name) == 0))
 			return device;
-		item = item->next;
 	}
 	
@@ -268,12 +277,10 @@
 static devmap_device_t *devmap_device_find_handle(dev_handle_t handle)
 {
-	link_t *item = devices_list.next;
-	
-	while (item != &devices_list) {
-		devmap_device_t *device = list_get_instance(item, devmap_device_t, devices);
+	link_t *item;
+	for (item = devices_list.next; item != &devices_list; item = item->next) {
+		devmap_device_t *device =
+		    list_get_instance(item, devmap_device_t, devices);
 		if (device->handle == handle)
 			return device;
-		
-		item = item->next;
 	}
 	
@@ -367,5 +374,4 @@
 	list_remove(&(device->driver_devices));
 	
-	free(device->namespace);
 	free(device->name);
 	free(device);
@@ -386,6 +392,6 @@
 	}
 	
-	devmap_driver_t *driver = (devmap_driver_t *) malloc(sizeof(devmap_driver_t));
-	
+	devmap_driver_t *driver =
+	    (devmap_driver_t *) malloc(sizeof(devmap_driver_t));
 	if (driver == NULL) {
 		ipc_answer_0(iid, ENOMEM);
@@ -404,5 +410,25 @@
 	}
 	
-	/* Initialize mutex for list of devices owned by this driver */
+	/*
+	 * Create connection to the driver
+	 */
+	ipc_call_t call;
+	ipc_callid_t callid = async_get_call(&call);
+	
+	if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) {
+		free(driver->name);
+		free(driver);
+		ipc_answer_0(callid, ENOTSUP);
+		ipc_answer_0(iid, ENOTSUP);
+		return NULL;
+	}
+	
+	driver->phone = IPC_GET_ARG5(call);
+	ipc_answer_0(callid, EOK);
+	
+	/*
+	 * Initialize mutex for list of devices
+	 * owned by this driver
+	 */
 	fibril_mutex_initialize(&driver->devices_mutex);
 	
@@ -411,24 +437,4 @@
 	 */
 	list_initialize(&driver->devices);
-	
-	/*
-	 * Create connection to the driver
-	 */
-	ipc_call_t call;
-	ipc_callid_t callid = async_get_call(&call);
-	
-	if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) {
-		ipc_answer_0(callid, ENOTSUP);
-		
-		free(driver->name);
-		free(driver);
-		ipc_answer_0(iid, ENOTSUP);
-		return NULL;
-	}
-	
-	driver->phone = IPC_GET_ARG5(call);
-	
-	ipc_answer_0(callid, EOK);
-	
 	list_initialize(&(driver->drivers));
 	
@@ -436,5 +442,6 @@
 	
 	/* TODO:
-	 * check that no driver with name equal to driver->name is registered
+	 * Check that no driver with name equal to
+	 * driver->name is registered
 	 */
 	
@@ -482,5 +489,5 @@
 	fibril_mutex_unlock(&drivers_list_mutex);
 	
-	/* free name and driver */
+	/* Free name and driver */
 	if (driver->name != NULL)
 		free(driver->name);
@@ -503,5 +510,6 @@
 	
 	/* Create new device entry */
-	devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t));
+	devmap_device_t *device =
+	    (devmap_device_t *) malloc(sizeof(devmap_device_t));
 	if (device == NULL) {
 		ipc_answer_0(iid, ENOMEM);
@@ -533,6 +541,7 @@
 	devmap_namespace_t *namespace = devmap_namespace_create(ns_name);
 	free(ns_name);
-	if (!namespace) {
+	if (namespace == NULL) {
 		fibril_mutex_unlock(&devices_list_mutex);
+		free(device->name);
 		free(device);
 		ipc_answer_0(iid, ENOMEM);
@@ -545,8 +554,8 @@
 	/* Check that device is not already registered */
 	if (devmap_device_find_name(namespace->name, device->name) != NULL) {
-		printf(NAME ": Device '%s/%s' already registered\n", device->namespace, device->name);
+		printf("%s: Device '%s/%s' already registered\n", NAME,
+		    device->namespace, device->name);
 		devmap_namespace_destroy(namespace);
 		fibril_mutex_unlock(&devices_list_mutex);
-		free(device->namespace);
 		free(device->name);
 		free(device);
@@ -603,4 +612,5 @@
 	
 	if ((dev == NULL) || (dev->driver == NULL) || (dev->driver->phone == 0)) {
+		fibril_mutex_unlock(&devices_list_mutex);
 		ipc_answer_0(callid, ENOENT);
 		return;
@@ -668,7 +678,8 @@
 		return;
 	}
+	
+	ipc_answer_1(iid, EOK, dev->handle);
+	
 	fibril_mutex_unlock(&devices_list_mutex);
-	
-	ipc_answer_1(iid, EOK, dev->handle);
 	free(ns_name);
 	free(name);
@@ -719,7 +730,8 @@
 		return;
 	}
+	
+	ipc_answer_1(iid, EOK, namespace->handle);
+	
 	fibril_mutex_unlock(&devices_list_mutex);
-	
-	ipc_answer_1(iid, EOK, namespace->handle);
 	free(name);
 }
@@ -729,7 +741,9 @@
 	fibril_mutex_lock(&devices_list_mutex);
 	
-	devmap_namespace_t *namespace = devmap_namespace_find_handle(IPC_GET_ARG1(*icall));
+	devmap_namespace_t *namespace =
+	    devmap_namespace_find_handle(IPC_GET_ARG1(*icall));
 	if (namespace == NULL) {
-		devmap_device_t *dev = devmap_device_find_handle(IPC_GET_ARG1(*icall));
+		devmap_device_t *dev =
+		    devmap_device_find_handle(IPC_GET_ARG1(*icall));
 		if (dev == NULL)
 			ipc_answer_1(iid, EOK, DEV_HANDLE_NONE);
@@ -753,5 +767,6 @@
 	fibril_mutex_lock(&devices_list_mutex);
 	
-	devmap_namespace_t *namespace = devmap_namespace_find_handle(IPC_GET_ARG1(*icall));
+	devmap_namespace_t *namespace =
+	    devmap_namespace_find_handle(IPC_GET_ARG1(*icall));
 	if (namespace == NULL)
 		ipc_answer_0(iid, EEXISTS);
@@ -782,4 +797,5 @@
 	size_t count = size / sizeof(dev_desc_t);
 	if (count != list_count(&namespaces_list)) {
+		fibril_mutex_unlock(&devices_list_mutex);
 		ipc_answer_0(callid, EOVERFLOW);
 		ipc_answer_0(iid, EOVERFLOW);
@@ -789,4 +805,5 @@
 	dev_desc_t *desc = (dev_desc_t *) malloc(size);
 	if (desc == NULL) {
+		fibril_mutex_unlock(&devices_list_mutex);
 		ipc_answer_0(callid, ENOMEM);
 		ipc_answer_0(iid, ENOMEM);
@@ -794,14 +811,14 @@
 	}
 	
-	link_t *item = namespaces_list.next;
+	link_t *item;
 	size_t pos = 0;
-	while (item != &namespaces_list) {
-		devmap_namespace_t *namespace = list_get_instance(item, devmap_namespace_t, namespaces);
+	for (item = namespaces_list.next; item != &namespaces_list;
+	    item = item->next) {
+		devmap_namespace_t *namespace =
+		    list_get_instance(item, devmap_namespace_t, namespaces);
 		
 		desc[pos].handle = namespace->handle;
 		str_cpy(desc[pos].name, DEVMAP_NAME_MAXLEN, namespace->name);
 		pos++;
-		
-		item = item->next;
 	}
 	
@@ -835,5 +852,6 @@
 	fibril_mutex_lock(&devices_list_mutex);
 	
-	devmap_namespace_t *namespace = devmap_namespace_find_handle(IPC_GET_ARG1(*icall));
+	devmap_namespace_t *namespace =
+	    devmap_namespace_find_handle(IPC_GET_ARG1(*icall));
 	if (namespace == NULL) {
 		fibril_mutex_unlock(&devices_list_mutex);
@@ -845,4 +863,5 @@
 	size_t count = size / sizeof(dev_desc_t);
 	if (count != namespace->refcnt) {
+		fibril_mutex_unlock(&devices_list_mutex);
 		ipc_answer_0(callid, EOVERFLOW);
 		ipc_answer_0(iid, EOVERFLOW);
@@ -852,4 +871,5 @@
 	dev_desc_t *desc = (dev_desc_t *) malloc(size);
 	if (desc == NULL) {
+		fibril_mutex_unlock(&devices_list_mutex);
 		ipc_answer_0(callid, ENOMEM);
 		ipc_answer_0(iid, EREFUSED);
@@ -857,8 +877,9 @@
 	}
 	
-	link_t *item = devices_list.next;
+	link_t *item;
 	size_t pos = 0;
-	while (item != &devices_list) {
-		devmap_device_t *device = list_get_instance(item, devmap_device_t, devices);
+	for (item = devices_list.next; item != &devices_list; item = item->next) {
+		devmap_device_t *device =
+		    list_get_instance(item, devmap_device_t, devices);
 		
 		if (device->namespace == namespace) {
@@ -867,6 +888,4 @@
 			pos++;
 		}
-		
-		item = item->next;
 	}
 	
@@ -909,5 +928,6 @@
 	}
 	
-	devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t));
+	devmap_device_t *device =
+	    (devmap_device_t *) malloc(sizeof(devmap_device_t));
 	if (device == NULL) {
 		fibril_mutex_unlock(&null_devices_mutex);
@@ -919,5 +939,5 @@
 	
 	devmap_namespace_t *namespace = devmap_namespace_create("null");
-	if (!namespace) {
+	if (namespace == NULL) {
 		fibril_mutex_lock(&devices_list_mutex);
 		fibril_mutex_unlock(&null_devices_mutex);
@@ -949,9 +969,14 @@
 static void devmap_null_destroy(ipc_callid_t iid, ipc_call_t *icall)
 {
+	ipcarg_t i = IPC_GET_ARG1(*icall);
+	if (i >= NULL_DEVICES) {
+		ipc_answer_0(iid, ELIMIT);
+		return;
+	}
+	
 	fibril_mutex_lock(&null_devices_mutex);
 	
-	ipcarg_t i = IPC_GET_ARG1(*icall);
-	
 	if (null_devices[i] == NULL) {
+		fibril_mutex_unlock(&null_devices_mutex);
 		ipc_answer_0(iid, ENOENT);
 		return;
@@ -965,5 +990,4 @@
 	
 	fibril_mutex_unlock(&null_devices_mutex);
-	
 	ipc_answer_0(iid, EOK);
 }
@@ -1121,8 +1145,8 @@
 int main(int argc, char *argv[])
 {
-	printf(NAME ": HelenOS Device Mapper\n");
+	printf("%s: HelenOS Device Mapper\n", NAME);
 	
 	if (!devmap_init()) {
-		printf(NAME ": Error while initializing service\n");
+		printf("%s: Error while initializing service\n", NAME);
 		return -1;
 	}
@@ -1136,5 +1160,5 @@
 		return -1;
 	
-	printf(NAME ": Accepting connections\n");
+	printf("%s: Accepting connections\n", NAME);
 	async_manager();
 	
Index: uspace/srv/hid/console/Makefile
===================================================================
--- uspace/srv/hid/console/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/console/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -33,5 +33,4 @@
 GENERIC_SOURCES = \
 	console.c \
-	screenbuffer.c \
 	keybuffer.c \
 	gcons.c
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/console/console.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -54,9 +54,11 @@
 #include <vfs/vfs.h>
 #include <fibril_synch.h>
+#include <io/style.h>
+#include <io/screenbuffer.h>
 
 #include "console.h"
 #include "gcons.h"
 #include "keybuffer.h"
-#include "screenbuffer.h"
+
 
 #define NAME       "console"
@@ -71,8 +73,8 @@
 /** Information about framebuffer */
 struct {
-	int phone;      /**< Framebuffer phone */
-	ipcarg_t cols;  /**< Framebuffer columns */
-	ipcarg_t rows;  /**< Framebuffer rows */
-	int color_cap;  /**< Color capabilities (FB_CCAP_xxx) */
+	int phone;           /**< Framebuffer phone */
+	ipcarg_t cols;       /**< Framebuffer columns */
+	ipcarg_t rows;       /**< Framebuffer rows */
+	ipcarg_t color_cap;  /**< Color capabilities (FB_CCAP_xxx) */
 } fb_info;
 
@@ -99,7 +101,7 @@
 /** Information on row-span yet unsent to FB driver. */
 struct {
-	size_t col;  /**< Leftmost column of the span. */
-	size_t row;  /**< Row where the span lies. */
-	size_t cnt;  /**< Width of the span. */
+	ipcarg_t col;  /**< Leftmost column of the span. */
+	ipcarg_t row;  /**< Row where the span lies. */
+	ipcarg_t cnt;  /**< Width of the span. */
 } fb_pending;
 
@@ -117,5 +119,5 @@
 }
 
-static void curs_goto(size_t x, size_t y)
+static void curs_goto(ipcarg_t x, ipcarg_t y)
 {
 	async_msg_2(fb_info.phone, FB_CURSOR_GOTO, x, y);
@@ -147,15 +149,15 @@
 }
 
-static void set_style(int style)
+static void set_style(uint8_t style)
 {
 	async_msg_1(fb_info.phone, FB_SET_STYLE, style);
 }
 
-static void set_color(int fgcolor, int bgcolor, int flags)
+static void set_color(uint8_t fgcolor, uint8_t bgcolor, uint8_t flags)
 {
 	async_msg_3(fb_info.phone, FB_SET_COLOR, fgcolor, bgcolor, flags);
 }
 
-static void set_rgb_color(int fgcolor, int bgcolor)
+static void set_rgb_color(uint32_t fgcolor, uint32_t bgcolor)
 {
 	async_msg_2(fb_info.phone, FB_SET_RGB_COLOR, fgcolor, bgcolor); 
@@ -178,14 +180,23 @@
 }
 
-static int ccap_fb_to_con(int ccap_fb, int *ccap_con)
+static int ccap_fb_to_con(ipcarg_t ccap_fb, ipcarg_t *ccap_con)
 {
 	switch (ccap_fb) {
-	case FB_CCAP_NONE: *ccap_con = CONSOLE_CCAP_NONE; break;
-	case FB_CCAP_STYLE: *ccap_con = CONSOLE_CCAP_STYLE; break;
-	case FB_CCAP_INDEXED: *ccap_con = CONSOLE_CCAP_INDEXED; break;
-	case FB_CCAP_RGB: *ccap_con = CONSOLE_CCAP_RGB; break;
-	default: return EINVAL;
-	}
-
+	case FB_CCAP_NONE:
+		*ccap_con = CONSOLE_CCAP_NONE;
+		break;
+	case FB_CCAP_STYLE:
+		*ccap_con = CONSOLE_CCAP_STYLE;
+		break;
+	case FB_CCAP_INDEXED:
+		*ccap_con = CONSOLE_CCAP_INDEXED;
+		break;
+	case FB_CCAP_RGB:
+		*ccap_con = CONSOLE_CCAP_RGB;
+		break;
+	default:
+		return EINVAL;
+	}
+	
 	return EOK;
 }
@@ -226,5 +237,5 @@
  *
  */
-static void cell_mark_changed(size_t col, size_t row)
+static void cell_mark_changed(ipcarg_t col, ipcarg_t row)
 {
 	if (fb_pending.cnt != 0) {
@@ -253,5 +264,5 @@
 {
 	bool flush_cursor = false;
-
+	
 	switch (ch) {
 	case '\n':
@@ -297,5 +308,5 @@
 			async_msg_1(fb_info.phone, FB_SCROLL, 1);
 	}
-
+	
 	if (cons == active_console && flush_cursor)
 		curs_goto(cons->scr.position_x, cons->scr.position_y);
@@ -327,8 +338,4 @@
 	
 	if (cons != kernel_console) {
-		size_t x;
-		size_t y;
-		int rc = 0;
-		
 		async_serialize_start();
 		
@@ -344,4 +351,9 @@
 		set_attrs(&cons->scr.attrs);
 		curs_visibility(false);
+		
+		ipcarg_t x;
+		ipcarg_t y;
+		int rc = 0;
+		
 		if (interbuffer) {
 			for (y = 0; y < cons->scr.size_y; y++) {
@@ -390,5 +402,4 @@
 	/* Ignore parameters, the connection is already opened */
 	while (true) {
-		
 		ipc_call_t call;
 		ipc_callid_t callid = async_get_call(&call);
@@ -433,16 +444,11 @@
 static void mouse_events(ipc_callid_t iid, ipc_call_t *icall)
 {
-	int button, press;
-	int dx, dy;
-	int newcon;
-
 	/* Ignore parameters, the connection is already opened */
 	while (true) {
-
 		ipc_call_t call;
 		ipc_callid_t callid = async_get_call(&call);
-
+		
 		int retval;
-
+		
 		switch (IPC_GET_METHOD(call)) {
 		case IPC_M_PHONE_HUNGUP:
@@ -450,8 +456,6 @@
 			return;
 		case MEVENT_BUTTON:
-			button = IPC_GET_ARG1(call);
-			press = IPC_GET_ARG2(call);
-			if (button == 1) {
-				newcon = gcons_mouse_btn(press);
+			if (IPC_GET_ARG1(call) == 1) {
+				int newcon = gcons_mouse_btn((bool) IPC_GET_ARG2(call));
 				if (newcon != -1)
 					change_console(&consoles[newcon]);
@@ -460,7 +464,6 @@
 			break;
 		case MEVENT_MOVE:
-			dx = IPC_GET_ARG1(call);
-			dy = IPC_GET_ARG2(call);
-			gcons_mouse_move(dx, dy);
+			gcons_mouse_move((int) IPC_GET_ARG1(call),
+			    (int) IPC_GET_ARG2(call));
 			retval = 0;
 			break;
@@ -520,4 +523,5 @@
 	console_event_t ev;
 	fibril_mutex_lock(&input_mutex);
+	
 recheck:
 	while ((keybuffer_pop(&cons->keybuffer, &ev)) && (pos < size)) {
@@ -536,4 +540,5 @@
 		goto recheck;
 	}
+	
 	fibril_mutex_unlock(&input_mutex);
 }
@@ -542,6 +547,7 @@
 {
 	console_event_t ev;
-
+	
 	fibril_mutex_lock(&input_mutex);
+	
 recheck:
 	if (keybuffer_pop(&cons->keybuffer, &ev)) {
@@ -551,4 +557,5 @@
 		goto recheck;
 	}
+	
 	fibril_mutex_unlock(&input_mutex);
 }
@@ -580,6 +587,5 @@
 	ipcarg_t arg2;
 	ipcarg_t arg3;
-
-	int cons_ccap;
+	
 	int rc;
 	
@@ -622,5 +628,4 @@
 			if (cons == active_console) {
 				async_req_0_0(fb_info.phone, FB_FLUSH);
-				
 				curs_goto(cons->scr.position_x, cons->scr.position_y);
 			}
@@ -650,10 +655,9 @@
 			break;
 		case CONSOLE_GET_COLOR_CAP:
-			rc = ccap_fb_to_con(fb_info.color_cap, &cons_ccap);
+			rc = ccap_fb_to_con(fb_info.color_cap, &arg1);
 			if (rc != EOK) {
 				ipc_answer_0(callid, rc);
 				continue;
 			}
-			arg1 = cons_ccap;
 			break;
 		case CONSOLE_SET_STYLE:
@@ -714,5 +718,5 @@
 		return false;
 	}
-
+	
 	kbd_phone = fd_phone(input_fd);
 	if (kbd_phone < 0) {
@@ -720,5 +724,5 @@
 		return false;
 	}
-
+	
 	/* NB: The callback connection is slotted for removal */
 	ipcarg_t phonehash;
@@ -727,16 +731,16 @@
 		return false;
 	}
-
+	
 	async_new_connection(phonehash, 0, NULL, keyboard_events);
-
+	
 	/* Connect to mouse device */
 	mouse_phone = -1;
 	int mouse_fd = open("/dev/hid_in/mouse", O_RDONLY);
-
+	
 	if (mouse_fd < 0) {
 		printf(NAME ": Notice - failed opening %s\n", "/dev/hid_in/mouse");
 		goto skip_mouse;
 	}
-
+	
 	mouse_phone = fd_phone(mouse_fd);
 	if (mouse_phone < 0) {
@@ -744,5 +748,5 @@
 		goto skip_mouse;
 	}
-
+	
 	if (ipc_connect_to_me(mouse_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) {
 		printf(NAME ": Failed to create callback from mouse device\n");
@@ -750,8 +754,8 @@
 		goto skip_mouse;
 	}
-
+	
 	async_new_connection(phonehash, 0, NULL, mouse_events);
 skip_mouse:
-
+	
 	/* Connect to framebuffer driver */
 	fb_info.phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VIDEO, 0, 0);
@@ -760,5 +764,5 @@
 		return -1;
 	}
-
+	
 	/* Register driver */
 	int rc = devmap_driver_register(NAME, client_connection);
@@ -772,9 +776,7 @@
 	
 	/* Synchronize, the gcons could put something in queue */
-	ipcarg_t color_cap;
 	async_req_0_0(fb_info.phone, FB_FLUSH);
 	async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.cols, &fb_info.rows);
-	async_req_0_1(fb_info.phone, FB_GET_COLOR_CAP, &color_cap);
-	fb_info.color_cap = color_cap;
+	async_req_0_1(fb_info.phone, FB_GET_COLOR_CAP, &fb_info.color_cap);
 	
 	/* Set up shared memory buffer. */
@@ -827,5 +829,5 @@
 	async_serialize_start();
 	gcons_redraw_console();
-	set_rgb_color(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
+	set_style(STYLE_NORMAL);
 	screen_clear();
 	curs_goto(0, 0);
Index: uspace/srv/hid/console/gcons.c
===================================================================
--- uspace/srv/hid/console/gcons.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/console/gcons.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -54,5 +54,30 @@
 #define STATUS_HEIGHT  48
 
-#define MAIN_COLOR  0xffffff
+#define COLOR_MAIN        0xffffff
+#define COLOR_FOREGROUND  0x202020
+#define COLOR_BACKGROUND  0xffffff
+
+extern char _binary_gfx_helenos_ppm_start[0];
+extern int _binary_gfx_helenos_ppm_size;
+extern char _binary_gfx_nameic_ppm_start[0];
+extern int _binary_gfx_nameic_ppm_size;
+
+extern char _binary_gfx_anim_1_ppm_start[0];
+extern int _binary_gfx_anim_1_ppm_size;
+extern char _binary_gfx_anim_2_ppm_start[0];
+extern int _binary_gfx_anim_2_ppm_size;
+extern char _binary_gfx_anim_3_ppm_start[0];
+extern int _binary_gfx_anim_3_ppm_size;
+extern char _binary_gfx_anim_4_ppm_start[0];
+extern int _binary_gfx_anim_4_ppm_size;
+
+extern char _binary_gfx_cons_selected_ppm_start[0];
+extern int _binary_gfx_cons_selected_ppm_size;
+extern char _binary_gfx_cons_idle_ppm_start[0];
+extern int _binary_gfx_cons_idle_ppm_size;
+extern char _binary_gfx_cons_has_data_ppm_start[0];
+extern int _binary_gfx_cons_has_data_ppm_size;
+extern char _binary_gfx_cons_kernel_ppm_start[0];
+extern int _binary_gfx_cons_kernel_ppm_size;
 
 static bool use_gcons = false;
@@ -82,10 +107,10 @@
 static size_t active_console = 0;
 
-size_t mouse_x;
-size_t mouse_y;
-
-bool btn_pressed;
-size_t btn_x;
-size_t btn_y;
+static ipcarg_t mouse_x = 0;
+static ipcarg_t mouse_y= 0;
+
+static bool btn_pressed = false;
+static ipcarg_t btn_x = 0;
+static ipcarg_t btn_y = 0;
 
 static void vp_switch(int vp)
@@ -95,5 +120,5 @@
 
 /** Create view port */
-static int vp_create(size_t x, size_t y, size_t width, size_t height)
+static int vp_create(ipcarg_t x, ipcarg_t y, ipcarg_t width, ipcarg_t height)
 {
 	return async_req_2_0(fbphone, FB_VIEWPORT_CREATE, (x << 16) | y,
@@ -112,5 +137,5 @@
 
 /** Transparent putchar */
-static void tran_putch(wchar_t ch, size_t col, size_t row)
+static void tran_putch(wchar_t ch, ipcarg_t col, ipcarg_t row)
 {
 	async_msg_3(fbphone, FB_PUTCHAR, ch, col, row);
@@ -259,14 +284,17 @@
 void gcons_mouse_move(ssize_t dx, ssize_t dy)
 {
-	mouse_x = limit(mouse_x + dx, 0, xres);
-	mouse_y = limit(mouse_y + dy, 0, yres);
-
+	ssize_t nx = (ssize_t) mouse_x + dx;
+	ssize_t ny = (ssize_t) mouse_y + dy;
+	
+	mouse_x = (size_t) limit(nx, 0, xres);
+	mouse_y = (size_t) limit(ny, 0, yres);
+	
 	if (active_console != KERNEL_CONSOLE)
 		async_msg_2(fbphone, FB_POINTER_MOVE, mouse_x, mouse_y);
 }
 
-static int gcons_find_conbut(int x, int y)
-{
-	int status_start = STATUS_START + (xres - 800) / 2;
+static int gcons_find_conbut(ipcarg_t x, ipcarg_t y)
+{
+	ipcarg_t status_start = STATUS_START + (xres - 800) / 2;
 	
 	if ((y < STATUS_TOP) || (y >= STATUS_TOP + STATUS_HEIGHT))
@@ -278,8 +306,14 @@
 	if (x >= status_start + (STATUS_WIDTH + STATUS_SPACE) * CONSOLE_COUNT)
 		return -1;
+	
 	if (((x - status_start) % (STATUS_WIDTH + STATUS_SPACE)) < STATUS_SPACE)
 		return -1;
 	
-	return (x - status_start) / (STATUS_WIDTH + STATUS_SPACE);
+	ipcarg_t btn = (x - status_start) / (STATUS_WIDTH + STATUS_SPACE);
+	
+	if (btn < CONSOLE_COUNT)
+		return btn;
+	
+	return -1;
 }
 
@@ -287,11 +321,15 @@
  *
  * @param state New state (true - pressed, false - depressed)
+ *
  */
 int gcons_mouse_btn(bool state)
 {
-	int conbut;
+	/* Ignore mouse clicks if no buttons
+	   are drawn at all */
+	if (xres < 800)
+		return -1;
 	
 	if (state) {
-		conbut = gcons_find_conbut(mouse_x, mouse_y);
+		int conbut = gcons_find_conbut(mouse_x, mouse_y);
 		if (conbut != -1) {
 			btn_pressed = true;
@@ -307,5 +345,5 @@
 	btn_pressed = false;
 	
-	conbut = gcons_find_conbut(mouse_x, mouse_y);
+	int conbut = gcons_find_conbut(mouse_x, mouse_y);
 	if (conbut == gcons_find_conbut(btn_x, btn_y))
 		return conbut;
@@ -313,5 +351,4 @@
 	return -1;
 }
-
 
 /** Draw a PPM pixmap to framebuffer
@@ -321,12 +358,10 @@
  * @param x Coordinate of upper left corner
  * @param y Coordinate of upper left corner
- */
-static void draw_pixmap(char *logo, size_t size, int x, int y)
-{
-	char *shm;
-	int rc;
-	
+ *
+ */
+static void draw_pixmap(char *logo, size_t size, ipcarg_t x, ipcarg_t y)
+{
 	/* Create area */
-	shm = mmap(NULL, size, PROTO_READ | PROTO_WRITE, MAP_SHARED |
+	char *shm = mmap(NULL, size, PROTO_READ | PROTO_WRITE, MAP_SHARED |
 	    MAP_ANONYMOUS, 0, 0);
 	if (shm == MAP_FAILED)
@@ -336,5 +371,5 @@
 	
 	/* Send area */
-	rc = async_req_1_0(fbphone, FB_PREPARE_SHM, (ipcarg_t) shm);
+	int rc = async_req_1_0(fbphone, FB_PREPARE_SHM, (ipcarg_t) shm);
 	if (rc)
 		goto exit;
@@ -356,19 +391,12 @@
 }
 
-extern char _binary_gfx_helenos_ppm_start[0];
-extern int _binary_gfx_helenos_ppm_size;
-extern char _binary_gfx_nameic_ppm_start[0];
-extern int _binary_gfx_nameic_ppm_size;
-
 /** Redraws console graphics */
 void gcons_redraw_console(void)
 {
-	int i;
-	
 	if (!use_gcons)
 		return;
 	
 	vp_switch(0);
-	set_rgb_color(MAIN_COLOR, MAIN_COLOR);
+	set_rgb_color(COLOR_MAIN, COLOR_MAIN);
 	clear();
 	draw_pixmap(_binary_gfx_helenos_ppm_start,
@@ -377,4 +405,5 @@
 	    (size_t) &_binary_gfx_nameic_ppm_size, 5, 17);
 	
+	unsigned int i;
 	for (i = 0; i < CONSOLE_COUNT; i++)
 		redraw_state(i);
@@ -393,10 +422,6 @@
 static int make_pixmap(char *data, size_t size)
 {
-	char *shm;
-	int rc;
-	int pxid = -1;
-	
 	/* Create area */
-	shm = mmap(NULL, size, PROTO_READ | PROTO_WRITE, MAP_SHARED |
+	char *shm = mmap(NULL, size, PROTO_READ | PROTO_WRITE, MAP_SHARED |
 	    MAP_ANONYMOUS, 0, 0);
 	if (shm == MAP_FAILED)
@@ -405,6 +430,8 @@
 	memcpy(shm, data, size);
 	
+	int pxid = -1;
+	
 	/* Send area */
-	rc = async_req_1_0(fbphone, FB_PREPARE_SHM, (ipcarg_t) shm);
+	int rc = async_req_1_0(fbphone, FB_PREPARE_SHM, (ipcarg_t) shm);
 	if (rc)
 		goto exit;
@@ -432,16 +459,8 @@
 }
 
-extern char _binary_gfx_anim_1_ppm_start[0];
-extern int _binary_gfx_anim_1_ppm_size;
-extern char _binary_gfx_anim_2_ppm_start[0];
-extern int _binary_gfx_anim_2_ppm_size;
-extern char _binary_gfx_anim_3_ppm_start[0];
-extern int _binary_gfx_anim_3_ppm_size;
-extern char _binary_gfx_anim_4_ppm_start[0];
-extern int _binary_gfx_anim_4_ppm_size;
-
 static void make_anim(void)
 {
-	int an = async_req_1_0(fbphone, FB_ANIM_CREATE, cstatus_vp[KERNEL_CONSOLE]);
+	int an = async_req_1_0(fbphone, FB_ANIM_CREATE,
+	    cstatus_vp[KERNEL_CONSOLE]);
 	if (an < 0)
 		return;
@@ -467,13 +486,4 @@
 	animation = an;
 }
-
-extern char _binary_gfx_cons_selected_ppm_start[0];
-extern int _binary_gfx_cons_selected_ppm_size;
-extern char _binary_gfx_cons_idle_ppm_start[0];
-extern int _binary_gfx_cons_idle_ppm_size;
-extern char _binary_gfx_cons_has_data_ppm_start[0];
-extern int _binary_gfx_cons_has_data_ppm_size;
-extern char _binary_gfx_cons_kernel_ppm_start[0];
-extern int _binary_gfx_cons_kernel_ppm_size;
 
 /** Initialize nice graphical console environment */
@@ -500,5 +510,5 @@
 	
 	/* Create status buttons */
-	size_t status_start = STATUS_START + (xres - 800) / 2;
+	ipcarg_t status_start = STATUS_START + (xres - 800) / 2;
 	size_t i;
 	for (i = 0; i < CONSOLE_COUNT; i++) {
@@ -511,5 +521,5 @@
 		
 		vp_switch(cstatus_vp[i]);
-		set_rgb_color(0x202020, 0xffffff);
+		set_rgb_color(COLOR_FOREGROUND, COLOR_BACKGROUND);
 	}
 	
Index: uspace/srv/hid/console/gcons.h
===================================================================
--- uspace/srv/hid/console/gcons.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/console/gcons.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -38,15 +38,15 @@
 #include <sys/types.h>
 
-void gcons_init(int phone);
+void gcons_init(int);
 
 void gcons_redraw_console(void);
-void gcons_change_console(size_t index);
-void gcons_notify_char(size_t index);
+void gcons_change_console(size_t);
+void gcons_notify_char(size_t);
 void gcons_in_kernel(void);
 
-void gcons_notify_connect(size_t index);
-void gcons_notify_disconnect(size_t index);
+void gcons_notify_connect(size_t);
+void gcons_notify_disconnect(size_t);
 
-void gcons_mouse_move(ssize_t dx, ssize_t dy);
+void gcons_mouse_move(ssize_t, ssize_t);
 int gcons_mouse_btn(bool state);
 
Index: uspace/srv/hid/console/keybuffer.h
===================================================================
--- uspace/srv/hid/console/keybuffer.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/console/keybuffer.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -47,7 +47,7 @@
 typedef struct {
 	console_event_t fifo[KEYBUFFER_SIZE];
-	unsigned long head;
-	unsigned long tail;
-	unsigned long items;
+	size_t head;
+	size_t tail;
+	size_t items;
 } keybuffer_t;
 
Index: pace/srv/hid/console/screenbuffer.c
===================================================================
--- uspace/srv/hid/console/screenbuffer.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,191 +1,0 @@
-/*
- * Copyright (c) 2006 Josef Cejka
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup console
- * @{
- */
-/** @file
- */
-
-#include <io/style.h>
-#include <malloc.h>
-#include <unistd.h>
-#include "screenbuffer.h"
-
-/** Store one character to screenbuffer.
- *
- * Its position is determined by scr->position_x
- * and scr->position_y.
- *
- * @param scr Screenbuffer
- * @param c   Stored character
- *
- */
-void screenbuffer_putchar(screenbuffer_t *scr, wchar_t ch)
-{
-	keyfield_t *field =
-	    get_field_at(scr, scr->position_x, scr->position_y);
-	
-	field->character = ch;
-	field->attrs = scr->attrs;
-}
-
-/** Initilize screenbuffer.
- *
- * Allocate space for screen content in accordance to given size.
- *
- * @param scr    Initialized screenbuffer
- * @param size_x Width in characters
- * @param size_y Height in characters
- *
- * @return Pointer to screenbuffer (same as scr parameter) or NULL
- *
- */
-screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, size_t size_x, size_t size_y)
-{
-	scr->buffer = (keyfield_t *) malloc(sizeof(keyfield_t) * size_x * size_y);
-	if (!scr->buffer)
-		return NULL;
-	
-	scr->size_x = size_x;
-	scr->size_y = size_y;
-	scr->attrs.t = at_style;
-	scr->attrs.a.s.style = STYLE_NORMAL;
-	scr->is_cursor_visible = 1;
-	
-	screenbuffer_clear(scr);
-	
-	return scr;
-}
-
-/** Clear screenbuffer.
- *
- * @param scr Screenbuffer
- *
- */
-void screenbuffer_clear(screenbuffer_t *scr)
-{
-	size_t i;
-	
-	for (i = 0; i < (scr->size_x * scr->size_y); i++) {
-		scr->buffer[i].character = ' ';
-		scr->buffer[i].attrs = scr->attrs;
-	}
-	
-	scr->top_line = 0;
-	scr->position_x = 0;
-	scr->position_y = 0;
-}
-
-/** Clear one buffer line.
- *
- * @param scr
- * @param line One buffer line (not a screen line!)
- *
- */
-void screenbuffer_clear_line(screenbuffer_t *scr, size_t line)
-{
-	size_t x;
-	
-	for (x = 0; x < scr->size_x; x++) {
-		scr->buffer[x + line * scr->size_x].character = ' ';
-		scr->buffer[x + line * scr->size_x].attrs = scr->attrs;
-	}
-}
-
-/** Copy content buffer from screenbuffer to given memory.
- *
- * @param scr  Source screenbuffer
- * @param dest Destination
- *
- */
-void screenbuffer_copy_buffer(screenbuffer_t *scr, keyfield_t *dest)
-{
-	size_t i;
-	
-	for (i = 0; i < (scr->size_x * scr->size_y); i++)
-		dest[i] = scr->buffer[i];
-}
-
-/** Set new cursor position in screenbuffer.
- *
- * @param scr
- * @param x
- * @param y
- *
- */
-void screenbuffer_goto(screenbuffer_t *scr, size_t x, size_t y)
-{
-	scr->position_x = x % scr->size_x;
-	scr->position_y = y % scr->size_y;
-}
-
-/** Set new style.
- *
- * @param scr
- * @param fg_color
- * @param bg_color
- *
- */
-void screenbuffer_set_style(screenbuffer_t *scr, uint8_t style)
-{
-	scr->attrs.t = at_style;
-	scr->attrs.a.s.style = style;
-}
-
-/** Set new color.
- *
- * @param scr
- * @param fg_color
- * @param bg_color
- *
- */
-void screenbuffer_set_color(screenbuffer_t *scr, uint8_t fg_color, uint8_t bg_color, uint8_t flags)
-{
-	scr->attrs.t = at_idx;
-	scr->attrs.a.i.fg_color = fg_color;
-	scr->attrs.a.i.bg_color = bg_color;
-	scr->attrs.a.i.flags = flags;
-}
-
-/** Set new RGB color.
- *
- * @param scr
- * @param fg_color
- * @param bg_color
- *
- */
-void screenbuffer_set_rgb_color(screenbuffer_t *scr, uint32_t fg_color, uint32_t bg_color)
-{
-	scr->attrs.t = at_rgb;
-	scr->attrs.a.r.fg_color = fg_color;
-	scr->attrs.a.r.bg_color = bg_color;
-}
-
-/** @}
- */
Index: pace/srv/hid/console/screenbuffer.h
===================================================================
--- uspace/srv/hid/console/screenbuffer.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,159 +1,0 @@
-/*
- * Copyright (c) 2006 Josef Cejka
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup console
- * @{
- */
-/** @file
- */
-
-#ifndef SCREENBUFFER_H__
-#define SCREENBUFFER_H__
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <bool.h>
-
-#define DEFAULT_FOREGROUND  0x0       /**< default console foreground color */
-#define DEFAULT_BACKGROUND  0xf0f0f0  /**< default console background color */
-
-typedef struct {
-	uint8_t style;
-} attr_style_t;
-
-typedef struct {
-	uint8_t fg_color;
-	uint8_t bg_color;
-	uint8_t flags;
-} attr_idx_t;
-
-typedef struct {
-	uint32_t bg_color;  /**< background color */
-	uint32_t fg_color;  /**< foreground color */
-} attr_rgb_t;
-
-typedef struct {
-	enum {
-		at_style,
-		at_idx,
-		at_rgb
-	} t;
-	union {
-		attr_style_t s;
-		attr_idx_t i;
-		attr_rgb_t r;
-	} a;
-} attrs_t;
-
-/** One field on screen. It contain one character and its attributes. */
-typedef struct {
-	wchar_t character;  /**< Character itself */
-	attrs_t attrs;      /**< Character attributes */
-} keyfield_t;
-
-/** Structure for buffering state of one virtual console.
- */
-typedef struct {
-	keyfield_t *buffer;      /**< Screen content - characters and
-	                              their attributes (used as a circular buffer) */
-	size_t size_x;           /**< Number of columns  */
-	size_t size_y;           /**< Number of rows */
-	
-	/** Coordinates of last printed character for determining cursor position */
-	size_t position_x;
-	size_t position_y;
-	
-	attrs_t attrs;           /**< Current attributes. */
-	size_t top_line;         /**< Points to buffer[][] line that will
-	                              be printed at screen as the first line */
-	bool is_cursor_visible;  /**< Cursor state - default is visible */
-} screenbuffer_t;
-
-/** Returns keyfield for position on screen
- *
- * Screenbuffer->buffer is cyclic buffer so we
- * must couted in index of the topmost line.
- *
- * @param scr Screenbuffer
- * @param x   Position on screen
- * @param y   Position on screen
- *
- * @return Keyfield structure with character and its attributes on x, y
- *
- */
-static inline keyfield_t *get_field_at(screenbuffer_t *scr, size_t x, size_t y)
-{
-	return scr->buffer + x + ((y + scr->top_line) % scr->size_y) * scr->size_x;
-}
-
-/** Compares two sets of attributes.
- *
- * @param s1 First style
- * @param s2 Second style
- *
- * @return Nonzero on equality
- *
- */
-static inline int attrs_same(attrs_t a1, attrs_t a2)
-{
-	if (a1.t != a2.t)
-		return 0;
-	
-	switch (a1.t) {
-	case at_style:
-		return (a1.a.s.style == a2.a.s.style);
-	case at_idx:
-		return (a1.a.i.fg_color == a2.a.i.fg_color)
-		    && (a1.a.i.bg_color == a2.a.i.bg_color)
-		    && (a1.a.i.flags == a2.a.i.flags);
-	case at_rgb:
-		return (a1.a.r.fg_color == a2.a.r.fg_color)
-		    && (a1.a.r.bg_color == a2.a.r.bg_color);
-	}
-	
-	return 0;
-}
-
-
-void screenbuffer_putchar(screenbuffer_t *scr, wchar_t c);
-screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, size_t size_x, size_t size_y);
-
-void screenbuffer_clear(screenbuffer_t *scr);
-void screenbuffer_clear_line(screenbuffer_t *scr, size_t line);
-void screenbuffer_copy_buffer(screenbuffer_t *scr, keyfield_t *dest);
-void screenbuffer_goto(screenbuffer_t *scr, size_t x, size_t y);
-void screenbuffer_set_style(screenbuffer_t *scr, uint8_t style);
-void screenbuffer_set_color(screenbuffer_t *scr, uint8_t fg_color,
-    uint8_t bg_color, uint8_t attr);
-void screenbuffer_set_rgb_color(screenbuffer_t *scr, uint32_t fg_color,
-    uint32_t bg_color);
-
-#endif
-
-/** @}
- */
Index: uspace/srv/hid/fb/Makefile
===================================================================
--- uspace/srv/hid/fb/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/fb/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -29,5 +29,13 @@
 
 USPACE_PREFIX = ../../..
+ROOT_PATH = $(USPACE_PREFIX)/..
+
+COMMON_MAKEFILE = $(ROOT_PATH)/Makefile.common
+CONFIG_MAKEFILE = $(ROOT_PATH)/Makefile.config
+
 BINARY = fb
+
+-include $(COMMON_MAKEFILE)
+-include $(CONFIG_MAKEFILE)
 
 SOURCES = \
@@ -36,43 +44,50 @@
 
 ifneq ($(UARCH),ia64)
-	SOURCES += fb.c \
+	SOURCES += \
+		fb.c \
 		font-8x16.c
-	EXTRA_CFLAGS = -DFB_ENABLED
+	EXTRA_CFLAGS += -DFB_ENABLED
 endif
 
 ifeq ($(UARCH),ia32)
-	SOURCES += ega.c
-	EXTRA_CFLAGS = -DEGA_ENABLED
+	SOURCES += \
+		ega.c
+	EXTRA_CFLAGS += -DEGA_ENABLED
 endif
 
 ifeq ($(UARCH),ia64)
-	SOURCES += ega.c \
+	SOURCES += \
+		ega.c \
 		ski.c \
 		serial_console.c
-	EXTRA_CFLAGS = -DSKI_ENABLED -DEGA_ENABLED
+	EXTRA_CFLAGS += -DSKI_ENABLED -DEGA_ENABLED
 endif
 
 ifeq ($(UARCH),amd64)
-	SOURCES += ega.c
-	EXTRA_CFLAGS = -DEGA_ENABLED
+	SOURCES += \
+		ega.c
+	EXTRA_CFLAGS += -DEGA_ENABLED
 endif
 
 ifeq ($(UARCH),mips32)
-	SOURCES += msim.c \
+	SOURCES += \
+		msim.c \
 		serial_console.c
-	EXTRA_CFLAGS = -DMSIM_ENABLED
+	EXTRA_CFLAGS += -DMSIM_ENABLED
 endif
 
 ifeq ($(UARCH),sparc64)
-	ifeq ($(PROCESSOR), sun4v)
-		SOURCES += niagara.c \
+	ifeq ($(PROCESSOR),sun4v)
+		SOURCES += \
+			niagara.c \
 			serial_console.c
-		EXTRA_CFLAGS = -DNIAGARA_ENABLED
+		EXTRA_CFLAGS += -DNIAGARA_ENABLED
 	endif
-
-	ifeq ($(MACHINE), serengeti)
-		SOURCES += sgcn.c \
+	
+	ifeq ($(MACHINE),serengeti)
+		SOURCES += \
+			sgcn.c \
 			serial_console.c
-		EXTRA_CFLAGS = -DSGCN_ENABLED
+		EXTRA_CFLAGS += -DSGCN_ENABLED
 	endif
 endif
Index: uspace/srv/hid/fb/ega.c
===================================================================
--- uspace/srv/hid/fb/ega.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/fb/ega.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -28,8 +28,8 @@
 
 /** @defgroup egafb EGA framebuffer
- * @brief	HelenOS EGA framebuffer.
+ * @brief HelenOS EGA framebuffer.
  * @ingroup fbs
  * @{
- */ 
+ */
 /** @file
  */
@@ -52,11 +52,12 @@
 #include <io/style.h>
 #include <io/color.h>
+#include <io/screenbuffer.h>
 #include <sys/types.h>
 
 #include "ega.h"
-#include "../console/screenbuffer.h"
 #include "main.h"
 
-#define MAX_SAVED_SCREENS 256
+#define MAX_SAVED_SCREENS  256
+
 typedef struct saved_screen {
 	short *data;
@@ -65,24 +66,70 @@
 saved_screen saved_screens[MAX_SAVED_SCREENS];
 
-#define EGA_IO_BASE ((ioport8_t *) 0x3d4)
-#define EGA_IO_SIZE 2
-
-int ega_normal_color = 0x0f;
-int ega_inverted_color = 0xf0;
-
-#define NORMAL_COLOR		ega_normal_color
-#define INVERTED_COLOR		ega_inverted_color
+#define EGA_IO_BASE  ((ioport8_t *) 0x3d4)
+#define EGA_IO_SIZE  2
 
 /* Allow only 1 connection */
 static int client_connected = 0;
 
-static unsigned int scr_width;
-static unsigned int scr_height;
+static sysarg_t scr_width;
+static sysarg_t scr_height;
 static uint8_t *scr_addr;
 
-static unsigned int style;
-
-static unsigned attr_to_ega_style(const attrs_t *a);
-static uint8_t ega_glyph(wchar_t ch);
+static uint8_t style_normal = 0xf0;
+static uint8_t style_inverted = 0x0f;
+static uint8_t style;
+
+static uint8_t style_to_ega_style(uint8_t style)
+{
+	switch (style) {
+	case STYLE_EMPHASIS:
+		return (style_normal | 0x04);
+	case STYLE_SELECTED:
+		return (style_inverted | 0x40);
+	case STYLE_INVERTED:
+		return style_inverted;
+	}
+	
+	return style_normal;
+}
+
+static uint8_t color_to_ega_style(uint8_t fg_color, uint8_t bg_color,
+    uint8_t attr)
+{
+	uint8_t style = (fg_color & 7) | ((bg_color & 7) << 4);
+	
+	if (attr & CATTR_BRIGHT)
+		style |= 0x08;
+	
+	return style;
+}
+
+static uint8_t rgb_to_ega_style(uint32_t fg, uint32_t bg)
+{
+	return (fg > bg) ? style_inverted : style_normal;
+}
+
+static uint8_t attr_to_ega_style(const attrs_t *attr)
+{
+	switch (attr->t) {
+	case at_style:
+		return style_to_ega_style(attr->a.s.style);
+	case at_idx:
+		return color_to_ega_style(attr->a.i.fg_color,
+		    attr->a.i.bg_color, attr->a.i.flags);
+	case at_rgb:
+		return rgb_to_ega_style(attr->a.r.fg_color, attr->a.r.bg_color);
+	default:
+		return style_normal;
+	}
+}
+
+static uint8_t ega_glyph(wchar_t ch)
+{
+	if (ch >= 0 && ch < 128)
+		return ch;
+	
+	return '?';
+}
 
 static void clrscr(void)
@@ -96,22 +143,20 @@
 }
 
-static void cursor_goto(unsigned int col, unsigned int row)
-{
-	int ega_cursor;
-
-	ega_cursor = col + scr_width * row;
+static void cursor_goto(sysarg_t col, sysarg_t row)
+{
+	sysarg_t cursor = col + scr_width * row;
 	
 	pio_write_8(EGA_IO_BASE, 0xe);
-	pio_write_8(EGA_IO_BASE + 1, (ega_cursor >> 8) & 0xff);
+	pio_write_8(EGA_IO_BASE + 1, (cursor >> 8) & 0xff);
 	pio_write_8(EGA_IO_BASE, 0xf);
-	pio_write_8(EGA_IO_BASE + 1, ega_cursor & 0xff);
+	pio_write_8(EGA_IO_BASE + 1, cursor & 0xff);
 }
 
 static void cursor_disable(void)
 {
-	uint8_t stat;
-
 	pio_write_8(EGA_IO_BASE, 0xa);
-	stat = pio_read_8(EGA_IO_BASE + 1);
+	
+	uint8_t stat = pio_read_8(EGA_IO_BASE + 1);
+	
 	pio_write_8(EGA_IO_BASE, 0xa);
 	pio_write_8(EGA_IO_BASE + 1, stat | (1 << 5));
@@ -120,16 +165,16 @@
 static void cursor_enable(void)
 {
-	uint8_t stat;
-
 	pio_write_8(EGA_IO_BASE, 0xa);
-	stat = pio_read_8(EGA_IO_BASE + 1);
+	
+	uint8_t stat = pio_read_8(EGA_IO_BASE + 1);
+	
 	pio_write_8(EGA_IO_BASE, 0xa);
 	pio_write_8(EGA_IO_BASE + 1, stat & (~(1 << 5)));
 }
 
-static void scroll(int rows)
-{
-	unsigned i;
-
+static void scroll(ssize_t rows)
+{
+	size_t i;
+	
 	if (rows > 0) {
 		memmove(scr_addr, ((char *) scr_addr) + rows * scr_width * 2,
@@ -142,9 +187,9 @@
 		    scr_width * scr_height * 2 + rows * scr_width * 2);
 		for (i = 0; i < -rows * scr_width; i++)
-			((short *)scr_addr)[i] = ((style << 8 ) + ' ');
-	}
-}
-
-static void printchar(wchar_t c, unsigned int col, unsigned int row)
+			((short *) scr_addr)[i] = ((style << 8 ) + ' ');
+	}
+}
+
+static void printchar(wchar_t c, sysarg_t col, sysarg_t row)
 {
 	scr_addr[(row * scr_width + col) * 2] = ega_glyph(c);
@@ -158,21 +203,23 @@
  * @param vport Viewport id
  * @param data  Text data.
- * @param x	Leftmost column of the area.
- * @param y	Topmost row of the area.
- * @param w	Number of rows.
- * @param h	Number of columns.
+ * @param x     Leftmost column of the area.
+ * @param y     Topmost row of the area.
+ * @param w     Number of rows.
+ * @param h     Number of columns.
+ *
  */
-static void draw_text_data(keyfield_t *data, unsigned int x,
-    unsigned int y, unsigned int w, unsigned int h)
-{
-	unsigned int i, j;
+static void draw_text_data(keyfield_t *data, sysarg_t x, sysarg_t y,
+    sysarg_t w, sysarg_t h)
+{
+	sysarg_t i;
+	sysarg_t j;
 	keyfield_t *field;
 	uint8_t *dp;
-
+	
 	for (j = 0; j < h; j++) {
 		for (i = 0; i < w; i++) {
 			field = &data[j * w + i];
 			dp = &scr_addr[2 * ((y + j) * scr_width + (x + i))];
-
+			
 			dp[0] = ega_glyph(field->character);
 			dp[1] = attr_to_ega_style(&field->attrs);
@@ -183,111 +230,74 @@
 static int save_screen(void)
 {
-	int i;
-
-	for (i = 0; (i < MAX_SAVED_SCREENS) && (saved_screens[i].data); i++)
-		;
-	if (i == MAX_SAVED_SCREENS) 
+	ipcarg_t i;
+	
+	/* Find empty screen */
+	for (i = 0; (i < MAX_SAVED_SCREENS) && (saved_screens[i].data); i++);
+	
+	if (i == MAX_SAVED_SCREENS)
 		return EINVAL;
-	if (!(saved_screens[i].data = malloc(2 * scr_width * scr_height))) 
+	
+	if (!(saved_screens[i].data = malloc(2 * scr_width * scr_height)))
 		return ENOMEM;
+	
 	memcpy(saved_screens[i].data, scr_addr, 2 * scr_width * scr_height);
-
-	return i;
-}
-
-static int print_screen(int i)
-{
-	if (saved_screens[i].data)
+	return (int) i;
+}
+
+static int print_screen(ipcarg_t i)
+{
+	if ((i >= MAX_SAVED_SCREENS) || (saved_screens[i].data))
 		memcpy(scr_addr, saved_screens[i].data, 2 * scr_width *
 		    scr_height);
 	else
 		return EINVAL;
-	return i;
-}
-
-static int style_to_ega_style(int style)
-{
-	unsigned int ega_style;
-
-	switch (style) {
-	case STYLE_NORMAL:
-		ega_style = INVERTED_COLOR;
-		break;
-	case STYLE_EMPHASIS:
-		ega_style = INVERTED_COLOR | 4;
-		break;
-	default:
-		return INVERTED_COLOR;
-	}
-
-	return ega_style;
-}
-
-static unsigned int color_to_ega_style(int fg_color, int bg_color, int attr)
-{
-	unsigned int style;
-
-	style = (fg_color & 7) | ((bg_color & 7) << 4);
-	if (attr & CATTR_BRIGHT)
-		style = style | 0x08;
-
-	return style;
-}
-
-static unsigned int rgb_to_ega_style(uint32_t fg, uint32_t bg)
-{
-	return (fg > bg) ? NORMAL_COLOR : INVERTED_COLOR;
-}
-
-static unsigned attr_to_ega_style(const attrs_t *a)
-{
-	switch (a->t) {
-	case at_style:
-		return style_to_ega_style(a->a.s.style);
-	case at_rgb:
-		return rgb_to_ega_style(a->a.r.fg_color, a->a.r.bg_color);
-	case at_idx:
-		return color_to_ega_style(a->a.i.fg_color,
-		    a->a.i.bg_color, a->a.i.flags);
-	default:
-		return INVERTED_COLOR;
-	}
-}
-
-static uint8_t ega_glyph(wchar_t ch)
-{
-	if (ch >= 0 && ch < 128)
-		return ch;
-
-	return '?';
+	
+	return (int) i;
 }
 
 static void ega_client_connection(ipc_callid_t iid, ipc_call_t *icall)
 {
-	int retval;
-	ipc_callid_t callid;
-	ipc_call_t call;
-	wchar_t c;
-	unsigned int row, col, w, h;
-	int bg_color, fg_color, attr;
-	uint32_t bg_rgb, fg_rgb;
+	size_t intersize = 0;
 	keyfield_t *interbuf = NULL;
-	size_t intersize = 0;
-	int i;
-
+	
 	if (client_connected) {
 		ipc_answer_0(iid, ELIMIT);
 		return;
 	}
+	
+	/* Accept connection */
 	client_connected = 1;
-	ipc_answer_0(iid, EOK); /* Accept connection */
-
-	while (1) {
-		callid = async_get_call(&call);
- 		switch (IPC_GET_METHOD(call)) {
+	ipc_answer_0(iid, EOK);
+	
+	while (true) {
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+		
+		wchar_t c;
+		
+		ipcarg_t col;
+		ipcarg_t row;
+		ipcarg_t w;
+		ipcarg_t h;
+		
+		ssize_t rows;
+		
+		uint8_t bg_color;
+		uint8_t fg_color;
+		uint8_t attr;
+		
+		uint32_t fg_rgb;
+		uint32_t bg_rgb;
+		
+		ipcarg_t scr;
+		int retval;
+		
+		switch (IPC_GET_METHOD(call)) {
 		case IPC_M_PHONE_HUNGUP:
 			client_connected = 0;
 			ipc_answer_0(callid, EOK);
-			return; /* Exit thread */
+			
+			/* Exit thread */
+			return;
 		case IPC_M_SHARE_OUT:
 			/* We accept one area for data interchange */
@@ -299,19 +309,23 @@
 				continue;
 			}
+			
 			retval = EINVAL;
 			break;
 		case FB_DRAW_TEXT_DATA:
+			if (!interbuf) {
+				retval = EINVAL;
+				break;
+			}
+			
 			col = IPC_GET_ARG1(call);
 			row = IPC_GET_ARG2(call);
 			w = IPC_GET_ARG3(call);
 			h = IPC_GET_ARG4(call);
-			if (!interbuf) {
+			
+			if ((col + w > scr_width) || (row + h > scr_height)) {
 				retval = EINVAL;
 				break;
 			}
-			if (col + w > scr_width || row + h > scr_height) {
-				retval = EINVAL;
-				break;
-			}
+			
 			draw_text_data(interbuf, col, row, w, h);
 			retval = 0;
@@ -331,28 +345,41 @@
 			col = IPC_GET_ARG2(call);
 			row = IPC_GET_ARG3(call);
-			if (col >= scr_width || row >= scr_height) {
+			
+			if ((col >= scr_width) || (row >= scr_height)) {
 				retval = EINVAL;
 				break;
 			}
+			
 			printchar(c, col, row);
 			retval = 0;
 			break;
- 		case FB_CURSOR_GOTO:
- 			col = IPC_GET_ARG1(call);
+		case FB_CURSOR_GOTO:
+			col = IPC_GET_ARG1(call);
 			row = IPC_GET_ARG2(call);
-			if (row >= scr_height || col >= scr_width) {
+			
+			if ((row >= scr_height) || (col >= scr_width)) {
 				retval = EINVAL;
 				break;
 			}
+			
 			cursor_goto(col, row);
- 			retval = 0;
- 			break;
+			retval = 0;
+			break;
 		case FB_SCROLL:
-			i = IPC_GET_ARG1(call);
-			if (i > (int) scr_height || i < -((int) scr_height)) {
-				retval = EINVAL;
-				break;
-			}
-			scroll(i);
+			rows = IPC_GET_ARG1(call);
+			
+			if (rows >= 0) {
+				if ((ipcarg_t) rows > scr_height) {
+					retval = EINVAL;
+					break;
+				}
+			} else {
+				if ((ipcarg_t) (-rows) > scr_height) {
+					retval = EINVAL;
+					break;
+				}
+			}
+			
+			scroll(rows);
 			retval = 0;
 			break;
@@ -362,4 +389,5 @@
 			else
 				cursor_disable();
+			
 			retval = 0;
 			break;
@@ -372,4 +400,5 @@
 			bg_color = IPC_GET_ARG2(call);
 			attr = IPC_GET_ARG3(call);
+			
 			style = color_to_ega_style(fg_color, bg_color, attr);
 			retval = 0;
@@ -378,10 +407,11 @@
 			fg_rgb = IPC_GET_ARG1(call);
 			bg_rgb = IPC_GET_ARG2(call);
+			
 			style = rgb_to_ega_style(fg_rgb, bg_rgb);
 			retval = 0;
 			break;
 		case FB_VP_DRAW_PIXMAP:
-			i = IPC_GET_ARG2(call);
-			retval = print_screen(i);
+			scr = IPC_GET_ARG2(call);
+			retval = print_screen(scr);
 			break;
 		case FB_VP2PIXMAP:
@@ -389,13 +419,16 @@
 			break;
 		case FB_DROP_PIXMAP:
-			i = IPC_GET_ARG1(call);
-			if (i >= MAX_SAVED_SCREENS) {
+			scr = IPC_GET_ARG1(call);
+			
+			if (scr >= MAX_SAVED_SCREENS) {
 				retval = EINVAL;
 				break;
 			}
-			if (saved_screens[i].data) {
-				free(saved_screens[i].data);
-				saved_screens[i].data = NULL;
-			}
+			
+			if (saved_screens[scr].data) {
+				free(saved_screens[scr].data);
+				saved_screens[scr].data = NULL;
+			}
+			
 			retval = 0;
 			break;
@@ -413,32 +446,39 @@
 int ega_init(void)
 {
-	void *ega_ph_addr;
-	size_t sz;
-
-	ega_ph_addr = (void *) sysinfo_value("fb.address.physical");
-	scr_width = sysinfo_value("fb.width");
-	scr_height = sysinfo_value("fb.height");
-
-	if (sysinfo_value("fb.blinking")) {
-		ega_normal_color &= 0x77;
-		ega_inverted_color &= 0x77;
-	}
-
-	style = NORMAL_COLOR;
-
+	sysarg_t paddr;
+	if (sysinfo_get_value("fb.address.physical", &paddr) != EOK)
+		return -1;
+	
+	if (sysinfo_get_value("fb.width", &scr_width) != EOK)
+		return -1;
+	
+	if (sysinfo_get_value("fb.height", &scr_height) != EOK)
+		return -1;
+	
+	sysarg_t blinking;
+	if (sysinfo_get_value("fb.blinking", &blinking) != EOK)
+		blinking = false;
+	
+	void *ega_ph_addr = (void *) paddr;
+	if (blinking) {
+		style_normal &= 0x77;
+		style_inverted &= 0x77;
+	}
+	
+	style = style_normal;
+	
 	iospace_enable(task_get_id(), (void *) EGA_IO_BASE, 2);
-
-	sz = scr_width * scr_height * 2;
+	
+	size_t sz = scr_width * scr_height * 2;
 	scr_addr = as_get_mappable_page(sz);
-
+	
 	if (physmem_map(ega_ph_addr, scr_addr, ALIGN_UP(sz, PAGE_SIZE) >>
 	    PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE) != 0)
 		return -1;
-
+	
 	async_set_client_connection(ega_client_connection);
-
+	
 	return 0;
 }
-
 
 /**
Index: uspace/srv/hid/fb/fb.c
===================================================================
--- uspace/srv/hid/fb/fb.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/fb/fb.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -59,9 +59,9 @@
 #include <stdio.h>
 #include <byteorder.h>
+#include <io/screenbuffer.h>
 
 #include "font-8x16.h"
 #include "fb.h"
 #include "main.h"
-#include "../console/screenbuffer.h"
 #include "ppm.h"
 
@@ -72,10 +72,10 @@
 #define DEFAULT_FGCOLOR  0x000000
 
-#define GLYPH_UNAVAIL    '?'
-
-#define MAX_ANIM_LEN     8
-#define MAX_ANIMATIONS   4
-#define MAX_PIXMAPS      256  /**< Maximum number of saved pixmaps */
-#define MAX_VIEWPORTS    128  /**< Viewport is a rectangular area on the screen */
+#define GLYPH_UNAVAIL  '?'
+
+#define MAX_ANIM_LEN    8
+#define MAX_ANIMATIONS  4
+#define MAX_PIXMAPS     256  /**< Maximum number of saved pixmaps */
+#define MAX_VIEWPORTS   128  /**< Viewport is a rectangular area on the screen */
 
 /** Function to render a pixel from a RGB value. */
@@ -956,5 +956,4 @@
 	bb_cell_t *bbp;
 	attrs_t *a;
-	attr_rgb_t rgb;
 	
 	for (j = 0; j < h; j++) {
@@ -966,4 +965,8 @@
 			
 			a = &data[j * w + i].attrs;
+			
+			attr_rgb_t rgb;
+			rgb.fg_color = 0;
+			rgb.bg_color = 0;
 			rgb_from_attr(&rgb, a);
 			
@@ -1511,8 +1514,16 @@
 		rgb->bg_color = color_table[COLOR_WHITE];
 		break;
+	case STYLE_INVERTED:
+		rgb->fg_color = color_table[COLOR_WHITE];
+		rgb->bg_color = color_table[COLOR_BLACK];
+		break;
+	case STYLE_SELECTED:
+		rgb->fg_color = color_table[COLOR_WHITE];
+		rgb->bg_color = color_table[COLOR_RED];
+		break;
 	default:
 		return EINVAL;
 	}
-
+	
 	return EOK;
 }
@@ -1756,21 +1767,38 @@
 	async_set_client_connection(fb_client_connection);
 	
-	void *fb_ph_addr = (void *) sysinfo_value("fb.address.physical");
-	unsigned int fb_offset = sysinfo_value("fb.offset");
-	unsigned int fb_width = sysinfo_value("fb.width");
-	unsigned int fb_height = sysinfo_value("fb.height");
-	unsigned int fb_scanline = sysinfo_value("fb.scanline");
-	unsigned int fb_visual = sysinfo_value("fb.visual");
-
-	unsigned int fbsize = fb_scanline * fb_height;
+	sysarg_t fb_ph_addr;
+	if (sysinfo_get_value("fb.address.physical", &fb_ph_addr) != EOK)
+		return -1;
+	
+	sysarg_t fb_offset;
+	if (sysinfo_get_value("fb.offset", &fb_offset) != EOK)
+		fb_offset = 0;
+	
+	sysarg_t fb_width;
+	if (sysinfo_get_value("fb.width", &fb_width) != EOK)
+		return -1;
+	
+	sysarg_t fb_height;
+	if (sysinfo_get_value("fb.height", &fb_height) != EOK)
+		return -1;
+	
+	sysarg_t fb_scanline;
+	if (sysinfo_get_value("fb.scanline", &fb_scanline) != EOK)
+		return -1;
+	
+	sysarg_t fb_visual;
+	if (sysinfo_get_value("fb.visual", &fb_visual) != EOK)
+		return -1;
+	
+	sysarg_t fbsize = fb_scanline * fb_height;
 	void *fb_addr = as_get_mappable_page(fbsize);
-
-	if (physmem_map(fb_ph_addr + fb_offset, fb_addr,
+	
+	if (physmem_map((void *) fb_ph_addr + fb_offset, fb_addr,
 	    ALIGN_UP(fbsize, PAGE_SIZE) >> PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE) != 0)
 		return -1;
-
+	
 	if (screen_init(fb_addr, fb_width, fb_height, fb_scanline, fb_visual))
 		return 0;
-
+	
 	return -1;
 }
Index: uspace/srv/hid/fb/main.c
===================================================================
--- uspace/srv/hid/fb/main.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/fb/main.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -60,11 +60,20 @@
 int main(int argc, char *argv[])
 {
-	printf(NAME ": HelenOS Framebuffer service\n");
+	printf("%s: HelenOS Framebuffer service\n", NAME);
 	
-	ipcarg_t phonead;
 	bool initialized = false;
+	sysarg_t fb_present;
+	sysarg_t fb_kind;
+	
+	if (sysinfo_get_value("fb", &fb_present) != EOK)
+		fb_present = false;
+	
+	if (sysinfo_get_value("fb.kind", &fb_kind) != EOK) {
+		printf("%s: Unable to detect framebuffer configuration\n", NAME);
+		return -1;
+	}
 	
 #ifdef FB_ENABLED
-	if (sysinfo_value("fb.kind") == 1) {
+	if ((!initialized) && (fb_kind == 1)) {
 		if (fb_init() == 0)
 			initialized = true;
@@ -72,5 +81,5 @@
 #endif
 #ifdef EGA_ENABLED
-	if ((!initialized) && (sysinfo_value("fb.kind") == 2)) {
+	if ((!initialized) && (fb_kind == 2)) {
 		if (ega_init() == 0)
 			initialized = true;
@@ -78,5 +87,5 @@
 #endif
 #ifdef MSIM_ENABLED
-	if ((!initialized) && (sysinfo_value("fb.kind") == 3)) {
+	if ((!initialized) && (fb_kind == 3)) {
 		if (msim_init() == 0)
 			initialized = true;
@@ -84,5 +93,5 @@
 #endif
 #ifdef SGCN_ENABLED
-	if ((!initialized) && (sysinfo_value("fb.kind") == 4)) {
+	if ((!initialized) && (fb_kind == 4)) {
 		if (sgcn_init() == 0)
 			initialized = true;
@@ -90,5 +99,5 @@
 #endif
 #ifdef NIAGARA_ENABLED
-	if ((!initialized) && (sysinfo_value("fb.kind") == 5)) {
+	if ((!initialized) && (fb_kind == 5)) {
 		if (niagara_init() == 0)
 			initialized = true;
@@ -96,5 +105,5 @@
 #endif
 #ifdef SKI_ENABLED
-	if ((!initialized) && (sysinfo_value("fb") != true)) {
+	if ((!initialized) && (!fb_present)) {
 		if (ski_init() == 0)
 			initialized = true;
@@ -105,8 +114,9 @@
 		return -1;
 	
+	ipcarg_t phonead;
 	if (ipc_connect_to_me(PHONE_NS, SERVICE_VIDEO, 0, 0, &phonead) != 0) 
 		return -1;
 	
-	printf(NAME ": Accepting connections\n");
+	printf("%s: Accepting connections\n", NAME);
 	async_manager();
 	
Index: uspace/srv/hid/fb/msim.c
===================================================================
--- uspace/srv/hid/fb/msim.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/fb/msim.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -29,8 +29,8 @@
 
 /** @defgroup msimfb MSIM text console
- * @brief	HelenOS MSIM text console.
+ * @brief HelenOS MSIM text console.
  * @ingroup fbs
  * @{
- */ 
+ */
 /** @file
  */
@@ -41,4 +41,5 @@
 #include <as.h>
 #include <ddi.h>
+#include <errno.h>
 
 #include "serial_console.h"
@@ -57,8 +58,12 @@
 int msim_init(void)
 {
-	void *phys_addr = (void *) sysinfo_value("fb.address.physical");
+	sysarg_t phys_addr;
+	if (sysinfo_get_value("fb.address.physical", &phys_addr) != EOK)
+		return -1;
+	
 	virt_addr = (char *) as_get_mappable_page(1);
 	
-	if (physmem_map(phys_addr, virt_addr, 1, AS_AREA_READ | AS_AREA_WRITE) != 0)
+	if (physmem_map((void *) phys_addr, virt_addr, 1,
+	    AS_AREA_READ | AS_AREA_WRITE) != 0)
 		return -1;
 	
@@ -69,5 +74,4 @@
 }
 
-/** 
- * @}
+/** @}
  */
Index: uspace/srv/hid/fb/niagara.c
===================================================================
--- uspace/srv/hid/fb/niagara.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/fb/niagara.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -91,9 +91,12 @@
 int niagara_init(void)
 {
+	sysarg_t paddr;
+	if (sysinfo_get_value("niagara.outbuf.address", &paddr) != EOK)
+		return -1;
+	
 	output_buffer_addr = (uintptr_t) as_get_mappable_page(PAGE_SIZE);
-	int result = physmem_map(
-		(void *) sysinfo_value("niagara.outbuf.address"),
-		(void *) output_buffer_addr,
-		1, AS_AREA_READ | AS_AREA_WRITE);
+	int result = physmem_map((void *) paddr,
+	    (void *) output_buffer_addr, 1,
+	    AS_AREA_READ | AS_AREA_WRITE);
 
 	if (result != 0) {
Index: uspace/srv/hid/fb/serial_console.c
===================================================================
--- uspace/srv/hid/fb/serial_console.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/fb/serial_console.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -31,7 +31,7 @@
 /**
  * @defgroup serial Serial console
- * @brief    Serial console services (putc, puts, clear screen, cursor goto,...)
+ * @brief Serial console services (putc, puts, clear screen, cursor goto,...)
  * @{
- */ 
+ */
 
 /** @file
@@ -47,6 +47,6 @@
 #include <io/style.h>
 #include <str.h>
-
-#include "../console/screenbuffer.h"
+#include <io/screenbuffer.h>
+
 #include "main.h"
 #include "serial_console.h"
@@ -54,12 +54,16 @@
 #define MAX_CONTROL 20
 
-static void serial_sgr(const unsigned int mode);
-void serial_putchar(wchar_t ch);
-
-static unsigned int scr_width;
-static unsigned int scr_height;
-static bool color = true;	/** True if producing color output. */
-static bool utf8 = false;	/** True if producing UTF8 output. */
+static ipcarg_t scr_width;
+static ipcarg_t scr_height;
+static bool color = true;    /**< True if producing color output. */
+static bool utf8 = false;    /**< True if producing UTF8 output. */
 static putc_function_t putc_function;
+
+static ipcarg_t lastcol = 0;
+static ipcarg_t lastrow = 0;
+static attrs_t cur_attr = {
+	.t = at_style,
+	.a.s.style = STYLE_NORMAL
+};
 
 /* Allow only 1 connection */
@@ -67,35 +71,35 @@
 
 enum sgr_color_index {
-	CI_BLACK	= 0,
-	CI_RED		= 1,
-	CI_GREEN	= 2,
-	CI_BROWN	= 3,
-	CI_BLUE		= 4,
-	CI_MAGENTA	= 5,
-	CI_CYAN		= 6,
-	CI_WHITE	= 7,
+	CI_BLACK   = 0,
+	CI_RED     = 1,
+	CI_GREEN   = 2,
+	CI_BROWN   = 3,
+	CI_BLUE    = 4,
+	CI_MAGENTA = 5,
+	CI_CYAN    = 6,
+	CI_WHITE   = 7
 };
 
 enum sgr_command {
-	SGR_RESET	= 0,
-	SGR_BOLD	= 1,
-	SGR_BLINK	= 5,
-	SGR_REVERSE	= 7,
-	SGR_NORMAL_INT	= 22,
-	SGR_BLINK_OFF	= 25,
+	SGR_RESET       = 0,
+	SGR_BOLD        = 1,
+	SGR_BLINK       = 5,
+	SGR_REVERSE     = 7,
+	SGR_NORMAL_INT  = 22,
+	SGR_BLINK_OFF   = 25,
 	SGR_REVERSE_OFF = 27,
-	SGR_FGCOLOR	= 30,
-	SGR_BGCOLOR	= 40
+	SGR_FGCOLOR     = 30,
+	SGR_BGCOLOR     = 40
 };
 
 static int color_map[] = {
-	[COLOR_BLACK]	= CI_BLACK,
-	[COLOR_BLUE]	= CI_RED,
-	[COLOR_GREEN]	= CI_GREEN,
-	[COLOR_CYAN]	= CI_CYAN,
-	[COLOR_RED]	= CI_RED,
+	[COLOR_BLACK]   = CI_BLACK,
+	[COLOR_BLUE]    = CI_RED,
+	[COLOR_GREEN]   = CI_GREEN,
+	[COLOR_CYAN]    = CI_CYAN,
+	[COLOR_RED]     = CI_RED,
 	[COLOR_MAGENTA] = CI_MAGENTA,
-	[COLOR_YELLOW]	= CI_BROWN,
-	[COLOR_WHITE]	= CI_WHITE
+	[COLOR_YELLOW]  = CI_BROWN,
+	[COLOR_WHITE]   = CI_WHITE
 };
 
@@ -106,29 +110,26 @@
 }
 
-void serial_putchar(wchar_t ch)
-{
-	char buf[STR_BOUNDS(1)];
-	size_t offs;
-	size_t i;
-
+static void serial_putchar(wchar_t ch)
+{
 	if (utf8 != true) {
 		if (ch >= 0 && ch < 128)
 			(*putc_function)((uint8_t) ch);
-		else 
+		else
 			(*putc_function)('?');
+		
 		return;
 	}
-
-	offs = 0;
+	
+	size_t offs = 0;
+	char buf[STR_BOUNDS(1)];
 	if (chr_encode(ch, buf, &offs, STR_BOUNDS(1)) == EOK) {
+		size_t i;
 		for (i = 0; i < offs; i++)
 			(*putc_function)(buf[i]);
-	} else {
+	} else
 		(*putc_function)('?');
-	}
-
-}
-
-void serial_goto(const unsigned int col, const unsigned int row)
+}
+
+void serial_goto(const ipcarg_t col, const ipcarg_t row)
 {
 	if ((col > scr_width) || (row > scr_height))
@@ -138,4 +139,94 @@
 	snprintf(control, MAX_CONTROL, "\033[%u;%uf", row + 1, col + 1);
 	serial_puts(control);
+}
+
+/** ECMA-48 Set Graphics Rendition. */
+static void serial_sgr(const unsigned int mode)
+{
+	char control[MAX_CONTROL];
+	snprintf(control, MAX_CONTROL, "\033[%um", mode);
+	serial_puts(control);
+}
+
+static void serial_set_style(console_style_t style)
+{
+	switch (style) {
+	case STYLE_EMPHASIS:
+		if (color) {
+			serial_sgr(SGR_RESET);
+			serial_sgr(SGR_FGCOLOR + CI_RED);
+			serial_sgr(SGR_BGCOLOR + CI_WHITE);
+		}
+		serial_sgr(SGR_BOLD);
+		break;
+	case STYLE_INVERTED:
+		if (color) {
+			serial_sgr(SGR_RESET);
+			serial_sgr(SGR_FGCOLOR + CI_WHITE);
+			serial_sgr(SGR_BGCOLOR + CI_BLACK);
+			serial_sgr(SGR_NORMAL_INT);
+		} else
+			serial_sgr(SGR_REVERSE);
+		break;
+	case STYLE_SELECTED:
+		if (color) {
+			serial_sgr(SGR_RESET);
+			serial_sgr(SGR_FGCOLOR + CI_WHITE);
+			serial_sgr(SGR_BGCOLOR + CI_RED);
+			serial_sgr(SGR_NORMAL_INT);
+		} else {
+			serial_sgr(SGR_BOLD);
+			serial_sgr(SGR_REVERSE);
+		}
+		break;
+	default:
+		if (color) {
+			serial_sgr(SGR_RESET);
+			serial_sgr(SGR_FGCOLOR + CI_BLACK);
+			serial_sgr(SGR_BGCOLOR + CI_WHITE);
+		}
+		serial_sgr(SGR_NORMAL_INT);
+	}
+}
+
+static void serial_set_idx(uint8_t fgcolor, uint8_t bgcolor,
+    uint8_t flags)
+{
+	if (color) {
+		serial_sgr(SGR_RESET);
+		serial_sgr(SGR_FGCOLOR + color_map[fgcolor]);
+		serial_sgr(SGR_BGCOLOR + color_map[bgcolor]);
+	} else {
+		if (fgcolor < bgcolor)
+			serial_sgr(SGR_RESET);
+		else
+			serial_sgr(SGR_REVERSE);
+	}	
+}
+
+static void serial_set_rgb(uint32_t fgcolor, uint32_t bgcolor)
+{
+	serial_sgr(SGR_RESET);
+	
+	if (fgcolor < bgcolor)
+		serial_sgr(SGR_REVERSE_OFF);
+	else
+		serial_sgr(SGR_REVERSE);
+}
+
+static void serial_set_attrs(attrs_t *a)
+{
+	switch (a->t) {
+	case at_style:
+		serial_set_style(a->a.s.style);
+		break;
+	case at_rgb:
+		serial_set_rgb(a->a.r.fg_color, a->a.r.bg_color);
+		break;
+	case at_idx:
+		serial_set_idx(a->a.i.fg_color, a->a.i.bg_color,
+		    a->a.i.flags);
+		break;
+	}
 }
 
@@ -148,9 +239,11 @@
 		serial_sgr(SGR_BGCOLOR + CI_WHITE);
 	}
-
+	
 	serial_puts("\033[2J");
-}
-
-void serial_scroll(int i)
+	
+	serial_set_attrs(&cur_attr);
+}
+
+void serial_scroll(ssize_t i)
 {
 	if (i > 0) {
@@ -165,14 +258,6 @@
 }
 
-/** ECMA-48 Set Graphics Rendition. */
-static void serial_sgr(const unsigned int mode)
-{
-	char control[MAX_CONTROL];
-	snprintf(control, MAX_CONTROL, "\033[%um", mode);
-	serial_puts(control);
-}
-
 /** Set scrolling region. */
-void serial_set_scroll_region(unsigned last_row)
+void serial_set_scroll_region(ipcarg_t last_row)
 {
 	char control[MAX_CONTROL];
@@ -191,5 +276,5 @@
 }
 
-void serial_console_init(putc_function_t putc_fn, uint32_t w, uint32_t h)
+void serial_console_init(putc_function_t putc_fn, ipcarg_t w, ipcarg_t h)
 {
 	scr_width = w;
@@ -198,63 +283,5 @@
 }
 
-static void serial_set_style(int style)
-{
-	if (style == STYLE_EMPHASIS) {
-		if (color) {
-			serial_sgr(SGR_RESET);
-			serial_sgr(SGR_FGCOLOR + CI_RED);
-			serial_sgr(SGR_BGCOLOR + CI_WHITE);
-		}
-		serial_sgr(SGR_BOLD);
-	} else {
-		if (color) {
-			serial_sgr(SGR_RESET);
-			serial_sgr(SGR_FGCOLOR + CI_BLACK);
-			serial_sgr(SGR_BGCOLOR + CI_WHITE);
-		}
-		serial_sgr(SGR_NORMAL_INT);
-	}
-}
-
-static void serial_set_idx(unsigned fgcolor, unsigned bgcolor,
-    unsigned flags)
-{
-	if (color) {
-		serial_sgr(SGR_RESET);
-		serial_sgr(SGR_FGCOLOR + color_map[fgcolor]);
-		serial_sgr(SGR_BGCOLOR + color_map[bgcolor]);
-	} else {
-		if (fgcolor < bgcolor)
-			serial_sgr(SGR_RESET);
-		else
-			serial_sgr(SGR_REVERSE);
-	}	
-}
-
-static void serial_set_rgb(uint32_t fgcolor, uint32_t bgcolor)
-{
-	if (fgcolor < bgcolor)
-		serial_sgr(SGR_REVERSE_OFF);
-	else
-		serial_sgr(SGR_REVERSE);
-}
-
-static void serial_set_attrs(const attrs_t *a)
-{
-	switch (a->t) {
-	case at_style:
-		serial_set_style(a->a.s.style);
-		break;
-	case at_rgb:
-		serial_set_rgb(a->a.r.fg_color, a->a.r.bg_color);
-		break;
-	case at_idx:
-		serial_set_idx(a->a.i.fg_color,
-		    a->a.i.bg_color, a->a.i.flags);
-		break;
-	default:
-		break;
-	}
-}
+
 
 /** Draw text data to viewport.
@@ -262,38 +289,35 @@
  * @param vport Viewport id
  * @param data  Text data.
- * @param x	Leftmost column of the area.
- * @param y	Topmost row of the area.
- * @param w	Number of rows.
- * @param h	Number of columns.
- */
-static void draw_text_data(keyfield_t *data, unsigned int x,
-    unsigned int y, unsigned int w, unsigned int h)
-{
-	unsigned int i, j;
-	keyfield_t *field;
-	attrs_t *a0, *a1;
-
+ * @param x     Leftmost column of the area.
+ * @param y     Topmost row of the area.
+ * @param w     Number of rows.
+ * @param h     Number of columns.
+ *
+ */
+static void draw_text_data(keyfield_t *data, ipcarg_t x, ipcarg_t y,
+    ipcarg_t w, ipcarg_t h)
+{
 	serial_goto(x, y);
-	a0 = &data[0].attrs;
-	serial_set_attrs(a0);
-
+	ipcarg_t i;
+	ipcarg_t j;
+	
+	attrs_t *a0 = &data[0].attrs;
+	
 	for (j = 0; j < h; j++) {
-		if (j > 0 && w != scr_width)
+		if ((j > 0) && (w != scr_width))
 			serial_goto(x, j);
-
+		
 		for (i = 0; i < w; i++) {
-			field = &data[j * w + i];
-
-			a1 = &field->attrs;
-			if (!attrs_same(*a0, *a1))
+			attrs_t *a1 = &data[j * w + i].attrs;
+			
+			if (!attrs_same(*a0, *a1)) {
 				serial_set_attrs(a1);
-			serial_putchar(field->character);
-			a0 = a1;
+				a0 = a1;
+			}
+			
+			serial_putchar(data[j * w + i].character);
 		}
 	}
 }
-
-unsigned int lastcol = 0;
-unsigned int lastrow = 0;
 
 /**
@@ -302,18 +326,6 @@
 void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall)
 {
-	int retval;
-	ipc_callid_t callid;
-	ipc_call_t call;
 	keyfield_t *interbuf = NULL;
 	size_t intersize = 0;
-
-	wchar_t c;
-	unsigned int col;
-	unsigned int row;
-	unsigned int w;
-	unsigned int h;
-	int i;
-
-	attrs_t cur_attr;
 	
 	if (client_connected) {
@@ -324,7 +336,4 @@
 	client_connected = 1;
 	ipc_answer_0(iid, EOK);
-
-	cur_attr.t = at_style;
-	cur_attr.a.s.style = STYLE_NORMAL;
 	
 	/* Clear the terminal, set scrolling region
@@ -335,9 +344,23 @@
 	
 	while (true) {
-		callid = async_get_call(&call);
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+		
+		wchar_t c;
+		ipcarg_t col;
+		ipcarg_t row;
+		ipcarg_t w;
+		ipcarg_t h;
+		attrs_t attr;
+		ssize_t rows;
+		
+		int retval;
+		
 		switch (IPC_GET_METHOD(call)) {
 		case IPC_M_PHONE_HUNGUP:
 			client_connected = 0;
 			ipc_answer_0(callid, EOK);
+			
+			/* Exit thread */
 			return;
 		case IPC_M_SHARE_OUT:
@@ -350,4 +373,5 @@
 				continue;
 			}
+			
 			retval = EINVAL;
 			break;
@@ -357,12 +381,15 @@
 			w = IPC_GET_ARG3(call);
 			h = IPC_GET_ARG4(call);
+			
 			if (!interbuf) {
 				retval = EINVAL;
 				break;
 			}
+			
 			if ((col + w > scr_width) || (row + h > scr_height)) {
 				retval = EINVAL;
 				break;
 			}
+			
 			draw_text_data(interbuf, col, row, w, h);
 			lastcol = col + w;
@@ -374,6 +401,8 @@
 			col = IPC_GET_ARG2(call);
 			row = IPC_GET_ARG3(call);
+			
 			if ((lastcol != col) || (lastrow != row))
 				serial_goto(col, row);
+			
 			lastcol = col + 1;
 			lastrow = row;
@@ -401,35 +430,40 @@
 			break;
 		case FB_SET_STYLE:
-			cur_attr.t = at_style;
-			cur_attr.a.s.style = IPC_GET_ARG1(call);
-			cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
+			attr.t = at_style;
+			attr.a.s.style = IPC_GET_ARG1(call);
 			serial_set_attrs(&cur_attr);
-
 			retval = 0;
 			break;
 		case FB_SET_COLOR:
-			cur_attr.t = at_idx;
-			cur_attr.a.i.fg_color = IPC_GET_ARG1(call);
-			cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
-			cur_attr.a.i.flags = IPC_GET_ARG3(call);
+			attr.t = at_idx;
+			attr.a.i.fg_color = IPC_GET_ARG1(call);
+			attr.a.i.bg_color = IPC_GET_ARG2(call);
+			attr.a.i.flags = IPC_GET_ARG3(call);
 			serial_set_attrs(&cur_attr);
-
 			retval = 0;
 			break;
 		case FB_SET_RGB_COLOR:
-			cur_attr.t = at_rgb;
-			cur_attr.a.i.fg_color = IPC_GET_ARG1(call);
-			cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
+			attr.t = at_rgb;
+			attr.a.r.fg_color = IPC_GET_ARG1(call);
+			attr.a.r.bg_color = IPC_GET_ARG2(call);
 			serial_set_attrs(&cur_attr);
-
 			retval = 0;
 			break;
 		case FB_SCROLL:
-			i = IPC_GET_ARG1(call);
-			if ((i > (int) scr_height) || (i < -((int) scr_height))) {
-				retval = EINVAL;
-				break;
+			rows = IPC_GET_ARG1(call);
+			
+			if (rows >= 0) {
+				if ((ipcarg_t) rows > scr_height) {
+					retval = EINVAL;
+					break;
+				}
+			} else {
+				if ((ipcarg_t) (-rows) > scr_height) {
+					retval = EINVAL;
+					break;
+				}
 			}
-			serial_scroll(i);
+			
+			serial_scroll(rows);
 			serial_goto(lastcol, lastrow);
 			retval = 0;
@@ -451,5 +485,4 @@
 		case FB_SCREEN_RECLAIM:
 			serial_clrscr();
-			serial_set_attrs(&cur_attr);
 			retval = 0;
 			break;
Index: uspace/srv/hid/fb/serial_console.h
===================================================================
--- uspace/srv/hid/fb/serial_console.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/fb/serial_console.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -29,7 +29,7 @@
 /**
  * @defgroup serial Serial console
- * @brief    Serial console services (putc, puts, clear screen, cursor goto,...)
+ * @brief Serial console services (putc, puts, clear screen, cursor goto,...)
  * @{
- */ 
+ */
 
 /** @file
@@ -43,14 +43,13 @@
 typedef void (*putc_function_t)(char);
 
-void serial_puts(const char *str);
-void serial_goto(const unsigned int col, const unsigned int row);
-void serial_clrscr(void);
-void serial_scroll(int i);
-void serial_cursor_disable(void);
-void serial_cursor_enable(void);
-void serial_set_scroll_region(unsigned height);
-void serial_console_init(putc_function_t putc_fn, uint32_t w, uint32_t h);
-void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall);
-
+extern void serial_puts(const char *);
+extern void serial_goto(const ipcarg_t, const ipcarg_t);
+extern void serial_clrscr(void);
+extern void serial_scroll(ssize_t);
+extern void serial_cursor_disable(void);
+extern void serial_cursor_enable(void);
+extern void serial_set_scroll_region(ipcarg_t);
+extern void serial_console_init(putc_function_t, ipcarg_t, ipcarg_t);
+extern void serial_client_connection(ipc_callid_t, ipc_call_t *);
 
 #endif
Index: uspace/srv/hid/fb/sgcn.c
===================================================================
--- uspace/srv/hid/fb/sgcn.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/fb/sgcn.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -122,14 +122,22 @@
 int sgcn_init(void)
 {
-	sram_virt_addr = (uintptr_t) as_get_mappable_page(sysinfo_value("sram.area.size"));
+	sysarg_t sram_paddr;
+	if (sysinfo_get_value("sram.address.physical", &sram_paddr) != EOK)
+		return -1;
 	
-	if (physmem_map((void *) sysinfo_value("sram.address.physical"),
-	    (void *) sram_virt_addr, sysinfo_value("sram.area.size") / PAGE_SIZE,
-	    AS_AREA_READ | AS_AREA_WRITE) != 0)
+	sysarg_t sram_size;
+	if (sysinfo_get_value("sram.area.size", &sram_size) != EOK)
+		return -1;
+	
+	if (sysinfo_get_value("sram.buffer.offset", &sram_buffer_offset) != EOK)
+		sram_buffer_offset = 0;
+	
+	sram_virt_addr = (uintptr_t) as_get_mappable_page(sram_size);
+	
+	if (physmem_map((void *) sram_paddr, (void *) sram_virt_addr,
+	    sram_size / PAGE_SIZE, AS_AREA_READ | AS_AREA_WRITE) != 0)
 		return -1;
 	
 	serial_console_init(sgcn_putc, WIDTH, HEIGHT);
-	
-	sram_buffer_offset = sysinfo_value("sram.buffer.offset");
 	
 	async_set_client_connection(serial_client_connection);
Index: uspace/srv/hid/kbd/generic/kbd.c
===================================================================
--- uspace/srv/hid/kbd/generic/kbd.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/kbd/generic/kbd.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -212,9 +212,12 @@
 int main(int argc, char **argv)
 {
-	printf(NAME ": HelenOS Keyboard service\n");
-	
-	if (sysinfo_value("kbd.cir.fhc") == 1)
+	printf("%s: HelenOS Keyboard service\n", NAME);
+	
+	sysarg_t fhc;
+	sysarg_t obio;
+	
+	if ((sysinfo_get_value("kbd.cir.fhc", &fhc) == EOK) && (fhc))
 		cir_service = SERVICE_FHC;
-	else if (sysinfo_value("kbd.cir.obio") == 1)
+	else if ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio))
 		cir_service = SERVICE_OBIO;
 	
@@ -240,5 +243,5 @@
 	int rc = devmap_driver_register(NAME, client_connection);
 	if (rc < 0) {
-		printf(NAME ": Unable to register driver (%d)\n", rc);
+		printf("%s: Unable to register driver (%d)\n", NAME, rc);
 		return -1;
 	}
@@ -249,5 +252,5 @@
 	dev_handle_t dev_handle;
 	if (devmap_device_register(kbd, &dev_handle) != EOK) {
-		printf(NAME ": Unable to register device %s\n", kbd);
+		printf("%s: Unable to register device %s\n", NAME, kbd);
 		return -1;
 	}
Index: uspace/srv/hid/kbd/port/gxemul.c
===================================================================
--- uspace/srv/hid/kbd/port/gxemul.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/kbd/port/gxemul.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -41,4 +41,5 @@
 #include <kbd.h>
 #include <ddi.h>
+#include <errno.h>
 
 static irq_cmd_t gxemul_cmds[] = {
@@ -63,8 +64,15 @@
 int kbd_port_init(void)
 {
+	sysarg_t addr;
+	if (sysinfo_get_value("kbd.address.virtual", &addr) != EOK)
+		return -1;
+	
+	sysarg_t inr;
+	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
+		return -1;
+	
 	async_set_interrupt_received(gxemul_irq_handler);
-	gxemul_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual");
-	ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(),
-	    0, &gxemul_kbd);
+	gxemul_cmds[0].addr = (void *) addr;
+	ipc_register_irq(inr, device_assign_devno(), 0, &gxemul_kbd);
 	return 0;
 }
Index: uspace/srv/hid/kbd/port/msim.c
===================================================================
--- uspace/srv/hid/kbd/port/msim.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/kbd/port/msim.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -30,7 +30,7 @@
  * @ingroup  kbd
  * @{
- */ 
+ */
 /** @file
- * @brief	Msim keyboard port driver.
+ * @brief Msim keyboard port driver.
  */
 
@@ -41,4 +41,5 @@
 #include <kbd.h>
 #include <ddi.h>
+#include <errno.h>
 
 irq_cmd_t msim_cmds[] = {
@@ -63,8 +64,16 @@
 int kbd_port_init(void)
 {
+	sysarg_t vaddr;
+	if (sysinfo_get_value("kbd.address.virtual", &vaddr) != EOK)
+		return -1;
+	
+	sysarg_t inr;
+	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
+		return -1;
+	
+	msim_cmds[0].addr = (void *) vaddr;
 	async_set_interrupt_received(msim_irq_handler);
-	msim_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual");
-	ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(),
-	    0, &msim_kbd);
+	ipc_register_irq(inr, device_assign_devno(), 0, &msim_kbd);
+	
 	return 0;
 }
Index: uspace/srv/hid/kbd/port/niagara.c
===================================================================
--- uspace/srv/hid/kbd/port/niagara.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/kbd/port/niagara.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -44,6 +44,7 @@
 #include <thread.h>
 #include <bool.h>
+#include <errno.h>
 
-#define POLL_INTERVAL		10000
+#define POLL_INTERVAL  10000
 
 /**
@@ -57,5 +58,6 @@
  * kernel/arch/sparc64/src/drivers/niagara.c.
  */
-#define INPUT_BUFFER_SIZE	((PAGE_SIZE) - 2 * 8)
+#define INPUT_BUFFER_SIZE  ((PAGE_SIZE) - 2 * 8)
+
 typedef volatile struct {
 	uint64_t write_ptr;
@@ -79,24 +81,25 @@
 int kbd_port_init(void)
 {
+	sysarg_t paddr;
+	if (sysinfo_get_value("niagara.inbuf.address", &paddr) != EOK)
+		return -1;
+	
 	input_buffer_addr = (uintptr_t) as_get_mappable_page(PAGE_SIZE);
-	int result = physmem_map(
-		(void *) sysinfo_value("niagara.inbuf.address"),
-		(void *) input_buffer_addr,
-		1, AS_AREA_READ | AS_AREA_WRITE);
-
-	if (result != 0) {
+	int rc = physmem_map((void *) paddr, (void *) input_buffer_addr,
+	    1, AS_AREA_READ | AS_AREA_WRITE);
+	
+	if (rc != 0) {
 		printf("Niagara: uspace driver couldn't map physical memory: %d\n",
-			result);
-	}
-
-	input_buffer = (input_buffer_t) input_buffer_addr;
-
-	thread_id_t tid;
-	int rc;
-
-	rc = thread_create(niagara_thread_impl, NULL, "kbd_poll", &tid);
-	if (rc != 0) {
+		    rc);
 		return rc;
 	}
+	
+	input_buffer = (input_buffer_t) input_buffer_addr;
+	
+	thread_id_t tid;
+	rc = thread_create(niagara_thread_impl, NULL, "kbd_poll", &tid);
+	if (rc != 0)
+		return rc;
+	
 	return 0;
 }
Index: uspace/srv/hid/kbd/port/ns16550.c
===================================================================
--- uspace/srv/hid/kbd/port/ns16550.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/kbd/port/ns16550.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -30,7 +30,7 @@
  * @ingroup  kbd
  * @{
- */ 
+ */
 /** @file
- * @brief	NS16550 port driver.
+ * @brief NS16550 port driver.
  */
 
@@ -43,20 +43,21 @@
 #include <sun.h>
 #include <ddi.h>
+#include <errno.h>
 
 /* NS16550 registers */
-#define RBR_REG		0	/** Receiver Buffer Register. */
-#define IER_REG		1	/** Interrupt Enable Register. */
-#define IIR_REG		2	/** Interrupt Ident Register (read). */
-#define FCR_REG		2	/** FIFO control register (write). */
-#define LCR_REG		3	/** Line Control register. */
-#define MCR_REG		4	/** Modem Control Register. */
-#define LSR_REG		5	/** Line Status Register. */
+#define RBR_REG  0  /** Receiver Buffer Register. */
+#define IER_REG  1  /** Interrupt Enable Register. */
+#define IIR_REG  2  /** Interrupt Ident Register (read). */
+#define FCR_REG  2  /** FIFO control register (write). */
+#define LCR_REG  3  /** Line Control register. */
+#define MCR_REG  4  /** Modem Control Register. */
+#define LSR_REG  5  /** Line Status Register. */
 
-#define LSR_DATA_READY	0x01
+#define LSR_DATA_READY  0x01
 
 static irq_cmd_t ns16550_cmds[] = {
 	{
 		.cmd = CMD_PIO_READ_8,
-		.addr = (void *) 0,	/* will be patched in run-time */
+		.addr = (void *) 0,     /* Will be patched in run-time */
 		.dstarg = 1
 	},
@@ -74,5 +75,5 @@
 	{
 		.cmd = CMD_PIO_READ_8,
-		.addr = (void *) 0,	/* will be patched in run-time */
+		.addr = (void *) 0,     /* Will be patched in run-time */
 		.dstarg = 2
 	},
@@ -96,12 +97,20 @@
 	void *vaddr;
 
-	async_set_interrupt_received(ns16550_irq_handler);
-
-	ns16550_physical = sysinfo_value("kbd.address.physical");
-	ns16550_kernel = sysinfo_value("kbd.address.kernel");
+	if (sysinfo_get_value("kbd.address.physical", &ns16550_physical) != EOK)
+		return -1;
+	
+	if (sysinfo_get_value("kbd.address.kernel", &ns16550_kernel) != EOK)
+		return -1;
+	
+	sysarg_t inr;
+	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
+		return -1;
+	
 	ns16550_kbd.cmds[0].addr = (void *) (ns16550_kernel + LSR_REG);
 	ns16550_kbd.cmds[3].addr = (void *) (ns16550_kernel + RBR_REG);
-	ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(),
-	    sysinfo_value("kbd.inr"), &ns16550_kbd);
+	
+	async_set_interrupt_received(ns16550_irq_handler);
+	ipc_register_irq(inr, device_assign_devno(), inr, &ns16550_kbd);
+	
 	return pio_enable((void *) ns16550_physical, 8, &vaddr);
 }
Index: uspace/srv/hid/kbd/port/pl050.c
===================================================================
--- uspace/srv/hid/kbd/port/pl050.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/kbd/port/pl050.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -45,6 +45,8 @@
 #include <ddi.h>
 #include <stdio.h>
+#include <errno.h>
 
-#define PL050_STAT_RXFULL (1 << 4)
+#define PL050_STAT_RXFULL  (1 << 4)
+
 static irq_cmd_t pl050_cmds[] = {
 	{
@@ -66,5 +68,5 @@
 	{
 		.cmd = CMD_PIO_READ_8,
-		.addr = NULL,	/* will be patched in run-time */
+		.addr = NULL,  /* Will be patched in run-time */
 		.dstarg = 2
 	},
@@ -83,12 +85,22 @@
 int kbd_port_init(void)
 {
-
-	pl050_kbd.cmds[0].addr = (void *) sysinfo_value("kbd.address.status");
-	pl050_kbd.cmds[3].addr = (void *) sysinfo_value("kbd.address.data");
-
+	sysarg_t addr;
+	if (sysinfo_get_value("kbd.address.status", &addr) != EOK)
+		return -1;
+	
+	pl050_kbd.cmds[0].addr = (void *) addr;
+	
+	if (sysinfo_get_value("kbd.address.data", &addr) != EOK)
+		return -1;
+	
+	pl050_kbd.cmds[3].addr = (void *) addr;
+	
+	sysarg_t inr;
+	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
+		return -1;
+	
 	async_set_interrupt_received(pl050_irq_handler);
-
-	ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(), 0, &pl050_kbd);
-
+	ipc_register_irq(inr, device_assign_devno(), 0, &pl050_kbd);
+	
 	return 0;
 }
Index: uspace/srv/hid/kbd/port/sgcn.c
===================================================================
--- uspace/srv/hid/kbd/port/sgcn.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/kbd/port/sgcn.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -30,7 +30,7 @@
  * @ingroup  kbd
  * @{
- */ 
+ */
 /** @file
- * @brief	SGCN (Serengeti Console) keyboard port driver.
+ * @brief SGCN (Serengeti Console) keyboard port driver.
  */
 
@@ -44,10 +44,11 @@
 #include <thread.h>
 #include <bool.h>
+#include <errno.h>
 
-#define POLL_INTERVAL		10000
+#define POLL_INTERVAL  10000
 
 /**
  * SGCN buffer header. It is placed at the very beginning of the SGCN
- * buffer. 
+ * buffer.
  */
 typedef struct {
@@ -102,22 +103,28 @@
 int kbd_port_init(void)
 {
-	sram_virt_addr = (uintptr_t) as_get_mappable_page(sysinfo_value("sram.area.size"));
-	if (physmem_map((void *) sysinfo_value("sram.address.physical"),
-	    (void *) sram_virt_addr, sysinfo_value("sram.area.size") / PAGE_SIZE,
-	    AS_AREA_READ | AS_AREA_WRITE) != 0) {
+	sysarg_t sram_paddr;
+	if (sysinfo_get_value("sram.address.physical", &sram_paddr) != EOK)
+		return -1;
+	
+	sysarg_t sram_size;
+	if (sysinfo_get_value("sram.area.size", &sram_size) != EOK)
+		return -1;
+	
+	if (sysinfo_get_value("sram.buffer.offset", &sram_buffer_offset) != EOK)
+		sram_buffer_offset = 0;
+	
+	sram_virt_addr = (uintptr_t) as_get_mappable_page(sram_size);
+	
+	if (physmem_map((void *) sram_paddr, (void *) sram_virt_addr,
+	    sram_size / PAGE_SIZE, AS_AREA_READ | AS_AREA_WRITE) != 0) {
 		printf("SGCN: uspace driver could not map physical memory.");
 		return -1;
 	}
 	
-	sram_buffer_offset = sysinfo_value("sram.buffer.offset");
-
 	thread_id_t tid;
-	int rc;
-
-	rc = thread_create(sgcn_thread_impl, NULL, "kbd_poll", &tid);
-	if (rc != 0) {
+	int rc = thread_create(sgcn_thread_impl, NULL, "kbd_poll", &tid);
+	if (rc != 0)
 		return rc;
-	}
-
+	
 	return 0;
 }
Index: uspace/srv/hid/kbd/port/sun.c
===================================================================
--- uspace/srv/hid/kbd/port/sun.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/kbd/port/sun.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -39,4 +39,6 @@
 #include <sun.h>
 #include <sysinfo.h>
+#include <errno.h>
+#include <bool.h>
 
 /** Sun keyboard virtual port driver.
@@ -50,10 +52,18 @@
 int kbd_port_init(void)
 {
-	if (sysinfo_value("kbd.type.z8530")) {
+	sysarg_t z8530;
+	if (sysinfo_get_value("kbd.type.z8530", &z8530) != EOK)
+		z8530 = false;
+	
+	sysarg_t ns16550;
+	if (sysinfo_get_value("kbd.type.ns16550", &ns16550) != EOK)
+		ns16550 = false;
+	
+	if (z8530) {
 		if (z8530_port_init() == 0)
 			return 0;
 	}
 	
-	if (sysinfo_value("kbd.type.ns16550")) {
+	if (ns16550) {
 		if (ns16550_port_init() == 0)
 			return 0;
Index: uspace/srv/hid/kbd/port/z8530.c
===================================================================
--- uspace/srv/hid/kbd/port/z8530.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hid/kbd/port/z8530.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -30,7 +30,7 @@
  * @ingroup  kbd
  * @{
- */ 
+ */
 /** @file
- * @brief	Z8530 keyboard port driver.
+ * @brief Z8530 keyboard port driver.
  */
 
@@ -44,14 +44,15 @@
 #include <sys/types.h>
 #include <ddi.h>
+#include <errno.h>
 
-#define CHAN_A_STATUS	4
-#define CHAN_A_DATA	6
+#define CHAN_A_STATUS  4
+#define CHAN_A_DATA    6
 
-#define RR0_RCA	1
+#define RR0_RCA  1
 
 static irq_cmd_t z8530_cmds[] = {
 	{
 		.cmd = CMD_PIO_READ_8,
-		.addr = (void *) 0,	/* will be patched in run-time */
+		.addr = (void *) 0,     /* Will be patched in run-time */
 		.dstarg = 1
 	},
@@ -69,5 +70,5 @@
 	{
 		.cmd = CMD_PIO_READ_8,
-		.addr = (void *) 0,	/* will be patched in run-time */
+		.addr = (void *) 0,     /* Will be patched in run-time */
 		.dstarg = 2
 	},
@@ -86,11 +87,18 @@
 int z8530_port_init(void)
 {
+	sysarg_t kaddr;
+	if (sysinfo_get_value("kbd.address.kernel", &kaddr) != EOK)
+		return -1;
+	
+	sysarg_t inr;
+	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
+		return -1;
+	
+	z8530_cmds[0].addr = (void *) kaddr + CHAN_A_STATUS;
+	z8530_cmds[3].addr = (void *) kaddr + CHAN_A_DATA;
+	
 	async_set_interrupt_received(z8530_irq_handler);
-	z8530_cmds[0].addr = (void *) sysinfo_value("kbd.address.kernel") +
-	    CHAN_A_STATUS;
-	z8530_cmds[3].addr = (void *) sysinfo_value("kbd.address.kernel") +
-	    CHAN_A_DATA;
-	ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(),
-	    sysinfo_value("kbd.inr"), &z8530_kbd);
+	ipc_register_irq(inr, device_assign_devno(), inr, &z8530_kbd);
+	
 	return 0;
 }
Index: uspace/srv/hw/bus/cuda_adb/cuda_adb.c
===================================================================
--- uspace/srv/hw/bus/cuda_adb/cuda_adb.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hw/bus/cuda_adb/cuda_adb.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -254,11 +254,14 @@
 static int cuda_init(void)
 {
+	if (sysinfo_get_value("cuda.address.physical", &(instance->cuda_physical)) != EOK)
+		return -1;
+	
+	if (sysinfo_get_value("cuda.address.kernel", &(instance->cuda_kernel)) != EOK)
+		return -1;
+	
 	void *vaddr;
-
-	instance->cuda_physical = sysinfo_value("cuda.address.physical");
-	instance->cuda_kernel = sysinfo_value("cuda.address.kernel");
-
 	if (pio_enable((void *) instance->cuda_physical, sizeof(cuda_t), &vaddr) != 0)
 		return -1;
+	
 	dev = vaddr;
 
Index: uspace/srv/hw/char/i8042/i8042.c
===================================================================
--- uspace/srv/hw/char/i8042/i8042.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hw/char/i8042/i8042.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -164,14 +164,27 @@
 static int i8042_init(void)
 {
+	if (sysinfo_get_value("i8042.address.physical", &i8042_physical) != EOK)
+		return -1;
+	
+	if (sysinfo_get_value("i8042.address.kernel", &i8042_kernel) != EOK)
+		return -1;
+	
 	void *vaddr;
-
-	i8042_physical = sysinfo_value("i8042.address.physical");
-	i8042_kernel = sysinfo_value("i8042.address.kernel");
 	if (pio_enable((void *) i8042_physical, sizeof(i8042_t), &vaddr) != 0)
 		return -1;
+	
 	i8042 = vaddr;
-
+	
+	sysarg_t inr_a;
+	sysarg_t inr_b;
+	
+	if (sysinfo_get_value("i8042.inr_a", &inr_a) != EOK)
+		return -1;
+	
+	if (sysinfo_get_value("i8042.inr_b", &inr_b) != EOK)
+		return -1;
+	
 	async_set_interrupt_received(i8042_irq_handler);
-
+	
 	/* Disable kbd and aux */
 	wait_ready();
@@ -186,8 +199,7 @@
 	i8042_kbd.cmds[0].addr = (void *) &((i8042_t *) i8042_kernel)->status;
 	i8042_kbd.cmds[3].addr = (void *) &((i8042_t *) i8042_kernel)->data;
-	ipc_register_irq(sysinfo_value("i8042.inr_a"), device_assign_devno(), 0, &i8042_kbd);
-	ipc_register_irq(sysinfo_value("i8042.inr_b"), device_assign_devno(), 0, &i8042_kbd);
-	printf("i8042: registered for interrupts %d and %d\n",
-	    sysinfo_value("i8042.inr_a"), sysinfo_value("i8042.inr_b"));
+	ipc_register_irq(inr_a, device_assign_devno(), 0, &i8042_kbd);
+	ipc_register_irq(inr_b, device_assign_devno(), 0, &i8042_kbd);
+	printf("%s: registered for interrupts %d and %d\n", NAME, inr_a, inr_b);
 
 	wait_ready();
Index: uspace/srv/hw/cir/fhc/fhc.c
===================================================================
--- uspace/srv/hw/cir/fhc/fhc.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hw/cir/fhc/fhc.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -109,14 +109,13 @@
 static bool fhc_init(void)
 {
-	ipcarg_t phonead;
+	sysarg_t paddr;
 
-	fhc_uart_size = sysinfo_value("fhc.uart.size");
-	fhc_uart_phys = (void *) sysinfo_value("fhc.uart.physical");
-	
-	if (!fhc_uart_size) {
+	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);
 	
@@ -132,6 +131,7 @@
 	printf(NAME ": FHC UART registers at %p, %d bytes\n", fhc_uart_phys,
 	    fhc_uart_size);
-
+	
 	async_set_client_connection(fhc_connection);
+	ipcarg_t phonead;
 	ipc_connect_to_me(PHONE_NS, SERVICE_FHC, 0, 0, &phonead);
 	
Index: uspace/srv/hw/cir/obio/obio.c
===================================================================
--- uspace/srv/hw/cir/obio/obio.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hw/cir/obio/obio.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -112,13 +112,12 @@
 static bool obio_init(void)
 {
-	ipcarg_t phonead;
-
-	base_phys = (void *) sysinfo_value("obio.base.physical");
+	sysarg_t paddr;
 	
-	if (!base_phys) {
+	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);
 	
@@ -133,6 +132,7 @@
 	
 	printf(NAME ": OBIO registers with base at %p\n", base_phys);
-
+	
 	async_set_client_connection(obio_connection);
+	ipcarg_t phonead;
 	ipc_connect_to_me(PHONE_NS, SERVICE_OBIO, 0, 0, &phonead);
 	
Index: uspace/srv/hw/netif/dp8390/Makefile
===================================================================
--- uspace/srv/hw/netif/dp8390/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hw/netif/dp8390/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -39,11 +39,9 @@
 -include $(CONFIG_MAKEFILE)
 
-ifeq ($(CONFIG_NETWORKING),modular)
-	BINARY = dp8390
+ifeq ($(CONFIG_NETIF_NIL_BUNDLE),y)
+	LIBS += $(USPACE_PREFIX)/srv/net/nil/eth/libeth.a
 endif
 
-ifeq ($(CONFIG_NETWORKING),module)
-	LIBRARY = libdp8390
-endif
+BINARY = dp8390
 
 SOURCES = \
Index: uspace/srv/hw/netif/dp8390/dp8390.c
===================================================================
--- uspace/srv/hw/netif/dp8390/dp8390.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hw/netif/dp8390/dp8390.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -37,9 +37,7 @@
 
 #include <net_byteorder.h>
-
+#include <netif_local.h>
 #include <packet/packet.h>
 #include <packet/packet_client.h>
-
-#include <netif.h>
 
 #include "dp8390_drv.h"
Index: uspace/srv/hw/netif/dp8390/dp8390_module.c
===================================================================
--- uspace/srv/hw/netif/dp8390/dp8390_module.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/hw/netif/dp8390/dp8390_module.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -50,6 +50,6 @@
 #include <net_device.h>
 #include <nil_interface.h>
-#include <netif.h>
-#include <netif_module.h>
+#include <netif_interface.h>
+#include <netif_local.h>
 
 #include "dp8390.h"
@@ -59,5 +59,5 @@
 /** DP8390 module name.
  */
-#define NAME	"dp8390 network interface"
+#define NAME  "dp8390"
 
 /** Returns the device from the interrupt call.
@@ -95,8 +95,4 @@
 };
 
-/** Network interface module global data.
- */
-netif_globals_t netif_globals;
-
 /** Handles the interrupt messages.
  *  This is the interrupt handler callback function.
@@ -104,5 +100,38 @@
  *  @param[in] call The interrupt message.
  */
-void irq_handler(ipc_callid_t iid, ipc_call_t * call);
+static void irq_handler(ipc_callid_t iid, ipc_call_t * call)
+{
+	netif_device_t * device;
+	dpeth_t * dep;
+	packet_t received;
+	device_id_t device_id;
+	int phone;
+
+	device_id = IRQ_GET_DEVICE(call);
+	fibril_rwlock_write_lock(&netif_globals.lock);
+	if(find_device(device_id, &device) != EOK){
+		fibril_rwlock_write_unlock(&netif_globals.lock);
+		return;
+	}
+	dep = (dpeth_t *) device->specific;
+	if (dep->de_mode != DEM_ENABLED){
+		fibril_rwlock_write_unlock(&netif_globals.lock);
+		return;
+	}
+	assert(dep->de_flags &DEF_ENABLED);
+	dep->de_int_pending = 0;
+	dp_check_ints(dep, IPC_GET_ISR(call));
+	if(dep->received_queue){
+		received = dep->received_queue;
+		phone = device->nil_phone;
+		dep->received_queue = NULL;
+		dep->received_count = 0;
+		fibril_rwlock_write_unlock(&netif_globals.lock);
+		nil_received_msg(phone, device_id, received, NULL);
+	}else{
+		fibril_rwlock_write_unlock(&netif_globals.lock);
+	}
+	ipc_answer_0(iid, EOK);
+}
 
 /** Changes the network interface state.
@@ -111,5 +140,17 @@
  *  @returns The new state.
  */
-int change_state(device_ref device, device_state_t 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){
@@ -120,5 +161,5 @@
 	ERROR_DECLARE;
 
-	device_ref device;
+	netif_device_t * device;
 	eth_stat_t * de_stat;
 
@@ -147,5 +188,5 @@
 	ERROR_DECLARE;
 
-	device_ref device;
+	netif_device_t * device;
 
 	if(! address){
@@ -158,56 +199,13 @@
 }
 
-void irq_handler(ipc_callid_t iid, ipc_call_t * call)
-{
-	device_ref device;
-	dpeth_t * dep;
-	packet_t received;
-	device_id_t device_id;
-	int phone;
-
-	device_id = IRQ_GET_DEVICE(call);
-	fibril_rwlock_write_lock(&netif_globals.lock);
-	if(find_device(device_id, &device) != EOK){
-		fibril_rwlock_write_unlock(&netif_globals.lock);
-		return;
-	}
-	dep = (dpeth_t *) device->specific;
-	if (dep->de_mode != DEM_ENABLED){
-		fibril_rwlock_write_unlock(&netif_globals.lock);
-		return;
-	}
-	assert(dep->de_flags &DEF_ENABLED);
-	dep->de_int_pending = 0;
-//	remove debug print:
-#ifdef CONFIG_DEBUG
-	printf("I%d: 0x%x\n", device_id, IPC_GET_ISR(call));
-#endif
-	dp_check_ints(dep, IPC_GET_ISR(call));
-	if(dep->received_queue){
-		received = dep->received_queue;
-		phone = device->nil_phone;
-		dep->received_queue = NULL;
-		dep->received_count = 0;
-		fibril_rwlock_write_unlock(&netif_globals.lock);
-//	remove debug dump:
-#ifdef CONFIG_DEBUG
-	uint8_t * data;
-	data = packet_get_data(received);
-	printf("Receiving packet:\n\tid\t= %d\n\tlength\t= %d\n\tdata\t= %.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX\n\t\t%.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX\n", packet_get_id(received), packet_get_data_length(received), data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31], data[32], data[33], data[34], data[35], data[36], data[37], data[38], data[39], data[40], data[41], data[42], data[43], data[44], data[45], data[46], data[47], data[48], data[49], data[50], data[51], data[52], data[53], data[54], data[55], data[56], data[57], data[58], data[59]);
-#endif
-		nil_received_msg(phone, device_id, received, NULL);
-	}else{
-		fibril_rwlock_write_unlock(&netif_globals.lock);
-	}
-	ipc_answer_0(iid, EOK);
-}
+
 
 int netif_probe_message(device_id_t device_id, int irq, uintptr_t io){
 	ERROR_DECLARE;
 
-	device_ref device;
-	dpeth_t * dep;
-
-	device = (device_ref) malloc(sizeof(device_t));
+	netif_device_t * device;
+	dpeth_t * dep;
+
+	device = (netif_device_t *) malloc(sizeof(netif_device_t));
 	if(! device){
 		return ENOMEM;
@@ -218,5 +216,5 @@
 		return ENOMEM;
 	}
-	bzero(device, sizeof(device_t));
+	bzero(device, sizeof(netif_device_t));
 	bzero(dep, sizeof(dpeth_t));
 	device->device_id = device_id;
@@ -233,5 +231,5 @@
 		return ERROR_CODE;
 	}
-	if(ERROR_OCCURRED(device_map_add(&netif_globals.device_map, device->device_id, device))){
+	if(ERROR_OCCURRED(netif_device_map_add(&netif_globals.device_map, device->device_id, device))){
 		free(dep);
 		free(device);
@@ -244,5 +242,5 @@
 	ERROR_DECLARE;
 
-	device_ref device;
+	netif_device_t * device;
 	dpeth_t * dep;
 	packet_t next;
@@ -257,10 +255,4 @@
 	do{
 		next = pq_detach(packet);
-//		remove debug dump:
-#ifdef CONFIG_DEBUG
-		uint8_t * data;
-		data = packet_get_data(packet);
-		printf("Sending packet:\n\tid\t= %d\n\tlength\t= %d\n\tdata\t= %.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX\n\t\t%.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX:%.2hhX %.2hhX %.2hhX %.2hhX\n", packet_get_id(packet), packet_get_data_length(packet), data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31], data[32], data[33], data[34], data[35], data[36], data[37], data[38], data[39], data[40], data[41], data[42], data[43], data[44], data[45], data[46], data[47], data[48], data[49], data[50], data[51], data[52], data[53], data[54], data[55], data[56], data[57], data[58], data[59]);
-#endif
 		if(do_pwrite(dep, packet, FALSE) != EBUSY){
 			netif_pq_release(packet_get_id(packet));
@@ -271,5 +263,5 @@
 }
 
-int netif_start_message(device_ref device){
+int netif_start_message(netif_device_t * device){
 	ERROR_DECLARE;
 
@@ -290,5 +282,5 @@
 }
 
-int netif_stop_message(device_ref device){
+int netif_stop_message(netif_device_t * device){
 	dpeth_t * dep;
 
@@ -302,10 +294,4 @@
 }
 
-int change_state(device_ref device, device_state_t state){
-	device->state = state;
-	printf("State changed to %s\n", (state == NETIF_ACTIVE) ? "ACTIVE" : "STOPPED");
-	return state;
-}
-
 int netif_initialize(void){
 	ipcarg_t phonehash;
@@ -315,8 +301,4 @@
 	return REGISTER_ME(SERVICE_DP8390, &phonehash);
 }
-
-#ifdef CONFIG_NETWORKING_modular
-
-#include <netif_standalone.h>
 
 /** Default thread for new connections.
@@ -346,5 +328,6 @@
 		
 		/* Process the message */
-		int res = netif_module_message(callid, &call, &answer, &answer_count);
+		int res = netif_module_message(NAME, callid, &call, &answer,
+		    &answer_count);
 		
 		/* End if said to either by the message or the processing result */
@@ -370,18 +353,10 @@
 	ERROR_DECLARE;
 	
-	/* Print the module label */
-	printf("Task %d - %s\n", task_get_id(), NAME);
+	/* Start the module */
+	if (ERROR_OCCURRED(netif_module_start(netif_client_connection)))
+		return ERROR_CODE;
 	
-	/* Start the module */
-	if (ERROR_OCCURRED(netif_module_start(netif_client_connection))) {
-		printf(" - ERROR %i\n", ERROR_CODE);
-		return ERROR_CODE;
-	}
-	
-	return EOK;
-}
-
-#endif /* CONFIG_NETWORKING_modular */
-
+	return EOK;
+}
 
 /** @}
Index: uspace/srv/net/cfg/Makefile
===================================================================
--- uspace/srv/net/cfg/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/srv/net/cfg/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,60 @@
+#
+# Copyright (c) 2010 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 = ../../..
+ROOT_PATH = $(USPACE_PREFIX)/..
+
+COMMON_MAKEFILE = $(ROOT_PATH)/Makefile.common
+CONFIG_MAKEFILE = $(ROOT_PATH)/Makefile.config
+
+-include $(COMMON_MAKEFILE)
+-include $(CONFIG_MAKEFILE)
+
+ifeq ($(CONFIG_NETIF_NIL_BUNDLE),y)
+	LO_SOURCE = lo.netif_nil_bundle
+	NE2K_SOURCE = ne2k.netif_nil_bundle
+else
+	LO_SOURCE = lo.netif_standalone
+	NE2K_SOURCE = ne2k.netif_standalone
+endif
+
+LO_TARGET = lo
+NE2K_TARGET = ne2k
+
+.PHONY: all clean
+
+all: $(LO_TARGET) $(NE2K_TARGET)
+
+clean:
+	rm -f $(LO_TARGET) $(NE2K_TARGET)
+
+$(LO_TARGET): $(LO_SOURCE)
+	cp $< $@
+
+$(NE2K_TARGET): $(NE2K_SOURCE)
+	cp $< $@
Index: uspace/srv/net/cfg/general
===================================================================
--- uspace/srv/net/cfg/general	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/srv/net/cfg/general	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,12 @@
+# general configuration
+
+IPV=4
+IP_ROUTING=no
+
+MTU=1500
+
+ICMP_ERROR_REPORTING=yes
+ICMP_ECHO_REPLYING=yes
+
+UDP_CHECKSUM_COMPUTING=yes
+UDP_AUTOBINDING=yes
Index: uspace/srv/net/cfg/lo.netif_nil_bundle
===================================================================
--- uspace/srv/net/cfg/lo.netif_nil_bundle	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/srv/net/cfg/lo.netif_nil_bundle	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,13 @@
+# loopback configuration
+
+NAME=lo
+
+NETIF=lo
+NIL=lo
+IL=ip
+
+IP_CONFIG=static
+IP_ADDR=127.0.0.1
+IP_NETMASK=255.0.0.0
+
+MTU=15535
Index: uspace/srv/net/cfg/lo.netif_standalone
===================================================================
--- uspace/srv/net/cfg/lo.netif_standalone	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/srv/net/cfg/lo.netif_standalone	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,13 @@
+# loopback configuration
+
+NAME=lo
+
+NETIF=lo
+NIL=nildummy
+IL=ip
+
+IP_CONFIG=static
+IP_ADDR=127.0.0.1
+IP_NETMASK=255.0.0.0
+
+MTU=15535
Index: pace/srv/net/cfg/modular/general
===================================================================
--- uspace/srv/net/cfg/modular/general	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,12 +1,0 @@
-# general configuration
-
-IPV=4
-IP_ROUTING=no
-
-MTU=1500
-
-ICMP_ERROR_REPORTING=yes
-ICMP_ECHO_REPLYING=yes
-
-UDP_CHECKSUM_COMPUTING=yes
-UDP_AUTOBINDING=yes
Index: pace/srv/net/cfg/modular/lo
===================================================================
--- uspace/srv/net/cfg/modular/lo	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,13 +1,0 @@
-# loopback configuration
-
-NAME=lo
-
-NETIF=lo
-NIL=nildummy
-IL=ip
-
-IP_CONFIG=static
-IP_ADDR=127.0.0.1
-IP_NETMASK=255.0.0.0
-
-MTU=15535
Index: pace/srv/net/cfg/modular/ne2k
===================================================================
--- uspace/srv/net/cfg/modular/ne2k	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,25 +1,0 @@
-# DP8390 (NE2k) configuration
-
-NAME=ne2k
-
-NETIF=dp8390
-NIL=ethernet
-IL=ip
-
-# sysinfo_value("netif.dp8390.inr")
-IRQ=9
-IO=300
-
-# 8023_2_LSAP, 8023_2_SNAP
-ETH_MODE=DIX
-ETH_DUMMY=no
-
-IP_CONFIG=static
-IP_ADDR=10.0.2.15
-IP_ROUTING=yes
-IP_NETMASK=255.255.255.240
-IP_BROADCAST=10.0.2.255
-IP_GATEWAY=10.0.2.2
-ARP=arp
-
-MTU=1492
Index: pace/srv/net/cfg/module/general
===================================================================
--- uspace/srv/net/cfg/module/general	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,12 +1,0 @@
-# general configuration
-
-IPV=4
-IP_ROUTING=no
-
-MTU=1500
-
-ICMP_ERROR_REPORTING=yes
-ICMP_ECHO_REPLYING=yes
-
-UDP_CHECKSUM_COMPUTING=yes
-UDP_AUTOBINDING=yes
Index: pace/srv/net/cfg/module/lo
===================================================================
--- uspace/srv/net/cfg/module/lo	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,13 +1,0 @@
-# loopback configuration
-
-NAME=lo
-
-NETIF=lo
-NIL=lo
-IL=ip
-
-IP_CONFIG=static
-IP_ADDR=127.0.0.1
-IP_NETMASK=255.0.0.0
-
-MTU=15535
Index: pace/srv/net/cfg/module/ne2k
===================================================================
--- uspace/srv/net/cfg/module/ne2k	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ 	(revision )
@@ -1,25 +1,0 @@
-# DP8390 (NE2k) configuration
-
-NAME=ne2k
-
-NETIF=dp8390
-NIL=dp8390
-IL=ip
-
-# sysinfo_value("netif.dp8390.inr")
-IRQ=9
-IO=300
-
-# 8023_2_LSAP, 8023_2_SNAP
-ETH_MODE=DIX
-ETH_DUMMY=no
-
-IP_CONFIG=static
-IP_ADDR=10.0.2.15
-IP_ROUTING=yes
-IP_NETMASK=255.255.255.240
-IP_BROADCAST=10.0.2.255
-IP_GATEWAY=10.0.2.2
-ARP=arp
-
-MTU=1492
Index: uspace/srv/net/cfg/ne2k.netif_nil_bundle
===================================================================
--- uspace/srv/net/cfg/ne2k.netif_nil_bundle	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/srv/net/cfg/ne2k.netif_nil_bundle	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,24 @@
+# DP8390 (NE2k) configuration
+
+NAME=ne2k
+
+NETIF=dp8390
+NIL=dp8390
+IL=ip
+
+IRQ=9
+IO=300
+
+# 8023_2_LSAP, 8023_2_SNAP
+ETH_MODE=DIX
+ETH_DUMMY=no
+
+IP_CONFIG=static
+IP_ADDR=10.0.2.15
+IP_ROUTING=yes
+IP_NETMASK=255.255.255.240
+IP_BROADCAST=10.0.2.255
+IP_GATEWAY=10.0.2.2
+ARP=arp
+
+MTU=1492
Index: uspace/srv/net/cfg/ne2k.netif_standalone
===================================================================
--- uspace/srv/net/cfg/ne2k.netif_standalone	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
+++ uspace/srv/net/cfg/ne2k.netif_standalone	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -0,0 +1,24 @@
+# DP8390 (NE2k) configuration
+
+NAME=ne2k
+
+NETIF=dp8390
+NIL=eth
+IL=ip
+
+IRQ=9
+IO=300
+
+# 8023_2_LSAP, 8023_2_SNAP
+ETH_MODE=DIX
+ETH_DUMMY=no
+
+IP_CONFIG=static
+IP_ADDR=10.0.2.15
+IP_ROUTING=yes
+IP_NETMASK=255.255.255.240
+IP_BROADCAST=10.0.2.255
+IP_GATEWAY=10.0.2.2
+ARP=arp
+
+MTU=1492
Index: uspace/srv/net/il/arp/arp.c
===================================================================
--- uspace/srv/net/il/arp/arp.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/il/arp/arp.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -57,5 +57,8 @@
 #include <packet/packet.h>
 #include <packet/packet_client.h>
+#include <packet_remote.h>
 #include <il_messages.h>
+#include <il_interface.h>
+#include <il_local.h>
 #include <arp_messages.h>
 
@@ -68,5 +71,5 @@
 /** ARP module name.
  */
-#define NAME	"ARP protocol"
+#define NAME  "arp"
 
 /** ARP global data.
@@ -338,5 +341,6 @@
 			return ERROR_CODE;
 		}
-		printf("New device registered:\n\tid\t= %d\n\ttype\t= 0x%x\n\tservice\t= %d\n\tproto\t= %d\n", device->device_id, device->hardware, device->service, protocol);
+		printf("%s: Device registered (id: %d, type: 0x%x, service: %d, proto: %d)\n",
+		    NAME, device->device_id, device->hardware, device->service, protocol);
 	}
 	fibril_rwlock_write_unlock(&arp_globals.lock);
@@ -369,7 +373,9 @@
 }
 
-int arp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
+int arp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
+    ipc_call_t *answer, int *answer_count)
+{
 	ERROR_DECLARE;
-
+	
 	measured_string_ref address;
 	measured_string_ref translation;
@@ -377,8 +383,7 @@
 	packet_t packet;
 	packet_t next;
-
-//	printf("message %d - %d\n", IPC_GET_METHOD(*call), NET_ARP_FIRST);
+	
 	*answer_count = 0;
-	switch(IPC_GET_METHOD(*call)){
+	switch (IPC_GET_METHOD(*call)) {
 		case IPC_M_PHONE_HUNGUP:
 			return EOK;
@@ -417,5 +422,5 @@
 			return EOK;
 		case NET_IL_RECEIVED:
-			if(! ERROR_OCCURRED(packet_translate(arp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
+			if(! ERROR_OCCURRED(packet_translate_remote(arp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
 				fibril_rwlock_read_lock(&arp_globals.lock);
 				do{
@@ -423,5 +428,5 @@
 					ERROR_CODE = arp_receive_message(IPC_GET_DEVICE(call), packet);
 					if(ERROR_CODE != 1){
-						pq_release(arp_globals.net_phone, packet_get_id(packet));
+						pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
 					}
 					packet = next;
@@ -433,4 +438,5 @@
 			return arp_mtu_changed_message(IPC_GET_DEVICE(call), IPC_GET_MTU(call));
 	}
+	
 	return ENOTSUP;
 }
@@ -569,5 +575,5 @@
 		return NULL;
 	}
-	packet = packet_get_4(arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix);
+	packet = packet_get_4_remote(arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix);
 	if(! packet){
 		return NULL;
@@ -575,5 +581,5 @@
 	header = (arp_header_ref) packet_suffix(packet, length);
 	if(! header){
-		pq_release(arp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
 		return NULL;
 	}
@@ -592,5 +598,5 @@
 	memcpy(((uint8_t *) header) + length, target->value, target->length);
 	if(packet_set_addr(packet, (uint8_t *) device->addr->value, (uint8_t *) device->broadcast_addr->value, CONVERT_SIZE(char, uint8_t, device->addr->length)) != EOK){
-		pq_release(arp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
 		return NULL;
 	}
@@ -618,8 +624,4 @@
 	}
 }
-
-#ifdef CONFIG_NETWORKING_modular
-
-#include <il_standalone.h>
 
 /** Default thread for new connections.
@@ -649,5 +651,6 @@
 		
 		/* Process the message */
-		int res = il_module_message(callid, &call, &answer, &answer_count);
+		int res = il_module_message_standalone(callid, &call, &answer,
+		    &answer_count);
 		
 		/* End if said to either by the message or the processing result */
@@ -673,17 +676,10 @@
 	ERROR_DECLARE;
 	
-	/* Print the module label */
-	printf("Task %d - %s\n", task_get_id(), NAME);
+	/* Start the module */
+	if (ERROR_OCCURRED(il_module_start_standalone(il_client_connection)))
+		return ERROR_CODE;
 	
-	/* Start the module */
-	if (ERROR_OCCURRED(il_module_start(il_client_connection))) {
-		printf(" - ERROR %i\n", ERROR_CODE);
-		return ERROR_CODE;
-	}
-	
-	return EOK;
-}
-
-#endif /* CONFIG_NETWORKING_modular */
+	return EOK;
+}
 
 /** @}
Index: uspace/srv/net/il/arp/arp_module.c
===================================================================
--- uspace/srv/net/il/arp/arp_module.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/il/arp/arp_module.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -48,5 +48,5 @@
 #include <net_interface.h>
 #include <packet/packet.h>
-#include <il_standalone.h>
+#include <il_local.h>
 
 #include "arp.h"
@@ -65,6 +65,6 @@
  *  @returns Other error codes as defined for the arp_message() function.
  */
-int il_module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
-	return arp_message(callid, call, answer, answer_count);
+int il_module_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
+	return arp_message_standalone(callid, call, answer, answer_count);
 }
 
@@ -76,20 +76,20 @@
  *  @returns Other error codes as defined for the REGISTER_ME() macro function.
  */
-int il_module_start(async_client_conn_t client_connection){
+int il_module_start_standalone(async_client_conn_t client_connection){
 	ERROR_DECLARE;
-
-	ipcarg_t phonehash;
-
+	
 	async_set_client_connection(client_connection);
 	arp_globals.net_phone = net_connect_module(SERVICE_NETWORKING);
 	ERROR_PROPAGATE(pm_init());
-	if(ERROR_OCCURRED(arp_initialize(client_connection))
-		|| ERROR_OCCURRED(REGISTER_ME(SERVICE_ARP, &phonehash))){
+	
+	ipcarg_t phonehash;
+	if (ERROR_OCCURRED(arp_initialize(client_connection))
+	    || ERROR_OCCURRED(REGISTER_ME(SERVICE_ARP, &phonehash))) {
 		pm_destroy();
 		return ERROR_CODE;
 	}
-
+	
 	async_manager();
-
+	
 	pm_destroy();
 	return EOK;
Index: uspace/srv/net/il/arp/arp_module.h
===================================================================
--- uspace/srv/net/il/arp/arp_module.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/il/arp/arp_module.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -58,5 +58,5 @@
  *  @see IS_NET_ARP_MESSAGE()
  */
-int arp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
+int arp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
 
 #endif
Index: uspace/srv/net/il/ip/ip.c
===================================================================
--- uspace/srv/net/il/ip/ip.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/il/ip/ip.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -69,6 +69,9 @@
 #include <adt/module_map.h>
 #include <packet/packet_client.h>
+#include <packet_remote.h>
 #include <nil_messages.h>
 #include <il_messages.h>
+#include <il_local.h>
+#include <ip_local.h>
 
 #include "ip.h"
@@ -79,5 +82,5 @@
 /** IP module name.
  */
-#define NAME	"IP protocol"
+#define NAME  "ip"
 
 /** IP version 4.
@@ -424,5 +427,5 @@
 }
 
-int ip_device_req(int il_phone, device_id_t device_id, services_t netif){
+int ip_device_req_local(int il_phone, device_id_t device_id, services_t netif){
 	ERROR_DECLARE;
 
@@ -430,5 +433,4 @@
 	ip_route_ref route;
 	int index;
-	char * data;
 
 	ip_netif = (ip_netif_ref) malloc(sizeof(ip_netif_t));
@@ -454,25 +456,28 @@
 	}
 	// print the settings
-	printf("New device registered:\n\tid\t= %d\n\tphone\t= %d\n\tIPV\t= %d\n", ip_netif->device_id, ip_netif->phone, ip_netif->ipv);
-	printf("\tconfiguration\t= %s\n", ip_netif->dhcp ? "dhcp" : "static");
+	printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n",
+	    NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv,
+	    ip_netif->dhcp ? "dhcp" : "static");
+	
 	// TODO ipv6 addresses
-	data = (char *) malloc(INET_ADDRSTRLEN);
-	if(data){
-		for(index = 0; index < ip_routes_count(&ip_netif->routes); ++ index){
-			route = ip_routes_get_index(&ip_netif->routes, index);
-			if(route){
-				printf("\tRouting %d:\n", index);
-				inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr, data, INET_ADDRSTRLEN);
-				printf("\t\taddress\t= %s\n", data);
-				inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr, data, INET_ADDRSTRLEN);
-				printf("\t\tnetmask\t= %s\n", data);
-				inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr, data, INET_ADDRSTRLEN);
-				printf("\t\tgateway\t= %s\n", data);
-			}
-		}
-		inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, data, INET_ADDRSTRLEN);
-		printf("\t\tbroadcast\t= %s\n", data);
-		free(data);
-	}
+	
+	char address[INET_ADDRSTRLEN];
+	char netmask[INET_ADDRSTRLEN];
+	char gateway[INET_ADDRSTRLEN];
+	
+	for (index = 0; index < ip_routes_count(&ip_netif->routes); ++ index){
+		route = ip_routes_get_index(&ip_netif->routes, index);
+		if (route) {
+			inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr, address, INET_ADDRSTRLEN);
+			inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr, netmask, INET_ADDRSTRLEN);
+			inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr, gateway, INET_ADDRSTRLEN);
+			printf("%s: Route %d (address: %s, netmask: %s, gateway: %s)\n",
+			    NAME, index, address, netmask, gateway);
+		}
+	}
+	
+	inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address, INET_ADDRSTRLEN);
+	printf("%s: Broadcast (%s)\n", NAME, address);
+	
 	fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
 	return EOK;
@@ -595,5 +600,5 @@
 	}
 	netif->packet_dimension.content = mtu;
-	printf("ip - device %d changed mtu to %d\n\n", device_id, mtu);
+	printf("%s: Device %d changed MTU to %d\n", NAME, device_id, mtu);
 	fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
 	return EOK;
@@ -611,5 +616,5 @@
 	}
 	netif->state = state;
-	printf("ip - device %d changed state to %d\n\n", device_id, state);
+	printf("%s: Device %d changed state to %d\n", NAME, device_id, state);
 	fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
 	return EOK;
@@ -646,10 +651,13 @@
 		return index;
 	}
-	printf("New protocol registered:\n\tprotocol\t= %d\n\tphone\t= %d\n", proto->protocol, proto->phone);
+	
+	printf("%s: Protocol registered (protocol: %d, phone: %d)\n",
+	    NAME, proto->protocol, proto->phone);
+	
 	fibril_rwlock_write_unlock(&ip_globals.protos_lock);
 	return EOK;
 }
 
-int ip_send_msg(int il_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error){
+int ip_send_msg_local(int il_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error){
 	ERROR_DECLARE;
 
@@ -777,5 +785,5 @@
 //			sleep(1);
 //			ERROR_PROPAGATE(arp_translate_req(netif->arp->phone, netif->device_id, SERVICE_IP, &destination, &translation, &data));
-			pq_release(ip_globals.net_phone, packet_get_id(packet));
+			pq_release_remote(ip_globals.net_phone, packet_get_id(packet));
 			return ERROR_CODE;
 		}
@@ -794,5 +802,5 @@
 	}else translation = NULL;
 	if(ERROR_OCCURRED(ip_prepare_packet(src, dest, packet, translation))){
-		pq_release(ip_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(ip_globals.net_phone, packet_get_id(packet));
 	}else{
 		packet = ip_split_packet(packet, netif->packet_dimension.prefix, netif->packet_dimension.content, netif->packet_dimension.suffix, netif->packet_dimension.addr_len, error);
@@ -886,54 +894,69 @@
 }
 
-int ip_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
+int ip_message_standalone(ipc_callid_t callid, ipc_call_t *call,
+    ipc_call_t *answer, int * answer_count)
+{
 	ERROR_DECLARE;
-
+	
 	packet_t packet;
-	struct sockaddr * addr;
+	struct sockaddr *addr;
 	size_t addrlen;
 	size_t prefix;
 	size_t suffix;
 	size_t content;
-	ip_pseudo_header_ref header;
+	void *header;
 	size_t headerlen;
 	device_id_t device_id;
-
+	
 	*answer_count = 0;
-	switch(IPC_GET_METHOD(*call)){
+	switch (IPC_GET_METHOD(*call)) {
 		case IPC_M_PHONE_HUNGUP:
 			return EOK;
 		case NET_IL_DEVICE:
-			return ip_device_req(0, IPC_GET_DEVICE(call), IPC_GET_SERVICE(call));
+			return ip_device_req_local(0, IPC_GET_DEVICE(call),
+			    IPC_GET_SERVICE(call));
 		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_SEND:
-			ERROR_PROPAGATE(packet_translate(ip_globals.net_phone, &packet, IPC_GET_PACKET(call)));
-			return ip_send_msg(0, IPC_GET_DEVICE(call), packet, 0, IPC_GET_ERROR(call));
+			ERROR_PROPAGATE(packet_translate_remote(ip_globals.net_phone, &packet,
+			    IPC_GET_PACKET(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:
-			ERROR_PROPAGATE(packet_translate(ip_globals.net_phone, &packet, IPC_GET_PACKET(call)));
+			ERROR_PROPAGATE(packet_translate_remote(ip_globals.net_phone, &packet,
+			    IPC_GET_PACKET(call)));
 			return ip_receive_message(IPC_GET_DEVICE(call), packet);
 		case NET_IP_RECEIVED_ERROR:
-			ERROR_PROPAGATE(packet_translate(ip_globals.net_phone, &packet, IPC_GET_PACKET(call)));
-			return ip_received_error_msg(0, IPC_GET_DEVICE(call), packet, IPC_GET_TARGET(call), IPC_GET_ERROR(call));
+			ERROR_PROPAGATE(packet_translate_remote(ip_globals.net_phone, &packet,
+			    IPC_GET_PACKET(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(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(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:
 			ERROR_PROPAGATE(data_receive((void **) &addr, &addrlen));
-			ERROR_PROPAGATE(ip_get_route_req(0, IP_GET_PROTOCOL(call), addr, (socklen_t) addrlen,
-			    &device_id, &header, &headerlen));
+			ERROR_PROPAGATE(ip_get_route_req_local(0, IP_GET_PROTOCOL(call),
+			    addr, (socklen_t) addrlen, &device_id, &header, &headerlen));
 			IPC_SET_DEVICE(answer, device_id);
 			IP_SET_HEADERLEN(answer, headerlen);
+			
 			*answer_count = 2;
-			if(! ERROR_OCCURRED(data_reply(&headerlen, sizeof(headerlen)))){
+			
+			if (!ERROR_OCCURRED(data_reply(&headerlen, sizeof(headerlen))))
 				ERROR_CODE = data_reply(header, headerlen);
-			}
+			
 			free(header);
 			return ERROR_CODE;
 		case NET_IL_PACKET_SPACE:
-			ERROR_PROPAGATE(ip_packet_size_message(IPC_GET_DEVICE(call), &addrlen, &prefix, &content, &suffix));
+			ERROR_PROPAGATE(ip_packet_size_message(IPC_GET_DEVICE(call),
+			    &addrlen, &prefix, &content, &suffix));
 			IPC_SET_ADDR(answer, addrlen);
 			IPC_SET_PREFIX(answer, prefix);
@@ -943,14 +966,20 @@
 			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));
+	}
+	
 	return ENOTSUP;
 }
 
-int ip_packet_size_req(int ip_phone, device_id_t device_id, packet_dimension_ref packet_dimension){
-	if(! packet_dimension){
+int ip_packet_size_req_local(int ip_phone, device_id_t device_id,
+    packet_dimension_ref packet_dimension)
+{
+	if (!packet_dimension)
 		return EBADMEM;
-	}
-	return ip_packet_size_message(device_id, &packet_dimension->addr_len, &packet_dimension->prefix, &packet_dimension->content, &packet_dimension->suffix);
+	
+	return ip_packet_size_message(device_id, &packet_dimension->addr_len,
+	    &packet_dimension->prefix, &packet_dimension->content,
+	    &packet_dimension->suffix);
 }
 
@@ -998,5 +1027,5 @@
 }
 
-int ip_add_route_req(int ip_phone, device_id_t device_id, in_addr_t address, in_addr_t netmask, in_addr_t gateway){
+int ip_add_route_req_local(int ip_phone, device_id_t device_id, in_addr_t address, in_addr_t netmask, in_addr_t gateway){
 	ip_route_ref route;
 	ip_netif_ref netif;
@@ -1062,5 +1091,6 @@
 }
 
-int ip_set_gateway_req(int ip_phone, device_id_t device_id, in_addr_t gateway){
+int ip_set_gateway_req_local(int ip_phone, device_id_t device_id, in_addr_t gateway)
+{
 	ip_netif_ref netif;
 
@@ -1107,5 +1137,5 @@
 					}
 				}else{
-					pq_release(ip_globals.net_phone, packet_get_id(next));
+					pq_release_remote(ip_globals.net_phone, packet_get_id(next));
 				}
 				next = new_packet;
@@ -1148,5 +1178,5 @@
 	}
 	// create the last fragment
-	new_packet = packet_get_4(ip_globals.net_phone, prefix, length, suffix, ((addrlen > addr_len) ? addrlen : addr_len));
+	new_packet = packet_get_4_remote(ip_globals.net_phone, prefix, length, suffix, ((addrlen > addr_len) ? addrlen : addr_len));
 	if(! new_packet){
 		return ENOMEM;
@@ -1172,5 +1202,5 @@
 	// create middle framgents
 	while(IP_TOTAL_LENGTH(header) > length){
-		new_packet = packet_get_4(ip_globals.net_phone, prefix, length, suffix, ((addrlen >= addr_len) ? addrlen : addr_len));
+		new_packet = packet_get_4_remote(ip_globals.net_phone, prefix, length, suffix, ((addrlen >= addr_len) ? addrlen : addr_len));
 		if(! new_packet){
 			return ENOMEM;
@@ -1352,5 +1382,18 @@
 }
 
-int ip_received_error_msg(int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error){
+/** Notify the IP module about the received error notification packet.
+ *
+ * @param[in] ip_phone  The IP module phone used for (semi)remote calls.
+ * @param[in] device_id The device identifier.
+ * @param[in] packet    The received packet or the received packet queue.
+ * @param[in] target    The target internetwork module service to be
+ *                      delivered to.
+ * @param[in] error     The packet error reporting service. Prefixes the
+ *                      received packet.
+ *
+ * @return EOK on success.
+ *
+ */
+int ip_received_error_msg_local(int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error){
 	uint8_t * data;
 	int offset;
@@ -1487,5 +1530,5 @@
 	next = pq_detach(packet);
 	if(next){
-		pq_release(ip_globals.net_phone, packet_get_id(next));
+		pq_release_remote(ip_globals.net_phone, packet_get_id(next));
 	}
 	if(! header){
@@ -1551,9 +1594,9 @@
 
 int ip_release_and_return(packet_t packet, int result){
-	pq_release(ip_globals.net_phone, packet_get_id(packet));
+	pq_release_remote(ip_globals.net_phone, packet_get_id(packet));
 	return result;
 }
 
-int ip_get_route_req(int ip_phone, ip_protocol_t protocol, const struct sockaddr * destination, socklen_t addrlen, device_id_t * device_id, ip_pseudo_header_ref * header, size_t * headerlen){
+int ip_get_route_req_local(int ip_phone, ip_protocol_t protocol, const struct sockaddr * destination, socklen_t addrlen, device_id_t * device_id, void **header, size_t * headerlen){
 	struct sockaddr_in * address_in;
 //	struct sockaddr_in6 *	address_in6;
@@ -1619,11 +1662,7 @@
 	header_in->protocol = protocol;
 	header_in->data_length = 0;
-	*header = (ip_pseudo_header_ref) header_in;
+	*header = header_in;
 	return EOK;
 }
-
-#ifdef CONFIG_NETWORKING_modular
-
-#include <il_standalone.h>
 
 /** Default thread for new connections.
@@ -1653,5 +1692,6 @@
 		
 		/* Process the message */
-		int res = il_module_message(callid, &call, &answer, &answer_count);
+		int res = il_module_message_standalone(callid, &call, &answer,
+		    &answer_count);
 		
 		/* End if said to either by the message or the processing result */
@@ -1677,18 +1717,11 @@
 	ERROR_DECLARE;
 	
-	/* Print the module label */
-	printf("Task %d - %s\n", task_get_id(), NAME);
-	
 	/* Start the module */
-	if (ERROR_OCCURRED(il_module_start(il_client_connection))) {
-		printf(" - ERROR %i\n", ERROR_CODE);
+	if (ERROR_OCCURRED(il_module_start_standalone(il_client_connection)))
 		return ERROR_CODE;
-	}
 	
 	return EOK;
 }
 
-#endif /* CONFIG_NETWORKING_modular */
-
 /** @}
  */
Index: uspace/srv/net/il/ip/ip_module.c
===================================================================
--- uspace/srv/net/il/ip/ip_module.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/il/ip/ip_module.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -47,5 +47,5 @@
 #include <net_interface.h>
 #include <packet/packet.h>
-#include <il_standalone.h>
+#include <il_local.h>
 
 #include "ip.h"
@@ -54,5 +54,5 @@
 /** IP module global data.
  */
-extern ip_globals_t	ip_globals;
+extern ip_globals_t ip_globals;
 
 /** Processes the IP message.
@@ -64,6 +64,6 @@
  *  @returns Other error codes as defined for the ip_message() function.
  */
-int il_module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
-	return ip_message(callid, call, answer, answer_count);
+int il_module_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
+	return ip_message_standalone(callid, call, answer, answer_count);
 }
 
@@ -75,20 +75,20 @@
  *  @returns Other error codes as defined for the REGISTER_ME() macro function.
  */
-int il_module_start(async_client_conn_t client_connection){
+int il_module_start_standalone(async_client_conn_t client_connection){
 	ERROR_DECLARE;
-
-	ipcarg_t phonehash;
-
+	
 	async_set_client_connection(client_connection);
 	ip_globals.net_phone = net_connect_module(SERVICE_NETWORKING);
 	ERROR_PROPAGATE(pm_init());
-	if(ERROR_OCCURRED(ip_initialize(client_connection))
-		|| ERROR_OCCURRED(REGISTER_ME(SERVICE_IP, &phonehash))){
+	
+	ipcarg_t phonehash;
+	if (ERROR_OCCURRED(ip_initialize(client_connection))
+	    || ERROR_OCCURRED(REGISTER_ME(SERVICE_IP, &phonehash))) {
 		pm_destroy();
 		return ERROR_CODE;
 	}
-
+	
 	async_manager();
-
+	
 	pm_destroy();
 	return EOK;
Index: uspace/srv/net/il/ip/ip_module.h
===================================================================
--- uspace/srv/net/il/ip/ip_module.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/il/ip/ip_module.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -59,5 +59,5 @@
  *  @see IS_NET_IP_MESSAGE()
  */
-int ip_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
+int ip_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
 
 #endif
Index: uspace/srv/net/net/Makefile
===================================================================
--- uspace/srv/net/net/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/net/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -30,6 +30,6 @@
 USPACE_PREFIX = ../../..
 ROOT_PATH = $(USPACE_PREFIX)/..
-LIBS = $(LIBNETIF_PREFIX)/libnetif.a $(LIBNET_PREFIX)/libnet.a $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBNETIF_PREFIX)/include -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
+LIBS = $(LIBNET_PREFIX)/libnet.a $(LIBSOCKET_PREFIX)/libsocket.a
+EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
 
 COMMON_MAKEFILE = $(ROOT_PATH)/Makefile.common
Index: uspace/srv/net/net/net.c
===================================================================
--- uspace/srv/net/net/net.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/net/net.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -28,9 +28,10 @@
 
 /** @addtogroup net
- *  @{
+ * @{
  */
 
 /** @file
- *  Networking subsystem central module implementation.
+ * Networking subsystem central module implementation.
+ *
  */
 
@@ -55,6 +56,6 @@
 #include <packet/packet.h>
 #include <il_messages.h>
+#include <netif_remote.h>
 #include <net_device.h>
-#include <netif_interface.h>
 #include <nil_interface.h>
 #include <net_interface.h>
@@ -64,232 +65,564 @@
 #include "net.h"
 
+/** Networking module name.
+ *
+ */
+#define NAME  "net"
+
 /** File read buffer size.
- */
-#define BUFFER_SIZE	256
-
-/** Networking module name.
- */
-#define NAME	"Networking"
+ *
+ */
+#define BUFFER_SIZE  256
 
 /** Networking module global data.
- */
-net_globals_t	net_globals;
-
-/** Generates new system-unique device identifier.
- *  @returns The system-unique devic identifier.
- */
-device_id_t generate_new_device_id(void);
-
-/** Returns the configured values.
- *  The network interface configuration is searched first.
- *  @param[in] netif_conf The network interface configuration setting.
- *  @param[out] configuration The found configured values.
- *  @param[in] count The desired settings count.
- *  @param[out] data The found configuration settings data.
- *  @returns EOK.
- */
-int net_get_conf(measured_strings_ref netif_conf, measured_string_ref configuration, size_t count, char ** data);
-
-/** Initializes the networking module.
- *  @param[in] client_connection The client connection processing function. The module skeleton propagates its own one.
- *  @returns EOK on success.
- *  @returns ENOMEM if there is not enough memory left.
- */
-int net_initialize(async_client_conn_t client_connection);
-
-/** \todo
- */
-int parse_line(measured_strings_ref configuration, char * line);
-
-/** Reads the networking subsystem global configuration.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the add_configuration() function.
- */
-int read_configuration(void);
-
-/** \todo
- */
-int read_configuration_file(const char * directory, const char * filename, measured_strings_ref configuration);
-
-/** Reads the network interface specific configuration.
- *  @param[in] name The network interface name.
- *  @param[in,out] netif The network interface structure.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the add_configuration() function.
- */
-int read_netif_configuration(const char * name, netif_ref netif);
-
-/** Starts the network interface according to its configuration.
- *  Registers the network interface with the subsystem modules.
- *  Starts the needed subsystem modules.
- *  @param[in] netif The network interface specific data.
- *  @returns EOK on success.
- *  @returns EINVAL if there are some settings missing.
- *  @returns ENOENT if the internet protocol module is not known.
- *  @returns Other error codes as defined for the netif_probe_req() function.
- *  @returns Other error codes as defined for the nil_device_req() function.
- *  @returns Other error codes as defined for the needed internet layer registering function.
- */
-int start_device(netif_ref netif);
-
-/** Reads the configuration and starts all network interfaces.
- *  @returns EOK on success.
- *  @returns EXDEV if there is no available system-unique device identifier.
- *  @returns EINVAL if any of the network interface names are not configured.
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns Other error codes as defined for the read_configuration() function.
- *  @returns Other error codes as defined for the read_netif_configuration() function.
- *  @returns Other error codes as defined for the start_device() function.
- */
-int startup(void);
-
-GENERIC_CHAR_MAP_IMPLEMENT(measured_strings, measured_string_t)
-
-DEVICE_MAP_IMPLEMENT(netifs, netif_t)
-
-int add_configuration(measured_strings_ref configuration, const char * name, const char * value){
-	ERROR_DECLARE;
-
-	measured_string_ref setting;
-
-	setting = measured_string_create_bulk(value, 0);
-	if(! setting){
+ *
+ */
+net_globals_t net_globals;
+
+GENERIC_CHAR_MAP_IMPLEMENT(measured_strings, measured_string_t);
+DEVICE_MAP_IMPLEMENT(netifs, netif_t);
+
+/** Add the configured setting to the configuration map.
+ *
+ * @param[in] configuration The configuration map.
+ * @param[in] name          The setting name.
+ * @param[in] value         The setting value.
+ *
+ * @returns EOK on success.
+ * @returns ENOMEM if there is not enough memory left.
+ *
+ */
+int add_configuration(measured_strings_ref configuration, const char *name,
+    const char *value)
+{
+	ERROR_DECLARE;
+	
+	measured_string_ref setting =
+	    measured_string_create_bulk(value, 0);
+	
+	if (!setting)
 		return ENOMEM;
-	}
-	// add the configuration setting
-	if(ERROR_OCCURRED(measured_strings_add(configuration, name, 0, setting))){
+	
+	/* Add the configuration setting */
+	if (ERROR_OCCURRED(measured_strings_add(configuration, name, 0, setting))) {
 		free(setting);
 		return ERROR_CODE;
 	}
-	return EOK;
-}
-
-device_id_t generate_new_device_id(void){
+	
+	return EOK;
+}
+
+/** Generate new system-unique device identifier.
+ *
+ * @returns The system-unique devic identifier.
+ *
+ */
+static device_id_t generate_new_device_id(void)
+{
 	return device_assign_devno();
 }
 
-/** Starts the networking module.
- *  Initializes the client connection serving function, initializes the module, registers the module service and starts 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.
- *  @returns EOK on successful module termination.
- *  @returns Other error codes as defined for the net_initialize() function.
- *  @returns Other error codes as defined for the REGISTER_ME() macro function.
- */
-static int net_module_start(async_client_conn_t client_connection){
-	ERROR_DECLARE;
-
-	ipcarg_t phonehash;
-
-	async_set_client_connection(client_connection);
-	ERROR_PROPAGATE(pm_init());
-	if(ERROR_OCCURRED(net_initialize(client_connection))
-		|| ERROR_OCCURRED(REGISTER_ME(SERVICE_NETWORKING, &phonehash))){
-		pm_destroy();
+static int parse_line(measured_strings_ref configuration, char *line)
+{
+	ERROR_DECLARE;
+	
+	/* From the beginning */
+	char *name = line;
+	
+	/* Skip comments and blank lines */
+	if ((*name == '#') || (*name == '\0'))
+		return EOK;
+	
+	/* Skip spaces */
+	while (isspace(*name))
+		name++;
+	
+	/* Remember the name start */
+	char *value = name;
+	
+	/* Skip the name */
+	while (isalnum(*value) || (*value == '_'))
+		value++;
+	
+	if (*value == '=') {
+		/* Terminate the name */
+		*value = '\0';
+	} else {
+		/* Terminate the name */
+		*value = '\0';
+		
+		/* Skip until '=' */
+		value++;
+		while ((*value) && (*value != '='))
+			value++;
+		
+		/* Not found? */
+		if (*value != '=')
+			return EINVAL;
+	}
+	
+	value++;
+	
+	/* Skip spaces */
+	while (isspace(*value))
+		value++;
+	
+	/* Create a bulk measured string till the end */
+	measured_string_ref setting =
+	    measured_string_create_bulk(value, 0);
+	if (!setting)
+		return ENOMEM;
+	
+	/* Add the configuration setting */
+	if (ERROR_OCCURRED(measured_strings_add(configuration, name, 0, setting))) {
+		free(setting);
 		return ERROR_CODE;
 	}
-
-	async_manager();
-
-	pm_destroy();
-	return EOK;
-}
-
-int net_connect_module(services_t service){
-	return EOK;
-}
-
-void net_free_settings(measured_string_ref settings, char * data){
-}
-
-int net_get_conf(measured_strings_ref netif_conf, measured_string_ref configuration, size_t count, char ** data){
-	measured_string_ref setting;
-	size_t index;
-
-	if(data){
-		*data = NULL;
-	}
-
-	for(index = 0; index < count; ++ index){
-		setting = measured_strings_find(netif_conf, configuration[index].value, 0);
-		if(! setting){
-			setting = measured_strings_find(&net_globals.configuration, configuration[index].value, 0);
+	
+	return EOK;
+}
+
+static int read_configuration_file(const char *directory, const char *filename,
+    measured_strings_ref configuration)
+{
+	ERROR_DECLARE;
+	
+	printf("%s: Reading configuration file %s/%s\n", NAME, directory, filename);
+	
+	/* Construct the full filename */
+	char line[BUFFER_SIZE];
+	if (snprintf(line, BUFFER_SIZE, "%s/%s", directory, filename) > BUFFER_SIZE)
+		return EOVERFLOW;
+	
+	/* Open the file */
+	FILE *cfg = fopen(line, "r");
+	if (!cfg)
+		return ENOENT;
+	
+	/*
+	 * Read the configuration line by line
+	 * until an error or the end of file
+	 */
+	unsigned int line_number = 0;
+	size_t index = 0;
+	while ((!ferror(cfg)) && (!feof(cfg))) {
+		int read = fgetc(cfg);
+		if ((read > 0) && (read != '\n') && (read != '\r')) {
+			if (index >= BUFFER_SIZE) {
+				line[BUFFER_SIZE - 1] = '\0';
+				fprintf(stderr, "%s: Configuration line %u too long: %s\n",
+				    NAME, line_number, line);
+				
+				/* No space left in the line buffer */
+				return EOVERFLOW;
+			} else {
+				/* Append the character */
+				line[index] = (char) read;
+				index++;
+			}
+		} else {
+			/* On error or new line */
+			line[index] = '\0';
+			line_number++;
+			if (ERROR_OCCURRED(parse_line(configuration, line)))
+				fprintf(stderr, "%s: Configuration error on line %u: %s\n",
+				    NAME, line_number, line);
+			
+			index = 0;
 		}
-		if(setting){
-			configuration[index].length = setting->length;
-			configuration[index].value = setting->value;
-		}else{
-			configuration[index].length = 0;
-			configuration[index].value = NULL;
-		}
-	}
-	return EOK;
-}
-
-int net_get_conf_req(int net_phone, measured_string_ref * configuration, size_t count, char ** data){
-	if(!(configuration && (count > 0))){
-		return EINVAL;
-	}
-
-	return net_get_conf(NULL, * configuration, count, data);
-}
-
-int net_get_device_conf_req(int net_phone, device_id_t device_id, measured_string_ref * configuration, size_t count, char ** data){
-	netif_ref netif;
-
-	if(!(configuration && (count > 0))){
-		return EINVAL;
-	}
-
-	netif = netifs_find(&net_globals.netifs, device_id);
-	if(netif){
-		return net_get_conf(&netif->configuration, * configuration, count, data);
-	}else{
-		return net_get_conf(NULL, * configuration, count, data);
-	}
-}
-
-int net_initialize(async_client_conn_t client_connection){
-	ERROR_DECLARE;
-
+	}
+	
+	fclose(cfg);
+	return EOK;
+}
+
+/** Read the network interface specific configuration.
+ *
+ * @param[in]     name  The network interface name.
+ * @param[in,out] netif The network interface structure.
+ *
+ * @returns EOK on success.
+ * @returns Other error codes as defined for the add_configuration() function.
+ *
+ */
+static int read_netif_configuration(const char *name, netif_t *netif)
+{
+	return read_configuration_file(CONF_DIR, name, &netif->configuration);
+}
+
+/** Read the networking subsystem global configuration.
+ *
+ * @returns EOK on success.
+ * @returns Other error codes as defined for the add_configuration() function.
+ *
+ */
+static int read_configuration(void)
+{
+	return read_configuration_file(CONF_DIR, CONF_GENERAL_FILE,
+	    &net_globals.configuration);
+}
+
+/** Initialize the networking module.
+ *
+ * @param[in] client_connection The client connection processing
+ *                              function. The module skeleton propagates
+ *                              its own one.
+ *
+ * @returns EOK on success.
+ * @returns ENOMEM if there is not enough memory left.
+ *
+ */
+static int net_initialize(async_client_conn_t client_connection)
+{
+	ERROR_DECLARE;
+	
 	netifs_initialize(&net_globals.netifs);
 	char_map_initialize(&net_globals.netif_names);
 	modules_initialize(&net_globals.modules);
 	measured_strings_initialize(&net_globals.configuration);
-
-	// TODO dynamic configuration
+	
+	// TODO: dynamic configuration
 	ERROR_PROPAGATE(read_configuration());
-
-	ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, LO_NAME, LO_FILENAME, SERVICE_LO, 0, connect_to_service));
-	ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, DP8390_NAME, DP8390_FILENAME, SERVICE_DP8390, 0, connect_to_service));
-	ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, ETHERNET_NAME, ETHERNET_FILENAME, SERVICE_ETHERNET, 0, connect_to_service));
-	ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, NILDUMMY_NAME, NILDUMMY_FILENAME, SERVICE_NILDUMMY, 0, connect_to_service));
-
-	// build specific initialization
+	
+	ERROR_PROPAGATE(add_module(NULL, &net_globals.modules,
+	    LO_NAME, LO_FILENAME, SERVICE_LO, 0, connect_to_service));
+	ERROR_PROPAGATE(add_module(NULL, &net_globals.modules,
+	    DP8390_NAME, DP8390_FILENAME, SERVICE_DP8390, 0, connect_to_service));
+	ERROR_PROPAGATE(add_module(NULL, &net_globals.modules,
+	    ETHERNET_NAME, ETHERNET_FILENAME, SERVICE_ETHERNET, 0,
+	    connect_to_service));
+	ERROR_PROPAGATE(add_module(NULL, &net_globals.modules,
+	    NILDUMMY_NAME, NILDUMMY_FILENAME, SERVICE_NILDUMMY, 0,
+	    connect_to_service));
+	
+	/* Build specific initialization */
 	return net_initialize_build(client_connection);
 }
 
-int net_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
-	ERROR_DECLARE;
-
+/** Start the networking module.
+ *
+ * Initializes the client connection serving function,
+ * initializes the module, registers the module service
+ * and starts 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.
+ *
+ * @returns EOK on successful module termination.
+ * @returns Other error codes as defined for the net_initialize() function.
+ * @returns Other error codes as defined for the REGISTER_ME() macro function.
+ *
+ */
+static int net_module_start(async_client_conn_t client_connection)
+{
+	ERROR_DECLARE;
+	
+	async_set_client_connection(client_connection);
+	ERROR_PROPAGATE(pm_init());
+	
+	ipcarg_t phonehash;
+	
+	if (ERROR_OCCURRED(net_initialize(client_connection))
+	    || ERROR_OCCURRED(REGISTER_ME(SERVICE_NETWORKING, &phonehash))){
+		pm_destroy();
+		return ERROR_CODE;
+	}
+	
+	async_manager();
+	
+	pm_destroy();
+	return EOK;
+}
+
+/** Return the configured values.
+ *
+ * The network interface configuration is searched first.
+ &
+ * @param[in]  netif_conf    The network interface configuration setting.
+ * @param[out] configuration The found configured values.
+ * @param[in]  count         The desired settings count.
+ * @param[out] data          The found configuration settings data.
+ *
+ * @returns EOK.
+ *
+ */
+static int net_get_conf(measured_strings_ref netif_conf,
+    measured_string_ref configuration, size_t count, char **data)
+{
+	if (data)
+		*data = NULL;
+	
+	size_t index;
+	for (index = 0; index < count; index++) {
+		measured_string_ref setting =
+		    measured_strings_find(netif_conf, configuration[index].value, 0);
+		if (!setting)
+			setting = measured_strings_find(&net_globals.configuration,
+			    configuration[index].value, 0);
+		
+		if (setting) {
+			configuration[index].length = setting->length;
+			configuration[index].value = setting->value;
+		} else {
+			configuration[index].length = 0;
+			configuration[index].value = NULL;
+		}
+	}
+	
+	return EOK;
+}
+
+int net_get_conf_req(int net_phone, measured_string_ref *configuration,
+    size_t count, char **data)
+{
+	if (!(configuration && (count > 0)))
+		return EINVAL;
+	
+	return net_get_conf(NULL, *configuration, count, data);
+}
+
+int net_get_device_conf_req(int net_phone, device_id_t device_id,
+    measured_string_ref *configuration, size_t count, char **data)
+{
+	if ((!configuration) || (count == 0))
+		return EINVAL;
+
+	netif_t *netif = netifs_find(&net_globals.netifs, device_id);
+	if (netif)
+		return net_get_conf(&netif->configuration, *configuration, count, data);
+	else
+		return net_get_conf(NULL, *configuration, count, data);
+}
+
+void net_free_settings(measured_string_ref settings, char *data)
+{
+}
+
+/** Start the network interface according to its configuration.
+ *
+ * Register the network interface with the subsystem modules.
+ * Start the needed subsystem modules.
+ *
+ * @param[in] netif The network interface specific data.
+ *
+ * @returns EOK on success.
+ * @returns EINVAL if there are some settings missing.
+ * @returns ENOENT if the internet protocol module is not known.
+ * @returns Other error codes as defined for the netif_probe_req() function.
+ * @returns Other error codes as defined for the nil_device_req() function.
+ * @returns Other error codes as defined for the needed internet layer
+ *          registering function.
+ *
+ */
+static int start_device(netif_t *netif)
+{
+	ERROR_DECLARE;
+	
+	/* Mandatory netif */
+	measured_string_ref setting =
+	    measured_strings_find(&netif->configuration, CONF_NETIF, 0);
+	
+	netif->driver = get_running_module(&net_globals.modules, setting->value);
+	if (!netif->driver) {
+		fprintf(stderr, "%s: Failed to start network interface driver '%s'\n",
+		    NAME, setting->value);
+		return EINVAL;
+	}
+	
+	/* Optional network interface layer */
+	setting = measured_strings_find(&netif->configuration, CONF_NIL, 0);
+	if (setting) {
+		netif->nil = get_running_module(&net_globals.modules, setting->value);
+		if (!netif->nil) {
+			fprintf(stderr, "%s: Failed to start network interface layer '%s'\n",
+			    NAME, setting->value);
+			return EINVAL;
+		}
+	} else
+		netif->nil = NULL;
+	
+	/* Mandatory internet layer */
+	setting = measured_strings_find(&netif->configuration, CONF_IL, 0);
+	netif->il = get_running_module(&net_globals.modules, setting->value);
+	if (!netif->il) {
+		fprintf(stderr, "%s: Failed to start internet layer '%s'\n",
+		    NAME, setting->value);
+		return EINVAL;
+	}
+	
+	/* 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;
+	
+	ERROR_PROPAGATE(netif_probe_req_remote(netif->driver->phone, netif->id, irq, io));
+	
+	/* Network interface layer startup */
+	services_t internet_service;
+	if (netif->nil) {
+		setting = measured_strings_find(&netif->configuration, CONF_MTU, 0);
+		if (!setting)
+			setting = measured_strings_find(&net_globals.configuration,
+			    CONF_MTU, 0);
+		
+		int mtu = setting ? strtol(setting->value, NULL, 10) : 0;
+		
+		ERROR_PROPAGATE(nil_device_req(netif->nil->phone, netif->id, mtu,
+		    netif->driver->service));
+		
+		internet_service = netif->nil->service;
+	} else
+		internet_service = netif->driver->service;
+	
+	/* Inter-network layer startup */
+	switch (netif->il->service) {
+		case SERVICE_IP:
+			ERROR_PROPAGATE(ip_device_req(netif->il->phone, netif->id,
+			    internet_service));
+			break;
+		default:
+			return ENOENT;
+	}
+	
+	ERROR_PROPAGATE(netif_start_req_remote(netif->driver->phone, netif->id));
+	return EOK;
+}
+
+/** Read the configuration and start all network interfaces.
+ *
+ * @returns EOK on success.
+ * @returns EXDEV if there is no available system-unique device identifier.
+ * @returns EINVAL if any of the network interface names are not configured.
+ * @returns ENOMEM if there is not enough memory left.
+ * @returns Other error codes as defined for the read_configuration()
+ *          function.
+ * @returns Other error codes as defined for the read_netif_configuration()
+ *          function.
+ * @returns Other error codes as defined for the start_device() function.
+ *
+ */
+static int startup(void)
+{
+	ERROR_DECLARE;
+	
+	const char *conf_files[] = {"lo", "ne2k"};
+	size_t count = sizeof(conf_files) / sizeof(char *);
+	
+	size_t i;
+	for (i = 0; i < count; i++) {
+		netif_t *netif = (netif_t *) malloc(sizeof(netif_t));
+		if (!netif)
+			return ENOMEM;
+		
+		netif->id = generate_new_device_id();
+		if (!netif->id)
+			return EXDEV;
+		
+		ERROR_PROPAGATE(measured_strings_initialize(&netif->configuration));
+		
+		/* Read configuration files */
+		if (ERROR_OCCURRED(read_netif_configuration(conf_files[i], netif))) {
+			measured_strings_destroy(&netif->configuration);
+			free(netif);
+			return ERROR_CODE;
+		}
+		
+		/* Mandatory name */
+		measured_string_ref setting =
+		    measured_strings_find(&netif->configuration, CONF_NAME, 0);
+		if (!setting) {
+			fprintf(stderr, "%s: Network interface name is missing\n", NAME);
+			measured_strings_destroy(&netif->configuration);
+			free(netif);
+			return EINVAL;
+		}
+		netif->name = setting->value;
+		
+		/* Add to the netifs map */
+		int index = netifs_add(&net_globals.netifs, netif->id, netif);
+		if (index < 0) {
+			measured_strings_destroy(&netif->configuration);
+			free(netif);
+			return index;
+		}
+		
+		/*
+		 * Add to the netif names map and start network interfaces
+		 * and needed modules.
+		 */
+		if ((ERROR_OCCURRED(char_map_add(&net_globals.netif_names,
+		    netif->name, 0, index))) || (ERROR_OCCURRED(start_device(netif)))) {
+			measured_strings_destroy(&netif->configuration);
+			netifs_exclude_index(&net_globals.netifs, index);
+			return ERROR_CODE;
+		}
+		
+		/* Increment modules' usage */
+		netif->driver->usage++;
+		if (netif->nil)
+			netif->nil->usage++;
+		netif->il->usage++;
+		
+		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->il->name);
+	}
+	
+	return EOK;
+}
+
+/** Process the networking message.
+ *
+ * @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.
+ *
+ * @returns EOK on success.
+ * @returns ENOTSUP if the message is not known.
+ *
+ * @see net_interface.h
+ * @see IS_NET_NET_MESSAGE()
+ *
+ */
+int net_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
+    int *answer_count)
+{
+	ERROR_DECLARE;
+	
 	measured_string_ref strings;
-	char * data;
-
+	char *data;
+	
 	*answer_count = 0;
-	switch(IPC_GET_METHOD(*call)){
+	switch (IPC_GET_METHOD(*call)) {
 		case IPC_M_PHONE_HUNGUP:
 			return EOK;
 		case NET_NET_GET_DEVICE_CONF:
-			ERROR_PROPAGATE(measured_strings_receive(&strings, &data, IPC_GET_COUNT(call)));
-			net_get_device_conf_req(0, IPC_GET_DEVICE(call), &strings, IPC_GET_COUNT(call), NULL);
-			// strings should not contain received data anymore
+			ERROR_PROPAGATE(measured_strings_receive(&strings, &data,
+			    IPC_GET_COUNT(call)));
+			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);
+			
 			ERROR_CODE = measured_strings_reply(strings, IPC_GET_COUNT(call));
 			free(strings);
 			return ERROR_CODE;
 		case NET_NET_GET_CONF:
-			ERROR_PROPAGATE(measured_strings_receive(&strings, &data, IPC_GET_COUNT(call)));
+			ERROR_PROPAGATE(measured_strings_receive(&strings, &data,
+			    IPC_GET_COUNT(call)));
 			net_get_conf_req(0, &strings, IPC_GET_COUNT(call), NULL);
-			// strings should not contain received data anymore
+			
+			/* Strings should not contain received data anymore */
 			free(data);
+			
 			ERROR_CODE = measured_strings_reply(strings, IPC_GET_COUNT(call));
 			free(strings);
@@ -301,273 +634,11 @@
 }
 
-int parse_line(measured_strings_ref configuration, char * line){
-	ERROR_DECLARE;
-
-	measured_string_ref setting;
-	char * name;
-	char * value;
-
-	// from the beginning
-	name = line;
-
-	// skip comments and blank lines
-	if((*name == '#') || (*name == '\0')){
-		return EOK;
-	}
-	// skip spaces
-	while(isspace(*name)){
-		++ name;
-	}
-
-	// remember the name start
-	value = name;
-	// skip the name
-	while(isalnum(*value) || (*value == '_')){
-		// make uppercase
-//		*value = toupper(*value);
-		++ value;
-	}
-
-	if(*value == '='){
-		// terminate the name
-		*value = '\0';
-	}else{
-		// terminate the name
-		*value = '\0';
-		// skip until '='
-		++ value;
-		while((*value) && (*value != '=')){
-			++ value;
-		}
-		// not found?
-		if(*value != '='){
-			return EINVAL;
-		}
-	}
-
-	++ value;
-	// skip spaces
-	while(isspace(*value)){
-		++ value;
-	}
-	// create a bulk measured string till the end
-	setting = measured_string_create_bulk(value, 0);
-	if(! setting){
-		return ENOMEM;
-	}
-
-	// add the configuration setting
-	if(ERROR_OCCURRED(measured_strings_add(configuration, name, 0, setting))){
-		free(setting);
-		return ERROR_CODE;
-	}
-	return EOK;
-}
-
-int read_configuration(void){
-	// read the general configuration file
-	return read_configuration_file(CONF_DIR, CONF_GENERAL_FILE, &net_globals.configuration);
-}
-
-int read_configuration_file(const char * directory, const char * filename, measured_strings_ref configuration){
-	ERROR_DECLARE;
-
-	size_t index = 0;
-	char line[BUFFER_SIZE];
-	FILE * cfg;
-	int read;
-	int line_number = 0;
-
-	// construct the full filename
-	printf("Reading file %s/%s\n", directory, filename);
-	if(snprintf(line, BUFFER_SIZE, "%s/%s", directory, filename) > BUFFER_SIZE){
-		return EOVERFLOW;
-	}
-	// open the file
-	cfg = fopen(line, "r");
-	if(! cfg){
-		return ENOENT;
-	}
-
-	// read the configuration line by line
-	// until an error or the end of file
-	while((! ferror(cfg)) && (! feof(cfg))){
-		read = fgetc(cfg);
-		if((read > 0) && (read != '\n') && (read != '\r')){
-			if(index >= BUFFER_SIZE){
-				line[BUFFER_SIZE - 1] = '\0';
-				printf("line %d too long: %s\n", line_number, line);
-				// no space left in the line buffer
-				return EOVERFLOW;
-			}else{
-				// append the character
-				line[index] = (char) read;
-				++ index;
-			}
-		}else{
-			// on error or new line
-			line[index] = '\0';
-			++ line_number;
-			if(ERROR_OCCURRED(parse_line(configuration, line))){
-				printf("error on line %d: %s\n", line_number, line);
-				//fclose(cfg);
-				//return ERROR_CODE;
-			}
-			index = 0;
-		}
-	}
-	fclose(cfg);
-	return EOK;
-}
-
-int read_netif_configuration(const char * name, netif_ref netif){
-	// read the netif configuration file
-	return read_configuration_file(CONF_DIR, name, &netif->configuration);
-}
-
-int start_device(netif_ref netif){
-	ERROR_DECLARE;
-
-	measured_string_ref setting;
-	services_t internet_service;
-	int irq;
-	int io;
-	int mtu;
-
-	// mandatory netif
-	setting = measured_strings_find(&netif->configuration, CONF_NETIF, 0);
-	netif->driver = get_running_module(&net_globals.modules, setting->value);
-	if(! netif->driver){
-		printf("Failed to start the network interface driver %s\n", setting->value);
-		return EINVAL;
-	}
-
-	// optional network interface layer
-	setting = measured_strings_find(&netif->configuration, CONF_NIL, 0);
-	if(setting){
-		netif->nil = get_running_module(&net_globals.modules, setting->value);
-		if(! netif->nil){
-			printf("Failed to start the network interface layer %s\n", setting->value);
-			return EINVAL;
-		}
-	}else{
-		netif->nil = NULL;
-	}
-
-	// mandatory internet layer
-	setting = measured_strings_find(&netif->configuration, CONF_IL, 0);
-	netif->il = get_running_module(&net_globals.modules, setting->value);
-	if(! netif->il){
-		printf("Failed to start the internet layer %s\n", setting->value);
-		return EINVAL;
-	}
-
-	// hardware configuration
-	setting = measured_strings_find(&netif->configuration, CONF_IRQ, 0);
-	irq = setting ? strtol(setting->value, NULL, 10) : 0;
-	setting = measured_strings_find(&netif->configuration, CONF_IO, 0);
-	io = setting ? strtol(setting->value, NULL, 16) : 0;
-	ERROR_PROPAGATE(netif_probe_req(netif->driver->phone, netif->id, irq, io));
-
-	// network interface layer startup
-	if(netif->nil){
-		setting = measured_strings_find(&netif->configuration, CONF_MTU, 0);
-		if(! setting){
-			setting = measured_strings_find(&net_globals.configuration, CONF_MTU, 0);
-		}
-		mtu = setting ? strtol(setting->value, NULL, 10) : 0;
-		ERROR_PROPAGATE(nil_device_req(netif->nil->phone, netif->id, mtu, netif->driver->service));
-		internet_service = netif->nil->service;
-	}else{
-		internet_service = netif->driver->service;
-	}
-
-	// inter-network layer startup
-	switch(netif->il->service){
-		case SERVICE_IP:
-			ERROR_PROPAGATE(ip_device_req(netif->il->phone, netif->id, internet_service));
-			break;
-		default:
-			return ENOENT;
-	}
-	ERROR_PROPAGATE(netif_start_req(netif->driver->phone, netif->id));
-	return EOK;
-}
-
-int startup(void){
-	ERROR_DECLARE;
-
-	const char * conf_files[] = {"lo", "ne2k"};
-
-	int count = sizeof(conf_files) / sizeof(char *);
-	int index;
-	netif_ref netif;
-	int i;
-	measured_string_ref setting;
-
-	for(i = 0; i < count; ++ i){
-		netif = (netif_ref) malloc(sizeof(netif_t));
-		if(! netif){
-			return ENOMEM;
-		}
-
-		netif->id = generate_new_device_id();
-		if(! netif->id){
-			return EXDEV;
-		}
-		ERROR_PROPAGATE(measured_strings_initialize(&netif->configuration));
-
-		// read configuration files
-		if(ERROR_OCCURRED(read_netif_configuration(conf_files[i], netif))){
-			measured_strings_destroy(&netif->configuration);
-			free(netif);
-			return ERROR_CODE;
-		}
-
-		// mandatory name
-		setting = measured_strings_find(&netif->configuration, CONF_NAME, 0);
-		if(! setting){
-			printf("The name is missing\n");
-			measured_strings_destroy(&netif->configuration);
-			free(netif);
-			return EINVAL;
-		}
-		netif->name = setting->value;
-
-		// add to the netifs map
-		index = netifs_add(&net_globals.netifs, netif->id, netif);
-		if(index < 0){
-			measured_strings_destroy(&netif->configuration);
-			free(netif);
-			return index;
-		}
-
-		// add to the netif names map
-		if(ERROR_OCCURRED(char_map_add(&net_globals.netif_names, netif->name, 0, index))
-		// start network interfaces and needed modules
-			|| ERROR_OCCURRED(start_device(netif))){
-			measured_strings_destroy(&netif->configuration);
-			netifs_exclude_index(&net_globals.netifs, index);
-			return ERROR_CODE;
-		}
-
-		// increment modules' usage
-		++ netif->driver->usage;
-		if(netif->nil){
-			++ netif->nil->usage;
-		}
-		++ netif->il->usage;
-		printf("New network interface started:\n\tname\t= %s\n\tid\t= %d\n\tdriver\t= %s\n\tnil\t= %s\n\til\t= %s\n", netif->name, netif->id, netif->driver->name, netif->nil ? netif->nil->name : NULL, netif->il->name);
-	}
-	return EOK;
-}
-
 /** Default thread for new connections.
  *
- *  @param[in] iid The initial message identifier.
- *  @param[in] icall The initial message call structure.
- *
- */
-static void net_client_connection(ipc_callid_t iid, ipc_call_t * icall)
+ * @param[in] iid The initial message identifier.
+ * @param[in] icall The initial message call structure.
+ *
+ */
+static void net_client_connection(ipc_callid_t iid, ipc_call_t *icall)
 {
 	/*
@@ -577,9 +648,8 @@
 	ipc_answer_0(iid, EOK);
 	
-	while(true) {
+	while (true) {
+		/* Clear the answer structure */
 		ipc_call_t answer;
 		int answer_count;
-		
-		/* Clear the answer structure */
 		refresh_answer(&answer, &answer_count);
 		
@@ -600,23 +670,10 @@
 }
 
-/** Starts 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[])
 {
 	ERROR_DECLARE;
 	
-	/* Print the module label */
-	printf("Task %d - %s\n", task_get_id(), NAME);
-	
-	/* Start the module */
 	if (ERROR_OCCURRED(net_module_start(net_client_connection))) {
-		printf(" - ERROR %i\n", ERROR_CODE);
+		fprintf(stderr, "%s: net_module_start error %i\n", NAME, ERROR_CODE);
 		return ERROR_CODE;
 	}
Index: uspace/srv/net/net/net.h
===================================================================
--- uspace/srv/net/net/net.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/net/net.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -28,9 +28,10 @@
 
 /** @addtogroup net
- *  @{
+ * @{
  */
 
 /** @file
- *  Networking subsystem central module.
+ * Networking subsystem central module.
+ *
  */
 
@@ -48,197 +49,92 @@
 
 /** @name Modules definitions
+ * @{
  */
-/*@{*/
 
-/** DP8390 network interface module full path filename.
+#define DP8390_FILENAME  "/srv/dp8390"
+#define DP8390_NAME      "dp8390"
+
+#define ETHERNET_FILENAME  "/srv/eth"
+#define ETHERNET_NAME      "eth"
+
+#define IP_FILENAME  "/srv/ip"
+#define IP_NAME      "ip"
+
+#define LO_FILENAME  "/srv/lo"
+#define LO_NAME      "lo"
+
+#define NILDUMMY_FILENAME  "/srv/nildummy"
+#define NILDUMMY_NAME      "nildummy"
+
+/** @}
  */
-#define DP8390_FILENAME		"/srv/dp8390"
-
-/** DP8390 network interface module name.
- */
-#define DP8390_NAME			"dp8390"
-
-/** Ethernet module full path filename.
- */
-#define ETHERNET_FILENAME	"/srv/eth"
-
-/** Ethernet module name.
- */
-#define ETHERNET_NAME		"ethernet"
-
-/** IP module full path filename.
- */
-#define IP_FILENAME			"/srv/ip"
-
-/** IP module name.
- */
-#define IP_NAME				"ip"
-
-/** Loopback network interface module full path filename.
- */
-#define LO_FILENAME			"/srv/lo"
-
-/** Loopback network interface module name.
- */
-#define LO_NAME				"lo"
-
-/** Ethernet module full path filename.
- */
-#define NILDUMMY_FILENAME	"/srv/nildummy"
-
-/** Ethernet module name.
- */
-#define NILDUMMY_NAME		"nildummy"
-
-/*@}*/
 
 /** @name Configuration setting names definitions
+ * @{
  */
-/*@{*/
 
-/** Internet protocol module name configuration label.
+#define CONF_IL     "IL"     /**< Internet protocol module name configuration label. */
+#define CONF_IO     "IO"     /**< Device input/output address configuration label. */
+#define CONF_IRQ    "IRQ"    /**< Interrupt number configuration label. */
+#define CONF_MTU    "MTU"    /**< Maximum transmission unit configuration label. */
+#define CONF_NAME   "NAME"   /**< Network interface name configuration label. */
+#define CONF_NETIF  "NETIF"  /**< Network interface module name configuration label. */
+#define CONF_NIL    "NIL"    /**< Network interface layer module name configuration label. */
+
+/** @}
  */
-#define CONF_IL				"IL"
 
-/** Device input/output address configuration label.
- */
-#define CONF_IO				"IO"
-
-/** Interrupt number configuration label.
- */
-#define CONF_IRQ			"IRQ"
-
-/** Maximum transmission unit configuration label.
- */
-#define CONF_MTU			"MTU"
-
-/** Network interface name configuration label.
- */
-#define CONF_NAME			"NAME"
-
-/** Network interface module name configuration label.
- */
-#define CONF_NETIF			"NETIF"
-
-/** Network interface layer module name configuration label.
- */
-#define CONF_NIL			"NIL"
-
-/*@}*/
-
-/** Configuration directory.
- */
-#define CONF_DIR			"/cfg/net"
-
-/** General configuration file.
- */
-#define CONF_GENERAL_FILE	"general"
-
-/** Type definition of the networking module global data.
- *  @see net_globals
- */
-typedef struct net_globals	net_globals_t;
-
-/** Type definition of the network interface specific data.
- *  @see netif
- */
-typedef struct netif	netif_t;
-
-/** Type definition of the network interface specific data pointer.
- *  @see netif
- */
-typedef netif_t *		netif_ref;
+#define CONF_DIR           "/cfg/net"  /**< Configuration directory. */
+#define CONF_GENERAL_FILE  "general"   /**< General configuration file. */
 
 /** Configuration settings.
- *  Maps setting names to the values.
- *  @see generic_char_map.h
+ *
+ * Maps setting names to the values.
+ * @see generic_char_map.h
+ *
  */
-GENERIC_CHAR_MAP_DECLARE(measured_strings, measured_string_t)
+GENERIC_CHAR_MAP_DECLARE(measured_strings, measured_string_t);
+
+/** Present network interface device.
+ *
+ */
+typedef struct {
+	measured_strings_t configuration;  /**< Configuration. */
+	
+	/** Serving network interface driver module index. */
+	module_ref driver;
+	
+	device_id_t id;  /**< System-unique network interface identifier. */
+	module_ref il;   /**< Serving internet layer module index. */
+	char *name;      /**< System-unique network interface name. */
+	module_ref nil;  /**< Serving link layer module index. */
+} netif_t;
 
 /** Present network interfaces.
- *  Maps devices to the networking device specific data.
- *  @see device.h
+ *
+ * Maps devices to the networking device specific data.
+ * @see device.h
+ *
  */
-DEVICE_MAP_DECLARE(netifs, netif_t)
+DEVICE_MAP_DECLARE(netifs, netif_t);
 
-/** Networking module global variables.
+/** Networking module global data.
+ *
  */
-struct net_globals{
-	/** Global configuration.
-	 */
-	measured_strings_t configuration;
-	/** Available modules.
-	 */
-	modules_t modules;
-	/** Network interface structure indices by names.
-	 */
+typedef struct {
+	measured_strings_t configuration;  /**< Global configuration. */
+	modules_t modules;                 /**< Available modules. */
+	
+	/** Network interface structure indices by names. */
 	char_map_t netif_names;
-	/** Present network interfaces.
-	 */
+	
+	/** Present network interfaces. */
 	netifs_t netifs;
-};
+} net_globals_t;
 
-/** Present network interface device.
- */
-struct netif{
-	/** Configuration.
-	 */
-	measured_strings_t configuration;
-	/** Serving network interface driver module index.
-	 */
-	module_ref driver;
-	/** System-unique network interface identifier.
-	 */
-	device_id_t id;
-	/** Serving internet layer module index.
-	 */
-	module_ref il;
-	/** System-unique network interface name.
-	 */
-	char * name;
-	/** Serving link layer module index.
-	 */
-	module_ref nil;
-};
-
-/** Adds the configured setting to the configuration map.
- *  @param[in] configuration The configuration map.
- *  @param[in] name The setting name.
- *  @param[in] value The setting value.
- *  @returns EOK on success.
- *  @returns ENOMEM if there is not enough memory left.
- */
-int add_configuration(measured_strings_ref configuration, const char * name, const char * value);
-
-/** Processes the module message.
- *  Distributes the message to the right bundled module.
- *  @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.
- *  @returns EOK on success.
- *  @returns ENOTSUP if the message is not known.
- *  @returns Other error codes as defined for each bundled module message function.
- */
-int net_module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
-
-/** Initializes the networking module for the chosen subsystem build type.
- *  @param[in] client_connection The client connection processing function. The module skeleton propagates its own one.
- *  @returns EOK on success.
- *  @returns ENOMEM if there is not enough memory left.
- */
-int net_initialize_build(async_client_conn_t client_connection);
-
-/** Processes the networking message.
- *  @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.
- *  @returns EOK on success.
- *  @returns ENOTSUP if the message is not known.
- *  @see net_interface.h
- *  @see IS_NET_NET_MESSAGE()
- */
-int net_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
+extern int add_configuration(measured_strings_ref, const char *, const char *);
+extern int net_module_message(ipc_callid_t, ipc_call_t *, ipc_call_t *, int *);
+extern int net_initialize_build(async_client_conn_t);
+extern int net_message(ipc_callid_t, ipc_call_t *, ipc_call_t *, int *);
 
 #endif
Index: uspace/srv/net/net/net_bundle.c
===================================================================
--- uspace/srv/net/net/net_bundle.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/net/net_bundle.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -60,4 +60,9 @@
 extern net_globals_t	net_globals;
 
+/** Initializes the networking module for the chosen subsystem build type.
+ *  @param[in] client_connection The client connection processing function. The module skeleton propagates its own one.
+ *  @returns EOK on success.
+ *  @returns ENOMEM if there is not enough memory left.
+ */
 int net_initialize_build(async_client_conn_t client_connection){
 	ERROR_DECLARE;
@@ -79,4 +84,14 @@
 }
 
+/** Processes the module message.
+ *  Distributes the message to the right bundled module.
+ *  @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.
+ *  @returns EOK on success.
+ *  @returns ENOTSUP if the message is not known.
+ *  @returns Other error codes as defined for each bundled module message function.
+ */
 int net_module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
 	if((IPC_GET_METHOD(*call) == IPC_M_CONNECT_TO_ME)
Index: uspace/srv/net/net/net_standalone.c
===================================================================
--- uspace/srv/net/net/net_standalone.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/net/net_standalone.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -49,34 +49,60 @@
 /** Networking module global data.
  */
-extern net_globals_t	net_globals;
+extern net_globals_t net_globals;
 
+/** Initialize the networking module for the chosen subsystem build type.
+ *
+ *  @param[in] client_connection The client connection processing function.
+ *                               The module skeleton propagates its own one.
+ *
+ *  @return EOK on success.
+ *  @return ENOMEM if there is not enough memory left.
+ *
+ */
 int net_initialize_build(async_client_conn_t client_connection){
 	ERROR_DECLARE;
-
-	task_id_t task_id;
-
-	task_id = spawn("/srv/ip");
-	if(! task_id){
+	
+	task_id_t task_id = spawn("/srv/ip");
+	if (!task_id)
 		return EINVAL;
-	}
-	ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, IP_NAME, IP_FILENAME, SERVICE_IP, task_id, ip_connect_module));
-	if(! spawn("/srv/icmp")){
+	
+	ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, IP_NAME,
+	    IP_FILENAME, SERVICE_IP, task_id, ip_connect_module));
+	
+	if (!spawn("/srv/icmp"))
 		return EINVAL;
-	}
-	if(! spawn("/srv/udp")){
+	
+	if (!spawn("/srv/udp"))
 		return EINVAL;
-	}
-	if(! spawn("/srv/tcp")){
+	
+	if (!spawn("/srv/tcp"))
 		return EINVAL;
-	}
+	
 	return EOK;
 }
 
-int net_module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
-	if(IS_NET_PACKET_MESSAGE(call)){
+/** Process the module message.
+ *
+ * Distribute the message to the right module.
+ *
+ * @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 bundled module
+ *         message function.
+ *
+ */
+int net_module_message(ipc_callid_t callid, ipc_call_t *call,
+    ipc_call_t *answer, int *answer_count)
+{
+	if (IS_NET_PACKET_MESSAGE(call))
 		return packet_server_message(callid, call, answer, answer_count);
-	}else{
-		return net_message(callid, call, answer, answer_count);
-	}
+	
+	return net_message(callid, call, answer, answer_count);
 }
 
Index: uspace/srv/net/netif/lo/Makefile
===================================================================
--- uspace/srv/net/netif/lo/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/netif/lo/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -39,11 +39,9 @@
 -include $(CONFIG_MAKEFILE)
 
-ifeq ($(CONFIG_NETWORKING),modular)
-	BINARY = lo
+ifeq ($(CONFIG_NETIF_NIL_BUNDLE),y)
+	LIBS += $(USPACE_PREFIX)/srv/net/nil/nildummy/libnildummy.a
 endif
 
-ifeq ($(CONFIG_NETWORKING),module)
-	LIBRARY = liblo
-endif
+BINARY = lo
 
 SOURCES = \
Index: uspace/srv/net/netif/lo/lo.c
===================================================================
--- uspace/srv/net/netif/lo/lo.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/netif/lo/lo.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -51,6 +51,6 @@
 #include <nil_interface.h>
 #include <nil_messages.h>
-#include <netif.h>
-#include <netif_module.h>
+#include <netif_interface.h>
+#include <netif_local.h>
 
 /** Default hardware address.
@@ -64,5 +64,5 @@
 /** Loopback module name.
  */
-#define NAME	"lo - loopback interface"
+#define NAME  "lo"
 
 /** Network interface global data.
@@ -76,5 +76,5 @@
  *  @returns EOK otherwise.
  */
-int change_state_message(device_ref device, device_state_t state);
+int change_state_message(netif_device_t * device, device_state_t state);
 
 /** Creates and returns the loopback network interface structure.
@@ -85,5 +85,5 @@
  *  @returns ENOMEM if there is not enough memory left.
  */
-int create(device_id_t device_id, device_ref * device);
+int create(device_id_t device_id, netif_device_t * * device);
 
 int netif_specific_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
@@ -103,5 +103,5 @@
 	ERROR_DECLARE;
 
-	device_ref device;
+	netif_device_t * device;
 
 	if(! stats){
@@ -113,20 +113,25 @@
 }
 
-int change_state_message(device_ref device, device_state_t state){
-	if(device->state != state){
+int change_state_message(netif_device_t * device, device_state_t state)
+{
+	if (device->state != state) {
 		device->state = state;
-		printf("State changed to %s\n", (state == NETIF_ACTIVE) ? "ACTIVE" : "STOPPED");
+		
+		printf("%s: State changed to %s\n", NAME,
+		    (state == NETIF_ACTIVE) ? "active" : "stopped");
+		
 		return state;
 	}
-	return EOK;
-}
-
-int create(device_id_t device_id, device_ref * device){
+	
+	return EOK;
+}
+
+int create(device_id_t device_id, netif_device_t * * device){
 	int index;
 
-	if(device_map_count(&netif_globals.device_map) > 0){
+	if(netif_device_map_count(&netif_globals.device_map) > 0){
 		return EXDEV;
 	}else{
-		*device = (device_ref) malloc(sizeof(device_t));
+		*device = (netif_device_t *) malloc(sizeof(netif_device_t));
 		if(!(*device)){
 			return ENOMEM;
@@ -141,5 +146,5 @@
 		(** device).nil_phone = -1;
 		(** device).state = NETIF_STOPPED;
-		index = device_map_add(&netif_globals.device_map, (** device).device_id, * device);
+		index = netif_device_map_add(&netif_globals.device_map, (** device).device_id, * device);
 		if(index < 0){
 			free(*device);
@@ -161,10 +166,10 @@
 	ERROR_DECLARE;
 
-	device_ref device;
+	netif_device_t * device;
 
 	// create a new device
 	ERROR_PROPAGATE(create(device_id, &device));
 	// print the settings
-	printf("New device created:\n\tid\t= %d\n", device->device_id);
+	printf("%s: Device created (id: %d)\n", NAME, device->device_id);
 	return EOK;
 }
@@ -173,5 +178,5 @@
 	ERROR_DECLARE;
 
-	device_ref device;
+	netif_device_t * device;
 	size_t length;
 	packet_t next;
@@ -199,23 +204,19 @@
 }
 
-int netif_start_message(device_ref device){
+int netif_start_message(netif_device_t * device){
 	return change_state_message(device, NETIF_ACTIVE);
 }
 
-int netif_stop_message(device_ref device){
+int netif_stop_message(netif_device_t * device){
 	return change_state_message(device, NETIF_STOPPED);
 }
 
-#ifdef CONFIG_NETWORKING_modular
-
-#include <netif_standalone.h>
-
 /** 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)
+ * @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)
 {
 	/*
@@ -237,5 +238,6 @@
 		
 		/* Process the message */
-		int res = netif_module_message(callid, &call, &answer, &answer_count);
+		int res = netif_module_message(NAME, callid, &call, &answer,
+		    &answer_count);
 		
 		/* End if said to either by the message or the processing result */
@@ -248,30 +250,14 @@
 }
 
-/** Starts 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[])
 {
 	ERROR_DECLARE;
 	
-	/* Print the module label */
-	printf("Task %d - %s\n", task_get_id(), NAME);
-	
 	/* Start the module */
-	if (ERROR_OCCURRED(netif_module_start(netif_client_connection))) {
-		printf(" - ERROR %i\n", ERROR_CODE);
+	if (ERROR_OCCURRED(netif_module_start(netif_client_connection)))
 		return ERROR_CODE;
-	}
-	
-	return EOK;
-}
-
-#endif /* CONFIG_NETWORKING_modular */
+	
+	return EOK;
+}
 
 /** @}
Index: uspace/srv/net/netstart/netstart.c
===================================================================
--- uspace/srv/net/netstart/netstart.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/netstart/netstart.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -44,4 +44,5 @@
 #include <stdio.h>
 #include <task.h>
+#include <str_error.h>
 #include <ipc/ipc.h>
 #include <ipc/services.h>
@@ -71,6 +72,8 @@
 	argv[1] = NULL;
 	
-	if (task_spawn(path, argv) == 0) {
-		fprintf(stderr, "%s: Error spawning %s\n", NAME, path);
+	int err;
+	if (task_spawn(path, argv, &err) == 0) {
+		fprintf(stderr, "%s: Error spawning %s (%s)\n", NAME, path,
+		    str_error(err));
 		return false;
 	}
@@ -79,15 +82,4 @@
 }
 
-/** Network startup entry point.
- *
- * @param[in] argc The number of command line parameters.
- * @param[in] argv The command line parameters.
- *
- * @returns EOK on success.
- * @returns EINVAL if the net module cannot be started.
- * @returns Other error codes as defined for the self_test() function.
- * @returns Other error codes as defined for the NET_NET_STARTUP message.
- *
- */
 int main(int argc, char *argv[])
 {
@@ -105,5 +97,5 @@
 	int net_phone = connect_to_service(SERVICE_NETWORKING);
 	if (ERROR_OCCURRED(ipc_call_sync_0_0(net_phone, NET_NET_STARTUP))) {
-		fprintf(stderr, "%s: Networking error %d\n", NAME, ERROR_CODE);
+		fprintf(stderr, "%s: Startup error %d\n", NAME, ERROR_CODE);
 		return ERROR_CODE;
 	}
Index: uspace/srv/net/netstart/self_test.c
===================================================================
--- uspace/srv/net/netstart/self_test.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/netstart/self_test.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -49,9 +49,8 @@
 #include "self_test.h"
 
-/** Test the function, compare the result and remember if the result differs.
- *
- *  @param[in] name          The test name.
- *  @param[in] function_call The function to be called and checked.
- *  @param[in] result        The expected result.
+/** Test the statement, compare the result and evaluate.
+ *
+ * @param[in] statement The statement to test.
+ * @param[in] result    The expected result.
  *
  */
@@ -85,4 +84,12 @@
 INT_MAP_IMPLEMENT(int_map, int);
 
+/** Self-test start function.
+ *
+ * Run all self-tests.
+ *
+ * @returns EOK on success.
+ * @returns The first error occurred.
+ *
+ */
 int self_test(void)
 {
Index: uspace/srv/net/nil/eth/Makefile
===================================================================
--- uspace/srv/net/nil/eth/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/nil/eth/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -29,7 +29,19 @@
 
 USPACE_PREFIX = ../../../..
-LIBS = $(LIBNETIF_PREFIX)/libnetif.a $(LIBNET_PREFIX)/libnet.a $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBNETIF_PREFIX)/include -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
-BINARY = eth
+ROOT_PATH = $(USPACE_PREFIX)/..
+LIBS = $(LIBNET_PREFIX)/libnet.a $(LIBSOCKET_PREFIX)/libsocket.a
+EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
+
+COMMON_MAKEFILE = $(ROOT_PATH)/Makefile.common
+CONFIG_MAKEFILE = $(ROOT_PATH)/Makefile.config
+
+-include $(COMMON_MAKEFILE)
+-include $(CONFIG_MAKEFILE)
+
+ifeq ($(CONFIG_NETIF_NIL_BUNDLE),y)
+	LIBRARY = libeth
+else
+	BINARY = eth
+endif
 
 SOURCES = \
Index: uspace/srv/net/nil/eth/eth.c
===================================================================
--- uspace/srv/net/nil/eth/eth.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/nil/eth/eth.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -60,4 +60,6 @@
 #include <adt/measured_strings.h>
 #include <packet/packet_client.h>
+#include <packet_remote.h>
+#include <nil_local.h>
 
 #include "eth.h"
@@ -66,5 +68,5 @@
 /** The module name.
  */
-#define NAME	"Ethernet protocol"
+#define NAME  "eth"
 
 /** Reserved packet prefix length.
@@ -270,5 +272,5 @@
 INT_MAP_IMPLEMENT(eth_protos, eth_proto_t)
 
-int nil_device_state_msg(int nil_phone, device_id_t device_id, int state){
+int nil_device_state_msg_local(int nil_phone, device_id_t device_id, int state){
 	int index;
 	eth_proto_ref proto;
@@ -401,5 +403,10 @@
 			return index;
 		}
-		printf("New device registered:\n\tid\t= %d\n\tservice\t= %d\n\tMTU\t= %d\n\taddress\t= %X:%X:%X:%X:%X:%X\n\tflags\t= 0x%x\n", device->device_id, device->service, device->mtu, device->addr_data[0], device->addr_data[1], device->addr_data[2], device->addr_data[3], device->addr_data[4], device->addr_data[5], device->flags);
+		printf("%s: Device registered (id: %d, service: %d: mtu: %d, "
+		    "mac: %x:%x:%x:%x:%x:%x, flags: 0x%x)\n",
+		    NAME, device->device_id, device->service, device->mtu,
+		    device->addr_data[0], device->addr_data[1],
+		    device->addr_data[2], device->addr_data[3],
+		    device->addr_data[4], device->addr_data[5], device->flags);
 	}
 	fibril_rwlock_write_unlock(&eth_globals.devices_lock);
@@ -469,5 +476,5 @@
 }
 
-int nil_received_msg(int nil_phone, device_id_t device_id, packet_t packet, services_t target){
+int nil_received_msg_local(int nil_phone, device_id_t device_id, packet_t packet, services_t target){
 	eth_proto_ref proto;
 	packet_t next;
@@ -491,5 +498,5 @@
 		}else{
 			// drop invalid/unknown
-			pq_release(eth_globals.net_phone, packet_get_id(packet));
+			pq_release_remote(eth_globals.net_phone, packet_get_id(packet));
 		}
 		packet = next;
@@ -571,5 +578,8 @@
 		}
 	}
-	printf("New protocol registered:\n\tprotocol\t= 0x%x\n\tservice\t= %d\n\tphone\t= %d\n", proto->protocol, proto->service, proto->phone);
+	
+	printf("%s: Protocol registered (protocol: %d, service: %d, phone: %d)\n",
+	    NAME, proto->protocol, proto->service, proto->phone);
+	
 	fibril_rwlock_write_unlock(&eth_globals.protos_lock);
 	return EOK;
@@ -672,5 +682,5 @@
 	ethertype = htons(protocol_map(SERVICE_ETHERNET, sender));
 	if(! ethertype){
-		pq_release(eth_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(eth_globals.net_phone, packet_get_id(packet));
 		return EINVAL;
 	}
@@ -690,5 +700,5 @@
 				packet = tmp;
 			}
-			pq_release(eth_globals.net_phone, packet_get_id(next));
+			pq_release_remote(eth_globals.net_phone, packet_get_id(next));
 			next = tmp;
 		}else{
@@ -704,7 +714,9 @@
 }
 
-int nil_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
+int nil_message_standalone(const char *name, ipc_callid_t callid, ipc_call_t *call,
+    ipc_call_t *answer, int *answer_count)
+{
 	ERROR_DECLARE;
-
+	
 	measured_string_ref address;
 	packet_t packet;
@@ -713,17 +725,20 @@
 	size_t suffix;
 	size_t content;
-
-//	printf("message %d - %d\n", IPC_GET_METHOD(*call), NET_NIL_FIRST);
+	
 	*answer_count = 0;
-	switch(IPC_GET_METHOD(*call)){
+	switch (IPC_GET_METHOD(*call)) {
 		case IPC_M_PHONE_HUNGUP:
 			return EOK;
 		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:
-			ERROR_PROPAGATE(packet_translate(eth_globals.net_phone, &packet, IPC_GET_PACKET(call)));
-			return eth_send_message(IPC_GET_DEVICE(call), packet, IPC_GET_SERVICE(call));
+			ERROR_PROPAGATE(packet_translate_remote(eth_globals.net_phone, &packet,
+			    IPC_GET_PACKET(call)));
+			return eth_send_message(IPC_GET_DEVICE(call), packet,
+			    IPC_GET_SERVICE(call));
 		case NET_NIL_PACKET_SPACE:
-			ERROR_PROPAGATE(eth_packet_space_message(IPC_GET_DEVICE(call), &addrlen, &prefix, &content, &suffix));
+			ERROR_PROPAGATE(eth_packet_space_message(IPC_GET_DEVICE(call),
+			    &addrlen, &prefix, &content, &suffix));
 			IPC_SET_ADDR(answer, addrlen);
 			IPC_SET_PREFIX(answer, prefix);
@@ -733,12 +748,16 @@
 			return EOK;
 		case NET_NIL_ADDR:
-			ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call), ETH_LOCAL_ADDR, &address));
+			ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call),
+			    ETH_LOCAL_ADDR, &address));
 			return measured_strings_reply(address, 1);
 		case NET_NIL_BROADCAST_ADDR:
-			ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call), ETH_BROADCAST_ADDR, &address));
+			ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call),
+			    ETH_BROADCAST_ADDR, &address));
 			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));
+	}
+	
 	return ENOTSUP;
 }
@@ -753,10 +772,10 @@
 		switch(IPC_GET_METHOD(*icall)){
 			case NET_NIL_DEVICE_STATE:
-				nil_device_state_msg(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:
-				if(! ERROR_OCCURRED(packet_translate(eth_globals.net_phone, &packet, IPC_GET_PACKET(icall)))){
-					ERROR_CODE = nil_received_msg(0, IPC_GET_DEVICE(icall), packet, 0);
+				if(! ERROR_OCCURRED(packet_translate_remote(eth_globals.net_phone, &packet, IPC_GET_PACKET(icall)))){
+					ERROR_CODE = nil_received_msg_local(0, IPC_GET_DEVICE(icall), packet, 0);
 				}
 				ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);
@@ -769,15 +788,13 @@
 }
 
-#ifdef CONFIG_NETWORKING_modular
-
-#include <nil_standalone.h>
+#ifndef CONFIG_NETIF_NIL_BUNDLE
 
 /** Default thread for new connections.
  *
- *  @param[in] iid The initial message identifier.
- *  @param[in] icall The initial message call structure.
+ * @param[in] iid The initial message identifier.
+ * @param[in] icall The initial message call structure.
  *
  */
-static void nil_client_connection(ipc_callid_t iid, ipc_call_t * icall)
+static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall)
 {
 	/*
@@ -799,5 +816,6 @@
 		
 		/* Process the message */
-		int res = nil_module_message(callid, &call, &answer, &answer_count);
+		int res = nil_module_message_standalone(NAME, callid, &call, &answer,
+		    &answer_count);
 		
 		/* End if said to either by the message or the processing result */
@@ -810,30 +828,16 @@
 }
 
-/** Starts 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[])
 {
 	ERROR_DECLARE;
 	
-	/* Print the module label */
-	printf("Task %d - %s\n", task_get_id(), NAME);
-	
 	/* Start the module */
-	if (ERROR_OCCURRED(nil_module_start(nil_client_connection))) {
-		printf(" - ERROR %i\n", ERROR_CODE);
+	if (ERROR_OCCURRED(nil_module_start_standalone(nil_client_connection)))
 		return ERROR_CODE;
-	}
 	
 	return EOK;
 }
 
-#endif /* CONFIG_NETWORKING_modular */
+#endif /* CONFIG_NETIF_NIL_BUNDLE */
 
 /** @}
Index: uspace/srv/net/nil/eth/eth.h
===================================================================
--- uspace/srv/net/nil/eth/eth.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/nil/eth/eth.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -147,25 +147,4 @@
 };
 
-/** Module initialization.
- *  Is called by the module_start() function.
- *  @param[in] net_phone The networking moduel phone.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for each specific module initialize function.
- */
-extern int nil_initialize(int net_phone);
-
-/** Message processing function.
- *  @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.
- *  @returns EOK on success.
- *  @returns ENOTSUP if the message is not known.
- *  @returns Other error codes as defined for each specific module message function.
- *  @see nil_interface.h
- *  @see IS_NET_NIL_MESSAGE()
- */
-extern int nil_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
-
 #endif
 
Index: uspace/srv/net/nil/eth/eth_module.c
===================================================================
--- uspace/srv/net/nil/eth/eth_module.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/nil/eth/eth_module.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -46,5 +46,5 @@
 #include <net_interface.h>
 #include <packet/packet.h>
-#include <nil_standalone.h>
+#include <nil_local.h>
 
 #include "eth.h"
@@ -58,36 +58,44 @@
  *  @returns Other error codes as defined for the REGISTER_ME() macro function.
  */
-int nil_module_start(async_client_conn_t client_connection){
+int nil_module_start_standalone(async_client_conn_t client_connection)
+{
 	ERROR_DECLARE;
-
+	
+	async_set_client_connection(client_connection);
+	int net_phone = net_connect_module(SERVICE_NETWORKING);
+	ERROR_PROPAGATE(pm_init());
+	
 	ipcarg_t phonehash;
-	int net_phone;
-
-	async_set_client_connection(client_connection);
-	net_phone = net_connect_module(SERVICE_NETWORKING);
-	ERROR_PROPAGATE(pm_init());
-	if(ERROR_OCCURRED(nil_initialize(net_phone))
-		|| ERROR_OCCURRED(REGISTER_ME(SERVICE_ETHERNET, &phonehash))){
+	if (ERROR_OCCURRED(nil_initialize(net_phone))
+	    || ERROR_OCCURRED(REGISTER_ME(SERVICE_ETHERNET, &phonehash))) {
 		pm_destroy();
 		return ERROR_CODE;
 	}
-
+	
 	async_manager();
-
+	
 	pm_destroy();
 	return EOK;
 }
 
-/** Passes the parameters to the module specific nil_message() function.
- *  @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.
- *  @returns EOK on success.
- *  @returns ENOTSUP if the message is not known.
- *  @returns Other error codes as defined for each specific module message function.
+/** Pass the parameters to the module specific nil_message() function.
+ *
+ * @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.
+ *
  */
-int nil_module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
-	return nil_message(callid, call, answer, answer_count);
+int nil_module_message_standalone(const char *name, ipc_callid_t callid, ipc_call_t *call,
+    ipc_call_t *answer, int *answer_count)
+{
+	return nil_message_standalone(name, callid, call, answer, answer_count);
 }
 
Index: uspace/srv/net/nil/nildummy/Makefile
===================================================================
--- uspace/srv/net/nil/nildummy/Makefile	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/nil/nildummy/Makefile	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -29,7 +29,19 @@
 
 USPACE_PREFIX = ../../../..
-LIBS = $(LIBNETIF_PREFIX)/libnetif.a $(LIBNET_PREFIX)/libnet.a $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBNETIF_PREFIX)/include -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
-BINARY = nildummy
+ROOT_PATH = $(USPACE_PREFIX)/..
+LIBS = $(LIBNET_PREFIX)/libnet.a $(LIBSOCKET_PREFIX)/libsocket.a
+EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
+
+COMMON_MAKEFILE = $(ROOT_PATH)/Makefile.common
+CONFIG_MAKEFILE = $(ROOT_PATH)/Makefile.config
+
+-include $(COMMON_MAKEFILE)
+-include $(CONFIG_MAKEFILE)
+
+ifeq ($(CONFIG_NETIF_NIL_BUNDLE),y)
+	LIBRARY = libnildummy
+else
+	BINARY = nildummy
+endif
 
 SOURCES = \
Index: uspace/srv/net/nil/nildummy/nildummy.c
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/nil/nildummy/nildummy.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -28,10 +28,10 @@
 
 /** @addtogroup nildummy
- *  @{
+ * @{
  */
 
 /** @file
- *  Dummy network interface layer module implementation.
- *  @see nildummy.h
+ * Dummy network interface layer module implementation.
+ * @see nildummy.h
  */
 
@@ -41,5 +41,4 @@
 #include <stdio.h>
 #include <str.h>
-
 #include <ipc/ipc.h>
 #include <ipc/services.h>
@@ -54,113 +53,106 @@
 #include <adt/measured_strings.h>
 #include <packet/packet.h>
-#include <nil_module.h>
+#include <packet_remote.h>
+#include <nil_local.h>
 
 #include "nildummy.h"
 
 /** The module name.
- */
-#define NAME	"Dummy nil protocol"
+ *
+ */
+#define NAME  "nildummy"
 
 /** Default maximum transmission unit.
- */
-#define NET_DEFAULT_MTU	1500
+ *
+ */
+#define NET_DEFAULT_MTU  1500
 
 /** Network interface layer module global data.
- */
-nildummy_globals_t	nildummy_globals;
-
-/** @name Message processing functions
- */
-/*@{*/
-
-/** Processes IPC messages from the registered device driver modules in an infinite loop.
- *  @param[in] iid The message identifier.
- *  @param[in,out] icall The message parameters.
- */
-void nildummy_receiver(ipc_callid_t iid, ipc_call_t * icall);
-
-/** Registers new device or updates the MTU of an existing one.
- *  Determines the device local hardware address.
- *  @param[in] device_id The new device identifier.
- *  @param[in] service The device driver service.
- *  @param[in] mtu The device maximum transmission unit.
- *  @returns EOK on success.
- *  @returns EEXIST if the device with the different service exists.
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns Other error codes as defined for the netif_bind_service() function.
- *  @returns Other error codes as defined for the netif_get_addr_req() function.
- */
-int nildummy_device_message(device_id_t device_id, services_t service, size_t mtu);
-
-/** Returns the device packet dimensions for sending.
- *  @param[in] device_id The device identifier.
- *  @param[out] addr_len The minimum reserved address length.
- *  @param[out] prefix The minimum reserved prefix size.
- *  @param[out] content The maximum content size.
- *  @param[out] suffix The minimum reserved suffix size.
- *  @returns EOK on success.
- *  @returns EBADMEM if either one of the parameters is NULL.
- *  @returns ENOENT if there is no such device.
- */
-int nildummy_packet_space_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix);
-
-/** Registers receiving module service.
- *  Passes received packets for this service.
- *  @param[in] service The module service.
- *  @param[in] phone The service phone.
- *  @returns EOK on success.
- *  @returns ENOENT if the service is not known.
- *  @returns ENOMEM if there is not enough memory left.
- */
-int nildummy_register_message(services_t service, int phone);
-
-/** Sends the packet queue.
- *  @param[in] device_id The device identifier.
- *  @param[in] packet The packet queue.
- *  @param[in] sender The sending module service.
- *  @returns EOK on success.
- *  @returns ENOENT if there no such device.
- *  @returns EINVAL if the service parameter is not known.
- */
-int nildummy_send_message(device_id_t device_id, packet_t packet, services_t sender);
-
-/** Returns the device hardware address.
- *  @param[in] device_id The device identifier.
- *  @param[out] address The device hardware address.
- *  @returns EOK on success.
- *  @returns EBADMEM if the address parameter is NULL.
- *  @returns ENOENT if there no such device.
- */
-int nildummy_addr_message(device_id_t device_id, measured_string_ref * address);
-
-/*@}*/
-
-DEVICE_MAP_IMPLEMENT(nildummy_devices, nildummy_device_t)
-
-int nil_device_state_msg(int nil_phone, device_id_t device_id, int state){
+ *
+ */
+nildummy_globals_t nildummy_globals;
+
+DEVICE_MAP_IMPLEMENT(nildummy_devices, nildummy_device_t);
+
+int nil_device_state_msg_local(int nil_phone, device_id_t device_id, int state)
+{
 	fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
-	if(nildummy_globals.proto.phone){
-		il_device_state_msg(nildummy_globals.proto.phone, device_id, state, nildummy_globals.proto.service);
-	}
+	
+	if (nildummy_globals.proto.phone)
+		il_device_state_msg(nildummy_globals.proto.phone, device_id, state,
+		    nildummy_globals.proto.service);
+	
 	fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
-	return EOK;
-}
-
-int nil_initialize(int net_phone){
+	
+	return EOK;
+}
+
+int nil_initialize(int net_phone)
+{
 	ERROR_DECLARE;
-
+	
 	fibril_rwlock_initialize(&nildummy_globals.devices_lock);
 	fibril_rwlock_initialize(&nildummy_globals.protos_lock);
 	fibril_rwlock_write_lock(&nildummy_globals.devices_lock);
 	fibril_rwlock_write_lock(&nildummy_globals.protos_lock);
+	
 	nildummy_globals.net_phone = net_phone;
 	nildummy_globals.proto.phone = 0;
 	ERROR_PROPAGATE(nildummy_devices_initialize(&nildummy_globals.devices));
+	
 	fibril_rwlock_write_unlock(&nildummy_globals.protos_lock);
 	fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
-	return EOK;
-}
-
-int nildummy_device_message(device_id_t device_id, services_t service, size_t mtu){
+	
+	return EOK;
+}
+
+/** Process IPC messages from the registered device driver modules in an infinite loop.
+ *
+ * @param[in]     iid   The message identifier.
+ * @param[in,out] icall The message parameters.
+ *
+ */
+static void nildummy_receiver(ipc_callid_t iid, ipc_call_t * icall){
+	ERROR_DECLARE;
+
+	packet_t packet;
+
+	while(true){
+		switch(IPC_GET_METHOD(*icall)){
+			case NET_NIL_DEVICE_STATE:
+				ERROR_CODE = nil_device_state_msg_local(0, IPC_GET_DEVICE(icall), IPC_GET_STATE(icall));
+				ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);
+				break;
+			case NET_NIL_RECEIVED:
+				if(! ERROR_OCCURRED(packet_translate_remote(nildummy_globals.net_phone, &packet, IPC_GET_PACKET(icall)))){
+					ERROR_CODE = nil_received_msg_local(0, IPC_GET_DEVICE(icall), packet, 0);
+				}
+				ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);
+				break;
+			default:
+				ipc_answer_0(iid, (ipcarg_t) ENOTSUP);
+		}
+		iid = async_get_call(icall);
+	}
+}
+
+/** Register new device or updates the MTU of an existing one.
+ *
+ * Determine the device local hardware address.
+ *
+ * @param[in] device_id The new device identifier.
+ * @param[in] service   The device driver service.
+ * @param[in] mtu       The device maximum transmission unit.
+ *
+ * @returns EOK on success.
+ * @returns EEXIST if the device with the different service exists.
+ * @returns ENOMEM if there is not enough memory left.
+ * @returns Other error codes as defined for the netif_bind_service() function.
+ * @returns Other error codes as defined for the netif_get_addr_req() function.
+ *
+ */
+static int nildummy_device_message(device_id_t device_id, services_t service,
+    size_t mtu)
+{
 	ERROR_DECLARE;
 
@@ -228,5 +220,6 @@
 			return index;
 		}
-		printf("New device registered:\n\tid\t= %d\n\tservice\t= %d\n\tMTU\t= %d\n", device->device_id, device->service, device->mtu);
+		printf("%s: Device registered (id: %d, service: %d, mtu: %d)\n",
+		    NAME, device->device_id, device->service, device->mtu);
 	}
 	fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
@@ -234,5 +227,17 @@
 }
 
-int nildummy_addr_message(device_id_t device_id, measured_string_ref * address){
+/** Return the device hardware address.
+ *
+ * @param[in]  device_id The device identifier.
+ * @param[out] address   The device hardware address.
+ *
+ * @return EOK on success.
+ * @return EBADMEM if the address parameter is NULL.
+ * @return ENOENT if there no such device.
+ *
+ */
+static int nildummy_addr_message(device_id_t device_id,
+    measured_string_ref *address)
+{
 	nildummy_device_ref device;
 
@@ -251,5 +256,20 @@
 }
 
-int nildummy_packet_space_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix){
+/** Return the device packet dimensions for sending.
+ *
+ * @param[in]  device_id The device identifier.
+ * @param[out] addr_len  The minimum reserved address length.
+ * @param[out] prefix    The minimum reserved prefix size.
+ * @param[out] content   The maximum content size.
+ * @param[out] suffix    The minimum reserved suffix size.
+ *
+ * @return EOK on success.
+ * @return EBADMEM if either one of the parameters is NULL.
+ * @return ENOENT if there is no such device.
+ *
+ */
+static int nildummy_packet_space_message(device_id_t device_id,
+    size_t *addr_len, size_t *prefix, size_t *content, size_t *suffix)
+{
 	nildummy_device_ref device;
 
@@ -271,5 +291,5 @@
 }
 
-int nil_received_msg(int nil_phone, device_id_t device_id, packet_t packet, services_t target){
+int nil_received_msg_local(int nil_phone, device_id_t device_id, packet_t packet, services_t target){
 	packet_t next;
 
@@ -286,14 +306,43 @@
 }
 
-int nildummy_register_message(services_t service, int phone){
+/** Register receiving module service.
+ *
+ * Pass received packets for this service.
+ *
+ * @param[in] service The module service.
+ * @param[in] phone   The service phone.
+ *
+ * @return EOK on success.
+ * @return ENOENT if the service is not known.
+ * @return ENOMEM if there is not enough memory left.
+ *
+ */
+static int nildummy_register_message(services_t service, int phone)
+{
 	fibril_rwlock_write_lock(&nildummy_globals.protos_lock);
 	nildummy_globals.proto.service = service;
 	nildummy_globals.proto.phone = phone;
-	printf("New protocol registered:\n\tservice\t= %d\n\tphone\t= %d\n", nildummy_globals.proto.service, nildummy_globals.proto.phone);
+	
+	printf("%s: Protocol registered (service: %d, phone: %d)\n",
+	    NAME, nildummy_globals.proto.service, nildummy_globals.proto.phone);
+	
 	fibril_rwlock_write_unlock(&nildummy_globals.protos_lock);
 	return EOK;
 }
 
-int nildummy_send_message(device_id_t device_id, packet_t packet, services_t sender){
+/** Send the packet queue.
+ *
+ * @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 ENOENT if there no such device.
+ * @return EINVAL if the service parameter is not known.
+ *
+ */
+static int nildummy_send_message(device_id_t device_id, packet_t packet,
+    services_t sender)
+{
 	nildummy_device_ref device;
 
@@ -312,7 +361,9 @@
 }
 
-int nil_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
+int nil_message_standalone(const char *name, ipc_callid_t callid, ipc_call_t *call,
+    ipc_call_t *answer, int *answer_count)
+{
 	ERROR_DECLARE;
-
+	
 	measured_string_ref address;
 	packet_t packet;
@@ -321,17 +372,20 @@
 	size_t suffix;
 	size_t content;
-
-//	printf("message %d - %d\n", IPC_GET_METHOD(*call), NET_NIL_FIRST);
+	
 	*answer_count = 0;
-	switch(IPC_GET_METHOD(*call)){
+	switch (IPC_GET_METHOD(*call)) {
 		case IPC_M_PHONE_HUNGUP:
 			return EOK;
 		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:
-			ERROR_PROPAGATE(packet_translate(nildummy_globals.net_phone, &packet, IPC_GET_PACKET(call)));
-			return nildummy_send_message(IPC_GET_DEVICE(call), packet, IPC_GET_SERVICE(call));
+			ERROR_PROPAGATE(packet_translate_remote(nildummy_globals.net_phone,
+			    &packet, IPC_GET_PACKET(call)));
+			return nildummy_send_message(IPC_GET_DEVICE(call), packet,
+			    IPC_GET_SERVICE(call));
 		case NET_NIL_PACKET_SPACE:
-			ERROR_PROPAGATE(nildummy_packet_space_message(IPC_GET_DEVICE(call), &addrlen, &prefix, &content, &suffix));
+			ERROR_PROPAGATE(nildummy_packet_space_message(IPC_GET_DEVICE(call),
+			    &addrlen, &prefix, &content, &suffix));
 			IPC_SET_ADDR(answer, addrlen);
 			IPC_SET_PREFIX(answer, prefix);
@@ -341,48 +395,28 @@
 			return EOK;
 		case NET_NIL_ADDR:
-			ERROR_PROPAGATE(nildummy_addr_message(IPC_GET_DEVICE(call), &address));
+			ERROR_PROPAGATE(nildummy_addr_message(IPC_GET_DEVICE(call),
+			    &address));
+			return measured_strings_reply(address, 1);
+		case NET_NIL_BROADCAST_ADDR:
+			ERROR_PROPAGATE(nildummy_addr_message(IPC_GET_DEVICE(call),
+			    &address));
 			return measured_strings_reply(address, 1);
 		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));
+	}
+	
 	return ENOTSUP;
 }
 
-void nildummy_receiver(ipc_callid_t iid, ipc_call_t * icall){
-	ERROR_DECLARE;
-
-	packet_t packet;
-
-	while(true){
-//		printf("message %d - %d\n", IPC_GET_METHOD(*icall), NET_NIL_FIRST);
-		switch(IPC_GET_METHOD(*icall)){
-			case NET_NIL_DEVICE_STATE:
-				ERROR_CODE = nil_device_state_msg(0, IPC_GET_DEVICE(icall), IPC_GET_STATE(icall));
-				ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);
-				break;
-			case NET_NIL_RECEIVED:
-				if(! ERROR_OCCURRED(packet_translate(nildummy_globals.net_phone, &packet, IPC_GET_PACKET(icall)))){
-					ERROR_CODE = nil_received_msg(0, IPC_GET_DEVICE(icall), packet, 0);
-				}
-				ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);
-				break;
-			default:
-				ipc_answer_0(iid, (ipcarg_t) ENOTSUP);
-		}
-		iid = async_get_call(icall);
-	}
-}
-
-#ifdef CONFIG_NETWORKING_modular
-
-#include <nil_standalone.h>
+#ifndef CONFIG_NETIF_NIL_BUNDLE
 
 /** Default thread for new connections.
  *
- *  @param[in] iid The initial message identifier.
- *  @param[in] icall The initial message call structure.
- *
- */
-static void nil_client_connection(ipc_callid_t iid, ipc_call_t * icall)
+ * @param[in] iid   The initial message identifier.
+ * @param[in] icall The initial message call structure.
+ *
+ */
+static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall)
 {
 	/*
@@ -404,5 +438,6 @@
 		
 		/* Process the message */
-		int res = nil_module_message(callid, &call, &answer, &answer_count);
+		int res = nil_module_message_standalone(NAME, callid, &call, &answer,
+		    &answer_count);
 		
 		/* End if said to either by the message or the processing result */
@@ -415,30 +450,16 @@
 }
 
-/** Starts 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[])
 {
 	ERROR_DECLARE;
 	
-	/* Print the module label */
-	printf("Task %d - %s\n", task_get_id(), NAME);
-	
 	/* Start the module */
-	if (ERROR_OCCURRED(nil_module_start(nil_client_connection))) {
-		printf(" - ERROR %i\n", ERROR_CODE);
+	if (ERROR_OCCURRED(nil_module_start_standalone(nil_client_connection)))
 		return ERROR_CODE;
-	}
-	
-	return EOK;
-}
-
-#endif /* CONFIG_NETWORKING_modular */
+	
+	return EOK;
+}
+
+#endif /* CONFIG_NETIF_NIL_BUNDLE */
 
 /** @}
Index: uspace/srv/net/nil/nildummy/nildummy_module.c
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy_module.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/nil/nildummy/nildummy_module.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -46,49 +46,64 @@
 #include <net_interface.h>
 #include <packet/packet.h>
-#include <nil_module.h>
-#include <nil_standalone.h>
+#include <nil_local.h>
 
 #include "nildummy.h"
 
-/** Starts the dummy nil module.
- *  Initializes the client connection serving function, initializes the module, registers the module service and starts 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.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the pm_init() function.
- *  @returns Other error codes as defined for the nil_initialize() function.
- *  @returns Other error codes as defined for the REGISTER_ME() macro function.
+/** Start the dummy nil module.
+ *
+ * Initialize the client connection serving function, initialize
+ * the module, register 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 the pm_init() function.
+ * @return Other error codes as defined for the nil_initialize() function.
+ * @return Other error codes as defined for the REGISTER_ME() macro function.
+ *
  */
-int nil_module_start(async_client_conn_t client_connection){
+int nil_module_start_standalone(async_client_conn_t client_connection)
+{
 	ERROR_DECLARE;
-
+	
+	async_set_client_connection(client_connection);
+	int net_phone = net_connect_module(SERVICE_NETWORKING);
+	ERROR_PROPAGATE(pm_init());
+	
 	ipcarg_t phonehash;
-	int net_phone;
-
-	async_set_client_connection(client_connection);
-	net_phone = net_connect_module(SERVICE_NETWORKING);
-	ERROR_PROPAGATE(pm_init());
-	if(ERROR_OCCURRED(nil_initialize(net_phone))
-		|| ERROR_OCCURRED(REGISTER_ME(SERVICE_NILDUMMY, &phonehash))){
+	if (ERROR_OCCURRED(nil_initialize(net_phone))
+	    || ERROR_OCCURRED(REGISTER_ME(SERVICE_NILDUMMY, &phonehash))){
 		pm_destroy();
 		return ERROR_CODE;
 	}
-
+	
 	async_manager();
-
+	
 	pm_destroy();
 	return EOK;
 }
 
-/** Passes the parameters to the module specific nil_message() function.
- *  @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.
- *  @returns EOK on success.
- *  @returns ENOTSUP if the message is not known.
- *  @returns Other error codes as defined for each specific module message function.
+/** Pass the parameters to the module specific nil_message() function.
+ *
+ * @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.
+ *
  */
-int nil_module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
-	return nil_message(callid, call, answer, answer_count);
+int nil_module_message_standalone(const char *name, ipc_callid_t callid,
+    ipc_call_t *call, ipc_call_t *answer, int *answer_count)
+{
+	return nil_message_standalone(name, callid, call, answer, answer_count);
 }
 
Index: uspace/srv/net/tl/icmp/icmp.c
===================================================================
--- uspace/srv/net/tl/icmp/icmp.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/tl/icmp/icmp.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -51,4 +51,5 @@
 #include <net_modules.h>
 #include <packet/packet_client.h>
+#include <packet_remote.h>
 #include <net_byteorder.h>
 #include <net_checksum.h>
@@ -67,4 +68,6 @@
 #include <socket_errno.h>
 #include <tl_messages.h>
+#include <tl_interface.h>
+#include <tl_local.h>
 #include <icmp_messages.h>
 #include <icmp_header.h>
@@ -288,5 +291,5 @@
 	// TODO do not ask all the time
 	ERROR_PROPAGATE(ip_packet_size_req(icmp_globals.ip_phone, -1, &icmp_globals.packet_dimension));
-	packet = packet_get_4(icmp_globals.net_phone, size, icmp_globals.packet_dimension.addr_len, ICMP_HEADER_SIZE + icmp_globals.packet_dimension.prefix, icmp_globals.packet_dimension.suffix);
+	packet = packet_get_4_remote(icmp_globals.net_phone, size, icmp_globals.packet_dimension.addr_len, ICMP_HEADER_SIZE + icmp_globals.packet_dimension.prefix, icmp_globals.packet_dimension.suffix);
 	if(! packet){
 		return ENOMEM;
@@ -626,5 +629,5 @@
 	// compute the reply key
 	reply_key = ICMP_GET_REPLY_KEY(header->un.echo.identifier, header->un.echo.sequence_number);
-	pq_release(icmp_globals.net_phone, packet_get_id(packet));
+	pq_release_remote(icmp_globals.net_phone, packet_get_id(packet));
 	// lock the globals
 	fibril_rwlock_write_lock(&icmp_globals.lock);
@@ -641,5 +644,5 @@
 }
 
-int icmp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
+int icmp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
 	ERROR_DECLARE;
 
@@ -649,5 +652,5 @@
 	switch(IPC_GET_METHOD(*call)){
 		case NET_TL_RECEIVED:
-			if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
+			if(! ERROR_OCCURRED(packet_translate_remote(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
 				ERROR_CODE = icmp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_ICMP, IPC_GET_ERROR(call));
 			}
@@ -759,20 +762,20 @@
 	switch(IPC_GET_METHOD(*call)){
 		case NET_ICMP_DEST_UNREACH:
-			if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
+			if(! ERROR_OCCURRED(packet_translate_remote(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
 				ERROR_CODE = icmp_destination_unreachable_msg(0, ICMP_GET_CODE(call), ICMP_GET_MTU(call), packet);
 			}
 			return ERROR_CODE;
 		case NET_ICMP_SOURCE_QUENCH:
-			if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
+			if(! ERROR_OCCURRED(packet_translate_remote(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
 				ERROR_CODE = icmp_source_quench_msg(0, packet);
 			}
 			return ERROR_CODE;
 		case NET_ICMP_TIME_EXCEEDED:
-			if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
+			if(! ERROR_OCCURRED(packet_translate_remote(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
 				ERROR_CODE = icmp_time_exceeded_msg(0, ICMP_GET_CODE(call), packet);
 			}
 			return ERROR_CODE;
 		case NET_ICMP_PARAMETERPROB:
-			if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
+			if(! ERROR_OCCURRED(packet_translate_remote(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
 				ERROR_CODE = icmp_parameter_problem_msg(0, ICMP_GET_CODE(call), ICMP_GET_POINTER(call), packet);
 			}
@@ -784,5 +787,5 @@
 
 int icmp_release_and_return(packet_t packet, int result){
-	pq_release(icmp_globals.net_phone, packet_get_id(packet));
+	pq_release_remote(icmp_globals.net_phone, packet_get_id(packet));
 	return result;
 }
@@ -819,8 +822,4 @@
 }
 
-#ifdef CONFIG_NETWORKING_modular
-
-#include <tl_standalone.h>
-
 /** Default thread for new connections.
  *
@@ -849,5 +848,6 @@
 		
 		/* Process the message */
-		int res = tl_module_message(callid, &call, &answer, &answer_count);
+		int res = tl_module_message_standalone(callid, &call, &answer,
+		    &answer_count);
 		
 		/* End if said to either by the message or the processing result */
@@ -873,18 +873,11 @@
 	ERROR_DECLARE;
 	
-	/* Print the module label */
-	printf("Task %d - %s\n", task_get_id(), NAME);
-	
 	/* Start the module */
-	if (ERROR_OCCURRED(tl_module_start(tl_client_connection))) {
-		printf(" - ERROR %i\n", ERROR_CODE);
+	if (ERROR_OCCURRED(tl_module_start_standalone(tl_client_connection)))
 		return ERROR_CODE;
-	}
 	
 	return EOK;
 }
 
-#endif /* CONFIG_NETWORKING_modular */
-
 /** @}
  */
Index: uspace/srv/net/tl/icmp/icmp_module.c
===================================================================
--- uspace/srv/net/tl/icmp/icmp_module.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/tl/icmp/icmp_module.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -47,5 +47,5 @@
 #include <packet/packet.h>
 #include <net_interface.h>
-#include <tl_standalone.h>
+#include <tl_local.h>
 
 #include "icmp.h"
@@ -63,5 +63,5 @@
  *  @returns Other error codes as defined for the REGISTER_ME() macro function.
  */
-int tl_module_start(async_client_conn_t client_connection){
+int tl_module_start_standalone(async_client_conn_t client_connection){
 	ERROR_DECLARE;
 
@@ -94,6 +94,6 @@
  *  @returns Other error codes as defined for the icmp_message() function.
  */
-int tl_module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
-	return icmp_message(callid, call, answer, answer_count);
+int tl_module_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
+	return icmp_message_standalone(callid, call, answer, answer_count);
 }
 
Index: uspace/srv/net/tl/icmp/icmp_module.h
===================================================================
--- uspace/srv/net/tl/icmp/icmp_module.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/tl/icmp/icmp_module.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -59,5 +59,5 @@
  *  @see IS_NET_ICMP_MESSAGE()
  */
-int icmp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
+int icmp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
 
 #endif
Index: uspace/srv/net/tl/tcp/tcp.c
===================================================================
--- uspace/srv/net/tl/tcp/tcp.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/tl/tcp/tcp.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -51,4 +51,5 @@
 #include <adt/dynamic_fifo.h>
 #include <packet/packet_client.h>
+#include <packet_remote.h>
 #include <net_checksum.h>
 #include <in.h>
@@ -68,4 +69,6 @@
 #include <tl_common.h>
 #include <tl_messages.h>
+#include <tl_local.h>
+#include <tl_interface.h>
 
 #include "tcp.h"
@@ -421,5 +424,5 @@
 			break;
 		default:
-			pq_release(tcp_globals.net_phone, packet_get_id(packet));
+			pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 	}
 
@@ -473,5 +476,5 @@
 			// release the acknowledged packets
 			next_packet = pq_next(packet);
-			pq_release(tcp_globals.net_phone, packet_get_id(packet));
+			pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 			packet = next_packet;
 			offset -= length;
@@ -517,5 +520,5 @@
 			next_packet = pq_next(next_packet);
 			pq_insert_after(tmp_packet, next_packet);
-			pq_release(tcp_globals.net_phone, packet_get_id(tmp_packet));
+			pq_release_remote(tcp_globals.net_phone, packet_get_id(tmp_packet));
 		}
 		assert(new_sequence_number + total_length == socket_data->next_incoming + socket_data->window);
@@ -548,5 +551,5 @@
 					socket_data->incoming = next_packet;
 				}
-				pq_release(tcp_globals.net_phone, packet_get_id(packet));
+				pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 				packet = next_packet;
 				continue;
@@ -568,5 +571,5 @@
 				if(length <= 0){
 					// remove the empty packet
-					pq_release(tcp_globals.net_phone, packet_get_id(packet));
+					pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 					packet = next_packet;
 					continue;
@@ -595,5 +598,5 @@
 				}
 				// remove the duplicit or corrupted packet
-				pq_release(tcp_globals.net_phone, packet_get_id(packet));
+				pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 				packet = next_packet;
 				continue;
@@ -617,6 +620,6 @@
 		if(ERROR_OCCURRED(pq_add(&socket_data->incoming, packet, new_sequence_number, length))){
 			// remove the corrupted packets
-			pq_release(tcp_globals.net_phone, packet_get_id(packet));
-			pq_release(tcp_globals.net_phone, packet_get_id(next_packet));
+			pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+			pq_release_remote(tcp_globals.net_phone, packet_get_id(next_packet));
 		}else{
 			while(next_packet){
@@ -626,5 +629,5 @@
 				if(ERROR_OCCURRED(pq_set_order(next_packet, new_sequence_number, length))
 					|| ERROR_OCCURRED(pq_insert_after(packet, next_packet))){
-					pq_release(tcp_globals.net_phone, packet_get_id(next_packet));
+					pq_release_remote(tcp_globals.net_phone, packet_get_id(next_packet));
 				}
 				next_packet = tmp_packet;
@@ -634,5 +637,5 @@
 		printf("unexpected\n");
 		// release duplicite or restricted
-		pq_release(tcp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 	}
 
@@ -679,5 +682,5 @@
 	// queue the received packet
 	if(ERROR_OCCURRED(dyn_fifo_push(&socket->received, packet_get_id(packet), SOCKET_MAX_RECEIVED_SIZE))
-		|| ERROR_OCCURRED(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension))){
+	    || ERROR_OCCURRED(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension))){
 		return tcp_release_and_return(packet, ERROR_CODE);
 	}
@@ -710,5 +713,5 @@
 		next_packet = pq_detach(packet);
 		if(next_packet){
-			pq_release(tcp_globals.net_phone, packet_get_id(next_packet));
+			pq_release_remote(tcp_globals.net_phone, packet_get_id(next_packet));
 		}
 		// trim if longer than the header
@@ -780,5 +783,5 @@
 				free(socket_data->addr);
 				free(socket_data);
-				pq_release(tcp_globals.net_phone, packet_get_id(packet));
+				pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 				return ERROR_CODE;
 			}
@@ -846,5 +849,5 @@
 			next_packet = pq_detach(packet);
 			if(next_packet){
-				pq_release(tcp_globals.net_phone, packet_get_id(next_packet));
+				pq_release_remote(tcp_globals.net_phone, packet_get_id(next_packet));
 			}
 			// trim if longer than the header
@@ -895,5 +898,5 @@
 
 		socket_data->next_incoming = ntohl(header->sequence_number);// + 1;
-		pq_release(tcp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 		socket_data->state = TCP_SOCKET_ESTABLISHED;
 		listening_socket = socket_cores_find(socket_data->local_sockets, socket_data->listening_socket_id);
@@ -981,5 +984,5 @@
 					// add to acknowledged or release
 					if(pq_add(&acknowledged, packet, 0, 0) != EOK){
-						pq_release(tcp_globals.net_phone, packet_get_id(packet));
+						pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 					}
 					packet = next;
@@ -990,5 +993,5 @@
 			// release acknowledged
 			if(acknowledged){
-				pq_release(tcp_globals.net_phone, packet_get_id(acknowledged));
+				pq_release_remote(tcp_globals.net_phone, packet_get_id(acknowledged));
 			}
 			return;
@@ -1006,5 +1009,5 @@
 }
 
-int tcp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
+int tcp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
 	ERROR_DECLARE;
 
@@ -1019,5 +1022,5 @@
 		case NET_TL_RECEIVED:
 			//fibril_rwlock_read_lock(&tcp_globals.lock);
-			if(! ERROR_OCCURRED(packet_translate(tcp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
+			if(! ERROR_OCCURRED(packet_translate_remote(tcp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
 				ERROR_CODE = tcp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_TCP, IPC_GET_ERROR(call));
 			}
@@ -1111,5 +1114,5 @@
 					fibril_rwlock_write_unlock(&lock);
 					if(res == EOK){
-						if(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, DEVICE_INVALID_ID, &packet_dimension) == EOK){
+						if (tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, DEVICE_INVALID_ID, &packet_dimension) == EOK){
 							SOCKET_SET_DATA_FRAGMENT_SIZE(answer, ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size));
 						}
@@ -1565,5 +1568,5 @@
 			}else{
 				if(ERROR_OCCURRED(pq_insert_after(previous, copy))){
-					pq_release(tcp_globals.net_phone, packet_get_id(copy));
+					pq_release_remote(tcp_globals.net_phone, packet_get_id(copy));
 					return sending;
 				}
@@ -1597,5 +1600,5 @@
 	// adjust the pseudo header
 	if(ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(socket_data->pseudo_header, socket_data->headerlen, packet_get_data_length(packet)))){
-		pq_release(tcp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 		return NULL;
 	}
@@ -1604,5 +1607,5 @@
 	header = (tcp_header_ref) packet_get_data(packet);
 	if(! header){
-		pq_release(tcp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 		return NULL;
 	}
@@ -1625,5 +1628,5 @@
 	// prepare the timeout
 		|| ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data, sequence_number, socket_data->state, socket_data->timeout, true))){
-		pq_release(tcp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 		return NULL;
 	}
@@ -1750,5 +1753,5 @@
 		return NO_DATA;
 	}
-	ERROR_PROPAGATE(packet_translate(tcp_globals.net_phone, &packet, packet_id));
+	ERROR_PROPAGATE(packet_translate_remote(tcp_globals.net_phone, &packet, packet_id));
 
 	// reply the packets
@@ -1757,5 +1760,5 @@
 	// release the packet
 	dyn_fifo_pop(&socket->received);
-	pq_release(tcp_globals.net_phone, packet_get_id(packet));
+	pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 	// return the total length
 	return (int) length;
@@ -1889,5 +1892,5 @@
 	ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension));
 	// get a new packet
-	*packet = packet_get_4(tcp_globals.net_phone, TCP_HEADER_SIZE, packet_dimension->addr_len, packet_dimension->prefix, packet_dimension->suffix);
+	*packet = packet_get_4_remote(tcp_globals.net_phone, TCP_HEADER_SIZE, packet_dimension->addr_len, packet_dimension->prefix, packet_dimension->suffix);
 	if(! * packet){
 		return ENOMEM;
@@ -1993,11 +1996,7 @@
 
 int tcp_release_and_return(packet_t packet, int result){
-	pq_release(tcp_globals.net_phone, packet_get_id(packet));
+	pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 	return result;
 }
-
-#ifdef CONFIG_NETWORKING_modular
-
-#include <tl_standalone.h>
 
 /** Default thread for new connections.
@@ -2027,5 +2026,6 @@
 		
 		/* Process the message */
-		int res = tl_module_message(callid, &call, &answer, &answer_count);
+		int res = tl_module_message_standalone(callid, &call, &answer,
+		    &answer_count);
 		
 		/* End if said to either by the message or the processing result */
@@ -2051,18 +2051,11 @@
 	ERROR_DECLARE;
 	
-	/* Print the module label */
-	printf("Task %d - %s\n", task_get_id(), NAME);
-	
 	/* Start the module */
-	if (ERROR_OCCURRED(tl_module_start(tl_client_connection))) {
-		printf(" - ERROR %i\n", ERROR_CODE);
+	if (ERROR_OCCURRED(tl_module_start_standalone(tl_client_connection)))
 		return ERROR_CODE;
-	}
 	
 	return EOK;
 }
 
-#endif /* CONFIG_NETWORKING_modular */
-
 /** @}
  */
Index: uspace/srv/net/tl/tcp/tcp.h
===================================================================
--- uspace/srv/net/tl/tcp/tcp.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/tl/tcp/tcp.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -232,5 +232,5 @@
 	/** IP pseudo header.
 	 */
-	ip_pseudo_header_ref pseudo_header;
+	void *pseudo_header;
 	/** IP pseudo header length.
 	 */
Index: uspace/srv/net/tl/tcp/tcp_module.c
===================================================================
--- uspace/srv/net/tl/tcp/tcp_module.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/tl/tcp/tcp_module.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -49,5 +49,5 @@
 #include <ip_protocols.h>
 #include <ip_interface.h>
-#include <tl_standalone.h>
+#include <tl_local.h>
 
 #include "tcp.h"
@@ -65,20 +65,21 @@
  *  @returns Other error codes as defined for the REGISTER_ME() macro function.
  */
-int tl_module_start(async_client_conn_t client_connection){
+int tl_module_start_standalone(async_client_conn_t client_connection)
+{
 	ERROR_DECLARE;
-
-	ipcarg_t phonehash;
-
+	
 	async_set_client_connection(client_connection);
 	tcp_globals.net_phone = net_connect_module(SERVICE_NETWORKING);
 	ERROR_PROPAGATE(pm_init());
-	if(ERROR_OCCURRED(tcp_initialize(client_connection))
-		|| ERROR_OCCURRED(REGISTER_ME(SERVICE_TCP, &phonehash))){
+	
+	ipcarg_t phonehash;
+	if (ERROR_OCCURRED(tcp_initialize(client_connection))
+	    || ERROR_OCCURRED(REGISTER_ME(SERVICE_TCP, &phonehash))) {
 		pm_destroy();
 		return ERROR_CODE;
 	}
-
+	
 	async_manager();
-
+	
 	pm_destroy();
 	return EOK;
@@ -93,6 +94,6 @@
  *  @returns Other error codes as defined for the tcp_message() function.
  */
-int tl_module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
-	return tcp_message(callid, call, answer, answer_count);
+int tl_module_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
+	return tcp_message_standalone(callid, call, answer, answer_count);
 }
 
Index: uspace/srv/net/tl/tcp/tcp_module.h
===================================================================
--- uspace/srv/net/tl/tcp/tcp_module.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/tl/tcp/tcp_module.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -59,5 +59,5 @@
  *  @see IS_NET_TCP_MESSAGE()
  */
-extern int tcp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
+extern int tcp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
 
 #endif
Index: uspace/srv/net/tl/udp/udp.c
===================================================================
--- uspace/srv/net/tl/udp/udp.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/tl/udp/udp.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -48,4 +48,5 @@
 #include <adt/dynamic_fifo.h>
 #include <packet/packet_client.h>
+#include <packet_remote.h>
 #include <net_checksum.h>
 #include <in.h>
@@ -63,4 +64,6 @@
 #include <socket_messages.h>
 #include <tl_common.h>
+#include <tl_local.h>
+#include <tl_interface.h>
 #include <tl_messages.h>
 
@@ -258,5 +261,5 @@
 	icmp_type_t type;
 	icmp_code_t code;
-	ip_pseudo_header_ref ip_header;
+	void *ip_header;
 	struct sockaddr * src;
 	struct sockaddr * dest;
@@ -356,5 +359,5 @@
 			while(tmp_packet){
 				next_packet = pq_detach(tmp_packet);
-				pq_release(udp_globals.net_phone, packet_get_id(tmp_packet));
+				pq_release_remote(udp_globals.net_phone, packet_get_id(tmp_packet));
 				tmp_packet = next_packet;
 			}
@@ -382,5 +385,5 @@
 	// queue the received packet
 	if(ERROR_OCCURRED(dyn_fifo_push(&socket->received, packet_get_id(packet), SOCKET_MAX_RECEIVED_SIZE))
-		|| ERROR_OCCURRED(tl_get_ip_packet_dimension(udp_globals.ip_phone, &udp_globals.dimensions, device_id, &packet_dimension))){
+	    || ERROR_OCCURRED(tl_get_ip_packet_dimension(udp_globals.ip_phone, &udp_globals.dimensions, device_id, &packet_dimension))){
 		return udp_release_and_return(packet, ERROR_CODE);
 	}
@@ -392,5 +395,5 @@
 }
 
-int udp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
+int udp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
 	ERROR_DECLARE;
 
@@ -400,5 +403,5 @@
 	switch(IPC_GET_METHOD(*call)){
 		case NET_TL_RECEIVED:
-			if(! ERROR_OCCURRED(packet_translate(udp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
+			if(! ERROR_OCCURRED(packet_translate_remote(udp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
 				ERROR_CODE = udp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_UDP, IPC_GET_ERROR(call));
 			}
@@ -457,5 +460,5 @@
 
 				if(res == EOK){
-					if(tl_get_ip_packet_dimension(udp_globals.ip_phone, &udp_globals.dimensions, DEVICE_INVALID_ID, &packet_dimension) == EOK){
+					if (tl_get_ip_packet_dimension(udp_globals.ip_phone, &udp_globals.dimensions, DEVICE_INVALID_ID, &packet_dimension) == EOK){
 						SOCKET_SET_DATA_FRAGMENT_SIZE(answer, packet_dimension->content);
 					}
@@ -533,5 +536,5 @@
 	uint16_t dest_port;
 	uint32_t checksum;
-	ip_pseudo_header_ref ip_header;
+	void *ip_header;
 	size_t headerlen;
 	device_id_t device_id;
@@ -662,9 +665,9 @@
 		return NO_DATA;
 	}
-	ERROR_PROPAGATE(packet_translate(udp_globals.net_phone, &packet, packet_id));
+	ERROR_PROPAGATE(packet_translate_remote(udp_globals.net_phone, &packet, packet_id));
 	// get udp header
 	data = packet_get_data(packet);
 	if(! data){
-		pq_release(udp_globals.net_phone, packet_id);
+		pq_release_remote(udp_globals.net_phone, packet_id);
 		return NO_DATA;
 	}
@@ -674,5 +677,5 @@
 	result = packet_get_addr(packet, (uint8_t **) &addr, NULL);
 	if(ERROR_OCCURRED(tl_set_address_port(addr, result, ntohs(header->source_port)))){
-		pq_release(udp_globals.net_phone, packet_id);
+		pq_release_remote(udp_globals.net_phone, packet_id);
 		return ERROR_CODE;
 	}
@@ -689,5 +692,5 @@
 	// release the packet
 	dyn_fifo_pop(&socket->received);
-	pq_release(udp_globals.net_phone, packet_get_id(packet));
+	pq_release_remote(udp_globals.net_phone, packet_get_id(packet));
 	// return the total length
 	return (int) length;
@@ -695,11 +698,7 @@
 
 int udp_release_and_return(packet_t packet, int result){
-	pq_release(udp_globals.net_phone, packet_get_id(packet));
+	pq_release_remote(udp_globals.net_phone, packet_get_id(packet));
 	return result;
 }
-
-#ifdef CONFIG_NETWORKING_modular
-
-#include <tl_standalone.h>
 
 /** Default thread for new connections.
@@ -729,5 +728,6 @@
 		
 		/* Process the message */
-		int res = tl_module_message(callid, &call, &answer, &answer_count);
+		int res = tl_module_message_standalone(callid, &call, &answer,
+		    &answer_count);
 		
 		/* End if said to either by the message or the processing result */
@@ -753,18 +753,11 @@
 	ERROR_DECLARE;
 	
-	/* Print the module label */
-	printf("Task %d - %s\n", task_get_id(), NAME);
-	
 	/* Start the module */
-	if (ERROR_OCCURRED(tl_module_start(tl_client_connection))) {
-		printf(" - ERROR %i\n", ERROR_CODE);
+	if (ERROR_OCCURRED(tl_module_start_standalone(tl_client_connection)))
 		return ERROR_CODE;
-	}
 	
 	return EOK;
 }
 
-#endif /* CONFIG_NETWORKING_modular */
-
 /** @}
  */
Index: uspace/srv/net/tl/udp/udp_module.c
===================================================================
--- uspace/srv/net/tl/udp/udp_module.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/tl/udp/udp_module.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -47,5 +47,5 @@
 #include <packet/packet.h>
 #include <net_interface.h>
-#include <tl_standalone.h>
+#include <tl_local.h>
 
 #include "udp.h"
@@ -63,5 +63,5 @@
  *  @returns Other error codes as defined for the REGISTER_ME() macro function.
  */
-int tl_module_start(async_client_conn_t client_connection){
+int tl_module_start_standalone(async_client_conn_t client_connection){
 	ERROR_DECLARE;
 
@@ -94,6 +94,6 @@
  *  @returns Other error codes as defined for the udp_message() function.
  */
-int tl_module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
-	return udp_message(callid, call, answer, answer_count);
+int tl_module_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
+	return udp_message_standalone(callid, call, answer, answer_count);
 }
 
Index: uspace/srv/net/tl/udp/udp_module.h
===================================================================
--- uspace/srv/net/tl/udp/udp_module.h	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/net/tl/udp/udp_module.h	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -59,5 +59,5 @@
  *  @see IS_NET_UDP_MESSAGE()
  */
-extern int udp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
+extern int udp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
 
 #endif
Index: uspace/srv/ns/ns.c
===================================================================
--- uspace/srv/ns/ns.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/ns/ns.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -55,8 +55,8 @@
 static void *klogaddr = NULL;
 
-static void get_as_area(ipc_callid_t callid, ipc_call_t *call, void *ph_addr,
+static void get_as_area(ipc_callid_t callid, ipc_call_t *call, void *faddr,
     size_t pages, void **addr)
 {
-	if (ph_addr == NULL) {
+	if ((faddr == NULL) || (pages == 0)) {
 		ipc_answer_0(callid, ENOENT);
 		return;
@@ -71,5 +71,5 @@
 		}
 		
-		if (physmem_map(ph_addr, *addr, pages,
+		if (physmem_map(faddr, *addr, pages,
 		    AS_AREA_READ | AS_AREA_CACHEABLE) != 0) {
 			ipc_answer_0(callid, ENOENT);
@@ -81,4 +81,32 @@
 }
 
+static void setup_clock_area(ipc_callid_t callid, ipc_call_t *call, void **addr)
+{
+	uintptr_t faddr;
+	int err = sysinfo_get_value("clock.faddr", &faddr);
+	
+	if (err != EOK)
+		ipc_answer_0(callid, err);
+	
+	get_as_area(callid, call, (void *) faddr, 1, addr);
+}
+
+static void setup_klog_area(ipc_callid_t callid, ipc_call_t *call, void **addr)
+{
+	uintptr_t faddr;
+	int err = sysinfo_get_value("klog.faddr", &faddr);
+	
+	if (err != EOK)
+		ipc_answer_0(callid, err);
+	
+	size_t pages;
+	err = sysinfo_get_value("klog.pages", &pages);
+	
+	if (err != EOK)
+		ipc_answer_0(callid, err);
+	
+	get_as_area(callid, call, (void *) faddr, pages, addr);
+}
+
 int main(int argc, char **argv)
 {
@@ -97,5 +125,5 @@
 		return rc;
 	
-	printf(NAME ": Accepting connections\n");
+	printf("%s: Accepting connections\n", NAME);
 	
 	while (true) {
@@ -113,12 +141,8 @@
 			switch (IPC_GET_ARG3(call)) {
 			case SERVICE_MEM_REALTIME:
-				get_as_area(callid, &call,
-				    (void *) sysinfo_value("clock.faddr"),
-				    1, &clockaddr);
+				setup_clock_area(callid, &call, &clockaddr);
 				break;
 			case SERVICE_MEM_KLOG:
-				get_as_area(callid, &call,
-				    (void *) sysinfo_value("klog.faddr"),
-				    sysinfo_value("klog.pages"), &klogaddr);
+				setup_klog_area(callid, &call, &klogaddr);
 				break;
 			default:
Index: uspace/srv/taskmon/taskmon.c
===================================================================
--- uspace/srv/taskmon/taskmon.c	(revision 38aaacc20a85af2361a0240ac2e7d643e086ecfa)
+++ uspace/srv/taskmon/taskmon.c	(revision f4f866c362e11c16ac8b6212e491af00b0bed2f2)
@@ -44,4 +44,5 @@
 #include <macros.h>
 #include <errno.h>
+#include <str_error.h>
 
 #define NAME  "taskmon"
@@ -96,7 +97,9 @@
 	}
 	putchar('\n');
-
-	if (!task_spawn(fname, argv))
-		printf(NAME ": Error spawning taskdump.\n", fname);
+	
+	int err;
+	if (!task_spawn(fname, argv, &err))
+		printf("%s: Error spawning %s (%s).\n", NAME, fname,
+		    str_error(err));
 }
 
