aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/mxser.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-10-13 05:40:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 12:51:41 -0400
commit216ba023a96c04e8d3aabf83d5931c35b6e2dbbb (patch)
tree3ff36bd6874a997354dcec8d02256489cf1fe508 /drivers/char/mxser.c
parentd18a750fe9fa3b6cab882d51f99bba25bb0a006e (diff)
mxser: Switch to kref tty
Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/mxser.c')
-rw-r--r--drivers/char/mxser.c192
1 files changed, 103 insertions, 89 deletions
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index b638403e8e9c..308cb6014002 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -610,15 +610,16 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp,
610 return 0; 610 return 0;
611} 611}
612 612
613static int mxser_set_baud(struct mxser_port *info, long newspd) 613static int mxser_set_baud(struct tty_struct *tty, long newspd)
614{ 614{
615 struct mxser_port *info = tty->driver_data;
615 int quot = 0, baud; 616 int quot = 0, baud;
616 unsigned char cval; 617 unsigned char cval;
617 618
618 if (!info->port.tty || !info->port.tty->termios) 619 if (!tty->termios)
619 return -1; 620 return -1;
620 621
621 if (!(info->ioaddr)) 622 if (!info->ioaddr)
622 return -1; 623 return -1;
623 624
624 if (newspd > info->max_baud) 625 if (newspd > info->max_baud)
@@ -626,13 +627,13 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
626 627
627 if (newspd == 134) { 628 if (newspd == 134) {
628 quot = 2 * info->baud_base / 269; 629 quot = 2 * info->baud_base / 269;
629 tty_encode_baud_rate(info->port.tty, 134, 134); 630 tty_encode_baud_rate(tty, 134, 134);
630 } else if (newspd) { 631 } else if (newspd) {
631 quot = info->baud_base / newspd; 632 quot = info->baud_base / newspd;
632 if (quot == 0) 633 if (quot == 0)
633 quot = 1; 634 quot = 1;
634 baud = info->baud_base/quot; 635 baud = info->baud_base/quot;
635 tty_encode_baud_rate(info->port.tty, baud, baud); 636 tty_encode_baud_rate(tty, baud, baud);
636 } else { 637 } else {
637 quot = 0; 638 quot = 0;
638 } 639 }
@@ -658,7 +659,7 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
658 outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ 659 outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */
659 660
660#ifdef BOTHER 661#ifdef BOTHER
661 if (C_BAUD(info->port.tty) == BOTHER) { 662 if (C_BAUD(tty) == BOTHER) {
662 quot = info->baud_base % newspd; 663 quot = info->baud_base % newspd;
663 quot *= 8; 664 quot *= 8;
664 if (quot % newspd > newspd / 2) { 665 if (quot % newspd > newspd / 2) {
@@ -679,21 +680,22 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
679 * This routine is called to set the UART divisor registers to match 680 * This routine is called to set the UART divisor registers to match
680 * the specified baud rate for a serial port. 681 * the specified baud rate for a serial port.
681 */ 682 */
682static int mxser_change_speed(struct mxser_port *info, 683static int mxser_change_speed(struct tty_struct *tty,
683 struct ktermios *old_termios) 684 struct ktermios *old_termios)
684{ 685{
686 struct mxser_port *info = tty->driver_data;
685 unsigned cflag, cval, fcr; 687 unsigned cflag, cval, fcr;
686 int ret = 0; 688 int ret = 0;
687 unsigned char status; 689 unsigned char status;
688 690
689 if (!info->port.tty || !info->port.tty->termios) 691 if (!tty->termios)
690 return ret; 692 return ret;
691 cflag = info->port.tty->termios->c_cflag; 693 cflag = tty->termios->c_cflag;
692 if (!(info->ioaddr)) 694 if (!info->ioaddr)
693 return ret; 695 return ret;
694 696
695 if (mxser_set_baud_method[info->port.tty->index] == 0) 697 if (mxser_set_baud_method[tty->index] == 0)
696 mxser_set_baud(info, tty_get_baud_rate(info->port.tty)); 698 mxser_set_baud(tty, tty_get_baud_rate(tty));
697 699
698 /* byte size and parity */ 700 /* byte size and parity */
699 switch (cflag & CSIZE) { 701 switch (cflag & CSIZE) {
@@ -762,9 +764,9 @@ static int mxser_change_speed(struct mxser_port *info,
762 info->MCR |= UART_MCR_AFE; 764 info->MCR |= UART_MCR_AFE;
763 } else { 765 } else {
764 status = inb(info->ioaddr + UART_MSR); 766 status = inb(info->ioaddr + UART_MSR);
765 if (info->port.tty->hw_stopped) { 767 if (tty->hw_stopped) {
766 if (status & UART_MSR_CTS) { 768 if (status & UART_MSR_CTS) {
767 info->port.tty->hw_stopped = 0; 769 tty->hw_stopped = 0;
768 if (info->type != PORT_16550A && 770 if (info->type != PORT_16550A &&
769 !info->board->chip_flag) { 771 !info->board->chip_flag) {
770 outb(info->IER & ~UART_IER_THRI, 772 outb(info->IER & ~UART_IER_THRI,
@@ -774,11 +776,11 @@ static int mxser_change_speed(struct mxser_port *info,
774 outb(info->IER, info->ioaddr + 776 outb(info->IER, info->ioaddr +
775 UART_IER); 777 UART_IER);
776 } 778 }
777 tty_wakeup(info->port.tty); 779 tty_wakeup(tty);
778 } 780 }
779 } else { 781 } else {
780 if (!(status & UART_MSR_CTS)) { 782 if (!(status & UART_MSR_CTS)) {
781 info->port.tty->hw_stopped = 1; 783 tty->hw_stopped = 1;
782 if ((info->type != PORT_16550A) && 784 if ((info->type != PORT_16550A) &&
783 (!info->board->chip_flag)) { 785 (!info->board->chip_flag)) {
784 info->IER &= ~UART_IER_THRI; 786 info->IER &= ~UART_IER_THRI;
@@ -804,21 +806,21 @@ static int mxser_change_speed(struct mxser_port *info,
804 * Set up parity check flag 806 * Set up parity check flag
805 */ 807 */
806 info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; 808 info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
807 if (I_INPCK(info->port.tty)) 809 if (I_INPCK(tty))
808 info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; 810 info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
809 if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) 811 if (I_BRKINT(tty) || I_PARMRK(tty))
810 info->read_status_mask |= UART_LSR_BI; 812 info->read_status_mask |= UART_LSR_BI;
811 813
812 info->ignore_status_mask = 0; 814 info->ignore_status_mask = 0;
813 815
814 if (I_IGNBRK(info->port.tty)) { 816 if (I_IGNBRK(tty)) {
815 info->ignore_status_mask |= UART_LSR_BI; 817 info->ignore_status_mask |= UART_LSR_BI;
816 info->read_status_mask |= UART_LSR_BI; 818 info->read_status_mask |= UART_LSR_BI;
817 /* 819 /*
818 * If we're ignore parity and break indicators, ignore 820 * If we're ignore parity and break indicators, ignore
819 * overruns too. (For real raw support). 821 * overruns too. (For real raw support).
820 */ 822 */
821 if (I_IGNPAR(info->port.tty)) { 823 if (I_IGNPAR(tty)) {
822 info->ignore_status_mask |= 824 info->ignore_status_mask |=
823 UART_LSR_OE | 825 UART_LSR_OE |
824 UART_LSR_PE | 826 UART_LSR_PE |
@@ -830,16 +832,16 @@ static int mxser_change_speed(struct mxser_port *info,
830 } 832 }
831 } 833 }
832 if (info->board->chip_flag) { 834 if (info->board->chip_flag) {
833 mxser_set_must_xon1_value(info->ioaddr, START_CHAR(info->port.tty)); 835 mxser_set_must_xon1_value(info->ioaddr, START_CHAR(tty));
834 mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(info->port.tty)); 836 mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(tty));
835 if (I_IXON(info->port.tty)) { 837 if (I_IXON(tty)) {
836 mxser_enable_must_rx_software_flow_control( 838 mxser_enable_must_rx_software_flow_control(
837 info->ioaddr); 839 info->ioaddr);
838 } else { 840 } else {
839 mxser_disable_must_rx_software_flow_control( 841 mxser_disable_must_rx_software_flow_control(
840 info->ioaddr); 842 info->ioaddr);
841 } 843 }
842 if (I_IXOFF(info->port.tty)) { 844 if (I_IXOFF(tty)) {
843 mxser_enable_must_tx_software_flow_control( 845 mxser_enable_must_tx_software_flow_control(
844 info->ioaddr); 846 info->ioaddr);
845 } else { 847 } else {
@@ -855,7 +857,8 @@ static int mxser_change_speed(struct mxser_port *info,
855 return ret; 857 return ret;
856} 858}
857 859
858static void mxser_check_modem_status(struct mxser_port *port, int status) 860static void mxser_check_modem_status(struct tty_struct *tty,
861 struct mxser_port *port, int status)
859{ 862{
860 /* update input line counters */ 863 /* update input line counters */
861 if (status & UART_MSR_TERI) 864 if (status & UART_MSR_TERI)
@@ -874,10 +877,11 @@ static void mxser_check_modem_status(struct mxser_port *port, int status)
874 wake_up_interruptible(&port->port.open_wait); 877 wake_up_interruptible(&port->port.open_wait);
875 } 878 }
876 879
880 tty = tty_port_tty_get(&port->port);
877 if (port->port.flags & ASYNC_CTS_FLOW) { 881 if (port->port.flags & ASYNC_CTS_FLOW) {
878 if (port->port.tty->hw_stopped) { 882 if (tty->hw_stopped) {
879 if (status & UART_MSR_CTS) { 883 if (status & UART_MSR_CTS) {
880 port->port.tty->hw_stopped = 0; 884 tty->hw_stopped = 0;
881 885
882 if ((port->type != PORT_16550A) && 886 if ((port->type != PORT_16550A) &&
883 (!port->board->chip_flag)) { 887 (!port->board->chip_flag)) {
@@ -887,11 +891,11 @@ static void mxser_check_modem_status(struct mxser_port *port, int status)
887 outb(port->IER, port->ioaddr + 891 outb(port->IER, port->ioaddr +
888 UART_IER); 892 UART_IER);
889 } 893 }
890 tty_wakeup(port->port.tty); 894 tty_wakeup(tty);
891 } 895 }
892 } else { 896 } else {
893 if (!(status & UART_MSR_CTS)) { 897 if (!(status & UART_MSR_CTS)) {
894 port->port.tty->hw_stopped = 1; 898 tty->hw_stopped = 1;
895 if (port->type != PORT_16550A && 899 if (port->type != PORT_16550A &&
896 !port->board->chip_flag) { 900 !port->board->chip_flag) {
897 port->IER &= ~UART_IER_THRI; 901 port->IER &= ~UART_IER_THRI;
@@ -903,8 +907,9 @@ static void mxser_check_modem_status(struct mxser_port *port, int status)
903 } 907 }
904} 908}
905 909
906static int mxser_startup(struct mxser_port *info) 910static int mxser_startup(struct tty_struct *tty)
907{ 911{
912 struct mxser_port *info = tty->driver_data;
908 unsigned long page; 913 unsigned long page;
909 unsigned long flags; 914 unsigned long flags;
910 915
@@ -921,8 +926,7 @@ static int mxser_startup(struct mxser_port *info)
921 } 926 }
922 927
923 if (!info->ioaddr || !info->type) { 928 if (!info->ioaddr || !info->type) {
924 if (info->port.tty) 929 set_bit(TTY_IO_ERROR, &tty->flags);
925 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
926 free_page(page); 930 free_page(page);
927 spin_unlock_irqrestore(&info->slock, flags); 931 spin_unlock_irqrestore(&info->slock, flags);
928 return 0; 932 return 0;
@@ -952,8 +956,8 @@ static int mxser_startup(struct mxser_port *info)
952 if (inb(info->ioaddr + UART_LSR) == 0xff) { 956 if (inb(info->ioaddr + UART_LSR) == 0xff) {
953 spin_unlock_irqrestore(&info->slock, flags); 957 spin_unlock_irqrestore(&info->slock, flags);
954 if (capable(CAP_SYS_ADMIN)) { 958 if (capable(CAP_SYS_ADMIN)) {
955 if (info->port.tty) 959 if (tty)
956 set_bit(TTY_IO_ERROR, &info->port.tty->flags); 960 set_bit(TTY_IO_ERROR, &tty->flags);
957 return 0; 961 return 0;
958 } else 962 } else
959 return -ENODEV; 963 return -ENODEV;
@@ -991,14 +995,13 @@ static int mxser_startup(struct mxser_port *info)
991 (void) inb(info->ioaddr + UART_IIR); 995 (void) inb(info->ioaddr + UART_IIR);
992 (void) inb(info->ioaddr + UART_MSR); 996 (void) inb(info->ioaddr + UART_MSR);
993 997
994 if (info->port.tty) 998 clear_bit(TTY_IO_ERROR, &tty->flags);
995 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
996 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; 999 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
997 1000
998 /* 1001 /*
999 * and set the speed of the serial port 1002 * and set the speed of the serial port
1000 */ 1003 */
1001 mxser_change_speed(info, NULL); 1004 mxser_change_speed(tty, NULL);
1002 info->port.flags |= ASYNC_INITIALIZED; 1005 info->port.flags |= ASYNC_INITIALIZED;
1003 spin_unlock_irqrestore(&info->slock, flags); 1006 spin_unlock_irqrestore(&info->slock, flags);
1004 1007
@@ -1009,8 +1012,9 @@ static int mxser_startup(struct mxser_port *info)
1009 * This routine will shutdown a serial port; interrupts maybe disabled, and 1012 * This routine will shutdown a serial port; interrupts maybe disabled, and
1010 * DTR is dropped if the hangup on close termio flag is on. 1013 * DTR is dropped if the hangup on close termio flag is on.
1011 */ 1014 */
1012static void mxser_shutdown(struct mxser_port *info) 1015static void mxser_shutdown(struct tty_struct *tty)
1013{ 1016{
1017 struct mxser_port *info = tty->driver_data;
1014 unsigned long flags; 1018 unsigned long flags;
1015 1019
1016 if (!(info->port.flags & ASYNC_INITIALIZED)) 1020 if (!(info->port.flags & ASYNC_INITIALIZED))
@@ -1035,7 +1039,7 @@ static void mxser_shutdown(struct mxser_port *info)
1035 info->IER = 0; 1039 info->IER = 0;
1036 outb(0x00, info->ioaddr + UART_IER); 1040 outb(0x00, info->ioaddr + UART_IER);
1037 1041
1038 if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) 1042 if (tty->termios->c_cflag & HUPCL)
1039 info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS); 1043 info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS);
1040 outb(info->MCR, info->ioaddr + UART_MCR); 1044 outb(info->MCR, info->ioaddr + UART_MCR);
1041 1045
@@ -1051,8 +1055,7 @@ static void mxser_shutdown(struct mxser_port *info)
1051 /* read data port to reset things */ 1055 /* read data port to reset things */
1052 (void) inb(info->ioaddr + UART_RX); 1056 (void) inb(info->ioaddr + UART_RX);
1053 1057
1054 if (info->port.tty) 1058 set_bit(TTY_IO_ERROR, &tty->flags);
1055 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
1056 1059
1057 info->port.flags &= ~ASYNC_INITIALIZED; 1060 info->port.flags &= ~ASYNC_INITIALIZED;
1058 1061
@@ -1084,14 +1087,14 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
1084 return -ENODEV; 1087 return -ENODEV;
1085 1088
1086 tty->driver_data = info; 1089 tty->driver_data = info;
1087 info->port.tty = tty; 1090 tty_port_tty_set(&info->port, tty);
1088 /* 1091 /*
1089 * Start up serial port 1092 * Start up serial port
1090 */ 1093 */
1091 spin_lock_irqsave(&info->slock, flags); 1094 spin_lock_irqsave(&info->slock, flags);
1092 info->port.count++; 1095 info->port.count++;
1093 spin_unlock_irqrestore(&info->slock, flags); 1096 spin_unlock_irqrestore(&info->slock, flags);
1094 retval = mxser_startup(info); 1097 retval = mxser_startup(tty);
1095 if (retval) 1098 if (retval)
1096 return retval; 1099 return retval;
1097 1100
@@ -1209,13 +1212,13 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
1209 break; 1212 break;
1210 } 1213 }
1211 } 1214 }
1212 mxser_shutdown(info); 1215 mxser_shutdown(tty);
1213 1216
1214 mxser_flush_buffer(tty); 1217 mxser_flush_buffer(tty);
1215 tty_ldisc_flush(tty); 1218 tty_ldisc_flush(tty);
1216 1219
1217 tty->closing = 0; 1220 tty->closing = 0;
1218 info->port.tty = NULL; 1221 tty_port_tty_set(&info->port, NULL);
1219 if (info->port.blocked_open) { 1222 if (info->port.blocked_open) {
1220 if (info->port.close_delay) 1223 if (info->port.close_delay)
1221 schedule_timeout_interruptible(info->port.close_delay); 1224 schedule_timeout_interruptible(info->port.close_delay);
@@ -1337,12 +1340,13 @@ static int mxser_chars_in_buffer(struct tty_struct *tty)
1337 * friends of mxser_ioctl() 1340 * friends of mxser_ioctl()
1338 * ------------------------------------------------------------ 1341 * ------------------------------------------------------------
1339 */ 1342 */
1340static int mxser_get_serial_info(struct mxser_port *info, 1343static int mxser_get_serial_info(struct tty_struct *tty,
1341 struct serial_struct __user *retinfo) 1344 struct serial_struct __user *retinfo)
1342{ 1345{
1346 struct mxser_port *info = tty->driver_data;
1343 struct serial_struct tmp = { 1347 struct serial_struct tmp = {
1344 .type = info->type, 1348 .type = info->type,
1345 .line = info->port.tty->index, 1349 .line = tty->index,
1346 .port = info->ioaddr, 1350 .port = info->ioaddr,
1347 .irq = info->board->irq, 1351 .irq = info->board->irq,
1348 .flags = info->port.flags, 1352 .flags = info->port.flags,
@@ -1357,9 +1361,10 @@ static int mxser_get_serial_info(struct mxser_port *info,
1357 return 0; 1361 return 0;
1358} 1362}
1359 1363
1360static int mxser_set_serial_info(struct mxser_port *info, 1364static int mxser_set_serial_info(struct tty_struct *tty,
1361 struct serial_struct __user *new_info) 1365 struct serial_struct __user *new_info)
1362{ 1366{
1367 struct mxser_port *info = tty->driver_data;
1363 struct serial_struct new_serial; 1368 struct serial_struct new_serial;
1364 speed_t baud; 1369 speed_t baud;
1365 unsigned long sl_flags; 1370 unsigned long sl_flags;
@@ -1393,14 +1398,14 @@ static int mxser_set_serial_info(struct mxser_port *info,
1393 (new_serial.flags & ASYNC_FLAGS)); 1398 (new_serial.flags & ASYNC_FLAGS));
1394 info->port.close_delay = new_serial.close_delay * HZ / 100; 1399 info->port.close_delay = new_serial.close_delay * HZ / 100;
1395 info->port.closing_wait = new_serial.closing_wait * HZ / 100; 1400 info->port.closing_wait = new_serial.closing_wait * HZ / 100;
1396 info->port.tty->low_latency = 1401 tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY)
1397 (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; 1402 ? 1 : 0;
1398 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && 1403 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
1399 (new_serial.baud_base != info->baud_base || 1404 (new_serial.baud_base != info->baud_base ||
1400 new_serial.custom_divisor != 1405 new_serial.custom_divisor !=
1401 info->custom_divisor)) { 1406 info->custom_divisor)) {
1402 baud = new_serial.baud_base / new_serial.custom_divisor; 1407 baud = new_serial.baud_base / new_serial.custom_divisor;
1403 tty_encode_baud_rate(info->port.tty, baud, baud); 1408 tty_encode_baud_rate(tty, baud, baud);
1404 } 1409 }
1405 } 1410 }
1406 1411
@@ -1411,11 +1416,11 @@ static int mxser_set_serial_info(struct mxser_port *info,
1411 if (info->port.flags & ASYNC_INITIALIZED) { 1416 if (info->port.flags & ASYNC_INITIALIZED) {
1412 if (flags != (info->port.flags & ASYNC_SPD_MASK)) { 1417 if (flags != (info->port.flags & ASYNC_SPD_MASK)) {
1413 spin_lock_irqsave(&info->slock, sl_flags); 1418 spin_lock_irqsave(&info->slock, sl_flags);
1414 mxser_change_speed(info, NULL); 1419 mxser_change_speed(tty, NULL);
1415 spin_unlock_irqrestore(&info->slock, sl_flags); 1420 spin_unlock_irqrestore(&info->slock, sl_flags);
1416 } 1421 }
1417 } else 1422 } else
1418 retval = mxser_startup(info); 1423 retval = mxser_startup(tty);
1419 1424
1420 return retval; 1425 return retval;
1421} 1426}
@@ -1461,7 +1466,7 @@ static int mxser_tiocmget(struct tty_struct *tty, struct file *file)
1461 spin_lock_irqsave(&info->slock, flags); 1466 spin_lock_irqsave(&info->slock, flags);
1462 status = inb(info->ioaddr + UART_MSR); 1467 status = inb(info->ioaddr + UART_MSR);
1463 if (status & UART_MSR_ANY_DELTA) 1468 if (status & UART_MSR_ANY_DELTA)
1464 mxser_check_modem_status(info, status); 1469 mxser_check_modem_status(tty, info, status);
1465 spin_unlock_irqrestore(&info->slock, flags); 1470 spin_unlock_irqrestore(&info->slock, flags);
1466 return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | 1471 return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) |
1467 ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | 1472 ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) |
@@ -1606,6 +1611,7 @@ static int __init mxser_read_register(int port, unsigned short *regs)
1606static int mxser_ioctl_special(unsigned int cmd, void __user *argp) 1611static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
1607{ 1612{
1608 struct mxser_port *port; 1613 struct mxser_port *port;
1614 struct tty_struct *tty;
1609 int result, status; 1615 int result, status;
1610 unsigned int i, j; 1616 unsigned int i, j;
1611 int ret = 0; 1617 int ret = 0;
@@ -1643,12 +1649,14 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
1643 1649
1644 if (!port->ioaddr) 1650 if (!port->ioaddr)
1645 goto copy; 1651 goto copy;
1652
1653 tty = tty_port_tty_get(&port->port);
1646 1654
1647 if (!port->port.tty || !port->port.tty->termios) 1655 if (!tty || !tty->termios)
1648 ms.cflag = port->normal_termios.c_cflag; 1656 ms.cflag = port->normal_termios.c_cflag;
1649 else 1657 else
1650 ms.cflag = port->port.tty->termios->c_cflag; 1658 ms.cflag = tty->termios->c_cflag;
1651 1659 tty_kref_put(tty);
1652 status = inb(port->ioaddr + UART_MSR); 1660 status = inb(port->ioaddr + UART_MSR);
1653 if (status & UART_MSR_DCD) 1661 if (status & UART_MSR_DCD)
1654 ms.dcd = 1; 1662 ms.dcd = 1;
@@ -1704,15 +1712,18 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
1704 me->up_txcnt[p] = port->mon_data.up_txcnt; 1712 me->up_txcnt[p] = port->mon_data.up_txcnt;
1705 me->modem_status[p] = 1713 me->modem_status[p] =
1706 port->mon_data.modem_status; 1714 port->mon_data.modem_status;
1707 me->baudrate[p] = tty_get_baud_rate(port->port.tty); 1715 tty = tty_port_tty_get(&port->port);
1708 1716
1709 if (!port->port.tty || !port->port.tty->termios) { 1717 if (!tty || !tty->termios) {
1710 cflag = port->normal_termios.c_cflag; 1718 cflag = port->normal_termios.c_cflag;
1711 iflag = port->normal_termios.c_iflag; 1719 iflag = port->normal_termios.c_iflag;
1720 me->baudrate[p] = tty_termios_baud_rate(&port->normal_termios);
1712 } else { 1721 } else {
1713 cflag = port->port.tty->termios->c_cflag; 1722 cflag = tty->termios->c_cflag;
1714 iflag = port->port.tty->termios->c_iflag; 1723 iflag = tty->termios->c_iflag;
1724 me->baudrate[p] = tty_get_baud_rate(tty);
1715 } 1725 }
1726 tty_kref_put(tty);
1716 1727
1717 me->databits[p] = cflag & CSIZE; 1728 me->databits[p] = cflag & CSIZE;
1718 me->stopbits[p] = cflag & CSTOPB; 1729 me->stopbits[p] = cflag & CSTOPB;
@@ -1822,12 +1833,12 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
1822 switch (cmd) { 1833 switch (cmd) {
1823 case TIOCGSERIAL: 1834 case TIOCGSERIAL:
1824 lock_kernel(); 1835 lock_kernel();
1825 retval = mxser_get_serial_info(info, argp); 1836 retval = mxser_get_serial_info(tty, argp);
1826 unlock_kernel(); 1837 unlock_kernel();
1827 return retval; 1838 return retval;
1828 case TIOCSSERIAL: 1839 case TIOCSSERIAL:
1829 lock_kernel(); 1840 lock_kernel();
1830 retval = mxser_set_serial_info(info, argp); 1841 retval = mxser_set_serial_info(tty, argp);
1831 unlock_kernel(); 1842 unlock_kernel();
1832 return retval; 1843 return retval;
1833 case TIOCSERGETLSR: /* Get line status register */ 1844 case TIOCSERGETLSR: /* Get line status register */
@@ -1896,7 +1907,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
1896 1907
1897 lock_kernel(); 1908 lock_kernel();
1898 status = mxser_get_msr(info->ioaddr, 1, tty->index); 1909 status = mxser_get_msr(info->ioaddr, 1, tty->index);
1899 mxser_check_modem_status(info, status); 1910 mxser_check_modem_status(tty, info, status);
1900 1911
1901 mcr = inb(info->ioaddr + UART_MCR); 1912 mcr = inb(info->ioaddr + UART_MCR);
1902 if (mcr & MOXA_MUST_MCR_XON_FLAG) 1913 if (mcr & MOXA_MUST_MCR_XON_FLAG)
@@ -1909,7 +1920,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
1909 else 1920 else
1910 info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; 1921 info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT;
1911 1922
1912 if (info->port.tty->hw_stopped) 1923 if (tty->hw_stopped)
1913 info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; 1924 info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD;
1914 else 1925 else
1915 info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; 1926 info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD;
@@ -1958,7 +1969,7 @@ static void mxser_stoprx(struct tty_struct *tty)
1958 } 1969 }
1959 } 1970 }
1960 1971
1961 if (info->port.tty->termios->c_cflag & CRTSCTS) { 1972 if (tty->termios->c_cflag & CRTSCTS) {
1962 info->MCR &= ~UART_MCR_RTS; 1973 info->MCR &= ~UART_MCR_RTS;
1963 outb(info->MCR, info->ioaddr + UART_MCR); 1974 outb(info->MCR, info->ioaddr + UART_MCR);
1964 } 1975 }
@@ -1995,7 +2006,7 @@ static void mxser_unthrottle(struct tty_struct *tty)
1995 } 2006 }
1996 } 2007 }
1997 2008
1998 if (info->port.tty->termios->c_cflag & CRTSCTS) { 2009 if (tty->termios->c_cflag & CRTSCTS) {
1999 info->MCR |= UART_MCR_RTS; 2010 info->MCR |= UART_MCR_RTS;
2000 outb(info->MCR, info->ioaddr + UART_MCR); 2011 outb(info->MCR, info->ioaddr + UART_MCR);
2001 } 2012 }
@@ -2040,7 +2051,7 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi
2040 unsigned long flags; 2051 unsigned long flags;
2041 2052
2042 spin_lock_irqsave(&info->slock, flags); 2053 spin_lock_irqsave(&info->slock, flags);
2043 mxser_change_speed(info, old_termios); 2054 mxser_change_speed(tty, old_termios);
2044 spin_unlock_irqrestore(&info->slock, flags); 2055 spin_unlock_irqrestore(&info->slock, flags);
2045 2056
2046 if ((old_termios->c_cflag & CRTSCTS) && 2057 if ((old_termios->c_cflag & CRTSCTS) &&
@@ -2138,10 +2149,10 @@ static void mxser_hangup(struct tty_struct *tty)
2138 struct mxser_port *info = tty->driver_data; 2149 struct mxser_port *info = tty->driver_data;
2139 2150
2140 mxser_flush_buffer(tty); 2151 mxser_flush_buffer(tty);
2141 mxser_shutdown(info); 2152 mxser_shutdown(tty);
2142 info->port.count = 0; 2153 info->port.count = 0;
2143 info->port.flags &= ~ASYNC_NORMAL_ACTIVE; 2154 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
2144 info->port.tty = NULL; 2155 tty_port_tty_set(&info->port, NULL);
2145 wake_up_interruptible(&info->port.open_wait); 2156 wake_up_interruptible(&info->port.open_wait);
2146} 2157}
2147 2158
@@ -2164,9 +2175,9 @@ static int mxser_rs_break(struct tty_struct *tty, int break_state)
2164 return 0; 2175 return 0;
2165} 2176}
2166 2177
2167static void mxser_receive_chars(struct mxser_port *port, int *status) 2178static void mxser_receive_chars(struct tty_struct *tty,
2179 struct mxser_port *port, int *status)
2168{ 2180{
2169 struct tty_struct *tty = port->port.tty;
2170 unsigned char ch, gdl; 2181 unsigned char ch, gdl;
2171 int ignored = 0; 2182 int ignored = 0;
2172 int cnt = 0; 2183 int cnt = 0;
@@ -2174,9 +2185,8 @@ static void mxser_receive_chars(struct mxser_port *port, int *status)
2174 int max = 256; 2185 int max = 256;
2175 2186
2176 recv_room = tty->receive_room; 2187 recv_room = tty->receive_room;
2177 if ((recv_room == 0) && (!port->ldisc_stop_rx)) 2188 if (recv_room == 0 && !port->ldisc_stop_rx)
2178 mxser_stoprx(tty); 2189 mxser_stoprx(tty);
2179
2180 if (port->board->chip_flag != MOXA_OTHER_UART) { 2190 if (port->board->chip_flag != MOXA_OTHER_UART) {
2181 2191
2182 if (*status & UART_LSR_SPECIAL) 2192 if (*status & UART_LSR_SPECIAL)
@@ -2253,7 +2263,7 @@ intr_old:
2253 } while (*status & UART_LSR_DR); 2263 } while (*status & UART_LSR_DR);
2254 2264
2255end_intr: 2265end_intr:
2256 mxvar_log.rxcnt[port->port.tty->index] += cnt; 2266 mxvar_log.rxcnt[tty->index] += cnt;
2257 port->mon_data.rxcnt += cnt; 2267 port->mon_data.rxcnt += cnt;
2258 port->mon_data.up_rxcnt += cnt; 2268 port->mon_data.up_rxcnt += cnt;
2259 2269
@@ -2267,14 +2277,14 @@ end_intr:
2267 spin_lock(&port->slock); 2277 spin_lock(&port->slock);
2268} 2278}
2269 2279
2270static void mxser_transmit_chars(struct mxser_port *port) 2280static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port)
2271{ 2281{
2272 int count, cnt; 2282 int count, cnt;
2273 2283
2274 if (port->x_char) { 2284 if (port->x_char) {
2275 outb(port->x_char, port->ioaddr + UART_TX); 2285 outb(port->x_char, port->ioaddr + UART_TX);
2276 port->x_char = 0; 2286 port->x_char = 0;
2277 mxvar_log.txcnt[port->port.tty->index]++; 2287 mxvar_log.txcnt[tty->index]++;
2278 port->mon_data.txcnt++; 2288 port->mon_data.txcnt++;
2279 port->mon_data.up_txcnt++; 2289 port->mon_data.up_txcnt++;
2280 port->icount.tx++; 2290 port->icount.tx++;
@@ -2284,8 +2294,8 @@ static void mxser_transmit_chars(struct mxser_port *port)
2284 if (port->port.xmit_buf == NULL) 2294 if (port->port.xmit_buf == NULL)
2285 return; 2295 return;
2286 2296
2287 if ((port->xmit_cnt <= 0) || port->port.tty->stopped || 2297 if (port->xmit_cnt <= 0 || tty->stopped ||
2288 (port->port.tty->hw_stopped && 2298 (tty->hw_stopped &&
2289 (port->type != PORT_16550A) && 2299 (port->type != PORT_16550A) &&
2290 (!port->board->chip_flag))) { 2300 (!port->board->chip_flag))) {
2291 port->IER &= ~UART_IER_THRI; 2301 port->IER &= ~UART_IER_THRI;
@@ -2302,14 +2312,14 @@ static void mxser_transmit_chars(struct mxser_port *port)
2302 if (--port->xmit_cnt <= 0) 2312 if (--port->xmit_cnt <= 0)
2303 break; 2313 break;
2304 } while (--count > 0); 2314 } while (--count > 0);
2305 mxvar_log.txcnt[port->port.tty->index] += (cnt - port->xmit_cnt); 2315 mxvar_log.txcnt[tty->index] += (cnt - port->xmit_cnt);
2306 2316
2307 port->mon_data.txcnt += (cnt - port->xmit_cnt); 2317 port->mon_data.txcnt += (cnt - port->xmit_cnt);
2308 port->mon_data.up_txcnt += (cnt - port->xmit_cnt); 2318 port->mon_data.up_txcnt += (cnt - port->xmit_cnt);
2309 port->icount.tx += (cnt - port->xmit_cnt); 2319 port->icount.tx += (cnt - port->xmit_cnt);
2310 2320
2311 if (port->xmit_cnt < WAKEUP_CHARS) 2321 if (port->xmit_cnt < WAKEUP_CHARS && tty)
2312 tty_wakeup(port->port.tty); 2322 tty_wakeup(tty);
2313 2323
2314 if (port->xmit_cnt <= 0) { 2324 if (port->xmit_cnt <= 0) {
2315 port->IER &= ~UART_IER_THRI; 2325 port->IER &= ~UART_IER_THRI;
@@ -2328,6 +2338,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
2328 int max, irqbits, bits, msr; 2338 int max, irqbits, bits, msr;
2329 unsigned int int_cnt, pass_counter = 0; 2339 unsigned int int_cnt, pass_counter = 0;
2330 int handled = IRQ_NONE; 2340 int handled = IRQ_NONE;
2341 struct tty_struct *tty;
2331 2342
2332 for (i = 0; i < MXSER_BOARDS; i++) 2343 for (i = 0; i < MXSER_BOARDS; i++)
2333 if (dev_id == &mxser_boards[i]) { 2344 if (dev_id == &mxser_boards[i]) {
@@ -2360,13 +2371,15 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
2360 if (iir & UART_IIR_NO_INT) 2371 if (iir & UART_IIR_NO_INT)
2361 break; 2372 break;
2362 iir &= MOXA_MUST_IIR_MASK; 2373 iir &= MOXA_MUST_IIR_MASK;
2363 if (!port->port.tty || 2374 tty = tty_port_tty_get(&port->port);
2375 if (!tty ||
2364 (port->port.flags & ASYNC_CLOSING) || 2376 (port->port.flags & ASYNC_CLOSING) ||
2365 !(port->port.flags & 2377 !(port->port.flags &
2366 ASYNC_INITIALIZED)) { 2378 ASYNC_INITIALIZED)) {
2367 status = inb(port->ioaddr + UART_LSR); 2379 status = inb(port->ioaddr + UART_LSR);
2368 outb(0x27, port->ioaddr + UART_FCR); 2380 outb(0x27, port->ioaddr + UART_FCR);
2369 inb(port->ioaddr + UART_MSR); 2381 inb(port->ioaddr + UART_MSR);
2382 tty_kref_put(tty);
2370 break; 2383 break;
2371 } 2384 }
2372 2385
@@ -2387,27 +2400,28 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
2387 iir == MOXA_MUST_IIR_RDA || 2400 iir == MOXA_MUST_IIR_RDA ||
2388 iir == MOXA_MUST_IIR_RTO || 2401 iir == MOXA_MUST_IIR_RTO ||
2389 iir == MOXA_MUST_IIR_LSR) 2402 iir == MOXA_MUST_IIR_LSR)
2390 mxser_receive_chars(port, 2403 mxser_receive_chars(tty, port,
2391 &status); 2404 &status);
2392 2405
2393 } else { 2406 } else {
2394 status &= port->read_status_mask; 2407 status &= port->read_status_mask;
2395 if (status & UART_LSR_DR) 2408 if (status & UART_LSR_DR)
2396 mxser_receive_chars(port, 2409 mxser_receive_chars(tty, port,
2397 &status); 2410 &status);
2398 } 2411 }
2399 msr = inb(port->ioaddr + UART_MSR); 2412 msr = inb(port->ioaddr + UART_MSR);
2400 if (msr & UART_MSR_ANY_DELTA) 2413 if (msr & UART_MSR_ANY_DELTA)
2401 mxser_check_modem_status(port, msr); 2414 mxser_check_modem_status(tty, port, msr);
2402 2415
2403 if (port->board->chip_flag) { 2416 if (port->board->chip_flag) {
2404 if (iir == 0x02 && (status & 2417 if (iir == 0x02 && (status &
2405 UART_LSR_THRE)) 2418 UART_LSR_THRE))
2406 mxser_transmit_chars(port); 2419 mxser_transmit_chars(tty, port);
2407 } else { 2420 } else {
2408 if (status & UART_LSR_THRE) 2421 if (status & UART_LSR_THRE)
2409 mxser_transmit_chars(port); 2422 mxser_transmit_chars(tty, port);
2410 } 2423 }
2424 tty_kref_put(tty);
2411 } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); 2425 } while (int_cnt++ < MXSER_ISR_PASS_LIMIT);
2412 spin_unlock(&port->slock); 2426 spin_unlock(&port->slock);
2413 } 2427 }