|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Chris Torek. ! 7: * ! 8: * Redistribution and use in source and binary forms are permitted ! 9: * provided that the above copyright notice and this paragraph are ! 10: * duplicated in all such forms and that any documentation, ! 11: * advertising materials, and other materials related to such ! 12: * distribution and use acknowledge that the software was developed ! 13: * by the University of California, Berkeley. The name of the ! 14: * University may not be used to endorse or promote products derived ! 15: * from this software without specific prior written permission. ! 16: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 17: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 18: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 19: * ! 20: * @(#)rx50.c 7.1 (Berkeley) 7/9/88 ! 21: */ ! 22: ! 23: #if VAX8200 ! 24: ! 25: /* ! 26: * Routines to handle the console RX50. ! 27: */ ! 28: ! 29: #include "param.h" ! 30: #include "time.h" ! 31: #include "kernel.h" ! 32: #include "vmmac.h" ! 33: #include "buf.h" ! 34: #include "errno.h" ! 35: #include "uio.h" ! 36: ! 37: #include "cpu.h" ! 38: #include "rx50reg.h" ! 39: ! 40: struct rx50device rx50device; ! 41: ! 42: #define rx50unit(dev) minor(dev) ! 43: ! 44: struct rx50state { ! 45: short rs_flags; /* see below */ ! 46: short rs_drive; /* current drive number */ ! 47: u_int rs_blkno; /* current block number */ ! 48: } rx50state; ! 49: ! 50: /* flags */ ! 51: #define RS_0OPEN 0x01 /* drive 0 open -- must be first */ ! 52: #define RS_1OPEN 0x02 /* drive 1 open -- must be second */ ! 53: #define RS_BUSY 0x04 /* operation in progress */ ! 54: #define RS_WANT 0x08 /* wakeup when done */ ! 55: #define RS_DONE 0x20 /* I/O operation done */ ! 56: #define RS_ERROR 0x40 /* error bit set at interrupt */ ! 57: ! 58: /* ! 59: * Open a console RX50. ! 60: */ ! 61: /*ARGSUSED*/ ! 62: rx50open(dev, flags) ! 63: dev_t dev; ! 64: int flags; ! 65: { ! 66: int unit; ! 67: ! 68: /* only on 8200 (yet) */ ! 69: if (cpu != VAX_8200 || (unit = rx50unit(dev)) >= 2) ! 70: return (ENXIO); ! 71: ! 72: /* enforce exclusive access */ ! 73: if (rx50state.rs_flags & (1 << unit)) ! 74: return (EBUSY); ! 75: rx50state.rs_flags |= 1 << unit; ! 76: return (0); ! 77: } ! 78: ! 79: /* ! 80: * Close a console RX50. ! 81: */ ! 82: /*ARGSUSED*/ ! 83: rx50close(dev, flags) ! 84: dev_t dev; ! 85: int flags; ! 86: { ! 87: ! 88: rx50state.rs_flags &= ~(1 << dev); /* atomic */ ! 89: } ! 90: ! 91: /* ! 92: * Perform a read (rw==UIO_READ) or write (rw==UIO_WRITE). ! 93: */ ! 94: rx50operation(dev, rw, uio) ! 95: dev_t dev; ! 96: enum uio_rw rw; ! 97: register struct uio *uio; ! 98: { ! 99: register struct rx50device *rxaddr; ! 100: register struct rx50state *rs; ! 101: register char *cp; ! 102: register int error, i, t; ! 103: char secbuf[512]; ! 104: static char driveselect[2] = { RXCMD_DRIVE0, RXCMD_DRIVE1 }; ! 105: ! 106: /* enforce whole-sector I/O */ ! 107: if ((uio->uio_offset & 511) || (uio->uio_resid & 511)) ! 108: return (EINVAL); ! 109: ! 110: rs = &rx50state; ! 111: ! 112: /* lock out others */ ! 113: i = spl4(); ! 114: while (rs->rs_flags & RS_BUSY) { ! 115: rs->rs_flags |= RS_WANT; ! 116: sleep((caddr_t) &rx50state, PZERO - 1); ! 117: } ! 118: rs->rs_flags |= RS_BUSY; ! 119: rs->rs_drive = rx50unit(dev); ! 120: splx(i); ! 121: ! 122: rxaddr = &rx50device; ! 123: error = 0; ! 124: ! 125: while (uio->uio_resid) { ! 126: rs->rs_blkno = uio->uio_offset >> 9; ! 127: if (rs->rs_blkno >= RX50MAXSEC) { ! 128: if (rs->rs_blkno > RX50MAXSEC) ! 129: error = EINVAL; ! 130: else if (rw == UIO_WRITE) ! 131: error = ENOSPC; ! 132: /* else ``eof'' */ ! 133: break; ! 134: } ! 135: rs->rs_flags &= ~(RS_ERROR | RS_DONE); ! 136: if (rw == UIO_WRITE) { ! 137: /* copy the data to the RX50 silo */ ! 138: error = uiomove(secbuf, 512, UIO_WRITE, uio); ! 139: if (error) ! 140: break; ! 141: i = rxaddr->rxrda; ! 142: for (cp = secbuf, i = 512; --i >= 0;) ! 143: rxaddr->rxfdb = *cp++; ! 144: i = RXCMD_WRITE; ! 145: } else ! 146: i = RXCMD_READ; ! 147: rxaddr->rxcmd = i | driveselect[rs->rs_drive]; ! 148: i = rs->rs_blkno - ((t = rs->rs_blkno / RX50SEC) * RX50SEC); ! 149: rxaddr->rxtrk = t == 79 ? 0 : t + 1; ! 150: #ifdef notdef ! 151: rxaddr->rxsec = "\1\3\5\7\11\1\3\5\7"[(2*t + i) % 5] + (i > 4); ! 152: #else ! 153: rxaddr->rxsec = RX50SKEW(i, t); ! 154: #endif ! 155: i = rxaddr->rxgo; /* start it up */ ! 156: i = spl4(); ! 157: while ((rs->rs_flags & RS_DONE) == 0) ! 158: sleep((caddr_t) &rs->rs_blkno, PRIBIO); ! 159: splx(i); ! 160: if (rs->rs_flags & RS_ERROR) { ! 161: error = EIO; ! 162: break; ! 163: } ! 164: if (rw == UIO_READ) { ! 165: /* copy the data out of the silo */ ! 166: i = rxaddr->rxrda; ! 167: for (cp = secbuf, i = 512; --i >= 0;) ! 168: *cp++ = rxaddr->rxedb; ! 169: error = uiomove(secbuf, 512, UIO_READ, uio); ! 170: if (error) ! 171: break; ! 172: } ! 173: } ! 174: ! 175: /* let others in */ ! 176: rs->rs_flags &= ~RS_BUSY; ! 177: if (rs->rs_flags & RS_WANT) ! 178: wakeup((caddr_t) rs); ! 179: ! 180: return (error); ! 181: } ! 182: ! 183: rx50read(dev, uio) ! 184: dev_t dev; ! 185: struct uio *uio; ! 186: { ! 187: ! 188: return (rx50operation(dev, UIO_READ, uio)); ! 189: } ! 190: ! 191: rx50write(dev, uio) ! 192: dev_t dev; ! 193: struct uio *uio; ! 194: { ! 195: ! 196: return (rx50operation(dev, UIO_WRITE, uio)); ! 197: } ! 198: ! 199: rx50intr() ! 200: { ! 201: register struct rx50device *rxaddr = &rx50device; ! 202: register struct rx50state *rs = &rx50state; ! 203: int i; ! 204: ! 205: #ifdef lint ! 206: i = 0; i = i; ! 207: #endif ! 208: ! 209: /* ignore spurious interrupts */ ! 210: if ((rxaddr->rxcmd & RXCMD_DONE) == 0) ! 211: return; ! 212: if ((rs->rs_flags & RS_BUSY) == 0) { ! 213: printf("stray rx50 interrupt ignored\n"); ! 214: return; ! 215: } ! 216: if (rxaddr->rxcmd & RXCMD_ERROR) { ! 217: printf( ! 218: "csa%d: hard error sn%d: cmd=%x trk=%x sec=%x csc=%x ict=%x ext=%x\n", ! 219: rs->rs_drive + 1, rs->rs_blkno, ! 220: rxaddr->rxcmd, rxaddr->rxtrk, rxaddr->rxsec, ! 221: rxaddr->rxcsc, rxaddr->rxict, rxaddr->rxext); ! 222: rxaddr->rxcmd = RXCMD_RESET; ! 223: i = rxaddr->rxgo; ! 224: rs->rs_flags |= RS_ERROR; ! 225: } ! 226: rs->rs_flags |= RS_DONE; ! 227: wakeup((caddr_t) &rs->rs_blkno); ! 228: } ! 229: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.