linux-serial.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 0/4] use kfifo instead of circ_buf
@ 2010-11-15 21:01 Bill Pemberton
  2010-11-15 21:01 ` [RFC PATCH 1/4] serial: " Bill Pemberton
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Bill Pemberton @ 2010-11-15 21:01 UTC (permalink / raw)
  To: linux-serial

This replaces the use of struct circ_buf with a kfifo in the serial
subsystem.  This was suggested by Alan Cox a while ago.  I've tested
the first patch, the second is compile tested only, and the last 2 are
not tested at all.



Bill Pemberton (4):
  serial: use kfifo instead of circ_buf
  serial: use kfifo instead of circ_buf in mrst_max3110
  serial: use kfifo instead of circ_buf in icom.c
  serial: use kfifo instead of circ_buf for SGI IOC controllers

 drivers/serial/8250.c         |   20 ++++++----
 drivers/serial/icom.c         |   26 ++++++--------
 drivers/serial/ioc3_serial.c  |   32 ++++++-----------
 drivers/serial/ioc4_serial.c  |   32 ++++++-----------
 drivers/serial/jsm/jsm_tty.c  |   26 +++++--------
 drivers/serial/mrst_max3110.c |   45 ++++++++++-------------
 drivers/serial/serial_core.c  |   78 +++++++++--------------------------------
 include/linux/serial_core.h   |    4 +-
 8 files changed, 94 insertions(+), 169 deletions(-)

-- 
1.7.3.2


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [RFC PATCH 1/4] serial: use kfifo instead of circ_buf
  2010-11-15 21:01 [RFC PATCH 0/4] use kfifo instead of circ_buf Bill Pemberton
@ 2010-11-15 21:01 ` Bill Pemberton
  2010-11-15 21:01 ` [RFC PATCH 2/4] serial: use kfifo instead of circ_buf in mrst_max3110 Bill Pemberton
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Bill Pemberton @ 2010-11-15 21:01 UTC (permalink / raw)
  To: linux-serial

The serial subsystem used struct circ_buf as provided by
circ_buf.h.  Use kfifo instead as suggested by Alan Cox.

Signed-off-by: Bill Pemberton <wfp5p@virginia.edu>
---
 drivers/serial/8250.c        |   20 ++++++----
 drivers/serial/jsm/jsm_tty.c |   26 +++++--------
 drivers/serial/serial_core.c |   78 +++++++++--------------------------------
 include/linux/serial_core.h  |    4 +-
 4 files changed, 41 insertions(+), 87 deletions(-)

diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 4d8e14b..69c68d2 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1461,8 +1461,10 @@ ignore_char:
 
 static void transmit_chars(struct uart_8250_port *up)
 {
-	struct circ_buf *xmit = &up->port.state->xmit;
+	struct kfifo *xmit_fifo = &up->port.state->xmit_fifo;
+	u8 iobuf;
 	int count;
+	int len;
 
 	if (up->port.x_char) {
 		serial_outp(up, UART_TX, up->port.x_char);
@@ -1474,26 +1476,28 @@ static void transmit_chars(struct uart_8250_port *up)
 		serial8250_stop_tx(&up->port);
 		return;
 	}
-	if (uart_circ_empty(xmit)) {
+	if (kfifo_is_empty(xmit_fifo)) {
 		__stop_tx(up);
 		return;
 	}
 
 	count = up->tx_loadsz;
 	do {
-		serial_out(up, UART_TX, xmit->buf[xmit->tail]);
-		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		len = kfifo_out(xmit_fifo, &iobuf, 1);
+		if (!len)
+			break;
+		serial_out(up, UART_TX, iobuf);
 		up->port.icount.tx++;
-		if (uart_circ_empty(xmit))
+		if (kfifo_is_empty(xmit_fifo))
 			break;
 	} while (--count > 0);
 
-	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+	if (kfifo_len(xmit_fifo) < WAKEUP_CHARS)
 		uart_write_wakeup(&up->port);
 
 	DEBUG_INTR("THRE...");
 
-	if (uart_circ_empty(xmit))
+	if (kfifo_is_empty(xmit_fifo))
 		__stop_tx(up);
 }
 
@@ -1762,7 +1766,7 @@ static void serial8250_backup_timeout(unsigned long data)
 	up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
 	spin_unlock_irqrestore(&up->port.lock, flags);
 	if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
-	    (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) &&
+	    (!kfifo_is_empty(&up->port.state->xmit_fifo ) || up->port.x_char) &&
 	    (lsr & UART_LSR_THRE)) {
 		iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
 		iir |= UART_IIR_THRI;
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 7a4a914..3eb54ee 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -846,12 +846,14 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch)
 int jsm_tty_write(struct uart_port *port)
 {
 	int bufcount;
+	int len;
+	u8 c;
 	int data_count = 0,data_count1 =0;
 	u16 head;
 	u16 tail;
 	u16 tmask;
 	u32 remain;
-	int temp_tail = port->state->xmit.tail;
+	struct kfifo *xmit_fifo = &port->state->xmit_fifo;
 	struct jsm_channel *channel = (struct jsm_channel *)port;
 
 	tmask = WQUEUEMASK;
@@ -867,13 +869,10 @@ int jsm_tty_write(struct uart_port *port)
 	data_count = 0;
 	if (bufcount >= remain) {
 		bufcount -= remain;
-		while ((port->state->xmit.head != temp_tail) &&
-		(data_count < remain)) {
-			channel->ch_wqueue[head++] =
-			port->state->xmit.buf[temp_tail];
-
-			temp_tail++;
-			temp_tail &= (UART_XMIT_SIZE - 1);
+		while ((!kfifo_is_empty(xmit_fifo)) &&
+		       (data_count < remain)) {
+			len = kfifo_out(xmit_fifo, &c, 1);
+			channel->ch_wqueue[head++] = c;
 			data_count++;
 		}
 		if (data_count == remain) head = 0;
@@ -882,20 +881,15 @@ int jsm_tty_write(struct uart_port *port)
 	data_count1 = 0;
 	if (bufcount > 0) {
 		remain = bufcount;
-		while ((port->state->xmit.head != temp_tail) &&
+		while ((!kfifo_is_empty(xmit_fifo)) &&
 			(data_count1 < remain)) {
-			channel->ch_wqueue[head++] =
-				port->state->xmit.buf[temp_tail];
-
-			temp_tail++;
-			temp_tail &= (UART_XMIT_SIZE - 1);
+			len = kfifo_out(xmit_fifo, &c, 1);
+			channel->ch_wqueue[head++] = c;
 			data_count1++;
 
 		}
 	}
 
-	port->state->xmit.tail = temp_tail;
-
 	data_count += data_count1;
 	if (data_count) {
 		head &= tmask;
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index c4ea146..5ef653b 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -94,7 +94,7 @@ static void __uart_start(struct tty_struct *tty)
 	struct uart_state *state = tty->driver_data;
 	struct uart_port *port = state->uart_port;
 
-	if (!uart_circ_empty(&state->xmit) && state->xmit.buf &&
+	if (!kfifo_is_empty(&state->xmit_fifo) &&
 	    !tty->stopped && !tty->hw_stopped)
 		port->ops->start_tx(port);
 }
@@ -141,7 +141,6 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, int in
 {
 	struct uart_port *uport = state->uart_port;
 	struct tty_port *port = &state->port;
-	unsigned long page;
 	int retval = 0;
 
 	if (port->flags & ASYNC_INITIALIZED)
@@ -161,14 +160,10 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, int in
 	 * Initialise and allocate the transmit and temporary
 	 * buffer.
 	 */
-	if (!state->xmit.buf) {
-		/* This is protected by the per port mutex */
-		page = get_zeroed_page(GFP_KERNEL);
-		if (!page)
+	if (!kfifo_initialized(&state->xmit_fifo)) {
+		retval = kfifo_alloc(&state->xmit_fifo, PAGE_SIZE, GFP_KERNEL);
+		if (retval)
 			return -ENOMEM;
-
-		state->xmit.buf = (unsigned char *) page;
-		uart_circ_clear(&state->xmit);
 	}
 
 	retval = uport->ops->startup(uport);
@@ -256,10 +251,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state)
 	/*
 	 * Free the transmit buffer page.
 	 */
-	if (state->xmit.buf) {
-		free_page((unsigned long)state->xmit.buf);
-		state->xmit.buf = NULL;
-	}
+	kfifo_free(&state->xmit_fifo);
 }
 
 /**
@@ -462,21 +454,13 @@ static void uart_change_speed(struct tty_struct *tty, struct uart_state *state,
 }
 
 static inline int __uart_put_char(struct uart_port *port,
-				struct circ_buf *circ, unsigned char c)
+				struct kfifo *fifo, unsigned char c)
 {
-	unsigned long flags;
 	int ret = 0;
 
-	if (!circ->buf)
+	if (!kfifo_initialized(fifo))
 		return 0;
-
-	spin_lock_irqsave(&port->lock, flags);
-	if (uart_circ_chars_free(circ) != 0) {
-		circ->buf[circ->head] = c;
-		circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1);
-		ret = 1;
-	}
-	spin_unlock_irqrestore(&port->lock, flags);
+	kfifo_in_locked(fifo, &c, sizeof(c), &port->lock);
 	return ret;
 }
 
@@ -484,7 +468,7 @@ static int uart_put_char(struct tty_struct *tty, unsigned char ch)
 {
 	struct uart_state *state = tty->driver_data;
 
-	return __uart_put_char(state->uart_port, &state->xmit, ch);
+	return __uart_put_char(state->uart_port, &state->xmit_fifo, ch);
 }
 
 static void uart_flush_chars(struct tty_struct *tty)
@@ -493,13 +477,11 @@ static void uart_flush_chars(struct tty_struct *tty)
 }
 
 static int uart_write(struct tty_struct *tty,
-					const unsigned char *buf, int count)
+		      const unsigned char *buf, int count)
 {
 	struct uart_state *state = tty->driver_data;
 	struct uart_port *port;
-	struct circ_buf *circ;
-	unsigned long flags;
-	int c, ret = 0;
+	int ret = 0;
 
 	/*
 	 * This means you called this function _after_ the port was
@@ -511,25 +493,11 @@ static int uart_write(struct tty_struct *tty,
 	}
 
 	port = state->uart_port;
-	circ = &state->xmit;
 
-	if (!circ->buf)
+	if (!kfifo_initialized(&state->xmit_fifo))
 		return 0;
 
-	spin_lock_irqsave(&port->lock, flags);
-	while (1) {
-		c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
-		if (count < c)
-			c = count;
-		if (c <= 0)
-			break;
-		memcpy(circ->buf + circ->head, buf, c);
-		circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
-		buf += c;
-		count -= c;
-		ret += c;
-	}
-	spin_unlock_irqrestore(&port->lock, flags);
+	ret = kfifo_in_locked(&state->xmit_fifo, buf, count, &port->lock);
 
 	uart_start(tty);
 	return ret;
@@ -538,25 +506,13 @@ static int uart_write(struct tty_struct *tty,
 static int uart_write_room(struct tty_struct *tty)
 {
 	struct uart_state *state = tty->driver_data;
-	unsigned long flags;
-	int ret;
-
-	spin_lock_irqsave(&state->uart_port->lock, flags);
-	ret = uart_circ_chars_free(&state->xmit);
-	spin_unlock_irqrestore(&state->uart_port->lock, flags);
-	return ret;
+	return PAGE_SIZE - kfifo_len(&state->xmit_fifo);
 }
 
 static int uart_chars_in_buffer(struct tty_struct *tty)
 {
 	struct uart_state *state = tty->driver_data;
-	unsigned long flags;
-	int ret;
-
-	spin_lock_irqsave(&state->uart_port->lock, flags);
-	ret = uart_circ_chars_pending(&state->xmit);
-	spin_unlock_irqrestore(&state->uart_port->lock, flags);
-	return ret;
+	return kfifo_len(&state->xmit_fifo);
 }
 
 static void uart_flush_buffer(struct tty_struct *tty)
@@ -578,7 +534,7 @@ static void uart_flush_buffer(struct tty_struct *tty)
 	pr_debug("uart_flush_buffer(%d) called\n", tty->index);
 
 	spin_lock_irqsave(&port->lock, flags);
-	uart_circ_clear(&state->xmit);
+	kfifo_reset(&state->xmit_fifo);
 	if (port->ops->flush_buffer)
 		port->ops->flush_buffer(port);
 	spin_unlock_irqrestore(&port->lock, flags);
@@ -899,7 +855,7 @@ static int uart_get_lsr_info(struct tty_struct *tty,
 	 * interrupt happens).
 	 */
 	if (uport->x_char ||
-	    ((uart_circ_chars_pending(&state->xmit) > 0) &&
+	    ((!kfifo_is_empty(&state->xmit_fifo)) &&
 	     !tty->stopped && !tty->hw_stopped))
 		result &= ~TIOCSER_TEMT;
 
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 41603d6..cf07aa7 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -206,7 +206,7 @@
 
 #include <linux/compiler.h>
 #include <linux/interrupt.h>
-#include <linux/circ_buf.h>
+#include <linux/kfifo.h>
 #include <linux/spinlock.h>
 #include <linux/sched.h>
 #include <linux/tty.h>
@@ -375,7 +375,7 @@ struct uart_state {
 	struct tty_port		port;
 
 	int			pm_state;
-	struct circ_buf		xmit;
+	struct kfifo		xmit_fifo;
 
 	struct tasklet_struct	tlet;
 	struct uart_port	*uart_port;
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [RFC PATCH 2/4] serial: use kfifo instead of circ_buf in mrst_max3110
  2010-11-15 21:01 [RFC PATCH 0/4] use kfifo instead of circ_buf Bill Pemberton
  2010-11-15 21:01 ` [RFC PATCH 1/4] serial: " Bill Pemberton
