.. | .. |
---|
22 | 22 | * |
---|
23 | 23 | */ |
---|
24 | 24 | |
---|
25 | | -/* |
---|
26 | | - * Serial driver configuration section. Here are the various options: |
---|
27 | | - * |
---|
28 | | - * SERIAL_PARANOIA_CHECK |
---|
29 | | - * Check the magic number for the async_structure where |
---|
30 | | - * ever possible. |
---|
31 | | - */ |
---|
32 | | - |
---|
33 | 25 | #include <linux/delay.h> |
---|
34 | | - |
---|
35 | | -#undef SERIAL_PARANOIA_CHECK |
---|
36 | 26 | |
---|
37 | 27 | /* Set of debugging defines */ |
---|
38 | 28 | |
---|
.. | .. |
---|
132 | 122 | |
---|
133 | 123 | #define serial_isroot() (capable(CAP_SYS_ADMIN)) |
---|
134 | 124 | |
---|
135 | | - |
---|
136 | | -static inline int serial_paranoia_check(struct serial_state *info, |
---|
137 | | - char *name, const char *routine) |
---|
138 | | -{ |
---|
139 | | -#ifdef SERIAL_PARANOIA_CHECK |
---|
140 | | - static const char *badmagic = |
---|
141 | | - "Warning: bad magic number for serial struct (%s) in %s\n"; |
---|
142 | | - static const char *badinfo = |
---|
143 | | - "Warning: null async_struct for (%s) in %s\n"; |
---|
144 | | - |
---|
145 | | - if (!info) { |
---|
146 | | - printk(badinfo, name, routine); |
---|
147 | | - return 1; |
---|
148 | | - } |
---|
149 | | - if (info->magic != SERIAL_MAGIC) { |
---|
150 | | - printk(badmagic, name, routine); |
---|
151 | | - return 1; |
---|
152 | | - } |
---|
153 | | -#endif |
---|
154 | | - return 0; |
---|
155 | | -} |
---|
156 | | - |
---|
157 | 125 | /* some serial hardware definitions */ |
---|
158 | 126 | #define SDR_OVRUN (1<<15) |
---|
159 | 127 | #define SDR_RBF (1<<14) |
---|
.. | .. |
---|
189 | 157 | struct serial_state *info = tty->driver_data; |
---|
190 | 158 | unsigned long flags; |
---|
191 | 159 | |
---|
192 | | - if (serial_paranoia_check(info, tty->name, "rs_stop")) |
---|
193 | | - return; |
---|
194 | | - |
---|
195 | 160 | local_irq_save(flags); |
---|
196 | 161 | if (info->IER & UART_IER_THRI) { |
---|
197 | 162 | info->IER &= ~UART_IER_THRI; |
---|
.. | .. |
---|
208 | 173 | { |
---|
209 | 174 | struct serial_state *info = tty->driver_data; |
---|
210 | 175 | unsigned long flags; |
---|
211 | | - |
---|
212 | | - if (serial_paranoia_check(info, tty->name, "rs_start")) |
---|
213 | | - return; |
---|
214 | 176 | |
---|
215 | 177 | local_irq_save(flags); |
---|
216 | 178 | if (info->xmit.head != info->xmit.tail |
---|
.. | .. |
---|
783 | 745 | |
---|
784 | 746 | info = tty->driver_data; |
---|
785 | 747 | |
---|
786 | | - if (serial_paranoia_check(info, tty->name, "rs_put_char")) |
---|
787 | | - return 0; |
---|
788 | | - |
---|
789 | 748 | if (!info->xmit.buf) |
---|
790 | 749 | return 0; |
---|
791 | 750 | |
---|
.. | .. |
---|
808 | 767 | struct serial_state *info = tty->driver_data; |
---|
809 | 768 | unsigned long flags; |
---|
810 | 769 | |
---|
811 | | - if (serial_paranoia_check(info, tty->name, "rs_flush_chars")) |
---|
812 | | - return; |
---|
813 | | - |
---|
814 | 770 | if (info->xmit.head == info->xmit.tail |
---|
815 | 771 | || tty->stopped |
---|
816 | 772 | || tty->hw_stopped |
---|
.. | .. |
---|
832 | 788 | int c, ret = 0; |
---|
833 | 789 | struct serial_state *info = tty->driver_data; |
---|
834 | 790 | unsigned long flags; |
---|
835 | | - |
---|
836 | | - if (serial_paranoia_check(info, tty->name, "rs_write")) |
---|
837 | | - return 0; |
---|
838 | 791 | |
---|
839 | 792 | if (!info->xmit.buf) |
---|
840 | 793 | return 0; |
---|
.. | .. |
---|
878 | 831 | { |
---|
879 | 832 | struct serial_state *info = tty->driver_data; |
---|
880 | 833 | |
---|
881 | | - if (serial_paranoia_check(info, tty->name, "rs_write_room")) |
---|
882 | | - return 0; |
---|
883 | 834 | return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); |
---|
884 | 835 | } |
---|
885 | 836 | |
---|
.. | .. |
---|
887 | 838 | { |
---|
888 | 839 | struct serial_state *info = tty->driver_data; |
---|
889 | 840 | |
---|
890 | | - if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer")) |
---|
891 | | - return 0; |
---|
892 | 841 | return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); |
---|
893 | 842 | } |
---|
894 | 843 | |
---|
.. | .. |
---|
897 | 846 | struct serial_state *info = tty->driver_data; |
---|
898 | 847 | unsigned long flags; |
---|
899 | 848 | |
---|
900 | | - if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) |
---|
901 | | - return; |
---|
902 | 849 | local_irq_save(flags); |
---|
903 | 850 | info->xmit.head = info->xmit.tail = 0; |
---|
904 | 851 | local_irq_restore(flags); |
---|
.. | .. |
---|
913 | 860 | { |
---|
914 | 861 | struct serial_state *info = tty->driver_data; |
---|
915 | 862 | unsigned long flags; |
---|
916 | | - |
---|
917 | | - if (serial_paranoia_check(info, tty->name, "rs_send_xchar")) |
---|
918 | | - return; |
---|
919 | 863 | |
---|
920 | 864 | info->x_char = ch; |
---|
921 | 865 | if (ch) { |
---|
.. | .. |
---|
952 | 896 | printk("throttle %s ....\n", tty_name(tty)); |
---|
953 | 897 | #endif |
---|
954 | 898 | |
---|
955 | | - if (serial_paranoia_check(info, tty->name, "rs_throttle")) |
---|
956 | | - return; |
---|
957 | | - |
---|
958 | 899 | if (I_IXOFF(tty)) |
---|
959 | 900 | rs_send_xchar(tty, STOP_CHAR(tty)); |
---|
960 | 901 | |
---|
.. | .. |
---|
973 | 914 | #ifdef SERIAL_DEBUG_THROTTLE |
---|
974 | 915 | printk("unthrottle %s ....\n", tty_name(tty)); |
---|
975 | 916 | #endif |
---|
976 | | - |
---|
977 | | - if (serial_paranoia_check(info, tty->name, "rs_unthrottle")) |
---|
978 | | - return; |
---|
979 | 917 | |
---|
980 | 918 | if (I_IXOFF(tty)) { |
---|
981 | 919 | if (info->x_char) |
---|
.. | .. |
---|
996 | 934 | * ------------------------------------------------------------ |
---|
997 | 935 | */ |
---|
998 | 936 | |
---|
999 | | -static int get_serial_info(struct tty_struct *tty, struct serial_state *state, |
---|
1000 | | - struct serial_struct __user * retinfo) |
---|
| 937 | +static int get_serial_info(struct tty_struct *tty, struct serial_struct *ss) |
---|
1001 | 938 | { |
---|
1002 | | - struct serial_struct tmp; |
---|
1003 | | - |
---|
1004 | | - memset(&tmp, 0, sizeof(tmp)); |
---|
| 939 | + struct serial_state *state = tty->driver_data; |
---|
| 940 | + |
---|
1005 | 941 | tty_lock(tty); |
---|
1006 | | - tmp.line = tty->index; |
---|
1007 | | - tmp.port = state->port; |
---|
1008 | | - tmp.flags = state->tport.flags; |
---|
1009 | | - tmp.xmit_fifo_size = state->xmit_fifo_size; |
---|
1010 | | - tmp.baud_base = state->baud_base; |
---|
1011 | | - tmp.close_delay = state->tport.close_delay; |
---|
1012 | | - tmp.closing_wait = state->tport.closing_wait; |
---|
1013 | | - tmp.custom_divisor = state->custom_divisor; |
---|
| 942 | + ss->line = tty->index; |
---|
| 943 | + ss->port = state->port; |
---|
| 944 | + ss->flags = state->tport.flags; |
---|
| 945 | + ss->xmit_fifo_size = state->xmit_fifo_size; |
---|
| 946 | + ss->baud_base = state->baud_base; |
---|
| 947 | + ss->close_delay = state->tport.close_delay; |
---|
| 948 | + ss->closing_wait = state->tport.closing_wait; |
---|
| 949 | + ss->custom_divisor = state->custom_divisor; |
---|
1014 | 950 | tty_unlock(tty); |
---|
1015 | | - if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) |
---|
1016 | | - return -EFAULT; |
---|
1017 | 951 | return 0; |
---|
1018 | 952 | } |
---|
1019 | 953 | |
---|
1020 | | -static int set_serial_info(struct tty_struct *tty, struct serial_state *state, |
---|
1021 | | - struct serial_struct __user * new_info) |
---|
| 954 | +static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss) |
---|
1022 | 955 | { |
---|
| 956 | + struct serial_state *state = tty->driver_data; |
---|
1023 | 957 | struct tty_port *port = &state->tport; |
---|
1024 | | - struct serial_struct new_serial; |
---|
1025 | 958 | bool change_spd; |
---|
1026 | 959 | int retval = 0; |
---|
1027 | 960 | |
---|
1028 | | - if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) |
---|
1029 | | - return -EFAULT; |
---|
1030 | | - |
---|
1031 | 961 | tty_lock(tty); |
---|
1032 | | - change_spd = ((new_serial.flags ^ port->flags) & ASYNC_SPD_MASK) || |
---|
1033 | | - new_serial.custom_divisor != state->custom_divisor; |
---|
1034 | | - if (new_serial.irq || new_serial.port != state->port || |
---|
1035 | | - new_serial.xmit_fifo_size != state->xmit_fifo_size) { |
---|
| 962 | + change_spd = ((ss->flags ^ port->flags) & ASYNC_SPD_MASK) || |
---|
| 963 | + ss->custom_divisor != state->custom_divisor; |
---|
| 964 | + if (ss->irq || ss->port != state->port || |
---|
| 965 | + ss->xmit_fifo_size != state->xmit_fifo_size) { |
---|
1036 | 966 | tty_unlock(tty); |
---|
1037 | 967 | return -EINVAL; |
---|
1038 | 968 | } |
---|
1039 | 969 | |
---|
1040 | 970 | if (!serial_isroot()) { |
---|
1041 | | - if ((new_serial.baud_base != state->baud_base) || |
---|
1042 | | - (new_serial.close_delay != port->close_delay) || |
---|
1043 | | - (new_serial.xmit_fifo_size != state->xmit_fifo_size) || |
---|
1044 | | - ((new_serial.flags & ~ASYNC_USR_MASK) != |
---|
| 971 | + if ((ss->baud_base != state->baud_base) || |
---|
| 972 | + (ss->close_delay != port->close_delay) || |
---|
| 973 | + (ss->closing_wait != port->closing_wait) || |
---|
| 974 | + (ss->xmit_fifo_size != state->xmit_fifo_size) || |
---|
| 975 | + ((ss->flags & ~ASYNC_USR_MASK) != |
---|
1045 | 976 | (port->flags & ~ASYNC_USR_MASK))) { |
---|
1046 | 977 | tty_unlock(tty); |
---|
1047 | 978 | return -EPERM; |
---|
1048 | 979 | } |
---|
1049 | 980 | port->flags = ((port->flags & ~ASYNC_USR_MASK) | |
---|
1050 | | - (new_serial.flags & ASYNC_USR_MASK)); |
---|
1051 | | - state->custom_divisor = new_serial.custom_divisor; |
---|
| 981 | + (ss->flags & ASYNC_USR_MASK)); |
---|
| 982 | + state->custom_divisor = ss->custom_divisor; |
---|
1052 | 983 | goto check_and_exit; |
---|
1053 | 984 | } |
---|
1054 | 985 | |
---|
1055 | | - if (new_serial.baud_base < 9600) { |
---|
| 986 | + if (ss->baud_base < 9600) { |
---|
1056 | 987 | tty_unlock(tty); |
---|
1057 | 988 | return -EINVAL; |
---|
1058 | 989 | } |
---|
.. | .. |
---|
1062 | 993 | * At this point, we start making changes..... |
---|
1063 | 994 | */ |
---|
1064 | 995 | |
---|
1065 | | - state->baud_base = new_serial.baud_base; |
---|
| 996 | + state->baud_base = ss->baud_base; |
---|
1066 | 997 | port->flags = ((port->flags & ~ASYNC_FLAGS) | |
---|
1067 | | - (new_serial.flags & ASYNC_FLAGS)); |
---|
1068 | | - state->custom_divisor = new_serial.custom_divisor; |
---|
1069 | | - port->close_delay = new_serial.close_delay * HZ/100; |
---|
1070 | | - port->closing_wait = new_serial.closing_wait * HZ/100; |
---|
| 998 | + (ss->flags & ASYNC_FLAGS)); |
---|
| 999 | + state->custom_divisor = ss->custom_divisor; |
---|
| 1000 | + port->close_delay = ss->close_delay * HZ/100; |
---|
| 1001 | + port->closing_wait = ss->closing_wait * HZ/100; |
---|
1071 | 1002 | port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
---|
1072 | 1003 | |
---|
1073 | 1004 | check_and_exit: |
---|
1074 | 1005 | if (tty_port_initialized(port)) { |
---|
1075 | 1006 | if (change_spd) { |
---|
1076 | 1007 | /* warn about deprecation unless clearing */ |
---|
1077 | | - if (new_serial.flags & ASYNC_SPD_MASK) |
---|
| 1008 | + if (ss->flags & ASYNC_SPD_MASK) |
---|
1078 | 1009 | dev_warn_ratelimited(tty->dev, "use of SPD flags is deprecated\n"); |
---|
1079 | 1010 | change_speed(tty, state, NULL); |
---|
1080 | 1011 | } |
---|
.. | .. |
---|
1083 | 1014 | tty_unlock(tty); |
---|
1084 | 1015 | return retval; |
---|
1085 | 1016 | } |
---|
1086 | | - |
---|
1087 | 1017 | |
---|
1088 | 1018 | /* |
---|
1089 | 1019 | * get_lsr_info - get line status register info |
---|
.. | .. |
---|
1118 | 1048 | unsigned char control, status; |
---|
1119 | 1049 | unsigned long flags; |
---|
1120 | 1050 | |
---|
1121 | | - if (serial_paranoia_check(info, tty->name, "rs_ioctl")) |
---|
1122 | | - return -ENODEV; |
---|
1123 | 1051 | if (tty_io_error(tty)) |
---|
1124 | 1052 | return -EIO; |
---|
1125 | 1053 | |
---|
.. | .. |
---|
1140 | 1068 | struct serial_state *info = tty->driver_data; |
---|
1141 | 1069 | unsigned long flags; |
---|
1142 | 1070 | |
---|
1143 | | - if (serial_paranoia_check(info, tty->name, "rs_ioctl")) |
---|
1144 | | - return -ENODEV; |
---|
1145 | 1071 | if (tty_io_error(tty)) |
---|
1146 | 1072 | return -EIO; |
---|
1147 | 1073 | |
---|
.. | .. |
---|
1164 | 1090 | */ |
---|
1165 | 1091 | static int rs_break(struct tty_struct *tty, int break_state) |
---|
1166 | 1092 | { |
---|
1167 | | - struct serial_state *info = tty->driver_data; |
---|
1168 | 1093 | unsigned long flags; |
---|
1169 | | - |
---|
1170 | | - if (serial_paranoia_check(info, tty->name, "rs_break")) |
---|
1171 | | - return -EINVAL; |
---|
1172 | 1094 | |
---|
1173 | 1095 | local_irq_save(flags); |
---|
1174 | 1096 | if (break_state == -1) |
---|
.. | .. |
---|
1221 | 1143 | DEFINE_WAIT(wait); |
---|
1222 | 1144 | int ret; |
---|
1223 | 1145 | |
---|
1224 | | - if (serial_paranoia_check(info, tty->name, "rs_ioctl")) |
---|
1225 | | - return -ENODEV; |
---|
1226 | | - |
---|
1227 | | - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
---|
1228 | | - (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && |
---|
| 1146 | + if ((cmd != TIOCSERCONFIG) && |
---|
1229 | 1147 | (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { |
---|
1230 | 1148 | if (tty_io_error(tty)) |
---|
1231 | 1149 | return -EIO; |
---|
1232 | 1150 | } |
---|
1233 | 1151 | |
---|
1234 | 1152 | switch (cmd) { |
---|
1235 | | - case TIOCGSERIAL: |
---|
1236 | | - return get_serial_info(tty, info, argp); |
---|
1237 | | - case TIOCSSERIAL: |
---|
1238 | | - return set_serial_info(tty, info, argp); |
---|
1239 | 1153 | case TIOCSERCONFIG: |
---|
1240 | 1154 | return 0; |
---|
1241 | 1155 | |
---|
1242 | 1156 | case TIOCSERGETLSR: /* Get line status register */ |
---|
1243 | 1157 | return get_lsr_info(info, argp); |
---|
1244 | | - |
---|
1245 | | - case TIOCSERGSTRUCT: |
---|
1246 | | - if (copy_to_user(argp, |
---|
1247 | | - info, sizeof(struct serial_state))) |
---|
1248 | | - return -EFAULT; |
---|
1249 | | - return 0; |
---|
1250 | 1158 | |
---|
1251 | 1159 | /* |
---|
1252 | 1160 | * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change |
---|
.. | .. |
---|
1287 | 1195 | } |
---|
1288 | 1196 | finish_wait(&info->tport.delta_msr_wait, &wait); |
---|
1289 | 1197 | return ret; |
---|
1290 | | - |
---|
1291 | | - case TIOCSERGWILD: |
---|
1292 | | - case TIOCSERSWILD: |
---|
1293 | | - /* "setserial -W" is called in Debian boot */ |
---|
1294 | | - printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); |
---|
1295 | | - return 0; |
---|
1296 | 1198 | |
---|
1297 | 1199 | default: |
---|
1298 | 1200 | return -ENOIOCTLCMD; |
---|
.. | .. |
---|
1359 | 1261 | struct serial_state *state = tty->driver_data; |
---|
1360 | 1262 | struct tty_port *port = &state->tport; |
---|
1361 | 1263 | |
---|
1362 | | - if (serial_paranoia_check(state, tty->name, "rs_close")) |
---|
1363 | | - return; |
---|
1364 | | - |
---|
1365 | 1264 | if (tty_port_close_start(port, tty, filp) == 0) |
---|
1366 | 1265 | return; |
---|
1367 | 1266 | |
---|
.. | .. |
---|
1404 | 1303 | struct serial_state *info = tty->driver_data; |
---|
1405 | 1304 | unsigned long orig_jiffies, char_time; |
---|
1406 | 1305 | int lsr; |
---|
1407 | | - |
---|
1408 | | - if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent")) |
---|
1409 | | - return; |
---|
1410 | 1306 | |
---|
1411 | 1307 | if (info->xmit_fifo_size == 0) |
---|
1412 | 1308 | return; /* Just in case.... */ |
---|
.. | .. |
---|
1466 | 1362 | { |
---|
1467 | 1363 | struct serial_state *info = tty->driver_data; |
---|
1468 | 1364 | |
---|
1469 | | - if (serial_paranoia_check(info, tty->name, "rs_hangup")) |
---|
1470 | | - return; |
---|
1471 | | - |
---|
1472 | 1365 | rs_flush_buffer(tty); |
---|
1473 | 1366 | shutdown(tty, info); |
---|
1474 | 1367 | info->tport.count = 0; |
---|
.. | .. |
---|
1493 | 1386 | port->tty = tty; |
---|
1494 | 1387 | tty->driver_data = info; |
---|
1495 | 1388 | tty->port = port; |
---|
1496 | | - if (serial_paranoia_check(info, tty->name, "rs_open")) |
---|
1497 | | - return -ENODEV; |
---|
1498 | 1389 | |
---|
1499 | 1390 | port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
---|
1500 | 1391 | |
---|
.. | .. |
---|
1607 | 1498 | .tiocmget = rs_tiocmget, |
---|
1608 | 1499 | .tiocmset = rs_tiocmset, |
---|
1609 | 1500 | .get_icount = rs_get_icount, |
---|
| 1501 | + .set_serial = set_serial_info, |
---|
| 1502 | + .get_serial = get_serial_info, |
---|
1610 | 1503 | .proc_show = rs_proc_show, |
---|
1611 | 1504 | }; |
---|
1612 | 1505 | |
---|