|
|
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.5 (Berkeley) 4/4/90
7: */
8:
9: /*
10: * IDC (RB730)
11: */
12:
13: #include "param.h"
14:
15: #include "../vax/pte.h"
16: #include "../vaxuba/idcreg.h"
17: #include "../vaxuba/ubareg.h"
18:
19: #include "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 == 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.