1*15712Skarels /* idc.c 6.2 83/12/13 */ 26969Ssam 36969Ssam /* 46969Ssam * IDC (RB730) 56969Ssam */ 69804Ssam #include "../machine/pte.h" 76969Ssam 86969Ssam #include "../h/param.h" 96969Ssam #include "../h/inode.h" 107445Sroot #include "../h/fs.h" 119186Ssam 129186Ssam #include "../vaxuba/idcreg.h" 139186Ssam #include "../vaxuba/ubareg.h" 149186Ssam 156969Ssam #include "saio.h" 166969Ssam #include "savax.h" 176969Ssam 186969Ssam u_short idcstd[] = { 0175606 }; 196969Ssam short rb02_off[] = { 0, 400, 0, -1, -1, -1, -1, -1 }; 206969Ssam short rb80_off[] = { 0, 37, 0, -1, -1, -1, 115, 305 }; 216969Ssam 226969Ssam int idc_type[4]; 236969Ssam 246969Ssam idcopen(io) 256969Ssam register struct iob *io; 266969Ssam { 276969Ssam register struct idcdevice *idcaddr; 286969Ssam register int i; 296969Ssam 306969Ssam idcaddr = (struct idcdevice *)((caddr_t)ubauba(io->i_unit) + 0x200); 316969Ssam if (io->i_boff < 0 || io->i_boff > 7) 326969Ssam _stop("idc bad unit"); 336969Ssam idcaddr->idcmpr = IDCGS_GETSTAT; 346969Ssam idcaddr->idccsr = IDC_GETSTAT|(io->i_unit<<8); 356969Ssam idcwait(idcaddr); 366969Ssam i = idcaddr->idcmpr; 376969Ssam idcaddr->idccsr = IDC_CRDY|(1<<(io->i_unit+16)); 386969Ssam idcwait(idcaddr); 396969Ssam idcaddr->idccsr = (io->i_unit<<8)|IDC_RHDR; 406969Ssam idcwait(idcaddr); 416969Ssam if (idcaddr->idccsr & IDC_ERR) { 426969Ssam printf("idc error: idccsr %x\n", idcaddr->idccsr); 436969Ssam _stop("idc fatal error"); 446969Ssam } 456969Ssam i = idcaddr->idcmpr; 466969Ssam i = idcaddr->idcmpr; 476969Ssam if (idcaddr->idccsr & IDC_R80) { 486969Ssam idc_type[io->i_unit] = 1; 49*15712Skarels io->i_boff = rb80_off[io->i_boff] * NRB80SECT * NRB80TRK; 506969Ssam } else { 516969Ssam idc_type[io->i_unit] = 0; 52*15712Skarels io->i_boff = rb02_off[io->i_boff] * NRB02SECT/2 * NRB02TRK; 536969Ssam } 546969Ssam if (io->i_boff < 0) 559305Sfeldman _stop("idc%d: bad unit type", io->i_unit); 566969Ssam } 576969Ssam 586969Ssam idcstrategy(io, func) 596969Ssam register struct iob *io; 606969Ssam { 616969Ssam register struct idcdevice *idcaddr; 626969Ssam int com; 636969Ssam daddr_t bn; 646969Ssam short dn, cn, sn, tn; 659305Sfeldman short ccleft, thiscc = 0; 666969Ssam int ubinfo, errcnt = 0; 676969Ssam 686969Ssam idcaddr = (struct idcdevice *)((caddr_t)ubauba(io->i_unit) + 0x200); 696969Ssam ubinfo = ubasetup(io, 1); 706969Ssam bn = io->i_bn; 719305Sfeldman ccleft = io->i_cc; 729305Sfeldman retry: 736969Ssam dn = io->i_unit; 746969Ssam if (idc_type[dn]) { 756969Ssam cn = bn/(NRB80SECT*NRB80TRK); 766969Ssam sn = bn%NRB80SECT; 776969Ssam tn = (bn / NRB80SECT) % NRB80TRK; 789305Sfeldman thiscc = (NRB80SECT - sn) * 512; 796969Ssam } else { 809305Sfeldman cn = 2*bn/(NRB02SECT*NRB02TRK); 819305Sfeldman sn = (2*bn)%NRB02SECT; 829305Sfeldman tn = (2*bn / NRB02SECT) % NRB02TRK; 839305Sfeldman thiscc = (NRB02SECT - sn) * 256; 846969Ssam } 859305Sfeldman thiscc = MIN(thiscc, ccleft); 869305Sfeldman ccleft -= thiscc; 876969Ssam idcaddr->idccsr = IDC_CRDY|IDC_SEEK|(dn<<8)|(1<<(dn+16)); 886969Ssam idcaddr->idcdar = (cn<<16)|(tn<<8)|sn; 896969Ssam idcaddr->idccsr = IDC_SEEK|(dn<<8); 906969Ssam idcwait(idcaddr); 916969Ssam idcaddr->idccsr &= ~IDC_ATTN; 926969Ssam com = dn<<8; 936969Ssam if (func == READ) 946969Ssam com |= IDC_READ; 956969Ssam else 966969Ssam com |= IDC_WRITE; 976969Ssam idcaddr->idccsr = IDC_CRDY|com; 986969Ssam idcaddr->idcbar = ubinfo&0x3ffff; 999305Sfeldman idcaddr->idcbcr = -thiscc; 1006969Ssam idcaddr->idcdar = (cn<<16)|(tn<<8)|sn; 1016969Ssam idcaddr->idccsr = com; 1026969Ssam idcwait(idcaddr); 1036969Ssam if (idcaddr->idccsr & IDC_ERR) { 104*15712Skarels printf("idc%d error: (cyl,trk,sec)=(%d,%d,%d) csr=%b\n", 105*15712Skarels dn, cn, tn, sn, idcaddr->idccsr, IDCCSR_BITS); 1066969Ssam if (errcnt == 10) { 1076969Ssam printf("idc: unrecovered error\n"); 1089305Sfeldman ubafree(io, ubinfo); 1096969Ssam return (-1); 1106969Ssam } 1116969Ssam errcnt++; 1126969Ssam goto retry; 1136969Ssam } 1146969Ssam if (errcnt) 1156969Ssam printf("idc: recovered by retry\n"); 1169305Sfeldman if (ccleft) { 11712150Sedward bn += thiscc/NBPG; 1189305Sfeldman ubinfo += thiscc; 1196969Ssam goto retry; 1206969Ssam } 1219305Sfeldman ubafree(io, ubinfo); 1229305Sfeldman return (io->i_cc); 1236969Ssam } 1246969Ssam 1256969Ssam idcwait(idcaddr) 1266969Ssam register struct idcdevice *idcaddr; 1276969Ssam { 1286969Ssam register int i; 1296969Ssam 1306969Ssam while ((idcaddr->idccsr & (IDC_CRDY|IDC_DRDY)) != (IDC_CRDY|IDC_DRDY)) 1316969Ssam for (i = 10; i; i--) 1326969Ssam ; 1336969Ssam } 13410024Ssam 13510024Ssam /*ARGSUSED*/ 13610024Ssam idcioctl(io, cmd, arg) 13710024Ssam struct iob *io; 13810024Ssam int cmd; 13910024Ssam caddr_t arg; 14010024Ssam { 14110024Ssam 14210024Ssam return (ECMD); 14310024Ssam } 144