Index: uspace/drv/char/ns8250/ns8250.c
===================================================================
--- uspace/drv/char/ns8250/ns8250.c	(revision 84c8971832eb7276829ce3edd6eefa6fc11a0b72)
+++ uspace/drv/char/ns8250/ns8250.c	(revision aaa77ba0f2326ec53c9ae75e8d4143dcad05a34e)
@@ -74,4 +74,56 @@
 #define DLAB_MASK (1 << 7)
 
+/** Interrupt Enable Register definition. */
+#define	NS8250_IER_RXREADY	(1 << 0)
+#define	NS8250_IER_THRE		(1 << 1)
+#define	NS8250_IER_RXSTATUS	(1 << 2)
+#define	NS8250_IER_MODEM_STATUS	(1 << 3)
+
+/** Interrupt ID Register definition. */
+#define	NS8250_IID_ACTIVE	(1 << 0)
+
+/** FIFO Control Register definition. */
+#define	NS8250_FCR_FIFOENABLE	(1 << 0)
+#define	NS8250_FCR_RXFIFORESET	(1 << 1)
+#define	NS8250_FCR_TXFIFORESET	(1 << 2)
+#define	NS8250_FCR_DMAMODE	(1 << 3)
+#define	NS8250_FCR_RXTRIGGERLOW	(1 << 6)
+#define	NS8250_FCR_RXTRIGGERHI	(1 << 7)
+
+/** Line Control Register definition. */
+#define	NS8250_LCR_STOPBITS	(1 << 2)
+#define	NS8250_LCR_PARITY	(1 << 3)
+#define	NS8250_LCR_SENDBREAK	(1 << 6)
+#define	NS8250_LCR_DLAB		(1 << 7)
+
+/** Modem Control Register definition. */
+#define	NS8250_MCR_DTR		(1 << 0)
+#define	NS8250_MCR_RTS		(1 << 1)
+#define	NS8250_MCR_OUT1		(1 << 2)
+#define	NS8250_MCR_OUT2		(1 << 3)
+#define	NS8250_MCR_LOOPBACK	(1 << 4)
+#define	NS8250_MCR_ALL		(0x1f)
+
+/** Line Status Register definition. */
+#define	NS8250_LSR_RXREADY	(1 << 0)
+#define	NS8250_LSR_OE		(1 << 1)
+#define	NS8250_LSR_PE		(1 << 2)
+#define	NS8250_LSR_FE		(1 << 3)
+#define	NS8250_LSR_BREAK	(1 << 4)
+#define	NS8250_LSR_THRE		(1 << 5)
+#define	NS8250_LSR_TSE		(1 << 6)
+
+/** Modem Status Register definition. */
+#define	NS8250_MSR_DELTACTS	(1 << 0)
+#define	NS8250_MSR_DELTADSR	(1 << 1)
+#define	NS8250_MSR_RITRAILING	(1 << 2)
+#define	NS8250_MSR_DELTADCD	(1 << 3)
+#define	NS8250_MSR_CTS		(1 << 4)
+#define	NS8250_MSR_DSR		(1 << 5)
+#define	NS8250_MSR_RI		(1 << 6)
+#define	NS8250_MSR_DCD		(1 << 7)
+#define	NS8250_MSR_SIGNALS	(NS8250_MSR_CTS | NS8250_MSR_DSR \
+    | NS8250_MSR_RI | NS8250_MSR_DCD)
+
 /** Obtain soft-state structure from function node */
 #define NS8250(fnode) ((ns8250_t *) ((fnode)->dev->driver_data))
@@ -96,4 +148,15 @@
 } stop_bit_t;
 
