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