1: /* 2: * Copyright (c) 1982, 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: * @(#)crl.c 7.1 (Berkeley) 6/5/86 7: */ 8: /* 9: * TO DO (tef 7/18/85): 10: * 1) change printf's to log() instead??? 11: */ 12: 13: #if VAX8600 14: #include "param.h" 15: #include "systm.h" 16: #include "conf.h" 17: #include "dir.h" 18: #include "user.h" 19: #include "buf.h" 20: #include "uio.h" 21: 22: #include "cons.h" 23: #include "cpu.h" 24: #include "crl.h" 25: #include "mtpr.h" 26: 27: struct { 28: short crl_state; /* open and busy flags */ 29: short crl_active; /* driver state flag */ 30: struct buf *crl_buf; /* buffer we're using */ 31: ushort *crl_xaddr; /* transfer address */ 32: short crl_errcnt; 33: } crltab; 34: 35: struct { 36: int crl_cs; /* saved controller status */ 37: int crl_ds; /* saved drive status */ 38: } crlstat; 39: 40: /*ARGSUSED*/ 41: crlopen(dev, flag) 42: dev_t dev; 43: int flag; 44: { 45: struct buf *geteblk(); 46: 47: if (cpu != VAX_8600) 48: return (ENXIO); 49: if (crltab.crl_state != CRL_IDLE) 50: return (EALREADY); 51: crltab.crl_state = CRL_OPEN; 52: crltab.crl_buf = geteblk(512); 53: return (0); 54: } 55: 56: /*ARGSUSED*/ 57: crlclose(dev, flag) 58: dev_t dev; 59: int flag; 60: { 61: 62: brelse(crltab.crl_buf); 63: crltab.crl_state = CRL_IDLE; 64: } 65: 66: crloperation(rw, uio) 67: enum uio_rw rw; 68: struct uio *uio; 69: { 70: register struct buf *bp; 71: register int i; 72: register int s; 73: int error; 74: 75: if (uio->uio_resid == 0) 76: return (0); 77: s = spl4(); 78: while (crltab.crl_state & CRL_BUSY) 79: sleep((caddr_t)&crltab, PRIBIO); 80: crltab.crl_state |= CRL_BUSY; 81: splx(s); 82: 83: bp = crltab.crl_buf; 84: error = 0; 85: while ((i = imin(CRLBYSEC, uio->uio_resid)) > 0) { 86: bp->b_blkno = uio->uio_offset>>9; 87: if (bp->b_blkno >= MAXSEC || (uio->uio_offset & 0x1FF) != 0) { 88: error = EIO; 89: break; 90: } 91: if (rw == UIO_WRITE) { 92: error = uiomove(bp->b_un.b_addr, i, UIO_WRITE, uio); 93: if (error) 94: break; 95: } 96: bp->b_flags = rw == UIO_WRITE ? B_WRITE : B_READ; 97: s = spl4(); 98: crlstart(); 99: while ((bp->b_flags & B_DONE) == 0) 100: sleep((caddr_t)bp, PRIBIO); 101: splx(s); 102: if (bp->b_flags & B_ERROR) { 103: error = EIO; 104: break; 105: } 106: if (rw == UIO_READ) { 107: error = uiomove(bp->b_un.b_addr, i, UIO_READ, uio); 108: if (error) 109: break; 110: } 111: } 112: crltab.crl_state &= ~CRL_BUSY; 113: wakeup((caddr_t)&crltab); 114: return (error); 115: } 116: 117: /*ARGSUSED*/ 118: crlread(dev, uio) 119: dev_t dev; 120: struct uio *uio; 121: { 122: 123: return (crloperation(UIO_READ, uio)); 124: } 125: 126: /*ARGSUSED*/ 127: crlwrite(dev, uio) 128: dev_t dev; 129: struct uio *uio; 130: { 131: 132: return (crloperation(UIO_WRITE, uio)); 133: } 134: 135: crlstart() 136: { 137: register struct buf *bp; 138: 139: bp = crltab.crl_buf; 140: crltab.crl_errcnt = 0; 141: crltab.crl_xaddr = (ushort *) bp->b_un.b_addr; 142: bp->b_resid = 0; 143: 144: if ((mfpr(STXCS) & STXCS_RDY) == 0) 145: /* not ready to receive order */ 146: return; 147: if ((bp->b_flags&(B_READ|B_WRITE)) == B_READ) { 148: crltab.crl_active = CRL_F_READ; 149: mtpr(STXCS, bp->b_blkno<<8 | STXCS_IE | CRL_F_READ); 150: } else { 151: crltab.crl_active = CRL_F_WRITE; 152: mtpr(STXCS, bp->b_blkno<<8 | STXCS_IE | CRL_F_WRITE); 153: } 154: #ifdef lint 155: crlintr(); 156: #endif 157: } 158: 159: crlintr() 160: { 161: register struct buf *bp; 162: int i; 163: 164: bp = crltab.crl_buf; 165: i = mfpr(STXCS); 166: switch ((i>>24) & 0xFF) { 167: 168: case CRL_S_XCMPLT: 169: switch (crltab.crl_active) { 170: 171: case CRL_F_RETSTS: 172: crlstat.crl_ds = mfpr(STXDB); 173: printf("crlcs=0x%b, crlds=0x%b\n", crlstat.crl_cs, 174: CRLCS_BITS, crlstat.crl_ds, CRLDS_BITS); 175: break; 176: 177: case CRL_F_READ: 178: case CRL_F_WRITE: 179: bp->b_flags |= B_DONE; 180: } 181: crltab.crl_active = 0; 182: wakeup((caddr_t)bp); 183: break; 184: 185: case CRL_S_XCONT: 186: switch (crltab.crl_active) { 187: 188: case CRL_F_WRITE: 189: mtpr(STXDB, *crltab.crl_xaddr++); 190: mtpr(STXCS, bp->b_blkno<<8 | STXCS_IE | CRL_F_WRITE); 191: break; 192: 193: case CRL_F_READ: 194: *crltab.crl_xaddr++ = mfpr(STXDB); 195: mtpr(STXCS, bp->b_blkno<<8 | STXCS_IE | CRL_F_READ); 196: } 197: break; 198: 199: case CRL_S_ABORT: 200: crltab.crl_active = CRL_F_RETSTS; 201: mtpr(STXCS, STXCS_IE | CRL_F_RETSTS); 202: bp->b_flags |= B_DONE|B_ERROR; 203: break; 204: 205: case CRL_S_RETSTS: 206: crlstat.crl_cs = mfpr(STXDB); 207: mtpr(STXCS, STXCS_IE | CRL_S_RETSTS); 208: break; 209: 210: case CRL_S_HNDSHK: 211: printf("crl: hndshk error\n"); /* dump out some status too? */ 212: crltab.crl_active = 0; 213: bp->b_flags |= B_DONE|B_ERROR; 214: wakeup((caddr_t)bp); 215: break; 216: 217: case CRL_S_HWERR: 218: printf("crl: hard error sn%d\n", bp->b_blkno); 219: crltab.crl_active = CRL_F_ABORT; 220: mtpr(STXCS, STXCS_IE | CRL_F_ABORT); 221: break; 222: } 223: } 224: #endif