1 /* 2 * Copyright (c) 1982 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 1.3 (Berkeley) 02/23/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 225