aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2009-01-02 08:46:24 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-02 13:19:39 -0500
commit4350f3ffec7a7e70770a7369186b3db7d97acfdf (patch)
treef4c1aeda5c4253ceb6458f63a30940e50aaa0786 /drivers/char
parent2a6eadbd5a2ae8f458e421f3614f1ad13c0f9a1c (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.c142
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
409static int stl_brdinit(struct stlbrd *brdp); 409static int stl_brdinit(struct stlbrd *brdp);
410static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp); 410static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp);
411static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); 411static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp);
412static 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/* 774static 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
802static 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)
899static void stl_close(struct tty_struct *tty, struct file *filp) 827static 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)
1414static void stl_hangup(struct tty_struct *tty) 1344static 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
2672static const struct tty_port_operations stl_port_ops = { 2605static 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/*****************************************************************************/