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