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