Commit a6614999e800cf3a134ce93ea46ef837e3c0e76e

Authored by Alan Cox
Committed by Linus Torvalds
1 parent 7834909f1e

tty: Introduce some close helpers for ports

Again this is a lot of common code we can unify

Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 11 changed files with 126 additions and 391 deletions Side-by-side Diff

drivers/char/isicom.c
... ... @@ -945,76 +945,30 @@
945 945  
946 946 static void isicom_close(struct tty_struct *tty, struct file *filp)
947 947 {
948   - struct isi_port *port = tty->driver_data;
  948 + struct isi_port *ip = tty->driver_data;
  949 + struct tty_port *port = &ip->port;
949 950 struct isi_board *card;
950 951 unsigned long flags;
951 952  
952   - if (!port)
953   - return;
954   - card = port->card;
955   - if (isicom_paranoia_check(port, tty->name, "isicom_close"))
956   - return;
  953 + BUG_ON(!ip);
957 954  
958   - pr_dbg("Close start!!!.\n");
959   -
960   - spin_lock_irqsave(&port->port.lock, flags);
961   - if (tty_hung_up_p(filp)) {
962   - spin_unlock_irqrestore(&port->port.lock, flags);
  955 + card = ip->card;
  956 + if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
963 957 return;
964   - }
965 958  
966   - if (tty->count == 1 && port->port.count != 1) {
967   - printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
968   - "count tty->count = 1 port count = %d.\n",
969   - card->base, port->port.count);
970   - port->port.count = 1;
971   - }
972   - if (--port->port.count < 0) {
973   - printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
974   - "count for channel%d = %d", card->base, port->channel,
975   - port->port.count);
976   - port->port.count = 0;
977   - }
978   -
979   - if (port->port.count) {
980   - spin_unlock_irqrestore(&port->port.lock, flags);
981   - return;
982   - }
983   - port->port.flags |= ASYNC_CLOSING;
984   - tty->closing = 1;
985   - spin_unlock_irqrestore(&port->port.lock, flags);
986   -
987   - if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
988   - tty_wait_until_sent(tty, port->port.closing_wait);
989 959 /* indicate to the card that no more data can be received
990 960 on this port */
991 961 spin_lock_irqsave(&card->card_lock, flags);
992   - if (port->port.flags & ASYNC_INITIALIZED) {
993   - card->port_status &= ~(1 << port->channel);
  962 + if (port->flags & ASYNC_INITIALIZED) {
  963 + card->port_status &= ~(1 << ip->channel);
994 964 outw(card->port_status, card->base + 0x02);
995 965 }
996   - isicom_shutdown_port(port);
  966 + isicom_shutdown_port(ip);
997 967 spin_unlock_irqrestore(&card->card_lock, flags);
998 968  
999 969 isicom_flush_buffer(tty);
1000   - tty_ldisc_flush(tty);
1001   -
1002   - spin_lock_irqsave(&port->port.lock, flags);
1003   - tty->closing = 0;
1004   -
1005   - if (port->port.blocked_open) {
1006   - spin_unlock_irqrestore(&port->port.lock, flags);
1007   - if (port->port.close_delay) {
1008   - pr_dbg("scheduling until time out.\n");
1009   - msleep_interruptible(
1010   - jiffies_to_msecs(port->port.close_delay));
1011   - }
1012   - spin_lock_irqsave(&port->port.lock, flags);
1013   - wake_up_interruptible(&port->port.open_wait);
1014   - }
1015   - port->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
1016   - wake_up_interruptible(&port->port.close_wait);
1017   - spin_unlock_irqrestore(&port->port.lock, flags);
  970 +
  971 + tty_port_close_end(port, tty);
1018 972 }
1019 973  
1020 974 /* write et all */
drivers/char/istallion.c
... ... @@ -767,7 +767,7 @@
767 767 break;
768 768 }
769 769 if (i == ARRAY_SIZE(stli_brdstr)) {
770   - printk("STALLION: unknown board name, %s?\n", argp[0]);
  770 + printk(KERN_WARNING "istallion: unknown board name, %s?\n", argp[0]);
771 771 return 0;
772 772 }
773 773  
774 774  
775 775  
... ... @@ -855,22 +855,9 @@
855 855 return;
856 856 port = &portp->port;
857 857  
858   - spin_lock_irqsave(&port->lock, flags);
859   - if (tty_hung_up_p(filp)) {
860   - spin_unlock_irqrestore(&port->lock, flags);
  858 + if (tty_port_close_start(port, tty, filp) == 0)
861 859 return;
862   - }
863   - if (tty->count == 1 && port->count != 1)
864   - port->count = 1;
865   - if (port->count-- > 1) {
866   - spin_unlock_irqrestore(&port->lock, flags);
867   - return;
868   - }
869 860  
870   - port->flags |= ASYNC_CLOSING;
871   - tty->closing = 1;
872   - spin_unlock_irqrestore(&port->lock, flags);
873   -
874 861 /*
875 862 * May want to wait for data to drain before closing. The BUSY flag
876 863 * keeps track of whether we are still transmitting or not. It is
... ... @@ -882,6 +869,8 @@
882 869 stli_flushchars(tty);
883 870 spin_unlock_irqrestore(&stli_lock, flags);
884 871  
  872 + /* We end up doing this twice for the moment. This needs looking at
  873 + eventually. Note we still use portp->closing_wait as a result */
