Commit c1d0b9d9 authored by Russell King's avatar Russell King

[SERIAL] Clean up serial_core.c write functions.

Since the tty layer now takes care of user space writes,
__uart_user_write() and associated temporary buffer and temporary
buffer semaphore have all become unnecessary.  There's also little
point in having __uart_kern_write() separate from uart_write(), so
combine the two together.

Adrian Bunk kindly provided the patch to remove __uart_user_write().
The rest of the work is rmk's.

Signed-off-by: Adrian Bunk
Signed-off-by: default avatarRussell King <rmk@arm.linux.org.uk>
parent 506b73c0
...@@ -162,8 +162,6 @@ static int uart_startup(struct uart_state *state, int init_hw) ...@@ -162,8 +162,6 @@ static int uart_startup(struct uart_state *state, int init_hw)
return -ENOMEM; return -ENOMEM;
info->xmit.buf = (unsigned char *) page; info->xmit.buf = (unsigned char *) page;
info->tmpbuf = info->xmit.buf + UART_XMIT_SIZE;
init_MUTEX(&info->tmpbuf_sem);
uart_circ_clear(&info->xmit); uart_circ_clear(&info->xmit);
} }
...@@ -238,7 +236,6 @@ static void uart_shutdown(struct uart_state *state) ...@@ -238,7 +236,6 @@ static void uart_shutdown(struct uart_state *state)
if (info->xmit.buf) { if (info->xmit.buf) {
free_page((unsigned long)info->xmit.buf); free_page((unsigned long)info->xmit.buf);
info->xmit.buf = NULL; info->xmit.buf = NULL;
info->tmpbuf = NULL;
} }
/* /*
...@@ -450,53 +447,30 @@ __uart_put_char(struct uart_port *port, struct circ_buf *circ, unsigned char c) ...@@ -450,53 +447,30 @@ __uart_put_char(struct uart_port *port, struct circ_buf *circ, unsigned char c)
spin_unlock_irqrestore(&port->lock, flags); spin_unlock_irqrestore(&port->lock, flags);
} }
static inline int static void uart_put_char(struct tty_struct *tty, unsigned char ch)
__uart_user_write(struct uart_port *port, struct circ_buf *circ,
const unsigned char __user *buf, int count)
{ {
unsigned long flags; struct uart_state *state = tty->driver_data;
int c, ret = 0;
if (down_interruptible(&port->info->tmpbuf_sem))
return -EINTR;
while (1) {
int c1;
c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
if (count < c)
c = count;
if (c <= 0)
break;
c -= copy_from_user(port->info->tmpbuf, buf, c); __uart_put_char(state->port, &state->info->xmit, ch);
if (!c) { }
if (!ret)
ret = -EFAULT;
break;
}
spin_lock_irqsave(&port->lock, flags);
c1 = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
if (c1 < c)
c = c1;
memcpy(circ->buf + circ->head, port->info->tmpbuf, c);
circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
spin_unlock_irqrestore(&port->lock, flags);
buf += c;
count -= c;
ret += c;
}
up(&port->info->tmpbuf_sem);
return ret; static void uart_flush_chars(struct tty_struct *tty)
{
uart_start(tty);
} }
static inline int static int
__uart_kern_write(struct uart_port *port, struct circ_buf *circ, 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 = state->port;
struct circ_buf *circ = &state->info->xmit;
unsigned long flags; unsigned long flags;
int c, ret = 0; int c, ret = 0;
if (!circ->buf)
return 0;
spin_lock_irqsave(&port->lock, flags); spin_lock_irqsave(&port->lock, flags);
while (1) { while (1) {
c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE); c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
...@@ -512,33 +486,6 @@ __uart_kern_write(struct uart_port *port, struct circ_buf *circ, ...@@ -512,33 +486,6 @@ __uart_kern_write(struct uart_port *port, struct circ_buf *circ,
} }
spin_unlock_irqrestore(&port->lock, flags); spin_unlock_irqrestore(&port->lock, flags);
return ret;
}
static void uart_put_char(struct tty_struct *tty, unsigned char ch)
{
struct uart_state *state = tty->driver_data;
__uart_put_char(state->port, &state->info->xmit, ch);
}
static void uart_flush_chars(struct tty_struct *tty)
{
uart_start(tty);
}
static int
uart_write(struct tty_struct *tty, const unsigned char * buf, int count)
{
struct uart_state *state = tty->driver_data;
int ret;
if (!state->info->xmit.buf)
return 0;
ret = __uart_kern_write(state->port, &state->info->xmit,
buf, count);
uart_start(tty); uart_start(tty);
return ret; return ret;
} }
......
...@@ -246,7 +246,7 @@ struct uart_state { ...@@ -246,7 +246,7 @@ struct uart_state {
struct semaphore sem; struct semaphore sem;
}; };
#define UART_XMIT_SIZE 1024 #define UART_XMIT_SIZE PAGE_SIZE
/* /*
* This is the state information which is only valid when the port * This is the state information which is only valid when the port
* is open; it may be freed by the core driver once the device has * is open; it may be freed by the core driver once the device has
...@@ -268,9 +268,6 @@ struct uart_info { ...@@ -268,9 +268,6 @@ struct uart_info {
#define UIF_NORMAL_ACTIVE (1 << 29) #define UIF_NORMAL_ACTIVE (1 << 29)
#define UIF_INITIALIZED (1 << 31) #define UIF_INITIALIZED (1 << 31)
unsigned char *tmpbuf;
struct semaphore tmpbuf_sem;
int blocked_open; int blocked_open;
struct tasklet_struct tlet; struct tasklet_struct tlet;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment