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