1 /* rk.c 4.5 82/07/15 */ 2 3 /* 4 * RK611/RK07 5 */ 6 7 #include "../h/param.h" 8 #include "../h/rkreg.h" 9 #include "../h/inode.h" 10 #include "../h/pte.h" 11 #include "../h/ubareg.h" 12 #include "../h/fs.h" 13 #include "saio.h" 14 #include "savax.h" 15 16 u_short rkstd[] = { 0777440 }; 17 short rk_off[] = { 0, 241, 0, -1, -1, -1, 393, -1 }; 18 19 rkopen(io) 20 register struct iob *io; 21 { 22 register struct rkdevice *rkaddr = (struct rkdevice *)ubamem(io->i_unit, rkstd[0]); 23 24 if (rk_off[io->i_boff] == -1 || 25 io->i_boff < 0 || io->i_boff > 7) 26 _stop("rk bad unit"); 27 io->i_boff = rk_off[io->i_boff] * NRKSECT*NRKTRK; 28 rkaddr->rkcs2 = RKCS2_SCLR; 29 rkwait(rkaddr); 30 } 31 32 rkstrategy(io, func) 33 register struct iob *io; 34 { 35 register struct rkdevice *rkaddr = (struct rkdevice *)ubamem(io->i_unit, rkstd[0]); 36 int com; 37 daddr_t bn; 38 short dn, cn, sn, tn; 39 int ubinfo, errcnt = 0; 40 41 retry: 42 ubinfo = ubasetup(io, 1); 43 bn = io->i_bn; 44 dn = io->i_unit; 45 cn = bn/(NRKSECT*NRKTRK); 46 sn = bn%NRKSECT; 47 tn = (bn / NRKSECT) % NRKTRK; 48 rkaddr->rkcs2 = dn; 49 rkaddr->rkcs1 = RK_CDT|RK_PACK|RK_GO; 50 rkwait(rkaddr); 51 rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 52 rkwait(rkaddr); 53 rkaddr->rkda = sn | (tn << 8); 54 rkaddr->rkcyl = cn; 55 rkaddr->rkba = ubinfo; 56 rkaddr->rkwc = -(io->i_cc >> 1); 57 com = RK_CDT|((ubinfo>>8)&0x300)|RK_GO; 58 if (func == READ) 59 com |= RK_READ; 60 else 61 com |= RK_WRITE; 62 rkaddr->rkcs1 = com; 63 rkwait(rkaddr); 64 while ((rkaddr->rkds & RKDS_SVAL) == 0) 65 ; 66 ubafree(io, ubinfo); 67 if (rkaddr->rkcs1 & RK_CERR) { 68 printf("rk error: (cyl,trk,sec)=(%d,%d,%d) cs2=%b er=%b\n", 69 cn, tn, sn, rkaddr->rkcs2, RKCS2_BITS, 70 rkaddr->rker, RKER_BITS); 71 rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 72 rkwait(rkaddr); 73 if (errcnt == 10) { 74 printf("rk: unrecovered error\n"); 75 return (-1); 76 } 77 errcnt++; 78 goto retry; 79 } 80 if (errcnt) 81 printf("rk: recovered by retry\n"); 82 return (io->i_cc); 83 } 84 85 rkwait(rkaddr) 86 register struct rkdevice *rkaddr; 87 { 88 89 while ((rkaddr->rkcs1 & RK_CRDY) == 0) 90 ; 91 } 92