diff options
Diffstat (limited to 'drivers/char/mxser.c')
-rw-r--r-- | drivers/char/mxser.c | 193 |
1 files changed, 101 insertions, 92 deletions
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index b638403e8e9c..8beef50f95a0 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -610,15 +610,13 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, | |||
610 | return 0; | 610 | return 0; |
611 | } | 611 | } |
612 | 612 | ||
613 | static int mxser_set_baud(struct mxser_port *info, long newspd) | 613 | static 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 (!info->ioaddr) |
619 | return -1; | ||
620 | |||
621 | if (!(info->ioaddr)) | ||
622 | return -1; | 620 | return -1; |
623 | 621 | ||
624 | if (newspd > info->max_baud) | 622 | if (newspd > info->max_baud) |
@@ -626,13 +624,13 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) | |||
626 | 624 | ||
627 | if (newspd == 134) { | 625 | if (newspd == 134) { |
628 | quot = 2 * info->baud_base / 269; | 626 | quot = 2 * info->baud_base / 269; |
629 | tty_encode_baud_rate(info->port.tty, 134, 134); | 627 | tty_encode_baud_rate(tty, 134, 134); |
630 | } else if (newspd) { | 628 | } else if (newspd) { |
631 | quot = info->baud_base / newspd; | 629 | quot = info->baud_base / newspd; |
632 | if (quot == 0) | 630 | if (quot == 0) |
633 | quot = 1; | 631 | quot = 1; |
634 | baud = info->baud_base/quot; | 632 | baud = info->baud_base/quot; |
635 | tty_encode_baud_rate(info->port.tty, baud, baud); | 633 | tty_encode_baud_rate(tty, baud, baud); |
636 | } else { | 634 | } else { |
637 | quot = 0; | 635 | quot = 0; |
638 | } | 636 | } |
@@ -658,7 +656,7 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) | |||
658 | outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ | 656 | outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ |
659 | 657 | ||
660 | #ifdef BOTHER | 658 | #ifdef BOTHER |
661 | if (C_BAUD(info->port.tty) == BOTHER) { | 659 | if (C_BAUD(tty) == BOTHER) { |
662 | quot = info->baud_base % newspd; | 660 | quot = info->baud_base % newspd; |
663 | quot *= 8; | 661 | quot *= 8; |
664 | if (quot % newspd > newspd / 2) { | 662 | if (quot % newspd > newspd / 2) { |
@@ -679,21 +677,20 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) | |||
679 | * This routine is called to set the UART divisor registers to match | 677 | * This routine is called to set the UART divisor registers to match |
680 | * the specified baud rate for a serial port. | 678 | * the specified baud rate for a serial port. |
681 | */ | 679 | */ |
682 | static int mxser_change_speed(struct mxser_port *info, | 680 | static int mxser_change_speed(struct tty_struct *tty, |
683 | struct ktermios *old_termios) | 681 | struct ktermios *old_termios) |
684 | { | 682 | { |
683 | struct mxser_port *info = tty->driver_data; | ||
685 | unsigned cflag, cval, fcr; | 684 | unsigned cflag, cval, fcr; |
686 | int ret = 0; | 685 | int ret = 0; |
687 | unsigned char status; | 686 | unsigned char status; |
688 | 687 | ||
689 | if (!info->port.tty || !info->port.tty->termios) | 688 | cflag = tty->termios->c_cflag; |
690 | return ret; | 689 | if (!info->ioaddr) |
691 | cflag = info->port.tty->termios->c_cflag; | ||
692 | if (!(info->ioaddr)) | ||
693 | return ret; | 690 | return ret; |
694 | 691 | ||
695 | if (mxser_set_baud_method[info->port.tty->index] == 0) | 692 | if (mxser_set_baud_method[tty->index] == 0) |
696 | mxser_set_baud(info, tty_get_baud_rate(info->port.tty)); | 693 | mxser_set_baud(tty, tty_get_baud_rate(tty)); |
697 | 694 | ||
698 | /* byte size and parity */ | 695 | /* byte size and parity */ |
699 | switch (cflag & CSIZE) { | 696 | switch (cflag & CSIZE) { |
@@ -762,9 +759,9 @@ static int mxser_change_speed(struct mxser_port *info, | |||
762 | info->MCR |= UART_MCR_AFE; | 759 | info->MCR |= UART_MCR_AFE; |
763 | } else { | 760 | } else { |
764 | status = inb(info->ioaddr + UART_MSR); | 761 | status = inb(info->ioaddr + UART_MSR); |
765 | if (info->port.tty->hw_stopped) { | 762 | if (tty->hw_stopped) { |
766 | if (status & UART_MSR_CTS) { | 763 | if (status & UART_MSR_CTS) { |
767 | info->port.tty->hw_stopped = 0; | 764 | tty->hw_stopped = 0; |
768 | if (info->type != PORT_16550A && | 765 | if (info->type != PORT_16550A && |
769 | !info->board->chip_flag) { | 766 | !info->board->chip_flag) { |
770 | outb(info->IER & ~UART_IER_THRI, | 767 | outb(info->IER & ~UART_IER_THRI, |
@@ -774,11 +771,11 @@ static int mxser_change_speed(struct mxser_port *info, | |||
774 | outb(info->IER, info->ioaddr + | 771 | outb(info->IER, info->ioaddr + |
775 | UART_IER); | 772 | UART_IER); |
776 | } | 773 | } |
777 | tty_wakeup(info->port.tty); | 774 | tty_wakeup(tty); |
778 | } | 775 | } |
779 | } else { | 776 | } else { |
780 | if (!(status & UART_MSR_CTS)) { | 777 | if (!(status & UART_MSR_CTS)) { |
781 | info->port.tty->hw_stopped = 1; | 778 | tty->hw_stopped = 1; |
782 | if ((info->type != PORT_16550A) && | 779 | if ((info->type != PORT_16550A) && |
783 | (!info->board->chip_flag)) { | 780 | (!info->board->chip_flag)) { |
784 | info->IER &= ~UART_IER_THRI; | 781 | info->IER &= ~UART_IER_THRI; |
@@ -804,21 +801,21 @@ static int mxser_change_speed(struct mxser_port *info, | |||
804 | * Set up parity check flag | 801 | * Set up parity check flag |
805 | */ | 802 | */ |
806 | info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; | 803 | info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; |
807 | if (I_INPCK(info->port.tty)) | 804 | if (I_INPCK(tty)) |
808 | info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; | 805 | info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; |
809 | if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) | 806 | if (I_BRKINT(tty) || I_PARMRK(tty)) |
810 | info->read_status_mask |= UART_LSR_BI; | 807 | info->read_status_mask |= UART_LSR_BI; |
811 | 808 | ||
812 | info->ignore_status_mask = 0; | 809 | info->ignore_status_mask = 0; |
813 | 810 | ||
814 | if (I_IGNBRK(info->port.tty)) { | 811 | if (I_IGNBRK(tty)) { |
815 | info->ignore_status_mask |= UART_LSR_BI; | 812 | info->ignore_status_mask |= UART_LSR_BI; |
816 | info->read_status_mask |= UART_LSR_BI; | 813 | info->read_status_mask |= UART_LSR_BI; |
817 | /* | 814 | /* |
818 | * If we're ignore parity and break indicators, ignore | 815 | * If we're ignore parity and break indicators, ignore |
819 | * overruns too. (For real raw support). | 816 | * overruns too. (For real raw support). |
820 | */ | 817 | */ |
821 | if (I_IGNPAR(info->port.tty)) { | 818 | if (I_IGNPAR(tty)) { |
822 | info->ignore_status_mask |= | 819 | info->ignore_status_mask |= |
823 | UART_LSR_OE | | 820 | UART_LSR_OE | |
824 | UART_LSR_PE | | 821 | UART_LSR_PE | |
@@ -830,16 +827,16 @@ static int mxser_change_speed(struct mxser_port *info, | |||
830 | } | 827 | } |
831 | } | 828 | } |
832 | if (info->board->chip_flag) { | 829 | if (info->board->chip_flag) { |
833 | mxser_set_must_xon1_value(info->ioaddr, START_CHAR(info->port.tty)); | 830 | mxser_set_must_xon1_value(info->ioaddr, START_CHAR(tty)); |
834 | mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(info->port.tty)); | 831 | mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(tty)); |
835 | if (I_IXON(info->port.tty)) { | 832 | if (I_IXON(tty)) { |
836 | mxser_enable_must_rx_software_flow_control( | 833 | mxser_enable_must_rx_software_flow_control( |
837 | info->ioaddr); | 834 | info->ioaddr); |
838 | } else { | 835 | } else { |
839 | mxser_disable_must_rx_software_flow_control( | 836 | mxser_disable_must_rx_software_flow_control( |
840 | info->ioaddr); | 837 | info->ioaddr); |
841 | } | 838 | } |
842 | if (I_IXOFF(info->port.tty)) { | 839 | if (I_IXOFF(tty)) { |
843 | mxser_enable_must_tx_software_flow_control( | 840 | mxser_enable_must_tx_software_flow_control( |
844 | info->ioaddr); | 841 | info->ioaddr); |
845 | } else { | 842 | } else { |
@@ -855,7 +852,8 @@ static int mxser_change_speed(struct mxser_port *info, | |||
855 | return ret; | 852 | return ret; |
856 | } | 853 | } |
857 | 854 | ||
858 | static void mxser_check_modem_status(struct mxser_port *port, int status) | 855 | static void mxser_check_modem_status(struct tty_struct *tty, |
856 | struct mxser_port *port, int status) | ||
859 | { | 857 | { |
860 | /* update input line counters */ | 858 | /* update input line counters */ |
861 | if (status & UART_MSR_TERI) | 859 | if (status & UART_MSR_TERI) |
@@ -874,10 +872,11 @@ static void mxser_check_modem_status(struct mxser_port *port, int status) | |||
874 | wake_up_interruptible(&port->port.open_wait); | 872 | wake_up_interruptible(&port->port.open_wait); |
875 | } | 873 | } |
876 | 874 | ||
875 | tty = tty_port_tty_get(&port->port); | ||
877 | if (port->port.flags & ASYNC_CTS_FLOW) { | 876 | if (port->port.flags & ASYNC_CTS_FLOW) { |
878 | if (port->port.tty->hw_stopped) { | 877 | if (tty->hw_stopped) { |
879 | if (status & UART_MSR_CTS) { | 878 | if (status & UART_MSR_CTS) { |
880 | port->port.tty->hw_stopped = 0; | 879 | tty->hw_stopped = 0; |
881 | 880 | ||
882 | if ((port->type != PORT_16550A) && | 881 | if ((port->type != PORT_16550A) && |
883 | (!port->board->chip_flag)) { | 882 | (!port->board->chip_flag)) { |
@@ -887,11 +886,11 @@ static void mxser_check_modem_status(struct mxser_port *port, int status) | |||
887 | outb(port->IER, port->ioaddr + | 886 | outb(port->IER, port->ioaddr + |
888 | UART_IER); | 887 | UART_IER); |
889 | } | 888 | } |
890 | tty_wakeup(port->port.tty); | 889 | tty_wakeup(tty); |
891 | } | 890 | } |
892 | } else { | 891 | } else { |
893 | if (!(status & UART_MSR_CTS)) { | 892 | if (!(status & UART_MSR_CTS)) { |
894 | port->port.tty->hw_stopped = 1; | 893 | tty->hw_stopped = 1; |
895 | if (port->type != PORT_16550A && | 894 | if (port->type != PORT_16550A && |
896 | !port->board->chip_flag) { | 895 | !port->board->chip_flag) { |
897 | port->IER &= ~UART_IER_THRI; | 896 | port->IER &= ~UART_IER_THRI; |
@@ -903,8 +902,9 @@ static void mxser_check_modem_status(struct mxser_port *port, int status) | |||
903 | } | 902 | } |
904 | } | 903 | } |
905 | 904 | ||
906 | static int mxser_startup(struct mxser_port *info) | 905 | static int mxser_startup(struct tty_struct *tty) |
907 | { | 906 | { |
907 | struct mxser_port *info = tty->driver_data; | ||
908 | unsigned long page; | 908 | unsigned long page; |
909 | unsigned long flags; | 909 | unsigned long flags; |
910 | 910 | ||
@@ -921,8 +921,7 @@ static int mxser_startup(struct mxser_port *info) | |||
921 | } | 921 | } |
922 | 922 | ||
923 | if (!info->ioaddr || !info->type) { | 923 | if (!info->ioaddr || !info->type) { |
924 | if (info->port.tty) | 924 | set_bit(TTY_IO_ERROR, &tty->flags); |
925 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | ||
926 | free_page(page); | 925 | free_page(page); |
927 | spin_unlock_irqrestore(&info->slock, flags); | 926 | spin_unlock_irqrestore(&info->slock, flags); |
928 | return 0; | 927 | return 0; |
@@ -952,8 +951,8 @@ static int mxser_startup(struct mxser_port *info) | |||
952 | if (inb(info->ioaddr + UART_LSR) == 0xff) { | 951 | if (inb(info->ioaddr + UART_LSR) == 0xff) { |
953 | spin_unlock_irqrestore(&info->slock, flags); | 952 | spin_unlock_irqrestore(&info->slock, flags); |
954 | if (capable(CAP_SYS_ADMIN)) { | 953 | if (capable(CAP_SYS_ADMIN)) { |
955 | if (info->port.tty) | 954 | if (tty) |
956 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | 955 | set_bit(TTY_IO_ERROR, &tty->flags); |
957 | return 0; | 956 | return 0; |
958 | } else | 957 | } else |
959 | return -ENODEV; | 958 | return -ENODEV; |
@@ -991,14 +990,13 @@ static int mxser_startup(struct mxser_port *info) | |||
991 | (void) inb(info->ioaddr + UART_IIR); | 990 | (void) inb(info->ioaddr + UART_IIR); |
992 | (void) inb(info->ioaddr + UART_MSR); | 991 | (void) inb(info->ioaddr + UART_MSR); |
993 | 992 | ||
994 | if (info->port.tty) | 993 | 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; | 994 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
997 | 995 | ||
998 | /* | 996 | /* |
999 | * and set the speed of the serial port | 997 | * and set the speed of the serial port |
1000 | */ | 998 | */ |
1001 | mxser_change_speed(info, NULL); | 999 | mxser_change_speed(tty, NULL); |
1002 | info->port.flags |= ASYNC_INITIALIZED; | 1000 | info->port.flags |= ASYNC_INITIALIZED; |
1003 | spin_unlock_irqrestore(&info->slock, flags); | 1001 | spin_unlock_irqrestore(&info->slock, flags); |
1004 | 1002 | ||
@@ -1009,8 +1007,9 @@ static int mxser_startup(struct mxser_port *info) | |||
1009 | * This routine will shutdown a serial port; interrupts maybe disabled, and | 1007 | * This routine will shutdown a serial port; interrupts maybe disabled, and |
1010 | * DTR is dropped if the hangup on close termio flag is on. | 1008 | * DTR is dropped if the hangup on close termio flag is on. |
1011 | */ | 1009 | */ |
1012 | static void mxser_shutdown(struct mxser_port *info) | 1010 | static void mxser_shutdown(struct tty_struct *tty) |
1013 | { | 1011 | { |
1012 | struct mxser_port *info = tty->driver_data; | ||
1014 | unsigned long flags; | 1013 | unsigned long flags; |
1015 | 1014 | ||
1016 | if (!(info->port.flags & ASYNC_INITIALIZED)) | 1015 | if (!(info->port.flags & ASYNC_INITIALIZED)) |
@@ -1035,7 +1034,7 @@ static void mxser_shutdown(struct mxser_port *info) | |||
1035 | info->IER = 0; | 1034 | info->IER = 0; |
1036 | outb(0x00, info->ioaddr + UART_IER); | 1035 | outb(0x00, info->ioaddr + UART_IER); |
1037 | 1036 | ||
1038 | if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) | 1037 | if (tty->termios->c_cflag & HUPCL) |
1039 | info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS); | 1038 | info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS); |
1040 | outb(info->MCR, info->ioaddr + UART_MCR); | 1039 | outb(info->MCR, info->ioaddr + UART_MCR); |
1041 | 1040 | ||
@@ -1051,8 +1050,7 @@ static void mxser_shutdown(struct mxser_port *info) | |||
1051 | /* read data port to reset things */ | 1050 | /* read data port to reset things */ |
1052 | (void) inb(info->ioaddr + UART_RX); | 1051 | (void) inb(info->ioaddr + UART_RX); |
1053 | 1052 | ||
1054 | if (info->port.tty) | 1053 | set_bit(TTY_IO_ERROR, &tty->flags); |
1055 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | ||
1056 | 1054 | ||
1057 | info->port.flags &= ~ASYNC_INITIALIZED; | 1055 | info->port.flags &= ~ASYNC_INITIALIZED; |
1058 | 1056 | ||
@@ -1084,14 +1082,14 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) | |||
1084 | return -ENODEV; | 1082 | return -ENODEV; |
1085 | 1083 | ||
1086 | tty->driver_data = info; | 1084 | tty->driver_data = info; |
1087 | info->port.tty = tty; | 1085 | tty_port_tty_set(&info->port, tty); |
1088 | /* | 1086 | /* |
1089 | * Start up serial port | 1087 | * Start up serial port |
1090 | */ | 1088 | */ |
1091 | spin_lock_irqsave(&info->slock, flags); | 1089 | spin_lock_irqsave(&info->slock, flags); |
1092 | info->port.count++; | 1090 | info->port.count++; |
1093 | spin_unlock_irqrestore(&info->slock, flags); | 1091 | spin_unlock_irqrestore(&info->slock, flags); |
1094 | retval = mxser_startup(info); | 1092 | retval = mxser_startup(tty); |
1095 | if (retval) | 1093 | if (retval) |
1096 | return retval; | 1094 | return retval; |
1097 | 1095 | ||
@@ -1209,13 +1207,13 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) | |||
1209 | break; | 1207 | break; |
1210 | } | 1208 | } |
1211 | } | 1209 | } |
1212 | mxser_shutdown(info); | 1210 | mxser_shutdown(tty); |
1213 | 1211 | ||
1214 | mxser_flush_buffer(tty); | 1212 | mxser_flush_buffer(tty); |
1215 | tty_ldisc_flush(tty); | 1213 | tty_ldisc_flush(tty); |
1216 | 1214 | ||
1217 | tty->closing = 0; | 1215 | tty->closing = 0; |
1218 | info->port.tty = NULL; | 1216 | tty_port_tty_set(&info->port, NULL); |
1219 | if (info->port.blocked_open) { | 1217 | if (info->port.blocked_open) { |
1220 | if (info->port.close_delay) | 1218 | if (info->port.close_delay) |
1221 | schedule_timeout_interruptible(info->port.close_delay); | 1219 | schedule_timeout_interruptible(info->port.close_delay); |
@@ -1337,12 +1335,13 @@ static int mxser_chars_in_buffer(struct tty_struct *tty) | |||
1337 | * friends of mxser_ioctl() | 1335 | * friends of mxser_ioctl() |
1338 | * ------------------------------------------------------------ | 1336 | * ------------------------------------------------------------ |
1339 | */ | 1337 | */ |
1340 | static int mxser_get_serial_info(struct mxser_port *info, | 1338 | static int mxser_get_serial_info(struct tty_struct *tty, |
1341 | struct serial_struct __user *retinfo) | 1339 | struct serial_struct __user *retinfo) |
1342 | { | 1340 | { |
1341 | struct mxser_port *info = tty->driver_data; | ||
1343 | struct serial_struct tmp = { | 1342 | struct serial_struct tmp = { |
1344 | .type = info->type, | 1343 | .type = info->type, |
1345 | .line = info->port.tty->index, | 1344 | .line = tty->index, |
1346 | .port = info->ioaddr, | 1345 | .port = info->ioaddr, |
1347 | .irq = info->board->irq, | 1346 | .irq = info->board->irq, |
1348 | .flags = info->port.flags, | 1347 | .flags = info->port.flags, |
@@ -1357,9 +1356,10 @@ static int mxser_get_serial_info(struct mxser_port *info, | |||
1357 | return 0; | 1356 | return 0; |
1358 | } | 1357 | } |
1359 | 1358 | ||
1360 | static int mxser_set_serial_info(struct mxser_port *info, | 1359 | static int mxser_set_serial_info(struct tty_struct *tty, |
1361 | struct serial_struct __user *new_info) | 1360 | struct serial_struct __user *new_info) |
1362 | { | 1361 | { |
1362 | struct mxser_port *info = tty->driver_data; | ||
1363 | struct serial_struct new_serial; | 1363 | struct serial_struct new_serial; |
1364 | speed_t baud; | 1364 | speed_t baud; |
1365 | unsigned long sl_flags; | 1365 | unsigned long sl_flags; |
@@ -1393,14 +1393,14 @@ static int mxser_set_serial_info(struct mxser_port *info, | |||
1393 | (new_serial.flags & ASYNC_FLAGS)); | 1393 | (new_serial.flags & ASYNC_FLAGS)); |
1394 | info->port.close_delay = new_serial.close_delay * HZ / 100; | 1394 | info->port.close_delay = new_serial.close_delay * HZ / 100; |
1395 | info->port.closing_wait = new_serial.closing_wait * HZ / 100; | 1395 | info->port.closing_wait = new_serial.closing_wait * HZ / 100; |
1396 | info->port.tty->low_latency = | 1396 | tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) |
1397 | (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1397 | ? 1 : 0; |
1398 | if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && | 1398 | if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && |
1399 | (new_serial.baud_base != info->baud_base || | 1399 | (new_serial.baud_base != info->baud_base || |
1400 | new_serial.custom_divisor != | 1400 | new_serial.custom_divisor != |
1401 | info->custom_divisor)) { | 1401 | info->custom_divisor)) { |
1402 | baud = new_serial.baud_base / new_serial.custom_divisor; | 1402 | baud = new_serial.baud_base / new_serial.custom_divisor; |
1403 | tty_encode_baud_rate(info->port.tty, baud, baud); | 1403 | tty_encode_baud_rate(tty, baud, baud); |
1404 | } | 1404 | } |
1405 | } | 1405 | } |
1406 | 1406 | ||
@@ -1411,11 +1411,11 @@ static int mxser_set_serial_info(struct mxser_port *info, | |||
1411 | if (info->port.flags & ASYNC_INITIALIZED) { | 1411 | if (info->port.flags & ASYNC_INITIALIZED) { |
1412 | if (flags != (info->port.flags & ASYNC_SPD_MASK)) { | 1412 | if (flags != (info->port.flags & ASYNC_SPD_MASK)) { |
1413 | spin_lock_irqsave(&info->slock, sl_flags); | 1413 | spin_lock_irqsave(&info->slock, sl_flags); |
1414 | mxser_change_speed(info, NULL); | 1414 | mxser_change_speed(tty, NULL); |
1415 | spin_unlock_irqrestore(&info->slock, sl_flags); | 1415 | spin_unlock_irqrestore(&info->slock, sl_flags); |
1416 | } | 1416 | } |
1417 | } else | 1417 | } else |
1418 | retval = mxser_startup(info); | 1418 | retval = mxser_startup(tty); |
1419 | 1419 | ||
1420 | return retval; | 1420 | return retval; |
1421 | } | 1421 | } |
@@ -1461,7 +1461,7 @@ static int mxser_tiocmget(struct tty_struct *tty, struct file *file) | |||
1461 | spin_lock_irqsave(&info->slock, flags); | 1461 | spin_lock_irqsave(&info->slock, flags); |
1462 | status = inb(info->ioaddr + UART_MSR); | 1462 | status = inb(info->ioaddr + UART_MSR); |
1463 | if (status & UART_MSR_ANY_DELTA) | 1463 | if (status & UART_MSR_ANY_DELTA) |
1464 | mxser_check_modem_status(info, status); | 1464 | mxser_check_modem_status(tty, info, status); |
1465 | spin_unlock_irqrestore(&info->slock, flags); | 1465 | spin_unlock_irqrestore(&info->slock, flags); |
1466 | return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | | 1466 | return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | |
1467 | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | | 1467 | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | |
@@ -1606,6 +1606,7 @@ static int __init mxser_read_register(int port, unsigned short *regs) | |||
1606 | static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | 1606 | static int mxser_ioctl_special(unsigned int cmd, void __user *argp) |
1607 | { | 1607 | { |
1608 | struct mxser_port *port; | 1608 | struct mxser_port *port; |
1609 | struct tty_struct *tty; | ||
1609 | int result, status; | 1610 | int result, status; |
1610 | unsigned int i, j; | 1611 | unsigned int i, j; |
1611 | int ret = 0; | 1612 | int ret = 0; |
@@ -1643,12 +1644,14 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1643 | 1644 | ||
1644 | if (!port->ioaddr) | 1645 | if (!port->ioaddr) |
1645 | goto copy; | 1646 | goto copy; |
1647 | |||
1648 | tty = tty_port_tty_get(&port->port); | ||
1646 | 1649 | ||
1647 | if (!port->port.tty || !port->port.tty->termios) | 1650 | if (!tty || !tty->termios) |
1648 | ms.cflag = port->normal_termios.c_cflag; | 1651 | ms.cflag = port->normal_termios.c_cflag; |
1649 | else | 1652 | else |
1650 | ms.cflag = port->port.tty->termios->c_cflag; | 1653 | ms.cflag = tty->termios->c_cflag; |
1651 | 1654 | tty_kref_put(tty); | |
1652 | status = inb(port->ioaddr + UART_MSR); | 1655 | status = inb(port->ioaddr + UART_MSR); |
1653 | if (status & UART_MSR_DCD) | 1656 | if (status & UART_MSR_DCD) |
1654 | ms.dcd = 1; | 1657 | ms.dcd = 1; |
@@ -1704,15 +1707,18 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1704 | me->up_txcnt[p] = port->mon_data.up_txcnt; | 1707 | me->up_txcnt[p] = port->mon_data.up_txcnt; |
1705 | me->modem_status[p] = | 1708 | me->modem_status[p] = |
1706 | port->mon_data.modem_status; | 1709 | port->mon_data.modem_status; |
1707 | me->baudrate[p] = tty_get_baud_rate(port->port.tty); | 1710 | tty = tty_port_tty_get(&port->port); |
1708 | 1711 | ||
1709 | if (!port->port.tty || !port->port.tty->termios) { | 1712 | if (!tty || !tty->termios) { |
1710 | cflag = port->normal_termios.c_cflag; | 1713 | cflag = port->normal_termios.c_cflag; |
1711 | iflag = port->normal_termios.c_iflag; | 1714 | iflag = port->normal_termios.c_iflag; |
1715 | me->baudrate[p] = tty_termios_baud_rate(&port->normal_termios); | ||
1712 | } else { | 1716 | } else { |
1713 | cflag = port->port.tty->termios->c_cflag; | 1717 | cflag = tty->termios->c_cflag; |
1714 | iflag = port->port.tty->termios->c_iflag; | 1718 | iflag = tty->termios->c_iflag; |
1719 | me->baudrate[p] = tty_get_baud_rate(tty); | ||
1715 | } | 1720 | } |
1721 | tty_kref_put(tty); | ||
1716 | 1722 | ||
1717 | me->databits[p] = cflag & CSIZE; | 1723 | me->databits[p] = cflag & CSIZE; |
1718 | me->stopbits[p] = cflag & CSTOPB; | 1724 | me->stopbits[p] = cflag & CSTOPB; |
@@ -1822,12 +1828,12 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1822 | switch (cmd) { | 1828 | switch (cmd) { |
1823 | case TIOCGSERIAL: | 1829 | case TIOCGSERIAL: |
1824 | lock_kernel(); | 1830 | lock_kernel(); |
1825 | retval = mxser_get_serial_info(info, argp); | 1831 | retval = mxser_get_serial_info(tty, argp); |
1826 | unlock_kernel(); | 1832 | unlock_kernel(); |
1827 | return retval; | 1833 | return retval; |
1828 | case TIOCSSERIAL: | 1834 | case TIOCSSERIAL: |
1829 | lock_kernel(); | 1835 | lock_kernel(); |
1830 | retval = mxser_set_serial_info(info, argp); | 1836 | retval = mxser_set_serial_info(tty, argp); |
1831 | unlock_kernel(); | 1837 | unlock_kernel(); |
1832 | return retval; | 1838 | return retval; |
1833 | case TIOCSERGETLSR: /* Get line status register */ | 1839 | case TIOCSERGETLSR: /* Get line status register */ |
@@ -1896,7 +1902,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1896 | 1902 | ||
1897 | lock_kernel(); | 1903 | lock_kernel(); |
1898 | status = mxser_get_msr(info->ioaddr, 1, tty->index); | 1904 | status = mxser_get_msr(info->ioaddr, 1, tty->index); |
1899 | mxser_check_modem_status(info, status); | 1905 | mxser_check_modem_status(tty, info, status); |
1900 | 1906 | ||
1901 | mcr = inb(info->ioaddr + UART_MCR); | 1907 | mcr = inb(info->ioaddr + UART_MCR); |
1902 | if (mcr & MOXA_MUST_MCR_XON_FLAG) | 1908 | if (mcr & MOXA_MUST_MCR_XON_FLAG) |
@@ -1909,7 +1915,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1909 | else | 1915 | else |
1910 | info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; | 1916 | info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; |
1911 | 1917 | ||
1912 | if (info->port.tty->hw_stopped) | 1918 | if (tty->hw_stopped) |
1913 | info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; | 1919 | info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; |
1914 | else | 1920 | else |
1915 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; | 1921 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; |
@@ -1958,7 +1964,7 @@ static void mxser_stoprx(struct tty_struct *tty) | |||
1958 | } | 1964 | } |
1959 | } | 1965 | } |
1960 | 1966 | ||
1961 | if (info->port.tty->termios->c_cflag & CRTSCTS) { | 1967 | if (tty->termios->c_cflag & CRTSCTS) { |
1962 | info->MCR &= ~UART_MCR_RTS; | 1968 | info->MCR &= ~UART_MCR_RTS; |
1963 | outb(info->MCR, info->ioaddr + UART_MCR); | 1969 | outb(info->MCR, info->ioaddr + UART_MCR); |
1964 | } | 1970 | } |
@@ -1995,7 +2001,7 @@ static void mxser_unthrottle(struct tty_struct *tty) | |||
1995 | } | 2001 | } |
1996 | } | 2002 | } |
1997 | 2003 | ||
1998 | if (info->port.tty->termios->c_cflag & CRTSCTS) { | 2004 | if (tty->termios->c_cflag & CRTSCTS) { |
1999 | info->MCR |= UART_MCR_RTS; | 2005 | info->MCR |= UART_MCR_RTS; |
2000 | outb(info->MCR, info->ioaddr + UART_MCR); | 2006 | outb(info->MCR, info->ioaddr + UART_MCR); |
2001 | } | 2007 | } |
@@ -2040,7 +2046,7 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi | |||
2040 | unsigned long flags; | 2046 | unsigned long flags; |
2041 | 2047 | ||
2042 | spin_lock_irqsave(&info->slock, flags); | 2048 | spin_lock_irqsave(&info->slock, flags); |
2043 | mxser_change_speed(info, old_termios); | 2049 | mxser_change_speed(tty, old_termios); |
2044 | spin_unlock_irqrestore(&info->slock, flags); | 2050 | spin_unlock_irqrestore(&info->slock, flags); |
2045 | 2051 | ||
2046 | if ((old_termios->c_cflag & CRTSCTS) && | 2052 | if ((old_termios->c_cflag & CRTSCTS) && |
@@ -2138,10 +2144,10 @@ static void mxser_hangup(struct tty_struct *tty) | |||
2138 | struct mxser_port *info = tty->driver_data; | 2144 | struct mxser_port *info = tty->driver_data; |
2139 | 2145 | ||
2140 | mxser_flush_buffer(tty); | 2146 | mxser_flush_buffer(tty); |
2141 | mxser_shutdown(info); | 2147 | mxser_shutdown(tty); |
2142 | info->port.count = 0; | 2148 | info->port.count = 0; |
2143 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 2149 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
2144 | info->port.tty = NULL; | 2150 | tty_port_tty_set(&info->port, NULL); |
2145 | wake_up_interruptible(&info->port.open_wait); | 2151 | wake_up_interruptible(&info->port.open_wait); |
2146 | } | 2152 | } |
2147 | 2153 | ||
@@ -2164,9 +2170,9 @@ static int mxser_rs_break(struct tty_struct *tty, int break_state) | |||
2164 | return 0; | 2170 | return 0; |
2165 | } | 2171 | } |
2166 | 2172 | ||
2167 | static void mxser_receive_chars(struct mxser_port *port, int *status) | 2173 | static void mxser_receive_chars(struct tty_struct *tty, |
2174 | struct mxser_port *port, int *status) | ||
2168 | { | 2175 | { |
2169 | struct tty_struct *tty = port->port.tty; | ||
2170 | unsigned char ch, gdl; | 2176 | unsigned char ch, gdl; |
2171 | int ignored = 0; | 2177 | int ignored = 0; |
2172 | int cnt = 0; | 2178 | int cnt = 0; |
@@ -2174,9 +2180,8 @@ static void mxser_receive_chars(struct mxser_port *port, int *status) | |||
2174 | int max = 256; | 2180 | int max = 256; |
2175 | 2181 | ||
2176 | recv_room = tty->receive_room; | 2182 | recv_room = tty->receive_room; |
2177 | if ((recv_room == 0) && (!port->ldisc_stop_rx)) | 2183 | if (recv_room == 0 && !port->ldisc_stop_rx) |
2178 | mxser_stoprx(tty); | 2184 | mxser_stoprx(tty); |
2179 | |||
2180 | if (port->board->chip_flag != MOXA_OTHER_UART) { | 2185 | if (port->board->chip_flag != MOXA_OTHER_UART) { |
2181 | 2186 | ||
2182 | if (*status & UART_LSR_SPECIAL) | 2187 | if (*status & UART_LSR_SPECIAL) |
@@ -2253,7 +2258,7 @@ intr_old: | |||
2253 | } while (*status & UART_LSR_DR); | 2258 | } while (*status & UART_LSR_DR); |
2254 | 2259 | ||
2255 | end_intr: | 2260 | end_intr: |
2256 | mxvar_log.rxcnt[port->port.tty->index] += cnt; | 2261 | mxvar_log.rxcnt[tty->index] += cnt; |
2257 | port->mon_data.rxcnt += cnt; | 2262 | port->mon_data.rxcnt += cnt; |
2258 | port->mon_data.up_rxcnt += cnt; | 2263 | port->mon_data.up_rxcnt += cnt; |
2259 | 2264 | ||
@@ -2267,14 +2272,14 @@ end_intr: | |||
2267 | spin_lock(&port->slock); | 2272 | spin_lock(&port->slock); |
2268 | } | 2273 | } |
2269 | 2274 | ||
2270 | static void mxser_transmit_chars(struct mxser_port *port) | 2275 | static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port) |
2271 | { | 2276 | { |
2272 | int count, cnt; | 2277 | int count, cnt; |
2273 | 2278 | ||
2274 | if (port->x_char) { | 2279 | if (port->x_char) { |
2275 | outb(port->x_char, port->ioaddr + UART_TX); | 2280 | outb(port->x_char, port->ioaddr + UART_TX); |
2276 | port->x_char = 0; | 2281 | port->x_char = 0; |
2277 | mxvar_log.txcnt[port->port.tty->index]++; | 2282 | mxvar_log.txcnt[tty->index]++; |
2278 | port->mon_data.txcnt++; | 2283 | port->mon_data.txcnt++; |
2279 | port->mon_data.up_txcnt++; | 2284 | port->mon_data.up_txcnt++; |
2280 | port->icount.tx++; | 2285 | port->icount.tx++; |
@@ -2284,8 +2289,8 @@ static void mxser_transmit_chars(struct mxser_port *port) | |||
2284 | if (port->port.xmit_buf == NULL) | 2289 | if (port->port.xmit_buf == NULL) |
2285 | return; | 2290 | return; |
2286 | 2291 | ||
2287 | if ((port->xmit_cnt <= 0) || port->port.tty->stopped || | 2292 | if (port->xmit_cnt <= 0 || tty->stopped || |
2288 | (port->port.tty->hw_stopped && | 2293 | (tty->hw_stopped && |
2289 | (port->type != PORT_16550A) && | 2294 | (port->type != PORT_16550A) && |
2290 | (!port->board->chip_flag))) { | 2295 | (!port->board->chip_flag))) { |
2291 | port->IER &= ~UART_IER_THRI; | 2296 | port->IER &= ~UART_IER_THRI; |
@@ -2302,14 +2307,14 @@ static void mxser_transmit_chars(struct mxser_port *port) | |||
2302 | if (--port->xmit_cnt <= 0) | 2307 | if (--port->xmit_cnt <= 0) |
2303 | break; | 2308 | break; |
2304 | } while (--count > 0); | 2309 | } while (--count > 0); |
2305 | mxvar_log.txcnt[port->port.tty->index] += (cnt - port->xmit_cnt); | 2310 | mxvar_log.txcnt[tty->index] += (cnt - port->xmit_cnt); |
2306 | 2311 | ||
2307 | port->mon_data.txcnt += (cnt - port->xmit_cnt); | 2312 | port->mon_data.txcnt += (cnt - port->xmit_cnt); |
2308 | port->mon_data.up_txcnt += (cnt - port->xmit_cnt); | 2313 | port->mon_data.up_txcnt += (cnt - port->xmit_cnt); |
2309 | port->icount.tx += (cnt - port->xmit_cnt); | 2314 | port->icount.tx += (cnt - port->xmit_cnt); |
2310 | 2315 | ||
2311 | if (port->xmit_cnt < WAKEUP_CHARS) | 2316 | if (port->xmit_cnt < WAKEUP_CHARS && tty) |
2312 | tty_wakeup(port->port.tty); | 2317 | tty_wakeup(tty); |
2313 | 2318 | ||
2314 | if (port->xmit_cnt <= 0) { | 2319 | if (port->xmit_cnt <= 0) { |
2315 | port->IER &= ~UART_IER_THRI; | 2320 | port->IER &= ~UART_IER_THRI; |
@@ -2328,6 +2333,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) | |||
2328 | int max, irqbits, bits, msr; | 2333 | int max, irqbits, bits, msr; |
2329 | unsigned int int_cnt, pass_counter = 0; | 2334 | unsigned int int_cnt, pass_counter = 0; |
2330 | int handled = IRQ_NONE; | 2335 | int handled = IRQ_NONE; |
2336 | struct tty_struct *tty; | ||
2331 | 2337 | ||
2332 | for (i = 0; i < MXSER_BOARDS; i++) | 2338 | for (i = 0; i < MXSER_BOARDS; i++) |
2333 | if (dev_id == &mxser_boards[i]) { | 2339 | if (dev_id == &mxser_boards[i]) { |
@@ -2360,13 +2366,15 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) | |||
2360 | if (iir & UART_IIR_NO_INT) | 2366 | if (iir & UART_IIR_NO_INT) |
2361 | break; | 2367 | break; |
2362 | iir &= MOXA_MUST_IIR_MASK; | 2368 | iir &= MOXA_MUST_IIR_MASK; |
2363 | if (!port->port.tty || | 2369 | tty = tty_port_tty_get(&port->port); |
2370 | if (!tty || | ||
2364 | (port->port.flags & ASYNC_CLOSING) || | 2371 | (port->port.flags & ASYNC_CLOSING) || |
2365 | !(port->port.flags & | 2372 | !(port->port.flags & |
2366 | ASYNC_INITIALIZED)) { | 2373 | ASYNC_INITIALIZED)) { |
2367 | status = inb(port->ioaddr + UART_LSR); | 2374 | status = inb(port->ioaddr + UART_LSR); |
2368 | outb(0x27, port->ioaddr + UART_FCR); | 2375 | outb(0x27, port->ioaddr + UART_FCR); |
2369 | inb(port->ioaddr + UART_MSR); | 2376 | inb(port->ioaddr + UART_MSR); |
2377 | tty_kref_put(tty); | ||
2370 | break; | 2378 | break; |
2371 | } | 2379 | } |
2372 | 2380 | ||
@@ -2387,27 +2395,28 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) | |||
2387 | iir == MOXA_MUST_IIR_RDA || | 2395 | iir == MOXA_MUST_IIR_RDA || |
2388 | iir == MOXA_MUST_IIR_RTO || | 2396 | iir == MOXA_MUST_IIR_RTO || |
2389 | iir == MOXA_MUST_IIR_LSR) | 2397 | iir == MOXA_MUST_IIR_LSR) |
2390 | mxser_receive_chars(port, | 2398 | mxser_receive_chars(tty, port, |
2391 | &status); | 2399 | &status); |
2392 | 2400 | ||
2393 | } else { | 2401 | } else { |
2394 | status &= port->read_status_mask; | 2402 | status &= port->read_status_mask; |
2395 | if (status & UART_LSR_DR) | 2403 | if (status & UART_LSR_DR) |
2396 | mxser_receive_chars(port, | 2404 | mxser_receive_chars(tty, port, |
2397 | &status); | 2405 | &status); |
2398 | } | 2406 | } |
2399 | msr = inb(port->ioaddr + UART_MSR); | 2407 | msr = inb(port->ioaddr + UART_MSR); |
2400 | if (msr & UART_MSR_ANY_DELTA) | 2408 | if (msr & UART_MSR_ANY_DELTA) |
2401 | mxser_check_modem_status(port, msr); | 2409 | mxser_check_modem_status(tty, port, msr); |
2402 | 2410 | ||
2403 | if (port->board->chip_flag) { | 2411 | if (port->board->chip_flag) { |
2404 | if (iir == 0x02 && (status & | 2412 | if (iir == 0x02 && (status & |
2405 | UART_LSR_THRE)) | 2413 | UART_LSR_THRE)) |
2406 | mxser_transmit_chars(port); | 2414 | mxser_transmit_chars(tty, port); |
2407 | } else { | 2415 | } else { |
2408 | if (status & UART_LSR_THRE) | 2416 | if (status & UART_LSR_THRE) |
2409 | mxser_transmit_chars(port); | 2417 | mxser_transmit_chars(tty, port); |
2410 | } | 2418 | } |
2419 | tty_kref_put(tty); | ||
2411 | } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); | 2420 | } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); |
2412 | spin_unlock(&port->slock); | 2421 | spin_unlock(&port->slock); |
2413 | } | 2422 | } |