si.c (10018) | si.c (10044) |
---|---|
1/* 2 * Device driver for Specialix range (SLXOS) of serial line multiplexors. 3 * 4 * Copyright (C) 1990, 1992 Specialix International, 5 * Copyright (C) 1993, Andy Rutter <andy@acronym.co.uk> 6 * Copyright (C) 1995, Peter Wemm <peter@haywire.dialix.com> 7 * 8 * Originally derived from: SunOS 4.x version --- 16 unchanged lines hidden (view full) --- 25 * International may be used to endorse or promote products derived from 26 * this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 30 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 31 * NO EVENT SHALL THE AUTHORS BE LIABLE. 32 * | 1/* 2 * Device driver for Specialix range (SLXOS) of serial line multiplexors. 3 * 4 * Copyright (C) 1990, 1992 Specialix International, 5 * Copyright (C) 1993, Andy Rutter <andy@acronym.co.uk> 6 * Copyright (C) 1995, Peter Wemm <peter@haywire.dialix.com> 7 * 8 * Originally derived from: SunOS 4.x version --- 16 unchanged lines hidden (view full) --- 25 * International may be used to endorse or promote products derived from 26 * this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 30 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 31 * NO EVENT SHALL THE AUTHORS BE LIABLE. 32 * |
33 * $Id: si.c,v 1.1 1995/08/09 13:13:46 peter Exp $ | 33 * $Id: si.c,v 1.2 1995/08/10 08:48:34 peter Exp $ |
34 */ 35 36#ifndef lint 37static char si_copyright1[] = "@(#) (C) Specialix International, 1990,1992", 38 si_copyright2[] = "@(#) (C) Andy Rutter 1993", 39 si_copyright3[] = "@(#) (C) Peter Wemm 1995"; 40#endif /* not lint */ 41 --- 30 unchanged lines hidden (view full) --- 72/* 73 * This device driver is designed to interface the Specialix International 74 * range of serial multiplexor cards (SLXOS) to BSDI/386 on an ISA bus machine. 75 * 76 * The controller is interfaced to the host via dual port ram 77 * and a (programmable - SIHOST2) interrupt at IRQ 11,12 or 15. 78 */ 79 | 34 */ 35 36#ifndef lint 37static char si_copyright1[] = "@(#) (C) Specialix International, 1990,1992", 38 si_copyright2[] = "@(#) (C) Andy Rutter 1993", 39 si_copyright3[] = "@(#) (C) Peter Wemm 1995"; 40#endif /* not lint */ 41 --- 30 unchanged lines hidden (view full) --- 72/* 73 * This device driver is designed to interface the Specialix International 74 * range of serial multiplexor cards (SLXOS) to BSDI/386 on an ISA bus machine. 75 * 76 * The controller is interfaced to the host via dual port ram 77 * and a (programmable - SIHOST2) interrupt at IRQ 11,12 or 15. 78 */ 79 |
80#define DEF_IXANY SPF_IXANY /* allow IXANY in t_iflag to work */ | |
81#define POLL /* turn on poller to generate buffer empty interrupt */ 82#define SI_I_HIGH_WATER (TTYHOG - SLXOS_BUFFERSIZE) 83 84enum si_mctl { GET, SET, BIS, BIC }; 85 86static void si_command __P((struct si_port *, int, int)); 87static int si_modem __P((struct si_port *, enum si_mctl, int)); 88static void si_write_enable __P((struct si_port *, int)); --- 13 unchanged lines hidden (view full) --- 102static int si_Nports = 0; 103static int si_Nmodules = 0; 104static int si_debug = 0; 105 106/* where the firmware lives */ 107extern int si_dsize; 108extern unsigned char si_download[]; 109 | 80#define POLL /* turn on poller to generate buffer empty interrupt */ 81#define SI_I_HIGH_WATER (TTYHOG - SLXOS_BUFFERSIZE) 82 83enum si_mctl { GET, SET, BIS, BIC }; 84 85static void si_command __P((struct si_port *, int, int)); 86static int si_modem __P((struct si_port *, enum si_mctl, int)); 87static void si_write_enable __P((struct si_port *, int)); --- 13 unchanged lines hidden (view full) --- 101static int si_Nports = 0; 102static int si_Nmodules = 0; 103static int si_debug = 0; 104 105/* where the firmware lives */ 106extern int si_dsize; 107extern unsigned char si_download[]; 108 |
110struct si_softc si_softc[NSI]; /* 4 elements */ | 109struct si_softc { 110 struct device sc_dev; /* base device */ |
111 | 111 |
112 int sc_type; /* adapter type */ 113 char *sc_typename; /* adapter type string */ 114 115 struct si_port *sc_ports; /* port structures for this card */ 116 117 caddr_t sc_paddr; /* physical addr of iomem */ 118 caddr_t sc_maddr; /* kvaddr of iomem */ 119 int sc_nport; /* # ports on this card */ 120 int sc_irq; /* copy of attach irq */ 121 int sc_eisa_iobase; /* EISA io port address */ 122 int sc_eisa_irqbits; 123 struct kern_devconf sc_kdc; 124}; 125struct si_softc si_softc[NSI]; /* up to 4 elements */ 126 |
|
112#ifndef B2000 /* not standard */ 113# define B2000 2000 114#endif 115static struct speedtab bdrates[] = { 116 B75, CLK75, /* 0x0 */ 117 B110, CLK110, /* 0x1 */ 118 B150, CLK150, /* 0x3 */ 119 B300, CLK300, /* 0x4 */ --- 27 unchanged lines hidden (view full) --- 147 B9600, 960, 148 B19200, 1920, 149 B38400, 3840, 150 B57600, 5760, 151 B115200, 11520, 152 -1, -1 153}; 154static volatile int in_intr = 0; /* Inside interrupt handler? */ | 127#ifndef B2000 /* not standard */ 128# define B2000 2000 129#endif 130static struct speedtab bdrates[] = { 131 B75, CLK75, /* 0x0 */ 132 B110, CLK110, /* 0x1 */ 133 B150, CLK150, /* 0x3 */ 134 B300, CLK300, /* 0x4 */ --- 27 unchanged lines hidden (view full) --- 162 B9600, 960, 163 B19200, 1920, 164 B38400, 3840, 165 B57600, 5760, 166 B115200, 11520, 167 -1, -1 168}; 169static volatile int in_intr = 0; /* Inside interrupt handler? */ |
155static int buffer_space = 128; /* Amount of free buffer space 156 which must be available before 157 the writer is unblocked */ | |
158static int sidefaultrate = TTYDEF_SPEED; 159 160#ifdef POLL 161#define POLL_INTERVAL (hz/2) 162static int init_finished = 0; 163static void si_poll __P((void *)); 164#endif 165 --- 404 unchanged lines hidden (view full) --- 570 case M422: 571 nmodule++; 572 nport = (modp->sm_type & MMASK); 573 ccbp = (struct si_channel *)((char *)modp+0x100); 574 for (x = 0; x < nport; x++, pp++, ccbp++) { 575 pp->sp_ccb = ccbp; /* save the address */ 576 pp->sp_tty = tp++; 577 pp->sp_pend = IDLE_CLOSE; | 170static int sidefaultrate = TTYDEF_SPEED; 171 172#ifdef POLL 173#define POLL_INTERVAL (hz/2) 174static int init_finished = 0; 175static void si_poll __P((void *)); 176#endif 177 --- 404 unchanged lines hidden (view full) --- 582 case M422: 583 nmodule++; 584 nport = (modp->sm_type & MMASK); 585 ccbp = (struct si_channel *)((char *)modp+0x100); 586 for (x = 0; x < nport; x++, pp++, ccbp++) { 587 pp->sp_ccb = ccbp; /* save the address */ 588 pp->sp_tty = tp++; 589 pp->sp_pend = IDLE_CLOSE; |
578 pp->sp_flags = DEF_IXANY; | 590 pp->sp_flags = 0; |
579 pp->sp_state = 0; /* internal flag */ 580 pp->sp_dtr_wait = 3 * hz; 581 pp->sp_iin.c_iflag = 0; 582 pp->sp_iin.c_oflag = 0; 583 pp->sp_iin.c_cflag = TTYDEF_CFLAG; 584 pp->sp_iin.c_lflag = 0; 585 termioschars(&pp->sp_iin); 586 pp->sp_iin.c_ispeed = pp->sp_iin.c_ospeed = --- 578 unchanged lines hidden (view full) --- 1165 */ 1166static int 1167si_Sioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) 1168{ 1169 struct si_softc *xsc; 1170 register struct si_port *xpp; 1171 volatile struct si_reg *regp; 1172 struct si_tcsi *dp; | 591 pp->sp_state = 0; /* internal flag */ 592 pp->sp_dtr_wait = 3 * hz; 593 pp->sp_iin.c_iflag = 0; 594 pp->sp_iin.c_oflag = 0; 595 pp->sp_iin.c_cflag = TTYDEF_CFLAG; 596 pp->sp_iin.c_lflag = 0; 597 termioschars(&pp->sp_iin); 598 pp->sp_iin.c_ispeed = pp->sp_iin.c_ospeed = --- 578 unchanged lines hidden (view full) --- 1177 */ 1178static int 1179si_Sioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) 1180{ 1181 struct si_softc *xsc; 1182 register struct si_port *xpp; 1183 volatile struct si_reg *regp; 1184 struct si_tcsi *dp; |
1185 struct si_pstat *sps; |
|
1173 BYTE *bp; 1174 int i, *ip, error = 0; 1175 int oldspl; 1176 int card, port; 1177 unsigned short *usp; 1178 int mynor = minor(dev); 1179 1180 DPRINT((0, DBG_ENTRY|DBG_IOCTL, "si_Sioctl(%x,%x,%x,%x)\n", 1181 dev, cmd, data, flag)); 1182 | 1186 BYTE *bp; 1187 int i, *ip, error = 0; 1188 int oldspl; 1189 int card, port; 1190 unsigned short *usp; 1191 int mynor = minor(dev); 1192 1193 DPRINT((0, DBG_ENTRY|DBG_IOCTL, "si_Sioctl(%x,%x,%x,%x)\n", 1194 dev, cmd, data, flag)); 1195 |
1196#if 1 1197 DPRINT((0, DBG_IOCTL, "TCSI_PORT=%x\n", TCSI_PORT)); 1198 DPRINT((0, DBG_IOCTL, "TCSI_CCB=%x\n", TCSI_CCB)); 1199 DPRINT((0, DBG_IOCTL, "TCSI_TTY=%x\n", TCSI_TTY)); 1200#endif 1201 |
|
1183 if (!IS_CONTROLDEV(mynor)) { 1184 DPRINT((0, DBG_IOCTL|DBG_FAIL, "not called from control device!\n")); 1185 return(ENODEV); 1186 } 1187 1188 oldspl = spltty(); /* better safe than sorry */ 1189 1190 ip = (int *)data; --- 13 unchanged lines hidden (view full) --- 1204 goto out; 1205 case TCSIGDBG_ALL: 1206 *ip = si_debug; 1207 goto out; 1208 default: 1209 /* 1210 * Check that a controller for this port exists 1211 */ | 1202 if (!IS_CONTROLDEV(mynor)) { 1203 DPRINT((0, DBG_IOCTL|DBG_FAIL, "not called from control device!\n")); 1204 return(ENODEV); 1205 } 1206 1207 oldspl = spltty(); /* better safe than sorry */ 1208 1209 ip = (int *)data; --- 13 unchanged lines hidden (view full) --- 1223 goto out; 1224 case TCSIGDBG_ALL: 1225 *ip = si_debug; 1226 goto out; 1227 default: 1228 /* 1229 * Check that a controller for this port exists 1230 */ |
1231 1232 /* may also be a struct si_pstat, a superset of si_tcsi */ 1233 |
|
1212 dp = (struct si_tcsi *)data; | 1234 dp = (struct si_tcsi *)data; |
1235 sps = (struct si_pstat *)data; |
|
1213 card = dp->tc_card; 1214 xsc = &si_softc[card]; /* check.. */ 1215 if (card < 0 || card >= NSI || xsc->sc_type == NULL) { 1216 error = ENOENT; 1217 goto out; 1218 } 1219 /* 1220 * And check that a port exists --- 46 unchanged lines hidden (view full) --- 1267 break; 1268 case TCSIGIT: 1269 dp->tc_int = regp->int_count; 1270 break; 1271 case TCSIIT: 1272 SUCHECK; 1273 regp->int_count = dp->tc_int; 1274 break; | 1236 card = dp->tc_card; 1237 xsc = &si_softc[card]; /* check.. */ 1238 if (card < 0 || card >= NSI || xsc->sc_type == NULL) { 1239 error = ENOENT; 1240 goto out; 1241 } 1242 /* 1243 * And check that a port exists --- 46 unchanged lines hidden (view full) --- 1290 break; 1291 case TCSIGIT: 1292 dp->tc_int = regp->int_count; 1293 break; 1294 case TCSIIT: 1295 SUCHECK; 1296 regp->int_count = dp->tc_int; 1297 break; |
1275 case TCSIGMIN: 1276 dp->tc_int = buffer_space; | 1298 case TCSISTATE: 1299 dp->tc_int = xpp->sp_ccb->hi_ip; |
1277 break; | 1300 break; |
1278 case TCSIMIN: | 1301 /* these next three use a different structure */ 1302 case TCSI_PORT: |
1279 SUCHECK; | 1303 SUCHECK; |
1280 buffer_space = dp->tc_int; | 1304 sps->tc_siport = *xpp; |
1281 break; | 1305 break; |
1282 case TCSIIXANY: 1283 switch (dp->tc_int) { 1284 case -1: 1285 dp->tc_int = (xpp->sp_flags & SPF_IXANY)?1:0; 1286 break; 1287 case 1: 1288 SUCHECK; 1289 xpp->sp_flags |= SPF_IXANY; 1290 break; 1291 case 0: 1292 SUCHECK; 1293 xpp->sp_flags &= ~SPF_IXANY; 1294 break; 1295 default: 1296 error = EINVAL; 1297 goto out; 1298 } | 1306 case TCSI_CCB: 1307 SUCHECK; 1308 sps->tc_ccb = *xpp->sp_ccb; |
1299 break; | 1309 break; |
1300 case TCSIFLOW: 1301 i = dp->tc_int; 1302 if (i == -1) 1303 dp->tc_int = xpp->sp_flags & (SPF_CTSOFLOW|SPF_RTSIFLOW); 1304 else { 1305 SUCHECK; 1306 if (i & ~(SPF_CTSOFLOW|SPF_RTSIFLOW) != 0) { 1307 error = EINVAL; 1308 goto out; 1309 } 1310 if (i & SPF_CTSOFLOW) 1311 xpp->sp_flags |= SPF_CTSOFLOW; 1312 else 1313 xpp->sp_flags &= ~SPF_CTSOFLOW; 1314 if (i & SPF_RTSIFLOW) 1315 xpp->sp_flags |= SPF_RTSIFLOW; 1316 else 1317 xpp->sp_flags &= ~SPF_RTSIFLOW; 1318 } | 1310 case TCSI_TTY: 1311 SUCHECK; 1312 sps->tc_tty = *xpp->sp_tty; |
1319 break; | 1313 break; |
1320 case TCSISTATE: 1321 dp->tc_int = xpp->sp_ccb->hi_ip; 1322 break; 1323 case TCSIPPP: 1324 switch (dp->tc_int) { 1325 case -1: 1326 dp->tc_int = (xpp->sp_flags & SPF_PPP)?1:0; 1327 break; 1328 case 1: 1329 SUCHECK; 1330 xpp->sp_flags |= SPF_PPP; 1331 break; 1332 case 0: 1333 SUCHECK; 1334 xpp->sp_flags &= ~SPF_PPP; 1335 break; 1336 default: 1337 error = EINVAL; 1338 goto out; 1339 } 1340 break; | |
1341 default: 1342 error = EINVAL; 1343 goto out; 1344 } 1345out: 1346 splx(oldspl); 1347 return(error); /* success */ 1348} --- 16 unchanged lines hidden (view full) --- 1365 int ispeed = 0; /* shutup gcc */ 1366 int ospeed = 0; /* shutup gcc */ 1367 1368 DPRINT((pp, DBG_ENTRY|DBG_PARAM, "siparam(%x,%x)\n", tp, t)); 1369 cflag = t->c_cflag; 1370 iflag = t->c_iflag; 1371 oflag = t->c_oflag; 1372 lflag = t->c_lflag; | 1314 default: 1315 error = EINVAL; 1316 goto out; 1317 } 1318out: 1319 splx(oldspl); 1320 return(error); /* success */ 1321} --- 16 unchanged lines hidden (view full) --- 1338 int ispeed = 0; /* shutup gcc */ 1339 int ospeed = 0; /* shutup gcc */ 1340 1341 DPRINT((pp, DBG_ENTRY|DBG_PARAM, "siparam(%x,%x)\n", tp, t)); 1342 cflag = t->c_cflag; 1343 iflag = t->c_iflag; 1344 oflag = t->c_oflag; 1345 lflag = t->c_lflag; |
1373 DPRINT((pp, DBG_PARAM, "OFLAG 0x%x CFLAG 0x%x IFLAG 0x%x\n", 1374 t->c_oflag, cflag, iflag)); | 1346 DPRINT((pp, DBG_PARAM, "OFLAG 0x%x CFLAG 0x%x IFLAG 0x%x LFLAG 0x%x\n", 1347 oflag, cflag, iflag, lflag)); |
1375 1376 1377 /* if not hung up.. */ 1378 if (t->c_ospeed != 0) { 1379 /* translate baud rate to firmware values */ 1380 ospeed = ttspeedtab(t->c_ospeed, bdrates); 1381 ispeed = t->c_ispeed ? 1382 ttspeedtab(t->c_ispeed, bdrates) : ospeed; --- 60 unchanged lines hidden (view full) --- 1443 1444 /* XXX: the card handles all the flow control... */ 1445 ccbp->hi_txon = t->c_cc[VSTART]; 1446 ccbp->hi_txoff = t->c_cc[VSTOP]; 1447 1448 ccbp->hi_rxon = t->c_cc[VSTART]; 1449 ccbp->hi_rxoff = t->c_cc[VSTOP]; 1450 | 1348 1349 1350 /* if not hung up.. */ 1351 if (t->c_ospeed != 0) { 1352 /* translate baud rate to firmware values */ 1353 ospeed = ttspeedtab(t->c_ospeed, bdrates); 1354 ispeed = t->c_ispeed ? 1355 ttspeedtab(t->c_ispeed, bdrates) : ospeed; --- 60 unchanged lines hidden (view full) --- 1416 1417 /* XXX: the card handles all the flow control... */ 1418 ccbp->hi_txon = t->c_cc[VSTART]; 1419 ccbp->hi_txoff = t->c_cc[VSTOP]; 1420 1421 ccbp->hi_rxon = t->c_cc[VSTART]; 1422 ccbp->hi_rxoff = t->c_cc[VSTOP]; 1423 |
1451 if ((iflag & IXANY) && pp->sp_flags&SPF_IXANY) | 1424 if (iflag & IXANY) |
1452 ccbp->hi_prtcl |= SP_TANY; 1453 if (iflag & IXON) 1454 ccbp->hi_prtcl |= SP_TXEN; 1455 if (iflag & IXOFF) 1456 ccbp->hi_prtcl |= SP_RXEN; 1457 if (iflag & INPCK) 1458 ccbp->hi_prtcl |= SP_PAEN; 1459 1460 /* 1461 * Enable H/W RTS/CTS handshaking. The default TA/MTA is 1462 * a DCE, hence the reverse sense of RTS and CTS 1463 */ 1464 1465 /* Output - RTS must be raised before data can be sent */ | 1425 ccbp->hi_prtcl |= SP_TANY; 1426 if (iflag & IXON) 1427 ccbp->hi_prtcl |= SP_TXEN; 1428 if (iflag & IXOFF) 1429 ccbp->hi_prtcl |= SP_RXEN; 1430 if (iflag & INPCK) 1431 ccbp->hi_prtcl |= SP_PAEN; 1432 1433 /* 1434 * Enable H/W RTS/CTS handshaking. The default TA/MTA is 1435 * a DCE, hence the reverse sense of RTS and CTS 1436 */ 1437 1438 /* Output - RTS must be raised before data can be sent */ |
1466 if (cflag & CCTS_OFLOW || pp->sp_flags&SPF_CTSOFLOW) | 1439 if (cflag & CCTS_OFLOW) |
1467 ccbp->hi_mr2 |= MR2_RTSCONT; 1468 /* Input - CTS is raised when port is ready to receive data */ | 1440 ccbp->hi_mr2 |= MR2_RTSCONT; 1441 /* Input - CTS is raised when port is ready to receive data */ |
1469 if (cflag & CRTS_IFLOW || pp->sp_flags&SPF_RTSIFLOW) | 1442 if (cflag & CRTS_IFLOW) |
1470 ccbp->hi_mr1 |= MR1_CTSCONT; 1471 1472 /* potential sleep here */ 1473 if (ccbp->hi_stat == IDLE_CLOSE) /* Not yet open */ 1474 si_command(pp, LOPEN, SI_WAIT); /* open it */ 1475 else 1476 si_command(pp, CONFIG, SI_WAIT); /* change params */ 1477 1478 /* Hangup if ospeed == 0 */ 1479 if (t->c_ospeed == 0) { 1480 (void) si_modem(pp, BIC, TIOCM_DTR|TIOCM_RTS); 1481 } else { 1482 /* 1483 * If the previous speed was 0, may need to re-enable 1484 * the modem signals 1485 */ 1486 (void) si_modem(pp, SET, TIOCM_DTR|TIOCM_RTS); 1487 } 1488 | 1443 ccbp->hi_mr1 |= MR1_CTSCONT; 1444 1445 /* potential sleep here */ 1446 if (ccbp->hi_stat == IDLE_CLOSE) /* Not yet open */ 1447 si_command(pp, LOPEN, SI_WAIT); /* open it */ 1448 else 1449 si_command(pp, CONFIG, SI_WAIT); /* change params */ 1450 1451 /* Hangup if ospeed == 0 */ 1452 if (t->c_ospeed == 0) { 1453 (void) si_modem(pp, BIC, TIOCM_DTR|TIOCM_RTS); 1454 } else { 1455 /* 1456 * If the previous speed was 0, may need to re-enable 1457 * the modem signals 1458 */ 1459 (void) si_modem(pp, SET, TIOCM_DTR|TIOCM_RTS); 1460 } 1461 |
1489 DPRINT((pp, DBG_PARAM, "siparam, config completed ok MR1 %x MR2 %x\n", 1490 ccbp->hi_mr1, ccbp->hi_mr2)); | 1462 DPRINT((pp, DBG_PARAM, "siparam, complete: MR1 %x MR2 %x HI_MASK %x PRTCL %x HI_BREAK %x\n", 1463 ccbp->hi_mr1, ccbp->hi_mr2, ccbp->hi_mask, ccbp->hi_prtcl, ccbp->hi_break)); |
1491 1492 splx(oldspl); 1493out: 1494 return(error); 1495} 1496 1497/* 1498 * Wait for buffered TX characters to drain away. --- 752 unchanged lines hidden --- | 1464 1465 splx(oldspl); 1466out: 1467 return(error); 1468} 1469 1470/* 1471 * Wait for buffered TX characters to drain away. --- 752 unchanged lines hidden --- |