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