1 /* rk.c 4.4 12/30/80 */ 2 3 #include "rk.h" 4 #if NRK > 0 5 /* 6 * RK disk driver 7 */ 8 9 #include "../h/param.h" 10 #include "../h/systm.h" 11 #include "../h/buf.h" 12 #include "../h/conf.h" 13 #include "../h/dir.h" 14 #include "../h/user.h" 15 #include "../h/pte.h" 16 #include "../h/map.h" 17 #include "../h/uba.h" 18 #include "../h/dk.h" 19 20 #define NCYL 815 21 #define NSECT 22 22 #define NTRK 3 23 #define NBLK (NTRK*NSECT*NCYL) 24 25 /* rkcs1 */ 26 #define CCLR 0100000 /* controller clear */ 27 #define DI 040000 /* drive interrupt */ 28 #define CTO 04000 /* controller timeout */ 29 #define CDT 02000 /* drive type (rk07/rk06) */ 30 #define RDY 0200 /* controller ready */ 31 #define IEN 0100 /* interrupt enable */ 32 33 34 /* rkcs2 */ 35 #define DLT 0100000 /* data late */ 36 #define WCE 040000 /* write check */ 37 #define UPE 020000 /* unibus parity */ 38 #define NED 010000 /* non-existant drive */ 39 #define NEM 04000 /* non-existant memory */ 40 #define PGE 02000 /* software error */ 41 #define MDS 01000 /* multiple drive select */ 42 #define UFE 0400 /* unit field error */ 43 #define SCLR 040 /* subsystem clear */ 44 #define cs2abort (NED|NEM|PGE|UFE) 45 46 /* rkds */ 47 #define SVAL 0100000 /* status valid */ 48 #define CDA 040000 /* current drive attention */ 49 #define PIP 020000 /* positioning in progress */ 50 #define WRL 04000 /* write lock */ 51 #define DDT 0400 /* disk drive type */ 52 #define DRDY 0200 /* drive ready */ 53 #define VV 0100 /* volume valid */ 54 #define DROT 040 /* drive off track */ 55 #define SPLS 020 /* speed loss */ 56 #define ACLO 010 /* ac low */ 57 #define OFFSET 04 /* offset mode */ 58 #define DRA 01 /* drive available */ 59 #define dsabort (ACLO|SPLS) 60 61 62 /* commands */ 63 #define SELECT 0 64 #define PACK 2 65 #define DCLR 4 66 #define RESET 012 67 #define WCOM 022 68 #define RCOM 020 69 #define GO 01 70 #define DRESET 012 71 72 struct device 73 { 74 short rkcs1; 75 short rkwc; 76 unsigned short rkba; 77 short rkda; 78 short rkcs2; 79 short rkds; 80 short rker; 81 short rkatt; 82 short rkcyl; 83 short rkdb; 84 short rkmr1; 85 short rkecps; 86 short rkecpt; 87 short rkmr2; 88 short rkmr3; 89 } ; 90 91 struct buf rktab; 92 struct buf rrkbuf; 93 94 struct devsize { 95 unsigned int nblocks; 96 int cyloff; 97 } rk_sizes [] ={ 98 9614, 0, /* 0 - 145 */ 99 6600, 146, /* 146 - 245 */ 100 37554, 246, /* 246 - 815 */ 101 0, 0, 102 0, 0, 103 0, 0, 104 0, 0, 105 0, 0, 106 }; 107 108 rkstrategy(bp) 109 register struct buf *bp; 110 { 111 register dn, sz; 112 113 dn = minor(bp->b_dev); 114 sz = (bp->b_bcount>>9); 115 if (dn > (NRK<<3) || sz+bp->b_blkno >= rk_sizes[dn&07].nblocks) { 116 bp->b_flags |= B_ERROR; 117 iodone(bp); 118 return; 119 } 120 bp->av_forw = (struct buf *)NULL; 121 spl5(); 122 if(rktab.b_actf == NULL) 123 rktab.b_actf = bp; 124 else 125 rktab.b_actl->av_forw = bp; 126 rktab.b_actl = bp; 127 if(rktab.b_active == NULL) 128 rkstart(); 129 spl0(); 130 } 131 132 int rk_info; 133 int tcn, ttn, tsn; 134 135 rkstart() 136 { 137 register struct buf *bp; 138 register com; 139 register struct device *rkaddr = RKADDR; 140 daddr_t bn; 141 int dn, cn, sn, tn; 142 143 if ((bp = rktab.b_actf) == NULL) 144 return; 145 rktab.b_active++; 146 rk_info = ubasetup(bp, 1); 147 bn = bp->b_blkno; 148 dn = minor(bp->b_dev); 149 cn = bn/(NTRK*NSECT); 150 cn += rk_sizes[dn&07].cyloff; 151 dn >>= 3; 152 if (dn != (rkaddr->rkcs2&07)) { 153 rkaddr->rkcs2 = dn; 154 rkaddr->rkcs1 = CDT | GO; 155 while ((rkaddr->rkcs1&RDY)==0) 156 ; 157 } 158 if ((rkaddr->rkds & VV) == 0) { 159 rkaddr->rkcs1 = PACK | CDT | GO; 160 while ((rkaddr->rkcs1&RDY)==0) 161 ; 162 } 163 tn = bn%(NTRK*NSECT); 164 tn = tn/NSECT; 165 sn = bn%NSECT; 166 rkaddr->rkcs2 = dn; 167 rkaddr->rkcyl = cn; 168 rkaddr->rkda = (tn << 8) | sn; 169 ttn = tn; tcn = cn; tsn = sn; 170 rkaddr->rkba = rk_info; 171 rkaddr->rkwc = -(bp->b_bcount>>1); 172 com = ((rk_info &0x30000) >> 8) | CDT | IEN | GO; 173 if(bp->b_flags & B_READ) 174 com |= RCOM; else 175 com |= WCOM; 176 rkaddr->rkcs1 = com; 177 dk_busy |= 1<<RKDK_N; 178 dk_xfer[RKDK_N] += 1; 179 com = bp->b_bcount>>6; 180 dk_wds[RKDK_N] += com; 181 } 182 183 rkintr() 184 { 185 register struct buf *bp; 186 register d, x; 187 register struct device *rkaddr = RKADDR; 188 int ds, er; 189 190 if (rktab.b_active == NULL) 191 return; 192 dk_busy &= ~(1<<RKDK_N); 193 bp = rktab.b_actf; 194 rktab.b_active = NULL; 195 if (rkaddr->rkcs1 < 0) { /* error bit */ 196 d = (minor(bp->b_dev)>>3); 197 x = 1; 198 if (rkaddr->rkcs1&DI) { 199 printf("DI"); 200 } 201 if (rkaddr->rkds&CDA) 202 printf("CDA "); 203 if ((rkaddr->rkds&CDA) || (rkaddr->rkcs1&DI)) { 204 er = (unsigned short)rkaddr->rker; 205 ds = (unsigned short)rkaddr->rkds; 206 rkaddr->rkcs1 = CDT | DCLR | GO; 207 printf("DCLR"); 208 } else { 209 if ((rkaddr->rkds&SVAL)==0) { 210 printf("no SVAL\n"); 211 x = rkselect(rkaddr, d); 212 printf("x = %d\n", x); 213 } 214 er = (unsigned short)rkaddr->rker; 215 ds = (unsigned short)rkaddr->rkds; 216 } 217 if (rkaddr->rkds&dsabort) { 218 printf("rk %d is down\n", d); 219 rktab.b_errcnt = 10; 220 } 221 if (rkaddr->rkcs2&cs2abort) { 222 printf("cs2 abort %o\n", rkaddr->rkcs2); 223 rktab.b_errcnt = 10; 224 } 225 if (rktab.b_errcnt >= 10) { 226 deverror(bp, er, ds); 227 printf("cn %d tn %d sn %d\n", tcn, ttn, tsn); 228 } 229 rkaddr->rkcs1 = CDT | DCLR | GO; 230 while ((rkaddr->rkcs1&RDY)==0) 231 ; 232 rkaddr->rkcs2 = SCLR; 233 while ((rkaddr->rkcs1&RDY)==0) 234 ; 235 if ((x=rkselect(rkaddr, d)) == 0) { 236 printf("after clears\n"); 237 goto bad; 238 } 239 printf("reset\n"); 240 rkaddr->rkcs1 = CDT | RESET | GO; 241 while (rkaddr->rkds & PIP) 242 ; 243 if (++rktab.b_errcnt <= 10) { 244 ubarelse(&rk_info); 245 rkstart(); 246 return; 247 } 248 bad: 249 bp->b_flags |= B_ERROR; 250 } 251 rktab.b_errcnt = 0; 252 rktab.b_actf = bp->av_forw; 253 bp->b_resid = 0; 254 ubarelse(&rk_info); 255 iodone(bp); 256 rkstart(); 257 } 258 259 260 rkselect(rkaddr, d) 261 register struct device *rkaddr; 262 { 263 rkaddr->rkcs2 = d; 264 rkaddr->rkcs1 = CDT|GO; 265 return(rkwait(rkaddr)); 266 } 267 268 rkwait(rkaddr) 269 register struct device *rkaddr; 270 { 271 register t; 272 273 for(t=0x8000; t && ((rkaddr->rkds&DRDY)==0); t--) 274 ; 275 if (t==0) 276 printf("rk not ready\n"); 277 return(t); 278 } 279 280 rkread(dev) 281 dev_t dev; 282 { 283 284 physio(rkstrategy, &rrkbuf, dev, B_READ, minphys); 285 } 286 287 rkwrite(dev) 288 dev_t dev; 289 { 290 291 physio(rkstrategy, &rrkbuf, dev, B_WRITE, minphys); 292 } 293 #endif 294