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.4 (Berkeley) 12/16/90 7 */ 8 /* 9 * TO DO (tef 7/18/85): 10 * 1) change printf's to log() instead??? 11 */ 12 13 #if VAX8600 14 #include "sys/param.h" 15 #include "sys/systm.h" 16 #include "sys/conf.h" 17 #include "sys/user.h" 18 #include "sys/buf.h" 19 20 #include "cons.h" 21 #include "../include/cpu.h" 22 #include "crl.h" 23 #include "../include/mtpr.h" 24 25 struct { 26 short crl_state; /* open and busy flags */ 27 short crl_active; /* driver state flag */ 28 struct buf *crl_buf; /* buffer we're using */ 29 ushort *crl_xaddr; /* transfer address */ 30 short crl_errcnt; 31 } crltab; 32 33 struct { 34 int crl_cs; /* saved controller status */ 35 int crl_ds; /* saved drive status */ 36 } crlstat; 37 38 /*ARGSUSED*/ 39 crlopen(dev, flag) 40 dev_t dev; 41 int flag; 42 { 43 struct buf *geteblk(); 44 45 if (cpu != VAX_8600) 46 return (ENXIO); 47 if (crltab.crl_state != CRL_IDLE) 48 return (EALREADY); 49 crltab.crl_state = CRL_OPEN; 50 crltab.crl_buf = geteblk(512); 51 return (0); 52 } 53 54 /*ARGSUSED*/ 55 crlclose(dev, flag) 56 dev_t dev; 57 int flag; 58 { 59 60 brelse(crltab.crl_buf); 61 crltab.crl_state = CRL_IDLE; 62 } 63 64 /*ARGSUSED*/ 65 crlrw(dev, uio, flag) 66 dev_t dev; 67 struct uio *uio; 68 int flag; 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 (uio->uio_rw == UIO_WRITE) { 92 error = uiomove(bp->b_un.b_addr, i, uio); 93 if (error) 94 break; 95 } 96 bp->b_flags = uio->uio_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 (uio->uio_rw == UIO_READ) { 107 error = uiomove(bp->b_un.b_addr, i, 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 crlstart() 118 { 119 register struct buf *bp; 120 121 bp = crltab.crl_buf; 122 crltab.crl_errcnt = 0; 123 crltab.crl_xaddr = (ushort *) bp->b_un.b_addr; 124 bp->b_resid = 0; 125 126 if ((mfpr(STXCS) & STXCS_RDY) == 0) 127 /* not ready to receive order */ 128 return; 129 if ((bp->b_flags&(B_READ|B_WRITE)) == B_READ) { 130 crltab.crl_active = CRL_F_READ; 131 mtpr(STXCS, bp->b_blkno<<8 | STXCS_IE | CRL_F_READ); 132 } else { 133 crltab.crl_active = CRL_F_WRITE; 134 mtpr(STXCS, bp->b_blkno<<8 | STXCS_IE | CRL_F_WRITE); 135 } 136 #ifdef lint 137 crlintr(); 138 #endif 139 } 140 141 crlintr() 142 { 143 register struct buf *bp; 144 int i; 145 146 bp = crltab.crl_buf; 147 i = mfpr(STXCS); 148 switch ((i>>24) & 0xFF) { 149 150 case CRL_S_XCMPLT: 151 switch (crltab.crl_active) { 152 153 case CRL_F_RETSTS: 154 crlstat.crl_ds = mfpr(STXDB); 155 printf("crlcs=0x%b, crlds=0x%b\n", crlstat.crl_cs, 156 CRLCS_BITS, crlstat.crl_ds, CRLDS_BITS); 157 break; 158 159 case CRL_F_READ: 160 case CRL_F_WRITE: 161 bp->b_flags |= B_DONE; 162 } 163 crltab.crl_active = 0; 164 wakeup((caddr_t)bp); 165 break; 166 167 case CRL_S_XCONT: 168 switch (crltab.crl_active) { 169 170 case CRL_F_WRITE: 171 mtpr(STXDB, *crltab.crl_xaddr++); 172 mtpr(STXCS, bp->b_blkno<<8 | STXCS_IE | CRL_F_WRITE); 173 break; 174 175 case CRL_F_READ: 176 *crltab.crl_xaddr++ = mfpr(STXDB); 177 mtpr(STXCS, bp->b_blkno<<8 | STXCS_IE | CRL_F_READ); 178 } 179 break; 180 181 case CRL_S_ABORT: 182 crltab.crl_active = CRL_F_RETSTS; 183 mtpr(STXCS, STXCS_IE | CRL_F_RETSTS); 184 bp->b_flags |= B_DONE|B_ERROR; 185 break; 186 187 case CRL_S_RETSTS: 188 crlstat.crl_cs = mfpr(STXDB); 189 mtpr(STXCS, STXCS_IE | CRL_S_RETSTS); 190 break; 191 192 case CRL_S_HNDSHK: 193 printf("crl: hndshk error\n"); /* dump out some status too? */ 194 crltab.crl_active = 0; 195 bp->b_flags |= B_DONE|B_ERROR; 196 wakeup((caddr_t)bp); 197 break; 198 199 case CRL_S_HWERR: 200 printf("crl: hard error sn%d\n", bp->b_blkno); 201 crltab.crl_active = CRL_F_ABORT; 202 mtpr(STXCS, STXCS_IE | CRL_F_ABORT); 203 break; 204 } 205 } 206 #endif 207