Commit abfa44b5 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'tty-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6

* 'tty-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6:
  tty/serial: fix apbuart build
  n_hdlc: fix read and write locking
  serial: unbreak billionton CF card
  tty: use for_each_console() and WARN() on sysfs failures
  vt: fix issue when fbcon wants to takeover a second time.

Fix up trivial conflict in drivers/tty/tty_io.c
parents 70d1f365 fed7bb32
...@@ -581,8 +581,9 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, ...@@ -581,8 +581,9 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
__u8 __user *buf, size_t nr) __u8 __user *buf, size_t nr)
{ {
struct n_hdlc *n_hdlc = tty2n_hdlc(tty); struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
int ret; int ret = 0;
struct n_hdlc_buf *rbuf; struct n_hdlc_buf *rbuf;
DECLARE_WAITQUEUE(wait, current);
if (debuglevel >= DEBUG_LEVEL_INFO) if (debuglevel >= DEBUG_LEVEL_INFO)
printk("%s(%d)n_hdlc_tty_read() called\n",__FILE__,__LINE__); printk("%s(%d)n_hdlc_tty_read() called\n",__FILE__,__LINE__);
...@@ -598,57 +599,55 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, ...@@ -598,57 +599,55 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
return -EFAULT; return -EFAULT;
} }
tty_lock(); add_wait_queue(&tty->read_wait, &wait);
for (;;) { for (;;) {
if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
tty_unlock(); ret = -EIO;
return -EIO; break;
} }
if (tty_hung_up_p(file))
break;
n_hdlc = tty2n_hdlc (tty); set_current_state(TASK_INTERRUPTIBLE);
if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC ||
tty != n_hdlc->tty) {
tty_unlock();
return 0;
}
rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list); rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list);
if (rbuf) if (rbuf) {
if (rbuf->count > nr) {
/* too large for caller's buffer */
ret = -EOVERFLOW;
} else {
if (copy_to_user(buf, rbuf->buf, rbuf->count))
ret = -EFAULT;
else
ret = rbuf->count;
}
if (n_hdlc->rx_free_buf_list.count >
DEFAULT_RX_BUF_COUNT)
kfree(rbuf);
else
n_hdlc_buf_put(&n_hdlc->rx_free_buf_list, rbuf);
break; break;
}
/* no data */ /* no data */
if (file->f_flags & O_NONBLOCK) { if (file->f_flags & O_NONBLOCK) {
tty_unlock(); ret = -EAGAIN;
return -EAGAIN; break;
} }
interruptible_sleep_on (&tty->read_wait); schedule();
if (signal_pending(current)) { if (signal_pending(current)) {
tty_unlock(); ret = -EINTR;
return -EINTR; break;
} }
} }
if (rbuf->count > nr) remove_wait_queue(&tty->read_wait, &wait);
/* frame too large for caller's buffer (discard frame) */ __set_current_state(TASK_RUNNING);
ret = -EOVERFLOW;
else {
/* Copy the data to the caller's buffer */
if (copy_to_user(buf, rbuf->buf, rbuf->count))
ret = -EFAULT;
else
ret = rbuf->count;
}
/* return HDLC buffer to free list unless the free list */
/* count has exceeded the default value, in which case the */
/* buffer is freed back to the OS to conserve memory */
if (n_hdlc->rx_free_buf_list.count > DEFAULT_RX_BUF_COUNT)
kfree(rbuf);
else
n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf);
tty_unlock();
return ret; return ret;
} /* end of n_hdlc_tty_read() */ } /* end of n_hdlc_tty_read() */
...@@ -691,14 +690,15 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, ...@@ -691,14 +690,15 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
count = maxframe; count = maxframe;
} }
tty_lock();
add_wait_queue(&tty->write_wait, &wait); add_wait_queue(&tty->write_wait, &wait);
set_current_state(TASK_INTERRUPTIBLE);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
/* Allocate transmit buffer */ tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list);
/* sleep until transmit buffer available */ if (tbuf)
while (!(tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list))) { break;
if (file->f_flags & O_NONBLOCK) { if (file->f_flags & O_NONBLOCK) {
error = -EAGAIN; error = -EAGAIN;
break; break;
...@@ -719,7 +719,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, ...@@ -719,7 +719,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
} }
} }
set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
remove_wait_queue(&tty->write_wait, &wait); remove_wait_queue(&tty->write_wait, &wait);
if (!error) { if (!error) {
...@@ -731,7 +731,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, ...@@ -731,7 +731,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf); n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf);
n_hdlc_send_frames(n_hdlc,tty); n_hdlc_send_frames(n_hdlc,tty);
} }
tty_unlock();
return error; return error;
} /* end of n_hdlc_tty_write() */ } /* end of n_hdlc_tty_write() */
......
...@@ -236,7 +236,8 @@ static const struct serial8250_config uart_config[] = { ...@@ -236,7 +236,8 @@ static const struct serial8250_config uart_config[] = {
.fifo_size = 128, .fifo_size = 128,
.tx_loadsz = 128, .tx_loadsz = 128,
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
.flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, /* UART_CAP_EFR breaks billionon CF bluetooth card. */
.flags = UART_CAP_FIFO | UART_CAP_SLEEP,
}, },
[PORT_16654] = { [PORT_16654] = {
.name = "ST16654", .name = "ST16654",
......
...@@ -1518,6 +1518,7 @@ config SERIAL_BCM63XX_CONSOLE ...@@ -1518,6 +1518,7 @@ config SERIAL_BCM63XX_CONSOLE
config SERIAL_GRLIB_GAISLER_APBUART config SERIAL_GRLIB_GAISLER_APBUART
tristate "GRLIB APBUART serial support" tristate "GRLIB APBUART serial support"
depends on OF depends on OF
select SERIAL_CORE
---help--- ---help---
Add support for the GRLIB APBUART serial port. Add support for the GRLIB APBUART serial port.
......
...@@ -3257,7 +3257,7 @@ static ssize_t show_cons_active(struct device *dev, ...@@ -3257,7 +3257,7 @@ static ssize_t show_cons_active(struct device *dev,
ssize_t count = 0; ssize_t count = 0;
console_lock(); console_lock();
for (c = console_drivers; c; c = c->next) { for_each_console(c) {
if (!c->device) if (!c->device)
continue; continue;
if (!c->write) if (!c->write)
...@@ -3306,7 +3306,7 @@ int __init tty_init(void) ...@@ -3306,7 +3306,7 @@ int __init tty_init(void)
if (IS_ERR(consdev)) if (IS_ERR(consdev))
consdev = NULL; consdev = NULL;
else else
device_create_file(consdev, &dev_attr_active); WARN_ON(device_create_file(consdev, &dev_attr_active) < 0);
#ifdef CONFIG_VT #ifdef CONFIG_VT
vty_init(&console_fops); vty_init(&console_fops);
......
...@@ -2994,7 +2994,7 @@ int __init vty_init(const struct file_operations *console_fops) ...@@ -2994,7 +2994,7 @@ int __init vty_init(const struct file_operations *console_fops)
if (IS_ERR(tty0dev)) if (IS_ERR(tty0dev))
tty0dev = NULL; tty0dev = NULL;
else else
device_create_file(tty0dev, &dev_attr_active); WARN_ON(device_create_file(tty0dev, &dev_attr_active) < 0);
vcs_init(); vcs_init();
...@@ -3545,7 +3545,7 @@ int register_con_driver(const struct consw *csw, int first, int last) ...@@ -3545,7 +3545,7 @@ int register_con_driver(const struct consw *csw, int first, int last)
/* already registered */ /* already registered */
if (con_driver->con == csw) if (con_driver->con == csw)
retval = -EINVAL; retval = -EBUSY;
} }
if (retval) if (retval)
...@@ -3656,7 +3656,12 @@ int take_over_console(const struct consw *csw, int first, int last, int deflt) ...@@ -3656,7 +3656,12 @@ int take_over_console(const struct consw *csw, int first, int last, int deflt)
int err; int err;
err = register_con_driver(csw, first, last); err = register_con_driver(csw, first, last);
/* if we get an busy error we still want to bind the console driver
* and return success, as we may have unbound the console driver
 * but not unregistered it.
*/
if (err == -EBUSY)
err = 0;
if (!err) if (!err)
bind_con_driver(csw, first, last, deflt); bind_con_driver(csw, first, last, deflt);
......
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