aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/cyclades.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/cyclades.c')
-rw-r--r--drivers/char/cyclades.c675
1 files changed, 340 insertions, 335 deletions
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 3bb4e534c14e..dd8223dc9086 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -1053,6 +1053,341 @@ detect_isa_irq(void __iomem *address)
1053} 1053}
1054#endif /* CONFIG_ISA */ 1054#endif /* CONFIG_ISA */
1055 1055
1056static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
1057 void __iomem *base_addr, int status, int index)
1058{
1059 struct cyclades_port *info;
1060 struct tty_struct *tty;
1061 volatile int char_count;
1062 int i, j, len, mdm_change, mdm_status, outch;
1063 int save_xir, channel, save_car;
1064 char data;
1065
1066 if (status & CySRReceive) { /* reception interrupt */
1067#ifdef CY_DEBUG_INTERRUPTS
1068 printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip);
1069#endif
1070 /* determine the channel & change to that context */
1071 spin_lock(&cinfo->card_lock);
1072 save_xir = (u_char) cy_readb(base_addr+(CyRIR<<index));
1073 channel = (u_short ) (save_xir & CyIRChannel);
1074 i = channel + chip * 4 + cinfo->first_line;
1075 info = &cy_port[i];
1076 info->last_active = jiffies;
1077 save_car = cy_readb(base_addr+(CyCAR<<index));
1078 cy_writeb(base_addr+(CyCAR<<index), save_xir);
1079
1080 /* if there is nowhere to put the data, discard it */
1081 if(info->tty == 0){
1082 j = (cy_readb(base_addr+(CyRIVR<<index)) & CyIVRMask);
1083 if ( j == CyIVRRxEx ) { /* exception */
1084 data = cy_readb(base_addr+(CyRDSR<<index));
1085 } else { /* normal character reception */
1086 char_count = cy_readb(base_addr+(CyRDCR<<index));
1087 while(char_count--){
1088 data = cy_readb(base_addr+(CyRDSR<<index));
1089 }
1090 }
1091 }else{ /* there is an open port for this data */
1092 tty = info->tty;
1093 j = (cy_readb(base_addr+(CyRIVR<<index)) & CyIVRMask);
1094 if ( j == CyIVRRxEx ) { /* exception */
1095 data = cy_readb(base_addr+(CyRDSR<<index));
1096
1097 /* For statistics only */
1098 if (data & CyBREAK)
1099 info->icount.brk++;
1100 else if(data & CyFRAME)
1101 info->icount.frame++;
1102 else if(data & CyPARITY)
1103 info->icount.parity++;
1104 else if(data & CyOVERRUN)
1105 info->icount.overrun++;
1106
1107 if(data & info->ignore_status_mask){
1108 info->icount.rx++;
1109 return;
1110 }
1111 if (tty_buffer_request_room(tty, 1)) {
1112 if (data & info->read_status_mask){
1113 if(data & CyBREAK){
1114 tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_BREAK);
1115 info->icount.rx++;
1116 if (info->flags & ASYNC_SAK){
1117 do_SAK(tty);
1118 }
1119 }else if(data & CyFRAME){
1120 tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME);
1121 info->icount.rx++;
1122 info->idle_stats.frame_errs++;
1123 }else if(data & CyPARITY){
1124 /* Pieces of seven... */
1125 tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_PARITY);
1126 info->icount.rx++;
1127 info->idle_stats.parity_errs++;
1128 }else if(data & CyOVERRUN){
1129 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
1130 info->icount.rx++;
1131 /* If the flip buffer itself is
1132 overflowing, we still lose
1133 the next incoming character.
1134 */
1135 tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME);
1136 info->icount.rx++;
1137 info->idle_stats.overruns++;
1138 /* These two conditions may imply */
1139 /* a normal read should be done. */
1140 /* }else if(data & CyTIMEOUT){ */
1141 /* }else if(data & CySPECHAR){ */
1142 }else {
1143 tty_insert_flip_char(tty, 0, TTY_NORMAL);
1144 info->icount.rx++;
1145 }
1146 }else{
1147 tty_insert_flip_char(tty, 0, TTY_NORMAL);
1148 info->icount.rx++;
1149 }
1150 }else{
1151 /* there was a software buffer
1152 overrun and nothing could be
1153 done about it!!! */
1154 info->icount.buf_overrun++;
1155 info->idle_stats.overruns++;
1156 }
1157 } else { /* normal character reception */
1158 /* load # chars available from the chip */
1159 char_count = cy_readb(base_addr+(CyRDCR<<index));
1160
1161#ifdef CY_ENABLE_MONITORING
1162 ++info->mon.int_count;
1163 info->mon.char_count += char_count;
1164 if (char_count > info->mon.char_max)
1165 info->mon.char_max = char_count;
1166 info->mon.char_last = char_count;
1167#endif
1168 len = tty_buffer_request_room(tty, char_count);
1169 while(len--){
1170 data = cy_readb(base_addr+(CyRDSR<<index));
1171 tty_insert_flip_char(tty, data, TTY_NORMAL);
1172 info->idle_stats.recv_bytes++;
1173 info->icount.rx++;
1174#ifdef CY_16Y_HACK
1175 udelay(10L);
1176#endif
1177 }
1178 info->idle_stats.recv_idle = jiffies;
1179 }
1180 tty_schedule_flip(tty);
1181 }
1182 /* end of service */
1183 cy_writeb(base_addr+(CyRIR<<index), (save_xir & 0x3f));
1184 cy_writeb(base_addr+(CyCAR<<index), (save_car));
1185 spin_unlock(&cinfo->card_lock);
1186 }
1187
1188
1189 if (status & CySRTransmit) { /* transmission interrupt */
1190 /* Since we only get here when the transmit buffer
1191 is empty, we know we can always stuff a dozen
1192 characters. */
1193#ifdef CY_DEBUG_INTERRUPTS
1194 printk("cyy_interrupt: xmit intr, chip %d\n\r", chip);
1195#endif
1196
1197 /* determine the channel & change to that context */
1198 spin_lock(&cinfo->card_lock);
1199 save_xir = (u_char) cy_readb(base_addr+(CyTIR<<index));
1200 channel = (u_short ) (save_xir & CyIRChannel);
1201 i = channel + chip * 4 + cinfo->first_line;
1202 save_car = cy_readb(base_addr+(CyCAR<<index));
1203 cy_writeb(base_addr+(CyCAR<<index), save_xir);
1204
1205 /* validate the port# (as configured and open) */
1206 if( (i < 0) || (NR_PORTS <= i) ){
1207 cy_writeb(base_addr+(CySRER<<index),
1208 cy_readb(base_addr+(CySRER<<index)) & ~CyTxRdy);
1209 goto txend;
1210 }
1211 info = &cy_port[i];
1212 info->last_active = jiffies;
1213 if(info->tty == 0){
1214 cy_writeb(base_addr+(CySRER<<index),
1215 cy_readb(base_addr+(CySRER<<index)) & ~CyTxRdy);
1216 goto txdone;
1217 }
1218
1219 /* load the on-chip space for outbound data */
1220 char_count = info->xmit_fifo_size;
1221
1222 if(info->x_char) { /* send special char */
1223 outch = info->x_char;
1224 cy_writeb(base_addr+(CyTDR<<index), outch);
1225 char_count--;
1226 info->icount.tx++;
1227 info->x_char = 0;
1228 }
1229
1230 if (info->breakon || info->breakoff) {
1231 if (info->breakon) {
1232 cy_writeb(base_addr + (CyTDR<<index), 0);
1233 cy_writeb(base_addr + (CyTDR<<index), 0x81);
1234 info->breakon = 0;
1235 char_count -= 2;
1236 }
1237 if (info->breakoff) {
1238 cy_writeb(base_addr + (CyTDR<<index), 0);
1239 cy_writeb(base_addr + (CyTDR<<index), 0x83);
1240 info->breakoff = 0;
1241 char_count -= 2;
1242 }
1243 }
1244
1245 while (char_count-- > 0){
1246 if (!info->xmit_cnt){
1247 if (cy_readb(base_addr+(CySRER<<index))&CyTxMpty) {
1248 cy_writeb(base_addr+(CySRER<<index),
1249 cy_readb(base_addr+(CySRER<<index)) &
1250 ~CyTxMpty);
1251 } else {
1252 cy_writeb(base_addr+(CySRER<<index),
1253 ((cy_readb(base_addr+(CySRER<<index))
1254 & ~CyTxRdy)
1255 | CyTxMpty));
1256 }
1257 goto txdone;
1258 }
1259 if (info->xmit_buf == 0){
1260 cy_writeb(base_addr+(CySRER<<index),
1261 cy_readb(base_addr+(CySRER<<index)) &
1262 ~CyTxRdy);
1263 goto txdone;
1264 }
1265 if (info->tty->stopped || info->tty->hw_stopped){
1266 cy_writeb(base_addr+(CySRER<<index),
1267 cy_readb(base_addr+(CySRER<<index)) &
1268 ~CyTxRdy);
1269 goto txdone;
1270 }
1271 /* Because the Embedded Transmit Commands have
1272 been enabled, we must check to see if the
1273 escape character, NULL, is being sent. If it
1274 is, we must ensure that there is room for it
1275 to be doubled in the output stream. Therefore
1276 we no longer advance the pointer when the
1277 character is fetched, but rather wait until
1278 after the check for a NULL output character.
1279 This is necessary because there may not be
1280 room for the two chars needed to send a NULL.)
1281 */
1282 outch = info->xmit_buf[info->xmit_tail];
1283 if( outch ){
1284 info->xmit_cnt--;
1285 info->xmit_tail = (info->xmit_tail + 1)
1286 & (SERIAL_XMIT_SIZE - 1);
1287 cy_writeb(base_addr+(CyTDR<<index), outch);
1288 info->icount.tx++;
1289 }else{
1290 if(char_count > 1){
1291 info->xmit_cnt--;
1292 info->xmit_tail = (info->xmit_tail + 1)
1293 & (SERIAL_XMIT_SIZE - 1);
1294 cy_writeb(base_addr+(CyTDR<<index),
1295 outch);
1296 cy_writeb(base_addr+(CyTDR<<index), 0);
1297 info->icount.tx++;
1298 char_count--;
1299 }else{
1300 }
1301 }
1302 }
1303
1304txdone:
1305 if (info->xmit_cnt < WAKEUP_CHARS) {
1306 cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
1307 }
1308txend:
1309 /* end of service */
1310 cy_writeb(base_addr+(CyTIR<<index),
1311 (save_xir & 0x3f));
1312 cy_writeb(base_addr+(CyCAR<<index), (save_car));
1313 spin_unlock(&cinfo->card_lock);
1314 }
1315
1316 if (status & CySRModem) { /* modem interrupt */
1317
1318 /* determine the channel & change to that context */
1319 spin_lock(&cinfo->card_lock);
1320 save_xir = (u_char) cy_readb(base_addr+(CyMIR<<index));
1321 channel = (u_short ) (save_xir & CyIRChannel);
1322 info = &cy_port[channel + chip * 4
1323 + cinfo->first_line];
1324 info->last_active = jiffies;
1325 save_car = cy_readb(base_addr+(CyCAR<<index));
1326 cy_writeb(base_addr+(CyCAR<<index), save_xir);
1327
1328 mdm_change = cy_readb(base_addr+(CyMISR<<index));
1329 mdm_status = cy_readb(base_addr+(CyMSVR1<<index));
1330
1331 if(info->tty == 0){/* no place for data, ignore it*/
1332 ;
1333 }else{
1334 if (mdm_change & CyANY_DELTA) {
1335 /* For statistics only */
1336 if (mdm_change & CyDCD) info->icount.dcd++;
1337 if (mdm_change & CyCTS) info->icount.cts++;
1338 if (mdm_change & CyDSR) info->icount.dsr++;
1339 if (mdm_change & CyRI) info->icount.rng++;
1340
1341 cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
1342 }
1343
1344 if((mdm_change & CyDCD)
1345 && (info->flags & ASYNC_CHECK_CD)){
1346 if(mdm_status & CyDCD){
1347 cy_sched_event(info,
1348 Cy_EVENT_OPEN_WAKEUP);
1349 }else{
1350 cy_sched_event(info,
1351 Cy_EVENT_HANGUP);
1352 }
1353 }
1354 if((mdm_change & CyCTS)
1355 && (info->flags & ASYNC_CTS_FLOW)){
1356 if(info->tty->hw_stopped){
1357 if(mdm_status & CyCTS){
1358 /* cy_start isn't used
1359 because... !!! */
1360 info->tty->hw_stopped = 0;
1361 cy_writeb(base_addr+(CySRER<<index),
1362 cy_readb(base_addr+(CySRER<<index)) |
1363 CyTxRdy);
1364 cy_sched_event(info,
1365 Cy_EVENT_WRITE_WAKEUP);
1366 }
1367 }else{
1368 if(!(mdm_status & CyCTS)){
1369 /* cy_stop isn't used
1370 because ... !!! */
1371 info->tty->hw_stopped = 1;
1372 cy_writeb(base_addr+(CySRER<<index),
1373 cy_readb(base_addr+(CySRER<<index)) &
1374 ~CyTxRdy);
1375 }
1376 }
1377 }
1378 if(mdm_change & CyDSR){
1379 }
1380 if(mdm_change & CyRI){
1381 }
1382 }
1383 /* end of service */
1384 cy_writeb(base_addr+(CyMIR<<index),
1385 (save_xir & 0x3f));
1386 cy_writeb(base_addr+(CyCAR<<index), save_car);
1387 spin_unlock(&cinfo->card_lock);
1388 }
1389}
1390
1056/* The real interrupt service routine is called 1391/* The real interrupt service routine is called
1057 whenever the card wants its hand held--chars 1392 whenever the card wants its hand held--chars
1058 received, out buffer empty, modem change, etc. 1393 received, out buffer empty, modem change, etc.
@@ -1060,22 +1395,14 @@ detect_isa_irq(void __iomem *address)
1060static irqreturn_t 1395static irqreturn_t
1061cyy_interrupt(int irq, void *dev_id) 1396cyy_interrupt(int irq, void *dev_id)
1062{ 1397{
1063 struct tty_struct *tty;
1064 int status; 1398 int status;
1065 struct cyclades_card *cinfo; 1399 struct cyclades_card *cinfo;
1066 struct cyclades_port *info;
1067 void __iomem *base_addr, *card_base_addr; 1400 void __iomem *base_addr, *card_base_addr;
1068 int chip; 1401 int chip;
1069 int save_xir, channel, save_car; 1402 int index;
1070 char data;
1071 volatile int char_count;
1072 int outch;
1073 int i,j,index;
1074 int too_many; 1403 int too_many;
1075 int had_work; 1404 int had_work;
1076 int mdm_change; 1405
1077 int mdm_status;
1078 int len;
1079 if((cinfo = (struct cyclades_card *)dev_id) == 0){ 1406 if((cinfo = (struct cyclades_card *)dev_id) == 0){
1080#ifdef CY_DEBUG_INTERRUPTS 1407#ifdef CY_DEBUG_INTERRUPTS
1081 printk("cyy_interrupt: spurious interrupt %d\n\r", irq); 1408 printk("cyy_interrupt: spurious interrupt %d\n\r", irq);
@@ -1107,331 +1434,9 @@ cyy_interrupt(int irq, void *dev_id)
1107 if(1000<too_many++){ 1434 if(1000<too_many++){
1108 break; 1435 break;
1109 } 1436 }
1110 if (status & CySRReceive) { /* reception interrupt */ 1437 cyy_intr_chip(cinfo, chip, base_addr, status, index);
1111#ifdef CY_DEBUG_INTERRUPTS 1438 }
1112 printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip); 1439 }
1113#endif
1114 /* determine the channel & change to that context */
1115 spin_lock(&cinfo->card_lock);
1116 save_xir = (u_char) cy_readb(base_addr+(CyRIR<<index));
1117 channel = (u_short ) (save_xir & CyIRChannel);
1118 i = channel + chip * 4 + cinfo->first_line;
1119 info = &cy_port[i];
1120 info->last_active = jiffies;
1121 save_car = cy_readb(base_addr+(CyCAR<<index));
1122 cy_writeb(base_addr+(CyCAR<<index), save_xir);
1123
1124 /* if there is nowhere to put the data, discard it */
1125 if(info->tty == 0){
1126 j = (cy_readb(base_addr+(CyRIVR<<index)) & CyIVRMask);
1127 if ( j == CyIVRRxEx ) { /* exception */
1128 data = cy_readb(base_addr+(CyRDSR<<index));
1129 } else { /* normal character reception */
1130 char_count = cy_readb(base_addr+(CyRDCR<<index));
1131 while(char_count--){
1132 data = cy_readb(base_addr+(CyRDSR<<index));
1133 }
1134 }
1135 }else{ /* there is an open port for this data */
1136 tty = info->tty;
1137 j = (cy_readb(base_addr+(CyRIVR<<index)) & CyIVRMask);
1138 if ( j == CyIVRRxEx ) { /* exception */
1139 data = cy_readb(base_addr+(CyRDSR<<index));
1140
1141 /* For statistics only */
1142 if (data & CyBREAK)
1143 info->icount.brk++;
1144 else if(data & CyFRAME)
1145 info->icount.frame++;
1146 else if(data & CyPARITY)
1147 info->icount.parity++;
1148 else if(data & CyOVERRUN)
1149 info->icount.overrun++;
1150
1151 if(data & info->ignore_status_mask){
1152 info->icount.rx++;
1153 continue;
1154 }
1155 if (tty_buffer_request_room(tty, 1)) {
1156 if (data & info->read_status_mask){
1157 if(data & CyBREAK){
1158 tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_BREAK);
1159 info->icount.rx++;
1160 if (info->flags & ASYNC_SAK){
1161 do_SAK(tty);
1162 }
1163 }else if(data & CyFRAME){
1164 tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME);
1165 info->icount.rx++;
1166 info->idle_stats.frame_errs++;
1167 }else if(data & CyPARITY){
1168 /* Pieces of seven... */
1169 tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_PARITY);
1170 info->icount.rx++;
1171 info->idle_stats.parity_errs++;
1172 }else if(data & CyOVERRUN){
1173 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
1174 info->icount.rx++;
1175 /* If the flip buffer itself is
1176 overflowing, we still lose
1177 the next incoming character.
1178 */
1179 tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME);
1180 info->icount.rx++;
1181 info->idle_stats.overruns++;
1182 /* These two conditions may imply */
1183 /* a normal read should be done. */
1184 /* }else if(data & CyTIMEOUT){ */
1185 /* }else if(data & CySPECHAR){ */
1186 }else {
1187 tty_insert_flip_char(tty, 0, TTY_NORMAL);
1188 info->icount.rx++;
1189 }
1190 }else{
1191 tty_insert_flip_char(tty, 0, TTY_NORMAL);
1192 info->icount.rx++;
1193 }
1194 }else{
1195 /* there was a software buffer
1196 overrun and nothing could be
1197 done about it!!! */
1198 info->icount.buf_overrun++;
1199 info->idle_stats.overruns++;
1200 }
1201 } else { /* normal character reception */
1202 /* load # chars available from the chip */
1203 char_count = cy_readb(base_addr+(CyRDCR<<index));
1204
1205#ifdef CY_ENABLE_MONITORING
1206 ++info->mon.int_count;
1207 info->mon.char_count += char_count;
1208 if (char_count > info->mon.char_max)
1209 info->mon.char_max = char_count;
1210 info->mon.char_last = char_count;
1211#endif
1212 len = tty_buffer_request_room(tty, char_count);
1213 while(len--){
1214 data = cy_readb(base_addr+(CyRDSR<<index));
1215 tty_insert_flip_char(tty, data, TTY_NORMAL);
1216 info->idle_stats.recv_bytes++;
1217 info->icount.rx++;
1218#ifdef CY_16Y_HACK
1219 udelay(10L);
1220#endif
1221 }
1222 info->idle_stats.recv_idle = jiffies;
1223 }
1224 tty_schedule_flip(tty);
1225 }
1226 /* end of service */
1227 cy_writeb(base_addr+(CyRIR<<index), (save_xir & 0x3f));
1228 cy_writeb(base_addr+(CyCAR<<index), (save_car));
1229 spin_unlock(&cinfo->card_lock);
1230 }
1231
1232
1233 if (status & CySRTransmit) { /* transmission interrupt */
1234 /* Since we only get here when the transmit buffer
1235 is empty, we know we can always stuff a dozen
1236 characters. */
1237#ifdef CY_DEBUG_INTERRUPTS
1238 printk("cyy_interrupt: xmit intr, chip %d\n\r", chip);
1239#endif
1240
1241 /* determine the channel & change to that context */
1242 spin_lock(&cinfo->card_lock);
1243 save_xir = (u_char) cy_readb(base_addr+(CyTIR<<index));
1244 channel = (u_short ) (save_xir & CyIRChannel);
1245 i = channel + chip * 4 + cinfo->first_line;
1246 save_car = cy_readb(base_addr+(CyCAR<<index));
1247 cy_writeb(base_addr+(CyCAR<<index), save_xir);
1248
1249 /* validate the port# (as configured and open) */
1250 if( (i < 0) || (NR_PORTS <= i) ){
1251 cy_writeb(base_addr+(CySRER<<index),
1252 cy_readb(base_addr+(CySRER<<index)) & ~CyTxRdy);
1253 goto txend;
1254 }
1255 info = &cy_port[i];
1256 info->last_active = jiffies;
1257 if(info->tty == 0){
1258 cy_writeb(base_addr+(CySRER<<index),
1259 cy_readb(base_addr+(CySRER<<index)) & ~CyTxRdy);
1260 goto txdone;
1261 }
1262
1263 /* load the on-chip space for outbound data */
1264 char_count = info->xmit_fifo_size;
1265
1266 if(info->x_char) { /* send special char */
1267 outch = info->x_char;
1268 cy_writeb(base_addr+(CyTDR<<index), outch);
1269 char_count--;
1270 info->icount.tx++;
1271 info->x_char = 0;
1272 }
1273
1274 if (info->breakon || info->breakoff) {
1275 if (info->breakon) {
1276 cy_writeb(base_addr + (CyTDR<<index), 0);
1277 cy_writeb(base_addr + (CyTDR<<index), 0x81);
1278 info->breakon = 0;
1279 char_count -= 2;
1280 }
1281 if (info->breakoff) {
1282 cy_writeb(base_addr + (CyTDR<<index), 0);
1283 cy_writeb(base_addr + (CyTDR<<index), 0x83);
1284 info->breakoff = 0;
1285 char_count -= 2;
1286 }
1287 }
1288
1289 while (char_count-- > 0){
1290 if (!info->xmit_cnt){
1291 if (cy_readb(base_addr+(CySRER<<index))&CyTxMpty) {
1292 cy_writeb(base_addr+(CySRER<<index),
1293 cy_readb(base_addr+(CySRER<<index)) &
1294 ~CyTxMpty);
1295 } else {
1296 cy_writeb(base_addr+(CySRER<<index),
1297 ((cy_readb(base_addr+(CySRER<<index))
1298 & ~CyTxRdy)
1299 | CyTxMpty));
1300 }
1301 goto txdone;
1302 }
1303 if (info->xmit_buf == 0){
1304 cy_writeb(base_addr+(CySRER<<index),
1305 cy_readb(base_addr+(CySRER<<index)) &
1306 ~CyTxRdy);
1307 goto txdone;
1308 }
1309 if (info->tty->stopped || info->tty->hw_stopped){
1310 cy_writeb(base_addr+(CySRER<<index),
1311 cy_readb(base_addr+(CySRER<<index)) &
1312 ~CyTxRdy);
1313 goto txdone;
1314 }
1315 /* Because the Embedded Transmit Commands have
1316 been enabled, we must check to see if the
1317 escape character, NULL, is being sent. If it
1318 is, we must ensure that there is room for it
1319 to be doubled in the output stream. Therefore
1320 we no longer advance the pointer when the
1321 character is fetched, but rather wait until
1322 after the check for a NULL output character.
1323 This is necessary because there may not be
1324 room for the two chars needed to send a NULL.)
1325 */
1326 outch = info->xmit_buf[info->xmit_tail];
1327 if( outch ){
1328 info->xmit_cnt--;
1329 info->xmit_tail = (info->xmit_tail + 1)
1330 & (SERIAL_XMIT_SIZE - 1);
1331 cy_writeb(base_addr+(CyTDR<<index), outch);
1332 info->icount.tx++;
1333 }else{
1334 if(char_count > 1){
1335 info->xmit_cnt--;
1336 info->xmit_tail = (info->xmit_tail + 1)
1337 & (SERIAL_XMIT_SIZE - 1);
1338 cy_writeb(base_addr+(CyTDR<<index),
1339 outch);
1340 cy_writeb(base_addr+(CyTDR<<index), 0);
1341 info->icount.tx++;
1342 char_count--;
1343 }else{
1344 }
1345 }
1346 }
1347
1348 txdone:
1349 if (info->xmit_cnt < WAKEUP_CHARS) {
1350 cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
1351 }
1352 txend:
1353 /* end of service */
1354 cy_writeb(base_addr+(CyTIR<<index),
1355 (save_xir & 0x3f));
1356 cy_writeb(base_addr+(CyCAR<<index), (save_car));
1357 spin_unlock(&cinfo->card_lock);
1358 }
1359
1360 if (status & CySRModem) { /* modem interrupt */
1361
1362 /* determine the channel & change to that context */
1363 spin_lock(&cinfo->card_lock);
1364 save_xir = (u_char) cy_readb(base_addr+(CyMIR<<index));
1365 channel = (u_short ) (save_xir & CyIRChannel);
1366 info = &cy_port[channel + chip * 4
1367 + cinfo->first_line];
1368 info->last_active = jiffies;
1369 save_car = cy_readb(base_addr+(CyCAR<<index));
1370 cy_writeb(base_addr+(CyCAR<<index), save_xir);
1371
1372 mdm_change = cy_readb(base_addr+(CyMISR<<index));
1373 mdm_status = cy_readb(base_addr+(CyMSVR1<<index));
1374
1375 if(info->tty == 0){/* no place for data, ignore it*/
1376 ;
1377 }else{
1378 if (mdm_change & CyANY_DELTA) {
1379 /* For statistics only */
1380 if (mdm_change & CyDCD) info->icount.dcd++;
1381 if (mdm_change & CyCTS) info->icount.cts++;
1382 if (mdm_change & CyDSR) info->icount.dsr++;
1383 if (mdm_change & CyRI) info->icount.rng++;
1384
1385 cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
1386 }
1387
1388 if((mdm_change & CyDCD)
1389 && (info->flags & ASYNC_CHECK_CD)){
1390 if(mdm_status & CyDCD){
1391 cy_sched_event(info,
1392 Cy_EVENT_OPEN_WAKEUP);
1393 }else{
1394 cy_sched_event(info,
1395 Cy_EVENT_HANGUP);
1396 }
1397 }
1398 if((mdm_change & CyCTS)
1399 && (info->flags & ASYNC_CTS_FLOW)){
1400 if(info->tty->hw_stopped){
1401 if(mdm_status & CyCTS){
1402 /* cy_start isn't used
1403 because... !!! */
1404 info->tty->hw_stopped = 0;
1405 cy_writeb(base_addr+(CySRER<<index),
1406 cy_readb(base_addr+(CySRER<<index)) |
1407 CyTxRdy);
1408 cy_sched_event(info,
1409 Cy_EVENT_WRITE_WAKEUP);
1410 }
1411 }else{
1412 if(!(mdm_status & CyCTS)){
1413 /* cy_stop isn't used
1414 because ... !!! */
1415 info->tty->hw_stopped = 1;
1416 cy_writeb(base_addr+(CySRER<<index),
1417 cy_readb(base_addr+(CySRER<<index)) &
1418 ~CyTxRdy);
1419 }
1420 }
1421 }
1422 if(mdm_change & CyDSR){
1423 }
1424 if(mdm_change & CyRI){
1425 }
1426 }
1427 /* end of service */
1428 cy_writeb(base_addr+(CyMIR<<index),
1429 (save_xir & 0x3f));
1430 cy_writeb(base_addr+(CyCAR<<index), save_car);
1431 spin_unlock(&cinfo->card_lock);
1432 }
1433 } /* end while status != 0 */
1434 } /* end loop for chips... */
1435 } while(had_work); 1440 } while(had_work);
1436 1441
1437 /* clear interrupts */ 1442 /* clear interrupts */