|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1985, 1986 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)dmz.c 7.9 (Berkeley) 4/12/90 ! 7: */ ! 8: ! 9: /* ! 10: * DMZ-32 driver ! 11: */ ! 12: ! 13: #include "dmz.h" ! 14: #if NDMZ > 0 ! 15: ! 16: #include "machine/pte.h" ! 17: ! 18: #include "uba.h" ! 19: #include "param.h" ! 20: #include "conf.h" ! 21: #include "user.h" ! 22: #include "proc.h" ! 23: #include "ioctl.h" ! 24: #include "tty.h" ! 25: #include "map.h" ! 26: #include "buf.h" ! 27: #include "vm.h" ! 28: #include "bkmac.h" ! 29: #include "clist.h" ! 30: #include "file.h" ! 31: #include "uio.h" ! 32: #include "kernel.h" ! 33: #include "syslog.h" ! 34: ! 35: #include "dmx.h" ! 36: #include "ubareg.h" ! 37: #include "ubavar.h" ! 38: #include "dmxreg.h" ! 39: #include "dmzreg.h" ! 40: #include "dmreg.h" ! 41: ! 42: extern int dmx_timeout; /* silo timeout, in ms */ ! 43: int dmzstart(); ! 44: ! 45: /* ! 46: * The clist space is mapped by one terminal driver onto each UNIBUS. ! 47: * The identity of the board which allocated resources is recorded, ! 48: * so the process may be repeated after UNIBUS resets. ! 49: * The UBACVT macro converts a clist space address for unibus uban ! 50: * into an i/o space address for the DMA routine. ! 51: */ ! 52: int dmz_uballoc[NUBA]; /* which dmz (if any) allocated unibus map */ ! 53: int cbase[NUBA]; /* base address of clists in unibus map */ ! 54: ! 55: /* ! 56: * Autoconfiguration and variables for DMZ32 ! 57: */ ! 58: int dmzprobe(), dmzattach(); ! 59: struct uba_device *dmzinfo[NDMZ]; ! 60: u_short dmzstd[] = { 0 }; ! 61: struct uba_driver dmzdriver = { ! 62: dmzprobe, 0, dmzattach, 0, dmzstd, "dmz", dmzinfo ! 63: }; ! 64: ! 65: struct tty dmz_tty[NDMZ*24]; ! 66: struct dmx_softc dmz_softc[3 * NDMZ]; ! 67: #ifndef lint ! 68: int ndmz = NDMZ*24; /* used by iostat */ ! 69: #endif ! 70: ! 71: dmzprobe(reg) ! 72: caddr_t reg; ! 73: { ! 74: register int br, cvec; ! 75: register struct dmzdevice *dmz_addr; ! 76: register unsigned int a; ! 77: ! 78: dmz_addr = (struct dmzdevice *)reg; ! 79: ! 80: #ifdef lint ! 81: br = 0; cvec = br; br = cvec; dmzxinta(0); dmzxintb(0); dmzxintc(0); ! 82: dmzrinta(0); dmzrintb(0); dmzrintc(0); ! 83: #endif ! 84: ! 85: br = 0x15; ! 86: ! 87: a = dmz_addr->dmz_config; ! 88: if (((a>>12) & ~DMZ_INTERFACE) != 0) { ! 89: printf(" Unknown interface type\n"); ! 90: return (0); ! 91: } ! 92: if (((a>>8) & DMZ_NOC_MASK) != 3) { ! 93: printf(" Not all octets are available\n"); ! 94: return (0); ! 95: } ! 96: ! 97: cvec = (uba_hd[numuba].uh_lastiv -= 4 * 6); ! 98: dmz_addr->dmz_config = cvec >> 2; ! 99: ! 100: return (sizeof(struct dmzdevice)); ! 101: } ! 102: ! 103: dmzattach(ui) ! 104: register struct uba_device *ui; ! 105: { ! 106: register struct dmx_softc *sc; ! 107: register int i; ! 108: ! 109: sc = &dmz_softc[3 * ui->ui_unit]; ! 110: for (i = 0; i < 3; i++, sc++) { ! 111: sc->dmx_type = 'z'; ! 112: sc->dmx_unit = ui->ui_unit; ! 113: sc->dmx_unit0 = 8 * i; ! 114: sc->dmx_ubanum = ui->ui_ubanum; ! 115: sc->dmx_softCAR = (ui->ui_flags >> (8 * i)) & 0xff; ! 116: sc->dmx_tty = &dmz_tty[((ui->ui_unit * 3) + i) * 8]; ! 117: sc->dmx_octet = (struct dmx_octet *) ! 118: &((struct dmzdevice *)ui->ui_addr)->dmz_octet[i]; ! 119: } ! 120: ! 121: cbase[ui->ui_ubanum] = -1; ! 122: dmz_uballoc[ui->ui_ubanum] = -1; ! 123: } ! 124: ! 125: /* ! 126: * Open a DMF32 line, mapping the clist onto the uba if this ! 127: * is the first dmf on this uba. Turn on this dmf if this is ! 128: * the first use of it. ! 129: */ ! 130: /*ARGSUSED*/ ! 131: dmzopen(dev, flag) ! 132: dev_t dev; ! 133: { ! 134: register struct tty *tp; ! 135: struct dmx_softc *sc; ! 136: int unit, dmz; ! 137: struct uba_device *ui; ! 138: int s; ! 139: int dmxparam(); ! 140: ! 141: unit = minor(dev); ! 142: dmz = DMZ(unit); ! 143: if (unit >= NDMZ*24 || (ui = dmzinfo[dmz])== 0 || ui->ui_alive == 0) ! 144: return (ENXIO); ! 145: ! 146: tp = &dmz_tty[unit]; ! 147: sc = &dmz_softc[unit / 8]; ! 148: tp->t_addr = (caddr_t)sc->dmx_octet; ! 149: tp->t_oproc = dmzstart; ! 150: tp->t_dev = dev; /* needed before dmxopen */ ! 151: tp->t_param = dmxparam; ! 152: ! 153: /* ! 154: * While setting up state for this uba, ! 155: * block uba resets which can clear the state. ! 156: */ ! 157: s = spl6(); ! 158: if (cbase[ui->ui_ubanum] == -1) { ! 159: dmz_uballoc[ui->ui_ubanum] = dmz; ! 160: cbase[ui->ui_ubanum] = UBAI_ADDR(uballoc(ui->ui_ubanum, ! 161: (caddr_t)cfree, nclist*sizeof(struct cblock), 0)); ! 162: } ! 163: splx(s); ! 164: ! 165: return (dmxopen(tp, sc, flag)); ! 166: } ! 167: ! 168: /* ! 169: * Close a DMZ32 line. ! 170: */ ! 171: /*ARGSUSED*/ ! 172: dmzclose(dev, flag) ! 173: dev_t dev; ! 174: int flag; ! 175: { ! 176: ! 177: return (dmxclose(&dmz_tty[minor(dev)])); ! 178: } ! 179: ! 180: dmzread(dev, uio, flag) ! 181: dev_t dev; ! 182: struct uio *uio; ! 183: { ! 184: register struct tty *tp; ! 185: ! 186: tp = &dmz_tty[minor(dev)]; ! 187: return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); ! 188: } ! 189: ! 190: dmzwrite(dev, uio) ! 191: dev_t dev; ! 192: struct uio *uio; ! 193: { ! 194: register struct tty *tp; ! 195: ! 196: tp = &dmz_tty[minor(dev)]; ! 197: return ((*linesw[tp->t_line].l_write)(tp, uio)); ! 198: } ! 199: ! 200: /* ! 201: * DMZ32 receiver interrupts. ! 202: */ ! 203: dmzrinta(dmz) ! 204: int dmz; ! 205: { ! 206: struct uba_device *ui; ! 207: ! 208: ui = dmzinfo[dmz]; ! 209: if (ui == 0 || ui->ui_alive == 0) ! 210: return; ! 211: dmxrint(&dmz_softc[3 * dmz + 0]); ! 212: } ! 213: ! 214: dmzrintb(dmz) ! 215: int dmz; ! 216: { ! 217: struct uba_device *ui; ! 218: ! 219: ui = dmzinfo[dmz]; ! 220: if (ui == 0 || ui->ui_alive == 0) ! 221: return; ! 222: dmxrint(&dmz_softc[3 * dmz + 1]); ! 223: } ! 224: ! 225: dmzrintc(dmz) ! 226: int dmz; ! 227: { ! 228: struct uba_device *ui; ! 229: ! 230: ui = dmzinfo[dmz]; ! 231: if (ui == 0 || ui->ui_alive == 0) ! 232: return; ! 233: dmxrint(&dmz_softc[3 * dmz + 2]); ! 234: } ! 235: ! 236: /* ! 237: * Ioctl for DMZ32. ! 238: */ ! 239: dmzioctl(dev, cmd, data, flag) ! 240: dev_t dev; ! 241: caddr_t data; ! 242: { ! 243: int unit = minor(dev); ! 244: ! 245: return (dmxioctl(&dmz_tty[unit], cmd, data, flag)); ! 246: } ! 247: ! 248: /* ! 249: * DMZ32 transmitter interrupts. ! 250: */ ! 251: dmzxinta(dmz) ! 252: int dmz; ! 253: { ! 254: ! 255: dmxxint(&dmz_softc[3 * dmz + 0]); ! 256: } ! 257: ! 258: dmzxintb(dmz) ! 259: int dmz; ! 260: { ! 261: ! 262: dmxxint(&dmz_softc[3 * dmz + 1]); ! 263: } ! 264: ! 265: dmzxintc(dmz) ! 266: int dmz; ! 267: { ! 268: ! 269: dmxxint(&dmz_softc[3 * dmz + 2]); ! 270: } ! 271: ! 272: /* ! 273: * Start (restart) transmission on the given line. ! 274: */ ! 275: dmzstart(tp) ! 276: struct tty *tp; ! 277: { ! 278: ! 279: dmxstart(tp, &dmz_softc[minor(tp->t_dev) >> 3]); ! 280: } ! 281: ! 282: /* ! 283: * Stop output on a line, e.g. for ^S/^Q or output flush. ! 284: */ ! 285: dmzstop(tp, flag) ! 286: struct tty *tp; ! 287: { ! 288: ! 289: dmxstop(tp, &dmz_softc[minor(tp->t_dev) >> 3], flag); ! 290: } ! 291: ! 292: /* ! 293: * Reset state of driver if UBA reset was necessary. ! 294: * Reset the csr, lpr, and lcr registers on open lines, and ! 295: * restart transmitters. ! 296: */ ! 297: dmzreset(uban) ! 298: int uban; ! 299: { ! 300: register int dmz; ! 301: register struct tty *tp; ! 302: register struct uba_device *ui; ! 303: register struct dmzdevice *addr; ! 304: int i; ! 305: ! 306: for (dmz = 0; dmz < NDMZ; dmz++) { ! 307: ui = dmzinfo[dmz]; ! 308: if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban) ! 309: continue; ! 310: printf("dmz%d ", dmz); ! 311: addr = (struct dmzdevice *)ui->ui_addr; ! 312: ! 313: if (dmz_uballoc[uban] == dmz) { ! 314: int info; ! 315: ! 316: info = uballoc(uban, (caddr_t)cfree, ! 317: nclist * sizeof(struct cblock), UBA_CANTWAIT); ! 318: if (info) ! 319: cbase[uban] = UBAI_ADDR(info); ! 320: else { ! 321: printf(" [can't get uba map]"); ! 322: cbase[uban] = -1; ! 323: } ! 324: } ! 325: ! 326: for (i = 0; i < 3; i++) ! 327: if (dmz_softc[3 * dmz + i].dmx_flags & DMX_ACTIVE) { ! 328: addr->dmz_octet[i].csr = DMF_IE; ! 329: addr->dmz_octet[i].rsp = dmx_timeout; ! 330: } ! 331: ! 332: /* ! 333: * If a unit is open or waiting for open to complete, ! 334: * reset it. ! 335: */ ! 336: tp = &dmz_tty[dmz * 24]; ! 337: for (i = 0; i < 24; i++, tp++) { ! 338: if (tp->t_state & (TS_ISOPEN | TS_WOPEN)) { ! 339: dmxparam(tp, &tp->t_termios); ! 340: (void) dmxmctl(tp, DMF_ON, DMSET); ! 341: tp->t_state &= ~TS_BUSY; ! 342: dmzstart(tp); ! 343: } ! 344: } ! 345: } ! 346: } ! 347: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.