Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision 4637c72da21ae63d19637654eb772d0cdae5841a)
+++ uspace/srv/fs/fat/fat_ops.c	(revision 17ccb9d746a0d3db19fc24efcc8f0cfa36479cdf)
@@ -1527,6 +1527,25 @@
 void fat_sync(ipc_callid_t rid, ipc_call_t *request)
 {
-	/* Dummy implementation */
-	ipc_answer_0(rid, EOK);
+	dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
+	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
+	
+	fs_node_t *fn;
+	int rc = fat_node_get(&fn, dev_handle, index);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	if (!fn) {
+		ipc_answer_0(rid, ENOENT);
+		return;
+	}
+	
+	fat_node_t *nodep = FAT_NODE(fn);
+	
+	nodep->dirty = true;
+	rc = fat_node_sync(nodep);
+	
+	fat_node_put(fn);
+	ipc_answer_0(rid, rc);
 }
 
Index: uspace/srv/fs/tmpfs/tmpfs_ops.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision 4637c72da21ae63d19637654eb772d0cdae5841a)
+++ uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision 17ccb9d746a0d3db19fc24efcc8f0cfa36479cdf)
@@ -736,5 +736,8 @@
 void tmpfs_sync(ipc_callid_t rid, ipc_call_t *request)
 {
-	/* Dummy implementation */
+	/*
+	 * TMPFS keeps its data structures always consistent,
+	 * thus the sync operation is a no-op.
+	 */
 	ipc_answer_0(rid, EOK);
 }
Index: uspace/srv/hid/kbd/Makefile
===================================================================
--- uspace/srv/hid/kbd/Makefile	(revision 4637c72da21ae63d19637654eb772d0cdae5841a)
+++ uspace/srv/hid/kbd/Makefile	(revision 17ccb9d746a0d3db19fc24efcc8f0cfa36479cdf)
@@ -60,6 +60,6 @@
 	ifeq ($(MACHINE),gta02)
 		SOURCES += \
-			port/dummy.c \
-			ctl/pc.c
+			port/chardev.c \
+			ctl/stty.c
 	endif
 	ifeq ($(MACHINE),testarm)
Index: uspace/srv/hid/kbd/port/chardev.c
===================================================================
--- uspace/srv/hid/kbd/port/chardev.c	(revision 4637c72da21ae63d19637654eb772d0cdae5841a)
+++ uspace/srv/hid/kbd/port/chardev.c	(revision 17ccb9d746a0d3db19fc24efcc8f0cfa36479cdf)
@@ -41,4 +41,5 @@
 #include <kbd.h>
 #include <vfs/vfs.h>
+#include <sys/stat.h>
 #include <fcntl.h>
 #include <errno.h>
@@ -50,21 +51,41 @@
 #define NAME "kbd"
 
