diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/mxser.c | 192 |
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 | ||
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 (!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 | */ |
682 | static int mxser_change_speed(struct mxser_port *info, | 683 | static 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 | ||
858 | static void mxser_check_modem_status(struct mxser_port *port, int status) | 860 | static 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 | ||
906 | static int mxser_startup(struct mxser_port *info) | 910 | static 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 | */ |
1012 | static void mxser_shutdown(struct mxser_port *info) | 1015 | static 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 | */ |
1340 | static int mxser_get_serial_info(struct mxser_port *info, | 1343 | static 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 | ||
1360 | static int mxser_set_serial_info(struct mxser_port *info, | 1364 | static 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) | |||
1606 | static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | 1611 | static 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 | ||
2167 | static void mxser_receive_chars(struct mxser_port *port, int *status) | 2178 | static 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 | ||
2255 | end_intr: | 2265 | end_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 | ||
2270 | static void mxser_transmit_chars(struct mxser_port *port) | 2280 | static 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 | } |