1*6969Ssam /* idc.c 4.1 82/05/27 */ 2*6969Ssam 3*6969Ssam /* 4*6969Ssam * IDC (RB730) 5*6969Ssam * 6*6969Ssam * This driver is full of kludges! 7*6969Ssam * It depends heavily on the 1K file system. 8*6969Ssam */ 9*6969Ssam 10*6969Ssam #include "../h/param.h" 11*6969Ssam #include "../h/idcreg.h" 12*6969Ssam #include "../h/inode.h" 13*6969Ssam #include "../h/pte.h" 14*6969Ssam #include "../h/ubareg.h" 15*6969Ssam #include "saio.h" 16*6969Ssam #include "savax.h" 17*6969Ssam 18*6969Ssam u_short idcstd[] = { 0175606 }; 19*6969Ssam short rb02_off[] = { 0, 400, 0, -1, -1, -1, -1, -1 }; 20*6969Ssam short rb80_off[] = { 0, 37, 0, -1, -1, -1, 115, 305 }; 21*6969Ssam 22*6969Ssam int idc_type[4]; 23*6969Ssam 24*6969Ssam idcopen(io) 25*6969Ssam register struct iob *io; 26*6969Ssam { 27*6969Ssam register struct idcdevice *idcaddr; 28*6969Ssam register int i; 29*6969Ssam 30*6969Ssam idcaddr = (struct idcdevice *)((caddr_t)ubauba(io->i_unit) + 0x200); 31*6969Ssam if (io->i_boff < 0 || io->i_boff > 7) 32*6969Ssam _stop("idc bad unit"); 33*6969Ssam idcaddr->idcmpr = IDCGS_GETSTAT; 34*6969Ssam idcaddr->idccsr = IDC_GETSTAT|(io->i_unit<<8); 35*6969Ssam idcwait(idcaddr); 36*6969Ssam i = idcaddr->idcmpr; 37*6969Ssam idcaddr->idccsr = IDC_CRDY|(1<<(io->i_unit+16)); 38*6969Ssam idcwait(idcaddr); 39*6969Ssam idcaddr->idccsr = (io->i_unit<<8)|IDC_RHDR; 40*6969Ssam idcwait(idcaddr); 41*6969Ssam if (idcaddr->idccsr & IDC_ERR) { 42*6969Ssam printf("idc error: idccsr %x\n", idcaddr->idccsr); 43*6969Ssam _stop("idc fatal error"); 44*6969Ssam } 45*6969Ssam i = idcaddr->idcmpr; 46*6969Ssam i = idcaddr->idcmpr; 47*6969Ssam if (idcaddr->idccsr & IDC_R80) { 48*6969Ssam idc_type[io->i_unit] = 1; 49*6969Ssam io->i_boff = rb80_off[io->i_boff]; 50*6969Ssam } else { 51*6969Ssam idc_type[io->i_unit] = 0; 52*6969Ssam io->i_boff = rb02_off[io->i_boff]; 53*6969Ssam } 54*6969Ssam if (io->i_boff < 0) 55*6969Ssam _stop("idc bad unit"); 56*6969Ssam } 57*6969Ssam 58*6969Ssam idcstrategy(io, func) 59*6969Ssam register struct iob *io; 60*6969Ssam { 61*6969Ssam register struct idcdevice *idcaddr; 62*6969Ssam int com; 63*6969Ssam daddr_t bn; 64*6969Ssam short dn, cn, sn, tn; 65*6969Ssam int ubinfo, errcnt = 0; 66*6969Ssam 67*6969Ssam idcaddr = (struct idcdevice *)((caddr_t)ubauba(io->i_unit) + 0x200); 68*6969Ssam retry: 69*6969Ssam ubinfo = ubasetup(io, 1); 70*6969Ssam bn = io->i_bn; 71*6969Ssam dn = io->i_unit; 72*6969Ssam if (io->i_cc != 1024) printf("idc: count %d != 1024\n", io->i_cc); 73*6969Ssam if (idc_type[dn]) { 74*6969Ssam cn = bn/(NRB80SECT*NRB80TRK); 75*6969Ssam sn = bn%NRB80SECT; 76*6969Ssam tn = (bn / NRB80SECT) % NRB80TRK; 77*6969Ssam if (sn == NRB80SECT) 78*6969Ssam io->i_cc = 512; 79*6969Ssam } else { 80*6969Ssam bn *= 2; 81*6969Ssam cn = bn/(NRB02SECT*NRB02TRK); 82*6969Ssam sn = bn%NRB02SECT; 83*6969Ssam tn = (bn / NRB02SECT) % NRB02TRK; 84*6969Ssam } 85*6969Ssam cn += io->i_boff; 86*6969Ssam idcaddr->idccsr = IDC_CRDY|IDC_SEEK|(dn<<8)|(1<<(dn+16)); 87*6969Ssam idcaddr->idcdar = (cn<<16)|(tn<<8)|sn; 88*6969Ssam idcaddr->idccsr = IDC_SEEK|(dn<<8); 89*6969Ssam idcwait(idcaddr); 90*6969Ssam idcaddr->idccsr &= ~IDC_ATTN; 91*6969Ssam com = dn<<8; 92*6969Ssam if (func == READ) 93*6969Ssam com |= IDC_READ; 94*6969Ssam else 95*6969Ssam com |= IDC_WRITE; 96*6969Ssam idcaddr->idccsr = IDC_CRDY|com; 97*6969Ssam idcaddr->idcbar = ubinfo&0x3ffff; 98*6969Ssam idcaddr->idcbcr = -io->i_cc; 99*6969Ssam idcaddr->idcdar = (cn<<16)|(tn<<8)|sn; 100*6969Ssam idcaddr->idccsr = com; 101*6969Ssam idcwait(idcaddr); 102*6969Ssam ubafree(io, ubinfo); 103*6969Ssam if (idcaddr->idccsr & IDC_ERR) { 104*6969Ssam printf("idc error: (cyl,trk,sec)=(%d,%d,%d) csr=%b\n", 105*6969Ssam cn, tn, sn, idcaddr->idccsr, IDCCSR_BITS); 106*6969Ssam if (errcnt == 10) { 107*6969Ssam printf("idc: unrecovered error\n"); 108*6969Ssam return (-1); 109*6969Ssam } 110*6969Ssam errcnt++; 111*6969Ssam goto retry; 112*6969Ssam } 113*6969Ssam if (errcnt) 114*6969Ssam printf("idc: recovered by retry\n"); 115*6969Ssam if (idc_type[dn] && sn == NRB80SECT) { 116*6969Ssam io->i_bn++; 117*6969Ssam goto retry; 118*6969Ssam } 119*6969Ssam return (1024); 120*6969Ssam } 121*6969Ssam 122*6969Ssam idcwait(idcaddr) 123*6969Ssam register struct idcdevice *idcaddr; 124*6969Ssam { 125*6969Ssam register int i; 126*6969Ssam 127*6969Ssam while ((idcaddr->idccsr & (IDC_CRDY|IDC_DRDY)) != (IDC_CRDY|IDC_DRDY)) 128*6969Ssam for (i = 10; i; i--) 129*6969Ssam ; 130*6969Ssam } 131