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