885 874 if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
886 875 tty_wait_until_sent(tty, portp->closing_wait);
887 876  
... ... @@ -905,17 +894,8 @@
905 894 set_bit(ST_DOFLUSHRX, &portp->state);
906 895 stli_flushbuffer(tty);
907 896  
908   - tty->closing = 0;
909   - tty_port_tty_set(&portp->port, NULL);
910   -
911   - if (port->blocked_open) {
912   - if (portp->close_delay)
913   - msleep_interruptible(jiffies_to_msecs(portp->close_delay));
914   - wake_up_interruptible(&port->open_wait);
915   - }
916   -
917   - port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
918   - wake_up_interruptible(&port->close_wait);
  897 + tty_port_close_end(port, tty);
  898 + tty_port_tty_set(port, NULL);
919 899 }
920 900  
921 901 /*****************************************************************************/
... ... @@ -1482,7 +1462,7 @@
1482 1462 sio.irq = 0;
1483 1463 sio.flags = portp->port.flags;
1484 1464 sio.baud_base = portp->baud_base;
1485   - sio.close_delay = portp->close_delay;
  1465 + sio.close_delay = portp->port.close_delay;
1486 1466 sio.closing_wait = portp->closing_wait;
1487 1467 sio.custom_divisor = portp->custom_divisor;
1488 1468 sio.xmit_fifo_size = 0;
... ... @@ -1514,7 +1494,7 @@
1514 1494 return -EFAULT;
1515 1495 if (!capable(CAP_SYS_ADMIN)) {
1516 1496 if ((sio.baud_base != portp->baud_base) ||
1517   - (sio.close_delay != portp->close_delay) ||
  1497 + (sio.close_delay != portp->port.close_delay) ||
1518 1498 ((sio.flags & ~ASYNC_USR_MASK) !=
1519 1499 (portp->port.flags & ~ASYNC_USR_MASK)))
1520 1500 return -EPERM;
... ... @@ -1523,7 +1503,7 @@
1523 1503 portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) |
1524 1504 (sio.flags & ASYNC_USR_MASK);
1525 1505 portp->baud_base = sio.baud_base;
1526   - portp->close_delay = sio.close_delay;
  1506 + portp->port.close_delay = sio.close_delay;
