misc pre-mba changes (non-recursive printf, futz, resuba, %uXX...)
[unix-history] / usr / src / sys / vax / uba / rk.c
CommitLineData
9357d0f1 1/* rk.c 4.5 %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,
9357d0f1 105 53790, 0,
d483c58c
BJ
106};
107
108rkstrategy(bp)
109register struct buf *bp;
110{
111register dn, sz;
112
113 dn = minor(bp->b_dev);
9357d0f1
BJ
114 sz = ((bp->b_bcount+511)>>9);
115 if (dn > (NRK<<3) || sz+bp->b_blkno > rk_sizes[dn&07].nblocks) {
d483c58c
BJ
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;
c134650e
BJ
177 dk_busy |= 1<<RKDK_N;
178 dk_xfer[RKDK_N] += 1;
d483c58c 179 com = bp->b_bcount>>6;
c134650e 180 dk_wds[RKDK_N] += com;
d483c58c
BJ
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;
c134650e 192 dk_busy &= ~(1<<RKDK_N);
d483c58c
BJ
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) {
9357d0f1 199 printf("rkintr: DI\n");
d483c58c
BJ
200 }
201 if (rkaddr->rkds&CDA)
9357d0f1 202 printf("rkintr: CDA\n");
d483c58c
BJ
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;
d483c58c
BJ
207 } else {
208 if ((rkaddr->rkds&SVAL)==0) {
9357d0f1
BJ
209 x = 0x8000 - rkselect(rkaddr, d);
210 printf("rkintr: no SVAL, delay %d\n", x);
d483c58c
BJ
211 }
212 er = (unsigned short)rkaddr->rker;
213 ds = (unsigned short)rkaddr->rkds;
214 }
215 if (rkaddr->rkds&dsabort) {
216 printf("rk %d is down\n", d);
217 rktab.b_errcnt = 10;
218 }
219 if (rkaddr->rkcs2&cs2abort) {
220 printf("cs2 abort %o\n", rkaddr->rkcs2);
221 rktab.b_errcnt = 10;
222 }
223 if (rktab.b_errcnt >= 10) {
224 deverror(bp, er, ds);
225 printf("cn %d tn %d sn %d\n", tcn, ttn, tsn);
226 }
227 rkaddr->rkcs1 = CDT | DCLR | GO;
228 while ((rkaddr->rkcs1&RDY)==0)
229 ;
230 rkaddr->rkcs2 = SCLR;
231 while ((rkaddr->rkcs1&RDY)==0)
232 ;
233 if ((x=rkselect(rkaddr, d)) == 0) {
234 printf("after clears\n");
235 goto bad;
236 }
d483c58c
BJ
237 rkaddr->rkcs1 = CDT | RESET | GO;
238 while (rkaddr->rkds & PIP)
239 ;
240 if (++rktab.b_errcnt <= 10) {
b28deaf8 241 ubarelse(&rk_info);
d483c58c
BJ
242 rkstart();
243 return;
244 }
245bad:
246 bp->b_flags |= B_ERROR;
247 }
248 rktab.b_errcnt = 0;
249 rktab.b_actf = bp->av_forw;
250 bp->b_resid = 0;
b28deaf8 251 ubarelse(&rk_info);
d483c58c
BJ
252 iodone(bp);
253 rkstart();
254}
255
256
257rkselect(rkaddr, d)
258register struct device *rkaddr;
259{
260 rkaddr->rkcs2 = d;
261 rkaddr->rkcs1 = CDT|GO;
262 return(rkwait(rkaddr));
263}
264
265rkwait(rkaddr)
266register struct device *rkaddr;
267{
268register t;
269
270 for(t=0x8000; t && ((rkaddr->rkds&DRDY)==0); t--)
271 ;
272 if (t==0)
273 printf("rk not ready\n");
274 return(t);
275}
276
277rkread(dev)
278dev_t dev;
279{
280
281 physio(rkstrategy, &rrkbuf, dev, B_READ, minphys);
282}
283
284rkwrite(dev)
285dev_t dev;
286{
287
288 physio(rkstrategy, &rrkbuf, dev, B_WRITE, minphys);
289}
290#endif