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