提交 216ba023 编写于 作者: A Alan Cox 提交者: Linus Torvalds

mxser: Switch to kref tty

Signed-off-by: NAlan Cox <alan@redhat.com>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 d18a750f
...@@ -610,15 +610,16 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, ...@@ -610,15 +610,16 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp,
return 0; return 0;
} }
static int mxser_set_baud(struct mxser_port *info, long newspd) static int mxser_set_baud(struct tty_struct *tty, long newspd)
{ {
struct mxser_port *info = tty->driver_data;
int quot = 0, baud; int quot = 0, baud;
unsigned char cval; unsigned char cval;
if (!info->port.tty || !info->port.tty->termios) if (!tty->termios)
return -1; return -1;
if (!(info->ioaddr)) if (!info->ioaddr)
return -1; return -1;
if (newspd > info->max_baud) if (newspd > info->max_baud)
...@@ -626,13 +627,13 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) ...@@ -626,13 +627,13 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
if (newspd == 134) { if (newspd == 134) {
quot = 2 * info->baud_base / 269; quot = 2 * info->baud_base / 269;
tty_encode_baud_rate(info->port.tty, 134, 134); tty_encode_baud_rate(tty, 134, 134);
} else if (newspd) { } else if (newspd) {
quot = info->baud_base / newspd; quot = info->baud_base / newspd;
if (quot == 0) if (quot == 0)
quot = 1; quot = 1;
baud = info->baud_base/quot; baud = info->baud_base/quot;
tty_encode_baud_rate(info->port.tty, baud, baud); tty_encode_baud_rate(tty, baud, baud);
} else { } else {
quot = 0; quot = 0;
} }
...@@ -658,7 +659,7 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) ...@@ -658,7 +659,7 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */
#ifdef BOTHER #ifdef BOTHER
if (C_BAUD(info->port.tty) == BOTHER) { if (C_BAUD(tty) == BOTHER) {
quot = info->baud_base % newspd; quot = info->baud_base % newspd;
quot *= 8; quot *= 8;
if (quot % newspd > newspd / 2) { if (quot % newspd > newspd / 2) {
...@@ -679,21 +680,22 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) ...@@ -679,21 +680,22 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
* This routine is called to set the UART divisor registers to match * This routine is called to set the UART divisor registers to match
* the specified baud rate for a serial port. * the specified baud rate for a serial port.
*/ */
static int mxser_change_speed(struct mxser_port *info, static int mxser_change_speed(struct tty_struct *tty,
struct ktermios *old_termios) struct ktermios *old_termios)
{ {
struct mxser_port *info = tty->driver_data;
unsigned cflag, cval, fcr; unsigned cflag, cval, fcr;
int ret = 0; int ret = 0;
unsigned char status; unsigned char status;
if (!info->port.tty || !info->port.tty->termios) if (!tty->termios)
return ret; return ret;
cflag = info->port.tty->termios->c_cflag; cflag = tty->termios->c_cflag;
if (!(info->ioaddr)) if (!info->ioaddr)
return ret; return ret;
if (mxser_set_baud_method[info->port.tty->index] == 0) if (mxser_set_baud_method[tty->index] == 0)
mxser_set_baud(info, tty_get_baud_rate(info->port.tty)); mxser_set_baud(tty, tty_get_baud_rate(tty));
/* byte size and parity */ /* byte size and parity */
switch (cflag & CSIZE) { switch (cflag & CSIZE) {
...@@ -762,9 +764,9 @@ static int mxser_change_speed(struct mxser_port *info, ...@@ -762,9 +764,9 @@ static int mxser_change_speed(struct mxser_port *info,
info->MCR |= UART_MCR_AFE; info->MCR |= UART_MCR_AFE;
} else { } else {
status = inb(info->ioaddr + UART_MSR); status = inb(info->ioaddr + UART_MSR);
if (info->port.tty->hw_stopped) { if (tty->hw_stopped) {
if (status & UART_MSR_CTS) { if (status & UART_MSR_CTS) {
info->port.tty->hw_stopped = 0; tty->hw_stopped = 0;
if (info->type != PORT_16550A && if (info->type != PORT_16550A &&
!info->board->chip_flag) { !info->board->chip_flag) {
outb(info->IER & ~UART_IER_THRI, outb(info->IER & ~UART_IER_THRI,
...@@ -774,11 +776,11 @@ static int mxser_change_speed(struct mxser_port *info, ...@@ -774,11 +776,11 @@ static int mxser_change_speed(struct mxser_port *info,
outb(info->IER, info->ioaddr + outb(info->IER, info->ioaddr +
UART_IER); UART_IER);
} }
tty_wakeup(info->port.tty); tty_wakeup(tty);
} }
} else { } else {
if (!(status & UART_MSR_CTS)) { if (!(status & UART_MSR_CTS)) {
info->port.tty->hw_stopped = 1; tty->hw_stopped = 1;
if ((info->type != PORT_16550A) && if ((info->type != PORT_16550A) &&
(!info->board->chip_flag)) { (!info->board->chip_flag)) {
info->IER &= ~UART_IER_THRI; info->IER &= ~UART_IER_THRI;
...@@ -804,21 +806,21 @@ static int mxser_change_speed(struct mxser_port *info, ...@@ -804,21 +806,21 @@ static int mxser_change_speed(struct mxser_port *info,
* Set up parity check flag * Set up parity check flag
*/ */
info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
if (I_INPCK(info->port.tty)) if (I_INPCK(tty))
info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) if (I_BRKINT(tty) || I_PARMRK(tty))
info->read_status_mask |= UART_LSR_BI; info->read_status_mask |= UART_LSR_BI;
info->ignore_status_mask = 0; info->ignore_status_mask = 0;
if (I_IGNBRK(info->port.tty)) { if (I_IGNBRK(tty)) {
info->ignore_status_mask |= UART_LSR_BI; info->ignore_status_mask |= UART_LSR_BI;
info->read_status_mask |= UART_LSR_BI; info->read_status_mask |= UART_LSR_BI;
/* /*
* If we're ignore parity and break indicators, ignore * If we're ignore parity and break indicators, ignore
* overruns too. (For real raw support). * overruns too. (For real raw support).
*/ */
if (I_IGNPAR(info->port.tty)) { if (I_IGNPAR(tty)) {
info->ignore_status_mask |= info->ignore_status_mask |=
UART_LSR_OE | UART_LSR_OE |
UART_LSR_PE | UART_LSR_PE |
...@@ -830,16 +832,16 @@ static int mxser_change_speed(struct mxser_port *info, ...@@ -830,16 +832,16 @@ static int mxser_change_speed(struct mxser_port *info,
} }
} }
if (info->board->chip_flag) { if (info->board->chip_flag) {
mxser_set_must_xon1_value(info->ioaddr, START_CHAR(info->port.tty)); mxser_set_must_xon1_value(info->ioaddr, START_CHAR(tty));
mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(info->port.tty)); mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(tty));
if (I_IXON(info->port.tty)) { if (I_IXON(tty)) {
mxser_enable_must_rx_software_flow_control( mxser_enable_must_rx_software_flow_control(
info->ioaddr); info->ioaddr);
} else { } else {
mxser_disable_must_rx_software_flow_control( mxser_disable_must_rx_software_flow_control(
info->ioaddr); info->ioaddr);
} }
if (I_IXOFF(info->port.tty)) { if (I_IXOFF(tty)) {
mxser_enable_must_tx_software_flow_control( mxser_enable_must_tx_software_flow_control(
info->ioaddr); info->ioaddr);
} else { } else {
...@@ -855,7 +857,8 @@ static int mxser_change_speed(struct mxser_port *info, ...@@ -855,7 +857,8 @@ static int mxser_change_speed(struct mxser_port *info,
return ret; return ret;
} }
static void mxser_check_modem_status(struct mxser_port *port, int status) static void mxser_check_modem_status(struct tty_struct *tty,
struct mxser_port *port, int status)
{ {
/* update input line counters */ /* update input line counters */
if (status & UART_MSR_TERI) if (status & UART_MSR_TERI)
...@@ -874,10 +877,11 @@ static void mxser_check_modem_status(struct mxser_port *port, int status) ...@@ -874,10 +877,11 @@ static void mxser_check_modem_status(struct mxser_port *port, int status)
wake_up_interruptible(&port->port.open_wait); wake_up_interruptible(&port->port.open_wait);
} }
tty = tty_port_tty_get(&port->port);
if (port->port.flags & ASYNC_CTS_FLOW) { if (port->port.flags & ASYNC_CTS_FLOW) {
if (port->port.tty->hw_stopped) { if (tty->hw_stopped) {
if (status & UART_MSR_CTS) { if (status & UART_MSR_CTS) {
port->port.tty->hw_stopped = 0; tty->hw_stopped = 0;
if ((port->type != PORT_16550A) && if ((port->type != PORT_16550A) &&
(!port->board->chip_flag)) { (!port->board->chip_flag)) {
...@@ -887,11 +891,11 @@ static void mxser_check_modem_status(struct mxser_port *port, int status) ...@@ -887,11 +891,11 @@ static void mxser_check_modem_status(struct mxser_port *port, int status)
outb(port->IER, port->ioaddr + outb(port->IER, port->ioaddr +
UART_IER); UART_IER);
} }
tty_wakeup(port->port.tty); tty_wakeup(tty);
} }
} else { } else {
if (!(status & UART_MSR_CTS)) { if (!(status & UART_MSR_CTS)) {
port->port.tty->hw_stopped = 1; tty->hw_stopped = 1;
if (port->type != PORT_16550A && if (port->type != PORT_16550A &&
!port->board->chip_flag) { !port->board->chip_flag) {
port->IER &= ~UART_IER_THRI; port->IER &= ~UART_IER_THRI;
...@@ -903,8 +907,9 @@ static void mxser_check_modem_status(struct mxser_port *port, int status) ...@@ -903,8 +907,9 @@ static void mxser_check_modem_status(struct mxser_port *port, int status)
} }
} }
static int mxser_startup(struct mxser_port *info) static int mxser_startup(struct tty_struct *tty)
{ {
struct mxser_port *info = tty->driver_data;
unsigned long page; unsigned long page;
unsigned long flags; unsigned long flags;
...@@ -921,8 +926,7 @@ static int mxser_startup(struct mxser_port *info) ...@@ -921,8 +926,7 @@ static int mxser_startup(struct mxser_port *info)
} }
if (!info->ioaddr || !info->type) { if (!info->ioaddr || !info->type) {
if (info->port.tty) set_bit(TTY_IO_ERROR, &tty->flags);
set_bit(TTY_IO_ERROR, &info->port.tty->flags);
free_page(page); free_page(page);
spin_unlock_irqrestore(&info->slock, flags); spin_unlock_irqrestore(&info->slock, flags);
return 0; return 0;
...@@ -952,8 +956,8 @@ static int mxser_startup(struct mxser_port *info) ...@@ -952,8 +956,8 @@ static int mxser_startup(struct mxser_port *info)
if (inb(info->ioaddr + UART_LSR) == 0xff) { if (inb(info->ioaddr + UART_LSR) == 0xff) {
spin_unlock_irqrestore(&info->slock, flags); spin_unlock_irqrestore(&info->slock, flags);
if (capable(CAP_SYS_ADMIN)) { if (capable(CAP_SYS_ADMIN)) {
if (info->port.tty) if (tty)
set_bit(TTY_IO_ERROR, &info->port.tty->flags); set_bit(TTY_IO_ERROR, &tty->flags);
return 0; return 0;
} else } else
return -ENODEV; return -ENODEV;
...@@ -991,14 +995,13 @@ static int mxser_startup(struct mxser_port *info) ...@@ -991,14 +995,13 @@ static int mxser_startup(struct mxser_port *info)
(void) inb(info->ioaddr + UART_IIR); (void) inb(info->ioaddr + UART_IIR);
(void) inb(info->ioaddr + UART_MSR); (void) inb(info->ioaddr + UART_MSR);
if (info->port.tty) clear_bit(TTY_IO_ERROR, &tty->flags);
clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
/* /*
* and set the speed of the serial port * and set the speed of the serial port
*/ */
mxser_change_speed(info, NULL); mxser_change_speed(tty, NULL);
info->port.flags |= ASYNC_INITIALIZED; info->port.flags |= ASYNC_INITIALIZED;
spin_unlock_irqrestore(&info->slock, flags); spin_unlock_irqrestore(&info->slock, flags);
...@@ -1009,8 +1012,9 @@ static int mxser_startup(struct mxser_port *info) ...@@ -1009,8 +1012,9 @@ static int mxser_startup(struct mxser_port *info)
* This routine will shutdown a serial port; interrupts maybe disabled, and * This routine will shutdown a serial port; interrupts maybe disabled, and
* DTR is dropped if the hangup on close termio flag is on. * DTR is dropped if the hangup on close termio flag is on.
*/ */
static void mxser_shutdown(struct mxser_port *info) static void mxser_shutdown(struct tty_struct *tty)
{ {
struct mxser_port *info = tty->driver_data;
unsigned long flags; unsigned long flags;
if (!(info->port.flags & ASYNC_INITIALIZED)) if (!(info->port.flags & ASYNC_INITIALIZED))
...@@ -1035,7 +1039,7 @@ static void mxser_shutdown(struct mxser_port *info) ...@@ -1035,7 +1039,7 @@ static void mxser_shutdown(struct mxser_port *info)
info->IER = 0; info->IER = 0;
outb(0x00, info->ioaddr + UART_IER); outb(0x00, info->ioaddr + UART_IER);
if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) if (tty->termios->c_cflag & HUPCL)
info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS); info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS);
outb(info->MCR, info->ioaddr + UART_MCR); outb(info->MCR, info->ioaddr + UART_MCR);
...@@ -1051,8 +1055,7 @@ static void mxser_shutdown(struct mxser_port *info) ...@@ -1051,8 +1055,7 @@ static void mxser_shutdown(struct mxser_port *info)
/* read data port to reset things */ /* read data port to reset things */
(void) inb(info->ioaddr + UART_RX); (void) inb(info->ioaddr + UART_RX);
if (info->port.tty) set_bit(TTY_IO_ERROR, &tty->flags);
set_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->port.flags &= ~ASYNC_INITIALIZED; info->port.flags &= ~ASYNC_INITIALIZED;
...@@ -1084,14 +1087,14 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) ...@@ -1084,14 +1087,14 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
return -ENODEV; return -ENODEV;
tty->driver_data = info; tty->driver_data = info;
info->port.tty = tty; tty_port_tty_set(&info->port, tty);
/* /*
* Start up serial port * Start up serial port
*/ */
spin_lock_irqsave(&info->slock, flags); spin_lock_irqsave(&info->slock, flags);
info->port.count++; info->port.count++;
spin_unlock_irqrestore(&info->slock, flags); spin_unlock_irqrestore(&info->slock, flags);
retval = mxser_startup(info); retval = mxser_startup(tty);
if (retval) if (retval)
return retval; return retval;
...@@ -1209,13 +1212,13 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) ...@@ -1209,13 +1212,13 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
break; break;
} }
} }
mxser_shutdown(info); mxser_shutdown(tty);
mxser_flush_buffer(tty); mxser_flush_buffer(tty);
tty_ldisc_flush(tty); tty_ldisc_flush(tty);
tty->closing = 0; tty->closing = 0;
info->port.tty = NULL; tty_port_tty_set(&info->port, NULL);
if (info->port.blocked_open) { if (info->port.blocked_open) {
if (info->port.close_delay) if (info->port.close_delay)
schedule_timeout_interruptible(info->port.close_delay); schedule_timeout_interruptible(info->port.close_delay);
...@@ -1337,12 +1340,13 @@ static int mxser_chars_in_buffer(struct tty_struct *tty) ...@@ -1337,12 +1340,13 @@ static int mxser_chars_in_buffer(struct tty_struct *tty)
* friends of mxser_ioctl() * friends of mxser_ioctl()
* ------------------------------------------------------------ * ------------------------------------------------------------
*/ */
static int mxser_get_serial_info(struct mxser_port *info, static int mxser_get_serial_info(struct tty_struct *tty,
struct serial_struct __user *retinfo) struct serial_struct __user *retinfo)
{ {
struct mxser_port *info = tty->driver_data;
struct serial_struct tmp = { struct serial_struct tmp = {
.type = info->type, .type = info->type,
.line = info->port.tty->index, .line = tty->index,
.port = info->ioaddr, .port = info->ioaddr,
.irq = info->board->irq, .irq = info->board->irq,
.flags = info->port.flags, .flags = info->port.flags,
...@@ -1357,9 +1361,10 @@ static int mxser_get_serial_info(struct mxser_port *info, ...@@ -1357,9 +1361,10 @@ static int mxser_get_serial_info(struct mxser_port *info,
return 0; return 0;
} }
static int mxser_set_serial_info(struct mxser_port *info, static int mxser_set_serial_info(struct tty_struct *tty,
struct serial_struct __user *new_info) struct serial_struct __user *new_info)
{ {
struct mxser_port *info = tty->driver_data;
struct serial_struct new_serial; struct serial_struct new_serial;
speed_t baud; speed_t baud;
unsigned long sl_flags; unsigned long sl_flags;
...@@ -1393,14 +1398,14 @@ static int mxser_set_serial_info(struct mxser_port *info, ...@@ -1393,14 +1398,14 @@ static int mxser_set_serial_info(struct mxser_port *info,
(new_serial.flags & ASYNC_FLAGS)); (new_serial.flags & ASYNC_FLAGS));
info->port.close_delay = new_serial.close_delay * HZ / 100; info->port.close_delay = new_serial.close_delay * HZ / 100;
info->port.closing_wait = new_serial.closing_wait * HZ / 100; info->port.closing_wait = new_serial.closing_wait * HZ / 100;
info->port.tty->low_latency = tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY)
(info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; ? 1 : 0;
if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
(new_serial.baud_base != info->baud_base || (new_serial.baud_base != info->baud_base ||
new_serial.custom_divisor != new_serial.custom_divisor !=
info->custom_divisor)) { info->custom_divisor)) {
baud = new_serial.baud_base / new_serial.custom_divisor; baud = new_serial.baud_base / new_serial.custom_divisor;
tty_encode_baud_rate(info->port.tty, baud, baud); tty_encode_baud_rate(tty, baud, baud);
} }
} }
...@@ -1411,11 +1416,11 @@ static int mxser_set_serial_info(struct mxser_port *info, ...@@ -1411,11 +1416,11 @@ static int mxser_set_serial_info(struct mxser_port *info,
if (info->port.flags & ASYNC_INITIALIZED) { if (info->port.flags & ASYNC_INITIALIZED) {
if (flags != (info->port.flags & ASYNC_SPD_MASK)) { if (flags != (info->port.flags & ASYNC_SPD_MASK)) {
spin_lock_irqsave(&info->slock, sl_flags); spin_lock_irqsave(&info->slock, sl_flags);
mxser_change_speed(info, NULL); mxser_change_speed(tty, NULL);
spin_unlock_irqrestore(&info->slock, sl_flags); spin_unlock_irqrestore(&info->slock, sl_flags);
} }
} else } else
retval = mxser_startup(info); retval = mxser_startup(tty);
return retval; return retval;
} }
...@@ -1461,7 +1466,7 @@ static int mxser_tiocmget(struct tty_struct *tty, struct file *file) ...@@ -1461,7 +1466,7 @@ static int mxser_tiocmget(struct tty_struct *tty, struct file *file)
spin_lock_irqsave(&info->slock, flags); spin_lock_irqsave(&info->slock, flags);
status = inb(info->ioaddr + UART_MSR); status = inb(info->ioaddr + UART_MSR);
if (status & UART_MSR_ANY_DELTA) if (status & UART_MSR_ANY_DELTA)
mxser_check_modem_status(info, status); mxser_check_modem_status(tty, info, status);
spin_unlock_irqrestore(&info->slock, flags); spin_unlock_irqrestore(&info->slock, flags);
return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) |
((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) |
...@@ -1606,6 +1611,7 @@ static int __init mxser_read_register(int port, unsigned short *regs) ...@@ -1606,6 +1611,7 @@ static int __init mxser_read_register(int port, unsigned short *regs)
static int mxser_ioctl_special(unsigned int cmd, void __user *argp) static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
{ {
struct mxser_port *port; struct mxser_port *port;
struct tty_struct *tty;
int result, status; int result, status;
unsigned int i, j; unsigned int i, j;
int ret = 0; int ret = 0;
...@@ -1643,12 +1649,14 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) ...@@ -1643,12 +1649,14 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
if (!port->ioaddr) if (!port->ioaddr)
goto copy; goto copy;
tty = tty_port_tty_get(&port->port);
if (!port->port.tty || !port->port.tty->termios) if (!tty || !tty->termios)
ms.cflag = port->normal_termios.c_cflag; ms.cflag = port->normal_termios.c_cflag;
else else
ms.cflag = port->port.tty->termios->c_cflag; ms.cflag = tty->termios->c_cflag;
tty_kref_put(tty);
status = inb(port->ioaddr + UART_MSR); status = inb(port->ioaddr + UART_MSR);
if (status & UART_MSR_DCD) if (status & UART_MSR_DCD)
ms.dcd = 1; ms.dcd = 1;
...@@ -1704,15 +1712,18 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) ...@@ -1704,15 +1712,18 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
me->up_txcnt[p] = port->mon_data.up_txcnt; me->up_txcnt[p] = port->mon_data.up_txcnt;
me->modem_status[p] = me->modem_status[p] =
port->mon_data.modem_status; port->mon_data.modem_status;
me->baudrate[p] = tty_get_baud_rate(port->port.tty); tty = tty_port_tty_get(&port->port);
if (!port->port.tty || !port->port.tty->termios) { if (!tty || !tty->termios) {
cflag = port->normal_termios.c_cflag; cflag = port->normal_termios.c_cflag;
iflag = port->normal_termios.c_iflag; iflag = port->normal_termios.c_iflag;
me->baudrate[p] = tty_termios_baud_rate(&port->normal_termios);
} else { } else {
cflag = port->port.tty->termios->c_cflag; cflag = tty->termios->c_cflag;
iflag = port->port.tty->termios->c_iflag; iflag = tty->termios->c_iflag;
me->baudrate[p] = tty_get_baud_rate(tty);
} }
tty_kref_put(tty);
me->databits[p] = cflag & CSIZE; me->databits[p] = cflag & CSIZE;
me->stopbits[p] = cflag & CSTOPB; me->stopbits[p] = cflag & CSTOPB;
...@@ -1822,12 +1833,12 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, ...@@ -1822,12 +1833,12 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
switch (cmd) { switch (cmd) {
case TIOCGSERIAL: case TIOCGSERIAL:
lock_kernel(); lock_kernel();
retval = mxser_get_serial_info(info, argp); retval = mxser_get_serial_info(tty, argp);
unlock_kernel(); unlock_kernel();
return retval; return retval;
case TIOCSSERIAL: case TIOCSSERIAL:
lock_kernel(); lock_kernel();
retval = mxser_set_serial_info(info, argp); retval = mxser_set_serial_info(tty, argp);
unlock_kernel(); unlock_kernel();
return retval; return retval;
case TIOCSERGETLSR: /* Get line status register */ case TIOCSERGETLSR: /* Get line status register */
...@@ -1896,7 +1907,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, ...@@ -1896,7 +1907,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
lock_kernel(); lock_kernel();
status = mxser_get_msr(info->ioaddr, 1, tty->index); status = mxser_get_msr(info->ioaddr, 1, tty->index);
mxser_check_modem_status(info, status); mxser_check_modem_status(tty, info, status);
mcr = inb(info->ioaddr + UART_MCR); mcr = inb(info->ioaddr + UART_MCR);
if (mcr & MOXA_MUST_MCR_XON_FLAG) if (mcr & MOXA_MUST_MCR_XON_FLAG)
...@@ -1909,7 +1920,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, ...@@ -1909,7 +1920,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
else else
info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT;
if (info->port.tty->hw_stopped) if (tty->hw_stopped)
info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD;
else else
info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD;
...@@ -1958,7 +1969,7 @@ static void mxser_stoprx(struct tty_struct *tty) ...@@ -1958,7 +1969,7 @@ static void mxser_stoprx(struct tty_struct *tty)
} }
} }
if (info->port.tty->termios->c_cflag & CRTSCTS) { if (tty->termios->c_cflag & CRTSCTS) {
info->MCR &= ~UART_MCR_RTS; info->MCR &= ~UART_MCR_RTS;
outb(info->MCR, info->ioaddr + UART_MCR); outb(info->MCR, info->ioaddr + UART_MCR);
} }
...@@ -1995,7 +2006,7 @@ static void mxser_unthrottle(struct tty_struct *tty) ...@@ -1995,7 +2006,7 @@ static void mxser_unthrottle(struct tty_struct *tty)
} }
} }
if (info->port.tty->termios->c_cflag & CRTSCTS) { if (tty->termios->c_cflag & CRTSCTS) {
info->MCR |= UART_MCR_RTS; info->MCR |= UART_MCR_RTS;
outb(info->MCR, info->ioaddr + UART_MCR); outb(info->MCR, info->ioaddr + UART_MCR);
} }
...@@ -2040,7 +2051,7 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi ...@@ -2040,7 +2051,7 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&info->slock, flags); spin_lock_irqsave(&info->slock, flags);
mxser_change_speed(info, old_termios); mxser_change_speed(tty, old_termios);
spin_unlock_irqrestore(&info->slock, flags); spin_unlock_irqrestore(&info->slock, flags);
if ((old_termios->c_cflag & CRTSCTS) && if ((old_termios->c_cflag & CRTSCTS) &&
...@@ -2138,10 +2149,10 @@ static void mxser_hangup(struct tty_struct *tty) ...@@ -2138,10 +2149,10 @@ static void mxser_hangup(struct tty_struct *tty)
struct mxser_port *info = tty->driver_data; struct mxser_port *info = tty->driver_data;
mxser_flush_buffer(tty); mxser_flush_buffer(tty);
mxser_shutdown(info); mxser_shutdown(tty);
info->port.count = 0; info->port.count = 0;
info->port.flags &= ~ASYNC_NORMAL_ACTIVE; info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
info->port.tty = NULL; tty_port_tty_set(&info->port, NULL);
wake_up_interruptible(&info->port.open_wait); wake_up_interruptible(&info->port.open_wait);
} }
...@@ -2164,9 +2175,9 @@ static int mxser_rs_break(struct tty_struct *tty, int break_state) ...@@ -2164,9 +2175,9 @@ static int mxser_rs_break(struct tty_struct *tty, int break_state)
return 0; return 0;
} }
static void mxser_receive_chars(struct mxser_port *port, int *status) static void mxser_receive_chars(struct tty_struct *tty,
struct mxser_port *port, int *status)
{ {
struct tty_struct *tty = port->port.tty;
unsigned char ch, gdl; unsigned char ch, gdl;
int ignored = 0; int ignored = 0;
int cnt = 0; int cnt = 0;
...@@ -2174,9 +2185,8 @@ static void mxser_receive_chars(struct mxser_port *port, int *status) ...@@ -2174,9 +2185,8 @@ static void mxser_receive_chars(struct mxser_port *port, int *status)
int max = 256; int max = 256;
recv_room = tty->receive_room; recv_room = tty->receive_room;
if ((recv_room == 0) && (!port->ldisc_stop_rx)) if (recv_room == 0 && !port->ldisc_stop_rx)
mxser_stoprx(tty); mxser_stoprx(tty);
if (port->board->chip_flag != MOXA_OTHER_UART) { if (port->board->chip_flag != MOXA_OTHER_UART) {
if (*status & UART_LSR_SPECIAL) if (*status & UART_LSR_SPECIAL)
...@@ -2253,7 +2263,7 @@ static void mxser_receive_chars(struct mxser_port *port, int *status) ...@@ -2253,7 +2263,7 @@ static void mxser_receive_chars(struct mxser_port *port, int *status)
} while (*status & UART_LSR_DR); } while (*status & UART_LSR_DR);
end_intr: end_intr:
mxvar_log.rxcnt[port->port.tty->index] += cnt; mxvar_log.rxcnt[tty->index] += cnt;
port->mon_data.rxcnt += cnt; port->mon_data.rxcnt += cnt;
port->mon_data.up_rxcnt += cnt; port->mon_data.up_rxcnt += cnt;
...@@ -2267,14 +2277,14 @@ static void mxser_receive_chars(struct mxser_port *port, int *status) ...@@ -2267,14 +2277,14 @@ static void mxser_receive_chars(struct mxser_port *port, int *status)
spin_lock(&port->slock); spin_lock(&port->slock);
} }
static void mxser_transmit_chars(struct mxser_port *port) static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port)
{ {
int count, cnt; int count, cnt;
if (port->x_char) { if (port->x_char) {
outb(port->x_char, port->ioaddr + UART_TX); outb(port->x_char, port->ioaddr + UART_TX);
port->x_char = 0; port->x_char = 0;
mxvar_log.txcnt[port->port.tty->index]++; mxvar_log.txcnt[tty->index]++;
port->mon_data.txcnt++; port->mon_data.txcnt++;
port->mon_data.up_txcnt++; port->mon_data.up_txcnt++;
port->icount.tx++; port->icount.tx++;
...@@ -2284,8 +2294,8 @@ static void mxser_transmit_chars(struct mxser_port *port) ...@@ -2284,8 +2294,8 @@ static void mxser_transmit_chars(struct mxser_port *port)
if (port->port.xmit_buf == NULL) if (port->port.xmit_buf == NULL)
return; return;
if ((port->xmit_cnt <= 0) || port->port.tty->stopped || if (port->xmit_cnt <= 0 || tty->stopped ||
(port->port.tty->hw_stopped && (tty->hw_stopped &&
(port->type != PORT_16550A) && (port->type != PORT_16550A) &&
(!port->board->chip_flag))) { (!port->board->chip_flag))) {
port->IER &= ~UART_IER_THRI; port->IER &= ~UART_IER_THRI;
...@@ -2302,14 +2312,14 @@ static void mxser_transmit_chars(struct mxser_port *port) ...@@ -2302,14 +2312,14 @@ static void mxser_transmit_chars(struct mxser_port *port)
if (--port->xmit_cnt <= 0) if (--port->xmit_cnt <= 0)
break; break;
} while (--count > 0); } while (--count > 0);
mxvar_log.txcnt[port->port.tty->index] += (cnt - port->xmit_cnt); mxvar_log.txcnt[tty->index] += (cnt - port->xmit_cnt);
port->mon_data.txcnt += (cnt - port->xmit_cnt); port->mon_data.txcnt += (cnt - port->xmit_cnt);
port->mon_data.up_txcnt += (cnt - port->xmit_cnt); port->mon_data.up_txcnt += (cnt - port->xmit_cnt);
port->icount.tx += (cnt - port->xmit_cnt); port->icount.tx += (cnt - port->xmit_cnt);
if (port->xmit_cnt < WAKEUP_CHARS) if (port->xmit_cnt < WAKEUP_CHARS && tty)
tty_wakeup(port->port.tty); tty_wakeup(tty);
if (port->xmit_cnt <= 0) { if (port->xmit_cnt <= 0) {
port->IER &= ~UART_IER_THRI; port->IER &= ~UART_IER_THRI;
...@@ -2328,6 +2338,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) ...@@ -2328,6 +2338,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
int max, irqbits, bits, msr; int max, irqbits, bits, msr;
unsigned int int_cnt, pass_counter = 0; unsigned int int_cnt, pass_counter = 0;
int handled = IRQ_NONE; int handled = IRQ_NONE;
struct tty_struct *tty;
for (i = 0; i < MXSER_BOARDS; i++) for (i = 0; i < MXSER_BOARDS; i++)
if (dev_id == &mxser_boards[i]) { if (dev_id == &mxser_boards[i]) {
...@@ -2360,13 +2371,15 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) ...@@ -2360,13 +2371,15 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
if (iir & UART_IIR_NO_INT) if (iir & UART_IIR_NO_INT)
break; break;
iir &= MOXA_MUST_IIR_MASK; iir &= MOXA_MUST_IIR_MASK;
if (!port->port.tty || tty = tty_port_tty_get(&port->port);
if (!tty ||
(port->port.flags & ASYNC_CLOSING) || (port->port.flags & ASYNC_CLOSING) ||
!(port->port.flags & !(port->port.flags &
ASYNC_INITIALIZED)) { ASYNC_INITIALIZED)) {
status = inb(port->ioaddr + UART_LSR); status = inb(port->ioaddr + UART_LSR);
outb(0x27, port->ioaddr + UART_FCR); outb(0x27, port->ioaddr + UART_FCR);
inb(port->ioaddr + UART_MSR); inb(port->ioaddr + UART_MSR);
tty_kref_put(tty);
break; break;
} }
...@@ -2387,27 +2400,28 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) ...@@ -2387,27 +2400,28 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
iir == MOXA_MUST_IIR_RDA || iir == MOXA_MUST_IIR_RDA ||
iir == MOXA_MUST_IIR_RTO || iir == MOXA_MUST_IIR_RTO ||
iir == MOXA_MUST_IIR_LSR) iir == MOXA_MUST_IIR_LSR)
mxser_receive_chars(port, mxser_receive_chars(tty, port,
&status); &status);
} else { } else {
status &= port->read_status_mask; status &= port->read_status_mask;
if (status & UART_LSR_DR) if (status & UART_LSR_DR)
mxser_receive_chars(port, mxser_receive_chars(tty, port,
&status); &status);
} }
msr = inb(port->ioaddr + UART_MSR); msr = inb(port->ioaddr + UART_MSR);
if (msr & UART_MSR_ANY_DELTA) if (msr & UART_MSR_ANY_DELTA)
mxser_check_modem_status(port, msr); mxser_check_modem_status(tty, port, msr);
if (port->board->chip_flag) { if (port->board->chip_flag) {
if (iir == 0x02 && (status & if (iir == 0x02 && (status &
UART_LSR_THRE)) UART_LSR_THRE))
mxser_transmit_chars(port); mxser_transmit_chars(tty, port);
} else { } else {
if (status & UART_LSR_THRE) if (status & UART_LSR_THRE)
mxser_transmit_chars(port); mxser_transmit_chars(tty, port);
} }
tty_kref_put(tty);
} while (int_cnt++ < MXSER_ISR_PASS_LIMIT); } while (int_cnt++ < MXSER_ISR_PASS_LIMIT);
spin_unlock(&port->slock); spin_unlock(&port->slock);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册