diff options
author | Alan Cox <alan@redhat.com> | 2009-01-02 08:46:24 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-02 13:19:39 -0500 |
commit | 4350f3ffec7a7e70770a7369186b3db7d97acfdf (patch) | |
tree | f4c1aeda5c4253ceb6458f63a30940e50aaa0786 /drivers/char | |
parent | 2a6eadbd5a2ae8f458e421f3614f1ad13c0f9a1c (diff) |
tty: rework stallion to use the tty_port bits
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/stallion.c | 142 |
1 files changed, 38 insertions, 104 deletions
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 12aecdaf61ec..77eef61c46f3 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -409,7 +409,6 @@ static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, uns | |||
409 | static int stl_brdinit(struct stlbrd *brdp); | 409 | static int stl_brdinit(struct stlbrd *brdp); |
410 | static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp); | 410 | static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp); |
411 | static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); | 411 | static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); |
412 | static int stl_waitcarrier(struct tty_struct *tty, struct stlport *portp, struct file *filp); | ||
413 | 412 | ||
414 | /* | 413 | /* |
415 | * CD1400 uart specific handling functions. | 414 | * CD1400 uart specific handling functions. |
@@ -705,8 +704,9 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
705 | { | 704 | { |
706 | struct stlport *portp; | 705 | struct stlport *portp; |
707 | struct stlbrd *brdp; | 706 | struct stlbrd *brdp; |
707 | struct tty_port *port; | ||
708 | unsigned int minordev, brdnr, panelnr; | 708 | unsigned int minordev, brdnr, panelnr; |
709 | int portnr, rc; | 709 | int portnr; |
710 | 710 | ||
711 | pr_debug("stl_open(tty=%p,filp=%p): device=%s\n", tty, filp, tty->name); | 711 | pr_debug("stl_open(tty=%p,filp=%p): device=%s\n", tty, filp, tty->name); |
712 | 712 | ||
@@ -717,6 +717,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
717 | brdp = stl_brds[brdnr]; | 717 | brdp = stl_brds[brdnr]; |
718 | if (brdp == NULL) | 718 | if (brdp == NULL) |
719 | return -ENODEV; | 719 | return -ENODEV; |
720 | |||
720 | minordev = MINOR2PORT(minordev); | 721 | minordev = MINOR2PORT(minordev); |
721 | for (portnr = -1, panelnr = 0; panelnr < STL_MAXPANELS; panelnr++) { | 722 | for (portnr = -1, panelnr = 0; panelnr < STL_MAXPANELS; panelnr++) { |
722 | if (brdp->panels[panelnr] == NULL) | 723 | if (brdp->panels[panelnr] == NULL) |
@@ -733,16 +734,17 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
733 | portp = brdp->panels[panelnr]->ports[portnr]; | 734 | portp = brdp->panels[panelnr]->ports[portnr]; |
734 | if (portp == NULL) | 735 | if (portp == NULL) |
735 | return -ENODEV; | 736 | return -ENODEV; |
737 | port = &portp->port; | ||
736 | 738 | ||
737 | /* | 739 | /* |
738 | * On the first open of the device setup the port hardware, and | 740 | * On the first open of the device setup the port hardware, and |
739 | * initialize the per port data structure. | 741 | * initialize the per port data structure. |
740 | */ | 742 | */ |
741 | tty_port_tty_set(&portp->port, tty); | 743 | tty_port_tty_set(port, tty); |
742 | tty->driver_data = portp; | 744 | tty->driver_data = portp; |
743 | portp->port.count++; | 745 | port->count++; |
744 | 746 | ||
745 | if ((portp->port.flags & ASYNC_INITIALIZED) == 0) { | 747 | if ((port->flags & ASYNC_INITIALIZED) == 0) { |
746 | if (!portp->tx.buf) { | 748 | if (!portp->tx.buf) { |
747 | portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); | 749 | portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); |
748 | if (!portp->tx.buf) | 750 | if (!portp->tx.buf) |
@@ -756,34 +758,9 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
756 | stl_enablerxtx(portp, 1, 1); | 758 | stl_enablerxtx(portp, 1, 1); |
757 | stl_startrxtx(portp, 1, 0); | 759 | stl_startrxtx(portp, 1, 0); |
758 | clear_bit(TTY_IO_ERROR, &tty->flags); | 760 | clear_bit(TTY_IO_ERROR, &tty->flags); |
759 | portp->port.flags |= ASYNC_INITIALIZED; | 761 | port->flags |= ASYNC_INITIALIZED; |
760 | } | ||
761 | |||
762 | /* | ||
763 | * Check if this port is in the middle of closing. If so then wait | ||
764 | * until it is closed then return error status, based on flag settings. | ||
765 | * The sleep here does not need interrupt protection since the wakeup | ||
766 | * for it is done with the same context. | ||
767 | */ | ||
768 | if (portp->port.flags & ASYNC_CLOSING) { | ||
769 | interruptible_sleep_on(&portp->port.close_wait); | ||
770 | if (portp->port.flags & ASYNC_HUP_NOTIFY) | ||
771 | return -EAGAIN; | ||
772 | return -ERESTARTSYS; | ||
773 | } | 762 | } |
774 | 763 | return tty_port_block_til_ready(port, tty, filp); | |
775 | /* | ||
776 | * Based on type of open being done check if it can overlap with any | ||
777 | * previous opens still in effect. If we are a normal serial device | ||
778 | * then also we might have to wait for carrier. | ||
779 | */ | ||
780 | if (!(filp->f_flags & O_NONBLOCK)) | ||
781 | if ((rc = stl_waitcarrier(tty, portp, filp)) != 0) | ||
782 | return rc; | ||
783 | |||
784 | portp->port.flags |= ASYNC_NORMAL_ACTIVE; | ||
785 | |||
786 | return 0; | ||
787 | } | 764 | } |
788 | 765 | ||
789 | /*****************************************************************************/ | 766 | /*****************************************************************************/ |
@@ -794,60 +771,11 @@ static int stl_carrier_raised(struct tty_port *port) | |||
794 | return (portp->sigs & TIOCM_CD) ? 1 : 0; | 771 | return (portp->sigs & TIOCM_CD) ? 1 : 0; |
795 | } | 772 | } |
796 | 773 | ||
797 | /* | 774 | static void stl_raise_dtr_rts(struct tty_port *port) |
798 | * Possibly need to wait for carrier (DCD signal) to come high. Say | ||
799 | * maybe because if we are clocal then we don't need to wait... | ||
800 | */ | ||
801 | |||
802 | static int stl_waitcarrier(struct tty_struct *tty, struct stlport *portp, | ||
803 | struct file *filp) | ||
804 | { | 775 | { |
805 | unsigned long flags; | 776 | struct stlport *portp = container_of(port, struct stlport, port); |
806 | int rc, doclocal; | 777 | /* Takes brd_lock internally */ |
807 | struct tty_port *port = &portp->port; | 778 | stl_setsignals(portp, 1, 1); |
808 | |||
809 | pr_debug("stl_waitcarrier(portp=%p,filp=%p)\n", portp, filp); | ||
810 | |||
811 | rc = 0; | ||
812 | doclocal = 0; | ||
813 | |||
814 | spin_lock_irqsave(&stallion_lock, flags); | ||
815 | |||
816 | if (tty->termios->c_cflag & CLOCAL) | ||
817 | doclocal++; | ||
818 | |||
819 | portp->openwaitcnt++; | ||
820 | if (! tty_hung_up_p(filp)) | ||
821 | port->count--; | ||
822 | |||
823 | for (;;) { | ||
824 | /* Takes brd_lock internally */ | ||
825 | stl_setsignals(portp, 1, 1); | ||
826 | if (tty_hung_up_p(filp) || | ||
827 | ((port->flags & ASYNC_INITIALIZED) == 0)) { | ||
828 | if (port->flags & ASYNC_HUP_NOTIFY) | ||
829 | rc = -EBUSY; | ||
830 | else | ||
831 | rc = -ERESTARTSYS; | ||
832 | break; | ||
833 | } | ||
834 | if (((port->flags & ASYNC_CLOSING) == 0) && | ||
835 | (doclocal || tty_port_carrier_raised(port))) | ||
836 | break; | ||
837 | if (signal_pending(current)) { | ||
838 | rc = -ERESTARTSYS; | ||
839 | break; | ||
840 | } | ||
841 | /* FIXME */ | ||
842 | interruptible_sleep_on(&port->open_wait); | ||
843 | } | ||
844 | |||
845 | if (! tty_hung_up_p(filp)) | ||
846 | port->count++; | ||
847 | portp->openwaitcnt--; | ||
848 | spin_unlock_irqrestore(&stallion_lock, flags); | ||
849 | |||
850 | return rc; | ||
851 | } | 779 | } |
852 | 780 | ||
853 | /*****************************************************************************/ | 781 | /*****************************************************************************/ |
@@ -899,6 +827,7 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout) | |||
899 | static void stl_close(struct tty_struct *tty, struct file *filp) | 827 | static void stl_close(struct tty_struct *tty, struct file *filp) |
900 | { | 828 | { |
901 | struct stlport *portp; | 829 | struct stlport *portp; |
830 | struct tty_port *port; | ||
902 | unsigned long flags; | 831 | unsigned long flags; |
903 | 832 | ||
904 | pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp); | 833 | pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp); |
@@ -906,21 +835,22 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
906 | portp = tty->driver_data; | 835 | portp = tty->driver_data; |
907 | if (portp == NULL) | 836 | if (portp == NULL) |
908 | return; | 837 | return; |
838 | port = &portp->port; | ||
909 | 839 | ||
910 | spin_lock_irqsave(&stallion_lock, flags); | 840 | spin_lock_irqsave(&port->lock, flags); |
911 | if (tty_hung_up_p(filp)) { | 841 | if (tty_hung_up_p(filp)) { |
912 | spin_unlock_irqrestore(&stallion_lock, flags); | 842 | spin_unlock_irqrestore(&port->lock, flags); |
913 | return; | 843 | return; |
914 | } | 844 | } |
915 | if ((tty->count == 1) && (portp->port.count != 1)) | 845 | if (tty->count == 1 && port->count != 1) |
916 | portp->port.count = 1; | 846 | port->count = 1; |
917 | if (portp->port.count-- > 1) { | 847 | if (port->count-- > 1) { |
918 | spin_unlock_irqrestore(&stallion_lock, flags); | 848 | spin_unlock_irqrestore(&port->lock, flags); |
919 | return; | 849 | return; |
920 | } | 850 | } |
921 | 851 | ||
922 | portp->port.count = 0; | 852 | port->count = 0; |
923 | portp->port.flags |= ASYNC_CLOSING; | 853 | port->flags |= ASYNC_CLOSING; |
924 | 854 | ||
925 | /* | 855 | /* |
926 | * May want to wait for any data to drain before closing. The BUSY | 856 | * May want to wait for any data to drain before closing. The BUSY |
@@ -930,16 +860,16 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
930 | */ | 860 | */ |
931 | tty->closing = 1; | 861 | tty->closing = 1; |
932 | 862 | ||
933 | spin_unlock_irqrestore(&stallion_lock, flags); | 863 | spin_unlock_irqrestore(&port->lock, flags); |
934 | 864 | ||
935 | if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) | 865 | if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) |
936 | tty_wait_until_sent(tty, portp->closing_wait); | 866 | tty_wait_until_sent(tty, portp->closing_wait); |
937 | stl_waituntilsent(tty, (HZ / 2)); | 867 | stl_waituntilsent(tty, (HZ / 2)); |
938 | 868 | ||
939 | 869 | ||
940 | spin_lock_irqsave(&stallion_lock, flags); | 870 | spin_lock_irqsave(&port->lock, flags); |
941 | portp->port.flags &= ~ASYNC_INITIALIZED; | 871 | portp->port.flags &= ~ASYNC_INITIALIZED; |
942 | spin_unlock_irqrestore(&stallion_lock, flags); | 872 | spin_unlock_irqrestore(&port->lock, flags); |
943 | 873 | ||
944 | stl_disableintrs(portp); | 874 | stl_disableintrs(portp); |
945 | if (tty->termios->c_cflag & HUPCL) | 875 | if (tty->termios->c_cflag & HUPCL) |
@@ -957,16 +887,16 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
957 | tty_ldisc_flush(tty); | 887 | tty_ldisc_flush(tty); |
958 | 888 | ||
959 | tty->closing = 0; | 889 | tty->closing = 0; |
960 | tty_port_tty_set(&portp->port, NULL); | 890 | tty_port_tty_set(port, NULL); |
961 | 891 | ||
962 | if (portp->openwaitcnt) { | 892 | if (port->blocked_open) { |
963 | if (portp->close_delay) | 893 | if (portp->close_delay) |
964 | msleep_interruptible(jiffies_to_msecs(portp->close_delay)); | 894 | msleep_interruptible(jiffies_to_msecs(portp->close_delay)); |
965 | wake_up_interruptible(&portp->port.open_wait); | 895 | wake_up_interruptible(&portp->port.open_wait); |
966 | } | 896 | } |
967 | 897 | ||
968 | portp->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 898 | portp->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
969 | wake_up_interruptible(&portp->port.close_wait); | 899 | wake_up_interruptible(&port->close_wait); |
970 | } | 900 | } |
971 | 901 | ||
972 | /*****************************************************************************/ | 902 | /*****************************************************************************/ |
@@ -1414,14 +1344,20 @@ static void stl_stop(struct tty_struct *tty) | |||
1414 | static void stl_hangup(struct tty_struct *tty) | 1344 | static void stl_hangup(struct tty_struct *tty) |
1415 | { | 1345 | { |
1416 | struct stlport *portp; | 1346 | struct stlport *portp; |
1347 | struct tty_port *port; | ||
1348 | unsigned long flags; | ||
1417 | 1349 | ||
1418 | pr_debug("stl_hangup(tty=%p)\n", tty); | 1350 | pr_debug("stl_hangup(tty=%p)\n", tty); |
1419 | 1351 | ||
1420 | portp = tty->driver_data; | 1352 | portp = tty->driver_data; |
1421 | if (portp == NULL) | 1353 | if (portp == NULL) |
1422 | return; | 1354 | return; |
1355 | port = &portp->port; | ||
1356 | |||
1357 | spin_lock_irqsave(&port->lock, flags); | ||
1358 | port->flags &= ~ASYNC_INITIALIZED; | ||
1359 | spin_unlock_irqrestore(&port->lock, flags); | ||
1423 | 1360 | ||
1424 | portp->port.flags &= ~ASYNC_INITIALIZED; | ||
1425 | stl_disableintrs(portp); | 1361 | stl_disableintrs(portp); |
1426 | if (tty->termios->c_cflag & HUPCL) | 1362 | if (tty->termios->c_cflag & HUPCL) |
1427 | stl_setsignals(portp, 0, 0); | 1363 | stl_setsignals(portp, 0, 0); |
@@ -1435,10 +1371,7 @@ static void stl_hangup(struct tty_struct *tty) | |||
1435 | portp->tx.head = NULL; | 1371 | portp->tx.head = NULL; |
1436 | portp->tx.tail = NULL; | 1372 | portp->tx.tail = NULL; |
1437 | } | 1373 | } |
1438 | tty_port_tty_set(&portp->port, NULL); | 1374 | tty_port_hangup(port); |
1439 | portp->port.flags &= ~ASYNC_NORMAL_ACTIVE; | ||
1440 | portp->port.count = 0; | ||
1441 | wake_up_interruptible(&portp->port.open_wait); | ||
1442 | } | 1375 | } |
1443 | 1376 | ||
1444 | /*****************************************************************************/ | 1377 | /*****************************************************************************/ |
@@ -2671,6 +2604,7 @@ static const struct tty_operations stl_ops = { | |||
2671 | 2604 | ||
2672 | static const struct tty_port_operations stl_port_ops = { | 2605 | static const struct tty_port_operations stl_port_ops = { |
2673 | .carrier_raised = stl_carrier_raised, | 2606 | .carrier_raised = stl_carrier_raised, |
2607 | .raise_dtr_rts = stl_raise_dtr_rts, | ||
2674 | }; | 2608 | }; |
2675 | 2609 | ||
2676 | /*****************************************************************************/ | 2610 | /*****************************************************************************/ |