mirror of
https://github.com/adulau/aha.git
synced 2024-12-29 12:16:20 +00:00
serial: use tty_port pointers in the core code
Extract out a lot of the x.port. uses and also show up where there are things left to be isolated that prevent use using the port helpers in the serial layer at this point Signed-off-by: Alan Cox <alan@linux.intel.com>
This commit is contained in:
parent
5e99df561f
commit
46d57a449a
1 changed files with 145 additions and 141 deletions
|
@ -141,7 +141,8 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
|
||||||
*/
|
*/
|
||||||
static int uart_startup(struct uart_state *state, int init_hw)
|
static int uart_startup(struct uart_state *state, int init_hw)
|
||||||
{
|
{
|
||||||
struct uart_port *port = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
|
struct tty_port *port = &state->port;
|
||||||
unsigned long page;
|
unsigned long page;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
|
@ -153,9 +154,9 @@ static int uart_startup(struct uart_state *state, int init_hw)
|
||||||
* once we have successfully opened the port. Also set
|
* once we have successfully opened the port. Also set
|
||||||
* up the tty->alt_speed kludge
|
* up the tty->alt_speed kludge
|
||||||
*/
|
*/
|
||||||
set_bit(TTY_IO_ERROR, &state->port.tty->flags);
|
set_bit(TTY_IO_ERROR, &port->tty->flags);
|
||||||
|
|
||||||
if (port->type == PORT_UNKNOWN)
|
if (uport->type == PORT_UNKNOWN)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -172,7 +173,7 @@ static int uart_startup(struct uart_state *state, int init_hw)
|
||||||
uart_circ_clear(&state->xmit);
|
uart_circ_clear(&state->xmit);
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = port->ops->startup(port);
|
retval = uport->ops->startup(uport);
|
||||||
if (retval == 0) {
|
if (retval == 0) {
|
||||||
if (init_hw) {
|
if (init_hw) {
|
||||||
/*
|
/*
|
||||||
|
@ -184,20 +185,20 @@ static int uart_startup(struct uart_state *state, int init_hw)
|
||||||
* Setup the RTS and DTR signals once the
|
* Setup the RTS and DTR signals once the
|
||||||
* port is open and ready to respond.
|
* port is open and ready to respond.
|
||||||
*/
|
*/
|
||||||
if (state->port.tty->termios->c_cflag & CBAUD)
|
if (port->tty->termios->c_cflag & CBAUD)
|
||||||
uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
|
uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->flags & UIF_CTS_FLOW) {
|
if (state->flags & UIF_CTS_FLOW) {
|
||||||
spin_lock_irq(&port->lock);
|
spin_lock_irq(&uport->lock);
|
||||||
if (!(port->ops->get_mctrl(port) & TIOCM_CTS))
|
if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS))
|
||||||
state->port.tty->hw_stopped = 1;
|
port->tty->hw_stopped = 1;
|
||||||
spin_unlock_irq(&port->lock);
|
spin_unlock_irq(&uport->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
state->flags |= UIF_INITIALIZED;
|
state->flags |= UIF_INITIALIZED;
|
||||||
|
|
||||||
clear_bit(TTY_IO_ERROR, &state->port.tty->flags);
|
clear_bit(TTY_IO_ERROR, &port->tty->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retval && capable(CAP_SYS_ADMIN))
|
if (retval && capable(CAP_SYS_ADMIN))
|
||||||
|
@ -672,7 +673,8 @@ static int uart_set_info(struct uart_state *state,
|
||||||
struct serial_struct __user *newinfo)
|
struct serial_struct __user *newinfo)
|
||||||
{
|
{
|
||||||
struct serial_struct new_serial;
|
struct serial_struct new_serial;
|
||||||
struct uart_port *port = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
|
struct tty_port *port = &state->port;
|
||||||
unsigned long new_port;
|
unsigned long new_port;
|
||||||
unsigned int change_irq, change_port, closing_wait;
|
unsigned int change_irq, change_port, closing_wait;
|
||||||
unsigned int old_custom_divisor, close_delay;
|
unsigned int old_custom_divisor, close_delay;
|
||||||
|
@ -700,47 +702,47 @@ static int uart_set_info(struct uart_state *state,
|
||||||
*/
|
*/
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&state->mutex);
|
||||||
|
|
||||||
change_irq = !(port->flags & UPF_FIXED_PORT)
|
change_irq = !(uport->flags & UPF_FIXED_PORT)
|
||||||
&& new_serial.irq != port->irq;
|
&& new_serial.irq != uport->irq;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since changing the 'type' of the port changes its resource
|
* Since changing the 'type' of the port changes its resource
|
||||||
* allocations, we should treat type changes the same as
|
* allocations, we should treat type changes the same as
|
||||||
* IO port changes.
|
* IO port changes.
|
||||||
*/
|
*/
|
||||||
change_port = !(port->flags & UPF_FIXED_PORT)
|
change_port = !(uport->flags & UPF_FIXED_PORT)
|
||||||
&& (new_port != port->iobase ||
|
&& (new_port != uport->iobase ||
|
||||||
(unsigned long)new_serial.iomem_base != port->mapbase ||
|
(unsigned long)new_serial.iomem_base != uport->mapbase ||
|
||||||
new_serial.hub6 != port->hub6 ||
|
new_serial.hub6 != uport->hub6 ||
|
||||||
new_serial.io_type != port->iotype ||
|
new_serial.io_type != uport->iotype ||
|
||||||
new_serial.iomem_reg_shift != port->regshift ||
|
new_serial.iomem_reg_shift != uport->regshift ||
|
||||||
new_serial.type != port->type);
|
new_serial.type != uport->type);
|
||||||
|
|
||||||
old_flags = port->flags;
|
old_flags = uport->flags;
|
||||||
new_flags = new_serial.flags;
|
new_flags = new_serial.flags;
|
||||||
old_custom_divisor = port->custom_divisor;
|
old_custom_divisor = uport->custom_divisor;
|
||||||
|
|
||||||
if (!capable(CAP_SYS_ADMIN)) {
|
if (!capable(CAP_SYS_ADMIN)) {
|
||||||
retval = -EPERM;
|
retval = -EPERM;
|
||||||
if (change_irq || change_port ||
|
if (change_irq || change_port ||
|
||||||
(new_serial.baud_base != port->uartclk / 16) ||
|
(new_serial.baud_base != uport->uartclk / 16) ||
|
||||||
(close_delay != state->port.close_delay) ||
|
(close_delay != port->close_delay) ||
|
||||||
(closing_wait != state->port.closing_wait) ||
|
(closing_wait != port->closing_wait) ||
|
||||||
(new_serial.xmit_fifo_size &&
|
(new_serial.xmit_fifo_size &&
|
||||||
new_serial.xmit_fifo_size != port->fifosize) ||
|
new_serial.xmit_fifo_size != uport->fifosize) ||
|
||||||
(((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0))
|
(((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0))
|
||||||
goto exit;
|
goto exit;
|
||||||
port->flags = ((port->flags & ~UPF_USR_MASK) |
|
uport->flags = ((uport->flags & ~UPF_USR_MASK) |
|
||||||
(new_flags & UPF_USR_MASK));
|
(new_flags & UPF_USR_MASK));
|
||||||
port->custom_divisor = new_serial.custom_divisor;
|
uport->custom_divisor = new_serial.custom_divisor;
|
||||||
goto check_and_exit;
|
goto check_and_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ask the low level driver to verify the settings.
|
* Ask the low level driver to verify the settings.
|
||||||
*/
|
*/
|
||||||
if (port->ops->verify_port)
|
if (uport->ops->verify_port)
|
||||||
retval = port->ops->verify_port(port, &new_serial);
|
retval = uport->ops->verify_port(uport, &new_serial);
|
||||||
|
|
||||||
if ((new_serial.irq >= nr_irqs) || (new_serial.irq < 0) ||
|
if ((new_serial.irq >= nr_irqs) || (new_serial.irq < 0) ||
|
||||||
(new_serial.baud_base < 9600))
|
(new_serial.baud_base < 9600))
|
||||||
|
@ -769,31 +771,31 @@ static int uart_set_info(struct uart_state *state,
|
||||||
unsigned long old_iobase, old_mapbase;
|
unsigned long old_iobase, old_mapbase;
|
||||||
unsigned int old_type, old_iotype, old_hub6, old_shift;
|
unsigned int old_type, old_iotype, old_hub6, old_shift;
|
||||||
|
|
||||||
old_iobase = port->iobase;
|
old_iobase = uport->iobase;
|
||||||
old_mapbase = port->mapbase;
|
old_mapbase = uport->mapbase;
|
||||||
old_type = port->type;
|
old_type = uport->type;
|
||||||
old_hub6 = port->hub6;
|
old_hub6 = uport->hub6;
|
||||||
old_iotype = port->iotype;
|
old_iotype = uport->iotype;
|
||||||
old_shift = port->regshift;
|
old_shift = uport->regshift;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free and release old regions
|
* Free and release old regions
|
||||||
*/
|
*/
|
||||||
if (old_type != PORT_UNKNOWN)
|
if (old_type != PORT_UNKNOWN)
|
||||||
port->ops->release_port(port);
|
uport->ops->release_port(uport);
|
||||||
|
|
||||||
port->iobase = new_port;
|
uport->iobase = new_port;
|
||||||
port->type = new_serial.type;
|
uport->type = new_serial.type;
|
||||||
port->hub6 = new_serial.hub6;
|
uport->hub6 = new_serial.hub6;
|
||||||
port->iotype = new_serial.io_type;
|
uport->iotype = new_serial.io_type;
|
||||||
port->regshift = new_serial.iomem_reg_shift;
|
uport->regshift = new_serial.iomem_reg_shift;
|
||||||
port->mapbase = (unsigned long)new_serial.iomem_base;
|
uport->mapbase = (unsigned long)new_serial.iomem_base;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Claim and map the new regions
|
* Claim and map the new regions
|
||||||
*/
|
*/
|
||||||
if (port->type != PORT_UNKNOWN) {
|
if (uport->type != PORT_UNKNOWN) {
|
||||||
retval = port->ops->request_port(port);
|
retval = uport->ops->request_port(uport);
|
||||||
} else {
|
} else {
|
||||||
/* Always success - Jean II */
|
/* Always success - Jean II */
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
@ -804,19 +806,19 @@ static int uart_set_info(struct uart_state *state,
|
||||||
* new port, try to restore the old settings.
|
* new port, try to restore the old settings.
|
||||||
*/
|
*/
|
||||||
if (retval && old_type != PORT_UNKNOWN) {
|
if (retval && old_type != PORT_UNKNOWN) {
|
||||||
port->iobase = old_iobase;
|
uport->iobase = old_iobase;
|
||||||
port->type = old_type;
|
uport->type = old_type;
|
||||||
port->hub6 = old_hub6;
|
uport->hub6 = old_hub6;
|
||||||
port->iotype = old_iotype;
|
uport->iotype = old_iotype;
|
||||||
port->regshift = old_shift;
|
uport->regshift = old_shift;
|
||||||
port->mapbase = old_mapbase;
|
uport->mapbase = old_mapbase;
|
||||||
retval = port->ops->request_port(port);
|
retval = uport->ops->request_port(uport);
|
||||||
/*
|
/*
|
||||||
* If we failed to restore the old settings,
|
* If we failed to restore the old settings,
|
||||||
* we fail like this.
|
* we fail like this.
|
||||||
*/
|
*/
|
||||||
if (retval)
|
if (retval)
|
||||||
port->type = PORT_UNKNOWN;
|
uport->type = PORT_UNKNOWN;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We failed anyway.
|
* We failed anyway.
|
||||||
|
@ -828,38 +830,38 @@ static int uart_set_info(struct uart_state *state,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (change_irq)
|
if (change_irq)
|
||||||
port->irq = new_serial.irq;
|
uport->irq = new_serial.irq;
|
||||||
if (!(port->flags & UPF_FIXED_PORT))
|
if (!(uport->flags & UPF_FIXED_PORT))
|
||||||
port->uartclk = new_serial.baud_base * 16;
|
uport->uartclk = new_serial.baud_base * 16;
|
||||||
port->flags = (port->flags & ~UPF_CHANGE_MASK) |
|
uport->flags = (uport->flags & ~UPF_CHANGE_MASK) |
|
||||||
(new_flags & UPF_CHANGE_MASK);
|
(new_flags & UPF_CHANGE_MASK);
|
||||||
port->custom_divisor = new_serial.custom_divisor;
|
uport->custom_divisor = new_serial.custom_divisor;
|
||||||
state->port.close_delay = close_delay;
|
port->close_delay = close_delay;
|
||||||
state->port.closing_wait = closing_wait;
|
port->closing_wait = closing_wait;
|
||||||
if (new_serial.xmit_fifo_size)
|
if (new_serial.xmit_fifo_size)
|
||||||
port->fifosize = new_serial.xmit_fifo_size;
|
uport->fifosize = new_serial.xmit_fifo_size;
|
||||||
if (state->port.tty)
|
if (port->tty)
|
||||||
state->port.tty->low_latency =
|
port->tty->low_latency =
|
||||||
(port->flags & UPF_LOW_LATENCY) ? 1 : 0;
|
(uport->flags & UPF_LOW_LATENCY) ? 1 : 0;
|
||||||
|
|
||||||
check_and_exit:
|
check_and_exit:
|
||||||
retval = 0;
|
retval = 0;
|
||||||
if (port->type == PORT_UNKNOWN)
|
if (uport->type == PORT_UNKNOWN)
|
||||||
goto exit;
|
goto exit;
|
||||||
if (state->flags & UIF_INITIALIZED) {
|
if (state->flags & UIF_INITIALIZED) {
|
||||||
if (((old_flags ^ port->flags) & UPF_SPD_MASK) ||
|
if (((old_flags ^ uport->flags) & UPF_SPD_MASK) ||
|
||||||
old_custom_divisor != port->custom_divisor) {
|
old_custom_divisor != uport->custom_divisor) {
|
||||||
/*
|
/*
|
||||||
* If they're setting up a custom divisor or speed,
|
* If they're setting up a custom divisor or speed,
|
||||||
* instead of clearing it, then bitch about it. No
|
* instead of clearing it, then bitch about it. No
|
||||||
* need to rate-limit; it's CAP_SYS_ADMIN only.
|
* need to rate-limit; it's CAP_SYS_ADMIN only.
|
||||||
*/
|
*/
|
||||||
if (port->flags & UPF_SPD_MASK) {
|
if (uport->flags & UPF_SPD_MASK) {
|
||||||
char buf[64];
|
char buf[64];
|
||||||
printk(KERN_NOTICE
|
printk(KERN_NOTICE
|
||||||
"%s sets custom speed on %s. This "
|
"%s sets custom speed on %s. This "
|
||||||
"is deprecated.\n", current->comm,
|
"is deprecated.\n", current->comm,
|
||||||
tty_name(state->port.tty, buf));
|
tty_name(port->tty, buf));
|
||||||
}
|
}
|
||||||
uart_change_speed(state, NULL);
|
uart_change_speed(state, NULL);
|
||||||
}
|
}
|
||||||
|
@ -878,10 +880,11 @@ static int uart_set_info(struct uart_state *state,
|
||||||
static int uart_get_lsr_info(struct uart_state *state,
|
static int uart_get_lsr_info(struct uart_state *state,
|
||||||
unsigned int __user *value)
|
unsigned int __user *value)
|
||||||
{
|
{
|
||||||
struct uart_port *port = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
|
struct tty_port *port = &state->port;
|
||||||
unsigned int result;
|
unsigned int result;
|
||||||
|
|
||||||
result = port->ops->tx_empty(port);
|
result = uport->ops->tx_empty(uport);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we're about to load something into the transmit
|
* If we're about to load something into the transmit
|
||||||
|
@ -889,9 +892,9 @@ static int uart_get_lsr_info(struct uart_state *state,
|
||||||
* avoid a race condition (depending on when the transmit
|
* avoid a race condition (depending on when the transmit
|
||||||
* interrupt happens).
|
* interrupt happens).
|
||||||
*/
|
*/
|
||||||
if (port->x_char ||
|
if (uport->x_char ||
|
||||||
((uart_circ_chars_pending(&state->xmit) > 0) &&
|
((uart_circ_chars_pending(&state->xmit) > 0) &&
|
||||||
!state->port.tty->stopped && !state->port.tty->hw_stopped))
|
!port->tty->stopped && !port->tty->hw_stopped))
|
||||||
result &= ~TIOCSER_TEMT;
|
result &= ~TIOCSER_TEMT;
|
||||||
|
|
||||||
return put_user(result, value);
|
return put_user(result, value);
|
||||||
|
@ -900,17 +903,17 @@ static int uart_get_lsr_info(struct uart_state *state,
|
||||||
static int uart_tiocmget(struct tty_struct *tty, struct file *file)
|
static int uart_tiocmget(struct tty_struct *tty, struct file *file)
|
||||||
{
|
{
|
||||||
struct uart_state *state = tty->driver_data;
|
struct uart_state *state = tty->driver_data;
|
||||||
struct uart_port *port = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
int result = -EIO;
|
int result = -EIO;
|
||||||
|
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&state->mutex);
|
||||||
if ((!file || !tty_hung_up_p(file)) &&
|
if ((!file || !tty_hung_up_p(file)) &&
|
||||||
!(tty->flags & (1 << TTY_IO_ERROR))) {
|
!(tty->flags & (1 << TTY_IO_ERROR))) {
|
||||||
result = port->mctrl;
|
result = uport->mctrl;
|
||||||
|
|
||||||
spin_lock_irq(&port->lock);
|
spin_lock_irq(&uport->lock);
|
||||||
result |= port->ops->get_mctrl(port);
|
result |= uport->ops->get_mctrl(uport);
|
||||||
spin_unlock_irq(&port->lock);
|
spin_unlock_irq(&uport->lock);
|
||||||
}
|
}
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&state->mutex);
|
||||||
|
|
||||||
|
@ -922,13 +925,13 @@ uart_tiocmset(struct tty_struct *tty, struct file *file,
|
||||||
unsigned int set, unsigned int clear)
|
unsigned int set, unsigned int clear)
|
||||||
{
|
{
|
||||||
struct uart_state *state = tty->driver_data;
|
struct uart_state *state = tty->driver_data;
|
||||||
struct uart_port *port = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
int ret = -EIO;
|
int ret = -EIO;
|
||||||
|
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&state->mutex);
|
||||||
if ((!file || !tty_hung_up_p(file)) &&
|
if ((!file || !tty_hung_up_p(file)) &&
|
||||||
!(tty->flags & (1 << TTY_IO_ERROR))) {
|
!(tty->flags & (1 << TTY_IO_ERROR))) {
|
||||||
uart_update_mctrl(port, set, clear);
|
uart_update_mctrl(uport, set, clear);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&state->mutex);
|
||||||
|
@ -938,12 +941,12 @@ uart_tiocmset(struct tty_struct *tty, struct file *file,
|
||||||
static int uart_break_ctl(struct tty_struct *tty, int break_state)
|
static int uart_break_ctl(struct tty_struct *tty, int break_state)
|
||||||
{
|
{
|
||||||
struct uart_state *state = tty->driver_data;
|
struct uart_state *state = tty->driver_data;
|
||||||
struct uart_port *port = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
|
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&state->mutex);
|
||||||
|
|
||||||
if (port->type != PORT_UNKNOWN)
|
if (uport->type != PORT_UNKNOWN)
|
||||||
port->ops->break_ctl(port, break_state);
|
uport->ops->break_ctl(uport, break_state);
|
||||||
|
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&state->mutex);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -951,7 +954,7 @@ static int uart_break_ctl(struct tty_struct *tty, int break_state)
|
||||||
|
|
||||||
static int uart_do_autoconfig(struct uart_state *state)
|
static int uart_do_autoconfig(struct uart_state *state)
|
||||||
{
|
{
|
||||||
struct uart_port *port = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
int flags, ret;
|
int flags, ret;
|
||||||
|
|
||||||
if (!capable(CAP_SYS_ADMIN))
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
|
@ -973,18 +976,18 @@ static int uart_do_autoconfig(struct uart_state *state)
|
||||||
* If we already have a port type configured,
|
* If we already have a port type configured,
|
||||||
* we must release its resources.
|
* we must release its resources.
|
||||||
*/
|
*/
|
||||||
if (port->type != PORT_UNKNOWN)
|
if (uport->type != PORT_UNKNOWN)
|
||||||
port->ops->release_port(port);
|
uport->ops->release_port(uport);
|
||||||
|
|
||||||
flags = UART_CONFIG_TYPE;
|
flags = UART_CONFIG_TYPE;
|
||||||
if (port->flags & UPF_AUTO_IRQ)
|
if (uport->flags & UPF_AUTO_IRQ)
|
||||||
flags |= UART_CONFIG_IRQ;
|
flags |= UART_CONFIG_IRQ;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This will claim the ports resources if
|
* This will claim the ports resources if
|
||||||
* a port is found.
|
* a port is found.
|
||||||
*/
|
*/
|
||||||
port->ops->config_port(port, flags);
|
uport->ops->config_port(uport, flags);
|
||||||
|
|
||||||
ret = uart_startup(state, 1);
|
ret = uart_startup(state, 1);
|
||||||
}
|
}
|
||||||
|
@ -1001,7 +1004,7 @@ static int uart_do_autoconfig(struct uart_state *state)
|
||||||
static int
|
static int
|
||||||
uart_wait_modem_status(struct uart_state *state, unsigned long arg)
|
uart_wait_modem_status(struct uart_state *state, unsigned long arg)
|
||||||
{
|
{
|
||||||
struct uart_port *port = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
DECLARE_WAITQUEUE(wait, current);
|
DECLARE_WAITQUEUE(wait, current);
|
||||||
struct uart_icount cprev, cnow;
|
struct uart_icount cprev, cnow;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -1009,20 +1012,20 @@ uart_wait_modem_status(struct uart_state *state, unsigned long arg)
|
||||||
/*
|
/*
|
||||||
* note the counters on entry
|
* note the counters on entry
|
||||||
*/
|
*/
|
||||||
spin_lock_irq(&port->lock);
|
spin_lock_irq(&uport->lock);
|
||||||
memcpy(&cprev, &port->icount, sizeof(struct uart_icount));
|
memcpy(&cprev, &uport->icount, sizeof(struct uart_icount));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Force modem status interrupts on
|
* Force modem status interrupts on
|
||||||
*/
|
*/
|
||||||
port->ops->enable_ms(port);
|
uport->ops->enable_ms(uport);
|
||||||
spin_unlock_irq(&port->lock);
|
spin_unlock_irq(&uport->lock);
|
||||||
|
|
||||||
add_wait_queue(&state->delta_msr_wait, &wait);
|
add_wait_queue(&state->delta_msr_wait, &wait);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
spin_lock_irq(&port->lock);
|
spin_lock_irq(&uport->lock);
|
||||||
memcpy(&cnow, &port->icount, sizeof(struct uart_icount));
|
memcpy(&cnow, &uport->icount, sizeof(struct uart_icount));
|
||||||
spin_unlock_irq(&port->lock);
|
spin_unlock_irq(&uport->lock);
|
||||||
|
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
|
|
||||||
|
@ -1062,11 +1065,11 @@ static int uart_get_count(struct uart_state *state,
|
||||||
{
|
{
|
||||||
struct serial_icounter_struct icount;
|
struct serial_icounter_struct icount;
|
||||||
struct uart_icount cnow;
|
struct uart_icount cnow;
|
||||||
struct uart_port *port = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
|
|
||||||
spin_lock_irq(&port->lock);
|
spin_lock_irq(&uport->lock);
|
||||||
memcpy(&cnow, &port->icount, sizeof(struct uart_icount));
|
memcpy(&cnow, &uport->icount, sizeof(struct uart_icount));
|
||||||
spin_unlock_irq(&port->lock);
|
spin_unlock_irq(&uport->lock);
|
||||||
|
|
||||||
icount.cts = cnow.cts;
|
icount.cts = cnow.cts;
|
||||||
icount.dsr = cnow.dsr;
|
icount.dsr = cnow.dsr;
|
||||||
|
@ -1158,9 +1161,9 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
struct uart_port *port = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
if (port->ops->ioctl)
|
if (uport->ops->ioctl)
|
||||||
ret = port->ops->ioctl(port, cmd, arg);
|
ret = uport->ops->ioctl(uport, cmd, arg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1173,10 +1176,10 @@ out:
|
||||||
static void uart_set_ldisc(struct tty_struct *tty)
|
static void uart_set_ldisc(struct tty_struct *tty)
|
||||||
{
|
{
|
||||||
struct uart_state *state = tty->driver_data;
|
struct uart_state *state = tty->driver_data;
|
||||||
struct uart_port *port = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
|
|
||||||
if (port->ops->set_ldisc)
|
if (uport->ops->set_ldisc)
|
||||||
port->ops->set_ldisc(port);
|
uport->ops->set_ldisc(uport);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uart_set_termios(struct tty_struct *tty,
|
static void uart_set_termios(struct tty_struct *tty,
|
||||||
|
@ -1254,16 +1257,15 @@ static void uart_set_termios(struct tty_struct *tty,
|
||||||
static void uart_close(struct tty_struct *tty, struct file *filp)
|
static void uart_close(struct tty_struct *tty, struct file *filp)
|
||||||
{
|
{
|
||||||
struct uart_state *state = tty->driver_data;
|
struct uart_state *state = tty->driver_data;
|
||||||
struct uart_port *port;
|
struct tty_port *port;
|
||||||
|
struct uart_port *uport;
|
||||||
|
|
||||||
BUG_ON(!kernel_locked());
|
BUG_ON(!kernel_locked());
|
||||||
|
|
||||||
if (!state || !state->uart_port)
|
uport = state->uart_port;
|
||||||
return;
|
port = &state->port;
|
||||||
|
|
||||||
port = state->uart_port;
|
pr_debug("uart_close(%d) called\n", uport->line);
|
||||||
|
|
||||||
pr_debug("uart_close(%d) called\n", port->line);
|
|
||||||
|
|
||||||
mutex_lock(&state->mutex);
|
mutex_lock(&state->mutex);
|
||||||
|
|
||||||
|
@ -1297,8 +1299,8 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
|
||||||
*/
|
*/
|
||||||
tty->closing = 1;
|
tty->closing = 1;
|
||||||
|
|
||||||
if (state->port.closing_wait != USF_CLOSING_WAIT_NONE)
|
if (port->closing_wait != USF_CLOSING_WAIT_NONE)
|
||||||
tty_wait_until_sent(tty, msecs_to_jiffies(state->port.closing_wait));
|
tty_wait_until_sent(tty, msecs_to_jiffies(port->closing_wait));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At this point, we stop accepting input. To do this, we
|
* At this point, we stop accepting input. To do this, we
|
||||||
|
@ -1307,14 +1309,14 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
|
||||||
if (state->flags & UIF_INITIALIZED) {
|
if (state->flags & UIF_INITIALIZED) {
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
spin_lock_irqsave(&port->lock, flags);
|
spin_lock_irqsave(&port->lock, flags);
|
||||||
port->ops->stop_rx(port);
|
uport->ops->stop_rx(uport);
|
||||||
spin_unlock_irqrestore(&port->lock, flags);
|
spin_unlock_irqrestore(&port->lock, flags);
|
||||||
/*
|
/*
|
||||||
* Before we drop DTR, make sure the UART transmitter
|
* Before we drop DTR, make sure the UART transmitter
|
||||||
* has completely drained; this is especially
|
* has completely drained; this is especially
|
||||||
* important if there is a transmit FIFO!
|
* important if there is a transmit FIFO!
|
||||||
*/
|
*/
|
||||||
uart_wait_until_sent(tty, port->timeout);
|
uart_wait_until_sent(tty, uport->timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
uart_shutdown(state);
|
uart_shutdown(state);
|
||||||
|
@ -1323,12 +1325,12 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
|
||||||
tty_ldisc_flush(tty);
|
tty_ldisc_flush(tty);
|
||||||
|
|
||||||
tty->closing = 0;
|
tty->closing = 0;
|
||||||
state->port.tty = NULL;
|
port->tty = NULL;
|
||||||
|
|
||||||
if (state->port.blocked_open) {
|
if (port->blocked_open) {
|
||||||
if (state->port.close_delay)
|
if (port->close_delay)
|
||||||
msleep_interruptible(state->port.close_delay);
|
msleep_interruptible(port->close_delay);
|
||||||
} else if (!uart_console(port)) {
|
} else if (!uart_console(uport)) {
|
||||||
uart_change_pm(state, 3);
|
uart_change_pm(state, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1336,9 +1338,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
|
||||||
* Wake up anyone trying to open this port.
|
* Wake up anyone trying to open this port.
|
||||||
*/
|
*/
|
||||||
state->flags &= ~UIF_NORMAL_ACTIVE;
|
state->flags &= ~UIF_NORMAL_ACTIVE;
|
||||||
wake_up_interruptible(&state->port.open_wait);
|
wake_up_interruptible(&port->open_wait);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&state->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1410,6 +1412,7 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||||
static void uart_hangup(struct tty_struct *tty)
|
static void uart_hangup(struct tty_struct *tty)
|
||||||
{
|
{
|
||||||
struct uart_state *state = tty->driver_data;
|
struct uart_state *state = tty->driver_data;
|
||||||
|
struct tty_port *port = &state->port;
|
||||||
|
|
||||||
BUG_ON(!kernel_locked());
|
BUG_ON(!kernel_locked());
|
||||||
pr_debug("uart_hangup(%d)\n", state->uart_port->line);
|
pr_debug("uart_hangup(%d)\n", state->uart_port->line);
|
||||||
|
@ -1420,8 +1423,8 @@ static void uart_hangup(struct tty_struct *tty)
|
||||||
uart_shutdown(state);
|
uart_shutdown(state);
|
||||||
state->count = 0;
|
state->count = 0;
|
||||||
state->flags &= ~UIF_NORMAL_ACTIVE;
|
state->flags &= ~UIF_NORMAL_ACTIVE;
|
||||||
state->port.tty = NULL;
|
port->tty = NULL;
|
||||||
wake_up_interruptible(&state->port.open_wait);
|
wake_up_interruptible(&port->open_wait);
|
||||||
wake_up_interruptible(&state->delta_msr_wait);
|
wake_up_interruptible(&state->delta_msr_wait);
|
||||||
}
|
}
|
||||||
mutex_unlock(&state->mutex);
|
mutex_unlock(&state->mutex);
|
||||||
|
@ -1470,20 +1473,21 @@ static int
|
||||||
uart_block_til_ready(struct file *filp, struct uart_state *state)
|
uart_block_til_ready(struct file *filp, struct uart_state *state)
|
||||||
{
|
{
|
||||||
DECLARE_WAITQUEUE(wait, current);
|
DECLARE_WAITQUEUE(wait, current);
|
||||||
struct uart_port *port = state->uart_port;
|
struct uart_port *uport = state->uart_port;
|
||||||
|
struct tty_port *port = &state->port;
|
||||||
unsigned int mctrl;
|
unsigned int mctrl;
|
||||||
|
|
||||||
state->port.blocked_open++;
|
port->blocked_open++;
|
||||||
state->count--;
|
state->count--;
|
||||||
|
|
||||||
add_wait_queue(&state->port.open_wait, &wait);
|
add_wait_queue(&port->open_wait, &wait);
|
||||||
while (1) {
|
while (1) {
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we have been hung up, tell userspace/restart open.
|
* If we have been hung up, tell userspace/restart open.
|
||||||
*/
|
*/
|
||||||
if (tty_hung_up_p(filp) || state->port.tty == NULL)
|
if (tty_hung_up_p(filp) || port->tty == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1502,8 +1506,8 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
|
||||||
* have set TTY_IO_ERROR for a non-existant port.
|
* have set TTY_IO_ERROR for a non-existant port.
|
||||||
*/
|
*/
|
||||||
if ((filp->f_flags & O_NONBLOCK) ||
|
if ((filp->f_flags & O_NONBLOCK) ||
|
||||||
(state->port.tty->termios->c_cflag & CLOCAL) ||
|
(port->tty->termios->c_cflag & CLOCAL) ||
|
||||||
(state->port.tty->flags & (1 << TTY_IO_ERROR)))
|
(port->tty->flags & (1 << TTY_IO_ERROR)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1511,17 +1515,17 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
|
||||||
* not set RTS here - we want to make sure we catch
|
* not set RTS here - we want to make sure we catch
|
||||||
* the data from the modem.
|
* the data from the modem.
|
||||||
*/
|
*/
|
||||||
if (state->port.tty->termios->c_cflag & CBAUD)
|
if (port->tty->termios->c_cflag & CBAUD)
|
||||||
uart_set_mctrl(port, TIOCM_DTR);
|
uart_set_mctrl(uport, TIOCM_DTR);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* and wait for the carrier to indicate that the
|
* and wait for the carrier to indicate that the
|
||||||
* modem is ready for us.
|
* modem is ready for us.
|
||||||
*/
|
*/
|
||||||
spin_lock_irq(&port->lock);
|
spin_lock_irq(&uport->lock);
|
||||||
port->ops->enable_ms(port);
|
uport->ops->enable_ms(uport);
|
||||||
mctrl = port->ops->get_mctrl(port);
|
mctrl = uport->ops->get_mctrl(uport);
|
||||||
spin_unlock_irq(&port->lock);
|
spin_unlock_irq(&uport->lock);
|
||||||
if (mctrl & TIOCM_CAR)
|
if (mctrl & TIOCM_CAR)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1533,15 +1537,15 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
set_current_state(TASK_RUNNING);
|
set_current_state(TASK_RUNNING);
|
||||||
remove_wait_queue(&state->port.open_wait, &wait);
|
remove_wait_queue(&port->open_wait, &wait);
|
||||||
|
|
||||||
state->count++;
|
state->count++;
|
||||||
state->port.blocked_open--;
|
port->blocked_open--;
|
||||||
|
|
||||||
if (signal_pending(current))
|
if (signal_pending(current))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
if (!state->port.tty || tty_hung_up_p(filp))
|
if (!port->tty || tty_hung_up_p(filp))
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue