USB: ti_usb: use kfifo to implement write buffering
authorJohan Hovold <jhovold@gmail.com>
Tue, 18 May 2010 22:01:35 +0000 (00:01 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 20 May 2010 20:21:50 +0000 (13:21 -0700)
Kill custom fifo implementation.

Compile-only tested.

Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/serial/ti_usb_3410_5052.c

index e1bfda3..90979a1 100644 (file)
@@ -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@steinerpoint.com>"
 #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;
-}