Index: uspace/lib/libc/include/ipc/serial_ctl.h
===================================================================
--- uspace/lib/libc/include/ipc/serial_ctl.h	(revision f4ef3c2d00beac7711a88e05770f36ab0bc9411b)
+++ uspace/lib/libc/include/ipc/serial_ctl.h	(revision f4ef3c2d00beac7711a88e05770f36ab0bc9411b)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBC_IPC_SERIAL_CTL_H_
+#define LIBC_IPC_SERIAL_CTL_H_
+
+#include <ipc/dev_iface.h>
+
+typedef enum {	
+	SERIAL_SET_BAUD_RATE = DEV_FIRST_CUSTOM_METHOD,	
+	SERIAL_SET_PARITY,
+	SERIAL_SET_STOP_BITS
+} serial_ctl_t;
+
+
+#endif
Index: uspace/srv/drivers/serial/serial.c
===================================================================
--- uspace/srv/drivers/serial/serial.c	(revision 08d9525a7da7649306a1aad8a472a5b2c7c3f056)
+++ uspace/srv/drivers/serial/serial.c	(revision f4ef3c2d00beac7711a88e05770f36ab0bc9411b)
@@ -59,4 +59,5 @@
 #include <ipc/devman.h>
 #include <device/hw_res.h>
+#include <ipc/serial_ctl.h>
 
 #include "cyclic_buffer.h"
@@ -65,4 +66,5 @@
 
 #define REG_COUNT 7
+#define MAX_BAUD_RATE 115200
 
 typedef struct serial_dev_data {
@@ -307,4 +309,15 @@
 }
 
+static inline void serial_port_interrupts_enable(ioport8_t *port)
+{	
+	pio_write_8(port + 1 , 0x01);   // Interrupt when data received
+	pio_write_8(port + 4, 0x0B);	
+}
+
+static inline void serial_port_interrupts_disable(ioport8_t *port)
+{
+	pio_write_8(port + 1, 0x00);    // Disable all interrupts
+}
+
 static int serial_interrupt_enable(device_t *dev)
 {
@@ -318,10 +331,47 @@
 	
 	// enable interrupt on the serial port
-	pio_write_8(data->port + 1 , 0x01);   // Interrupt when data received
-	pio_write_8(data->port + 4, 0x0B);	
+	serial_port_interrupts_enable(data->port);
 	
 	return EOK;
 }
 
+static int serial_port_set_baud_rate(ioport8_t *port, unsigned int baud_rate)
+{
+	uint16_t divisor;
+	uint8_t div_low, div_high;
+	
+	if (50 > baud_rate || 0 != MAX_BAUD_RATE % baud_rate) {
+		return EINVAL; 
+	}
+	
+	divisor = MAX_BAUD_RATE / baud_rate;
+	div_low = (uint8_t)divisor;
+	div_high = (uint8_t)(divisor >> 8);	
+	
+	pio_write_8(port + 3, 0x80);    // Enable DLAB (set baud rate divisor)
+	
+	pio_write_8(port + 0, div_low);    // Set divisor low byte
+	pio_write_8(port + 1, div_high);    // Set divisor high byte
+	
+	pio_write_8(port + 3, pio_read_8(port + 3) & (~0x80));    // Clear DLAB	
+	
+	return EOK;		
+}
+
+static int serial_set_baud_rate(device_t *dev, unsigned int baud_rate) 
+{
+	serial_dev_data_t *data = (serial_dev_data_t *)dev->driver_data;
+	ioport8_t *port = data->port;
+	int ret;
+	
+	fibril_mutex_lock(&data->mutex);	
+	serial_port_interrupts_disable(port);    // Disable all interrupts
+	ret = serial_port_set_baud_rate(port, baud_rate);
+	serial_port_interrupts_enable(port);
+	fibril_mutex_unlock(&data->mutex);	
+	
+	return ret;	
+}
+
 static void serial_initialize_port(device_t *dev)
 {
@@ -329,8 +379,6 @@
 	ioport8_t *port = data->port;
 	
-	pio_write_8(port + 1, 0x00);    // Disable all interrupts
-	pio_write_8(port + 3, 0x80);    // Enable DLAB (set baud rate divisor)
-	pio_write_8(port + 0, 0x60);    // Set divisor to 96 (lo byte) 1200 baud
-	pio_write_8(port + 1, 0x00);    //                   (hi byte)
+	serial_port_interrupts_disable(port);     // Disable all interrupts
+	serial_port_set_baud_rate(port, 1200);
 	pio_write_8(port + 3, 0x07);    // 8 bits, no parity, two stop bits
 	pio_write_8(port + 2, 0xC7);    // Enable FIFO, clear them, with 14-byte threshold
@@ -479,4 +527,29 @@
 }
 
+/** Default handler for client requests which are not handled by the standard interfaces.
+ * 
+ * Configure the parameters of the serial communication.
+ */
+static void serial_default_handler(device_t *dev, ipc_callid_t callid, ipc_call_t *call)
+{
+	ipcarg_t method = IPC_GET_METHOD(*call);
+	int ret;
+	
+	switch(method) {
+		case SERIAL_SET_BAUD_RATE:
+			ret = serial_set_baud_rate(dev, IPC_GET_ARG1(*call));
+			ipc_answer_0(callid, ret);
+			break;
+		case SERIAL_SET_PARITY:
+			// TODO
+			break;
+		case SERIAL_SET_STOP_BITS:
+			// TODO
+			break;
+		default:
+			ipc_answer_0(callid, ENOTSUP);		
+	}
+}
+
 /** Initialize the serial port driver.
  * 
@@ -492,4 +565,5 @@
 	
 	serial_dev_class.interfaces[CHAR_DEV_IFACE] = &serial_char_iface;
+	serial_dev_class.default_handler = &serial_default_handler;
 }
 
