diff options
Diffstat (limited to 'drivers/char/cyclades.c')
-rw-r--r-- | drivers/char/cyclades.c | 767 |
1 files changed, 324 insertions, 443 deletions
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 9e0adfe27c12..d15234c5965e 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -662,7 +662,7 @@ | |||
662 | static void cy_throttle(struct tty_struct *tty); | 662 | static void cy_throttle(struct tty_struct *tty); |
663 | static void cy_send_xchar(struct tty_struct *tty, char ch); | 663 | static void cy_send_xchar(struct tty_struct *tty, char ch); |
664 | 664 | ||
665 | #define IS_CYC_Z(card) ((card).num_chips == -1) | 665 | #define IS_CYC_Z(card) ((card).num_chips == (unsigned int)-1) |
666 | 666 | ||
667 | #define Z_FPGA_CHECK(card) \ | 667 | #define Z_FPGA_CHECK(card) \ |
668 | ((readl(&((struct RUNTIME_9060 __iomem *) \ | 668 | ((readl(&((struct RUNTIME_9060 __iomem *) \ |
@@ -897,71 +897,6 @@ static inline int serial_paranoia_check(struct cyclades_port *info, | |||
897 | return 0; | 897 | return 0; |
898 | } /* serial_paranoia_check */ | 898 | } /* serial_paranoia_check */ |
899 | 899 | ||
900 | /* | ||
901 | * This routine is used by the interrupt handler to schedule | ||
902 | * processing in the software interrupt portion of the driver | ||
903 | * (also known as the "bottom half"). This can be called any | ||
904 | * number of times for any channel without harm. | ||
905 | */ | ||
906 | static inline void cy_sched_event(struct cyclades_port *info, int event) | ||
907 | { | ||
908 | info->event |= 1 << event; /* remember what kind of event and who */ | ||
909 | schedule_work(&info->tqueue); | ||
910 | } /* cy_sched_event */ | ||
911 | |||
912 | /* | ||
913 | * This routine is used to handle the "bottom half" processing for the | ||
914 | * serial driver, known also the "software interrupt" processing. | ||
915 | * This processing is done at the kernel interrupt level, after the | ||
916 | * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This | ||
917 | * is where time-consuming activities which can not be done in the | ||
918 | * interrupt driver proper are done; the interrupt driver schedules | ||
919 | * them using cy_sched_event(), and they get done here. | ||
920 | * | ||
921 | * This is done through one level of indirection--the task queue. | ||
922 | * When a hardware interrupt service routine wants service by the | ||
923 | * driver's bottom half, it enqueues the appropriate tq_struct (one | ||
924 | * per port) to the keventd work queue and sets a request flag | ||
925 | * that the work queue be processed. | ||
926 | * | ||
927 | * Although this may seem unwieldy, it gives the system a way to | ||
928 | * pass an argument (in this case the pointer to the cyclades_port | ||
929 | * structure) to the bottom half of the driver. Previous kernels | ||
930 | * had to poll every port to see if that port needed servicing. | ||
931 | */ | ||
932 | static void | ||
933 | do_softint(struct work_struct *work) | ||
934 | { | ||
935 | struct cyclades_port *info = | ||
936 | container_of(work, struct cyclades_port, tqueue); | ||
937 | struct tty_struct *tty; | ||
938 | |||
939 | tty = info->tty; | ||
940 | if (!tty) | ||
941 | return; | ||
942 | |||
943 | if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) { | ||
944 | tty_hangup(info->tty); | ||
945 | wake_up_interruptible(&info->open_wait); | ||
946 | info->flags &= ~ASYNC_NORMAL_ACTIVE; | ||
947 | } | ||
948 | if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) | ||
949 | wake_up_interruptible(&info->open_wait); | ||
950 | #ifdef CONFIG_CYZ_INTR | ||
951 | if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event) && | ||
952 | !timer_pending(&cyz_rx_full_timer[info->line])) | ||
953 | mod_timer(&cyz_rx_full_timer[info->line], jiffies + 1); | ||
954 | #endif | ||
955 | if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) | ||
956 | wake_up_interruptible(&info->delta_msr_wait); | ||
957 | tty_wakeup(tty); | ||
958 | #ifdef Z_WAKE | ||
959 | if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) | ||
960 | complete(&info->shutdown_wait); | ||
961 | #endif | ||
962 | } /* do_softint */ | ||
963 | |||
964 | |||
965 | /***********************************************************/ | 900 | /***********************************************************/ |
966 | /********* Start of block of Cyclom-Y specific code ********/ | 901 | /********* Start of block of Cyclom-Y specific code ********/ |
967 | 902 | ||
@@ -1045,382 +980,332 @@ static unsigned detect_isa_irq(void __iomem * address) | |||
1045 | } | 980 | } |
1046 | #endif /* CONFIG_ISA */ | 981 | #endif /* CONFIG_ISA */ |
1047 | 982 | ||
1048 | static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | 983 | static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, |
1049 | void __iomem * base_addr, int status, int index) | 984 | void __iomem *base_addr) |
1050 | { | 985 | { |
1051 | struct cyclades_port *info; | 986 | struct cyclades_port *info; |
1052 | struct tty_struct *tty; | 987 | struct tty_struct *tty; |
1053 | int char_count; | 988 | int len, index = cinfo->bus_index; |
1054 | int j, len, mdm_change, mdm_status, outch; | 989 | u8 save_xir, channel, save_car, data, char_count; |
1055 | int save_xir, channel, save_car; | ||
1056 | char data; | ||
1057 | 990 | ||
1058 | if (status & CySRReceive) { /* reception interrupt */ | ||
1059 | #ifdef CY_DEBUG_INTERRUPTS | 991 | #ifdef CY_DEBUG_INTERRUPTS |
1060 | printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip); | 992 | printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip); |
1061 | #endif | 993 | #endif |
1062 | /* determine the channel & change to that context */ | 994 | /* determine the channel & change to that context */ |
1063 | spin_lock(&cinfo->card_lock); | 995 | save_xir = readb(base_addr + (CyRIR << index)); |
1064 | save_xir = (u_char) readb(base_addr + (CyRIR << index)); | 996 | channel = save_xir & CyIRChannel; |
1065 | channel = (u_short) (save_xir & CyIRChannel); | 997 | info = &cinfo->ports[channel + chip * 4]; |
1066 | info = &cinfo->ports[channel + chip * 4]; | 998 | save_car = readb(base_addr + (CyCAR << index)); |
1067 | save_car = readb(base_addr + (CyCAR << index)); | 999 | cy_writeb(base_addr + (CyCAR << index), save_xir); |
1068 | cy_writeb(base_addr + (CyCAR << index), save_xir); | 1000 | |
1069 | 1001 | /* if there is nowhere to put the data, discard it */ | |
1070 | /* if there is nowhere to put the data, discard it */ | 1002 | if (info->tty == NULL) { |
1071 | if (info->tty == NULL) { | 1003 | if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) == |
1072 | j = (readb(base_addr + (CyRIVR << index)) & | 1004 | CyIVRRxEx) { /* exception */ |
1073 | CyIVRMask); | 1005 | data = readb(base_addr + (CyRDSR << index)); |
1074 | if (j == CyIVRRxEx) { /* exception */ | 1006 | } else { /* normal character reception */ |
1007 | char_count = readb(base_addr + (CyRDCR << index)); | ||
1008 | while (char_count--) | ||
1075 | data = readb(base_addr + (CyRDSR << index)); | 1009 | data = readb(base_addr + (CyRDSR << index)); |
1076 | } else { /* normal character reception */ | 1010 | } |
1077 | char_count = readb(base_addr + | 1011 | goto end; |
1078 | (CyRDCR << index)); | 1012 | } |
1079 | while (char_count--) { | 1013 | /* there is an open port for this data */ |
1080 | data = readb(base_addr + | 1014 | tty = info->tty; |
1081 | (CyRDSR << index)); | 1015 | if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) == |
1082 | } | 1016 | CyIVRRxEx) { /* exception */ |
1083 | } | 1017 | data = readb(base_addr + (CyRDSR << index)); |
1084 | } else { /* there is an open port for this data */ | 1018 | |
1085 | tty = info->tty; | 1019 | /* For statistics only */ |
1086 | j = (readb(base_addr + (CyRIVR << index)) & | 1020 | if (data & CyBREAK) |
1087 | CyIVRMask); | 1021 | info->icount.brk++; |
1088 | if (j == CyIVRRxEx) { /* exception */ | 1022 | else if (data & CyFRAME) |
1089 | data = readb(base_addr + (CyRDSR << index)); | 1023 | info->icount.frame++; |
1090 | 1024 | else if (data & CyPARITY) | |
1091 | /* For statistics only */ | 1025 | info->icount.parity++; |
1092 | if (data & CyBREAK) | 1026 | else if (data & CyOVERRUN) |
1093 | info->icount.brk++; | 1027 | info->icount.overrun++; |
1094 | else if (data & CyFRAME) | 1028 | |
1095 | info->icount.frame++; | 1029 | if (data & info->ignore_status_mask) { |
1096 | else if (data & CyPARITY) | 1030 | info->icount.rx++; |
1097 | info->icount.parity++; | 1031 | return; |
1098 | else if (data & CyOVERRUN) | 1032 | } |
1099 | info->icount.overrun++; | 1033 | if (tty_buffer_request_room(tty, 1)) { |
1100 | 1034 | if (data & info->read_status_mask) { | |
1101 | if (data & info->ignore_status_mask) { | 1035 | if (data & CyBREAK) { |
1036 | tty_insert_flip_char(tty, | ||
1037 | readb(base_addr + (CyRDSR << | ||
1038 | index)), TTY_BREAK); | ||
1039 | info->icount.rx++; | ||
1040 | if (info->flags & ASYNC_SAK) | ||
1041 | do_SAK(tty); | ||
1042 | } else if (data & CyFRAME) { | ||
1043 | tty_insert_flip_char( tty, | ||
1044 | readb(base_addr + (CyRDSR << | ||
1045 | index)), TTY_FRAME); | ||
1046 | info->icount.rx++; | ||
1047 | info->idle_stats.frame_errs++; | ||
1048 | } else if (data & CyPARITY) { | ||
1049 | /* Pieces of seven... */ | ||
1050 | tty_insert_flip_char(tty, | ||
1051 | readb(base_addr + (CyRDSR << | ||
1052 | index)), TTY_PARITY); | ||
1053 | info->icount.rx++; | ||
1054 | info->idle_stats.parity_errs++; | ||
1055 | } else if (data & CyOVERRUN) { | ||
1056 | tty_insert_flip_char(tty, 0, | ||
1057 | TTY_OVERRUN); | ||
1058 | info->icount.rx++; | ||
1059 | /* If the flip buffer itself is | ||
1060 | overflowing, we still lose | ||
1061 | the next incoming character. | ||
1062 | */ | ||
1063 | tty_insert_flip_char(tty, | ||
1064 | readb(base_addr + (CyRDSR << | ||
1065 | index)), TTY_FRAME); | ||
1102 | info->icount.rx++; | 1066 | info->icount.rx++; |
1103 | spin_unlock(&cinfo->card_lock); | ||
1104 | return; | ||
1105 | } | ||
1106 | if (tty_buffer_request_room(tty, 1)) { | ||
1107 | if (data & info->read_status_mask) { | ||
1108 | if (data & CyBREAK) { | ||
1109 | tty_insert_flip_char( | ||
1110 | tty, | ||
1111 | readb( | ||
1112 | base_addr + | ||
1113 | (CyRDSR << | ||
1114 | index)), | ||
1115 | TTY_BREAK); | ||
1116 | info->icount.rx++; | ||
1117 | if (info->flags & | ||
1118 | ASYNC_SAK) { | ||
1119 | do_SAK(tty); | ||
1120 | } | ||
1121 | } else if (data & CyFRAME) { | ||
1122 | tty_insert_flip_char( | ||
1123 | tty, | ||
1124 | readb( | ||
1125 | base_addr + | ||
1126 | (CyRDSR << | ||
1127 | index)), | ||
1128 | TTY_FRAME); | ||
1129 | info->icount.rx++; | ||
1130 | info->idle_stats. | ||
1131 | frame_errs++; | ||
1132 | } else if (data & CyPARITY) { | ||
1133 | /* Pieces of seven... */ | ||
1134 | tty_insert_flip_char( | ||
1135 | tty, | ||
1136 | readb( | ||
1137 | base_addr + | ||
1138 | (CyRDSR << | ||
1139 | index)), | ||
1140 | TTY_PARITY); | ||
1141 | info->icount.rx++; | ||
1142 | info->idle_stats. | ||
1143 | parity_errs++; | ||
1144 | } else if (data & CyOVERRUN) { | ||
1145 | tty_insert_flip_char( | ||
1146 | tty, 0, | ||
1147 | TTY_OVERRUN); | ||
1148 | info->icount.rx++; | ||
1149 | /* If the flip buffer itself is | ||
1150 | overflowing, we still lose | ||
1151 | the next incoming character. | ||
1152 | */ | ||
1153 | tty_insert_flip_char( | ||
1154 | tty, | ||
1155 | readb( | ||
1156 | base_addr + | ||
1157 | (CyRDSR << | ||
1158 | index)), | ||
1159 | TTY_FRAME); | ||
1160 | info->icount.rx++; | ||
1161 | info->idle_stats. | ||
1162 | overruns++; | ||
1163 | /* These two conditions may imply */ | ||
1164 | /* a normal read should be done. */ | ||
1165 | /* }else if(data & CyTIMEOUT){ */ | ||
1166 | /* }else if(data & CySPECHAR){ */ | ||
1167 | } else { | ||
1168 | tty_insert_flip_char( | ||
1169 | tty, 0, | ||
1170 | TTY_NORMAL); | ||
1171 | info->icount.rx++; | ||
1172 | } | ||
1173 | } else { | ||
1174 | tty_insert_flip_char(tty, 0, | ||
1175 | TTY_NORMAL); | ||
1176 | info->icount.rx++; | ||
1177 | } | ||
1178 | } else { | ||
1179 | /* there was a software buffer | ||
1180 | overrun and nothing could be | ||
1181 | done about it!!! */ | ||
1182 | info->icount.buf_overrun++; | ||
1183 | info->idle_stats.overruns++; | 1067 | info->idle_stats.overruns++; |
1068 | /* These two conditions may imply */ | ||
1069 | /* a normal read should be done. */ | ||
1070 | /* } else if(data & CyTIMEOUT) { */ | ||
1071 | /* } else if(data & CySPECHAR) { */ | ||
1072 | } else { | ||
1073 | tty_insert_flip_char(tty, 0, | ||
1074 | TTY_NORMAL); | ||
1075 | info->icount.rx++; | ||
1184 | } | 1076 | } |
1185 | } else { /* normal character reception */ | 1077 | } else { |
1186 | /* load # chars available from the chip */ | 1078 | tty_insert_flip_char(tty, 0, TTY_NORMAL); |
1187 | char_count = readb(base_addr + | 1079 | info->icount.rx++; |
1188 | (CyRDCR << index)); | 1080 | } |
1081 | } else { | ||
1082 | /* there was a software buffer overrun and nothing | ||
1083 | * could be done about it!!! */ | ||
1084 | info->icount.buf_overrun++; | ||
1085 | info->idle_stats.overruns++; | ||
1086 | } | ||
1087 | } else { /* normal character reception */ | ||
1088 | /* load # chars available from the chip */ | ||
1089 | char_count = readb(base_addr + (CyRDCR << index)); | ||
1189 | 1090 | ||
1190 | #ifdef CY_ENABLE_MONITORING | 1091 | #ifdef CY_ENABLE_MONITORING |
1191 | ++info->mon.int_count; | 1092 | ++info->mon.int_count; |
1192 | info->mon.char_count += char_count; | 1093 | info->mon.char_count += char_count; |
1193 | if (char_count > info->mon.char_max) | 1094 | if (char_count > info->mon.char_max) |
1194 | info->mon.char_max = char_count; | 1095 | info->mon.char_max = char_count; |
1195 | info->mon.char_last = char_count; | 1096 | info->mon.char_last = char_count; |
1196 | #endif | 1097 | #endif |
1197 | len = tty_buffer_request_room(tty, char_count); | 1098 | len = tty_buffer_request_room(tty, char_count); |
1198 | while (len--) { | 1099 | while (len--) { |
1199 | data = readb(base_addr + | 1100 | data = readb(base_addr + (CyRDSR << index)); |
1200 | (CyRDSR << index)); | 1101 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
1201 | tty_insert_flip_char(tty, data, | 1102 | info->idle_stats.recv_bytes++; |
1202 | TTY_NORMAL); | 1103 | info->icount.rx++; |
1203 | info->idle_stats.recv_bytes++; | ||
1204 | info->icount.rx++; | ||
1205 | #ifdef CY_16Y_HACK | 1104 | #ifdef CY_16Y_HACK |
1206 | udelay(10L); | 1105 | udelay(10L); |
1207 | #endif | 1106 | #endif |
1208 | } | ||
1209 | info->idle_stats.recv_idle = jiffies; | ||
1210 | } | ||
1211 | tty_schedule_flip(tty); | ||
1212 | } | 1107 | } |
1213 | /* end of service */ | 1108 | info->idle_stats.recv_idle = jiffies; |
1214 | cy_writeb(base_addr + (CyRIR << index), (save_xir & 0x3f)); | ||
1215 | cy_writeb(base_addr + (CyCAR << index), (save_car)); | ||
1216 | spin_unlock(&cinfo->card_lock); | ||
1217 | } | 1109 | } |
1110 | tty_schedule_flip(tty); | ||
1111 | end: | ||
1112 | /* end of service */ | ||
1113 | cy_writeb(base_addr + (CyRIR << index), save_xir & 0x3f); | ||
1114 | cy_writeb(base_addr + (CyCAR << index), save_car); | ||
1115 | } | ||
1116 | |||
1117 | static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip, | ||
1118 | void __iomem *base_addr) | ||
1119 | { | ||
1120 | struct cyclades_port *info; | ||
1121 | int char_count, index = cinfo->bus_index; | ||
1122 | u8 save_xir, channel, save_car, outch; | ||
1218 | 1123 | ||
1219 | if (status & CySRTransmit) { /* transmission interrupt */ | 1124 | /* Since we only get here when the transmit buffer |
1220 | /* Since we only get here when the transmit buffer | 1125 | is empty, we know we can always stuff a dozen |
1221 | is empty, we know we can always stuff a dozen | 1126 | characters. */ |
1222 | characters. */ | ||
1223 | #ifdef CY_DEBUG_INTERRUPTS | 1127 | #ifdef CY_DEBUG_INTERRUPTS |
1224 | printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip); | 1128 | printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip); |
1225 | #endif | 1129 | #endif |
1226 | 1130 | ||
1227 | /* determine the channel & change to that context */ | 1131 | /* determine the channel & change to that context */ |
1228 | spin_lock(&cinfo->card_lock); | 1132 | save_xir = readb(base_addr + (CyTIR << index)); |
1229 | save_xir = (u_char) readb(base_addr + (CyTIR << index)); | 1133 | channel = save_xir & CyIRChannel; |
1230 | channel = (u_short) (save_xir & CyIRChannel); | 1134 | save_car = readb(base_addr + (CyCAR << index)); |
1231 | save_car = readb(base_addr + (CyCAR << index)); | 1135 | cy_writeb(base_addr + (CyCAR << index), save_xir); |
1232 | cy_writeb(base_addr + (CyCAR << index), save_xir); | ||
1233 | 1136 | ||
1234 | /* validate the port# (as configured and open) */ | 1137 | /* validate the port# (as configured and open) */ |
1235 | if (channel + chip * 4 >= cinfo->nports) { | 1138 | if (channel + chip * 4 >= cinfo->nports) { |
1236 | cy_writeb(base_addr + (CySRER << index), | 1139 | cy_writeb(base_addr + (CySRER << index), |
1237 | readb(base_addr + (CySRER << index)) & | 1140 | readb(base_addr + (CySRER << index)) & ~CyTxRdy); |
1238 | ~CyTxRdy); | 1141 | goto end; |
1239 | goto txend; | 1142 | } |
1240 | } | 1143 | info = &cinfo->ports[channel + chip * 4]; |
1241 | info = &cinfo->ports[channel + chip * 4]; | 1144 | if (info->tty == NULL) { |
1242 | if (info->tty == NULL) { | 1145 | cy_writeb(base_addr + (CySRER << index), |
1243 | cy_writeb(base_addr + (CySRER << index), | 1146 | readb(base_addr + (CySRER << index)) & ~CyTxRdy); |
1244 | readb(base_addr + (CySRER << index)) & | 1147 | goto end; |
1245 | ~CyTxRdy); | 1148 | } |
1246 | goto txdone; | ||
1247 | } | ||
1248 | 1149 | ||
1249 | /* load the on-chip space for outbound data */ | 1150 | /* load the on-chip space for outbound data */ |
1250 | char_count = info->xmit_fifo_size; | 1151 | char_count = info->xmit_fifo_size; |
1251 | 1152 | ||
1252 | if (info->x_char) { /* send special char */ | 1153 | if (info->x_char) { /* send special char */ |
1253 | outch = info->x_char; | 1154 | outch = info->x_char; |
1254 | cy_writeb(base_addr + (CyTDR << index), outch); | 1155 | cy_writeb(base_addr + (CyTDR << index), outch); |
1255 | char_count--; | 1156 | char_count--; |
1256 | info->icount.tx++; | 1157 | info->icount.tx++; |
1257 | info->x_char = 0; | 1158 | info->x_char = 0; |
1258 | } | 1159 | } |
1259 | 1160 | ||
1260 | if (info->breakon || info->breakoff) { | 1161 | if (info->breakon || info->breakoff) { |
1261 | if (info->breakon) { | 1162 | if (info->breakon) { |
1262 | cy_writeb(base_addr + (CyTDR << index), 0); | 1163 | cy_writeb(base_addr + (CyTDR << index), 0); |
1263 | cy_writeb(base_addr + (CyTDR << index), 0x81); | 1164 | cy_writeb(base_addr + (CyTDR << index), 0x81); |
1264 | info->breakon = 0; | 1165 | info->breakon = 0; |
1265 | char_count -= 2; | 1166 | char_count -= 2; |
1266 | } | 1167 | } |
1267 | if (info->breakoff) { | 1168 | if (info->breakoff) { |
1268 | cy_writeb(base_addr + (CyTDR << index), 0); | 1169 | cy_writeb(base_addr + (CyTDR << index), 0); |
1269 | cy_writeb(base_addr + (CyTDR << index), 0x83); | 1170 | cy_writeb(base_addr + (CyTDR << index), 0x83); |
1270 | info->breakoff = 0; | 1171 | info->breakoff = 0; |
1271 | char_count -= 2; | 1172 | char_count -= 2; |
1272 | } | ||
1273 | } | 1173 | } |
1174 | } | ||
1274 | 1175 | ||
1275 | while (char_count-- > 0) { | 1176 | while (char_count-- > 0) { |
1276 | if (!info->xmit_cnt) { | 1177 | if (!info->xmit_cnt) { |
1277 | if (readb(base_addr + (CySRER << index)) & | 1178 | if (readb(base_addr + (CySRER << index)) & CyTxMpty) { |
1278 | CyTxMpty) { | 1179 | cy_writeb(base_addr + (CySRER << index), |
1279 | cy_writeb(base_addr + (CySRER << index), | 1180 | readb(base_addr + (CySRER << index)) & |
1280 | readb(base_addr + | ||
1281 | (CySRER << index)) & | ||
1282 | ~CyTxMpty); | 1181 | ~CyTxMpty); |
1283 | } else { | 1182 | } else { |
1284 | cy_writeb(base_addr + (CySRER << index), | 1183 | cy_writeb(base_addr + (CySRER << index), |
1285 | (readb(base_addr + | 1184 | (readb(base_addr + (CySRER << index)) & |
1286 | (CySRER << index)) & | ||
1287 | ~CyTxRdy) | CyTxMpty); | 1185 | ~CyTxRdy) | CyTxMpty); |
1288 | } | ||
1289 | goto txdone; | ||
1290 | } | 1186 | } |
1291 | if (info->xmit_buf == NULL) { | 1187 | goto done; |
1292 | cy_writeb(base_addr + (CySRER << index), | 1188 | } |
1293 | readb(base_addr + (CySRER << index)) & | 1189 | if (info->xmit_buf == NULL) { |
1190 | cy_writeb(base_addr + (CySRER << index), | ||
1191 | readb(base_addr + (CySRER << index)) & | ||
1294 | ~CyTxRdy); | 1192 | ~CyTxRdy); |
1295 | goto txdone; | 1193 | goto done; |
1296 | } | 1194 | } |
1297 | if (info->tty->stopped || info->tty->hw_stopped) { | 1195 | if (info->tty->stopped || info->tty->hw_stopped) { |
1298 | cy_writeb(base_addr + (CySRER << index), | 1196 | cy_writeb(base_addr + (CySRER << index), |
1299 | readb(base_addr + (CySRER << index)) & | 1197 | readb(base_addr + (CySRER << index)) & |
1300 | ~CyTxRdy); | 1198 | ~CyTxRdy); |
1301 | goto txdone; | 1199 | goto done; |
1302 | } | 1200 | } |
1303 | /* Because the Embedded Transmit Commands have | 1201 | /* Because the Embedded Transmit Commands have been enabled, |
1304 | been enabled, we must check to see if the | 1202 | * we must check to see if the escape character, NULL, is being |
1305 | escape character, NULL, is being sent. If it | 1203 | * sent. If it is, we must ensure that there is room for it to |
1306 | is, we must ensure that there is room for it | 1204 | * be doubled in the output stream. Therefore we no longer |
1307 | to be doubled in the output stream. Therefore | 1205 | * advance the pointer when the character is fetched, but |
1308 | we no longer advance the pointer when the | 1206 | * rather wait until after the check for a NULL output |
1309 | character is fetched, but rather wait until | 1207 | * character. This is necessary because there may not be room |
1310 | after the check for a NULL output character. | 1208 | * for the two chars needed to send a NULL.) |
1311 | This is necessary because there may not be | 1209 | */ |
1312 | room for the two chars needed to send a NULL.) | 1210 | outch = info->xmit_buf[info->xmit_tail]; |
1313 | */ | 1211 | if (outch) { |
1314 | outch = info->xmit_buf[info->xmit_tail]; | 1212 | info->xmit_cnt--; |
1315 | if (outch) { | 1213 | info->xmit_tail = (info->xmit_tail + 1) & |
1214 | (SERIAL_XMIT_SIZE - 1); | ||
1215 | cy_writeb(base_addr + (CyTDR << index), outch); | ||
1216 | info->icount.tx++; | ||
1217 | } else { | ||
1218 | if (char_count > 1) { | ||
1316 | info->xmit_cnt--; | 1219 | info->xmit_cnt--; |
1317 | info->xmit_tail = (info->xmit_tail + 1) & | 1220 | info->xmit_tail = (info->xmit_tail + 1) & |
1318 | (SERIAL_XMIT_SIZE - 1); | 1221 | (SERIAL_XMIT_SIZE - 1); |
1319 | cy_writeb(base_addr + (CyTDR << index), outch); | 1222 | cy_writeb(base_addr + (CyTDR << index), outch); |
1223 | cy_writeb(base_addr + (CyTDR << index), 0); | ||
1320 | info->icount.tx++; | 1224 | info->icount.tx++; |
1321 | } else { | 1225 | char_count--; |
1322 | if (char_count > 1) { | ||
1323 | info->xmit_cnt--; | ||
1324 | info->xmit_tail = (info->xmit_tail + 1)& | ||
1325 | (SERIAL_XMIT_SIZE - 1); | ||
1326 | cy_writeb(base_addr + (CyTDR << index), | ||
1327 | outch); | ||
1328 | cy_writeb(base_addr + (CyTDR << index), | ||
1329 | 0); | ||
1330 | info->icount.tx++; | ||
1331 | char_count--; | ||
1332 | } | ||
1333 | } | 1226 | } |
1334 | } | 1227 | } |
1335 | |||
1336 | txdone: | ||
1337 | if (info->xmit_cnt < WAKEUP_CHARS) { | ||
1338 | cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); | ||
1339 | } | ||
1340 | txend: | ||
1341 | /* end of service */ | ||
1342 | cy_writeb(base_addr + (CyTIR << index), (save_xir & 0x3f)); | ||
1343 | cy_writeb(base_addr + (CyCAR << index), (save_car)); | ||
1344 | spin_unlock(&cinfo->card_lock); | ||
1345 | } | 1228 | } |
1346 | 1229 | ||
1347 | if (status & CySRModem) { /* modem interrupt */ | 1230 | done: |
1231 | tty_wakeup(info->tty); | ||
1232 | end: | ||
1233 | /* end of service */ | ||
1234 | cy_writeb(base_addr + (CyTIR << index), save_xir & 0x3f); | ||
1235 | cy_writeb(base_addr + (CyCAR << index), save_car); | ||
1236 | } | ||
1348 | 1237 | ||
1349 | /* determine the channel & change to that context */ | 1238 | static void cyy_chip_modem(struct cyclades_card *cinfo, int chip, |
1350 | spin_lock(&cinfo->card_lock); | 1239 | void __iomem *base_addr) |
1351 | save_xir = (u_char) readb(base_addr + (CyMIR << index)); | 1240 | { |
1352 | channel = (u_short) (save_xir & CyIRChannel); | 1241 | struct cyclades_port *info; |
1353 | info = &cinfo->ports[channel + chip * 4]; | 1242 | int index = cinfo->bus_index; |
1354 | save_car = readb(base_addr + (CyCAR << index)); | 1243 | u8 save_xir, channel, save_car, mdm_change, mdm_status; |
1355 | cy_writeb(base_addr + (CyCAR << index), save_xir); | ||
1356 | 1244 | ||
1357 | mdm_change = readb(base_addr + (CyMISR << index)); | 1245 | /* determine the channel & change to that context */ |
1358 | mdm_status = readb(base_addr + (CyMSVR1 << index)); | 1246 | save_xir = readb(base_addr + (CyMIR << index)); |
1247 | channel = save_xir & CyIRChannel; | ||
1248 | info = &cinfo->ports[channel + chip * 4]; | ||
1249 | save_car = readb(base_addr + (CyCAR << index)); | ||
1250 | cy_writeb(base_addr + (CyCAR << index), save_xir); | ||
1359 | 1251 | ||
1360 | if (info->tty) { | 1252 | mdm_change = readb(base_addr + (CyMISR << index)); |
1361 | if (mdm_change & CyANY_DELTA) { | 1253 | mdm_status = readb(base_addr + (CyMSVR1 << index)); |
1362 | /* For statistics only */ | ||
1363 | if (mdm_change & CyDCD) | ||
1364 | info->icount.dcd++; | ||
1365 | if (mdm_change & CyCTS) | ||
1366 | info->icount.cts++; | ||
1367 | if (mdm_change & CyDSR) | ||
1368 | info->icount.dsr++; | ||
1369 | if (mdm_change & CyRI) | ||
1370 | info->icount.rng++; | ||
1371 | |||
1372 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); | ||
1373 | } | ||
1374 | 1254 | ||
1375 | if ((mdm_change & CyDCD) && | 1255 | if (!info->tty) |
1376 | (info->flags & ASYNC_CHECK_CD)) { | 1256 | goto end; |
1377 | if (mdm_status & CyDCD) { | 1257 | |
1378 | cy_sched_event(info, | 1258 | if (mdm_change & CyANY_DELTA) { |
1379 | Cy_EVENT_OPEN_WAKEUP); | 1259 | /* For statistics only */ |
1380 | } else { | 1260 | if (mdm_change & CyDCD) |
1381 | cy_sched_event(info, Cy_EVENT_HANGUP); | 1261 | info->icount.dcd++; |
1382 | } | 1262 | if (mdm_change & CyCTS) |
1383 | } | 1263 | info->icount.cts++; |
1384 | if ((mdm_change & CyCTS) && | 1264 | if (mdm_change & CyDSR) |
1385 | (info->flags & ASYNC_CTS_FLOW)) { | 1265 | info->icount.dsr++; |
1386 | if (info->tty->hw_stopped) { | 1266 | if (mdm_change & CyRI) |
1387 | if (mdm_status & CyCTS) { | 1267 | info->icount.rng++; |
1388 | /* cy_start isn't used | 1268 | |
1389 | because... !!! */ | 1269 | wake_up_interruptible(&info->delta_msr_wait); |
1390 | info->tty->hw_stopped = 0; | 1270 | } |
1391 | cy_writeb(base_addr + | 1271 | |
1392 | (CySRER << index), | 1272 | if ((mdm_change & CyDCD) && (info->flags & ASYNC_CHECK_CD)) { |
1393 | readb(base_addr + | 1273 | if (!(mdm_status & CyDCD)) { |
1394 | (CySRER << | 1274 | tty_hangup(info->tty); |
1395 | index))| | 1275 | info->flags &= ~ASYNC_NORMAL_ACTIVE; |
1396 | CyTxRdy); | 1276 | } |
1397 | cy_sched_event(info, | 1277 | wake_up_interruptible(&info->open_wait); |
1398 | Cy_EVENT_WRITE_WAKEUP); | 1278 | } |
1399 | } | 1279 | if ((mdm_change & CyCTS) && (info->flags & ASYNC_CTS_FLOW)) { |
1400 | } else { | 1280 | if (info->tty->hw_stopped) { |
1401 | if (!(mdm_status & CyCTS)) { | 1281 | if (mdm_status & CyCTS) { |
1402 | /* cy_stop isn't used | 1282 | /* cy_start isn't used |
1403 | because ... !!! */ | 1283 | because... !!! */ |
1404 | info->tty->hw_stopped = 1; | 1284 | info->tty->hw_stopped = 0; |
1405 | cy_writeb(base_addr + | 1285 | cy_writeb(base_addr + (CySRER << index), |
1406 | (CySRER << index), | 1286 | readb(base_addr + (CySRER << index)) | |
1407 | readb(base_addr + | 1287 | CyTxRdy); |
1408 | (CySRER << | 1288 | tty_wakeup(info->tty); |
1409 | index)) & | ||
1410 | ~CyTxRdy); | ||
1411 | } | ||
1412 | } | ||
1413 | } | 1289 | } |
1414 | /* if (mdm_change & CyDSR) { | 1290 | } else { |
1291 | if (!(mdm_status & CyCTS)) { | ||
1292 | /* cy_stop isn't used | ||
1293 | because ... !!! */ | ||
1294 | info->tty->hw_stopped = 1; | ||
1295 | cy_writeb(base_addr + (CySRER << index), | ||
1296 | readb(base_addr + (CySRER << index)) & | ||
1297 | ~CyTxRdy); | ||
1415 | } | 1298 | } |
1416 | if (mdm_change & CyRI) { | ||
1417 | }*/ | ||
1418 | } | 1299 | } |
1419 | /* end of service */ | ||
1420 | cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f)); | ||
1421 | cy_writeb(base_addr + (CyCAR << index), save_car); | ||
1422 | spin_unlock(&cinfo->card_lock); | ||
1423 | } | 1300 | } |
1301 | /* if (mdm_change & CyDSR) { | ||
1302 | } | ||
1303 | if (mdm_change & CyRI) { | ||
1304 | }*/ | ||
1305 | end: | ||
1306 | /* end of service */ | ||
1307 | cy_writeb(base_addr + (CyMIR << index), save_xir & 0x3f); | ||
1308 | cy_writeb(base_addr + (CyCAR << index), save_car); | ||
1424 | } | 1309 | } |
1425 | 1310 | ||
1426 | /* The real interrupt service routine is called | 1311 | /* The real interrupt service routine is called |
@@ -1432,10 +1317,8 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) | |||
1432 | int status; | 1317 | int status; |
1433 | struct cyclades_card *cinfo = dev_id; | 1318 | struct cyclades_card *cinfo = dev_id; |
1434 | void __iomem *base_addr, *card_base_addr; | 1319 | void __iomem *base_addr, *card_base_addr; |
1435 | int chip; | 1320 | unsigned int chip, too_many, had_work; |
1436 | int index; | 1321 | int index; |
1437 | int too_many; | ||
1438 | int had_work; | ||
1439 | 1322 | ||
1440 | if (unlikely(cinfo == NULL)) { | 1323 | if (unlikely(cinfo == NULL)) { |
1441 | #ifdef CY_DEBUG_INTERRUPTS | 1324 | #ifdef CY_DEBUG_INTERRUPTS |
@@ -1470,11 +1353,16 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) | |||
1470 | chips to be checked in a round-robin fashion (after | 1353 | chips to be checked in a round-robin fashion (after |
1471 | draining each of a bunch (1000) of characters). | 1354 | draining each of a bunch (1000) of characters). |
1472 | */ | 1355 | */ |
1473 | if (1000 < too_many++) { | 1356 | if (1000 < too_many++) |
1474 | break; | 1357 | break; |
1475 | } | 1358 | spin_lock(&cinfo->card_lock); |
1476 | cyy_intr_chip(cinfo, chip, base_addr, status, | 1359 | if (status & CySRReceive) /* rx intr */ |
1477 | index); | 1360 | cyy_chip_rx(cinfo, chip, base_addr); |
1361 | if (status & CySRTransmit) /* tx intr */ | ||
1362 | cyy_chip_tx(cinfo, chip, base_addr); | ||
1363 | if (status & CySRModem) /* modem intr */ | ||
1364 | cyy_chip_modem(cinfo, chip, base_addr); | ||
1365 | spin_unlock(&cinfo->card_lock); | ||
1478 | } | 1366 | } |
1479 | } | 1367 | } |
1480 | } while (had_work); | 1368 | } while (had_work); |
@@ -1529,7 +1417,7 @@ cyz_issue_cmd(struct cyclades_card *cinfo, | |||
1529 | struct ZFW_CTRL __iomem *zfw_ctrl; | 1417 | struct ZFW_CTRL __iomem *zfw_ctrl; |
1530 | struct BOARD_CTRL __iomem *board_ctrl; | 1418 | struct BOARD_CTRL __iomem *board_ctrl; |
1531 | __u32 __iomem *pci_doorbell; | 1419 | __u32 __iomem *pci_doorbell; |
1532 | int index; | 1420 | unsigned int index; |
1533 | 1421 | ||
1534 | firm_id = cinfo->base_addr + ID_ADDRESS; | 1422 | firm_id = cinfo->base_addr + ID_ADDRESS; |
1535 | if (!ISZLOADED(*cinfo)) { | 1423 | if (!ISZLOADED(*cinfo)) { |
@@ -1554,13 +1442,12 @@ cyz_issue_cmd(struct cyclades_card *cinfo, | |||
1554 | return 0; | 1442 | return 0; |
1555 | } /* cyz_issue_cmd */ | 1443 | } /* cyz_issue_cmd */ |
1556 | 1444 | ||
1557 | static void | 1445 | static void cyz_handle_rx(struct cyclades_port *info, |
1558 | cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, | ||
1559 | struct BUF_CTRL __iomem *buf_ctrl) | 1446 | struct BUF_CTRL __iomem *buf_ctrl) |
1560 | { | 1447 | { |
1561 | struct cyclades_card *cinfo = info->card; | 1448 | struct cyclades_card *cinfo = info->card; |
1562 | struct tty_struct *tty = info->tty; | 1449 | struct tty_struct *tty = info->tty; |
1563 | int char_count; | 1450 | unsigned int char_count; |
1564 | int len; | 1451 | int len; |
1565 | #ifdef BLOCKMOVE | 1452 | #ifdef BLOCKMOVE |
1566 | unsigned char *buf; | 1453 | unsigned char *buf; |
@@ -1633,9 +1520,11 @@ cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, | |||
1633 | char_count = rx_put - rx_get; | 1520 | char_count = rx_put - rx_get; |
1634 | else | 1521 | else |
1635 | char_count = rx_put - rx_get + rx_bufsize; | 1522 | char_count = rx_put - rx_get + rx_bufsize; |
1636 | if (char_count >= (int)readl(&buf_ctrl->rx_threshold)) { | 1523 | if (char_count >= readl(&buf_ctrl->rx_threshold) && |
1637 | cy_sched_event(info, Cy_EVENT_Z_RX_FULL); | 1524 | !timer_pending(&cyz_rx_full_timer[ |
1638 | } | 1525 | info->line])) |
1526 | mod_timer(&cyz_rx_full_timer[info->line], | ||
1527 | jiffies + 1); | ||
1639 | #endif | 1528 | #endif |
1640 | info->idle_stats.recv_idle = jiffies; | 1529 | info->idle_stats.recv_idle = jiffies; |
1641 | tty_schedule_flip(tty); | 1530 | tty_schedule_flip(tty); |
@@ -1645,14 +1534,13 @@ cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, | |||
1645 | } | 1534 | } |
1646 | } | 1535 | } |
1647 | 1536 | ||
1648 | static void | 1537 | static void cyz_handle_tx(struct cyclades_port *info, |
1649 | cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, | ||
1650 | struct BUF_CTRL __iomem *buf_ctrl) | 1538 | struct BUF_CTRL __iomem *buf_ctrl) |
1651 | { | 1539 | { |
1652 | struct cyclades_card *cinfo = info->card; | 1540 | struct cyclades_card *cinfo = info->card; |
1653 | struct tty_struct *tty = info->tty; | 1541 | struct tty_struct *tty = info->tty; |
1654 | char data; | 1542 | u8 data; |
1655 | int char_count; | 1543 | unsigned int char_count; |
1656 | #ifdef BLOCKMOVE | 1544 | #ifdef BLOCKMOVE |
1657 | int small_count; | 1545 | int small_count; |
1658 | #endif | 1546 | #endif |
@@ -1717,9 +1605,7 @@ cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, | |||
1717 | } | 1605 | } |
1718 | #endif | 1606 | #endif |
1719 | ztxdone: | 1607 | ztxdone: |
1720 | if (info->xmit_cnt < WAKEUP_CHARS) { | 1608 | tty_wakeup(tty); |
1721 | cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); | ||
1722 | } | ||
1723 | /* Update tx_put */ | 1609 | /* Update tx_put */ |
1724 | cy_writel(&buf_ctrl->tx_put, tx_put); | 1610 | cy_writel(&buf_ctrl->tx_put, tx_put); |
1725 | } | 1611 | } |
@@ -1781,10 +1667,11 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1781 | if ((fw_ver > 241 ? ((u_long) param) : | 1667 | if ((fw_ver > 241 ? ((u_long) param) : |
1782 | readl(&ch_ctrl->rs_status)) & | 1668 | readl(&ch_ctrl->rs_status)) & |
1783 | C_RS_DCD) { | 1669 | C_RS_DCD) { |
1784 | cy_sched_event(info, | 1670 | wake_up_interruptible(&info->open_wait); |
1785 | Cy_EVENT_OPEN_WAKEUP); | ||
1786 | } else { | 1671 | } else { |
1787 | cy_sched_event(info, Cy_EVENT_HANGUP); | 1672 | tty_hangup(info->tty); |
1673 | wake_up_interruptible(&info->open_wait); | ||
1674 | info->flags &= ~ASYNC_NORMAL_ACTIVE; | ||
1788 | } | 1675 | } |
1789 | } | 1676 | } |
1790 | break; | 1677 | break; |
@@ -1802,7 +1689,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1802 | break; | 1689 | break; |
1803 | #ifdef Z_WAKE | 1690 | #ifdef Z_WAKE |
1804 | case C_CM_IOCTLW: | 1691 | case C_CM_IOCTLW: |
1805 | cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP); | 1692 | complete(&info->shutdown_wait); |
1806 | break; | 1693 | break; |
1807 | #endif | 1694 | #endif |
1808 | #ifdef CONFIG_CYZ_INTR | 1695 | #ifdef CONFIG_CYZ_INTR |
@@ -1814,7 +1701,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1814 | printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " | 1701 | printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " |
1815 | "port %ld\n", info->card, channel); | 1702 | "port %ld\n", info->card, channel); |
1816 | #endif | 1703 | #endif |
1817 | cyz_handle_rx(info, ch_ctrl, buf_ctrl); | 1704 | cyz_handle_rx(info, buf_ctrl); |
1818 | break; | 1705 | break; |
1819 | case C_CM_TXBEMPTY: | 1706 | case C_CM_TXBEMPTY: |
1820 | case C_CM_TXLOWWM: | 1707 | case C_CM_TXLOWWM: |
@@ -1824,7 +1711,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1824 | printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " | 1711 | printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " |
1825 | "port %ld\n", info->card, channel); | 1712 | "port %ld\n", info->card, channel); |
1826 | #endif | 1713 | #endif |
1827 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); | 1714 | cyz_handle_tx(info, buf_ctrl); |
1828 | break; | 1715 | break; |
1829 | #endif /* CONFIG_CYZ_INTR */ | 1716 | #endif /* CONFIG_CYZ_INTR */ |
1830 | case C_CM_FATAL: | 1717 | case C_CM_FATAL: |
@@ -1834,7 +1721,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1834 | break; | 1721 | break; |
1835 | } | 1722 | } |
1836 | if (delta_count) | 1723 | if (delta_count) |
1837 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); | 1724 | wake_up_interruptible(&info->delta_msr_wait); |
1838 | if (special_count) | 1725 | if (special_count) |
1839 | tty_schedule_flip(tty); | 1726 | tty_schedule_flip(tty); |
1840 | } | 1727 | } |
@@ -1893,10 +1780,9 @@ static void cyz_poll(unsigned long arg) | |||
1893 | struct FIRM_ID __iomem *firm_id; | 1780 | struct FIRM_ID __iomem *firm_id; |
1894 | struct ZFW_CTRL __iomem *zfw_ctrl; | 1781 | struct ZFW_CTRL __iomem *zfw_ctrl; |
1895 | struct BOARD_CTRL __iomem *board_ctrl; | 1782 | struct BOARD_CTRL __iomem *board_ctrl; |
1896 | struct CH_CTRL __iomem *ch_ctrl; | ||
1897 | struct BUF_CTRL __iomem *buf_ctrl; | 1783 | struct BUF_CTRL __iomem *buf_ctrl; |
1898 | unsigned long expires = jiffies + HZ; | 1784 | unsigned long expires = jiffies + HZ; |
1899 | int card, port; | 1785 | unsigned int port, card; |
1900 | 1786 | ||
1901 | for (card = 0; card < NR_CARDS; card++) { | 1787 | for (card = 0; card < NR_CARDS; card++) { |
1902 | cinfo = &cy_card[card]; | 1788 | cinfo = &cy_card[card]; |
@@ -1923,12 +1809,11 @@ static void cyz_poll(unsigned long arg) | |||
1923 | for (port = 0; port < cinfo->nports; port++) { | 1809 | for (port = 0; port < cinfo->nports; port++) { |
1924 | info = &cinfo->ports[port]; | 1810 | info = &cinfo->ports[port]; |
1925 | tty = info->tty; | 1811 | tty = info->tty; |
1926 | ch_ctrl = &(zfw_ctrl->ch_ctrl[port]); | ||
1927 | buf_ctrl = &(zfw_ctrl->buf_ctrl[port]); | 1812 | buf_ctrl = &(zfw_ctrl->buf_ctrl[port]); |
1928 | 1813 | ||
1929 | if (!info->throttle) | 1814 | if (!info->throttle) |
1930 | cyz_handle_rx(info, ch_ctrl, buf_ctrl); | 1815 | cyz_handle_rx(info, buf_ctrl); |
1931 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); | 1816 | cyz_handle_tx(info, buf_ctrl); |
1932 | } | 1817 | } |
1933 | /* poll every 'cyz_polling_cycle' period */ | 1818 | /* poll every 'cyz_polling_cycle' period */ |
1934 | expires = jiffies + cyz_polling_cycle; | 1819 | expires = jiffies + cyz_polling_cycle; |
@@ -2491,11 +2376,11 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2491 | static int cy_open(struct tty_struct *tty, struct file *filp) | 2376 | static int cy_open(struct tty_struct *tty, struct file *filp) |
2492 | { | 2377 | { |
2493 | struct cyclades_port *info; | 2378 | struct cyclades_port *info; |
2494 | unsigned int i; | 2379 | unsigned int i, line; |
2495 | int retval, line; | 2380 | int retval; |
2496 | 2381 | ||
2497 | line = tty->index; | 2382 | line = tty->index; |
2498 | if ((line < 0) || (NR_PORTS <= line)) { | 2383 | if ((tty->index < 0) || (NR_PORTS <= line)) { |
2499 | return -ENODEV; | 2384 | return -ENODEV; |
2500 | } | 2385 | } |
2501 | for (i = 0; i < NR_CARDS; i++) | 2386 | for (i = 0; i < NR_CARDS; i++) |
@@ -2812,7 +2697,6 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
2812 | spin_lock_irqsave(&card->card_lock, flags); | 2697 | spin_lock_irqsave(&card->card_lock, flags); |
2813 | 2698 | ||
2814 | tty->closing = 0; | 2699 | tty->closing = 0; |
2815 | info->event = 0; | ||
2816 | info->tty = NULL; | 2700 | info->tty = NULL; |
2817 | if (info->blocked_open) { | 2701 | if (info->blocked_open) { |
2818 | spin_unlock_irqrestore(&card->card_lock, flags); | 2702 | spin_unlock_irqrestore(&card->card_lock, flags); |
@@ -4444,7 +4328,6 @@ static void cy_hangup(struct tty_struct *tty) | |||
4444 | 4328 | ||
4445 | cy_flush_buffer(tty); | 4329 | cy_flush_buffer(tty); |
4446 | shutdown(info); | 4330 | shutdown(info); |
4447 | info->event = 0; | ||
4448 | info->count = 0; | 4331 | info->count = 0; |
4449 | #ifdef CY_DEBUG_COUNT | 4332 | #ifdef CY_DEBUG_COUNT |
4450 | printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n", | 4333 | printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n", |
@@ -4467,9 +4350,9 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo) | |||
4467 | { | 4350 | { |
4468 | struct cyclades_port *info; | 4351 | struct cyclades_port *info; |
4469 | u32 uninitialized_var(mailbox); | 4352 | u32 uninitialized_var(mailbox); |
4470 | unsigned int nports; | 4353 | unsigned int nports, port; |
4471 | unsigned short chip_number; | 4354 | unsigned short chip_number; |
4472 | int uninitialized_var(index), port; | 4355 | int uninitialized_var(index); |
4473 | 4356 | ||
4474 | spin_lock_init(&cinfo->card_lock); | 4357 | spin_lock_init(&cinfo->card_lock); |
4475 | 4358 | ||
@@ -4502,7 +4385,6 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo) | |||
4502 | info->closing_wait = CLOSING_WAIT_DELAY; | 4385 | info->closing_wait = CLOSING_WAIT_DELAY; |
4503 | info->close_delay = 5 * HZ / 10; | 4386 | info->close_delay = 5 * HZ / 10; |
4504 | 4387 | ||
4505 | INIT_WORK(&info->tqueue, do_softint); | ||
4506 | init_waitqueue_head(&info->open_wait); | 4388 | init_waitqueue_head(&info->open_wait); |
4507 | init_waitqueue_head(&info->close_wait); | 4389 | init_waitqueue_head(&info->close_wait); |
4508 | init_completion(&info->shutdown_wait); | 4390 | init_completion(&info->shutdown_wait); |
@@ -5236,7 +5118,7 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, | |||
5236 | } | 5118 | } |
5237 | } | 5119 | } |
5238 | #endif /* CONFIG_CYZ_INTR */ | 5120 | #endif /* CONFIG_CYZ_INTR */ |
5239 | cy_card[card_no].num_chips = -1; | 5121 | cy_card[card_no].num_chips = (unsigned int)-1; |
5240 | } | 5122 | } |
5241 | 5123 | ||
5242 | /* set cy_card */ | 5124 | /* set cy_card */ |
@@ -5480,13 +5362,13 @@ static int __init cy_init(void) | |||
5480 | #ifdef CONFIG_PCI | 5362 | #ifdef CONFIG_PCI |
5481 | /* look for pci boards */ | 5363 | /* look for pci boards */ |
5482 | retval = pci_register_driver(&cy_pci_driver); | 5364 | retval = pci_register_driver(&cy_pci_driver); |
5483 | if (retval && !nboards) | 5365 | if (retval && !nboards) { |
5484 | goto err_unr; | 5366 | tty_unregister_driver(cy_serial_driver); |
5367 | goto err_frtty; | ||
5368 | } | ||
5485 | #endif | 5369 | #endif |
5486 | 5370 | ||
5487 | return 0; | 5371 | return 0; |
5488 | err_unr: | ||
5489 | tty_unregister_driver(cy_serial_driver); | ||
5490 | err_frtty: | 5372 | err_frtty: |
5491 | put_tty_driver(cy_serial_driver); | 5373 | put_tty_driver(cy_serial_driver); |
5492 | err: | 5374 | err: |
@@ -5496,7 +5378,7 @@ err: | |||
5496 | static void __exit cy_cleanup_module(void) | 5378 | static void __exit cy_cleanup_module(void) |
5497 | { | 5379 | { |
5498 | struct cyclades_card *card; | 5380 | struct cyclades_card *card; |
5499 | int i, e1; | 5381 | unsigned int i, e1; |
5500 | 5382 | ||
5501 | #ifndef CONFIG_CYZ_INTR | 5383 | #ifndef CONFIG_CYZ_INTR |
5502 | del_timer_sync(&cyz_timerlist); | 5384 | del_timer_sync(&cyz_timerlist); |
@@ -5524,8 +5406,7 @@ static void __exit cy_cleanup_module(void) | |||
5524 | #endif /* CONFIG_CYZ_INTR */ | 5406 | #endif /* CONFIG_CYZ_INTR */ |
5525 | ) | 5407 | ) |
5526 | free_irq(card->irq, card); | 5408 | free_irq(card->irq, card); |
5527 | for (e1 = card->first_line; | 5409 | for (e1 = card->first_line; e1 < card->first_line + |
5528 | e1 < card->first_line + | ||
5529 | card->nports; e1++) | 5410 | card->nports; e1++) |
5530 | tty_unregister_device(cy_serial_driver, e1); | 5411 | tty_unregister_device(cy_serial_driver, e1); |
5531 | kfree(card->ports); | 5412 | kfree(card->ports); |