@ 2010-11-15 21:01 ` Bill Pemberton
  2010-11-15 21:01 ` [RFC PATCH 3/4] serial: use kfifo instead of circ_buf in icom.c Bill Pemberton
  2010-11-15 21:01 ` [RFC PATCH 4/4] serial: use kfifo instead of circ_buf for SGI IOC controllers Bill Pemberton
  3 siblings, 0 replies; 5+ messages in thread
From: Bill Pemberton @ 2010-11-15 21:01 UTC (permalink / raw)
  To: linux-serial

Compile tested only.

Signed-off-by: Bill Pemberton <wfp5p@virginia.edu>
---
 drivers/serial/mrst_max3110.c |   45 ++++++++++++++++++----------------------
 1 files changed, 20 insertions(+), 25 deletions(-)

diff --git a/drivers/serial/mrst_max3110.c b/drivers/serial/mrst_max3110.c
index b62857b..7cba9db 100644
--- a/drivers/serial/mrst_max3110.c
+++ b/drivers/serial/mrst_max3110.c
@@ -67,7 +67,7 @@ struct uart_max3110 {
 	unsigned long uart_flags;
 
 	/* console related */
-	struct circ_buf con_xmit;
+	struct kfifo con_xmit;
 };
 
 /* global data structure, may need be removed */
@@ -184,12 +184,11 @@ static void serial_m3110_con_putchar(struct uart_port *port, int ch)
 {
 	struct uart_max3110 *max =
 		container_of(port, struct uart_max3110, port);
-	struct circ_buf *xmit = &max->con_xmit;
+	struct kfifo *xmit = &max->con_xmit;
+
+	if (kfifo_avail(xmit))
+		kfifo_in(xmit, &ch, sizeof(ch));
 
-	if (uart_circ_chars_free(xmit)) {
-		xmit->buf[xmit->head] = (char)ch;
-		xmit->head = (xmit->head + 1) & (PAGE_SIZE - 1);
-	}
 }
 
 /*
@@ -272,11 +271,12 @@ static void serial_m3110_stop_rx(struct uart_port *port)
 
 #define WORDS_PER_XFER	128
 static void send_circ_buf(struct uart_max3110 *max,
-				struct circ_buf *xmit)
+			  struct kfifo *xmit)
 {
 	void *buf;
 	u16 *obuf, *ibuf;
 	u8 valid_str[WORDS_PER_XFER];
+	u8 c;
 	int i, j, len, blen, dma_size, left, ret = 0;
 
 
@@ -287,17 +287,16 @@ static void send_circ_buf(struct uart_max3110 *max,
 	obuf = buf;
 	ibuf = buf + dma_size/2;
 
-	while (!uart_circ_empty(xmit)) {
-		left = uart_circ_chars_pending(xmit);
+	while (!kfifo_is_empty(xmit)) {
+		left = kfifo_len(xmit);
 		while (left) {
 			len = min(left, WORDS_PER_XFER);
 			blen = len * sizeof(u16);
 			memset(ibuf, 0, blen);
 
 			for (i = 0; i < len; i++) {
-				obuf[i] = (u8)xmit->buf[xmit->tail] | WD_TAG;
-				xmit->tail = (xmit->tail + 1) &
-						(UART_XMIT_SIZE - 1);
+				ret = kfifo_out(xmit, &c, 1);
+				obuf[i] = c | WD_TAG;
 			}
 
 			/* Fail to send msg to console is not very critical */
@@ -325,17 +324,17 @@ static void send_circ_buf(struct uart_max3110 *max,
 static void transmit_char(struct uart_max3110 *max)
 {
 	struct uart_port *port = &max->port;
-	struct circ_buf *xmit = &port->state->xmit;
+	struct kfifo *xmit = &port->state->xmit_fifo;
 
-	if (uart_circ_empty(xmit) || uart_tx_stopped(port))
+	if (kfifo_is_empty(xmit) || uart_tx_stopped(port))
 		return;
 
 	send_circ_buf(max, xmit);
 
-	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+	if (kfifo_len(xmit) < WAKEUP_CHARS)
 		uart_write_wakeup(port);
 
-	if (uart_circ_empty(xmit))
+	if (kfifo_is_empty(xmit))
 		serial_m3110_stop_tx(port);
 }
 
@@ -419,7 +418,7 @@ static int max3110_main_thread(void *_max)
 	struct uart_max3110 *max = _max;
 	wait_queue_head_t *wq = &max->wq;
 	int ret = 0;
-	struct circ_buf *xmit = &max->con_xmit;
+	struct kfifo *xmit = &max->con_xmit;
 
 	init_waitqueue_head(wq);
 	pr_info(PR_FMT "start main thread\n");
@@ -784,7 +783,6 @@ static int serial_m3110_resume(struct spi_device *spi)
 static int __devinit serial_m3110_probe(struct spi_device *spi)
 {
 	struct uart_max3110 *max;
-	void *buffer;
 	u16 res;
 	int ret = 0;
 
@@ -829,14 +827,11 @@ static int __devinit serial_m3110_probe(struct spi_device *spi)
 		goto err_get_page;
 	}
 
-	buffer = (void *)__get_free_page(GFP_KERNEL);
-	if (!buffer) {
+	ret = kfifo_alloc(&max->con_xmit, PAGE_SIZE, GFP_KERNEL);
+	if (ret) {
 		ret = -ENOMEM;
 		goto err_get_page;
 	}
-	max->con_xmit.buf = buffer;
-	max->con_xmit.head = 0;
-	max->con_xmit.tail = 0;
 
 	max->main_thread = kthread_run(max3110_main_thread,
 					max, "max3110_main");
@@ -855,7 +850,7 @@ static int __devinit serial_m3110_probe(struct spi_device *spi)
 	return 0;
 
 err_kthread:
-	free_page((unsigned long)buffer);
+	kfifo_free(&max->con_xmit);
 err_get_page:
 	kfree(max);
 	return ret;
@@ -870,7 +865,7 @@ static int __devexit serial_m3110_remove(struct spi_device *dev)
 
 	uart_remove_one_port(&serial_m3110_reg, &max->port);
 
-	free_page((unsigned long)max->con_xmit.buf);
+	kfifo_free(&max->con_xmit);
 
 	if (max->main_thread)
 		kthread_stop(max->main_thread);
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [RFC PATCH 3/4] serial: use kfifo instead of circ_buf in icom.c
  2010-11-15 21:01 [RFC PATCH 0/4] use kfifo instead of circ_buf Bill Pemberton
  2010-11-15 21:01 ` [RFC PATCH 1/4] serial: " Bill Pemberton
  2010-11-15 21:01 ` [RFC PATCH 2/4] serial: use kfifo instead of circ_buf in mrst_max3110 Bill Pemberton
@ 2010-11-15 21:01 ` Bill Pemberton
  2010-11-15 21:01 ` [RFC PATCH 4/4] serial: use kfifo instead of circ_buf for SGI IOC controllers Bill Pemberton
  3 siblings, 0 replies; 5+ messages in thread
From: Bill Pemberton @ 2010-11-15 21:01 UTC (permalink / raw)
  To: linux-serial

Not tested!

Signed-off-by: Bill Pemberton <wfp5p@virginia.edu>
---
 drivers/serial/icom.c |   26 +++++++++++---------------
 1 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index 53a4682..0d63d42 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -627,7 +627,9 @@ static int icom_write(struct uart_port *port)
 	unsigned long data_count;
 	unsigned char cmdReg;
 	unsigned long offset;
-	int temp_tail = port->state->xmit.tail;
+	struct kfifo *xmit_fifo = &port->stat->xmit_fifo;
+	u8 c;
+	int len;
 
 	trace(ICOM_PORT, "WRITE", 0);
 
@@ -638,14 +640,11 @@ static int icom_write(struct uart_port *port)
 	}
 
 	data_count = 0;
-	while ((port->state->xmit.head != temp_tail) &&
+	while ((!kifo_is_empty(xmit_fifo)) &&
 	       (data_count <= XMIT_BUFF_SZ)) {
 
-		ICOM_PORT->xmit_buf[data_count++] =
-		    port->state->xmit.buf[temp_tail];
-
-		temp_tail++;
-		temp_tail &= (UART_XMIT_SIZE - 1);
+		len = kfifo_out(xmit_fifo, &c, 1);
+		ICOM_PORT->xmit_buf[data_count++] = c;
 	}
 
 	if (data_count) {
@@ -704,7 +703,9 @@ static inline void check_modem_status(struct icom_port *icom_port)
 static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
 {
 	unsigned short int count;
-	int i;
+	int i, len;
+	u8 c;
+
 
 	if (port_int_reg & (INT_XMIT_COMPLETED)) {
 		trace(icom_port, "XMIT_COMPLETE", 0);
@@ -717,13 +718,8 @@ static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
 			cpu_to_le16(icom_port->statStg->xmit[0].leLength);
 		icom_port->uart_port.icount.tx += count;
 
-		for (i=0; i<count &&
-			!uart_circ_empty(&icom_port->uart_port.state->xmit); i++) {
-
-			icom_port->uart_port.state->xmit.tail++;
-			icom_port->uart_port.state->xmit.tail &=
-				(UART_XMIT_SIZE - 1);
-		}
+		len = kfifo_out(&icom_port->uart_port.state->xmit_fifo,
+				&c, count);
 
 		if (!icom_write(&icom_port->uart_port))
 			/* activate write queue */
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [RFC PATCH 4/4] serial: use kfifo instead of circ_buf for SGI IOC controllers
  2010-11-15 21:01 [RFC PATCH 0/4] use kfifo instead of circ_buf Bill Pemberton
                   ` (2 preceding siblings ...)
  2010-11-15 21:01 ` [RFC PATCH 3/4] serial: use kfifo instead of circ_buf in icom.c Bill Pemberton
@ 2010-11-15 21:01 ` Bill Pemberton
  3 siblings, 0 replies; 5+ messages in thread
