1 /* rk.c 4.1 12/17/80 */ 2 3 /* 4 * RK disk driver, standalone version 5 */ 6 7 #include "../h/param.h" 8 #include "../h/inode.h" 9 #include "../h/pte.h" 10 #include "../h/uba.h" 11 #include "saio.h" 12 13 #define RKADDR ((struct rk_regs *)(PHYSUMEM - 0160000 + 0177440)) 14 #define FORMAT_22 0 15 #define RESET 0102000 16 #define WCOM 022 17 #define RCOM 020 18 #define RK07 02000 19 #define GO 01 20 #define RELEASE 010 21 #define CTLRDY 0200 22 #define PACKAK 000003 /* Pack Acknowledge */ 23 24 struct rk_regs 25 { 26 short rkcs1; 27 short rkwc; 28 u_short rkba; 29 short rkda; 30 short rkcs2; 31 short rkds; 32 short rker; 33 short rkasof; 34 short rkdc; 35 short rknull; 36 short rkdb; 37 short rkmr1; 38 short rkecps; 39 short rkecpt; 40 short rkmr2; 41 short rkmr3; 42 }; 43 44 struct devsize { 45 daddr_t cyloff; 46 } rk_sizes[] = { 47 0, 146, 246, -1, -1, -1, -1, -1, 48 }; 49 50 rkopen(io) 51 register struct iob *io; 52 { 53 54 if (rk_sizes[io->i_boff].cyloff == -1 || 55 io->i_boff < 0 || io->i_boff > 7) 56 _stop("rk bad unit"); 57 io->i_boff = rk_sizes[io->i_boff].cyloff * 66; 58 } 59 60 rkstrategy(io, func) 61 register struct iob *io; 62 { 63 register short com; 64 daddr_t bn; 65 short dn, cn, sn, tn; 66 int ubinfo; 67 68 ubinfo = ubasetup(io, 1); 69 bn = io->i_bn; 70 dn = io->i_unit; 71 cn = bn/66; 72 sn = bn%22; 73 tn = (bn / 22) % 3; 74 75 RKADDR->rkcs2 = dn; 76 RKADDR->rkcs1 = PACKAK | RK07; 77 while ((com = RKADDR->rkcs1) & 01) 78 ; 79 RKADDR->rkda = sn | (tn << 8); 80 RKADDR->rkdc = cn; 81 RKADDR->rkba = ubinfo; 82 RKADDR->rkwc = -(io->i_cc >> 1); 83 com = ((ubinfo & 0x30000) >> 8) | RK07 | GO | (FORMAT_22 << 12); 84 if(func == READ) 85 com |= RCOM; else 86 com |= WCOM; 87 RKADDR->rkcs1 = com; 88 while (((com = RKADDR->rkcs1) & CTLRDY) == 0) 89 ; 90 while(RKADDR->rkds >= 0) 91 ; 92 ubafree(ubinfo); 93 if (RKADDR->rkcs1 < 0) { /* error bit */ 94 printf("RK07 error: unit %d, cyl %d, trk %d, sect %d, ", 95 io->i_unit, cn, tn, sn); 96 printf("cs1 %X, cs2 %X, err %X\n", 97 RKADDR->rkcs1, RKADDR->rkcs2, RKADDR->rker); 98 RKADDR->rkcs1 = RESET|GO; 99 while(((com = RKADDR->rkcs1)&CTLRDY) == 0) 100 ; 101 return (-1); 102 } 103 return (io->i_cc); 104 } 105