|
|
1.1 root 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) 7/9/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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.