1: #
2: /*
3: */
4:
5: /*
6: * RP04 disk driver
7: *
8: * This driver has been tested on a working RP04 for a few hours.
9: * It does not attempt ECC error correction and is probably
10: * deficient in general in the case of errors and when packs
11: * are dismounted.
12: */
13:
14: #include "../param.h"
15: #include "../buf.h"
16: #include "../conf.h"
17: #include "../user.h"
18:
19: struct {
20: int hpcs1; /* Control and Status register 1 */
21: int hpwc; /* Word count register */
22: int hpba; /* UNIBUS address register */
23: int hpda; /* Desired address register */
24: int hpcs2; /* Control and Status register 2*/
25: int hpds; /* Drive Status */
26: int hper1; /* Error register 1 */
27: int hpas; /* Attention Summary */
28: int hpla; /* Look ahead */
29: int hpdb; /* Data buffer */
30: int hpmr; /* Maintenance register */
31: int hpdt; /* Drive type */
32: int hpsn; /* Serial number */
33: int hpof; /* Offset register */
34: int hpca; /* Desired Cylinder address register*/
35: int hpcc; /* Current Cylinder */
36: int hper2; /* Error register 2 */
37: int hper3; /* Error register 3 */
38: int hppos; /* Burst error bit position */
39: int hppat; /* Burst error bit pattern */
40: int hpbae; /* 11/70 bus extension */
41: };
42:
43: #define HPADDR 0176700
44: #define NHP 8
45:
46: struct {
47: char *nblocks;
48: int cyloff;
49: } hp_sizes[] {
50: 9614, 0, /* cyl 0 thru 23 */
51: /* cyl 24 thru 43 available */
52: -1, 44, /* cyl 44 thru 200 */
53: -1, 201, /* cyl 201 thru 357 */
54: 20900, 358, /* cyl 358 thru 407 */
55: /* cyl 408 thru 410 blank */
56: 40600, 0,
57: 40600, 100,
58: 40600, 200,
59: 40600, 300,
60: };
61:
62:
63: struct devtab hptab;
64: struct buf hpbuf;
65:
66: char hp_openf;
67:
68: /* Drive Commands */
69: #define GO 01
70: #define PRESET 020
71: #define RECAL 06
72: #define RCLR 010
73: #define OFFSET 014
74:
75: #define READY 0200 /* hpds - drive ready */
76: #define PIP 020000 /* hpds - Positioning Operation in Progress */
77: #define ERR 040000 /* hpcs1 - composite error */
78:
79: #define DU 040000 /* hper1 - Drive Unsafe */
80: #define DTE 010000 /* hper1 - Drive Timing Error */
81: #define OPI 020000 /* hper1 - Operation Incomplete */
82: /* Error Correction Code errors */
83: #define DCK 0100000 /* hper1 - Data Check error */
84: #define ECH 0100 /* hper1 - ECC hard error */
85:
86: #define CLR 040 /* hpcs2 - Controller Clear */
87:
88: #define FMT22 010000 /* hpof - 16 bit /word format */
89: /*
90: * Use av_back to save track+sector,
91: * b_resid for cylinder.
92: */
93:
94: #define trksec av_back
95: #define cylin b_resid
96:
97: hpopen()
98: {
99:
100: if(!hp_openf){
101: hp_openf++;
102: HPADDR->hpcs2 = CLR;
103: HPADDR->hpcs1 = RCLR|GO;
104: HPADDR->hpcs1 = PRESET|GO;
105: HPADDR->hpof = FMT22;
106: }
107: }
108:
109: hpstrategy(abp)
110: struct buf *abp;
111: {
112: register struct buf *bp;
113: register char *p1, *p2;
114:
115: bp = abp;
116: p1 = &hp_sizes[bp->b_dev.d_minor&07];
117: if (bp->b_dev.d_minor >= (NHP<<3) ||
118: bp->b_blkno >= p1->nblocks) {
119: bp->b_flags =| B_ERROR;
120: iodone(bp);
121: return;
122: }
123: bp->av_forw = 0;
124: bp->cylin = p1->cyloff;
125: p1 = bp->b_blkno;
126: p2 = lrem(p1, 22);
127: p1 = ldiv(p1, 22);
128: bp->trksec = (p1%19)<<8 | p2;
129: bp->cylin =+ p1/19;
130: spl5();
131: if ((p1 = hptab.d_actf)==0)
132: hptab.d_actf = bp;
133: else {
134: for (; p2 = p1->av_forw; p1 = p2) {
135: if (p1->cylin <= bp->cylin
136: && bp->cylin < p2->cylin
137: || p1->cylin >= bp->cylin
138: && bp->cylin > p2->cylin)
139: break;
140: }
141: bp->av_forw = p2;
142: p1->av_forw = bp;
143: }
144: if (hptab.d_active==0)
145: hpstart();
146: spl0();
147: }
148:
149: hpstart()
150: {
151: register struct buf *bp;
152:
153: if ((bp = hptab.d_actf) == 0)
154: return;
155: hptab.d_active++;
156: HPADDR->hpcs2 = bp->b_dev.d_minor >> 3;
157: HPADDR->hpca = bp->cylin;
158: rhstart(bp, &HPADDR->hpda, bp->trksec, &HPADDR->hpbae);
159: }
160:
161: hpintr()
162: {
163: register struct buf *bp;
164: register int ctr;
165:
166: if (hptab.d_active == 0)
167: return;
168: bp = hptab.d_actf;
169: hptab.d_active = 0;
170: if (HPADDR->hpcs1 & ERR) { /* error bit */
171: deverror(bp, HPADDR->hpcs2, 0);
172: if(HPADDR->hper1 & (DU|DTE|OPI)) {
173: HPADDR->hpcs2 = CLR;
174: HPADDR->hpcs1 = RECAL|GO;
175: ctr = 0;
176: while ((HPADDR->hpds&PIP) && --ctr);
177: }
178: HPADDR->hpcs1 = RCLR|GO;
179: if (++hptab.d_errcnt <= 10) {
180: hpstart();
181: return;
182: }
183: bp->b_flags =| B_ERROR;
184: }
185: hptab.d_errcnt = 0;
186: hptab.d_actf = bp->av_forw;
187: bp->b_resid = HPADDR->hpwc;
188: iodone(bp);
189: hpstart();
190: }
191:
192: hpread(dev)
193: {
194:
195: if(hpphys(dev))
196: physio(hpstrategy, &hpbuf, dev, B_READ);
197: }
198:
199: hpwrite(dev)
200: {
201:
202: if(hpphys(dev))
203: physio(hpstrategy, &hpbuf, dev, B_WRITE);
204: }
205:
206: hpphys(dev)
207: {
208: register c;
209:
210: c = lshift(u.u_offset, -9);
211: c =+ ldiv(u.u_count+511, 512);
212: if(c > hp_sizes[dev.d_minor & 07].nblocks) {
213: u.u_error = ENXIO;
214: return(0);
215: }
216: return(1);
217: }
Defined functions
Defined variables
hpbuf
defined in line
64; used 2 times
hptab
defined in line
63; used 11 times
Defined macros
CLR
defined in line
86; used 2 times
DCK
defined in line
83;
never used
DTE
defined in line
80; used 1 times
DU
defined in line
79; used 1 times
ECH
defined in line
84;
never used
ERR
defined in line
77; used 1 times
FMT22
defined in line
88; used 1 times
GO
defined in line
69; used 4 times
HPADDR
defined in line
43; used 16 times
NHP
defined in line
44; used 1 times
OPI
defined in line
81; used 1 times
PIP
defined in line
76; used 1 times
RCLR
defined in line
72; used 2 times
READY
defined in line
75;
never used
RECAL
defined in line
71; used 1 times
cylin
defined in line
95; used 11 times