From: Bill Pemberton @ 2010-11-15 21:01 UTC (permalink / raw)
  To: linux-serial

Not tested!

Signed-off-by: Bill Pemberton <wfp5p@virginia.edu>
---
 drivers/serial/ioc3_serial.c |   32 +++++++++++---------------------
 drivers/serial/ioc4_serial.c |   32 +++++++++++---------------------
 2 files changed, 22 insertions(+), 42 deletions(-)

diff --git a/drivers/serial/ioc3_serial.c b/drivers/serial/ioc3_serial.c
index ee43efc..109369a 100644
--- a/drivers/serial/ioc3_serial.c
+++ b/drivers/serial/ioc3_serial.c
@@ -893,9 +893,9 @@ static int ioc3_set_proto(struct ioc3_port *port, int proto)
  */
 static void transmit_chars(struct uart_port *the_port)
 {
-	int xmit_count, tail, head;
+	int len;
 	int result;
-	char *start;
+	u8 iobuf[16];
 	struct tty_struct *tty;
 	struct ioc3_port *port = get_ioc3_port(the_port);
 	struct uart_state *state;
@@ -908,35 +908,25 @@ static void transmit_chars(struct uart_port *the_port)
 	state = the_port->state;
 	tty = state->port.tty;
 
-	if (uart_circ_empty(&state->xmit) || uart_tx_stopped(the_port)) {
+	if (kfifo_is_empty(&state->xmit_fifo) || uart_tx_stopped(the_port)) {
 		/* Nothing to do or hw stopped */
 		set_notification(port, N_ALL_OUTPUT, 0);
 		return;
 	}
 
-	head = state->xmit.head;
-	tail = state->xmit.tail;
-	start = (char *)&state->xmit.buf[tail];
-
 	/* write out all the data or until the end of the buffer */
-	xmit_count = (head < tail) ? (UART_XMIT_SIZE - tail) : (head - tail);
-	if (xmit_count > 0) {
-		result = do_write(port, start, xmit_count);
-		if (result > 0) {
-			/* booking */
-			xmit_count -= result;
+	while (!kfifo_is_empty(&state->xmit_fifo)) {
+		len = kfifo_out(&state->xmit_fifo, iobuf, 16);
+		result = do_write(port, start, len);
+		if (result > 0)
 			the_port->icount.tx += result;
-			/* advance the pointers */
-			tail += result;
-			tail &= UART_XMIT_SIZE - 1;
-			state->xmit.tail = tail;
-			start = (char *)&state->xmit.buf[tail];
-		}
 	}
-	if (uart_circ_chars_pending(&state->xmit) < WAKEUP_CHARS)
+
+	len = kfifo_len(&state->xmit_fifo);
+	if (len  < WAKEUP_CHARS)
 		uart_write_wakeup(the_port);
 
-	if (uart_circ_empty(&state->xmit)) {
+	if (kfifo_is_empty(&state->xmit_fifo)) {
 		set_notification(port, N_OUTPUT_LOWAT, 0);
 	} else {
 		set_notification(port, N_OUTPUT_LOWAT, 1);
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index fcfe826..f72cb7b 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -1623,9 +1623,9 @@ static int ioc4_set_proto(struct ioc4_port *port, int proto)
  */
 static void transmit_chars(struct uart_port *the_port)
 {
-	int xmit_count, tail, head;
+	int len;
 	int result;
-	char *start;
+	u8 iobuf[16];
 	struct tty_struct *tty;
 	struct ioc4_port *port = get_ioc4_port(the_port, 0);
 	struct uart_state *state;
@@ -1638,35 +1638,25 @@ static void transmit_chars(struct uart_port *the_port)
 	state = the_port->state;
 	tty = state->port.tty;
 
-	if (uart_circ_empty(&state->xmit) || uart_tx_stopped(the_port)) {
+	if (kfifo_is_empty(&state->xmit_fifo) || uart_tx_stopped(the_port)) {
 		/* Nothing to do or hw stopped */
 		set_notification(port, N_ALL_OUTPUT, 0);
 		return;
 	}
 
-	head = state->xmit.head;
-	tail = state->xmit.tail;
-	start = (char *)&state->xmit.buf[tail];
-
 	/* write out all the data or until the end of the buffer */
-	xmit_count = (head < tail) ? (UART_XMIT_SIZE - tail) : (head - tail);
-	if (xmit_count > 0) {
-		result = do_write(port, start, xmit_count);
-		if (result > 0) {
-			/* booking */
-			xmit_count -= result;
+	while (!kfifo_is_empty(&state->xmit_fifo)) {
+		len = kfifo_out(&state->xmit_fifo, iobuf, 16);
+		result = do_write(port, start, len);
+		if (result > 0)
 			the_port->icount.tx += result;
-			/* advance the pointers */
-			tail += result;
-			tail &= UART_XMIT_SIZE - 1;
-			state->xmit.tail = tail;
-			start = (char *)&state->xmit.buf[tail];
-		}
 	}
-	if (uart_circ_chars_pending(&state->xmit) < WAKEUP_CHARS)
+
+	len = kfifo_len(&state->xmit_fifo);
+	if (len  < WAKEUP_CHARS)
 		uart_write_wakeup(the_port);
 
-	if (uart_circ_empty(&state->xmit)) {
+	if (kfifo_is_empty(&state->xmit_fifo)) {
 		set_notification(port, N_OUTPUT_LOWAT, 0);
 	} else {
 		set_notification(port, N_OUTPUT_LOWAT, 1);
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-11-15 21:09 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-15 21:01 [RFC PATCH 0/4] use kfifo instead of circ_buf Bill Pemberton
2010-11-15 21:01 ` [RFC PATCH 1/4] serial: " Bill Pemberton
2010-11-15 21:01 ` [RFC PATCH 2/4] serial: use kfifo instead of circ_buf in mrst_max3110 Bill Pemberton
2010-11-15 21:01 ` [RFC PATCH 3/4] serial: use kfifo instead of circ_buf in icom.c Bill Pemberton
2010-11-15 21:01 ` [RFC PATCH 4/4] serial: use kfifo instead of circ_buf for SGI IOC controllers Bill Pemberton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).