arrange for dhfdm to be #included
[unix-history] / usr / src / sys / vax / uba / rk.c
CommitLineData
66b4fb09 1/* rk.c 4.2 %G% */
d483c58c 2
66b4fb09 3#include "rk.h"
d483c58c
BJ
4#if NRK > 0
5/*
6 * RK disk driver
7 */
8
9#include "../h/param.h"
10#include "../h/systm.h"
11#include "../h/buf.h"
12#include "../h/conf.h"
13#include "../h/dir.h"
14#include "../h/user.h"
15#include "../h/pte.h"
16#include "../h/map.h"
17#include "../h/uba.h"
18#include "../h/dk.h"
19
20#define NCYL 815
21#define NSECT 22
22#define NTRK 3
23#define NBLK (NTRK*NSECT*NCYL)
24
25/* rkcs1 */
26#define CCLR 0100000 /* controller clear */
27#define DI 040000 /* drive interrupt */
28#define CTO 04000 /* controller timeout */
29#define CDT 02000 /* drive type (rk07/rk06) */
30#define RDY 0200 /* controller ready */
31#define IEN 0100 /* interrupt enable */
32
33
34/* rkcs2 */
35#define DLT 0100000 /* data late */
36#define WCE 040000 /* write check */
37#define UPE 020000 /* unibus parity */
38#define NED 010000 /* non-existant drive */
39#define NEM 04000 /* non-existant memory */
40#define PGE 02000 /* software error */
41#define MDS 01000 /* multiple drive select */
42#define UFE 0400 /* unit field error */
43#define SCLR 040 /* subsystem clear */
44#define cs2abort (NED|NEM|PGE|UFE)
45
46/* rkds */
47#define SVAL 0100000 /* status valid */
48#define CDA 040000 /* current drive attention */
49#define PIP 020000 /* positioning in progress */
50#define WRL 04000 /* write lock */
51#define DDT 0400 /* disk drive type */
52#define DRDY 0200 /* drive ready */
53#define VV 0100 /* volume valid */
54#define DROT 040 /* drive off track */
55#define SPLS 020 /* speed loss */
56#define ACLO 010 /* ac low */
57#define OFFSET 04 /* offset mode */
58#define DRA 01 /* drive available */
59#define dsabort (ACLO|SPLS)
60
61
62/* commands */
63#define SELECT 0
64#define PACK 2
65#define DCLR 4
66#define RESET 012
67#define WCOM 022
68#define RCOM 020
69#define GO 01
70#define DRESET 012
71
72struct device
73{
74 short rkcs1;
75 short rkwc;
76 unsigned short rkba;
77 short rkda;
78 short rkcs2;
79 short rkds;
80 short rker;
81 short rkatt;
82 short rkcyl;
83 short rkdb;
84 short rkmr1;
85 short rkecps;
86 short rkecpt;
87 short rkmr2;
88 short rkmr3;
89} ;
90
91struct buf rktab;
92struct buf rrkbuf;
93
94struct devsize {
95 unsigned int nblocks;
96 int cyloff;
97} rk_sizes [] ={
98 9614, 0, /* 0 - 145 */
99 6600, 146, /* 146 - 245 */
100 37554, 246, /* 246 - 815 */
101 0, 0,
102 0, 0,
103 0, 0,
104 0, 0,
105 0, 0,
106};
107
108rkstrategy(bp)
109register struct buf *bp;
110{
111register dn, sz;
112
113 dn = minor(bp->b_dev);
114 sz = (bp->b_bcount>>9);
115 if (dn > (NRK<<3) || sz+bp->b_blkno >= rk_sizes[dn&07].nblocks) {
116 bp->b_flags |= B_ERROR;
117 iodone(bp);
118 return;
119 }
120 bp->av_forw = (struct buf *)NULL;
121 spl5();
122 if(rktab.b_actf == NULL)
123 rktab.b_actf = bp;
124 else
125 rktab.b_actl->av_forw = bp;
126 rktab.b_actl = bp;
127 if(rktab.b_active == NULL)
128 rkstart();
129 spl0();
130}
131
132int rk_info;
133int tcn, ttn, tsn;
134
135rkstart()
136{
137 register struct buf *bp;
138 register com;
139 register struct device *rkaddr = RKADDR;
140 daddr_t bn;
141 int dn, cn, sn, tn;
142
143 if ((bp = rktab.b_actf) == NULL)
144 return;
145 rktab.b_active++;
146 rk_info = ubasetup(bp, 1);
147 bn = bp->b_blkno;
148 dn = minor(bp->b_dev);
149 cn = bn/(NTRK*NSECT);
150 cn += rk_sizes[dn&07].cyloff;
151 dn >>= 3;
152 if (dn != (rkaddr->rkcs2&07)) {
153 rkaddr->rkcs2 = dn;
154 rkaddr->rkcs1 = CDT | GO;
155 while ((rkaddr->rkcs1&RDY)==0)
156 ;
157 }
158 if ((rkaddr->rkds & VV) == 0) {
159 rkaddr->rkcs1 = PACK | CDT | GO;
160 while ((rkaddr->rkcs1&RDY)==0)
161 ;
162 }
163 tn = bn%(NTRK*NSECT);
164 tn = tn/NSECT;
165 sn = bn%NSECT;
166 rkaddr->rkcs2 = dn;
167 rkaddr->rkcyl = cn;
168 rkaddr->rkda = (tn << 8) | sn;
169 ttn = tn; tcn = cn; tsn = sn;
170 rkaddr->rkba = rk_info;
171 rkaddr->rkwc = -(bp->b_bcount>>1);
172 com = ((rk_info &0x30000) >> 8) | CDT | IEN | GO;
173 if(bp->b_flags & B_READ)
174 com |= RCOM; else
175 com |= WCOM;
176 rkaddr->rkcs1 = com;
177 dk_busy |= 1<<DK_N;
178 dk_xfer[DK_N] += 1;
179 com = bp->b_bcount>>6;
180 dk_wds[DK_N] += com;
181}
182
183rkintr()
184{
185 register struct buf *bp;
186 register d, x;
187 register struct device *rkaddr = RKADDR;
188 int ds, er;
189
190 if (rktab.b_active == NULL)
191 return;
192 dk_busy &= ~(1<<DK_N);
193 bp = rktab.b_actf;
194 rktab.b_active = NULL;
195 if (rkaddr->rkcs1 < 0) { /* error bit */
196 d = (minor(bp->b_dev)>>3);
197 x = 1;
198 if (rkaddr->rkcs1&DI) {
199 printf("DI");
200 }
201 if (rkaddr->rkds&CDA)
202 printf("CDA ");
203 if ((rkaddr->rkds&CDA) || (rkaddr->rkcs1&DI)) {
204 er = (unsigned short)rkaddr->rker;
205 ds = (unsigned short)rkaddr->rkds;
206 rkaddr->rkcs1 = CDT | DCLR | GO;
207 printf("DCLR");
208 } else {
209 if ((rkaddr->rkds&SVAL)==0) {
210 printf("no SVAL\n");
211 x = rkselect(rkaddr, d);
212 printf("x = %d\n", x);
213 }
214 er = (unsigned short)rkaddr->rker;
215 ds = (unsigned short)rkaddr->rkds;
216 }
217 if (rkaddr->rkds&dsabort) {
218 printf("rk %d is down\n", d);
219 rktab.b_errcnt = 10;
220 }
221 if (rkaddr->rkcs2&cs2abort) {
222 printf("cs2 abort %o\n", rkaddr->rkcs2);
223 rktab.b_errcnt = 10;
224 }
225 if (rktab.b_errcnt >= 10) {
226 deverror(bp, er, ds);
227 printf("cn %d tn %d sn %d\n", tcn, ttn, tsn);
228 }
229 rkaddr->rkcs1 = CDT | DCLR | GO;
230 while ((rkaddr->rkcs1&RDY)==0)
231 ;
232 rkaddr->rkcs2 = SCLR;
233 while ((rkaddr->rkcs1&RDY)==0)
234 ;
235 if ((x=rkselect(rkaddr, d)) == 0) {
236 printf("after clears\n");
237 goto bad;
238 }
239 printf("reset\n");
240 rkaddr->rkcs1 = CDT | RESET | GO;
241 while (rkaddr->rkds & PIP)
242 ;
243 if (++rktab.b_errcnt <= 10) {
244 ubafree(rk_info);
245 rkstart();
246 return;
247 }
248bad:
249 bp->b_flags |= B_ERROR;
250 }
251 rktab.b_errcnt = 0;
252 rktab.b_actf = bp->av_forw;
253 bp->b_resid = 0;
254 ubafree(rk_info);
255 iodone(bp);
256 rkstart();
257}
258
259
260rkselect(rkaddr, d)
261register struct device *rkaddr;
262{
263 rkaddr->rkcs2 = d;
264 rkaddr->rkcs1 = CDT|GO;
265 return(rkwait(rkaddr));
266}
267
268rkwait(rkaddr)
269register struct device *rkaddr;
270{
271register t;
272
273 for(t=0x8000; t && ((rkaddr->rkds&DRDY)==0); t--)
274 ;
275 if (t==0)
276 printf("rk not ready\n");
277 return(t);
278}
279
280rkread(dev)
281dev_t dev;
282{
283
284 physio(rkstrategy, &rrkbuf, dev, B_READ, minphys);
285}
286
287rkwrite(dev)
288dev_t dev;
289{
290
291 physio(rkstrategy, &rrkbuf, dev, B_WRITE, minphys);
292}
293#endif