diff options
Diffstat (limited to 'drivers/char/riscom8.c')
-rw-r--r-- | drivers/char/riscom8.c | 194 |
1 files changed, 48 insertions, 146 deletions
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 2c6c8f33d6b4..9af8d74875bc 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -857,98 +857,21 @@ static void rc_shutdown_port(struct tty_struct *tty, | |||
857 | rc_shutdown_board(bp); | 857 | rc_shutdown_board(bp); |
858 | } | 858 | } |
859 | 859 | ||
860 | static int block_til_ready(struct tty_struct *tty, struct file *filp, | 860 | static int carrier_raised(struct tty_port *port) |
861 | struct riscom_port *port) | ||
862 | { | 861 | { |
863 | DECLARE_WAITQUEUE(wait, current); | 862 | struct riscom_port *p = container_of(port, struct riscom_port, port); |
864 | struct riscom_board *bp = port_Board(port); | 863 | struct riscom_board *bp = port_Board(p); |
865 | int retval; | ||
866 | int do_clocal = 0; | ||
867 | int CD; | ||
868 | unsigned long flags; | 864 | unsigned long flags; |
869 | 865 | int CD; | |
870 | /* | 866 | |
871 | * If the device is in the middle of being closed, then block | ||
872 | * until it's done, and then try again. | ||
873 | */ | ||
874 | if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) { | ||
875 | interruptible_sleep_on(&port->port.close_wait); | ||
876 | if (port->port.flags & ASYNC_HUP_NOTIFY) | ||
877 | return -EAGAIN; | ||
878 | else | ||
879 | return -ERESTARTSYS; | ||
880 | } | ||
881 | |||
882 | /* | ||
883 | * If non-blocking mode is set, or the port is not enabled, | ||
884 | * then make the check up front and then exit. | ||
885 | */ | ||
886 | if ((filp->f_flags & O_NONBLOCK) || | ||
887 | (tty->flags & (1 << TTY_IO_ERROR))) { | ||
888 | port->port.flags |= ASYNC_NORMAL_ACTIVE; | ||
889 | return 0; | ||
890 | } | ||
891 | |||
892 | if (C_CLOCAL(tty)) | ||
893 | do_clocal = 1; | ||
894 | |||
895 | /* | ||
896 | * Block waiting for the carrier detect and the line to become | ||
897 | * free (i.e., not in use by the callout). While we are in | ||
898 | * this loop, info->count is dropped by one, so that | ||
899 | * rs_close() knows when to free things. We restore it upon | ||
900 | * exit, either normal or abnormal. | ||
901 | */ | ||
902 | retval = 0; | ||
903 | add_wait_queue(&port->port.open_wait, &wait); | ||
904 | |||
905 | spin_lock_irqsave(&riscom_lock, flags); | 867 | spin_lock_irqsave(&riscom_lock, flags); |
906 | 868 | rc_out(bp, CD180_CAR, port_No(p)); | |
907 | if (!tty_hung_up_p(filp)) | 869 | CD = rc_in(bp, CD180_MSVR) & MSVR_CD; |
908 | port->port.count--; | 870 | rc_out(bp, CD180_MSVR, MSVR_RTS); |
909 | 871 | bp->DTR &= ~(1u << port_No(p)); | |
872 | rc_out(bp, RC_DTR, bp->DTR); | ||
910 | spin_unlock_irqrestore(&riscom_lock, flags); | 873 | spin_unlock_irqrestore(&riscom_lock, flags); |
911 | 874 | return CD; | |
912 | port->port.blocked_open++; | ||
913 | while (1) { | ||
914 | spin_lock_irqsave(&riscom_lock, flags); | ||
915 | |||
916 | rc_out(bp, CD180_CAR, port_No(port)); | ||
917 | CD = rc_in(bp, CD180_MSVR) & MSVR_CD; | ||
918 | rc_out(bp, CD180_MSVR, MSVR_RTS); | ||
919 | bp->DTR &= ~(1u << port_No(port)); | ||
920 | rc_out(bp, RC_DTR, bp->DTR); | ||
921 | |||
922 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
923 | |||
924 | set_current_state(TASK_INTERRUPTIBLE); | ||
925 | if (tty_hung_up_p(filp) || | ||
926 | !(port->port.flags & ASYNC_INITIALIZED)) { | ||
927 | if (port->port.flags & ASYNC_HUP_NOTIFY) | ||
928 | retval = -EAGAIN; | ||
929 | else | ||
930 | retval = -ERESTARTSYS; | ||
931 | break; | ||
932 | } | ||
933 | if (!(port->port.flags & ASYNC_CLOSING) && | ||
934 | (do_clocal || CD)) | ||
935 | break; | ||
936 | if (signal_pending(current)) { | ||
937 | retval = -ERESTARTSYS; | ||
938 | break; | ||
939 | } | ||
940 | schedule(); | ||
941 | } | ||
942 | __set_current_state(TASK_RUNNING); | ||
943 | remove_wait_queue(&port->port.open_wait, &wait); | ||
944 | if (!tty_hung_up_p(filp)) | ||
945 | port->port.count++; | ||
946 | port->port.blocked_open--; | ||
947 | if (retval) | ||
948 | return retval; | ||
949 | |||
950 | port->port.flags |= ASYNC_NORMAL_ACTIVE; | ||
951 | return 0; | ||
952 | } | 875 | } |
953 | 876 | ||
954 | static int rc_open(struct tty_struct *tty, struct file *filp) | 877 | static int rc_open(struct tty_struct *tty, struct file *filp) |
@@ -977,13 +900,13 @@ static int rc_open(struct tty_struct *tty, struct file *filp) | |||
977 | 900 | ||
978 | error = rc_setup_port(bp, port); | 901 | error = rc_setup_port(bp, port); |
979 | if (error == 0) | 902 | if (error == 0) |
980 | error = block_til_ready(tty, filp, port); | 903 | error = tty_port_block_til_ready(&port->port, tty, filp); |
981 | return error; | 904 | return error; |
982 | } | 905 | } |
983 | 906 | ||
984 | static void rc_flush_buffer(struct tty_struct *tty) | 907 | static void rc_flush_buffer(struct tty_struct *tty) |
985 | { | 908 | { |
986 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 909 | struct riscom_port *port = tty->driver_data; |
987 | unsigned long flags; | 910 | unsigned long flags; |
988 | 911 | ||
989 | if (rc_paranoia_check(port, tty->name, "rc_flush_buffer")) | 912 | if (rc_paranoia_check(port, tty->name, "rc_flush_buffer")) |
@@ -998,7 +921,7 @@ static void rc_flush_buffer(struct tty_struct *tty) | |||
998 | 921 | ||
999 | static void rc_close(struct tty_struct *tty, struct file *filp) | 922 | static void rc_close(struct tty_struct *tty, struct file *filp) |
1000 | { | 923 | { |
1001 | struct riscom_port *port = (struct riscom_port *) tty->driver_data; | 924 | struct riscom_port *port = tty->driver_data; |
1002 | struct riscom_board *bp; | 925 | struct riscom_board *bp; |
1003 | unsigned long flags; | 926 | unsigned long flags; |
1004 | unsigned long timeout; | 927 | unsigned long timeout; |
@@ -1006,40 +929,19 @@ static void rc_close(struct tty_struct *tty, struct file *filp) | |||
1006 | if (!port || rc_paranoia_check(port, tty->name, "close")) | 929 | if (!port || rc_paranoia_check(port, tty->name, "close")) |
1007 | return; | 930 | return; |
1008 | 931 | ||
1009 | spin_lock_irqsave(&riscom_lock, flags); | ||
1010 | |||
1011 | if (tty_hung_up_p(filp)) | ||
1012 | goto out; | ||
1013 | |||
1014 | bp = port_Board(port); | 932 | bp = port_Board(port); |
1015 | if ((tty->count == 1) && (port->port.count != 1)) { | 933 | |
1016 | printk(KERN_INFO "rc%d: rc_close: bad port count;" | 934 | if (tty_port_close_start(&port->port, tty, filp) == 0) |
1017 | " tty->count is 1, port count is %d\n", | 935 | return; |
1018 | board_No(bp), port->port.count); | 936 | |
1019 | port->port.count = 1; | ||
1020 | } | ||
1021 | if (--port->port.count < 0) { | ||
1022 | printk(KERN_INFO "rc%d: rc_close: bad port count " | ||
1023 | "for tty%d: %d\n", | ||
1024 | board_No(bp), port_No(port), port->port.count); | ||
1025 | port->port.count = 0; | ||
1026 | } | ||
1027 | if (port->port.count) | ||
1028 | goto out; | ||
1029 | port->port.flags |= ASYNC_CLOSING; | ||
1030 | /* | ||
1031 | * Now we wait for the transmit buffer to clear; and we notify | ||
1032 | * the line discipline to only process XON/XOFF characters. | ||
1033 | */ | ||
1034 | tty->closing = 1; | ||
1035 | if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) | ||
1036 | tty_wait_until_sent(tty, port->port.closing_wait); | ||
1037 | /* | 937 | /* |
1038 | * At this point we stop accepting input. To do this, we | 938 | * At this point we stop accepting input. To do this, we |
1039 | * disable the receive line status interrupts, and tell the | 939 | * disable the receive line status interrupts, and tell the |
1040 | * interrupt driver to stop checking the data ready bit in the | 940 | * interrupt driver to stop checking the data ready bit in the |
1041 | * line status register. | 941 | * line status register. |
1042 | */ | 942 | */ |
943 | |||
944 | spin_lock_irqsave(&riscom_lock, flags); | ||
1043 | port->IER &= ~IER_RXD; | 945 | port->IER &= ~IER_RXD; |
1044 | if (port->port.flags & ASYNC_INITIALIZED) { | 946 | if (port->port.flags & ASYNC_INITIALIZED) { |
1045 | port->IER &= ~IER_TXRDY; | 947 | port->IER &= ~IER_TXRDY; |
@@ -1053,33 +955,24 @@ static void rc_close(struct tty_struct *tty, struct file *filp) | |||
1053 | */ | 955 | */ |
1054 | timeout = jiffies + HZ; | 956 | timeout = jiffies + HZ; |
1055 | while (port->IER & IER_TXEMPTY) { | 957 | while (port->IER & IER_TXEMPTY) { |
958 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1056 | msleep_interruptible(jiffies_to_msecs(port->timeout)); | 959 | msleep_interruptible(jiffies_to_msecs(port->timeout)); |
960 | spin_lock_irqsave(&riscom_lock, flags); | ||
1057 | if (time_after(jiffies, timeout)) | 961 | if (time_after(jiffies, timeout)) |
1058 | break; | 962 | break; |
1059 | } | 963 | } |
1060 | } | 964 | } |
1061 | rc_shutdown_port(tty, bp, port); | 965 | rc_shutdown_port(tty, bp, port); |
1062 | rc_flush_buffer(tty); | 966 | rc_flush_buffer(tty); |
1063 | tty_ldisc_flush(tty); | ||
1064 | |||
1065 | tty->closing = 0; | ||
1066 | port->port.tty = NULL; | ||
1067 | if (port->port.blocked_open) { | ||
1068 | if (port->port.close_delay) | ||
1069 | msleep_interruptible(jiffies_to_msecs(port->port.close_delay)); | ||
1070 | wake_up_interruptible(&port->port.open_wait); | ||
1071 | } | ||
1072 | port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | ||
1073 | wake_up_interruptible(&port->port.close_wait); | ||
1074 | |||
1075 | out: | ||
1076 | spin_unlock_irqrestore(&riscom_lock, flags); | 967 | spin_unlock_irqrestore(&riscom_lock, flags); |
968 | |||
969 | tty_port_close_end(&port->port, tty); | ||
1077 | } | 970 | } |
1078 | 971 | ||
1079 | static int rc_write(struct tty_struct *tty, | 972 | static int rc_write(struct tty_struct *tty, |
1080 | const unsigned char *buf, int count) | 973 | const unsigned char *buf, int count) |
1081 | { | 974 | { |
1082 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 975 | struct riscom_port *port = tty->driver_data; |
1083 | struct riscom_board *bp; | 976 | struct riscom_board *bp; |
1084 | int c, total = 0; | 977 | int c, total = 0; |
1085 | unsigned long flags; | 978 | unsigned long flags; |
@@ -1122,7 +1015,7 @@ static int rc_write(struct tty_struct *tty, | |||
1122 | 1015 | ||
1123 | static int rc_put_char(struct tty_struct *tty, unsigned char ch) | 1016 | static int rc_put_char(struct tty_struct *tty, unsigned char ch) |
1124 | { | 1017 | { |
1125 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1018 | struct riscom_port *port = tty->driver_data; |
1126 | unsigned long flags; | 1019 | unsigned long flags; |
1127 | int ret = 0; | 1020 | int ret = 0; |
1128 | 1021 | ||
@@ -1146,7 +1039,7 @@ out: | |||
1146 | 1039 | ||
1147 | static void rc_flush_chars(struct tty_struct *tty) | 1040 | static void rc_flush_chars(struct tty_struct *tty) |
1148 | { | 1041 | { |
1149 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1042 | struct riscom_port *port = tty->driver_data; |
1150 | unsigned long flags; | 1043 | unsigned long flags; |
1151 | 1044 | ||
1152 | if (rc_paranoia_check(port, tty->name, "rc_flush_chars")) | 1045 | if (rc_paranoia_check(port, tty->name, "rc_flush_chars")) |
@@ -1166,7 +1059,7 @@ static void rc_flush_chars(struct tty_struct *tty) | |||
1166 | 1059 | ||
1167 | static int rc_write_room(struct tty_struct *tty) | 1060 | static int rc_write_room(struct tty_struct *tty) |
1168 | { | 1061 | { |
1169 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1062 | struct riscom_port *port = tty->driver_data; |
1170 | int ret; | 1063 | int ret; |
1171 | 1064 | ||
1172 | if (rc_paranoia_check(port, tty->name, "rc_write_room")) | 1065 | if (rc_paranoia_check(port, tty->name, "rc_write_room")) |
@@ -1180,7 +1073,7 @@ static int rc_write_room(struct tty_struct *tty) | |||
1180 | 1073 | ||
1181 | static int rc_chars_in_buffer(struct tty_struct *tty) | 1074 | static int rc_chars_in_buffer(struct tty_struct *tty) |
1182 | { | 1075 | { |
1183 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1076 | struct riscom_port *port = tty->driver_data; |
1184 | 1077 | ||
1185 | if (rc_paranoia_check(port, tty->name, "rc_chars_in_buffer")) | 1078 | if (rc_paranoia_check(port, tty->name, "rc_chars_in_buffer")) |
1186 | return 0; | 1079 | return 0; |
@@ -1190,7 +1083,7 @@ static int rc_chars_in_buffer(struct tty_struct *tty) | |||
1190 | 1083 | ||
1191 | static int rc_tiocmget(struct tty_struct *tty, struct file *file) | 1084 | static int rc_tiocmget(struct tty_struct *tty, struct file *file) |
1192 | { | 1085 | { |
1193 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1086 | struct riscom_port *port = tty->driver_data; |
1194 | struct riscom_board *bp; | 1087 | struct riscom_board *bp; |
1195 | unsigned char status; | 1088 | unsigned char status; |
1196 | unsigned int result; | 1089 | unsigned int result; |
@@ -1220,7 +1113,7 @@ static int rc_tiocmget(struct tty_struct *tty, struct file *file) | |||
1220 | static int rc_tiocmset(struct tty_struct *tty, struct file *file, | 1113 | static int rc_tiocmset(struct tty_struct *tty, struct file *file, |
1221 | unsigned int set, unsigned int clear) | 1114 | unsigned int set, unsigned int clear) |
1222 | { | 1115 | { |
1223 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1116 | struct riscom_port *port = tty->driver_data; |
1224 | unsigned long flags; | 1117 | unsigned long flags; |
1225 | struct riscom_board *bp; | 1118 | struct riscom_board *bp; |
1226 | 1119 | ||
@@ -1252,7 +1145,7 @@ static int rc_tiocmset(struct tty_struct *tty, struct file *file, | |||
1252 | 1145 | ||
1253 | static int rc_send_break(struct tty_struct *tty, int length) | 1146 | static int rc_send_break(struct tty_struct *tty, int length) |
1254 | { | 1147 | { |
1255 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1148 | struct riscom_port *port = tty->driver_data; |
1256 | struct riscom_board *bp = port_Board(port); | 1149 | struct riscom_board *bp = port_Board(port); |
1257 | unsigned long flags; | 1150 | unsigned long flags; |
1258 | 1151 | ||
@@ -1345,7 +1238,7 @@ static int rc_get_serial_info(struct riscom_port *port, | |||
1345 | static int rc_ioctl(struct tty_struct *tty, struct file *filp, | 1238 | static int rc_ioctl(struct tty_struct *tty, struct file *filp, |
1346 | unsigned int cmd, unsigned long arg) | 1239 | unsigned int cmd, unsigned long arg) |
1347 | { | 1240 | { |
1348 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1241 | struct riscom_port *port = tty->driver_data; |
1349 | void __user *argp = (void __user *)arg; | 1242 | void __user *argp = (void __user *)arg; |
1350 | int retval; | 1243 | int retval; |
1351 | 1244 | ||
@@ -1371,7 +1264,7 @@ static int rc_ioctl(struct tty_struct *tty, struct file *filp, | |||
1371 | 1264 | ||
1372 | static void rc_throttle(struct tty_struct *tty) | 1265 | static void rc_throttle(struct tty_struct *tty) |
1373 | { | 1266 | { |
1374 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1267 | struct riscom_port *port = tty->driver_data; |
1375 | struct riscom_board *bp; | 1268 | struct riscom_board *bp; |
1376 | unsigned long flags; | 1269 | unsigned long flags; |
1377 | 1270 | ||
@@ -1393,7 +1286,7 @@ static void rc_throttle(struct tty_struct *tty) | |||
1393 | 1286 | ||
1394 | static void rc_unthrottle(struct tty_struct *tty) | 1287 | static void rc_unthrottle(struct tty_struct *tty) |
1395 | { | 1288 | { |
1396 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1289 | struct riscom_port *port = tty->driver_data; |
1397 | struct riscom_board *bp; | 1290 | struct riscom_board *bp; |
1398 | unsigned long flags; | 1291 | unsigned long flags; |
1399 | 1292 | ||
@@ -1415,7 +1308,7 @@ static void rc_unthrottle(struct tty_struct *tty) | |||
1415 | 1308 | ||
1416 | static void rc_stop(struct tty_struct *tty) | 1309 | static void rc_stop(struct tty_struct *tty) |
1417 | { | 1310 | { |
1418 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1311 | struct riscom_port *port = tty->driver_data; |
1419 | struct riscom_board *bp; | 1312 | struct riscom_board *bp; |
1420 | unsigned long flags; | 1313 | unsigned long flags; |
1421 | 1314 | ||
@@ -1433,7 +1326,7 @@ static void rc_stop(struct tty_struct *tty) | |||
1433 | 1326 | ||
1434 | static void rc_start(struct tty_struct *tty) | 1327 | static void rc_start(struct tty_struct *tty) |
1435 | { | 1328 | { |
1436 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1329 | struct riscom_port *port = tty->driver_data; |
1437 | struct riscom_board *bp; | 1330 | struct riscom_board *bp; |
1438 | unsigned long flags; | 1331 | unsigned long flags; |
1439 | 1332 | ||
@@ -1454,8 +1347,9 @@ static void rc_start(struct tty_struct *tty) | |||
1454 | 1347 | ||
1455 | static void rc_hangup(struct tty_struct *tty) | 1348 | static void rc_hangup(struct tty_struct *tty) |
1456 | { | 1349 | { |
1457 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1350 | struct riscom_port *port = tty->driver_data; |
1458 | struct riscom_board *bp; | 1351 | struct riscom_board *bp; |
1352 | unsigned long flags; | ||
1459 | 1353 | ||
1460 | if (rc_paranoia_check(port, tty->name, "rc_hangup")) | 1354 | if (rc_paranoia_check(port, tty->name, "rc_hangup")) |
1461 | return; | 1355 | return; |
@@ -1463,16 +1357,18 @@ static void rc_hangup(struct tty_struct *tty) | |||
1463 | bp = port_Board(port); | 1357 | bp = port_Board(port); |
1464 | 1358 | ||
1465 | rc_shutdown_port(tty, bp, port); | 1359 | rc_shutdown_port(tty, bp, port); |
1360 | spin_lock_irqsave(&port->port.lock, flags); | ||
1466 | port->port.count = 0; | 1361 | port->port.count = 0; |
1467 | port->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 1362 | port->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
1468 | port->port.tty = NULL; | 1363 | port->port.tty = NULL; |
1469 | wake_up_interruptible(&port->port.open_wait); | 1364 | wake_up_interruptible(&port->port.open_wait); |
1365 | spin_unlock_irqrestore(&port->port.lock, flags); | ||
1470 | } | 1366 | } |
1471 | 1367 | ||
1472 | static void rc_set_termios(struct tty_struct *tty, | 1368 | static void rc_set_termios(struct tty_struct *tty, |
1473 | struct ktermios *old_termios) | 1369 | struct ktermios *old_termios) |
1474 | { | 1370 | { |
1475 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1371 | struct riscom_port *port = tty->driver_data; |
1476 | unsigned long flags; | 1372 | unsigned long flags; |
1477 | 1373 | ||
1478 | if (rc_paranoia_check(port, tty->name, "rc_set_termios")) | 1374 | if (rc_paranoia_check(port, tty->name, "rc_set_termios")) |
@@ -1510,6 +1406,11 @@ static const struct tty_operations riscom_ops = { | |||
1510 | .break_ctl = rc_send_break, | 1406 | .break_ctl = rc_send_break, |
1511 | }; | 1407 | }; |
1512 | 1408 | ||
1409 | static const struct tty_port_operations riscom_port_ops = { | ||
1410 | .carrier_raised = carrier_raised, | ||
1411 | }; | ||
1412 | |||
1413 | |||
1513 | static int __init rc_init_drivers(void) | 1414 | static int __init rc_init_drivers(void) |
1514 | { | 1415 | { |
1515 | int error; | 1416 | int error; |
@@ -1541,6 +1442,7 @@ static int __init rc_init_drivers(void) | |||
1541 | memset(rc_port, 0, sizeof(rc_port)); | 1442 | memset(rc_port, 0, sizeof(rc_port)); |
1542 | for (i = 0; i < RC_NPORT * RC_NBOARD; i++) { | 1443 | for (i = 0; i < RC_NPORT * RC_NBOARD; i++) { |
1543 | tty_port_init(&rc_port[i].port); | 1444 | tty_port_init(&rc_port[i].port); |
1445 | rc_port[i].port.ops = &riscom_port_ops; | ||
1544 | rc_port[i].magic = RISCOM8_MAGIC; | 1446 | rc_port[i].magic = RISCOM8_MAGIC; |
1545 | } | 1447 | } |
1546 | return 0; | 1448 | return 0; |