Index: .bzrignore
===================================================================
--- .bzrignore	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
+++ .bzrignore	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -0,0 +1,150 @@
+Makefile.depend
+Makefile.depend.prev
+*.map
+*.disasm
+Makefile.common
+Makefile.config
+autotool/
+common.h
+common.h.prev
+config.h
+image.iso
+cscope.out
+boot/distroot/
+boot/initrd.fs
+boot/initrd.img
+kernel/kernel.bin
+kernel/kernel.dump
+kernel/kernel.map.prev
+kernel/kernel.raw
+kernel/arch/amd64/_link.ld
+kernel/arch/amd64/include/common.h
+kernel/arch/ia32/_link.ld
+kernel/generic/include/arch
+kernel/generic/include/genarch
+kernel/generic/src/debug/real_map.bin
+uspace/app/bdsh/bdsh
+uspace/app/edit/edit
+uspace/app/getterm/getterm
+uspace/app/init/init
+uspace/app/klog/klog
+uspace/app/mkfat/mkfat
+uspace/app/netecho/netecho
+uspace/app/nettest1/nettest1
+uspace/app/nettest2/nettest2
+uspace/app/ping/ping
+uspace/app/redir/redir
+uspace/app/sbi/sbi
+uspace/app/stats/stats
+uspace/app/taskdump/taskdump
+uspace/app/tasks/tasks
+uspace/app/test_serial/test_serial
+uspace/app/tester/tester
+uspace/app/tetris/tetris
+uspace/app/top/top
+uspace/app/trace/trace
+uspace/dist/app/bdsh
+uspace/dist/app/edit
+uspace/dist/app/getterm
+uspace/dist/app/klog
+uspace/dist/app/mkfat
+uspace/dist/app/netecho
+uspace/dist/app/nettest1
+uspace/dist/app/nettest2
+uspace/dist/app/ping
+uspace/dist/app/redir
+uspace/dist/app/sbi
+uspace/dist/app/stats
+uspace/dist/app/taskdump
+uspace/dist/app/tasks
+uspace/dist/app/test_serial
+uspace/dist/app/tester
+uspace/dist/app/tetris
+uspace/dist/app/top
+uspace/dist/app/trace
+uspace/dist/cfg/net/general
+uspace/dist/cfg/net/lo
+uspace/dist/cfg/net/ne2k
+uspace/dist/drv/isa/
+uspace/dist/drv/ns8250/
+uspace/dist/drv/pciintel/
+uspace/dist/drv/root/
+uspace/dist/drv/rootia32/
+uspace/dist/srv/arp
+uspace/dist/srv/ata_bd
+uspace/dist/srv/char_ms
+uspace/dist/srv/clip
+uspace/dist/srv/console
+uspace/dist/srv/devfs
+uspace/dist/srv/devman
+uspace/dist/srv/dp8390
+uspace/dist/srv/eth
+uspace/dist/srv/ext2
+uspace/dist/srv/fat
+uspace/dist/srv/fb
+uspace/dist/srv/file_bd
+uspace/dist/srv/g_part
+uspace/dist/srv/i8042
+uspace/dist/srv/icmp
+uspace/dist/srv/ip
+uspace/dist/srv/kbd
+uspace/dist/srv/lo
+uspace/dist/srv/mbr_part
+uspace/dist/srv/net
+uspace/dist/srv/nildummy
+uspace/dist/srv/pipefs
+uspace/dist/srv/taskmon
+uspace/dist/srv/tcp
+uspace/dist/srv/tmpfs
+uspace/dist/srv/udp
+uspace/drv/root/root
+uspace/drv/isa/isa
+uspace/drv/ns8250/ns8250
+uspace/drv/pciintel/pciintel
+uspace/drv/rootia32/rootia32
+uspace/lib/c/arch/amd64/_link.ld
+uspace/lib/c/arch/amd64/include/common.h
+uspace/lib/c/arch/ia32/_link.ld
+uspace/lib/c/include/arch
+uspace/lib/c/include/kernel
+uspace/lib/c/include/libarch
+uspace/srv/bd/ata_bd/ata_bd
+uspace/srv/bd/file_bd/file_bd
+uspace/srv/bd/gxe_bd/gxe_bd
+uspace/srv/bd/part/guid_part/g_part
+uspace/srv/bd/part/mbr_part/mbr_part
+uspace/srv/bd/rd/rd
+uspace/srv/clip/clip
+uspace/srv/devman/devman
+uspace/srv/devmap/devmap
+uspace/srv/fs/devfs/devfs
+uspace/srv/fs/ext2/ext2
+uspace/srv/fs/fat/fat
+uspace/srv/fs/tmpfs/tmpfs
+uspace/srv/fs/pipefs/pipefs
+uspace/srv/hid/adb_mouse/adb_ms
+uspace/srv/hid/char_mouse/char_ms
+uspace/srv/hid/console/console
+uspace/srv/hid/fb/fb
+uspace/srv/hid/kbd/kbd
+uspace/srv/hid/s3c24xx_ts/s3c24ts
+uspace/srv/hw/char/i8042/i8042
+uspace/srv/hw/char/s3c24xx_uart/s3c24ser
+uspace/srv/hw/netif/dp8390/dp8390
+uspace/srv/loader/loader
+uspace/srv/loader/arch/amd64/_link.ld
+uspace/srv/loader/arch/ia32/_link.ld
+uspace/srv/net/cfg/lo
+uspace/srv/net/cfg/ne2k
+uspace/srv/net/il/arp/arp
+uspace/srv/net/il/ip/ip
+uspace/srv/net/net/net
+uspace/srv/net/netif/lo/lo
+uspace/srv/net/nil/eth/eth
+uspace/srv/net/nil/nildummy/nildummy
+uspace/srv/net/tl/icmp/icmp
+uspace/srv/net/tl/tcp/tcp
+uspace/srv/net/tl/udp/udp
+uspace/srv/ns/ns
+uspace/srv/taskmon/taskmon
+uspace/srv/vfs/vfs
Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision 0b378820b4861f67ea1335ef6260a5c98a59c64c)
+++ boot/Makefile.common	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -97,4 +97,6 @@
 	$(USPACE_PATH)/srv/fs/tmpfs/tmpfs \
 	$(USPACE_PATH)/srv/fs/fat/fat \
+	$(USPACE_PATH)/srv/fs/pipefs/pipefs \
+	$(USPACE_PATH)/srv/fs/ext2/ext2 \
 	$(USPACE_PATH)/srv/taskmon/taskmon \
 	$(USPACE_PATH)/srv/hw/netif/ne2000/ne2000 \
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 0b378820b4861f67ea1335ef6260a5c98a59c64c)
+++ uspace/Makefile	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -72,4 +72,6 @@
 	srv/fs/tmpfs \
 	srv/fs/devfs \
+	srv/fs/pipefs \
+	srv/fs/ext2 \
 	srv/hid/adb_mouse \
 	srv/hid/char_mouse \
@@ -148,5 +150,6 @@
 	lib/drv \
 	lib/packet \
-	lib/net
+	lib/net \
+	lib/ext2
 
 LIBC_BUILD = $(addsuffix .build,$(LIBC))
Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision 0b378820b4861f67ea1335ef6260a5c98a59c64c)
+++ uspace/Makefile.common	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -86,4 +86,6 @@
 LIBCLUI_PREFIX = $(LIB_PREFIX)/clui
 
+LIBEXT2_PREFIX = $(LIB_PREFIX)/ext2
+
 LIBDRV_PREFIX = $(LIB_PREFIX)/drv
 LIBPACKET_PREFIX = $(LIB_PREFIX)/packet
