Index: tools/check.sh
===================================================================
--- tools/check.sh	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ tools/check.sh	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -66,5 +66,5 @@
 do
 	echo -n ">>>> Building $P... "
-	( make distclean && make PROFILE=$P HANDS_OFF=y $1 ) >>/dev/null 2>>/dev/null
+	( make distclean && make PROFILE=$P HANDS_OFF=y "$@" ) >>/dev/null 2>>/dev/null
 	if [ $? -ne 0 ];
 	then
Index: tools/mkfat.py
===================================================================
--- tools/mkfat.py	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ tools/mkfat.py	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -168,47 +168,106 @@
 """
 
-def mangle_fname(name):
+LFN_ENTRY = """little:
+	uint8_t pos
+	uint16_t name1[5]
+	uint8_t attr
+	uint8_t type
+	uint8_t csum
+	uint16_t name2[6]
+	uint16_t fc
+	uint16_t name3[2]
+"""
+
+# Global variable to hold the file names in 8.3 format. Needed to 
+# keep track of "number" when creating a short fname from a LFN.
+name83_list = []
+
+def name83(fname):
+	"Create a 8.3 name for the given fname"
+
 	# FIXME: filter illegal characters
-	parts = name.split('.')
-	
+	parts = fname.split('.')
+	
+	name = ''
+	ext = ''
+	lfn = False
+
+	if len(fname) > 11 :
+		lfn = True
+
 	if len(parts) > 0:
-		fname = parts[0]
-	else:
-		fname = ''
-	
-	if len(fname) > 8:
-		sys.stdout.write("mkfat.py: error: Directory entry " + name +
-		    " base name is longer than 8 characters\n")
-		sys.exit(1);
-	
-	return (fname + '          ').upper()[0:8]
-
-def mangle_ext(name):
-	# FIXME: filter illegal characters
-	parts = name.split('.')
-	
-	if len(parts) > 1:
-		ext = parts[1]
-	else:
-		ext = ''
-	
-	if len(parts) > 2:
-		sys.stdout.write("mkfat.py: error: Directory entry " + name +
-		    " has more than one extension\n")
-		sys.exit(1);
-	
-	if len(ext) > 3:
-		sys.stdout.write("mkfat.py: error: Directory entry " + name +
-		    " extension is longer than 3 characters\n")
-		sys.exit(1);
-	
-	return (ext + '   ').upper()[0:3]
+		name = parts[0]
+		if len(name) > 8 :
+			lfn = True
+
+	if len(parts) > 1 :
+		ext = parts[-1]
+		if len(ext) > 3 :
+			lfn = True
+
+	if len(parts) > 2 :
+		lfn = True
+
+	if (lfn == False) :
+		return (name.ljust(8)[0:8], ext.ljust(3)[0:3], False)
+
+	# For filenames with multiple extensions, we treat the last one
+	# as the actual extension. The rest of the filename is stripped
+	# of dots and concatenated to form the short name
+	for _name in parts[1:-1]:
+		name = name + _name		
+
+	global name83_list
+	for number in range(1, 10000) :
+		number_str = '~' + str(number)
+
+		if len(name) + len(number_str) > 8 :
+			name = name[0:8 - len(number_str)]
+
+		name = name + number_str;
+
+		if (name + ext) not in name83_list :
+			break
+			
+	name83_list.append(name + ext)	
+
+	return (name.ljust(8)[0:8], ext.ljust(3)[0:3], True)
+
+def get_utf16(name, l) :
+	"Create a int array out of a string which we can store in uint16_t arrays"
+
+	bs = [0xFFFF for i in range(l)]
+
+	for i in range(len(name)) :
+		bs[i] = ord(name[i])
+	
+	if (len(name) < l) :
+		bs[len(name)] = 0;
+	
+	return bs
+
+def create_lfn_entry((name, index)) :
+	entry = xstruct.create(LFN_ENTRY)
+
+	entry.name1 = get_utf16(name[0:5], 5)
+	entry.name2 = get_utf16(name[5:11], 6)
+	entry.name3 = get_utf16(name[11:13], 2)
+	entry.pos = index
+
+	entry.attr = 0xF
+	entry.fc = 0
+	entry.type = 0
+
+	return entry
 
 def create_dirent(name, directory, cluster, size):
+	
 	dir_entry = xstruct.create(DIR_ENTRY)
 	
-	dir_entry.name = mangle_fname(name).encode('ascii')
-	dir_entry.ext = mangle_ext(name).encode('ascii')
-	
+	dir_entry.name, dir_entry.ext, lfn = name83(name)
+
+	dir_entry.name = dir_entry.name.upper().encode('ascii')
+	dir_entry.ext = dir_entry.ext.upper().encode('ascii')
+
 	if (directory):
 		dir_entry.attr = 0x30
@@ -230,5 +289,27 @@
 		dir_entry.size = size
 	
-	return dir_entry
+
+	if not lfn:
+		return [dir_entry]
+
+	n = len(name) / 13 + 1
+	names = [(name[i * 13: (i + 1) * 13 + 1], i + 1) for i in range(n)]
+
+	entries = sorted(map (create_lfn_entry, names), reverse = True, key = lambda e : e.pos)
+	entries[0].pos |= 0x40
+
+	fname11 = dir_entry.name + dir_entry.ext
+
+	csum = 0
+	for i in range(0, 11) :
+		csum = ((csum & 1) << 7) + (csum  >> 1) + ord(fname11[i])
+		csum = csum & 0xFF
+	
+	for e in entries :
+		e.csum = csum;
+	
+	entries.append(dir_entry)
+
+	return entries
 
 def create_dot_dirent(empty_cluster):
@@ -288,8 +369,8 @@
 		if item.is_file:
 			rv = write_file(item, outf, cluster_size, data_start, fat, reserved_clusters)
-			directory.append(create_dirent(item.name, False, rv[0], rv[1]))
+			directory.extend(create_dirent(item.name, False, rv[0], rv[1]))
 		elif item.is_dir:
 			rv = recursion(False, item.path, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, empty_cluster)
-			directory.append(create_dirent(item.name, True, rv[0], rv[1]))
+			directory.extend(create_dirent(item.name, True, rv[0], rv[1]))
 	
 	if (head):
Index: uspace/app/bdsh/cmds/modules/cat/cat.c
===================================================================
--- uspace/app/bdsh/cmds/modules/cat/cat.c	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ uspace/app/bdsh/cmds/modules/cat/cat.c	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -52,6 +52,6 @@
 #define CAT_VERSION "0.0.1"
 #define CAT_DEFAULT_BUFLEN 1024
-
-static const char *cat_oops = "That option is not yet supported\n";
+#define CAT_FULL_FILE 0
+
 static const char *hexchars = "0123456789abcdef";
 
@@ -163,10 +163,12 @@
 }
 
-static unsigned int cat_file(const char *fname, size_t blen, bool hex)
+static unsigned int cat_file(const char *fname, size_t blen, bool hex,
+    off64_t head, off64_t tail, bool tail_first)
 {
 	int fd, bytes = 0, count = 0, reads = 0;
 	char *buff = NULL;
 	int i;
-	size_t offset = 0;
+	size_t offset = 0, copied_bytes = 0;
+	off64_t file_size = 0, length = 0;
 
 	fd = open(fname, O_RDONLY);
@@ -183,8 +185,34 @@
 	}
 
+	if (tail != CAT_FULL_FILE) {
+		file_size = lseek(fd, 0, SEEK_END);
+		if (head == CAT_FULL_FILE) {
+			head = file_size;
+			length = tail;
+		} else if (tail_first) {
+			length = head;
+		} else {
+			if (tail > head)
+				tail = head;
+			length = tail;
+		}
+
+		if (tail_first) {
+			lseek(fd, (tail >= file_size) ? 0 : (file_size - tail), SEEK_SET);
+		} else {
+			lseek(fd, ((head - tail) >= file_size) ? 0 : (head - tail), SEEK_SET);
+		}
+	} else
+		length = head;
+
 	do {
-		bytes = read(fd, buff, blen);
+		bytes = read(fd, buff + copied_bytes, (
+			(length != CAT_FULL_FILE && length - (off64_t)count <= (off64_t)(blen - copied_bytes)) ?
+			(size_t)(length - count) :
+			(blen - copied_bytes) ) );
+		bytes += copied_bytes;
+		copied_bytes = 0;
+
 		if (bytes > 0) {
-			count += bytes;
 			buff[bytes] = '\0';
 			offset = 0;
@@ -193,4 +221,5 @@
 					paged_char(hexchars[((uint8_t)buff[i])/16]);
 					paged_char(hexchars[((uint8_t)buff[i])%16]);
+					paged_char(((count+i+1) & 0xf) == 0 ? '\n' : ' ');
 				}
 				else {
@@ -199,4 +228,10 @@
 						/* Reached end of string */
 						break;
+					} else if (c == U_SPECIAL && offset + 2 >= (size_t)bytes) {
+						/* If an extended character is cut off due to the size of the buffer,
+						   we will copy it over to the next buffer so it can be read correctly. */
+						copied_bytes = bytes - offset + 1;
+						memcpy(buff, buff + offset - 1, copied_bytes);
+						break;
 					}
 					paged_char(c);
@@ -204,7 +239,8 @@
 				
 			}
+			count += bytes;
 			reads++;
 		}
-	} while (bytes > 0 && !should_quit);
+	} while (bytes > 0 && !should_quit && (count < length || length == CAT_FULL_FILE));
 
 	close(fd);
@@ -223,8 +259,11 @@
 int cmd_cat(char **argv)
 {
-	unsigned int argc, i, ret = 0, buffer = 0;
+	unsigned int argc, i, ret = 0;
+	size_t buffer = 0;
 	int c, opt_ind;
+	aoff64_t head = CAT_FULL_FILE, tail = CAT_FULL_FILE;
 	bool hex = false;
 	bool more = false;
+	bool tailFirst = false;
 	sysarg_t rows, cols;
 	int rc;
@@ -254,11 +293,22 @@
 			return CMD_SUCCESS;
 		case 'H':
-			printf("%s", cat_oops);
-			return CMD_FAILURE;
+			if (!optarg || str_uint64_t(optarg, NULL, 10, false, &head) != EOK ) {
+				puts("Invalid head size\n");
+				return CMD_FAILURE;
+			}
+			break;
 		case 't':
-			printf("%s", cat_oops);
-			return CMD_FAILURE;
+			if (!optarg || str_uint64_t(optarg, NULL, 10, false, &tail) != EOK ) {
+				puts("Invalid tail size\n");
+				return CMD_FAILURE;
+			}
+			if (head == CAT_FULL_FILE)
+				tailFirst = true;
+			break;
 		case 'b':
-			printf("%s", cat_oops);
+			if (!optarg || str_size_t(optarg, NULL, 10, false, &buffer) != EOK ) {
+				puts("Invalid buffer size\n");
+				return CMD_FAILURE;
+			}
 			break;
 		case 'm':
@@ -279,5 +329,5 @@
 	}
 
-	if (buffer <= 0)
+	if (buffer < 4)
 		buffer = CAT_DEFAULT_BUFLEN;
 	
@@ -295,5 +345,5 @@
 
 	for (i = optind; argv[i] != NULL && !should_quit; i++)
-		ret += cat_file(argv[i], buffer, hex);
+		ret += cat_file(argv[i], buffer, hex, head, tail, tailFirst);
 
 	if (ret)
Index: uspace/app/bdsh/cmds/modules/cat/cat.h
===================================================================
--- uspace/app/bdsh/cmds/modules/cat/cat.h	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ uspace/app/bdsh/cmds/modules/cat/cat.h	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -4,5 +4,5 @@
 /* Prototypes for the cat command, excluding entry points */
 
-static unsigned int cat_file(const char *, size_t, bool);
+static unsigned int cat_file(const char *, size_t, bool, off64_t, off64_t, bool);
 
 #endif /* CAT_H */
Index: uspace/app/sportdmp/sportdmp.c
===================================================================
--- uspace/app/sportdmp/sportdmp.c	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ uspace/app/sportdmp/sportdmp.c	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -27,20 +27,20 @@
  */
 
+#include <device/char_dev.h>
 #include <errno.h>
+#include <ipc/serial_ctl.h>
+#include <loc.h>
 #include <stdio.h>
-#include <devman.h>
-#include <ipc/devman.h>
-#include <device/char_dev.h>
-#include <ipc/serial_ctl.h>
 
 #define BUF_SIZE 1
 
-static void syntax_print() {
-	fprintf(stderr, "Usage: sportdmp <baud> <device_path>\n");
+static void syntax_print(void)
+{
+	fprintf(stderr, "Usage: sportdmp <baud> <device_service>\n");
 }
 
 int main(int argc, char **argv)
 {
-	const char* devpath = "/hw/pci0/00:01.0/com1/a";
+	const char* svc_path = "devices/\\hw\\pci0\\00:01.0\\com1\\a";
 	sysarg_t baud = 9600;
 	
@@ -56,5 +56,5 @@
 	
 	if (argc > 2) {
-		devpath = argv[2];
+		svc_path = argv[2];
 	}
 	
@@ -64,15 +64,15 @@
 	}
 	
-	devman_handle_t device;
-	int rc = devman_fun_get_handle(devpath, &device, IPC_FLAG_BLOCKING);
+	service_id_t svc_id;
+	int rc = loc_service_get_id(svc_path, &svc_id, IPC_FLAG_BLOCKING);
 	if (rc != EOK) {
-		fprintf(stderr, "Cannot open device %s\n", devpath);
+		fprintf(stderr, "Cannot find device service %s\n", svc_path);
 		return 1;
 	}
 	
-	async_sess_t *sess = devman_device_connect(EXCHANGE_SERIALIZE, device,
+	async_sess_t *sess = loc_service_connect(EXCHANGE_SERIALIZE, svc_id,
 	    IPC_FLAG_BLOCKING);
 	if (!sess) {
-		fprintf(stderr, "Cannot connect device\n");
+		fprintf(stderr, "Failed connecting to service %s\n", svc_path);
 	}
 	
@@ -83,5 +83,5 @@
 	
 	if (rc != EOK) {
-		fprintf(stderr, "Cannot set serial properties\n");
+		fprintf(stderr, "Failed setting serial properties\n");
 		return 2;
 	}
@@ -89,5 +89,5 @@
 	uint8_t *buf = (uint8_t *) malloc(BUF_SIZE);
 	if (buf == NULL) {
-		fprintf(stderr, "Cannot allocate buffer\n");
+		fprintf(stderr, "Failed allocating buffer\n");
 		return 3;
 	}
Index: uspace/app/tester/hw/serial/serial1.c
===================================================================
--- uspace/app/tester/hw/serial/serial1.c	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ uspace/app/tester/hw/serial/serial1.c	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -42,6 +42,5 @@
 #include <async.h>
 #include <ipc/services.h>
-#include <ipc/devman.h>
-#include <devman.h>
+#include <loc.h>
 #include <device/char_dev.h>
 #include <str.h>
@@ -71,19 +70,19 @@
 		}
 	
-	devman_handle_t handle;
-	int res = devman_fun_get_handle("/hw/pci0/00:01.0/com1/a", &handle,
-	    IPC_FLAG_BLOCKING);
+	service_id_t svc_id;
+	int res = loc_service_get_id("devices/\\hw\\pci0\\00:01.0\\com1\\a",
+	    &svc_id, IPC_FLAG_BLOCKING);
 	if (res != EOK)
-		return "Could not get serial device handle";
-	
-	async_sess_t *sess = devman_device_connect(EXCHANGE_SERIALIZE, handle,
+		return "Failed getting serial port service ID";
+	
+	async_sess_t *sess = loc_service_connect(EXCHANGE_SERIALIZE, svc_id,
 	    IPC_FLAG_BLOCKING);
 	if (!sess)
-		return "Unable to connect to serial device";
+		return "Failed connecting to serial device";
 	
 	char *buf = (char *) malloc(cnt + 1);
 	if (buf == NULL) {
 		async_hangup(sess);
-		return "Failed to allocate input buffer";
+		return "Failed allocating input buffer";
 	}
 	
@@ -112,9 +111,9 @@
 		free(buf);
 		async_hangup(sess);
-		return "Failed to set serial communication parameters";
-	}
-	
-	TPRINTF("Trying to read %zu characters from serial device "
-	    "(handle=%" PRIun ")\n", cnt, handle);
+		return "Failed setting serial communication parameters";
+	}
+	
+	TPRINTF("Trying reading %zu characters from serial device "
+	    "(svc_id=%" PRIun ")\n", cnt, svc_id);
 	
 	size_t total = 0;
@@ -130,5 +129,5 @@
 			free(buf);
 			async_hangup(sess);
-			return "Failed read from serial device";
+			return "Failed reading from serial device";
 		}
 		
@@ -165,5 +164,5 @@
 				free(buf);
 				async_hangup(sess);
-				return "Failed write to serial device";
+				return "Failed writing to serial device";
 			}
 			
Index: uspace/drv/bus/isa/isa.c
===================================================================
--- uspace/drv/bus/isa/isa.c	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ uspace/drv/bus/isa/isa.c	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -66,6 +66,4 @@
 #include <ops/hw_res.h>
 
-#include <devman.h>
-#include <ipc/devman.h>
 #include <device/hw_res.h>
 
Index: uspace/drv/bus/usb/uhcirh/port.c
===================================================================
--- uspace/drv/bus/usb/uhcirh/port.c	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ uspace/drv/bus/usb/uhcirh/port.c	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -37,5 +37,4 @@
 #include <str_error.h>
 #include <async.h>
-#include <devman.h>
 
 #include <usb/usb.h>    /* usb_address_t */
Index: uspace/drv/bus/usb/usbhub/port.c
===================================================================
--- uspace/drv/bus/usb/usbhub/port.c	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ uspace/drv/bus/usb/usbhub/port.c	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -35,5 +35,4 @@
 
 #include <bool.h>
-#include <devman.h>
 #include <errno.h>
 #include <str_error.h>
Index: uspace/drv/char/ps2mouse/main.c
===================================================================
--- uspace/drv/char/ps2mouse/main.c	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ uspace/drv/char/ps2mouse/main.c	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -35,5 +35,4 @@
 #include <libarch/inttypes.h>
 #include <ddf/driver.h>
-#include <devman.h>
 #include <device/hw_res_parsed.h>
 #include <errno.h>
Index: uspace/drv/char/xtkbd/main.c
===================================================================
--- uspace/drv/char/xtkbd/main.c	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ uspace/drv/char/xtkbd/main.c	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -35,5 +35,4 @@
 #include <libarch/inttypes.h>
 #include <ddf/driver.h>
-#include <devman.h>
 #include <device/hw_res_parsed.h>
 #include <errno.h>
Index: uspace/drv/infrastructure/root/root.c
===================================================================
--- uspace/drv/infrastructure/root/root.c	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ uspace/drv/infrastructure/root/root.c	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -53,6 +53,4 @@
 #include <ddf/driver.h>
 #include <ddf/log.h>
-#include <devman.h>
-#include <ipc/devman.h>
 
 #define NAME "root"
Index: uspace/drv/infrastructure/rootpc/rootpc.c
===================================================================
--- uspace/drv/infrastructure/rootpc/rootpc.c	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ uspace/drv/infrastructure/rootpc/rootpc.c	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -48,6 +48,4 @@
 #include <ddf/driver.h>
 #include <ddf/log.h>
-#include <devman.h>
-#include <ipc/devman.h>
 #include <ipc/dev_iface.h>
 #include <ops/hw_res.h>
Index: uspace/drv/nic/e1k/e1k.c
===================================================================
--- uspace/drv/nic/e1k/e1k.c	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ uspace/drv/nic/e1k/e1k.c	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -46,5 +46,4 @@
 #include <ddf/log.h>
 #include <ddf/interrupt.h>
-#include <devman.h>
 #include <device/hw_res_parsed.h>
 #include <device/pci.h>
Index: uspace/lib/net/generic/net_remote.c
===================================================================
--- uspace/lib/net/generic/net_remote.c	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ uspace/lib/net/generic/net_remote.c	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -40,5 +40,4 @@
 #include <malloc.h>
 #include <async.h>
-#include <devman.h>
 #include <generic.h>
 #include <net/modules.h>
Index: uspace/lib/usb/src/ddfiface.c
===================================================================
--- uspace/lib/usb/src/ddfiface.c	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ uspace/lib/usb/src/ddfiface.c	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -33,5 +33,4 @@
  * Implementations of DDF interfaces functions (actual implementation).
  */
-#include <ipc/devman.h>
 #include <devman.h>
 #include <async.h>
Index: uspace/lib/usbvirt/src/ipc_dev.c
===================================================================
--- uspace/lib/usbvirt/src/ipc_dev.c	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ uspace/lib/usbvirt/src/ipc_dev.c	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -38,5 +38,4 @@
 #include <assert.h>
 #include <async.h>
-#include <devman.h>
 #include <usbvirt/device.h>
 #include <usbvirt/ipc.h>
Index: uspace/lib/usbvirt/src/ipc_hc.c
===================================================================
--- uspace/lib/usbvirt/src/ipc_hc.c	(revision 063ae7061e8d9afc7544f3cfa1e0c2b6d4342952)
+++ uspace/lib/usbvirt/src/ipc_hc.c	(revision fb8dcb4f762a0caef5c61ef0af0a62df56143c7d)
@@ -38,5 +38,4 @@
 #include <assert.h>
 #include <async.h>
-#include <devman.h>
 #include <usbvirt/device.h>
 #include <usbvirt/ipc.h>