1527 1507 portp->closing_wait = sio.closing_wait;
1528 1508 portp->custom_divisor = sio.custom_divisor;
1529 1509  
... ... @@ -2065,7 +2045,7 @@
2065 2045 unsigned char __iomem *bits;
2066 2046  
2067 2047 if (test_bit(ST_CMDING, &portp->state)) {
2068   - printk(KERN_ERR "STALLION: command already busy, cmd=%x!\n",
  2048 + printk(KERN_ERR "istallion: command already busy, cmd=%x!\n",
2069 2049 (int) cmd);
2070 2050 return;
2071 2051 }
... ... @@ -2625,7 +2605,7 @@
2625 2605 for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) {
2626 2606 portp = kzalloc(sizeof(struct stliport), GFP_KERNEL);
2627 2607 if (!portp) {
2628   - printk("STALLION: failed to allocate port structure\n");
  2608 + printk(KERN_WARNING "istallion: failed to allocate port structure\n");
2629 2609 continue;
2630 2610 }
2631 2611 tty_port_init(&portp->port);
... ... @@ -2635,7 +2615,7 @@
2635 2615 portp->brdnr = brdp->brdnr;
2636 2616 portp->panelnr = panelnr;
2637 2617 portp->baud_base = STL_BAUDBASE;
2638   - portp->close_delay = STL_CLOSEDELAY;
  2618 + portp->port.close_delay = STL_CLOSEDELAY;
2639 2619 portp->closing_wait = 30 * HZ;
2640 2620 init_waitqueue_head(&portp->port.open_wait);
2641 2621 init_waitqueue_head(&portp->port.close_wait);
... ... @@ -2692,7 +2672,7 @@
2692 2672 unsigned char val;
2693 2673  
2694 2674 if (offset > brdp->memsize) {
2695   - printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
  2675 + printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2696 2676 "range at line=%d(%d), brd=%d\n",
2697 2677 (int) offset, line, __LINE__, brdp->brdnr);
2698 2678 ptr = NULL;
... ... @@ -2766,7 +2746,7 @@
2766 2746 unsigned char val;
2767 2747  
2768 2748 if (offset > brdp->memsize) {
2769   - printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
  2749 + printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2770 2750 "range at line=%d(%d), brd=%d\n",
2771 2751 (int) offset, line, __LINE__, brdp->brdnr);
2772 2752 ptr = NULL;
... ... @@ -2818,7 +2798,7 @@
2818 2798 unsigned char val;
2819 2799  
2820 2800 if (offset > brdp->memsize) {
2821   - printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
  2801 + printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2822 2802 "range at line=%d(%d), brd=%d\n",
2823 2803 (int) offset, line, __LINE__, brdp->brdnr);
2824 2804 ptr = NULL;
... ... @@ -2863,7 +2843,7 @@
2863 2843 unsigned char val;
2864 2844  
2865 2845 if (offset > brdp->memsize) {
2866   - printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
  2846 + printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2867 2847 "range at line=%d(%d), board=%d\n",
2868 2848 (int) offset, line, __LINE__, brdp->brdnr);
2869 2849 ptr = NULL;
... ... @@ -2928,7 +2908,7 @@
2928 2908 void __iomem *ptr;
2929 2909  
2930 2910 if (offset > brdp->memsize) {
2931   - printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
  2911 + printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2932 2912 "range at line=%d(%d), brd=%d\n",
2933 2913 (int) offset, line, __LINE__, brdp->brdnr);
2934 2914 ptr = NULL;
... ... @@ -2994,7 +2974,7 @@
2994 2974 unsigned char val;
2995 2975  
2996 2976 if (offset > brdp->memsize) {
2997   - printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
  2977 + printk(KERN_ERR "istallion: shared memory pointer=%x out of "
2998 2978 "range at line=%d(%d), brd=%d\n",
2999 2979 (int) offset, line, __LINE__, brdp->brdnr);
3000 2980 ptr = NULL;
... ... @@ -3433,7 +3413,7 @@
3433 3413 #endif
3434 3414  
3435 3415 if (nrdevs < (brdp->nrports + 1)) {
3436   - printk(KERN_ERR "STALLION: slave failed to allocate memory for "
  3416 + printk(KERN_ERR "istallion: slave failed to allocate memory for "
3437 3417 "all devices, devices=%d\n", nrdevs);
3438 3418 brdp->nrports = nrdevs - 1;
3439 3419 }
3440 3420  
... ... @@ -3443,13 +3423,13 @@
3443 3423 brdp->bitsize = (nrdevs + 7) / 8;
3444 3424 memoff = readl(&hdrp->memp);
3445 3425 if (memoff > brdp->memsize) {
3446   - printk(KERN_ERR "STALLION: corrupted shared memory region?\n");
  3426 + printk(KERN_ERR "istallion: corrupted shared memory region?\n");
3447 3427 rc = -EIO;
3448 3428 goto stli_donestartup;
3449 3429 }
3450 3430 memp = (cdkmem_t __iomem *) EBRDGETMEMPTR(brdp, memoff);
3451 3431 if (readw(&memp->dtype) != TYP_ASYNCTRL) {
3452   - printk(KERN_ERR "STALLION: no slave control device found\n");
  3432 + printk(KERN_ERR "istallion: no slave control device found\n");
3453 3433 goto stli_donestartup;
3454 3434 }
3455 3435 memp++;
... ... @@ -3534,7 +3514,7 @@
3534 3514 retval = stli_initonb(brdp);
3535 3515 break;
3536 3516 default:
3537   - printk(KERN_ERR "STALLION: board=%d is unknown board "
  3517 + printk(KERN_ERR "istallion: board=%d is unknown board "
3538 3518 "type=%d\n", brdp->brdnr, brdp->brdtype);
3539 3519 retval = -ENODEV;
3540 3520 }
... ... @@ -3543,7 +3523,7 @@
3543 3523 return retval;
3544 3524  
3545 3525 stli_initports(brdp);
3546   - printk(KERN_INFO "STALLION: %s found, board=%d io=%x mem=%x "
  3526 + printk(KERN_INFO "istallion: %s found, board=%d io=%x mem=%x "
3547 3527 "nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype],
3548 3528 brdp->brdnr, brdp->iobase, (int) brdp->memaddr,
3549 3529 brdp->nrpanels, brdp->nrports);
... ... @@ -3637,7 +3617,7 @@
3637 3617 if (! foundit) {
3638 3618 brdp->memaddr = 0;
3639 3619 brdp->membase = NULL;
3640   - printk(KERN_ERR "STALLION: failed to probe shared memory "
  3620 + printk(KERN_ERR "istallion: failed to probe shared memory "
3641 3621 "region for %s in EISA slot=%d\n",
3642 3622 stli_brdnames[brdp->brdtype], (brdp->iobase >> 12));
3643 3623 return -ENODEV;
... ... @@ -3782,7 +3762,7 @@
3782 3762 mutex_lock(&stli_brdslock);
3783 3763 brdnr = stli_getbrdnr();
3784 3764 if (brdnr < 0) {
3785   - printk(KERN_INFO "STALLION: too many boards found, "
  3765 + printk(KERN_INFO "istallion: too many boards found, "
3786 3766 "maximum supported %d\n", STL_MAXBRDS);
3787 3767 mutex_unlock(&stli_brdslock);
3788 3768 retval = -EIO;
... ... @@ -3854,7 +3834,7 @@
3854 3834  
3855 3835 brdp = kzalloc(sizeof(struct stlibrd), GFP_KERNEL);
3856 3836 if (!brdp) {
3857   - printk(KERN_ERR "STALLION: failed to allocate memory "
  3837 + printk(KERN_ERR "istallion: failed to allocate memory "
3858 3838 "(size=%Zd)\n", sizeof(struct stlibrd));
3859 3839 return NULL;
3860 3840 }
... ... @@ -4493,7 +4473,7 @@
4493 4473  
4494 4474 stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL);
4495 4475 if (!stli_txcookbuf) {
4496   - printk(KERN_ERR "STALLION: failed to allocate memory "
  4476 + printk(KERN_ERR "istallion: failed to allocate memory "
4497 4477 "(size=%d)\n", STLI_TXBUFSIZE);
4498 4478 retval = -ENOMEM;
4499 4479 goto err;
... ... @@ -4518,7 +4498,7 @@
4518 4498  
4519 4499 retval = tty_register_driver(stli_serial);
4520 4500 if (retval) {
4521   - printk(KERN_ERR "STALLION: failed to register serial driver\n");
  4501 + printk(KERN_ERR "istallion: failed to register serial driver\n");
4522 4502 goto err_ttyput;
4523 4503 }
4524 4504  
... ... @@ -4532,7 +4512,7 @@
4532 4512 */
4533 4513 retval = register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stli_fsiomem);
4534 4514 if (retval) {
4535   - printk(KERN_ERR "STALLION: failed to register serial memory "
  4515 + printk(KERN_ERR "istallion: failed to register serial memory "
4536 4516 "device\n");
4537 4517 goto err_deinit;
4538 4518 }
drivers/char/mxser.c
... ... @@ -1080,58 +1080,27 @@
1080 1080 static void mxser_close(struct tty_struct *tty, struct file *filp)
1081 1081 {
1082 1082 struct mxser_port *info = tty->driver_data;
  1083 + struct tty_port *port = &info->port;
1083 1084  
1084 1085 unsigned long timeout;
1085   - unsigned long flags;
1086 1086  
1087 1087 if (tty->index == MXSER_PORTS)
1088 1088 return;
1089 1089 if (!info)
1090 1090 return;
1091 1091  
1092   - spin_lock_irqsave(&info->port.lock, flags);
1093   -
1094   - if (tty_hung_up_p(filp)) {
1095   - spin_unlock_irqrestore(&info->port.lock, flags);
  1092 + if (tty_port_close_start(port, tty, filp) == 0)
1096 1093 return;
1097   - }
1098   - if ((tty->count == 1) && (info->port.count != 1)) {
1099   - /*
1100   - * Uh, oh. tty->count is 1, which means that the tty
1101   - * structure will be freed. Info->port.count should always
1102   - * be one in these conditions. If it's greater than
1103   - * one, we've got real problems, since it means the
1104   - * serial port won't be shutdown.
1105   - */
1106   - printk(KERN_ERR "mxser_close: bad serial port count; "
1107   - "tty->count is 1, info->port.count is %d\n", info->port.count);
1108   - info->port.count = 1;
1109   - }
1110   - if (--info->port.count < 0) {
1111   - printk(KERN_ERR "mxser_close: bad serial port count for "
1112   - "ttys%d: %d\n", tty->index, info->port.count);
1113   - info->port.count = 0;
1114   - }
1115   - if (info->port.count) {
1116   - spin_unlock_irqrestore(&info->port.lock, flags);
1117   - return;
1118   - }
1119   - info->port.flags |= ASYNC_CLOSING;
1120   - spin_unlock_irqrestore(&info->port.lock, flags);
  1094 +
1121 1095 /*
1122 1096 * Save the termios structure, since this port may have
1123 1097 * separate termios for callout and dialin.
  1098 + *
  1099 + * FIXME: Can this go ?
1124 1100 */
1125 1101 if (info->port.flags & ASYNC_NORMAL_ACTIVE)
1126 1102 info->normal_termios = *tty->termios;
1127 1103 /*
1128   - * Now we wait for the transmit buffer to clear; and we notify
1129   - * the line discipline to only process XON/XOFF characters.
1130   - */
1131   - tty->closing = 1;
1132   - if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
1133   - tty_wait_until_sent(tty, info->port.closing_wait);
1134   - /*
1135 1104 * At this point we stop accepting input. To do this, we
1136 1105 * disable the receive line status interrupts, and tell the
1137 1106 * interrupt driver to stop checking the data ready bit in the
1138 1107  
1139 1108  
... ... @@ -1156,19 +1125,12 @@
1156 1125 }
1157 1126 }
1158 1127 mxser_shutdown(tty);
1159   -
1160 1128 mxser_flush_buffer(tty);
1161   - tty_ldisc_flush(tty);
1162 1129  
1163   - tty->closing = 0;
1164   - tty_port_tty_set(&info->port, NULL);
1165   - if (info->port.blocked_open) {
1166   - if (info->port.close_delay)
1167   - schedule_timeout_interruptible(info->port.close_delay);
1168   - wake_up_interruptible(&info->port.open_wait);
1169   - }
1170   -
1171   - info->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
  1130 + /* Right now the tty_port set is done outside of the close_end helper
  1131 + as we don't yet have everyone using refcounts */
  1132 + tty_port_close_end(port, tty);
  1133 + tty_port_tty_set(port, NULL);
1172 1134 }
1173 1135  
1174 1136 static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count)
drivers/char/riscom8.c
... ... @@ -929,36 +929,12 @@
929 929 if (!port || rc_paranoia_check(port, tty->name, "close"))
930 930 return;
931 931  
932   - spin_lock_irqsave(&port->port.lock, flags);
933   -
934   - if (tty_hung_up_p(filp))
935   - goto out;
936   -
937 932 bp = port_Board(port);
938   - if ((tty->count == 1) && (port->port.count != 1)) {
939   - printk(KERN_INFO "rc%d: rc_close: bad port count;"
940   - " tty->count is 1, port count is %d\n",
941   - board_No(bp), port->port.count);
942   - port->port.count = 1;
943   - }
944   - if (--port->port.count < 0) {
945   - printk(KERN_INFO "rc%d: rc_close: bad port count "
946   - "for tty%d: %d\n",
947   - board_No(bp), port_No(port), port->port.count);
948   - port->port.count = 0;
949   - }
950   - if (port->port.count)
951   - goto out;
952   - port->port.flags |= ASYNC_CLOSING;
  933 +
  934 + if (tty_port_close_start(&port->port, tty, filp) == 0)
  935 + return;
  936 +
953 937 /*
954   - * Now we wait for the transmit buffer to clear; and we notify
955   - * the line discipline to only process XON/XOFF characters.
956   - */
957   - tty->closing = 1;
958   - spin_unlock_irqrestore(&port->port.lock, flags);
959   - if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
960   - tty_wait_until_sent(tty, port->port.closing_wait);
961   - /*
962 938 * At this point we stop accepting input. To do this, we
963 939 * disable the receive line status interrupts, and tell the
964 940 * interrupt driver to stop checking the data ready bit in the
965 941  
... ... @@ -989,23 +965,8 @@
989 965 rc_shutdown_port(tty, bp, port);
990 966 rc_flush_buffer(tty);
991 967 spin_unlock_irqrestore(&riscom_lock, flags);
992   - tty_ldisc_flush(tty);
993 968  
994   - spin_lock_irqsave(&port->port.lock, flags);
995   - tty->closing = 0;
996   - port->port.tty = NULL;
997   - if (port->port.blocked_open) {
998   - spin_unlock_irqrestore(&port->port.lock, flags);
999   - if (port->port.close_delay)
1000   - msleep_interruptible(jiffies_to_msecs(port->port.close_delay));
1001   - wake_up_interruptible(&port->port.open_wait);
1002   - spin_lock_irqsave(&port->port.lock, flags);
1003   - }
1004   - port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1005   - wake_up_interruptible(&port->port.close_wait);
1006   -
1007   -out:
1008   - spin_unlock_irqrestore(&riscom_lock, flags);
  969 + tty_port_close_end(&port->port, tty);
1009 970 }
1010 971  
1011 972 static int rc_write(struct tty_struct *tty,
drivers/char/stallion.c
... ... @@ -833,40 +833,20 @@
833 833 pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp);
834 834  
835 835 portp = tty->driver_data;
836   - if (portp == NULL)
837   - return;
  836 + BUG_ON(portp == NULL);
  837 +
838 838 port = &portp->port;
839 839  
840   - spin_lock_irqsave(&port->lock, flags);
841   - if (tty_hung_up_p(filp)) {
842   - spin_unlock_irqrestore(&port->lock, flags);
  840 + if (tty_port_close_start(port, tty, filp) == 0)
843 841 return;
844   - }
845   - if (tty->count == 1 && port->count != 1)
846   - port->count = 1;
847   - if (port->count-- > 1) {
848   - spin_unlock_irqrestore(&port->lock, flags);
849   - return;
850   - }
851   -
852   - port->count = 0;
853   - port->flags |= ASYNC_CLOSING;
854   -
855 842 /*
856 843 * May want to wait for any data to drain before closing. The BUSY
857 844 * flag keeps track of whether we are still sending or not - it is
858 845 * very accurate for the cd1400, not quite so for the sc26198.
859 846 * (The sc26198 has no "end-of-data" interrupt only empty FIFO)
860 847 */
861   - tty->closing = 1;
862   -
863   - spin_unlock_irqrestore(&port->lock, flags);
864   -
865   - if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
866   - tty_wait_until_sent(tty, portp->closing_wait);
867 848 stl_waituntilsent(tty, (HZ / 2));
868 849  
869   -
870 850 spin_lock_irqsave(&port->lock, flags);
871 851 portp->port.flags &= ~ASYNC_INITIALIZED;
872 852 spin_unlock_irqrestore(&port->lock, flags);
873 853  
874 854  
... ... @@ -883,20 +863,9 @@
883 863 portp->tx.head = NULL;
884 864 portp->tx.tail = NULL;
885 865 }
886   - set_bit(TTY_IO_ERROR, &tty->flags);
887   - tty_ldisc_flush(tty);
888 866  
889   - tty->closing = 0;
  867 + tty_port_close_end(port, tty);
890 868 tty_port_tty_set(port, NULL);
891   -
892   - if (port->blocked_open) {
893   - if (portp->close_delay)
894   - msleep_interruptible(jiffies_to_msecs(portp->close_delay));
895   - wake_up_interruptible(&portp->port.open_wait);
896   - }
897   -
898   - portp->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
899   - wake_up_interruptible(&port->close_wait);
900 869 }
901 870  
902 871 /*****************************************************************************/
drivers/char/synclink.c
... ... @@ -3104,70 +3104,18 @@
3104 3104 if (debug_level >= DEBUG_LEVEL_INFO)
3105 3105 printk("%s(%d):mgsl_close(%s) entry, count=%d\n",
3106 3106 __FILE__,__LINE__, info->device_name, info->port.count);
3107   -
3108   - if (!info->port.count)
3109   - return;
3110 3107  
3111   - if (tty_hung_up_p(filp))
  3108 + if (tty_port_close_start(&info->port, tty, filp) == 0)
3112 3109 goto cleanup;
3113 3110  
3114   - if ((tty->count == 1) && (info->port.count != 1)) {
3115   - /*
3116   - * tty->count is 1 and the tty structure will be freed.
3117   - * info->port.count should be one in this case.
3118   - * if it's not, correct it so that the port is shutdown.
3119   - */
3120   - printk("mgsl_close: bad refcount; tty->count is 1, "
3121   - "info->port.count is %d\n", info->port.count);
3122   - info->port.count = 1;
3123   - }
3124   -
3125   - info->port.count--;
3126   -
3127   - /* if at least one open remaining, leave hardware active */
3128   - if (info->port.count)
3129   - goto cleanup;
3130   -
3131   - info->port.flags |= ASYNC_CLOSING;
3132   -
3133   - /* set tty->closing to notify line discipline to
3134   - * only process XON/XOFF characters. Only the N_TTY
3135   - * discipline appears to use this (ppp does not).
3136   - */
3137   - tty->closing = 1;
3138   -
3139   - /* wait for transmit data to clear all layers */
3140   -
3141   - if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
3142   - if (debug_level >= DEBUG_LEVEL_INFO)
3143   - printk("%s(%d):mgsl_close(%s) calling tty_wait_until_sent\n",
3144   - __FILE__,__LINE__, info->device_name );
3145   - tty_wait_until_sent(tty, info->port.closing_wait);
3146   - }
3147   -
3148 3111 if (info->port.flags & ASYNC_INITIALIZED)
3149 3112 mgsl_wait_until_sent(tty, info->timeout);
3150   -
3151 3113 mgsl_flush_buffer(tty);
3152   -
3153 3114 tty_ldisc_flush(tty);
3154   -
3155 3115 shutdown(info);
3156   -
3157   - tty->closing = 0;
  3116 +
  3117 + tty_port_close_end(&info->port, tty);
3158 3118 info->port.tty = NULL;
3159   -
3160   - if (info->port.blocked_open) {
3161   - if (info->port.close_delay) {
3162   - msleep_interruptible(jiffies_to_msecs(info->port.close_delay));
3163   - }
3164   - wake_up_interruptible(&info->port.open_wait);
3165   - }
3166   -
3167   - info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
3168   -
3169   - wake_up_interruptible(&info->port.close_wait);
3170   -
3171 3119 cleanup:
3172 3120 if (debug_level >= DEBUG_LEVEL_INFO)
3173 3121 printk("%s(%d):mgsl_close(%s) exit, count=%d\n", __FILE__,__LINE__,
drivers/char/synclink_gt.c
... ... @@ -720,44 +720,9 @@
720 720 return;
721 721 DBGINFO(("%s close entry, count=%d\n", info->device_name, info->port.count));
722 722  
723   - if (!info->port.count)
724   - return;
725   -
726   - if (tty_hung_up_p(filp))
  723 + if (tty_port_close_start(&info->port, tty, filp) == 0)
727 724 goto cleanup;
728 725  
729   - if ((tty->count == 1) && (info->port.count != 1)) {
730   - /*
731   - * tty->count is 1 and the tty structure will be freed.
732   - * info->port.count should be one in this case.
733   - * if it's not, correct it so that the port is shutdown.
734   - */
735   - DBGERR(("%s close: bad refcount; tty->count=1, "
736   - "info->port.count=%d\n", info->device_name, info->port.count));
737   - info->port.count = 1;
738   - }
739   -
740   - info->port.count--;
741   -
742   - /* if at least one open remaining, leave hardware active */
743   - if (info->port.count)
744   - goto cleanup;
745   -
746   - info->port.flags |= ASYNC_CLOSING;
747   -
748   - /* set tty->closing to notify line discipline to
749   - * only process XON/XOFF characters. Only the N_TTY
750   - * discipline appears to use this (ppp does not).
751   - */
752   - tty->closing = 1;
753   -
754   - /* wait for transmit data to clear all layers */
755   -
756   - if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
757   - DBGINFO(("%s call tty_wait_until_sent\n", info->device_name));
758   - tty_wait_until_sent(tty, info->port.closing_wait);
759   - }
760   -
761 726 if (info->port.flags & ASYNC_INITIALIZED)
762 727 wait_until_sent(tty, info->timeout);
763 728 flush_buffer(tty);
764 729  
... ... @@ -765,20 +730,8 @@
765 730  
766 731 shutdown(info);
767 732  
768   - tty->closing = 0;
  733 + tty_port_close_end(&info->port, tty);
769 734 info->port.tty = NULL;
770   -
771   - if (info->port.blocked_open) {
772   - if (info->port.close_delay) {
773   - msleep_interruptible(jiffies_to_msecs(info->port.close_delay));
774   - }
775   - wake_up_interruptible(&info->port.open_wait);
776   - }
777   -
778   - info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
779   -
780   - wake_up_interruptible(&info->port.close_wait);
781   -
782 735 cleanup:
783 736 DBGINFO(("%s close exit, count=%d\n", tty->driver->name, info->port.count));
784 737 }
drivers/char/synclinkmp.c
... ... @@ -810,70 +810,18 @@
810 810 printk("%s(%d):%s close() entry, count=%d\n",
811 811 __FILE__,__LINE__, info->device_name, info->port.count);
812 812  
813   - if (!info->port.count)
814   - return;
815   -
816   - if (tty_hung_up_p(filp))
  813 + if (tty_port_close_start(&info->port, tty, filp) == 0)
817 814 goto cleanup;
818   -
819   - if ((tty->count == 1) && (info->port.count != 1)) {
820   - /*
821   - * tty->count is 1 and the tty structure will be freed.
822   - * info->port.count should be one in this case.
823   - * if it's not, correct it so that the port is shutdown.
824   - */
825   - printk("%s(%d):%s close: bad refcount; tty->count is 1, "
826   - "info->port.count is %d\n",
827   - __FILE__,__LINE__, info->device_name, info->port.count);
828   - info->port.count = 1;
829   - }
830   -
831   - info->port.count--;
832   -
833   - /* if at least one open remaining, leave hardware active */
834   - if (info->port.count)
835   - goto cleanup;
836   -
837   - info->port.flags |= ASYNC_CLOSING;
838   -
839   - /* set tty->closing to notify line discipline to
840   - * only process XON/XOFF characters. Only the N_TTY
841   - * discipline appears to use this (ppp does not).
842   - */
843   - tty->closing = 1;
844   -
845   - /* wait for transmit data to clear all layers */
846   -
847   - if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
848   - if (debug_level >= DEBUG_LEVEL_INFO)
849   - printk("%s(%d):%s close() calling tty_wait_until_sent\n",
850   - __FILE__,__LINE__, info->device_name );
851   - tty_wait_until_sent(tty, info->port.closing_wait);
852   - }
853   -
  815 +
854 816 if (info->port.flags & ASYNC_INITIALIZED)
855 817 wait_until_sent(tty, info->timeout);
856 818  
857 819 flush_buffer(tty);
858   -
859 820 tty_ldisc_flush(tty);
860   -
861 821 shutdown(info);
862 822  
863   - tty->closing = 0;
  823 + tty_port_close_end(&info->port, tty);
864 824 info->port.tty = NULL;
865   -
866   - if (info->port.blocked_open) {
867   - if (info->port.close_delay) {
868   - msleep_interruptible(jiffies_to_msecs(info->port.close_delay));
869   - }
870   - wake_up_interruptible(&info->port.open_wait);
871   - }
872   -
873   - info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
874   -
875   - wake_up_interruptible(&info->port.close_wait);
876   -
877 825 cleanup:
878 826 if (debug_level >= DEBUG_LEVEL_INFO)
879 827 printk("%s(%d):%s close() exit, count=%d\n", __FILE__,__LINE__,
drivers/char/tty_port.c
... ... @@ -256,4 +256,63 @@
256 256  
257 257 }
258 258 EXPORT_SYMBOL(tty_port_block_til_ready);
  259 +
  260 +int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct file *filp)
  261 +{
  262 + unsigned long flags;
  263 +
  264 + spin_lock_irqsave(&port->lock, flags);
  265 + if (tty_hung_up_p(filp)) {
  266 + spin_unlock_irqrestore(&port->lock, flags);
  267 + return 0;
  268 + }
  269 +
  270 + if( tty->count == 1 && port->count != 1) {
  271 + printk(KERN_WARNING
  272 + "tty_port_close_start: tty->count = 1 port count = %d.\n",
  273 + port->count);
  274 + port->count = 1;
  275 + }
  276 + if (--port->count < 0) {
  277 + printk(KERN_WARNING "tty_port_close_start: count = %d\n",
  278 + port->count);
  279 + port->count = 0;
  280 + }
  281 +
  282 + if (port->count) {
  283 + spin_unlock_irqrestore(&port->lock, flags);
  284 + return 0;
  285 + }
  286 + port->flags |= ASYNC_CLOSING;
  287 + tty->closing = 1;
  288 + spin_unlock_irqrestore(&port->lock, flags);
  289 + if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
  290 + tty_wait_until_sent(tty, port->closing_wait);
  291 + return 1;
  292 +}
  293 +EXPORT_SYMBOL(tty_port_close_start);
  294 +
  295 +void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
  296 +{
  297 + unsigned long flags;
  298 +
  299 + tty_ldisc_flush(tty);
  300 +
  301 + spin_lock_irqsave(&port->lock, flags);
  302 + tty->closing = 0;
  303 +
  304 + if (port->blocked_open) {
  305 + spin_unlock_irqrestore(&port->lock, flags);
  306 + if (port->close_delay) {
  307 + msleep_interruptible(
  308 + jiffies_to_msecs(port->close_delay));
  309 + }
  310 + spin_lock_irqsave(&port->lock, flags);
  311 + wake_up_interruptible(&port->open_wait);
  312 + }
  313 + port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
  314 + wake_up_interruptible(&port->close_wait);
  315 + spin_unlock_irqrestore(&port->lock, flags);
  316 +}
  317 +EXPORT_SYMBOL(tty_port_close_end);
include/linux/istallion.h
... ... @@ -59,7 +59,6 @@
59 59 unsigned int devnr;
60 60 int baud_base;
61 61 int custom_divisor;
62   - int close_delay;
63 62 int closing_wait;
64 63 int rc;
65 64 int argsize;
... ... @@ -441,6 +441,9 @@
441 441 extern void tty_port_hangup(struct tty_port *port);
442 442 extern int tty_port_block_til_ready(struct tty_port *port,
443 443 struct tty_struct *tty, struct file *filp);
  444 +extern int tty_port_close_start(struct tty_port *port,
  445 + struct tty_struct *tty, struct file *filp);
  446 +extern void tty_port_close_end(struct tty_port *port, struct tty_struct *tty);
444 447  
445 448 extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc);
446 449 extern int tty_unregister_ldisc(int disc);