1*2380Swnj /* rk.c 4.6 02/08/81 */ 21899Swnj 31942Swnj #include "rk.h" 41899Swnj #if NRK > 0 51899Swnj /* 61899Swnj * RK disk driver 71899Swnj */ 81899Swnj 91899Swnj #include "../h/param.h" 101899Swnj #include "../h/systm.h" 111899Swnj #include "../h/buf.h" 121899Swnj #include "../h/conf.h" 131899Swnj #include "../h/dir.h" 141899Swnj #include "../h/user.h" 151899Swnj #include "../h/pte.h" 161899Swnj #include "../h/map.h" 171899Swnj #include "../h/uba.h" 181899Swnj #include "../h/dk.h" 191899Swnj 201899Swnj #define NCYL 815 211899Swnj #define NSECT 22 221899Swnj #define NTRK 3 231899Swnj #define NBLK (NTRK*NSECT*NCYL) 241899Swnj 251899Swnj /* rkcs1 */ 261899Swnj #define CCLR 0100000 /* controller clear */ 271899Swnj #define DI 040000 /* drive interrupt */ 281899Swnj #define CTO 04000 /* controller timeout */ 291899Swnj #define CDT 02000 /* drive type (rk07/rk06) */ 301899Swnj #define RDY 0200 /* controller ready */ 311899Swnj #define IEN 0100 /* interrupt enable */ 321899Swnj 331899Swnj 341899Swnj /* rkcs2 */ 351899Swnj #define DLT 0100000 /* data late */ 361899Swnj #define WCE 040000 /* write check */ 371899Swnj #define UPE 020000 /* unibus parity */ 381899Swnj #define NED 010000 /* non-existant drive */ 391899Swnj #define NEM 04000 /* non-existant memory */ 401899Swnj #define PGE 02000 /* software error */ 411899Swnj #define MDS 01000 /* multiple drive select */ 421899Swnj #define UFE 0400 /* unit field error */ 431899Swnj #define SCLR 040 /* subsystem clear */ 441899Swnj #define cs2abort (NED|NEM|PGE|UFE) 451899Swnj 461899Swnj /* rkds */ 471899Swnj #define SVAL 0100000 /* status valid */ 481899Swnj #define CDA 040000 /* current drive attention */ 491899Swnj #define PIP 020000 /* positioning in progress */ 501899Swnj #define WRL 04000 /* write lock */ 511899Swnj #define DDT 0400 /* disk drive type */ 521899Swnj #define DRDY 0200 /* drive ready */ 531899Swnj #define VV 0100 /* volume valid */ 541899Swnj #define DROT 040 /* drive off track */ 551899Swnj #define SPLS 020 /* speed loss */ 561899Swnj #define ACLO 010 /* ac low */ 571899Swnj #define OFFSET 04 /* offset mode */ 581899Swnj #define DRA 01 /* drive available */ 591899Swnj #define dsabort (ACLO|SPLS) 601899Swnj 611899Swnj 621899Swnj /* commands */ 631899Swnj #define SELECT 0 641899Swnj #define PACK 2 651899Swnj #define DCLR 4 661899Swnj #define RESET 012 671899Swnj #define WCOM 022 681899Swnj #define RCOM 020 691899Swnj #define GO 01 701899Swnj #define DRESET 012 711899Swnj 721899Swnj struct device 731899Swnj { 741899Swnj short rkcs1; 751899Swnj short rkwc; 761899Swnj unsigned short rkba; 771899Swnj short rkda; 781899Swnj short rkcs2; 791899Swnj short rkds; 801899Swnj short rker; 811899Swnj short rkatt; 821899Swnj short rkcyl; 831899Swnj short rkdb; 841899Swnj short rkmr1; 851899Swnj short rkecps; 861899Swnj short rkecpt; 871899Swnj short rkmr2; 881899Swnj short rkmr3; 891899Swnj } ; 901899Swnj 911899Swnj struct buf rktab; 921899Swnj struct buf rrkbuf; 931899Swnj 941899Swnj struct devsize { 951899Swnj unsigned int nblocks; 961899Swnj int cyloff; 971899Swnj } rk_sizes [] ={ 981899Swnj 9614, 0, /* 0 - 145 */ 991899Swnj 6600, 146, /* 146 - 245 */ 1001899Swnj 37554, 246, /* 246 - 815 */ 1011899Swnj 0, 0, 1021899Swnj 0, 0, 1031899Swnj 0, 0, 1041899Swnj 0, 0, 1052173Swnj 53790, 0, 1061899Swnj }; 1071899Swnj 1081899Swnj rkstrategy(bp) 1091899Swnj register struct buf *bp; 1101899Swnj { 1111899Swnj register dn, sz; 1121899Swnj 1131899Swnj dn = minor(bp->b_dev); 1142173Swnj sz = ((bp->b_bcount+511)>>9); 1152173Swnj if (dn > (NRK<<3) || sz+bp->b_blkno > rk_sizes[dn&07].nblocks) { 1161899Swnj bp->b_flags |= B_ERROR; 1171899Swnj iodone(bp); 1181899Swnj return; 1191899Swnj } 1201899Swnj bp->av_forw = (struct buf *)NULL; 1211899Swnj spl5(); 1221899Swnj if(rktab.b_actf == NULL) 1231899Swnj rktab.b_actf = bp; 1241899Swnj else 1251899Swnj rktab.b_actl->av_forw = bp; 1261899Swnj rktab.b_actl = bp; 1271899Swnj if(rktab.b_active == NULL) 1281899Swnj rkstart(); 1291899Swnj spl0(); 1301899Swnj } 1311899Swnj 1321899Swnj int rk_info; 1331899Swnj int tcn, ttn, tsn; 1341899Swnj 1351899Swnj rkstart() 1361899Swnj { 1371899Swnj register struct buf *bp; 1381899Swnj register com; 1391899Swnj register struct device *rkaddr = RKADDR; 1401899Swnj daddr_t bn; 1411899Swnj int dn, cn, sn, tn; 1421899Swnj 1431899Swnj if ((bp = rktab.b_actf) == NULL) 1441899Swnj return; 1451899Swnj rktab.b_active++; 1461899Swnj rk_info = ubasetup(bp, 1); 1471899Swnj bn = bp->b_blkno; 1481899Swnj dn = minor(bp->b_dev); 1491899Swnj cn = bn/(NTRK*NSECT); 1501899Swnj cn += rk_sizes[dn&07].cyloff; 1511899Swnj dn >>= 3; 1521899Swnj if (dn != (rkaddr->rkcs2&07)) { 1531899Swnj rkaddr->rkcs2 = dn; 1541899Swnj rkaddr->rkcs1 = CDT | GO; 1551899Swnj while ((rkaddr->rkcs1&RDY)==0) 1561899Swnj ; 1571899Swnj } 1581899Swnj if ((rkaddr->rkds & VV) == 0) { 1591899Swnj rkaddr->rkcs1 = PACK | CDT | GO; 1601899Swnj while ((rkaddr->rkcs1&RDY)==0) 1611899Swnj ; 1621899Swnj } 1631899Swnj tn = bn%(NTRK*NSECT); 1641899Swnj tn = tn/NSECT; 1651899Swnj sn = bn%NSECT; 1661899Swnj rkaddr->rkcs2 = dn; 1671899Swnj rkaddr->rkcyl = cn; 1681899Swnj rkaddr->rkda = (tn << 8) | sn; 1691899Swnj ttn = tn; tcn = cn; tsn = sn; 1701899Swnj rkaddr->rkba = rk_info; 1711899Swnj rkaddr->rkwc = -(bp->b_bcount>>1); 1721899Swnj com = ((rk_info &0x30000) >> 8) | CDT | IEN | GO; 1731899Swnj if(bp->b_flags & B_READ) 1741899Swnj com |= RCOM; else 1751899Swnj com |= WCOM; 1761899Swnj rkaddr->rkcs1 = com; 1771946Swnj dk_busy |= 1<<RKDK_N; 1781946Swnj dk_xfer[RKDK_N] += 1; 1791899Swnj com = bp->b_bcount>>6; 1801946Swnj dk_wds[RKDK_N] += com; 1811899Swnj } 1821899Swnj 1831899Swnj rkintr() 1841899Swnj { 1851899Swnj register struct buf *bp; 1861899Swnj register d, x; 1871899Swnj register struct device *rkaddr = RKADDR; 1881899Swnj int ds, er; 1891899Swnj 1901899Swnj if (rktab.b_active == NULL) 1911899Swnj return; 1921946Swnj dk_busy &= ~(1<<RKDK_N); 1931899Swnj bp = rktab.b_actf; 1941899Swnj rktab.b_active = NULL; 1951899Swnj if (rkaddr->rkcs1 < 0) { /* error bit */ 1961899Swnj d = (minor(bp->b_dev)>>3); 1971899Swnj x = 1; 1981899Swnj if (rkaddr->rkcs1&DI) { 1992173Swnj printf("rkintr: DI\n"); 2001899Swnj } 2011899Swnj if (rkaddr->rkds&CDA) 2022173Swnj printf("rkintr: CDA\n"); 2031899Swnj if ((rkaddr->rkds&CDA) || (rkaddr->rkcs1&DI)) { 2041899Swnj er = (unsigned short)rkaddr->rker; 2051899Swnj ds = (unsigned short)rkaddr->rkds; 2061899Swnj rkaddr->rkcs1 = CDT | DCLR | GO; 2071899Swnj } else { 2081899Swnj if ((rkaddr->rkds&SVAL)==0) { 2092173Swnj x = 0x8000 - rkselect(rkaddr, d); 2102173Swnj printf("rkintr: no SVAL, delay %d\n", x); 2111899Swnj } 2121899Swnj er = (unsigned short)rkaddr->rker; 2131899Swnj ds = (unsigned short)rkaddr->rkds; 2141899Swnj } 2151899Swnj if (rkaddr->rkds&dsabort) { 2161899Swnj printf("rk %d is down\n", d); 2171899Swnj rktab.b_errcnt = 10; 2181899Swnj } 2191899Swnj if (rkaddr->rkcs2&cs2abort) { 2201899Swnj printf("cs2 abort %o\n", rkaddr->rkcs2); 2211899Swnj rktab.b_errcnt = 10; 2221899Swnj } 2231899Swnj if (rktab.b_errcnt >= 10) { 2241899Swnj deverror(bp, er, ds); 2251899Swnj printf("cn %d tn %d sn %d\n", tcn, ttn, tsn); 2261899Swnj } 2271899Swnj rkaddr->rkcs1 = CDT | DCLR | GO; 2281899Swnj while ((rkaddr->rkcs1&RDY)==0) 2291899Swnj ; 2301899Swnj rkaddr->rkcs2 = SCLR; 2311899Swnj while ((rkaddr->rkcs1&RDY)==0) 2321899Swnj ; 2331899Swnj if ((x=rkselect(rkaddr, d)) == 0) { 2341899Swnj printf("after clears\n"); 2351899Swnj goto bad; 2361899Swnj } 2371899Swnj rkaddr->rkcs1 = CDT | RESET | GO; 2381899Swnj while (rkaddr->rkds & PIP) 2391899Swnj ; 2401899Swnj if (++rktab.b_errcnt <= 10) { 2412054Swnj ubarelse(&rk_info); 2421899Swnj rkstart(); 2431899Swnj return; 2441899Swnj } 2451899Swnj bad: 2461899Swnj bp->b_flags |= B_ERROR; 2471899Swnj } 2481899Swnj rktab.b_errcnt = 0; 2491899Swnj rktab.b_actf = bp->av_forw; 2501899Swnj bp->b_resid = 0; 2512054Swnj ubarelse(&rk_info); 2521899Swnj iodone(bp); 2531899Swnj rkstart(); 2541899Swnj } 2551899Swnj 2561899Swnj 2571899Swnj rkselect(rkaddr, d) 2581899Swnj register struct device *rkaddr; 2591899Swnj { 2601899Swnj rkaddr->rkcs2 = d; 2611899Swnj rkaddr->rkcs1 = CDT|GO; 2621899Swnj return(rkwait(rkaddr)); 2631899Swnj } 2641899Swnj 2651899Swnj rkwait(rkaddr) 2661899Swnj register struct device *rkaddr; 2671899Swnj { 2681899Swnj register t; 2691899Swnj 2701899Swnj for(t=0x8000; t && ((rkaddr->rkds&DRDY)==0); t--) 2711899Swnj ; 2721899Swnj if (t==0) 2731899Swnj printf("rk not ready\n"); 2741899Swnj return(t); 2751899Swnj } 2761899Swnj 2771899Swnj rkread(dev) 2781899Swnj dev_t dev; 2791899Swnj { 2801899Swnj 2811899Swnj physio(rkstrategy, &rrkbuf, dev, B_READ, minphys); 2821899Swnj } 2831899Swnj 2841899Swnj rkwrite(dev) 2851899Swnj dev_t dev; 2861899Swnj { 2871899Swnj 2881899Swnj physio(rkstrategy, &rrkbuf, dev, B_WRITE, minphys); 2891899Swnj } 290*2380Swnj 291*2380Swnj rkdump() 292*2380Swnj { 293*2380Swnj 294*2380Swnj printf("don't know how to dump to rk (yet)\n"); 295*2380Swnj } 2961899Swnj #endif 297