aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/rocket.c177
-rw-r--r--drivers/char/tty_port.c3
2 files changed, 21 insertions, 159 deletions
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index b5e5e77c59de..f59fc5cea067 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -879,108 +879,6 @@ static void raise_dtr_rts(struct tty_port *port)
879 sSetRTS(&info->channel); 879 sSetRTS(&info->channel);
880} 880}
881 881
882/* info->port.count is considered critical, protected by spinlocks. */
883static int block_til_ready(struct tty_struct *tty, struct file *filp,
884 struct r_port *info)
885{
886 DECLARE_WAITQUEUE(wait, current);
887 struct tty_port *port = &info->port;
888 int retval;
889 int do_clocal = 0, extra_count = 0;
890 unsigned long flags;
891
892 /*
893 * If the device is in the middle of being closed, then block
894 * until it's done, and then try again.
895 */
896 if (tty_hung_up_p(filp))
897 return ((info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
898 if (info->flags & ASYNC_CLOSING) {
899 if (wait_for_completion_interruptible(&info->close_wait))
900 return -ERESTARTSYS;
901 return ((info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
902 }
903
904 /*
905 * If non-blocking mode is set, or the port is not enabled,
906 * then make the check up front and then exit.
907 */
908 if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) {
909 info->port.flags |= ASYNC_NORMAL_ACTIVE;
910 return 0;
911 }
912 if (tty->termios->c_cflag & CLOCAL)
913 do_clocal = 1;
914
915 /*
916 * Block waiting for the carrier detect and the line to become free. While we are in
917 * this loop, port->count is dropped by one, so that rp_close() knows when to free things.
918 * We restore it upon exit, either normal or abnormal.
919 */
920 retval = 0;
921 add_wait_queue(&port->open_wait, &wait);
922#ifdef ROCKET_DEBUG_OPEN
923 printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, port->count);
924#endif
925 spin_lock_irqsave(&port->lock, flags);
926
927#ifdef ROCKET_DISABLE_SIMUSAGE
928 info->port.flags |= ASYNC_NORMAL_ACTIVE;
929#else
930 if (!tty_hung_up_p(filp)) {
931 extra_count = 1;
932 port->count--;
933 }
934#endif
935 port->blocked_open++;
936
937 spin_unlock_irqrestore(&port->lock, flags);
938
939 while (1) {
940 if (tty->termios->c_cflag & CBAUD)
941 tty_port_raise_dtr_rts(port);
942 set_current_state(TASK_INTERRUPTIBLE);
943 if (tty_hung_up_p(filp) || !(info->port.flags & ASYNC_INITIALIZED)) {
944 if (info->port.flags & ASYNC_HUP_NOTIFY)
945 retval = -EAGAIN;
946 else
947 retval = -ERESTARTSYS;
948 break;
949 }
950 if (!(info->port.flags & ASYNC_CLOSING) &&
951 (do_clocal || tty_port_carrier_raised(port)))
952 break;
953 if (signal_pending(current)) {
954 retval = -ERESTARTSYS;
955 break;
956 }
957#ifdef ROCKET_DEBUG_OPEN
958 printk(KERN_INFO "block_til_ready blocking: ttyR%d, count = %d, flags=0x%0x\n",
959 info->line, port->count, info->port.flags);
960#endif
961 schedule(); /* Don't hold spinlock here, will hang PC */
962 }
963 __set_current_state(TASK_RUNNING);
964 remove_wait_queue(&port->open_wait, &wait);
965
966 spin_lock_irqsave(&port->lock, flags);
967
968 if (extra_count)
969 port->count++;
970 port->blocked_open--;
971
972 spin_unlock_irqrestore(&port->lock, flags);
973
974#ifdef ROCKET_DEBUG_OPEN
975 printk(KERN_INFO "block_til_ready after blocking: ttyR%d, count = %d\n",
976 info->line, port->count);
977#endif
978 if (retval)
979 return retval;
980 info->port.flags |= ASYNC_NORMAL_ACTIVE;
981 return 0;
982}
983
984/* 882/*
985 * Exception handler that opens a serial port. Creates xmit_buf storage, fills in 883 * Exception handler that opens a serial port. Creates xmit_buf storage, fills in
986 * port's r_port struct. Initializes the port hardware. 884 * port's r_port struct. Initializes the port hardware.
@@ -988,24 +886,26 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
988static int rp_open(struct tty_struct *tty, struct file *filp) 886static int rp_open(struct tty_struct *tty, struct file *filp)
989{ 887{
990 struct r_port *info; 888 struct r_port *info;
889 struct tty_port *port;
991 int line = 0, retval; 890 int line = 0, retval;
992 CHANNEL_t *cp; 891 CHANNEL_t *cp;
993 unsigned long page; 892 unsigned long page;
994 893
995 line = tty->index; 894 line = tty->index;
996 if ((line < 0) || (line >= MAX_RP_PORTS) || ((info = rp_table[line]) == NULL)) 895 if (line < 0 || line >= MAX_RP_PORTS || ((info = rp_table[line]) == NULL))
997 return -ENXIO; 896 return -ENXIO;
998 897 port = &info->port;
898
999 page = __get_free_page(GFP_KERNEL); 899 page = __get_free_page(GFP_KERNEL);
1000 if (!page) 900 if (!page)
1001 return -ENOMEM; 901 return -ENOMEM;
1002 902
1003 if (info->port.flags & ASYNC_CLOSING) { 903 if (port->flags & ASYNC_CLOSING) {
1004 retval = wait_for_completion_interruptible(&info->close_wait); 904 retval = wait_for_completion_interruptible(&info->close_wait);
1005 free_page(page); 905 free_page(page);
1006 if (retval) 906 if (retval)
1007 return retval; 907 return retval;
1008 return ((info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); 908 return ((port->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
1009 } 909 }
1010 910
1011 /* 911 /*
@@ -1017,9 +917,9 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
1017 info->xmit_buf = (unsigned char *) page; 917 info->xmit_buf = (unsigned char *) page;
1018 918
1019 tty->driver_data = info; 919 tty->driver_data = info;
1020 tty_port_tty_set(&info->port, tty); 920 tty_port_tty_set(port, tty);
1021 921
1022 if (info->port.count++ == 0) { 922 if (port->count++ == 0) {
1023 atomic_inc(&rp_num_ports_open); 923 atomic_inc(&rp_num_ports_open);
1024 924
1025#ifdef ROCKET_DEBUG_OPEN 925#ifdef ROCKET_DEBUG_OPEN
@@ -1034,7 +934,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
1034 /* 934 /*
1035 * Info->count is now 1; so it's safe to sleep now. 935 * Info->count is now 1; so it's safe to sleep now.
1036 */ 936 */
1037 if ((info->port.flags & ASYNC_INITIALIZED) == 0) { 937 if (!test_bit(ASYNC_INITIALIZED, &port->flags)) {
1038 cp = &info->channel; 938 cp = &info->channel;
1039 sSetRxTrigger(cp, TRIG_1); 939 sSetRxTrigger(cp, TRIG_1);
1040 if (sGetChanStatus(cp) & CD_ACT) 940 if (sGetChanStatus(cp) & CD_ACT)
@@ -1058,7 +958,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
1058 sEnRxFIFO(cp); 958 sEnRxFIFO(cp);
1059 sEnTransmit(cp); 959 sEnTransmit(cp);
1060 960
1061 info->port.flags |= ASYNC_INITIALIZED; 961 set_bit(ASYNC_INITIALIZED, &info->port.flags);
1062 962
1063 /* 963 /*
1064 * Set up the tty->alt_speed kludge 964 * Set up the tty->alt_speed kludge
@@ -1081,7 +981,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
1081 /* Starts (or resets) the maint polling loop */ 981 /* Starts (or resets) the maint polling loop */
1082 mod_timer(&rocket_timer, jiffies + POLL_PERIOD); 982 mod_timer(&rocket_timer, jiffies + POLL_PERIOD);
1083 983
1084 retval = block_til_ready(tty, filp, info); 984 retval = tty_port_block_til_ready(port, tty, filp);
1085 if (retval) { 985 if (retval) {
1086#ifdef ROCKET_DEBUG_OPEN 986#ifdef ROCKET_DEBUG_OPEN
1087 printk(KERN_INFO "rp_open returning after block_til_ready with %d\n", retval); 987 printk(KERN_INFO "rp_open returning after block_til_ready with %d\n", retval);
@@ -1098,7 +998,6 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
1098{ 998{
1099 struct r_port *info = tty->driver_data; 999 struct r_port *info = tty->driver_data;
1100 struct tty_port *port = &info->port; 1000 struct tty_port *port = &info->port;
1101 unsigned long flags;
1102 int timeout; 1001 int timeout;
1103 CHANNEL_t *cp; 1002 CHANNEL_t *cp;
1104 1003
@@ -1109,53 +1008,10 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
1109 printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->port.count); 1008 printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->port.count);
1110#endif 1009#endif
1111 1010
1112 if (tty_hung_up_p(filp)) 1011 if (tty_port_close_start(port, tty, filp) == 0)
1113 return; 1012 return;
1114 spin_lock_irqsave(&port->lock, flags);
1115
1116 if (tty->count == 1 && port->count != 1) {
1117 /*
1118 * Uh, oh. tty->count is 1, which means that the tty
1119 * structure will be freed. Info->count should always
1120 * be one in these conditions. If it's greater than
1121 * one, we've got real problems, since it means the
1122 * serial port won't be shutdown.
1123 */
1124 printk(KERN_WARNING "rp_close: bad serial port count; "
1125 "tty->count is 1, info->port.count is %d\n", info->port.count);
1126 port->count = 1;
1127 }
1128 if (--port->count < 0) {
1129 printk(KERN_WARNING "rp_close: bad serial port count for "
1130 "ttyR%d: %d\n", info->line, info->port.count);
1131 port->count = 0;
1132 }
1133 if (port->count) {
1134 spin_unlock_irqrestore(&port->lock, flags);
1135 return;
1136 }
1137 info->port.flags |= ASYNC_CLOSING;
1138 spin_unlock_irqrestore(&port->lock, flags);
1139 1013
1140 cp = &info->channel; 1014 cp = &info->channel;
1141
1142 /*
1143 * Notify the line discpline to only process XON/XOFF characters
1144 */
1145 tty->closing = 1;
1146
1147 /*
1148 * If transmission was throttled by the application request,
1149 * just flush the xmit buffer.
1150 */
1151 if (tty->flow_stopped)
1152 rp_flush_buffer(tty);
1153
1154 /*
1155 * Wait for the transmit buffer to clear
1156 */
1157 if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
1158 tty_wait_until_sent(tty, port->closing_wait);
1159 /* 1015 /*
1160 * Before we drop DTR, make sure the UART transmitter 1016 * Before we drop DTR, make sure the UART transmitter
1161 * has completely drained; this is especially 1017 * has completely drained; this is especially
@@ -1184,6 +1040,9 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
1184 1040
1185 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); 1041 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1186 1042
1043 /* We can't yet use tty_port_close_end as the buffer handling in this
1044 driver is a bit different to the usual */
1045
1187 if (port->blocked_open) { 1046 if (port->blocked_open) {
1188 if (port->close_delay) { 1047 if (port->close_delay) {
1189 msleep_interruptible(jiffies_to_msecs(port->close_delay)); 1048 msleep_interruptible(jiffies_to_msecs(port->close_delay));
@@ -1197,6 +1056,8 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
1197 } 1056 }
1198 info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING | ASYNC_NORMAL_ACTIVE); 1057 info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING | ASYNC_NORMAL_ACTIVE);
1199 tty->closing = 0; 1058 tty->closing = 0;
1059 tty_port_tty_set(port, NULL);
1060 wake_up_interruptible(&port->close_wait);
1200 complete_all(&info->close_wait); 1061 complete_all(&info->close_wait);
1201 atomic_dec(&rp_num_ports_open); 1062 atomic_dec(&rp_num_ports_open);
1202 1063
@@ -1659,9 +1520,7 @@ static void rp_hangup(struct tty_struct *tty)
1659 atomic_dec(&rp_num_ports_open); 1520 atomic_dec(&rp_num_ports_open);
1660 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); 1521 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1661 1522
1662 info->port.count = 0; 1523 tty_port_hangup(&info->port);
1663 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1664 tty_port_tty_set(&info->port, NULL);
1665 1524
1666 cp = &info->channel; 1525 cp = &info->channel;
1667 sDisRxFIFO(cp); 1526 sDisRxFIFO(cp);
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index b580fcf629f8..9b8004c72686 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -286,6 +286,9 @@ int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct f
286 port->flags |= ASYNC_CLOSING; 286 port->flags |= ASYNC_CLOSING;
287 tty->closing = 1; 287 tty->closing = 1;
288 spin_unlock_irqrestore(&port->lock, flags); 288 spin_unlock_irqrestore(&port->lock, flags);
289 /* Don't block on a stalled port, just pull the chain */
290 if (tty->flow_stopped)
291 tty_driver_flush_buffer(tty);
289 if (port->flags & ASYNC_INITIALIZED && 292 if (port->flags & ASYNC_INITIALIZED &&
290 port->closing_wait != ASYNC_CLOSING_WAIT_NONE) 293 port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
291 tty_wait_until_sent(tty, port->closing_wait); 294 tty_wait_until_sent(tty, port->closing_wait);