lkml.org 
[lkml]   [2009]   [Nov]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 08/11] sdio_uart: Use kfifo instead of the messy circ stuff
    Date
    Probably all the tty code should switch to this, especially when the new
    lockless kfifo is merged.

    Signed-off-by: Alan Cox <alan@linux.intel.com>
    ---

    drivers/mmc/card/sdio_uart.c | 92 +++++++++++++-----------------------------
    1 files changed, 29 insertions(+), 63 deletions(-)


    diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
    index ffa56cb..4139b24 100644
    --- a/drivers/mmc/card/sdio_uart.c
    +++ b/drivers/mmc/card/sdio_uart.c
    @@ -32,7 +32,7 @@
    #include <linux/mutex.h>
    #include <linux/seq_file.h>
    #include <linux/serial_reg.h>
    -#include <linux/circ_buf.h>
    +#include <linux/kfifo.h>
    #include <linux/gfp.h>
    #include <linux/tty.h>
    #include <linux/tty_flip.h>
    @@ -46,18 +46,9 @@
    #define UART_NR 8 /* Number of UARTs this driver can handle */


    -#define UART_XMIT_SIZE PAGE_SIZE
    +#define FIFO_SIZE PAGE_SIZE
    #define WAKEUP_CHARS 256

    -#define circ_empty(circ) ((circ)->head == (circ)->tail)
    -#define circ_clear(circ) ((circ)->head = (circ)->tail = 0)
    -
    -#define circ_chars_pending(circ) \
    - (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
    -
    -#define circ_chars_free(circ) \
    - (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
    -

    struct uart_icount {
    __u32 cts;
    @@ -81,7 +72,7 @@ struct sdio_uart_port {
    struct mutex func_lock;
    struct task_struct *in_sdio_uart_irq;
    unsigned int regs_offset;
    - struct circ_buf xmit;
    + struct kfifo *xmit_fifo;
    spinlock_t write_lock;
    struct uart_icount icount;
    unsigned int uartclk;
    @@ -103,6 +94,9 @@ static int sdio_uart_add_port(struct sdio_uart_port *port)
    kref_init(&port->kref);
    mutex_init(&port->func_lock);
    spin_lock_init(&port->write_lock);
    + port->xmit_fifo = kfifo_alloc(FIFO_SIZE, GFP_KERNEL, &port->write_lock);
    + if (port->xmit_fifo == NULL)
    + return -ENOMEM;

    spin_lock(&sdio_uart_table_lock);
    for (index = 0; index < UART_NR; index++) {
    @@ -138,6 +132,7 @@ static void sdio_uart_port_destroy(struct kref *kref)
    {
    struct sdio_uart_port *port =
    container_of(kref, struct sdio_uart_port, kref);
    + kfifo_free(port->xmit_fifo);
    kfree(port);
    }

    @@ -452,9 +447,11 @@ static void sdio_uart_receive_chars(struct sdio_uart_port *port,

    static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
    {
    - struct circ_buf *xmit = &port->xmit;
    + struct kfifo *xmit = port->xmit_fifo;
    int count;
    struct tty_struct *tty;
    + u8 iobuf[16];
    + int len;

    if (port->x_char) {
    sdio_out(port, UART_TX, port->x_char);
    @@ -465,25 +462,22 @@ static void sdio_uart_transmit_chars(struct sdio_uart_port *port)

    tty = tty_port_tty_get(&port->port);

    - if (tty == NULL || circ_empty(xmit) || tty->stopped || tty->hw_stopped) {
    + if (tty == NULL || !kfifo_len(xmit) || tty->stopped || tty->hw_stopped) {
    sdio_uart_stop_tx(port);
    tty_kref_put(tty);
    return;
    }

    - count = 16;
    - do {
    - sdio_out(port, UART_TX, xmit->buf[xmit->tail]);
    - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
    + len = kfifo_get(xmit, iobuf, 16);
    + for (count = 0; count < len; count++) {
    + sdio_out(port, UART_TX, iobuf[count]);
    port->icount.tx++;
    - if (circ_empty(xmit))
    - break;
    - } while (--count > 0);
    + }

    - if (circ_chars_pending(xmit) < WAKEUP_CHARS)
    + if (len < WAKEUP_CHARS)
    tty_wakeup(tty);

    - if (circ_empty(xmit))
    + if (len == 0)
    sdio_uart_stop_tx(port);
    tty_kref_put(tty);
    }
    @@ -597,7 +591,6 @@ static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty)
    {
    struct sdio_uart_port *port =
    container_of(tport, struct sdio_uart_port, port);
    - unsigned long page;
    int ret;

    /*
    @@ -606,22 +599,17 @@ static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty)
    */
    set_bit(TTY_IO_ERROR, &tty->flags);

    - /* Initialise and allocate the transmit buffer. */
    - page = __get_free_page(GFP_KERNEL);
    - if (!page)
    - return -ENOMEM;
    - port->xmit.buf = (unsigned char *)page;
    - circ_clear(&port->xmit);
    + kfifo_reset(port->xmit_fifo);

    ret = sdio_uart_claim_func(port);
    if (ret)
    - goto err1;
    + return ret;
    ret = sdio_enable_func(port->func);
    if (ret)
    - goto err2;
    + goto err1;
    ret = sdio_claim_irq(port->func, sdio_uart_irq);
    if (ret)
    - goto err3;
    + goto err2;

    /*
    * Clear the FIFO buffers and disable them.
    @@ -665,12 +653,10 @@ static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty)
    sdio_uart_release_func(port);
    return 0;

    -err3:
    - sdio_disable_func(port->func);
    err2:
    - sdio_uart_release_func(port);
    + sdio_disable_func(port->func);
    err1:
    - free_page((unsigned long)port->xmit.buf);
    + sdio_uart_release_func(port);
    return ret;
    }

    @@ -689,11 +675,9 @@ static void sdio_uart_shutdown(struct tty_port *tport)
    {
    struct sdio_uart_port *port =
    container_of(tport, struct sdio_uart_port, port);
    - int ret;

    - ret = sdio_uart_claim_func(port);
    - if (ret)
    - goto skip;
    + if (sdio_uart_claim_func(port))
    + return;

    sdio_uart_stop_rx(port);

    @@ -715,10 +699,6 @@ static void sdio_uart_shutdown(struct tty_port *tport)
    sdio_disable_func(port->func);

    sdio_uart_release_func(port);
    -
    -skip:
    - /* Free the transmit buffer page. */
    - free_page((unsigned long)port->xmit.buf);
    }

    /**
    @@ -789,26 +769,12 @@ static int sdio_uart_write(struct tty_struct * tty, const unsigned char *buf,
    int count)
    {
    struct sdio_uart_port *port = tty->driver_data;
    - struct circ_buf *circ = &port->xmit;
    - int c, ret = 0;
    + int ret;

    if (!port->func)
    return -ENODEV;

    - spin_lock(&port->write_lock);
    - 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(&port->write_lock);
    + ret = kfifo_put(port->xmit_fifo, buf, count);

    if ( !(port->ier & UART_IER_THRI)) {
    int err = sdio_uart_claim_func(port);
    @@ -826,13 +792,13 @@ static int sdio_uart_write(struct tty_struct * tty, const unsigned char *buf,
    static int sdio_uart_write_room(struct tty_struct *tty)
    {
    struct sdio_uart_port *port = tty->driver_data;
    - return port ? circ_chars_free(&port->xmit) : 0;
    + return FIFO_SIZE - kfifo_len(port->xmit_fifo);
    }

    static int sdio_uart_chars_in_buffer(struct tty_struct *tty)
    {
    struct sdio_uart_port *port = tty->driver_data;
    - return port ? circ_chars_pending(&port->xmit) : 0;
    + return kfifo_len(port->xmit_fifo);
    }

    static void sdio_uart_send_xchar(struct tty_struct *tty, char ch)


    \
     
     \ /
      Last update: 2009-11-18 15:55    [W:0.037 / U:34.872 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site