+/** List of devices to try connecting to. */
+static const char *in_devs[] = {
+	"/dev/char/ps2a",
+	"/dev/char/s3c24ser"
+};
+
+static const int num_devs = sizeof(in_devs) / sizeof(in_devs[0]);
+
 int kbd_port_init(void)
 {
-	const char *input = "/dev/char/ps2a";
 	int input_fd;
+	int i;
 
-	printf(NAME ": open %s\n", input);
+	input_fd = -1;
+	for (i = 0; i < num_devs; i++) {
+		struct stat s;
 
-	input_fd = open(input, O_RDONLY);
+		if (stat(in_devs[i], &s) == EOK)
+			break;
+	}
+
+	if (i >= num_devs) {
+		printf(NAME ": Could not find any suitable input device.\n");
+		return -1;
+	}
+
+	input_fd = open(in_devs[i], O_RDONLY);
 	if (input_fd < 0) {
-		printf(NAME ": Failed opening %s (%d)\n", input, input_fd);
-		return false;
+		printf(NAME ": failed opening device %s (%d).\n", in_devs[i],
+		    input_fd);
+		return -1;
 	}
 
 	dev_phone = fd_phone(input_fd);
 	if (dev_phone < 0) {
-		printf(NAME ": Failed to connect to device\n");
-		return false;
+		printf(NAME ": Failed connecting to device\n");
+		return -1;
 	}
 
@@ -73,5 +94,5 @@
 	if (ipc_connect_to_me(dev_phone, 0, 0, 0, &phonehash) != 0) {
 		printf(NAME ": Failed to create callback from device\n");
-		return false;
+		return -1;
 	}
 
Index: uspace/srv/hid/kbd/port/i8042.h
===================================================================
--- uspace/srv/hid/kbd/port/i8042.h	(revision 4637c72da21ae63d19637654eb772d0cdae5841a)
+++ 	(revision )
@@ -1,55 +1,0 @@
-/*
- * Copyright (c) 2006 Josef Cejka
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup kbd_port
- * @ingroup  kbd
- * @{
- */
-
-/** @file
- * @brief i8042 port driver.
- */
-
-#ifndef KBD_PORT_i8042_H_
-#define KBD_PORT_i8042_H_
-
-#include <libarch/ddi.h>
-#include <libarch/types.h>
-
-struct i8042 {
-	ioport8_t data;
-	uint8_t pad[3];
-	ioport8_t status;
-} __attribute__ ((packed));
-typedef struct i8042 i8042_t;
-
-#endif
-
-/**
- * @}
- */ 
Index: uspace/srv/hw/char/s3c24xx_uart/Makefile
===================================================================
--- uspace/srv/hw/char/s3c24xx_uart/Makefile	(revision 17ccb9d746a0d3db19fc24efcc8f0cfa36479cdf)
+++ uspace/srv/hw/char/s3c24xx_uart/Makefile	(revision 17ccb9d746a0d3db19fc24efcc8f0cfa36479cdf)
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+USPACE_PREFIX = ../../../..
+
+# Need to use short name because of FAT 8+3 limit
+BINARY = s3c24ser
+
+SOURCES = \
+	s3c24xx_uart.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c
===================================================================
--- uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision 17ccb9d746a0d3db19fc24efcc8f0cfa36479cdf)
+++ uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision 17ccb9d746a0d3db19fc24efcc8f0cfa36479cdf)
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup driver_serial
+ * @{
+ */
+/**
+ * @file
+ * @brief Samsung S3C24xx on-chip UART driver.
+ *
+ * This UART is present on the Samsung S3C24xx CPU (on the gta02 platform).
+ */
+
+#include <ddi.h>
+#include <libarch/ddi.h>
+#include <devmap.h>
+#include <ipc/ipc.h>
+#include <ipc/char.h>
+#include <async.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sysinfo.h>
+#include <errno.h>
+
+#include "s3c24xx_uart.h"
+
+#define NAME "s3c24ser"
+#define NAMESPACE "char"
+
+/* Bits in UTRSTAT register */
+#define S3C24XX_UTRSTAT_TX_EMPTY	0x4
+#define S3C24XX_UTRSTAT_RDATA		0x1
+
+/* Bits in UFSTAT register */
+#define S3C24XX_UFSTAT_TX_FULL		0x4000
+#define S3C24XX_UFSTAT_RX_FULL		0x0040
+#define S3C24XX_UFSTAT_RX_COUNT		0x002f
+
+static irq_cmd_t uart_irq_cmds[] = {
+	{
+		.cmd = CMD_ACCEPT
+	}
+};
+
+static irq_code_t uart_irq_code = {
+	sizeof(uart_irq_cmds) / sizeof(irq_cmd_t),
+	uart_irq_cmds
+};
+
+/** S3C24xx UART instance structure */
+static s3c24xx_uart_t *uart;
+
+static void s3c24xx_uart_connection(ipc_callid_t iid, ipc_call_t *icall);
+static void s3c24xx_uart_irq_handler(ipc_callid_t iid, ipc_call_t *call);
+static int s3c24xx_uart_init(s3c24xx_uart_t *uart);
+static void s3c24xx_uart_sendb(s3c24xx_uart_t *uart, uint8_t byte);
+
+int main(int argc, char *argv[])
+{
+	int rc;
+
+	printf(NAME ": S3C24xx on-chip UART driver\n");
+
+	rc = devmap_driver_register(NAME, s3c24xx_uart_connection);
+	if (rc < 0) {
+		printf(NAME ": Unable to register driver.\n");
+		return -1;
+	}
+
+	uart = malloc(sizeof(s3c24xx_uart_t));
+	if (uart == NULL)
+		return -1;
+
+	if (s3c24xx_uart_init(uart) != EOK)
+		return -1;
+
+	rc = devmap_device_register(NAMESPACE "/" NAME, &uart->dev_handle);
+	if (rc != EOK) {
+		devmap_hangup_phone(DEVMAP_DRIVER);
+		printf(NAME ": Unable to register device %s.\n");
+		return -1;
+	}
+
+	printf(NAME ": Registered device %s.\n", NAMESPACE "/" NAME);
+
+	printf(NAME ": Accepting connections\n");
+	task_retval(0);
+	async_manager();
+
+	/* Not reached */
+	return 0;
+}
+
+/** Character device connection handler. */
+static void s3c24xx_uart_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipc_callid_t callid;
+	ipc_call_t call;
+	ipcarg_t method;
+	int retval;
+
+	/* Answer the IPC_M_CONNECT_ME_TO call. */
+	ipc_answer_0(iid, EOK);
+
+	while (1) {
+		callid = async_get_call(&call);
+		method = IPC_GET_METHOD(call);
+		switch (method) {
+		case IPC_M_PHONE_HUNGUP:
+			/* The other side has hung up. */
+			ipc_answer_0(callid, EOK);
+			return;
+		case IPC_M_CONNECT_TO_ME:
+			printf(NAME ": creating callback connection\n");
+			uart->client_phone = IPC_GET_ARG5(call);
+			retval = 0;
+			break;
+		case CHAR_WRITE_BYTE:
+			printf(NAME ": write %d to device\n",
+			    IPC_GET_ARG1(call));
+			s3c24xx_uart_sendb(uart, (uint8_t) IPC_GET_ARG1(call));
+			retval = 0;
+			break;
+		default:
+			retval = EINVAL;
+			break;
+		}
+		ipc_answer_0(callid, retval);
+	}
+}
+
+static void s3c24xx_uart_irq_handler(ipc_callid_t iid, ipc_call_t *call)
+{
+	(void) iid; (void) call;
+
+	while ((pio_read_32(&uart->io->ufstat) & S3C24XX_UFSTAT_RX_COUNT) != 0) {
+		uint32_t data = pio_read_32(&uart->io->urxh) & 0xff;
+		uint32_t status = pio_read_32(&uart->io->uerstat);
+
+		if (uart->client_phone != -1) {
+			async_msg_1(uart->client_phone, CHAR_NOTIF_BYTE,
+			    data);
+		}
+
+		if (status & 0x0f)
+			printf(NAME ": Error status 0x%x\n", status);
+	}
+}
+
+/** Initialize S3C24xx on-chip UART. */
+static int s3c24xx_uart_init(s3c24xx_uart_t *uart)
+{
+	void *vaddr;
+	sysarg_t inr;
+
+	if (sysinfo_get_value("s3c24xx_uart.address.physical",
+	    &uart->paddr) != EOK)
+		return -1;
+
+	if (pio_enable((void *) uart->paddr, sizeof(s3c24xx_uart_io_t),
+	    &vaddr) != 0)
+		return -1;
+
+	if (sysinfo_get_value("s3c24xx_uart.inr", &inr) != EOK)
+		return -1;
+
+	uart->io = vaddr;
+	uart->client_phone = -1;
+
+	printf(NAME ": device at physical address 0x%x, inr %d.\n",
+	    uart->paddr, inr);
+
+	async_set_interrupt_received(s3c24xx_uart_irq_handler);
+
+	ipc_register_irq(inr, device_assign_devno(), 0, &uart_irq_code);
+
+	/* Enable FIFO, Tx trigger level: empty, Rx trigger level: 1 byte. */
+	pio_write_32(&uart->io->ufcon, 0x01);
+
+	/* Set RX interrupt to pulse mode */
+	pio_write_32(&uart->io->ucon,
+	    pio_read_32(&uart->io->ucon) & ~(1 << 8));
+
+	return EOK;
+}
+
+/** Send a byte to the UART. */
+static void s3c24xx_uart_sendb(s3c24xx_uart_t *uart, uint8_t byte)
+{
+	/* Wait for space becoming available in Tx FIFO. */
+	while ((pio_read_32(&uart->io->ufstat) & S3C24XX_UFSTAT_TX_FULL) != 0)
+		;
+
+	pio_write_32(&uart->io->utxh, byte);
+}
+
+/** @}
+ */
Index: uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.h
===================================================================
--- uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.h	(revision 17ccb9d746a0d3db19fc24efcc8f0cfa36479cdf)
+++ uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.h	(revision 17ccb9d746a0d3db19fc24efcc8f0cfa36479cdf)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief Samsung S3C24xx on-chip UART driver.
+ */
+
+#ifndef S3C24XX_UART_H_
+#define S3C24XX_UART_H_
+
+#include <sys/types.h>
+
+/** S3C24xx UART I/O */
+typedef struct {
+	uint32_t ulcon;
+	uint32_t ucon;
+	uint32_t ufcon;
+	uint32_t umcon;
+
+	uint32_t utrstat;
+	uint32_t uerstat;
+	uint32_t ufstat;
+	uint32_t umstat;
+
+	uint32_t utxh;
+	uint32_t urxh;
+
+	uint32_t ubrdiv;
+} s3c24xx_uart_io_t;
+
+/** S3C24xx UART instance */
+typedef struct {
+	/** Physical device address */
+	uintptr_t paddr;
+
+	/** Device I/O structure */
+	s3c24xx_uart_io_t *io;
+
+	/** Callback phone to the client */
+	int client_phone;
+
+	/** Device handle */
+	dev_handle_t dev_handle;
+} s3c24xx_uart_t;
+
+#endif
+
+/** @}
+ */