Index: uspace/app/bdsh/cmds/modules/mount/mount.c
===================================================================
--- uspace/app/bdsh/cmds/modules/mount/mount.c	(revision 0b378820b4861f67ea1335ef6260a5c98a59c64c)
+++ uspace/app/bdsh/cmds/modules/mount/mount.c	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -44,5 +44,5 @@
 {
 	static char helpfmt[] =
-	    "Usage:  %s <fstype> <mp> <dev> [<moptions>]\n";
+	    "Usage:  %s <fstype> <mp> [dev] [<moptions>]\n";
 	if (level == HELP_SHORT) {
 		printf("'%s' mounts a file system.\n", cmdname);
@@ -59,17 +59,20 @@
 	unsigned int argc;
 	const char *mopts = "";
+	const char *dev = "";
 	int rc;
 
 	argc = cli_count_args(argv);
 
-	if ((argc < 4) || (argc > 5)) {
+	if ((argc < 3) || (argc > 5)) {
 		printf("%s: invalid number of arguments.\n",
 		    cmdname);
 		return CMD_FAILURE;
 	}
+	if (argc > 3)
+		dev = argv[3];
 	if (argc == 5)
 		mopts = argv[4];
 
-	rc = mount(argv[1], argv[2], argv[3], mopts, 0);
+	rc = mount(argv[1], argv[2], dev, mopts, 0);
 	if (rc != EOK) {
 		printf("Unable to mount %s filesystem to %s on %s (rc=%d)\n",
Index: uspace/app/redir/redir.c
===================================================================
--- uspace/app/redir/redir.c	(revision 0b378820b4861f67ea1335ef6260a5c98a59c64c)
+++ uspace/app/redir/redir.c	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -49,5 +49,5 @@
 static void usage(void)
 {
-	printf("Usage: %s [-i <stdin>] [-o <stdout>] [-e <stderr>] -- <cmd> [args ...]\n",
+	fprintf(stderr, "Usage: %s [-i <stdin>] [-o <stdout>] [-e <stderr>] -- <cmd> [args ...]\n",
 	    NAME);
 }
@@ -83,5 +83,5 @@
 	args = (const char **) calloc(argc + 1, sizeof(char *));
 	if (!args) {
-		printf("No memory available\n");
+		fprintf(stderr, "No memory available\n");
 		return 0;
 	}
@@ -98,6 +98,7 @@
 	
 	if (rc != EOK) {
-		printf("%s: Error spawning %s (%s)\n", NAME, argv[0],
+		fprintf(stderr, "%s: Error spawning %s (%s)\n", NAME, argv[0],
 		    str_error(rc));
+		return 0;
 	}
 	
Index: uspace/lib/ext2/Makefile
===================================================================
--- uspace/lib/ext2/Makefile	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
+++ uspace/lib/ext2/Makefile	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
+# Copyright (c) 2010 Martin Sucha
+# 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 = ../..
+LIBRARY = libext2
+
+SOURCES = \
+	libext2.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/ext2/libext2.c
===================================================================
--- uspace/lib/ext2/libext2.c	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
+++ uspace/lib/ext2/libext2.c	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010 Martin Sucha
+ * 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 libext2
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include "libext2.h"
+#include <macros.h>
+#include <errno.h>
+
+/** @}
+ */
Index: uspace/lib/ext2/libext2.h
===================================================================
--- uspace/lib/ext2/libext2.h	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
+++ uspace/lib/ext2/libext2.h	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 Martin Sucha
+ * 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 libext2
+ * @{
+ */
+/**
+ * @file
+ */
+
+#ifndef LIBEXT2_LIBEXT2_H_
+#define LIBEXT2_LIBEXT2_H_
+
+
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/fs/ext2/Makefile
===================================================================
--- uspace/srv/fs/ext2/Makefile	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
+++ uspace/srv/fs/ext2/Makefile	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
+# Copyright (c) 2010 Martin Sucha
+# 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 = ../../..
+LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBFS_PREFIX)/libfs.a $(LIBEXT2_PREFIX)/libext2.a
+EXTRA_CFLAGS += -I$(LIBBLOCK_PREFIX) -I$(LIBFS_PREFIX) -I$(LIBEXT2_PREFIX)
+BINARY = ext2
+
+SOURCES = \
+	ext2.c \
+	ext2_ops.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/fs/ext2/ext2.c
===================================================================
--- uspace/srv/fs/ext2/ext2.c	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
+++ uspace/srv/fs/ext2/ext2.c	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2006 Martin Decky
+ * Copyright (c) 2008 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup fs
+ * @{
+ */ 
+
+/**
+ * @file	ext2.c
+ * @brief	EXT2 file system driver for HelenOS.
+ */
+
+#include "ext2.h"
+#include <ipc/services.h>
+#include <ipc/ns.h>
+#include <async.h>
+#include <errno.h>
+#include <unistd.h>
+#include <task.h>
+#include <stdio.h>
+#include <libfs.h>
+#include "../../vfs/vfs.h"
+
+#define NAME	"ext2"
+
+vfs_info_t ext2_vfs_info = {
+	.name = NAME,
+};
+
+fs_reg_t ext2_reg;
+
+/**
+ * This connection fibril processes VFS requests from VFS.
+ *
+ * In order to support simultaneous VFS requests, our design is as follows.
+ * The connection fibril accepts VFS requests from VFS. If there is only one
+ * instance of the fibril, VFS will need to serialize all VFS requests it sends
+ * to EXT2. To overcome this bottleneck, VFS can send EXT2 the IPC_M_CONNECT_ME_TO
+ * call. In that case, a new connection fibril will be created, which in turn
+ * will accept the call. Thus, a new phone will be opened for VFS.
+ *
+ * There are few issues with this arrangement. First, VFS can run out of
+ * available phones. In that case, VFS can close some other phones or use one
+ * phone for more serialized requests. Similarily, EXT2 can refuse to duplicate
+ * the connection. VFS should then just make use of already existing phones and
+ * route its requests through them. To avoid paying the fibril creation price 
+ * upon each request, EXT2 might want to keep the connections open after the
+ * request has been completed.
+ */
+static void ext2_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	if (iid) {
+		/*
+		 * This only happens for connections opened by
+		 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections
+		 * created by IPC_M_CONNECT_TO_ME.
+		 */
+		async_answer_0(iid, EOK);
+	}
+	
+	dprintf(NAME ": connection opened\n");
+	while (1) {
+		ipc_callid_t callid;
+		ipc_call_t call;
+	
+		callid = async_get_call(&call);
+		switch  (IPC_GET_IMETHOD(call)) {
+		case IPC_M_PHONE_HUNGUP:
+			return;
+		case VFS_OUT_MOUNTED:
+			ext2_mounted(callid, &call);
+			break;
+		case VFS_OUT_MOUNT:
+			ext2_mount(callid, &call);
+			break;
+		case VFS_OUT_UNMOUNTED:
+			ext2_unmounted(callid, &call);
+			break;
+		case VFS_OUT_UNMOUNT:
+			ext2_unmount(callid, &call);
+			break;
+		case VFS_OUT_LOOKUP:
+			ext2_lookup(callid, &call);
+			break;
+		case VFS_OUT_READ:
+			ext2_read(callid, &call);
+			break;
+		case VFS_OUT_WRITE:
+			ext2_write(callid, &call);
+			break;
+		case VFS_OUT_TRUNCATE:
+			ext2_truncate(callid, &call);
+			break;
+		case VFS_OUT_STAT:
+			ext2_stat(callid, &call);
+			break;
+		case VFS_OUT_CLOSE:
+			ext2_close(callid, &call);
+			break;
+		case VFS_OUT_DESTROY:
+			ext2_destroy(callid, &call);
+			break;
+		case VFS_OUT_OPEN_NODE:
+			ext2_open_node(callid, &call);
+			break;
+		case VFS_OUT_SYNC:
+			ext2_sync(callid, &call);
+			break;
+		default:
+			async_answer_0(callid, ENOTSUP);
+			break;
+		}
+	}
+}
+
+int main(int argc, char **argv)
+{
+	int vfs_phone;
+	int rc;
+
+	printf(NAME ": HelenOS EXT2 file system server\n");
+
+	vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
+	if (vfs_phone < EOK) {
+		printf(NAME ": failed to connect to VFS\n");
+		return -1;
+	}
+	
+	rc = fs_register(vfs_phone, &ext2_reg, &ext2_vfs_info, ext2_connection);
+	
+	printf(NAME ": Accepting connections\n");
+	task_retval(0);
+	async_manager();
+	/* not reached */
+	return 0;
+}
+
+/**
+ * @}
+ */ 
Index: uspace/srv/fs/ext2/ext2.h
===================================================================
--- uspace/srv/fs/ext2/ext2.h	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
+++ uspace/srv/fs/ext2/ext2.h	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2008 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup fs
+ * @{
+ */ 
+
+#ifndef EXT2_EXT2_H_
+#define EXT2_EXT2_H_
+
+#include <libext2.h>
+#include <fibril_synch.h>
+#include <libfs.h>
+#include <atomic.h>
+#include <sys/types.h>
+#include <bool.h>
+#include "../../vfs/vfs.h"
+
+#ifndef dprintf
+#define dprintf(...)	printf(__VA_ARGS__)
+#endif
+
+#define min(a, b)		((a) < (b) ? (a) : (b))
+
+extern fs_reg_t ext2_reg;
+
+extern void ext2_mounted(ipc_callid_t, ipc_call_t *);
+extern void ext2_mount(ipc_callid_t, ipc_call_t *);
+extern void ext2_unmounted(ipc_callid_t, ipc_call_t *);
+extern void ext2_unmount(ipc_callid_t, ipc_call_t *);
+extern void ext2_lookup(ipc_callid_t, ipc_call_t *);
+extern void ext2_read(ipc_callid_t, ipc_call_t *);
+extern void ext2_write(ipc_callid_t, ipc_call_t *);
+extern void ext2_truncate(ipc_callid_t, ipc_call_t *);
+extern void ext2_stat(ipc_callid_t, ipc_call_t *);
+extern void ext2_close(ipc_callid_t, ipc_call_t *);
+extern void ext2_destroy(ipc_callid_t, ipc_call_t *);
+extern void ext2_open_node(ipc_callid_t, ipc_call_t *);
+extern void ext2_stat(ipc_callid_t, ipc_call_t *);
+extern void ext2_sync(ipc_callid_t, ipc_call_t *);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/fs/ext2/ext2_ops.c
===================================================================
--- uspace/srv/fs/ext2/ext2_ops.c	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
+++ uspace/srv/fs/ext2/ext2_ops.c	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2008 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup fs
+ * @{
+ */ 
+
+/**
+ * @file	ext2_ops.c
+ * @brief	Implementation of VFS operations for the EXT2 file system server.
+ */
+
+#include "ext2.h"
+#include "../../vfs/vfs.h"
+#include <libfs.h>
+#include <libblock.h>
+#include <libext2.h>
+#include <ipc/services.h>
+#include <ipc/devmap.h>
+#include <macros.h>
+#include <async.h>
+#include <errno.h>
+#include <str.h>
+#include <byteorder.h>
+#include <adt/hash_table.h>
+#include <adt/list.h>
+#include <assert.h>
+#include <fibril_synch.h>
+#include <sys/mman.h>
+#include <align.h>
+
+#define EXT2_NODE(node)	((node) ? (ext2_node_t *) (node)->data : NULL)
+#define FS_NODE(node)	((node) ? (node)->bp : NULL)
+
+/*
+ * Forward declarations of EXT2 libfs operations.
+ */
+static int ext2_root_get(fs_node_t **, devmap_handle_t);
+static int ext2_match(fs_node_t **, fs_node_t *, const char *);
+static int ext2_node_get(fs_node_t **, devmap_handle_t, fs_index_t);
+static int ext2_node_open(fs_node_t *);
+static int ext2_node_put(fs_node_t *);
+static int ext2_create_node(fs_node_t **, devmap_handle_t, int);
+static int ext2_destroy_node(fs_node_t *);
+static int ext2_link(fs_node_t *, fs_node_t *, const char *);
+static int ext2_unlink(fs_node_t *, fs_node_t *, const char *);
+static int ext2_has_children(bool *, fs_node_t *);
+static fs_index_t ext2_index_get(fs_node_t *);
+static aoff64_t ext2_size_get(fs_node_t *);
+static unsigned ext2_lnkcnt_get(fs_node_t *);
+static char ext2_plb_get_char(unsigned);
+static bool ext2_is_directory(fs_node_t *);
+static bool ext2_is_file(fs_node_t *node);
+static devmap_handle_t ext2_device_get(fs_node_t *node);
+
+/*
+ * EXT2 libfs operations.
+ */
+
+int ext2_root_get(fs_node_t **rfn, devmap_handle_t devmap_handle)
+{
+	// TODO
+	return 0;
+	//return ext2_node_get(rfn, devmap_handle, 0);
+}
+
+int ext2_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
+{
+	// TODO
+	return ENOTSUP;
+}
+
+/** Instantiate a EXT2 in-core node. */
+int ext2_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle, fs_index_t index)
+{
+	// TODO
+	return ENOTSUP;
+}
+
+int ext2_node_open(fs_node_t *fn)
+{
+	/*
+	 * Opening a file is stateless, nothing
+	 * to be done here.
+	 */
+	return EOK;
+}
+
+int ext2_node_put(fs_node_t *fn)
+{
+	// TODO
+	return ENOTSUP;
+}
+
+int ext2_create_node(fs_node_t **rfn, devmap_handle_t devmap_handle, int flags)
+{
+	// TODO
+	return ENOTSUP;
+}
+
+int ext2_destroy_node(fs_node_t *fn)
+{
+	// TODO
+	return ENOTSUP;
+}
+
+int ext2_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)
+{
+	// TODO
+	return ENOTSUP;
+}
+
+int ext2_unlink(fs_node_t *pfn, fs_node_t *cfn, const char *nm)
+{
+	// TODO
+	return ENOTSUP;
+}
+
+int ext2_has_children(bool *has_children, fs_node_t *fn)
+{
+	// TODO
+	return ENOTSUP;
+}
+
+
+fs_index_t ext2_index_get(fs_node_t *fn)
+{
+	// TODO
+	return 0;
+}
+
+aoff64_t ext2_size_get(fs_node_t *fn)
+{
+	// TODO
+	return 0;
+}
+
+unsigned ext2_lnkcnt_get(fs_node_t *fn)
+{
+	// TODO
+	return 0;
+}
+
+char ext2_plb_get_char(unsigned pos)
+{
+	return ext2_reg.plb_ro[pos % PLB_SIZE];
+}
+
+bool ext2_is_directory(fs_node_t *fn)
+{
+	// TODO
+	return false;
+}
+
+bool ext2_is_file(fs_node_t *fn)
+{
+	// TODO
+	return false;
+}
+
+devmap_handle_t ext2_device_get(fs_node_t *node)
+{
+	return 0;
+}
+
+/** libfs operations */
+libfs_ops_t ext2_libfs_ops = {
+	.root_get = ext2_root_get,
+	.match = ext2_match,
+	.node_get = ext2_node_get,
+	.node_open = ext2_node_open,
+	.node_put = ext2_node_put,
+	.create = ext2_create_node,
+	.destroy = ext2_destroy_node,
+	.link = ext2_link,
+	.unlink = ext2_unlink,
+	.has_children = ext2_has_children,
+	.index_get = ext2_index_get,
+	.size_get = ext2_size_get,
+	.lnkcnt_get = ext2_lnkcnt_get,
+	.plb_get_char = ext2_plb_get_char,
+	.is_directory = ext2_is_directory,
+	.is_file = ext2_is_file,
+	.device_get = ext2_device_get
+};
+
+/*
+ * VFS operations.
+ */
+
+void ext2_mounted(ipc_callid_t rid, ipc_call_t *request)
+{
+//	devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
+	// TODO
+	async_answer_0(rid, ENOTSUP);
+}
+
+void ext2_mount(ipc_callid_t rid, ipc_call_t *request)
+{
+	libfs_mount(&ext2_libfs_ops, ext2_reg.fs_handle, rid, request);
+}
+
+void ext2_unmounted(ipc_callid_t rid, ipc_call_t *request)
+{
+//	devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
+	// TODO
+	async_answer_0(rid, ENOTSUP);
+}
+
+void ext2_unmount(ipc_callid_t rid, ipc_call_t *request)
+{
+	libfs_unmount(&ext2_libfs_ops, rid, request);
+}
+
+void ext2_lookup(ipc_callid_t rid, ipc_call_t *request)
+{
+	libfs_lookup(&ext2_libfs_ops, ext2_reg.fs_handle, rid, request);
+}
+
+void ext2_read(ipc_callid_t rid, ipc_call_t *request)
+{
+//	devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
+//	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
+//	aoff64_t pos =
+//	    (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
+	
+	// TODO
+	async_answer_0(rid, ENOTSUP);
+}
+
+void ext2_write(ipc_callid_t rid, ipc_call_t *request)
+{
+//	devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
+//	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
+//	aoff64_t pos =
+//	    (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
+	
+	// TODO
+	async_answer_0(rid, ENOTSUP);
+}
+
+void ext2_truncate(ipc_callid_t rid, ipc_call_t *request)
+{
+//	devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
+//	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
+//	aoff64_t size =
+//	    (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
+	
+	// TODO
+	async_answer_0(rid, ENOTSUP);
+}
+
+void ext2_close(ipc_callid_t rid, ipc_call_t *request)
+{
+	async_answer_0(rid, EOK);
+}
+
+void ext2_destroy(ipc_callid_t rid, ipc_call_t *request)
+{
+//	devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request);
+//	fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
+	
+	// TODO
+	async_answer_0(rid, ENOTSUP);
+}
+
+void ext2_open_node(ipc_callid_t rid, ipc_call_t *request)
+{
+	libfs_open_node(&ext2_libfs_ops, ext2_reg.fs_handle, rid, request);
+}
+
+void ext2_stat(ipc_callid_t rid, ipc_call_t *request)
+{
+	libfs_stat(&ext2_libfs_ops, ext2_reg.fs_handle, rid, request);
+}
+
+void ext2_sync(ipc_callid_t rid, ipc_call_t *request)
+{
+//	devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
+//	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
+	
+	// TODO
+	async_answer_0(rid, ENOTSUP);
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/fs/pipefs/Makefile
===================================================================
--- uspace/srv/fs/pipefs/Makefile	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
+++ uspace/srv/fs/pipefs/Makefile	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -0,0 +1,39 @@
+#
+# 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 = ../../..
+LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBFS_PREFIX)/libfs.a
+EXTRA_CFLAGS += -I$(LIBBLOCK_PREFIX) -I$(LIBFS_PREFIX)
+BINARY = pipefs
+
+SOURCES = \
+	pipefs.c \
+	pipefs_ops.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/fs/pipefs/pipefs.c
===================================================================
--- uspace/srv/fs/pipefs/pipefs.c	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
+++ uspace/srv/fs/pipefs/pipefs.c	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2006 Martin Decky
+ * Copyright (c) 2008 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup fs
+ * @{
+ */ 
+
+/**
+ * @file	pipefs.c
+ * @brief	File system driver for in-memory file system.
+ *
+ * Every instance of pipefs exists purely in memory and has neither a disk layout
+ * nor any permanent storage (e.g. disk blocks). With each system reboot, data
+ * stored in a pipefs file system is lost.
+ */
+
+#include "pipefs.h"
+#include <ipc/services.h>
+#include <ipc/ns.h>
+#include <async.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <task.h>
+#include <libfs.h>
+#include "../../vfs/vfs.h"
+
+#define NAME "pipefs"
+
+
+vfs_info_t pipefs_vfs_info = {
+	.name = NAME,
+};
+
+fs_reg_t pipefs_reg;
+
+/**
+ * This connection fibril processes VFS requests from VFS.
+ *
+ * In order to support simultaneous VFS requests, our design is as follows.
+ * The connection fibril accepts VFS requests from VFS. If there is only one
+ * instance of the fibril, VFS will need to serialize all VFS requests it sends
+ * to PIPEFS. To overcome this bottleneck, VFS can send PIPEFS the
+ * IPC_M_CONNECT_ME_TO call. In that case, a new connection fibril will be
+ * created, which in turn will accept the call. Thus, a new phone will be
+ * opened for VFS.
+ *
+ * There are few issues with this arrangement. First, VFS can run out of
+ * available phones. In that case, VFS can close some other phones or use one
+ * phone for more serialized requests. Similarily, PIPEFS can refuse to duplicate
+ * the connection. VFS should then just make use of already existing phones and
+ * route its requests through them. To avoid paying the fibril creation price 
+ * upon each request, PIPEFS might want to keep the connections open after the
+ * request has been completed.
+ */
+static void pipefs_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	if (iid) {
+		/*
+		 * This only happens for connections opened by
+		 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections
+		 * created by IPC_M_CONNECT_TO_ME.
+		 */
+		async_answer_0(iid, EOK);
+	}
+	
+	dprintf(NAME ": connection opened\n");
+	while (1) {
+		ipc_callid_t callid;
+		ipc_call_t call;
+	
+		callid = async_get_call(&call);
+		switch  (IPC_GET_IMETHOD(call)) {
+		case IPC_M_PHONE_HUNGUP:
+			return;
+		case VFS_OUT_MOUNTED:
+			pipefs_mounted(callid, &call);
+			break;
+		case VFS_OUT_MOUNT:
+			pipefs_mount(callid, &call);
+			break;
+		case VFS_OUT_UNMOUNTED:
+			pipefs_unmounted(callid, &call);
+			break;
+		case VFS_OUT_UNMOUNT:
+			pipefs_unmount(callid, &call);
+			break;
+		case VFS_OUT_LOOKUP:
+			pipefs_lookup(callid, &call);
+			break;
+		case VFS_OUT_READ:
+			pipefs_read(callid, &call);
+			break;
+		case VFS_OUT_WRITE:
+			pipefs_write(callid, &call);
+			break;
+		case VFS_OUT_TRUNCATE:
+			pipefs_truncate(callid, &call);
+			break;
+		case VFS_OUT_CLOSE:
+			pipefs_close(callid, &call);
+			break;
+		case VFS_OUT_DESTROY:
+			pipefs_destroy(callid, &call);
+			break;
+		case VFS_OUT_OPEN_NODE:
+			pipefs_open_node(callid, &call);
+			break;
+		case VFS_OUT_STAT:
+			pipefs_stat(callid, &call);
+			break;
+		case VFS_OUT_SYNC:
+			pipefs_sync(callid, &call);
+			break;
+		default:
+			async_answer_0(callid, ENOTSUP);
+			break;
+		}
+	}
+}
+
+int main(int argc, char **argv)
+{
+	printf(NAME ": HelenOS PIPEFS file system server\n");
+
+	if (!pipefs_init()) {
+		printf(NAME ": failed to initialize PIPEFS\n");
+		return -1;
+	}
+
+	int vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
+	if (vfs_phone < EOK) {
+		printf(NAME ": Unable to connect to VFS\n");
+		return -1;
+	}
+
+	int rc = fs_register(vfs_phone, &pipefs_reg, &pipefs_vfs_info,
+	    pipefs_connection);
+	if (rc != EOK) {
+		printf(NAME ": Failed to register file system (%d)\n", rc);
+		return rc;
+	}
+
+	printf(NAME ": Accepting connections\n");
+	task_retval(0);
+	async_manager();
+	/* not reached */
+	return 0;
+}
+
+/**
+ * @}
+ */ 
Index: uspace/srv/fs/pipefs/pipefs.h
===================================================================
--- uspace/srv/fs/pipefs/pipefs.h	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
+++ uspace/srv/fs/pipefs/pipefs.h	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2008 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup fs
+ * @{
+ */
+
+#ifndef PIPEFS_PIPEFS_H_
+#define PIPEFS_PIPEFS_H_
+
+#include <libfs.h>
+#include <atomic.h>
+#include <sys/types.h>
+#include <bool.h>
+#include <adt/hash_table.h>
+
+#define PIPEFS_NODE(node)	((node) ? (pipefs_node_t *)(node)->data : NULL)
+#define FS_NODE(node)		((node) ? (node)->bp : NULL)
+
+typedef enum {
+	PIPEFS_NONE,
+	PIPEFS_FILE,
+	PIPEFS_DIRECTORY
+} pipefs_dentry_type_t;
+
+/* forward declaration */
+struct pipefs_node;
+
+typedef struct pipefs_dentry {
+	link_t link;		/**< Linkage for the list of siblings. */
+	struct pipefs_node *node;/**< Back pointer to PIPEFS node. */
+	char *name;		/**< Name of dentry. */
+} pipefs_dentry_t;
+
+typedef struct pipefs_node {
+	fs_node_t *bp;		/**< Back pointer to the FS node. */
+	fs_index_t index;	/**< PIPEFS node index. */
+	devmap_handle_t devmap_handle;/**< Device handle. */
+	link_t nh_link;		/**< Nodes hash table link. */
+	pipefs_dentry_type_t type;
+	unsigned lnkcnt;	/**< Link count. */
+	/* Following is for nodes of type PIPEFS_FILE */
+	aoff64_t start;		/**< File offset where first data block resides */
+	size_t size;		/**< File size if type is PIPEFS_FILE. */
+	link_t data_head;	/**< Head of data blocks list for PIPEFS_FILE. */
+	/* This is for directory */
+	link_t cs_head;		/**< Head of child's siblings list. */	
+} pipefs_node_t;
+
+typedef struct pipefs_data_block {
+	link_t link;		/**< Linkage for the list of data blocks */
+	size_t size;		/**< Size of this block */
+	void *data;			/**< Data for this block */
+} pipefs_data_block_t;
+
+extern fs_reg_t pipefs_reg;
+
+extern libfs_ops_t pipefs_libfs_ops;
+
+extern bool pipefs_init(void);
+
+extern void pipefs_mounted(ipc_callid_t, ipc_call_t *);
+extern void pipefs_mount(ipc_callid_t, ipc_call_t *);
+extern void pipefs_unmounted(ipc_callid_t, ipc_call_t *);
+extern void pipefs_unmount(ipc_callid_t, ipc_call_t *);
+extern void pipefs_lookup(ipc_callid_t, ipc_call_t *);
+extern void pipefs_read(ipc_callid_t, ipc_call_t *);
+extern void pipefs_write(ipc_callid_t, ipc_call_t *);
+extern void pipefs_truncate(ipc_callid_t, ipc_call_t *);
+extern void pipefs_stat(ipc_callid_t, ipc_call_t *);
+extern void pipefs_close(ipc_callid_t, ipc_call_t *);
+extern void pipefs_destroy(ipc_callid_t, ipc_call_t *);
+extern void pipefs_open_node(ipc_callid_t, ipc_call_t *);
+extern void pipefs_sync(ipc_callid_t, ipc_call_t *);
+
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/fs/pipefs/pipefs_ops.c
===================================================================
--- uspace/srv/fs/pipefs/pipefs_ops.c	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
+++ uspace/srv/fs/pipefs/pipefs_ops.c	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -0,0 +1,787 @@
+/*
+ * Copyright (c) 2008 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup fs
+ * @{
+ */
+
+/**
+ * @file	pipefs_ops.c
+ * @brief	Implementation of VFS operations for the PIPEFS file system
+ *		server.
+ */
+
+#include "pipefs.h"
+#include "../../vfs/vfs.h"
+#include <macros.h>
+#include <stdint.h>
+#include <async.h>
+#include <errno.h>
+#include <atomic.h>
+#include <stdlib.h>
+#include <str.h>
+#include <stdio.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <adt/hash_table.h>
+#include <as.h>
+#include <libfs.h>
+
+#define min(a, b)		((a) < (b) ? (a) : (b))
+#define max(a, b)		((a) > (b) ? (a) : (b))
+
+#define NODES_BUCKETS	256
+
+/** All root nodes have index 0. */
+#define PIPEFS_SOME_ROOT		0
+/** Global counter for assigning node indices. Shared by all instances. */
+fs_index_t pipefs_next_index = 1;
+
+/*
+ * Implementation of the libfs interface.
+ */
+
+/* Forward declarations of static functions. */
+static int pipefs_match(fs_node_t **, fs_node_t *, const char *);
+static int pipefs_node_get(fs_node_t **, devmap_handle_t, fs_index_t);
+static int pipefs_node_open(fs_node_t *);
+static int pipefs_node_put(fs_node_t *);
+static int pipefs_create_node(fs_node_t **, devmap_handle_t, int);
+static int pipefs_destroy_node(fs_node_t *);
+static int pipefs_link_node(fs_node_t *, fs_node_t *, const char *);
+static int pipefs_unlink_node(fs_node_t *, fs_node_t *, const char *);
+
+/* Implementation of helper functions. */
+static int pipefs_root_get(fs_node_t **rfn, devmap_handle_t devmap_handle)
+{
+	return pipefs_node_get(rfn, devmap_handle, PIPEFS_SOME_ROOT); 
+}
+
+static int pipefs_has_children(bool *has_children, fs_node_t *fn)
+{
+	*has_children = !list_empty(&PIPEFS_NODE(fn)->cs_head);
+	return EOK;
+}
+
+static fs_index_t pipefs_index_get(fs_node_t *fn)
+{
+	return PIPEFS_NODE(fn)->index;
+}
+
+static aoff64_t pipefs_size_get(fs_node_t *fn)
+{
+	return PIPEFS_NODE(fn)->size;
+}
+
+static unsigned pipefs_lnkcnt_get(fs_node_t *fn)
+{
+	return PIPEFS_NODE(fn)->lnkcnt;
+}
+
+static char pipefs_plb_get_char(unsigned pos)
+{
+	return pipefs_reg.plb_ro[pos % PLB_SIZE];
+}
+
+static bool pipefs_is_directory(fs_node_t *fn)
+{
+	return PIPEFS_NODE(fn)->type == PIPEFS_DIRECTORY;
+}
+
+static bool pipefs_is_file(fs_node_t *fn)
+{
+	return PIPEFS_NODE(fn)->type == PIPEFS_FILE;
+}
+
+static devmap_handle_t pipefs_device_get(fs_node_t *fn)
+{
+	return 0;
+}
+
+/** libfs operations */
+libfs_ops_t pipefs_libfs_ops = {
+	.root_get = pipefs_root_get,
+	.match = pipefs_match,
+	.node_get = pipefs_node_get,
+	.node_open = pipefs_node_open,
+	.node_put = pipefs_node_put,
+	.create = pipefs_create_node,
+	.destroy = pipefs_destroy_node,
+	.link = pipefs_link_node,
+	.unlink = pipefs_unlink_node,
+	.has_children = pipefs_has_children,
+	.index_get = pipefs_index_get,
+	.size_get = pipefs_size_get,
+	.lnkcnt_get = pipefs_lnkcnt_get,
+	.plb_get_char = pipefs_plb_get_char,
+	.is_directory = pipefs_is_directory,
+	.is_file = pipefs_is_file,
+	.device_get = pipefs_device_get
+};
+
+/** Hash table of all PIPEFS nodes. */
+hash_table_t nodes;
+
+#define NODES_KEY_DEV	0	
+#define NODES_KEY_INDEX	1
+
+/* Implementation of hash table interface for the nodes hash table. */
+static hash_index_t nodes_hash(unsigned long key[])
+{
+	return key[NODES_KEY_INDEX] % NODES_BUCKETS;
+}
+
+static int nodes_compare(unsigned long key[], hash_count_t keys, link_t *item)
+{
+	pipefs_node_t *nodep = hash_table_get_instance(item, pipefs_node_t,
+	    nh_link);
+	
+	switch (keys) {
+	case 1:
+		return (nodep->devmap_handle == key[NODES_KEY_DEV]);
+	case 2:	
+		return ((nodep->devmap_handle == key[NODES_KEY_DEV]) &&
+		    (nodep->index == key[NODES_KEY_INDEX]));
+	default:
+		assert((keys == 1) || (keys == 2));
+	}
+
+	return 0;
+}
+
+static void nodes_remove_callback(link_t *item)
+{
+	pipefs_node_t *nodep = hash_table_get_instance(item, pipefs_node_t,
+	    nh_link);
+
+	while (!list_empty(&nodep->cs_head)) {
+		pipefs_dentry_t *dentryp = list_get_instance(nodep->cs_head.next,
+		    pipefs_dentry_t, link);
+
+		assert(nodep->type == PIPEFS_DIRECTORY);
+		list_remove(&dentryp->link);
+		free(dentryp);
+	}
+
+	while (!list_empty(&nodep->data_head)) {
+		assert(nodep->type == PIPEFS_FILE);
+		
+		pipefs_data_block_t *data_block = list_get_instance(nodep->data_head.next,
+		    pipefs_data_block_t, link);
+		
+		list_remove(&data_block->link);
+		free(data_block->data);
+		free(data_block);
+	}
+	free(nodep->bp);
+	free(nodep);
+}
+
+/** PIPEFS nodes hash table operations. */
+hash_table_operations_t nodes_ops = {
+	.hash = nodes_hash,
+	.compare = nodes_compare,
+	.remove_callback = nodes_remove_callback
+};
+
+static void pipefs_node_initialize(pipefs_node_t *nodep)
+{
+	nodep->bp = NULL;
+	nodep->index = 0;
+	nodep->devmap_handle = 0;
+	nodep->type = PIPEFS_NONE;
+	nodep->lnkcnt = 0;
+	nodep->start = 0;
+	nodep->size = 0;
+	list_initialize(&nodep->data_head);
+	link_initialize(&nodep->nh_link);
+	list_initialize(&nodep->cs_head);
+}
+
+static void pipefs_dentry_initialize(pipefs_dentry_t *dentryp)
+{
+	link_initialize(&dentryp->link);
+	dentryp->name = NULL;
+	dentryp->node = NULL;
+}
+
+bool pipefs_init(void)
+{
+	if (!hash_table_create(&nodes, NODES_BUCKETS, 2, &nodes_ops))
+		return false;
+	
+	return true;
+}
+
+static bool pipefs_instance_init(devmap_handle_t devmap_handle)
+{
+	fs_node_t *rfn;
+	int rc;
+	
+	rc = pipefs_create_node(&rfn, devmap_handle, L_DIRECTORY);
+	if (rc != EOK || !rfn)
+		return false;
+	PIPEFS_NODE(rfn)->lnkcnt = 0;	/* FS root is not linked */
+	return true;
+}
+
+static void pipefs_instance_done(devmap_handle_t devmap_handle)
+{
+	unsigned long key[] = {
+		[NODES_KEY_DEV] = devmap_handle
+	};
+	/*
+	 * Here we are making use of one special feature of our hash table
+	 * implementation, which allows to remove more items based on a partial
+	 * key match. In the following, we are going to remove all nodes
+	 * matching our device handle. The nodes_remove_callback() function will
+	 * take care of resource deallocation.
+	 */
+	hash_table_remove(&nodes, key, 1);
+}
+
+int pipefs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
+{
+	pipefs_node_t *parentp = PIPEFS_NODE(pfn);
+	link_t *lnk;
+
+	for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head;
+	    lnk = lnk->next) {
+		pipefs_dentry_t *dentryp;
+		dentryp = list_get_instance(lnk, pipefs_dentry_t, link);
+		if (!str_cmp(dentryp->name, component)) {
+			*rfn = FS_NODE(dentryp->node);
+			return EOK;
+		}
+	}
+
+	*rfn = NULL;
+	return EOK;
+}
+
+int pipefs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle, fs_index_t index)
+{
+	unsigned long key[] = {
+		[NODES_KEY_DEV] = devmap_handle,
+		[NODES_KEY_INDEX] = index
+	};
+	link_t *lnk = hash_table_find(&nodes, key);
+	if (lnk) {
+		pipefs_node_t *nodep;
+		nodep = hash_table_get_instance(lnk, pipefs_node_t, nh_link);
+		*rfn = FS_NODE(nodep);
+	} else {
+		*rfn = NULL;
+	}
+	return EOK;	
+}
+
+int pipefs_node_open(fs_node_t *fn)
+{
+	/* nothing to do */
+	return EOK;
+}
+
+int pipefs_node_put(fs_node_t *fn)
+{
+	/* nothing to do */
+	return EOK;
+}
+
+int pipefs_create_node(fs_node_t **rfn, devmap_handle_t devmap_handle, int lflag)
+{
+	fs_node_t *rootfn;
+	int rc;
+
+	assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
+
+	pipefs_node_t *nodep = malloc(sizeof(pipefs_node_t));
+	if (!nodep)
+		return ENOMEM;
+	pipefs_node_initialize(nodep);
+	nodep->bp = malloc(sizeof(fs_node_t));
+	if (!nodep->bp) {
+		free(nodep);
+		return ENOMEM;
+	}
+	fs_node_initialize(nodep->bp);
+	nodep->bp->data = nodep;	/* link the FS and PIPEFS nodes */
+
+	rc = pipefs_root_get(&rootfn, devmap_handle);
+	assert(rc == EOK);
+	if (!rootfn)
+		nodep->index = PIPEFS_SOME_ROOT;
+	else
+		nodep->index = pipefs_next_index++;
+	nodep->devmap_handle = devmap_handle;
+	if (lflag & L_DIRECTORY) 
+		nodep->type = PIPEFS_DIRECTORY;
+	else 
+		nodep->type = PIPEFS_FILE;
+
+	/* Insert the new node into the nodes hash table. */
+	unsigned long key[] = {
+		[NODES_KEY_DEV] = nodep->devmap_handle,
+		[NODES_KEY_INDEX] = nodep->index
+	};
+	hash_table_insert(&nodes, key, &nodep->nh_link);
+	*rfn = FS_NODE(nodep);
+	return EOK;
+}
+
+int pipefs_destroy_node(fs_node_t *fn)
+{
+	pipefs_node_t *nodep = PIPEFS_NODE(fn);
+	
+	assert(!nodep->lnkcnt);
+	assert(list_empty(&nodep->cs_head));
+
+	unsigned long key[] = {
+		[NODES_KEY_DEV] = nodep->devmap_handle,
+		[NODES_KEY_INDEX] = nodep->index
+	};
+	hash_table_remove(&nodes, key, 2);
+
+	/*
+	 * The nodes_remove_callback() function takes care of the actual
+	 * resource deallocation.
+	 */
+	return EOK;
+}
+
+int pipefs_link_node(fs_node_t *pfn, fs_node_t *cfn, const char *nm)
+{
+	pipefs_node_t *parentp = PIPEFS_NODE(pfn);
+	pipefs_node_t *childp = PIPEFS_NODE(cfn);
+	pipefs_dentry_t *dentryp;
+	link_t *lnk;
+
+	assert(parentp->type == PIPEFS_DIRECTORY);
+
+	/* Check for duplicit entries. */
+	for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head;
+	    lnk = lnk->next) {
+		dentryp = list_get_instance(lnk, pipefs_dentry_t, link);	
+		if (!str_cmp(dentryp->name, nm))
+			return EEXIST;
+	}
+
+	/* Allocate and initialize the dentry. */
+	dentryp = malloc(sizeof(pipefs_dentry_t));
+	if (!dentryp)
+		return ENOMEM;
+	pipefs_dentry_initialize(dentryp);
+
+	/* Populate and link the new dentry. */
+	size_t size = str_size(nm);
+	dentryp->name = malloc(size + 1);
+	if (!dentryp->name) {
+		free(dentryp);
+		return ENOMEM;
+	}
+	str_cpy(dentryp->name, size + 1, nm);
+	dentryp->node = childp;
+	childp->lnkcnt++;
+	list_append(&dentryp->link, &parentp->cs_head);
+
+	return EOK;
+}
+
+int pipefs_unlink_node(fs_node_t *pfn, fs_node_t *cfn, const char *nm)
+{
+	pipefs_node_t *parentp = PIPEFS_NODE(pfn);
+	pipefs_node_t *childp = NULL;
+	pipefs_dentry_t *dentryp;
+	link_t *lnk;
+
+	if (!parentp)
+		return EBUSY;
+	
+	for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head;
+	    lnk = lnk->next) {
+		dentryp = list_get_instance(lnk, pipefs_dentry_t, link);
+		if (!str_cmp(dentryp->name, nm)) {
+			childp = dentryp->node;
+			assert(FS_NODE(childp) == cfn);
+			break;
+		}	
+	}
+
+	if (!childp)
+		return ENOENT;
+		
+	if ((childp->lnkcnt == 1) && !list_empty(&childp->cs_head))
+		return ENOTEMPTY;
+
+	list_remove(&dentryp->link);
+	free(dentryp);
+	childp->lnkcnt--;
+
+	return EOK;
+}
+
+void pipefs_mounted(ipc_callid_t rid, ipc_call_t *request)
+{
+	devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
+	fs_node_t *rootfn;
+	int rc;
+	
+	/* Accept the mount options. */
+	char *opts;
+	rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
+	if (rc != EOK) {
+		async_answer_0(rid, rc);
+		return;
+	}
+
+	/* Check if this device is not already mounted. */
+	rc = pipefs_root_get(&rootfn, devmap_handle);
+	if ((rc == EOK) && (rootfn)) {
+		(void) pipefs_node_put(rootfn);
+		free(opts);
+		async_answer_0(rid, EEXIST);
+		return;
+	}
+
+	/* Initialize PIPEFS instance. */
+	if (!pipefs_instance_init(devmap_handle)) {
+		free(opts);
+		async_answer_0(rid, ENOMEM);
+		return;
+	}
+
+	rc = pipefs_root_get(&rootfn, devmap_handle);
+	assert(rc == EOK);
+	pipefs_node_t *rootp = PIPEFS_NODE(rootfn);
+	async_answer_3(rid, EOK, rootp->index, rootp->size, rootp->lnkcnt);
+	free(opts);
+}
+
+void pipefs_mount(ipc_callid_t rid, ipc_call_t *request)
+{
+	libfs_mount(&pipefs_libfs_ops, pipefs_reg.fs_handle, rid, request);
+}
+
+void pipefs_unmounted(ipc_callid_t rid, ipc_call_t *request)
+{
+	devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
+
+	pipefs_instance_done(devmap_handle);
+	async_answer_0(rid, EOK);
+}
+
+void pipefs_unmount(ipc_callid_t rid, ipc_call_t *request)
+{
+	libfs_unmount(&pipefs_libfs_ops, rid, request);
+}
+
+void pipefs_lookup(ipc_callid_t rid, ipc_call_t *request)
+{
+	libfs_lookup(&pipefs_libfs_ops, pipefs_reg.fs_handle, rid, request);
+}
+
+void pipefs_read(ipc_callid_t rid, ipc_call_t *request)
+{
+	devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
+	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
+	aoff64_t pos =
+	    (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
+	
+	/*
+	 * Lookup the respective PIPEFS node.
+	 */
+	link_t *hlp;
+	unsigned long key[] = {
+		[NODES_KEY_DEV] = devmap_handle,
+		[NODES_KEY_INDEX] = index
+	};
+	hlp = hash_table_find(&nodes, key);
+	if (!hlp) {
+		async_answer_0(rid, ENOENT);
+		return;
+	}
+	pipefs_node_t *nodep = hash_table_get_instance(hlp, pipefs_node_t,
+	    nh_link);
+	
+	/*
+	 * Receive the read request.
+	 */
+	ipc_callid_t callid;
+	size_t size;
+	if (!async_data_read_receive(&callid, &size)) {
+		async_answer_0(callid, EINVAL);
+		async_answer_0(rid, EINVAL);
+		return;
+	}
+
+	size_t bytes;
+	if (nodep->type == PIPEFS_FILE) {
+		/*
+		 * Check if we still have the requested data.
+		 * This may happen if the client seeked backwards
+		 */
+		if (pos < nodep->start) {
+			async_answer_0(callid, ENOTSUP);
+			async_answer_0(rid, ENOTSUP);
+			return;
+		}
+		
+		/*
+		 * Free all data blocks that end before pos.
+		 * This is in case the client seeked forward 
+		 */
+		while (!list_empty(&nodep->data_head)) {
+			pipefs_data_block_t *data_block =
+			    list_get_instance(nodep->data_head.next,
+			        pipefs_data_block_t, link);
+		
+			aoff64_t block_end = nodep->start + data_block->size;
+			
+			if (block_end > pos) {
+				break;
+			}
+			
+			list_remove(&data_block->link);
+			free(data_block->data);
+			free(data_block);
+			nodep->start = block_end;
+		}
+		
+		if (!list_empty(&nodep->data_head)) {
+			/* We have data block, so let's return its portion after pos */
+			pipefs_data_block_t *data_block =
+			    list_get_instance(nodep->data_head.next,
+			        pipefs_data_block_t, link);
+			
+			assert(nodep->start <= pos);
+			
+			aoff64_t block_end = nodep->start + data_block->size;
+			size_t block_offset = pos - nodep->start;
+			
+			assert(block_end > pos);
+			
+			bytes = min(block_end - pos, size);
+			(void) async_data_read_finalize(callid,
+			    data_block->data + block_offset,
+			    bytes);
+			
+			if (nodep->start + block_offset + bytes == block_end) {
+				/* Free the data block - it was fully read */
+				list_remove(&data_block->link);
+				free(data_block->data);
+				free(data_block);
+				nodep->start = block_end;
+			}
+		}
+		else {
+			/*
+			 * there is no data
+			 * TODO implement waiting for the data
+			 * and remove this else clause
+			 */
+			async_answer_0(callid, ENOTSUP);
+			async_answer_1(rid, ENOTSUP, 0);
+			return;
+		}
+	} else {
+		pipefs_dentry_t *dentryp;
+		link_t *lnk;
+		aoff64_t i;
+		
+		assert(nodep->type == PIPEFS_DIRECTORY);
+		
+		/*
+		 * Yes, we really use O(n) algorithm here.
+		 * If it bothers someone, it could be fixed by introducing a
+		 * hash table.
+		 */
+		for (i = 0, lnk = nodep->cs_head.next;
+		    (i < pos) && (lnk != &nodep->cs_head);
+		    i++, lnk = lnk->next)
+			;
+
+		if (lnk == &nodep->cs_head) {
+			async_answer_0(callid, ENOENT);
+			async_answer_1(rid, ENOENT, 0);
+			return;
+		}
+
+		dentryp = list_get_instance(lnk, pipefs_dentry_t, link);
+
+		(void) async_data_read_finalize(callid, dentryp->name,
+		    str_size(dentryp->name) + 1);
+		bytes = 1;
+	}
+
+	/*
+	 * Answer the VFS_READ call.
+	 */
+	async_answer_1(rid, EOK, bytes);
+}
+
+void pipefs_write(ipc_callid_t rid, ipc_call_t *request)
+{
+	devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
+	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
+	aoff64_t pos =
+	    (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
+	
+	/*
+	 * Lookup the respective PIPEFS node.
+	 */
+	link_t *hlp;
+	unsigned long key[] = {
+		[NODES_KEY_DEV] = devmap_handle,
+		[NODES_KEY_INDEX] = index
+	};
+	hlp = hash_table_find(&nodes, key);
+	if (!hlp) {
+		async_answer_0(rid, ENOENT);
+		return;
+	}
+	pipefs_node_t *nodep = hash_table_get_instance(hlp, pipefs_node_t,
+	    nh_link);
+
+	/*
+	 * Receive the write request.
+	 */
+	ipc_callid_t callid;
+	size_t size;
+	if (!async_data_write_receive(&callid, &size)) {
+		async_answer_0(callid, EINVAL);	
+		async_answer_0(rid, EINVAL);
+		return;
+	}
+
+	/*
+	 * Check whether we are writing to the end
+	 */
+	if (pos != nodep->size) {
+		async_answer_0(callid, ENOTSUP);
+		async_answer_2(rid, EOK, 0, nodep->size);
+		return;
+	}
+	
+	/*
+	 * Allocate a buffer for the new data.
+	 * Currently we accept any size, create a data block from this
+	 * and append it to the end of a file
+	 */
+	void *newdata = malloc(size);
+	if (!newdata) {
+		async_answer_0(callid, ENOMEM);
+		async_answer_2(rid, EOK, 0, nodep->size);
+		return;
+	}
+	
+	pipefs_data_block_t *newblock = malloc(sizeof(pipefs_data_block_t));
+	
+	if (!newblock) {
+		free(newdata);
+		async_answer_0(callid, ENOMEM);
+		async_answer_2(rid, EOK, 0, nodep->size);
+		return;
+	}
+	
+	int rc = async_data_write_finalize(callid, newdata, size);
+	
+	if (rc != EOK) {
+		free(newblock);
+		free(newdata);
+		async_answer_0(callid, rc);
+		async_answer_2(rid, EOK, 0, nodep->size);
+		return;
+	}
+	
+	link_initialize(&newblock->link);
+	newblock->size = size;
+	newblock->data = newdata;
+	list_append(&newblock->link, &nodep->data_head);
+	
+	nodep->size += size;
+	
+	async_answer_2(rid, EOK, size, nodep->size);
+}
+
+void pipefs_truncate(ipc_callid_t rid, ipc_call_t *request)
+{
+	/*
+	 * PIPEFS does not support resizing of files
+	 */
+	async_answer_0(rid, ENOTSUP);
+}
+
+void pipefs_close(ipc_callid_t rid, ipc_call_t *request)
+{
+	async_answer_0(rid, EOK);
+}
+
+void pipefs_destroy(ipc_callid_t rid, ipc_call_t *request)
+{
+	devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request);
+	fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
+	int rc;
+
+	link_t *hlp;
+	unsigned long key[] = {
+		[NODES_KEY_DEV] = devmap_handle,
+		[NODES_KEY_INDEX] = index
+	};
+	hlp = hash_table_find(&nodes, key);
+	if (!hlp) {
+		async_answer_0(rid, ENOENT);
+		return;
+	}
+	pipefs_node_t *nodep = hash_table_get_instance(hlp, pipefs_node_t,
+	    nh_link);
+	rc = pipefs_destroy_node(FS_NODE(nodep));
+	async_answer_0(rid, rc);
+}
+
+void pipefs_open_node(ipc_callid_t rid, ipc_call_t *request)
+{
+	libfs_open_node(&pipefs_libfs_ops, pipefs_reg.fs_handle, rid, request);
+}
+
+void pipefs_stat(ipc_callid_t rid, ipc_call_t *request)
+{
+	libfs_stat(&pipefs_libfs_ops, pipefs_reg.fs_handle, rid, request);
+}
+
+void pipefs_sync(ipc_callid_t rid, ipc_call_t *request)
+{
+	/*
+	 * PIPEFS keeps its data structures always consistent,
+	 * thus the sync operation is a no-op.
+	 */
+	async_answer_0(rid, EOK);
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hw/netif/ne2000/dp8390_drv.h
===================================================================
--- uspace/srv/hw/netif/ne2000/dp8390_drv.h	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
+++ uspace/srv/hw/netif/ne2000/dp8390_drv.h	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup dp8390
+ *  @{
+ */
+
+/** @file
+ *  DP8390 network interface driver interface.
+ */
+
+#ifndef __NET_NETIF_DP8390_DRIVER_H__
+#define __NET_NETIF_DP8390_DRIVER_H__
+
+#include "dp8390.h"
+
+/** Initializes and/or starts the network interface.
+ *  @param[in,out] dep The network interface structure.
+ *  @param[in] mode The state mode.
+ *  @returns EOK on success.
+ *  @returns EXDEV if the network interface is disabled.
+ */
+int do_init(dpeth_t *dep, int mode);
+
+/** Stops the network interface.
+ *  @param[in,out] dep The network interface structure.
+ */
+void do_stop(dpeth_t *dep);
+
+/** Processes the interrupt.
+ *  @param[in,out] dep The network interface structure.
+ *  @param[in] isr The interrupt status register.
+ */
+void dp_check_ints(dpeth_t *dep, int isr);
+
+/** Probes and initializes the network interface.
+ *  @param[in,out] dep The network interface structure.
+ *  @returns EOK on success.
+ *  @returns EXDEV if the network interface was not recognized.
+ */
+int do_probe(dpeth_t * dep);
+
+/** Sends a packet.
+ *  @param[in,out] dep The network interface structure.
+ *  @param[in] packet The packet t be sent.
+ *  @param[in] from_int The value indicating whether the sending is initialized from the interrupt handler.
+ *  @returns 
+ */
+int do_pwrite(dpeth_t * dep, packet_t *packet, int from_int);
+
+/** Prints out network interface information.
+ *  @param[in] dep The network interface structure.
+ */
+void dp8390_dump(dpeth_t * dep);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/hw/netif/ne2000/dp8390_port.h
===================================================================
--- uspace/srv/hw/netif/ne2000/dp8390_port.h	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
+++ uspace/srv/hw/netif/ne2000/dp8390_port.h	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup dp8390
+ *  @{
+ */
+
+/** @file
+ *  DP8390 network interface types and structures ports.
+ */
+
+#ifndef __NET_NETIF_DP8390_PORT_H__
+#define __NET_NETIF_DP8390_PORT_H__
+
+#include <errno.h>
+#include <mem.h>
+#include <stdio.h>
+#include <libarch/ddi.h>
+#include <sys/types.h>
+
+/** Macro for difining functions.
+ *  @param[in] function The function type and name definition.
+ *  @param[in] params The function parameters definition.
+ */
+#define _PROTOTYPE(function, params) function params
+
+/** Success error code.
+ */
+#define OK	EOK
+
+/** Type definition of the unsigned byte.
+ */
+typedef uint8_t u8_t;
+
+/** Type definition of the unsigned short.
+ */
+typedef uint16_t u16_t;
+
+/** Compares two memory blocks.
+ *  @param[in] first The first memory block.
+ *  @param[in] second The second memory block.
+ *  @param[in] size The blocks size in bytes.
+ *  @returns 0 if equeal.
+ *  @returns -1 if the first is greater than the second.
+ *  @returns 1 if the second is greater than the first.
+ */
+#define memcmp(first, second, size)	bcmp((char *) (first), (char *) (second), (size))
+
+/** Reads 1 byte.
+ *  @param[in] port The address to be read.
+ *  @returns The read value.
+ */
+#define inb(port)	pio_read_8((ioport8_t *) (port))
+
+/** Reads 1 word (2 bytes).
+ *  @param[in] port The address to be read.
+ *  @returns The read value.
+ */
+#define inw(port)	pio_read_16((ioport16_t *) (port))
+
+/** Writes 1 byte.
+ *  @param[in] port The address to be written.
+ *  @param[in] value The value to be written.
+ */
+#define outb(port, value)	pio_write_8((ioport8_t *) (port), (value))
+
+/** Writes 1 word (2 bytes).
+ *  @param[in] port The address to be written.
+ *  @param[in] value The value to be written.
+ */
+#define outw(port, value)	pio_write_16((ioport16_t *) (port), (value))
+
+/** Prints out the driver critical error.
+ *  Does not call the system panic().
+ */
+#define panic(...)	printf("%s%s%d", __VA_ARGS__)
+
+/** Copies a memory block.
+ *  @param proc The source process. Ignored parameter.
+ *  @param src_s Ignored parameter.
+ *  @param[in] src The source address.
+ *  @param me The current proces. Ignored parameter.
+ *  @param dst_s Ignored parameter.
+ *  @param[in] dst The destination address.
+ *  @param[in] bytes The block size in bytes.
+ *  @returns EOK.
+ */
+#define sys_vircopy(proc, src_s, src, me, dst_s, dst, bytes)	({memcpy((void *)(dst), (void *)(src), (bytes)); EOK;})
+
+/** Reads a memory block byte by byte.
+ *  @param[in] port The address to be written.
+ *  @param proc The source process. Ignored parameter.
+ *  @param[in] dst The destination address.
+ *  @param[in] bytes The block size in bytes.
+ */
+#define do_vir_insb(port, proc, dst, bytes)	insb((port), (void *)(dst), (bytes))
+
+/** Reads a memory block word by word (2 bytes).
+ *  @param[in] port The address to be written.
+ *  @param proc The source process. Ignored parameter.
+ *  @param[in] dst The destination address.
+ *  @param[in] bytes The block size in bytes.
+ */
+#define do_vir_insw(port, proc, dst, bytes)	insw((port), (void *)(dst), (bytes))
+
+/** Writes a memory block byte by byte.
+ *  @param[in] port The address to be written.
+ *  @param proc The source process. Ignored parameter.
+ *  @param[in] src The source address.
+ *  @param[in] bytes The block size in bytes.
+ */
+#define do_vir_outsb(port, proc, src, bytes)	outsb((port), (void *)(src), (bytes))
+
+/** Writes a memory block word by word (2 bytes).
+ *  @param[in] port The address to be written.
+ *  @param proc The source process. Ignored parameter.
+ *  @param[in] src The source address.
+ *  @param[in] bytes The block size in bytes.
+ */
+#define do_vir_outsw(port, proc, src, bytes)	outsw((port), (void *)(src), (bytes))
+
+/* com.h */
+/* Bits in 'DL_MODE' field of DL requests. */
+#  define DL_NOMODE		0x0
+#  define DL_PROMISC_REQ	0x2
+#  define DL_MULTI_REQ		0x4
+#  define DL_BROAD_REQ		0x8
+
+/* const.h */
+/** True value.
+ */
+#define TRUE               1	/* used for turning integers into Booleans */
+
+/** False value.
+ */
+#define FALSE              0	/* used for turning integers into Booleans */
+
+/** No number value.
+ */
+#define NO_NUM        0x8000	/* used as numerical argument to panic() */
+
+/* devio.h */
+//typedef u16_t port_t;
+/** Type definition of a port.
+ */
+typedef long port_t;
+
+/* dl_eth.h */
+/** Ethernet statistics.
+ */
+typedef struct eth_stat
+{
+	/** Number of receive errors.
+	 */
+	unsigned long ets_recvErr;
+	/** Number of send error.
+	 */
+	unsigned long ets_sendErr;
+	/** Number of buffer overwrite warnings.
+	 */
+	unsigned long ets_OVW;
+	/** Number of crc errors of read.
+	 */
+	unsigned long ets_CRCerr;
+	/** Number of frames not alligned (number of bits % 8 != 0).
+	 */
+	unsigned long ets_frameAll;
+	/** Number of packets missed due to slow processing.
+	 */
+	unsigned long ets_missedP;
+	/** Number of packets received.
+	 */
+	unsigned long ets_packetR;
+	/** Number of packets transmitted.
+	 */
+	unsigned long ets_packetT;
+	/** Number of transmission defered (Tx was busy).
+	 */
+	unsigned long ets_transDef;
+	/** Number of collissions.
+	 */
+	unsigned long ets_collision;
+	/** Number of Tx aborted due to excess collisions.
+	 */
+	unsigned long ets_transAb;
+	/** Number of carrier sense lost.
+	 */
+	unsigned long ets_carrSense;
+	/** Number of FIFO underruns (processor too busy).
+	 */
+	unsigned long ets_fifoUnder;
+	/** Number of FIFO overruns (processor too busy).
+	 */
+	unsigned long ets_fifoOver;
+	/** Number of times unable to transmit collision sig.
+	 */
+	unsigned long ets_CDheartbeat;
+	/** Number of times out of window collision.
+	 */
+	unsigned long ets_OWC;
+} eth_stat_t;
+
+/* errno.h */
+/** Generic error.
+ */
+#define EGENERIC     EINVAL
+
+/* ether.h */
+/** Minimum Ethernet packet size in bytes.
+ */
+#define ETH_MIN_PACK_SIZE		  60
+
+/** Maximum Ethernet packet size in bytes.
+ */
+#define ETH_MAX_PACK_SIZE_TAGGED	1518
+
+/** Ethernet address type definition.
+ */
+typedef struct ether_addr
+{
+	/** Address data.
+	 */
+	u8_t ea_addr[6];
+} ether_addr_t;
+
+/* type.h */
+/** Type definition of the physical addresses and lengths in bytes.
+ */
+typedef unsigned long phys_bytes;
+
+/** Type definition of the virtual addresses and lengths in bytes.
+ */
+typedef unsigned long vir_bytes;
+
+/** Type definition of the input/output vector.
+ */
+typedef struct {
+	/** Address of an I/O buffer.
+	 */
+	vir_bytes iov_addr;
+	/** Sizeof an I/O buffer.
+	 */
+	vir_bytes iov_size;
+} iovec_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/hw/netif/ne2000/local.h
===================================================================
--- uspace/srv/hw/netif/ne2000/local.h	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
+++ uspace/srv/hw/netif/ne2000/local.h	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 1987,1997, 2006, Vrije Universiteit, Amsterdam, The Netherlands All rights reserved. Redistribution and use of the MINIX 3 operating system 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.
+ * * Neither the name of the Vrije Universiteit nor the names of the software authors or contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+ * * Any deviations from these conditions require written permission from the copyright holder in advance
+ *
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, 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 COPYRIGHT HOLDER OR ANY AUTHORS 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.
+ *
+ * Changes:
+ *  2009 ported to HelenOS, Lukas Mejdrech
+ */
+
+/** @addtogroup dp8390
+ *  @{
+ */
+
+/** @file
+ *  Network interface probe functions.
+ */
+
+#ifndef __NET_NETIF_DP8390_CONFIG_H__
+#define __NET_NETIF_DP8390_CONFIG_H__
+
+#include "dp8390_port.h"
+
+/*
+local.h
+*/
+
+/** WDETH switch.
+ */
+#define ENABLE_WDETH 0
+
+/** NE2000 switch.
+ */
+#define ENABLE_NE2000 1
+
+/** 3C503 switch.
+ */
+#define ENABLE_3C503 0
+
+/** PCI support switch.
+ */
+#define ENABLE_PCI 0
+
+struct dpeth;
+
+/* 3c503.c */
+/* * Probes a 3C503 network interface.
+ *  @param[in] dep The network interface structure.
+ *  @returns 1 if the NE2000 network interface is present.
+ *  @returns 0 otherwise.
+ */
+//_PROTOTYPE(int el2_probe, (struct dpeth*dep)				);
+
+/* ne2000.c */
+/** Probes a NE2000 or NE1000 network interface.
+ *  @param[in] dep The network interface structure.
+ *  @returns 1 if the NE2000 network interface is present.
+ *  @returns 0 otherwise.
+ */
+int ne_probe(struct dpeth * dep);
+//_PROTOTYPE(int ne_probe, (struct dpeth *dep)				);
+//_PROTOTYPE(void ne_init, (struct dpeth *dep)				);
+
+/* rtl8029.c */
+/* * Probes a RTL8029 network interface.
+ *  @param[in] dep The network interface structure.
+ *  @returns 1 if the NE2000 network interface is present.
+ *  @returns 0 otherwise.
+ */
+//_PROTOTYPE(int rtl_probe, (struct dpeth *dep)				);
+
+/* wdeth.c */
+/* * Probes a WDETH network interface.
+ *  @param[in] dep The network interface structure.
+ *  @returns 1 if the NE2000 network interface is present.
+ *  @returns 0 otherwise.
+ */
+//_PROTOTYPE(int wdeth_probe, (struct dpeth*dep)				);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/hw/netif/ne2000/ne2000.h
===================================================================
--- uspace/srv/hw/netif/ne2000/ne2000.h	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
+++ uspace/srv/hw/netif/ne2000/ne2000.h	(revision cf2af9420beac4beb87e825927a6a1c8bbed8ade)
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1987,1997, 2006, Vrije Universiteit, Amsterdam, The Netherlands All rights reserved. Redistribution and use of the MINIX 3 operating system 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.
+ * * Neither the name of the Vrije Universiteit nor the names of the software authors or contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+ * * Any deviations from these conditions require written permission from the copyright holder in advance
+ *
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, 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 COPYRIGHT HOLDER OR ANY AUTHORS 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.
+ *
+ * Changes:
+ *  2009 ported to HelenOS, Lukas Mejdrech
+ */
+
+/*
+ne2000.h
+
+Created:	March 15, 1994 by Philip Homburg <philip@f-mnx.phicoh.com>
+*/
+
+/** @addtogroup ne2k
+ *  @{
+ */
+
+/** @file
+ *  NE1000 and NE2000 network interface definitions.
+ */
+
+#ifndef __NET_NETIF_NE2000_H__
+#define __NET_NETIF_NE2000_H__
+
+#include <libarch/ddi.h>
+
+#include "dp8390_port.h"
+
+/** DP8390 register offset.
+ */
+#define NE_DP8390	0x00
+
+/** Data register.
+ */
+#define NE_DATA		0x10
+
+/** Reset register.
+ */
+#define NE_RESET	0x1F
+
+/** NE1000 data start.
+ */
+#define NE1000_START	0x2000
+
+/** NE1000 data size.
+ */
+#define NE1000_SIZE	0x2000
+
+/** NE2000 data start.
+ */
+#define NE2000_START	0x4000
+
+/** NE2000 data size.
+ */
+#define NE2000_SIZE	0x4000
+
+/** Reads 1 byte register.
+ *  @param[in] dep The network interface structure.
+ *  @param[in] reg The register offset.
+ *  @returns The read value.
+ */
+#define inb_ne(dep, reg)	(inb(dep->de_base_port+reg))
+
+/** Writes 1 byte register.
+ *  @param[in] dep The network interface structure.
+ *  @param[in] reg The register offset.
+ *  @param[in] data The value to be written.
+ */
+#define outb_ne(dep, reg, data)	(outb(dep->de_base_port+reg, data))
+
+/** Reads 1 word (2 bytes) register.
+ *  @param[in] dep The network interface structure.
+ *  @param[in] reg The register offset.
+ *  @returns The read value.
+ */
+#define inw_ne(dep, reg)	(inw(dep->de_base_port+reg))
+
+/** Writes 1 word (2 bytes) register.
+ *  @param[in] dep The network interface structure.
+ *  @param[in] reg The register offset.
+ *  @param[in] data The value to be written.
+ */
+#define outw_ne(dep, reg, data)	(outw(dep->de_base_port+reg, data))
+
+#endif /* __NET_NETIF_NE2000_H__ */
+
+/*
+ * $PchId: ne2000.h,v 1.4 2004/08/03 12:03:20 philip Exp $
+ */
+
+/** @}
+ */
