1 /*- 2 * Copyright (c) 1982, 1986 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)crl.c 7.5 (Berkeley) 05/09/91 8 */ 9 10 /* 11 * TO DO (tef 7/18/85): 12 * 1) change printf's to log() instead??? 13 */ 14 15 #if VAX8600 16 #include "sys/param.h" 17 #include "sys/systm.h" 18 #include "sys/conf.h" 19 #include "sys/user.h" 20 #include "sys/buf.h" 21 22 #include "cons.h" 23 #include "../include/cpu.h" 24 #include "crl.h" 25 #include "../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 /*ARGSUSED*/ 67 crlrw(dev, uio, flag) 68 dev_t dev; 69 struct uio *uio; 70 int flag; 71 { 72 register struct buf *bp; 73 register int i; 74 register int s; 75 int error; 76 77 if (uio->uio_resid == 0) 78 return (0); 79 s = spl4(); 80 while (crltab.crl_state & CRL_BUSY) 81 sleep((caddr_t)&crltab, PRIBIO); 82 crltab.crl_state |= CRL_BUSY; 83 splx(s); 84 85 bp = crltab.crl_buf; 86 error = 0; 87 while ((i = imin(CRLBYSEC, uio->uio_resid)) > 0) { 88 bp->b_blkno = uio->uio_offset>>9; 89 if (bp->b_blkno >= MAXSEC || (uio->uio_offset & 0x1FF) != 0) { 90 error = EIO; 91 break; 92 } 93 if (uio->uio_rw == UIO_WRITE) { 94 error = uiomove(bp->b_un.b_addr, i, uio); 95 if (error) 96 break; 97 } 98 bp->b_flags = uio->uio_rw == UIO_WRITE ? B_WRITE : B_READ; 99 s = spl4(); 100 crlstart(); 101 while ((bp->b_flags & B_DONE) == 0) 102 sleep((caddr_t)bp, PRIBIO); 103 splx(s); 104 if (bp->b_flags & B_ERROR) { 105 error = EIO; 106 break; 107 } 108 if (uio->uio_rw == UIO_READ) { 109 error = uiomove(bp->b_un.b_addr, i, uio); 110 if (error) 111 break; 112 } 113 } 114 crltab.crl_state &= ~CRL_BUSY; 115 wakeup((caddr_t)&crltab); 116 return (error); 117 } 118 119 crlstart() 120 { 121 register struct buf *bp; 122 123 bp = crltab.crl_buf; 124 crltab.crl_errcnt = 0; 125 crltab.crl_xaddr = (ushort *) bp->b_un.b_addr; 126 bp->b_resid = 0; 127 128 if ((mfpr(STXCS) & STXCS_RDY) == 0) 129 /* not ready to receive order */ 130 return; 131 if ((bp->b_flags&(B_READ|B_WRITE)) == B_READ) { 132 crltab.crl_active = CRL_F_READ; 133 mtpr(STXCS, bp->b_blkno<<8 | STXCS_IE | CRL_F_READ); 134 } else { 135 crltab.crl_active = CRL_F_WRITE; 136 mtpr(STXCS, bp->b_blkno<<8 | STXCS_IE | CRL_F_WRITE); 137 } 138 #ifdef lint 139 crlintr(); 140 #endif 141 } 142 143 crlintr() 144 { 145 register struct buf *bp; 146 int i; 147 148 bp = crltab.crl_buf; 149 i = mfpr(STXCS); 150 switch ((i>>24) & 0xFF) { 151 152 case CRL_S_XCMPLT: 153 switch (crltab.crl_active) { 154 155 case CRL_F_RETSTS: 156 crlstat.crl_ds = mfpr(STXDB); 157 printf("crlcs=0x%b, crlds=0x%b\n", crlstat.crl_cs, 158 CRLCS_BITS, crlstat.crl_ds, CRLDS_BITS); 159 break; 160 161 case CRL_F_READ: 162 case CRL_F_WRITE: 163 bp->b_flags |= B_DONE; 164 } 165 crltab.crl_active = 0; 166 wakeup((caddr_t)bp); 167 break; 168 169 case CRL_S_XCONT: 170 switch (crltab.crl_active) { 171 172 case CRL_F_WRITE: 173 mtpr(STXDB, *crltab.crl_xaddr++); 174 mtpr(STXCS, bp->b_blkno<<8 | STXCS_IE | CRL_F_WRITE); 175 break; 176 177 case CRL_F_READ: 178 *crltab.crl_xaddr++ = mfpr(STXDB); 179 mtpr(STXCS, bp->b_blkno<<8 | STXCS_IE | CRL_F_READ); 180 } 181 break; 182 183 case CRL_S_ABORT: 184 crltab.crl_active = CRL_F_RETSTS; 185 mtpr(STXCS, STXCS_IE | CRL_F_RETSTS); 186 bp->b_flags |= B_DONE|B_ERROR; 187 break; 188 189 case CRL_S_RETSTS: 190 crlstat.crl_cs = mfpr(STXDB); 191 mtpr(STXCS, STXCS_IE | CRL_S_RETSTS); 192 break; 193 194 case CRL_S_HNDSHK: 195 printf("crl: hndshk error\n"); /* dump out some status too? */ 196 crltab.crl_active = 0; 197 bp->b_flags |= B_DONE|B_ERROR; 198 wakeup((caddr_t)bp); 199 break; 200 201 case CRL_S_HWERR: 202 printf("crl: hard error sn%d\n", bp->b_blkno); 203 crltab.crl_active = CRL_F_ABORT; 204 mtpr(STXCS, STXCS_IE | CRL_F_ABORT); 205 break; 206 } 207 } 208 #endif 209