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