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