1: /*
2: * Copyright (c) 1982, 1986 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: * @(#)rl.c 7.1 (Berkeley) 6/5/86
7: */
8:
9: /*
10: * Standalone RL02 disk driver
11: */
12: #include "../machine/pte.h"
13:
14: #include "../h/param.h"
15: #include "../h/inode.h"
16: #include "../h/fs.h"
17:
18: #include "../vaxuba/rlreg.h"
19: #include "../vaxuba/ubareg.h"
20:
21: #include "saio.h"
22: #include "savax.h"
23:
24: u_short rlstd[] = { 0774400 };
25: short rl_off[] = { 0, 361, 0, -1, -1, -1, -1, -1 };
26:
27: /* struct to keep state info about the controller */
28: struct rl_stat {
29: short rl_dn; /* drive number */
30: short rl_cylnhd; /* cylinder and head */
31: u_short rl_bleft; /* bytes left to transfer */
32: u_short rl_bpart; /* bytes transferred */
33: } rl_stat[] = { -1, 0, 0, 0};
34:
35: rlopen(io)
36: register struct iob *io;
37: {
38: register struct rldevice *rladdr =
39: (struct rldevice *)ubamem(io->i_unit, rlstd[0]);
40: register struct rl_stat *st = &rl_stat[0];
41: register int ctr = 0;
42:
43: if (rl_off[io->i_boff] == -1 ||
44: io->i_boff < 0 || io->i_boff > 7)
45: _stop("rl bad unit");
46:
47: /*
48: * DEC reports that:
49: * For some unknown reason the RL02 (seems to be only drive 1)
50: * does not return a valid drive status the first time that a
51: * GET STATUS request is issued for the drive, in fact it can
52: * take up to three or more GET STATUS requests to obtain the
53: * correct status.
54: * In order to overcome this, the driver has been modified to
55: * issue a GET STATUS request and validate the drive status
56: * returned. If a valid status is not returned after eight
57: * attempts, then an error message is printed.
58: */
59: do {
60: rladdr->rlda.getstat = RL_RESET;
61: rladdr->rlcs = (io->i_unit <<8) | RL_GETSTAT; /* Get status*/
62: rlwait(rladdr);
63: } while( (rladdr->rlmp.getstat&RLMP_STATUS) != RLMP_STATOK && ++ctr<8 );
64:
65: if ((rladdr->rlcs & RL_DE) || (ctr >= 8))
66: _stop("rl unit does not respond");
67:
68: if ((rladdr->rlmp.getstat & RLMP_DT) == 0 ) /* NO RL01'S */
69: _stop("rl01 unit not supported");
70:
71: /* Determine disk posistion */
72: rladdr->rlcs = (io->i_unit << 8) | RL_RHDR;
73: rlwait(rladdr);
74:
75: /* save disk drive posistion */
76: st->rl_cylnhd = (rladdr->rlmp.readhdr & 0177700) >> 6;
77: st->rl_dn = io->i_unit;
78:
79: /* byte offset for cylinder desired */
80: io->i_boff = rl_off[io->i_boff] * NRLBPSC * NRLTRKS * NRLSECT;
81: }
82:
83: rlstrategy(io, func)
84: register struct iob *io;
85: {
86: register struct rldevice *rladdr =
87: (struct rldevice *)ubamem(io->i_unit, rlstd[0]);
88: register struct rl_stat *st = &rl_stat[0];
89: int com;
90: daddr_t bn;
91: short cn, sn, head;
92: int diff, ubinfo, ubaddr, errcnt = 0;
93:
94: retry:
95: ubinfo = ubasetup(io, 1);
96: bn = io->i_bn; /* block number */
97: cn = bn / 40; /* 40 512 byte blocks per cylinder */
98: sn = (bn % 20) << 1;
99: head = (bn / 20) & 1;
100: st->rl_bleft = io->i_cc; /* total number of bytes to trans */
101: ubaddr = ubinfo;
102:
103: stupid_rl:
104: /* find out how many cylinders to seek */
105: diff = (st->rl_cylnhd >> 1) - cn;
106: if ( diff == 0 && (st->rl_cylnhd & 1) == head )
107: goto noseek;
108:
109: /* first time or we switched drives */
110: st->rl_dn = io->i_unit; /* drive number */
111:
112: if ( diff < 0 )
113: rladdr->rlda.seek = -diff<<7 | RLDA_HGH | head << 4;
114: else
115: rladdr->rlda.seek = diff<<7 | RLDA_LOW | head << 4;
116: rladdr->rlcs = (st->rl_dn << 8) | RL_SEEK;
117:
118: /* reset position of drive */
119: st->rl_cylnhd = (cn << 1) | head;
120:
121: noseek:
122: /* wait for controller and drive */
123: while( (rladdr->rlcs & RL_DCRDY) != RL_DCRDY)
124: continue;
125:
126: /* calculate the max number of bytes we can trans */
127: st->rl_bpart = NRLSECT * NRLBPSC - (sn * NRLBPSC);
128: if ( st->rl_bleft < st->rl_bpart )
129: st->rl_bpart = st->rl_bleft;
130:
131: rladdr->rlda.rw = (st->rl_cylnhd << 6) | sn;
132: rladdr->rlmp.rw = -(st->rl_bpart >> 1);
133: rladdr->rlba = ubaddr;
134:
135: com = (st->rl_dn << 8) | ((ubaddr>>12)&RL_BAE);
136:
137: if (func == READ)
138: com |= RL_READ;
139: else
140: com |= RL_WRITE;
141: rladdr->rlcs = com;
142:
143: /* wait for controller and drive */
144: while( (rladdr->rlcs & RL_DCRDY) != RL_DCRDY)
145: continue;
146:
147: if (rladdr->rlcs & RL_ERR) {
148: int status;
149:
150: if ( rladdr->rlcs & RL_DE ) {
151: rladdr->rlda.getstat = RL_GSTAT;
152: rladdr->rlcs = (st->rl_dn << 8) | RL_GETSTAT;
153: rlwait(rladdr);
154: status = rladdr->rlmp.getstat;
155: rladdr->rlda.getstat = RL_RESET;
156: rladdr->rlcs = (st->rl_dn <<8) | RL_GETSTAT;
157: rlwait(rladdr);
158: }
159: printf("rl error: (cyl,head,sec)=(%d,%d,%d) cs=%b mp=%b\n",
160: cn, head, sn, rladdr->rlcs & 0xffff, RLCS_BITS,
161: status, RLER_BITS);
162:
163: /* Determine disk posistion */
164: rladdr->rlcs = (st->rl_dn << 8) | RL_RHDR;
165: rlwait(rladdr);
166:
167: /* save disk drive posistion */
168: st->rl_cylnhd = (rladdr->rlmp.readhdr & 0177700) >> 6;
169:
170: if (errcnt == 10) {
171: printf("rl: unrecovered error\n");
172: return (-1);
173: }
174: errcnt++;
175: goto retry;
176: }
177:
178: /* do we have to finish off the rest of the transfer? */
179: if ( (st->rl_bleft -= st->rl_bpart) > 0 ) {
180: /* increment head and/or cylinder */
181: if ( ++head > 1 ) {
182: cn++; /* want next cyl, head 0 sector 0 */
183: head = 0;
184: }
185:
186: /* we always want sector to be zero */
187: sn = 0;
188:
189: /*
190: * standalone code for ubafree does what regular
191: * ubapurge does and we want to purge last transfer
192: */
193: ubafree(io, ubinfo);
194:
195: ubaddr = ubinfo + io->i_cc - st->rl_bleft;
196:
197: goto stupid_rl;
198: }
199:
200: ubafree(io, ubinfo);
201:
202: if (errcnt)
203: printf("rl: recovered by retry\n");
204: return (io->i_cc);
205: }
206:
207: rlwait(rladdr)
208: register struct rldevice *rladdr;
209: {
210:
211: while ((rladdr->rlcs & RL_CRDY) == 0)
212: continue;
213: }
214:
215: rlioctl(io, cmd, arg)
216: struct iob *io;
217: int cmd;
218: caddr_t arg;
219: {
220:
221: return (ECMD);
222: }
Defined functions
Defined variables
rlstd
defined in line
24; used 2 times
Defined struct's