[PATCH 221/229] USB: ti_usb: use kfifo to implement write buffering

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Johan Hovold <jhovold@xxxxxxxxx>

Kill custom fifo implementation.

Compile-only tested.

Signed-off-by: Johan Hovold <jhovold@xxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>
---
 drivers/usb/serial/ti_usb_3410_5052.c |  179 +++------------------------------
 1 files changed, 14 insertions(+), 165 deletions(-)

diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index e1bfda3..90979a1 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -30,7 +30,7 @@
 #include <linux/spinlock.h>
 #include <linux/ioctl.h>
 #include <linux/serial.h>
-#include <linux/circ_buf.h>
+#include <linux/kfifo.h>
 #include <linux/mutex.h>
 #include <linux/uaccess.h>
 #include <linux/usb.h>
@@ -40,7 +40,7 @@
 
 /* Defines */
 
-#define TI_DRIVER_VERSION	"v0.9"
+#define TI_DRIVER_VERSION	"v0.10"
 #define TI_DRIVER_AUTHOR	"Al Borchers <alborchers@xxxxxxxxxxxxxxxx>"
 #define TI_DRIVER_DESC		"TI USB 3410/5052 Serial Driver"
 
@@ -82,7 +82,7 @@ struct ti_port {
 	spinlock_t		tp_lock;
 	int			tp_read_urb_state;
 	int			tp_write_urb_in_use;
-	struct circ_buf		*tp_write_buf;
+	struct kfifo		write_fifo;
 };
 
 struct ti_device {
@@ -144,15 +144,6 @@ static int ti_write_byte(struct ti_device *tdev, unsigned long addr,
 
 static int ti_download_firmware(struct ti_device *tdev);
 
-/* circular buffer */
-static struct circ_buf *ti_buf_alloc(void);
-static void ti_buf_free(struct circ_buf *cb);
-static void ti_buf_clear(struct circ_buf *cb);
-static int ti_buf_data_avail(struct circ_buf *cb);
-static int ti_buf_space_avail(struct circ_buf *cb);
-static int ti_buf_put(struct circ_buf *cb, const char *buf, int count);
-static int ti_buf_get(struct circ_buf *cb, char *buf, int count);
-
 
 /* Data */
 
@@ -450,8 +441,8 @@ static int ti_startup(struct usb_serial *serial)
 		tport->tp_closing_wait = closing_wait;
 		init_waitqueue_head(&tport->tp_msr_wait);
 		init_waitqueue_head(&tport->tp_write_wait);
-		tport->tp_write_buf = ti_buf_alloc();
-		if (tport->tp_write_buf == NULL) {
+		if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE,
+								GFP_KERNEL)) {
 			dev_err(&dev->dev, "%s - out of memory\n", __func__);
 			kfree(tport);
 			status = -ENOMEM;
@@ -468,7 +459,7 @@ static int ti_startup(struct usb_serial *serial)
 free_tports:
 	for (--i; i >= 0; --i) {
 		tport = usb_get_serial_port_data(serial->port[i]);
-		ti_buf_free(tport->tp_write_buf);
+		kfifo_free(&tport->write_fifo);
 		kfree(tport);
 		usb_set_serial_port_data(serial->port[i], NULL);
 	}
@@ -490,7 +481,7 @@ static void ti_release(struct usb_serial *serial)
 	for (i = 0; i < serial->num_ports; ++i) {
 		tport = usb_get_serial_port_data(serial->port[i]);
 		if (tport) {
-			ti_buf_free(tport->tp_write_buf);
+			kfifo_free(&tport->write_fifo);
 			kfree(tport);
 		}
 	}
@@ -701,7 +692,6 @@ static int ti_write(struct tty_struct *tty, struct usb_serial_port *port,
 			const unsigned char *data, int count)
 {
 	struct ti_port *tport = usb_get_serial_port_data(port);
-	unsigned long flags;
 
 	dbg("%s - port %d", __func__, port->number);
 
@@ -713,10 +703,8 @@ static int ti_write(struct tty_struct *tty, struct usb_serial_port *port,
 	if (tport == NULL || !tport->tp_is_open)
 		return -ENODEV;
 
-	spin_lock_irqsave(&tport->tp_lock, flags);
-	count = ti_buf_put(tport->tp_write_buf, data, count);
-	spin_unlock_irqrestore(&tport->tp_lock, flags);
-
+	count = kfifo_in_locked(&tport->write_fifo, data, count,
+							&tport->tp_lock);
 	ti_send(tport);
 
 	return count;
@@ -736,7 +724,7 @@ static int ti_write_room(struct tty_struct *tty)
 		return 0;
 
 	spin_lock_irqsave(&tport->tp_lock, flags);
-	room = ti_buf_space_avail(tport->tp_write_buf);
+	room = kfifo_avail(&tport->write_fifo);
 	spin_unlock_irqrestore(&tport->tp_lock, flags);
 
 	dbg("%s - returns %d", __func__, room);
@@ -757,7 +745,7 @@ static int ti_chars_in_buffer(struct tty_struct *tty)
 		return 0;
 
 	spin_lock_irqsave(&tport->tp_lock, flags);
-	chars = ti_buf_data_avail(tport->tp_write_buf);
+	chars = kfifo_len(&tport->write_fifo);
 	spin_unlock_irqrestore(&tport->tp_lock, flags);
 
 	dbg("%s - returns %d", __func__, chars);
@@ -1309,7 +1297,7 @@ static void ti_send(struct ti_port *tport)
 	if (tport->tp_write_urb_in_use)
 		goto unlock;
 
-	count = ti_buf_get(tport->tp_write_buf,
+	count = kfifo_out(&tport->write_fifo,
 				port->write_urb->transfer_buffer,
 				port->bulk_out_size);
 
@@ -1504,7 +1492,7 @@ static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush)
 	add_wait_queue(&tport->tp_write_wait, &wait);
 	for (;;) {
 		set_current_state(TASK_INTERRUPTIBLE);
-		if (ti_buf_data_avail(tport->tp_write_buf) == 0
+		if (kfifo_len(&tport->write_fifo) == 0
 		|| timeout == 0 || signal_pending(current)
 		|| tdev->td_urb_error
 		|| port->serial->disconnected)  /* disconnect */
@@ -1518,7 +1506,7 @@ static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush)
 
 	/* flush any remaining data in the buffer */
 	if (flush)
-		ti_buf_clear(tport->tp_write_buf);
+		kfifo_reset_out(&tport->write_fifo);
 
 	spin_unlock_irq(&tport->tp_lock);
 
@@ -1761,142 +1749,3 @@ static int ti_download_firmware(struct ti_device *tdev)
 
 	return 0;
 }
-
-
-/* Circular Buffer Functions */
-
-/*
- * ti_buf_alloc
- *
- * Allocate a circular buffer and all associated memory.
- */
-
-static struct circ_buf *ti_buf_alloc(void)
-{
-	struct circ_buf *cb;
-
-	cb = kmalloc(sizeof(struct circ_buf), GFP_KERNEL);
-	if (cb == NULL)
-		return NULL;
-
-	cb->buf = kmalloc(TI_WRITE_BUF_SIZE, GFP_KERNEL);
-	if (cb->buf == NULL) {
-		kfree(cb);
-		return NULL;
-	}
-
-	ti_buf_clear(cb);
-
-	return cb;
-}
-
-
-/*
- * ti_buf_free
- *
- * Free the buffer and all associated memory.
- */
-
-static void ti_buf_free(struct circ_buf *cb)
-{
-	kfree(cb->buf);
-	kfree(cb);
-}
-
-
-/*
- * ti_buf_clear
- *
- * Clear out all data in the circular buffer.
- */
-
-static void ti_buf_clear(struct circ_buf *cb)
-{
-	cb->head = cb->tail = 0;
-}
-
-
-/*
- * ti_buf_data_avail
- *
- * Return the number of bytes of data available in the circular
- * buffer.
- */
-
-static int ti_buf_data_avail(struct circ_buf *cb)
-{
-	return CIRC_CNT(cb->head, cb->tail, TI_WRITE_BUF_SIZE);
-}
-
-
-/*
- * ti_buf_space_avail
- *
- * Return the number of bytes of space available in the circular
- * buffer.
- */
-
-static int ti_buf_space_avail(struct circ_buf *cb)
-{
-	return CIRC_SPACE(cb->head, cb->tail, TI_WRITE_BUF_SIZE);
-}
-
-
-/*
- * ti_buf_put
- *
- * Copy data data from a user buffer and put it into the circular buffer.
- * Restrict to the amount of space available.
- *
- * Return the number of bytes copied.
- */
-
-static int ti_buf_put(struct circ_buf *cb, const char *buf, int count)
-{
-	int c, ret = 0;
-
-	while (1) {
-		c = CIRC_SPACE_TO_END(cb->head, cb->tail, TI_WRITE_BUF_SIZE);
-		if (count < c)
-			c = count;
-		if (c <= 0)
-			break;
-		memcpy(cb->buf + cb->head, buf, c);
-		cb->head = (cb->head + c) & (TI_WRITE_BUF_SIZE-1);
-		buf += c;
-		count -= c;
-		ret += c;
-	}
-
-	return ret;
-}
-
-
-/*
- * ti_buf_get
- *
- * Get data from the circular buffer and copy to the given buffer.
- * Restrict to the amount of data available.
- *
- * Return the number of bytes copied.
- */
-
-static int ti_buf_get(struct circ_buf *cb, char *buf, int count)
-{
-	int c, ret = 0;
-
-	while (1) {
-		c = CIRC_CNT_TO_END(cb->head, cb->tail, TI_WRITE_BUF_SIZE);
-		if (count < c)
-			c = count;
-		if (c <= 0)
-			break;
-		memcpy(buf, cb->buf + cb->tail, c);
-		cb->tail = (cb->tail + c) & (TI_WRITE_BUF_SIZE-1);
-		buf += c;
-		count -= c;
-		ret += c;
-	}
-
-	return ret;
-}
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux