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