Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tty: use port methods for the rocket driver

Now we have our ducks in order we can begin switching to the port
operations

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

authored by

Alan Cox and committed by
Linus Torvalds
fba85e01 47b01b3a

+21 -159
+18 -159
drivers/char/rocket.c
··· 879 879 sSetRTS(&info->channel); 880 880 } 881 881 882 - /* info->port.count is considered critical, protected by spinlocks. */ 883 - static 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 883 * Exception handler that opens a serial port. Creates xmit_buf storage, fills in 986 884 * port's r_port struct. Initializes the port hardware. ··· 886 988 static int rp_open(struct tty_struct *tty, struct file *filp) 887 989 { 888 990 struct r_port *info; 991 + struct tty_port *port; 889 992 int line = 0, retval; 890 993 CHANNEL_t *cp; 891 994 unsigned long page; 892 995 893 996 line = tty->index; 894 - if ((line < 0) || (line >= MAX_RP_PORTS) || ((info = rp_table[line]) == NULL)) 997 + if (line < 0 || line >= MAX_RP_PORTS || ((info = rp_table[line]) == NULL)) 895 998 return -ENXIO; 896 - 999 + port = &info->port; 1000 + 897 1001 page = __get_free_page(GFP_KERNEL); 898 1002 if (!page) 899 1003 return -ENOMEM; 900 1004 901 - if (info->port.flags & ASYNC_CLOSING) { 1005 + if (port->flags & ASYNC_CLOSING) { 902 1006 retval = wait_for_completion_interruptible(&info->close_wait); 903 1007 free_page(page); 904 1008 if (retval) 905 1009 return retval; 906 - return ((info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); 1010 + return ((port->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); 907 1011 } 908 1012 909 1013 /* ··· 917 1017 info->xmit_buf = (unsigned char *) page; 918 1018 919 1019 tty->driver_data = info; 920 - tty_port_tty_set(&info->port, tty); 1020 + tty_port_tty_set(port, tty); 921 1021 922 - if (info->port.count++ == 0) { 1022 + if (port->count++ == 0) { 923 1023 atomic_inc(&rp_num_ports_open); 924 1024 925 1025 #ifdef ROCKET_DEBUG_OPEN ··· 934 1034 /* 935 1035 * Info->count is now 1; so it's safe to sleep now. 936 1036 */ 937 - if ((info->port.flags & ASYNC_INITIALIZED) == 0) { 1037 + if (!test_bit(ASYNC_INITIALIZED, &port->flags)) { 938 1038 cp = &info->channel; 939 1039 sSetRxTrigger(cp, TRIG_1); 940 1040 if (sGetChanStatus(cp) & CD_ACT) ··· 958 1058 sEnRxFIFO(cp); 959 1059 sEnTransmit(cp); 960 1060 961 - info->port.flags |= ASYNC_INITIALIZED; 1061 + set_bit(ASYNC_INITIALIZED, &info->port.flags); 962 1062 963 1063 /* 964 1064 * Set up the tty->alt_speed kludge ··· 981 1081 /* Starts (or resets) the maint polling loop */ 982 1082 mod_timer(&rocket_timer, jiffies + POLL_PERIOD); 983 1083 984 - retval = block_til_ready(tty, filp, info); 1084 + retval = tty_port_block_til_ready(port, tty, filp); 985 1085 if (retval) { 986 1086 #ifdef ROCKET_DEBUG_OPEN 987 1087 printk(KERN_INFO "rp_open returning after block_til_ready with %d\n", retval); ··· 998 1098 { 999 1099 struct r_port *info = tty->driver_data; 1000 1100 struct tty_port *port = &info->port; 1001 - unsigned long flags; 1002 1101 int timeout; 1003 1102 CHANNEL_t *cp; 1004 1103 ··· 1008 1109 printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->port.count); 1009 1110 #endif 1010 1111 1011 - if (tty_hung_up_p(filp)) 1112 + if (tty_port_close_start(port, tty, filp) == 0) 1012 1113 return; 1013 - spin_lock_irqsave(&port->lock, flags); 1014 - 1015 - if (tty->count == 1 && port->count != 1) { 1016 - /* 1017 - * Uh, oh. tty->count is 1, which means that the tty 1018 - * structure will be freed. Info->count should always 1019 - * be one in these conditions. If it's greater than 1020 - * one, we've got real problems, since it means the 1021 - * serial port won't be shutdown. 1022 - */ 1023 - printk(KERN_WARNING "rp_close: bad serial port count; " 1024 - "tty->count is 1, info->port.count is %d\n", info->port.count); 1025 - port->count = 1; 1026 - } 1027 - if (--port->count < 0) { 1028 - printk(KERN_WARNING "rp_close: bad serial port count for " 1029 - "ttyR%d: %d\n", info->line, info->port.count); 1030 - port->count = 0; 1031 - } 1032 - if (port->count) { 1033 - spin_unlock_irqrestore(&port->lock, flags); 1034 - return; 1035 - } 1036 - info->port.flags |= ASYNC_CLOSING; 1037 - spin_unlock_irqrestore(&port->lock, flags); 1038 1114 1039 1115 cp = &info->channel; 1040 - 1041 - /* 1042 - * Notify the line discpline to only process XON/XOFF characters 1043 - */ 1044 - tty->closing = 1; 1045 - 1046 - /* 1047 - * If transmission was throttled by the application request, 1048 - * just flush the xmit buffer. 1049 - */ 1050 - if (tty->flow_stopped) 1051 - rp_flush_buffer(tty); 1052 - 1053 - /* 1054 - * Wait for the transmit buffer to clear 1055 - */ 1056 - if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) 1057 - tty_wait_until_sent(tty, port->closing_wait); 1058 1116 /* 1059 1117 * Before we drop DTR, make sure the UART transmitter 1060 1118 * has completely drained; this is especially ··· 1040 1184 1041 1185 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); 1042 1186 1187 + /* We can't yet use tty_port_close_end as the buffer handling in this 1188 + driver is a bit different to the usual */ 1189 + 1043 1190 if (port->blocked_open) { 1044 1191 if (port->close_delay) { 1045 1192 msleep_interruptible(jiffies_to_msecs(port->close_delay)); ··· 1056 1197 } 1057 1198 info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING | ASYNC_NORMAL_ACTIVE); 1058 1199 tty->closing = 0; 1200 + tty_port_tty_set(port, NULL); 1201 + wake_up_interruptible(&port->close_wait); 1059 1202 complete_all(&info->close_wait); 1060 1203 atomic_dec(&rp_num_ports_open); 1061 1204 ··· 1520 1659 atomic_dec(&rp_num_ports_open); 1521 1660 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); 1522 1661 1523 - info->port.count = 0; 1524 - info->port.flags &= ~ASYNC_NORMAL_ACTIVE; 1525 - tty_port_tty_set(&info->port, NULL); 1662 + tty_port_hangup(&info->port); 1526 1663 1527 1664 cp = &info->channel; 1528 1665 sDisRxFIFO(cp);
+3
drivers/char/tty_port.c
··· 286 286 port->flags |= ASYNC_CLOSING; 287 287 tty->closing = 1; 288 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 292 if (port->flags & ASYNC_INITIALIZED && 290 293 port->closing_wait != ASYNC_CLOSING_WAIT_NONE) 291 294 tty_wait_until_sent(tty, port->closing_wait);