+/** 8250 UART registers layout. */
+typedef struct {
+	ioport8_t data;		/**< Data register. */
+	ioport8_t ier;		/**< Interrupt Enable Reg. */
+	ioport8_t iid;		/**< Interrupt ID Reg. */
+	ioport8_t lcr;		/**< Line Control Reg. */
+	ioport8_t mcr;		/**< Modem Control Reg. */
+	ioport8_t lsr;		/**< Line Status Reg. */
+	ioport8_t msr;		/**< Modem Status Reg. */
+} ns8250_regs_t;
+
 /** The driver data for the serial port devices. */
 typedef struct ns8250 {
@@ -102,4 +165,6 @@
 	/** DDF function node */
 	ddf_fun_t *fun;
+	/** I/O registers **/
+	ns8250_regs_t *regs;
 	/** Is there any client conntected to the device? */
 	bool client_connected;
@@ -124,7 +189,7 @@
  *			otherwise.
  */
-static bool ns8250_received(ioport8_t *port)
-{
-	return (pio_read_8(port + 5) & 1) != 0;
+static bool ns8250_received(ns8250_regs_t *regs)
+{
+	return (pio_read_8(&regs->lsr) & NS8250_LSR_RXREADY) != 0;
 }
 
@@ -134,7 +199,7 @@
  * @return		The data read.
  */
-static uint8_t ns8250_read_8(ioport8_t *port)
-{
-	return pio_read_8(port);
+static uint8_t ns8250_read_8(ns8250_regs_t *regs)
+{
+	return pio_read_8(&regs->data);
 }
 
@@ -143,7 +208,7 @@
  * @param port		The base address of the serial port device's ports.
  */
-static bool is_transmit_empty(ioport8_t *port)
-{
-	return (pio_read_8(port + 5) & 0x20) != 0;
+static bool is_transmit_empty(ns8250_regs_t *regs)
+{
+	return (pio_read_8(&regs->lsr) & NS8250_LSR_THRE) != 0;
 }
 
@@ -153,10 +218,10 @@
  * @param c		The character to be written to the serial port device.
  */
-static void ns8250_write_8(ioport8_t *port, uint8_t c)
-{
-	while (!is_transmit_empty(port))
+static void ns8250_write_8(ns8250_regs_t *regs, uint8_t c)
+{
+	while (!is_transmit_empty(regs))
 		;
 	
-	pio_write_8(port, c);
+	pio_write_8(&regs->data, c);
 }
 
@@ -193,5 +258,5 @@
 {
 	fibril_mutex_lock(&ns->mutex);
-	ns8250_write_8(ns->port, c);
+	ns8250_write_8(ns->regs, c);
 	fibril_mutex_unlock(&ns->mutex);
 }
@@ -266,4 +331,6 @@
 		return false;
 	}
+
+	ns->regs = (ns8250_regs_t *)ns->port;
 	
 	return true;
@@ -279,19 +346,19 @@
 	ddf_msg(LVL_DEBUG, "ns8250_dev_probe %s", ns->dev->name);
 	
-	ioport8_t *port_addr = ns->port;
 	bool res = true;
 	uint8_t olddata;
 	
-	olddata = pio_read_8(port_addr + 4);
-	
-	pio_write_8(port_addr + 4, 0x10);
-	if (pio_read_8(port_addr + 6) & 0xf0)
+	olddata = pio_read_8(&ns->regs->mcr);
+	
+	pio_write_8(&ns->regs->mcr, NS8250_MCR_LOOPBACK);
+	if (pio_read_8(&ns->regs->msr) & NS8250_MSR_SIGNALS)
 		res = false;
 	
-	pio_write_8(port_addr + 4, 0x1f);
-	if ((pio_read_8(port_addr + 6) & 0xf0) != 0xf0)
+	pio_write_8(&ns->regs->mcr, NS8250_MCR_ALL);
+	if ((pio_read_8(&ns->regs->msr) & NS8250_MSR_SIGNALS) 
+	    != NS8250_MSR_SIGNALS)
 		res = false;
 	
-	pio_write_8(port_addr + 4, olddata);
+	pio_write_8(&ns->regs->mcr, olddata);
 	
 	if (!res) {
@@ -390,8 +457,10 @@
  * @param port		The base address of the serial port device's ports.
  */
-static inline void ns8250_port_interrupts_enable(ioport8_t *port)
-{
-	pio_write_8(port + 1, 0x1);	/* Interrupt when data received. */
-	pio_write_8(port + 4, 0xB);
+static inline void ns8250_port_interrupts_enable(ns8250_regs_t *regs)
+{
+	/* Interrupt when data received. */
+	pio_write_8(&regs->ier, NS8250_IER_RXREADY);
+	pio_write_8(&regs->mcr, NS8250_MCR_DTR | NS8250_MCR_RTS 
+	    | NS8250_MCR_OUT2);
 }
 
@@ -400,7 +469,7 @@
  * @param port		The base address of the serial port device's ports
  */
-static inline void ns8250_port_interrupts_disable(ioport8_t *port)
-{
-	pio_write_8(port + 1, 0x0);	/* Disable all interrupts. */
+static inline void ns8250_port_interrupts_disable(ns8250_regs_t *regs)
+{
+	pio_write_8(&regs->ier, 0x0);	/* Disable all interrupts. */
 }
 
@@ -431,5 +500,5 @@
 
 	/* Enable interrupt on the serial port. */
-	ns8250_port_interrupts_enable(ns->port);
+	ns8250_port_interrupts_enable(ns->regs);
 	
 	return EOK;
@@ -443,8 +512,8 @@
  * @param port		The base address of the serial port device's ports.
  */
-static inline void enable_dlab(ioport8_t *port)
-{
-	uint8_t val = pio_read_8(port + 3);
-	pio_write_8(port + 3, val | DLAB_MASK);
+static inline void enable_dlab(ns8250_regs_t *regs)
+{
+	uint8_t val = pio_read_8(&regs->lcr);
+	pio_write_8(&regs->lcr, val | NS8250_LCR_DLAB);
 }
 
@@ -453,8 +522,8 @@
  * @param port		The base address of the serial port device's ports.
  */
-static inline void clear_dlab(ioport8_t *port)
-{
-	uint8_t val = pio_read_8(port + 3);
-	pio_write_8(port + 3, val & (~DLAB_MASK));
+static inline void clear_dlab(ns8250_regs_t *regs)
+{
+	uint8_t val = pio_read_8(&regs->lcr);
+	pio_write_8(&regs->lcr, val & (~NS8250_LCR_DLAB));
 }
 
@@ -466,5 +535,5 @@
  *			if the specified baud_rate is not valid).
  */
-static int ns8250_port_set_baud_rate(ioport8_t *port, unsigned int baud_rate)
+static int ns8250_port_set_baud_rate(ns8250_regs_t *regs, unsigned int baud_rate)
 {
 	uint16_t divisor;
@@ -482,12 +551,12 @@
 	
 	/* Enable DLAB to be able to access baud rate divisor. */
-	enable_dlab(port);
+	enable_dlab(regs);
 	
 	/* Set divisor low byte. */
-	pio_write_8(port + 0, div_low);
+	pio_write_8(&regs->data, div_low);
 	/* Set divisor high byte. */
-	pio_write_8(port + 1, div_high);
-	
-	clear_dlab(port);
+	pio_write_8(&regs->ier, div_high);
+	
+	clear_dlab(regs);
 	
 	return EOK;
@@ -499,5 +568,5 @@
  * @param baud_rate	The ouput parameter to which the baud rate is stored.
  */
-static unsigned int ns8250_port_get_baud_rate(ioport8_t *port)
+static unsigned int ns8250_port_get_baud_rate(ns8250_regs_t *regs)
 {
 	uint16_t divisor;
@@ -505,12 +574,12 @@
 	
 	/* Enable DLAB to be able to access baud rate divisor. */
-	enable_dlab(port);
+	enable_dlab(regs);
 	
 	/* Get divisor low byte. */
-	div_low = pio_read_8(port + 0);
+	div_low = pio_read_8(&regs->data);
 	/* Get divisor high byte. */
-	div_high = pio_read_8(port + 1);
-	
-	clear_dlab(port);
+	div_high = pio_read_8(&regs->ier);
+	
+	clear_dlab(regs);
 	
 	divisor = (div_high << 8) | div_low;
@@ -525,11 +594,11 @@
  * @param stop_bits	The number of stop bits used (one or two).
  */
-static void ns8250_port_get_com_props(ioport8_t *port, unsigned int *parity,
+static void ns8250_port_get_com_props(ns8250_regs_t *regs, unsigned int *parity,
     unsigned int *word_length, unsigned int *stop_bits)
 {
 	uint8_t val;
 	
-	val = pio_read_8(port + 3);
-	*parity = ((val >> 3) & 7);
+	val = pio_read_8(&regs->lcr);
+	*parity = ((val >> NS8250_LCR_PARITY) & 7);
 	
 	switch (val & 3) {
@@ -548,5 +617,5 @@
 	}
 	
-	if ((val >> 2) & 1)
+	if ((val >> NS8250_LCR_STOPBITS) & 1)
 		*stop_bits = 2;
 	else
@@ -562,5 +631,5 @@
  *			is invalid.
  */
-static int ns8250_port_set_com_props(ioport8_t *port, unsigned int parity,
+static int ns8250_port_set_com_props(ns8250_regs_t *regs, unsigned int parity,
     unsigned int word_length, unsigned int stop_bits)
 {
@@ -586,8 +655,8 @@
 	switch (stop_bits) {
 	case 1:
-		val |= ONE_STOP_BIT << 2;
+		val |= ONE_STOP_BIT << NS8250_LCR_STOPBITS;
 		break;
 	case 2:
-		val |= TWO_STOP_BITS << 2;
+		val |= TWO_STOP_BITS << NS8250_LCR_STOPBITS;
 		break;
 	default:
@@ -601,5 +670,5 @@
 	case SERIAL_MARK_PARITY:
 	case SERIAL_SPACE_PARITY:
-		val |= parity << 3;
+		val |= parity << NS8250_LCR_PARITY;
 		break;
 	default:
@@ -607,5 +676,5 @@
 	}
 	
-	pio_write_8(port + 3, val);
+	pio_write_8(&regs->lcr, val);
 	
 	return EOK;
@@ -620,19 +689,20 @@
 static void ns8250_initialize_port(ns8250_t *ns)
 {
-	ioport8_t *port = ns->port;
-	
 	/* Disable interrupts. */
-	ns8250_port_interrupts_disable(port);
+	ns8250_port_interrupts_disable(ns->regs);
 	/* Set baud rate. */
-	ns8250_port_set_baud_rate(port, 38400);
+	ns8250_port_set_baud_rate(ns->regs, 38400);
 	/* 8 bits, no parity, two stop bits. */
-	ns8250_port_set_com_props(port, SERIAL_NO_PARITY, 8, 2);
+	ns8250_port_set_com_props(ns->regs, SERIAL_NO_PARITY, 8, 2);
 	/* Enable FIFO, clear them, with 14-byte threshold. */
-	pio_write_8(port + 2, 0xC7);
+	pio_write_8(&ns->regs->iid, NS8250_FCR_FIFOENABLE
+	    | NS8250_FCR_RXFIFORESET | NS8250_FCR_TXFIFORESET 
+	    | NS8250_FCR_RXTRIGGERLOW | NS8250_FCR_RXTRIGGERHI);
 	/*
 	 * RTS/DSR set (Request to Send and Data Terminal Ready lines enabled),
 	 * Aux Output2 set - needed for interrupts.
 	 */
-	pio_write_8(port + 4, 0x0B);
+	pio_write_8(&ns->regs->mcr, NS8250_MCR_DTR | NS8250_MCR_RTS
+	    | NS8250_MCR_OUT2);
 }
 
@@ -644,9 +714,9 @@
 {
 	/* Disable FIFO */
-	pio_write_8(ns->port + 2, 0x00);
+	pio_write_8(&ns->regs->iid, 0x00);
 	/* Disable DTR, RTS, OUT1, OUT2 (int. enable) */
-	pio_write_8(ns->port + 4, 0x00);
+	pio_write_8(&ns->regs->mcr, 0x00);
 	/* Disable all interrupts from the port */
-	ns8250_port_interrupts_disable(ns->port);
+	ns8250_port_interrupts_disable(ns->regs);
 }
 
@@ -658,5 +728,5 @@
 static void ns8250_read_from_device(ns8250_t *ns)
 {
-	ioport8_t *port = ns->port;
+	ns8250_regs_t *regs = ns->regs;
 	bool cont = true;
 	
@@ -664,7 +734,7 @@
 		fibril_mutex_lock(&ns->mutex);
 		
-		cont = ns8250_received(port);
+		cont = ns8250_received(regs);
 		if (cont) {
-			uint8_t val = ns8250_read_8(port);
+			uint8_t val = ns8250_read_8(regs);
 			
 			if (ns->client_connected) {
@@ -896,11 +966,11 @@
 {
 	ns8250_t *data = (ns8250_t *) dev->driver_data;
-	ioport8_t *port = data->port;
+	ns8250_regs_t *regs = data->regs;
 	
 	fibril_mutex_lock(&data->mutex);
-	ns8250_port_interrupts_disable(port);
-	*baud_rate = ns8250_port_get_baud_rate(port);
-	ns8250_port_get_com_props(port, parity, word_length, stop_bits);
-	ns8250_port_interrupts_enable(port);
+	ns8250_port_interrupts_disable(regs);
+	*baud_rate = ns8250_port_get_baud_rate(regs);
+	ns8250_port_get_com_props(regs, parity, word_length, stop_bits);
+	ns8250_port_interrupts_enable(regs);
 	fibril_mutex_unlock(&data->mutex);
 	
@@ -927,13 +997,13 @@
 	
 	ns8250_t *data = (ns8250_t *) dev->driver_data;
-	ioport8_t *port = data->port;
+	ns8250_regs_t *regs = data->regs;
 	int ret;
 	
 	fibril_mutex_lock(&data->mutex);
-	ns8250_port_interrupts_disable(port);
-	ret = ns8250_port_set_baud_rate(port, baud_rate);
+	ns8250_port_interrupts_disable(regs);
+	ret = ns8250_port_set_baud_rate(regs, baud_rate);
 	if (ret == EOK)
-		ret = ns8250_port_set_com_props(port, parity, word_length, stop_bits);
-	ns8250_port_interrupts_enable(port);
+		ret = ns8250_port_set_com_props(regs, parity, word_length, stop_bits);
+	ns8250_port_interrupts_enable(regs);
 	fibril_mutex_unlock(&data->mutex);
 	
