1: /*
2: * ML11 solid state disk driver.
3: *
4: * This driver was written by Fred Canter and distributed on the
5: * DEC v7m UNIX tape. It has been modified for 2BSD and has been
6: * included with the permission of the DEC UNIX Engineering Group.
7: *
8: * This driver does not support mixed drive types,
9: * it requires that the ML11 be on a separate
10: * RH11 or RH70 controller and that there be only
11: * ML11 drives on that controller.
12: */
13:
14: /*
15: * SCCS id @(#)ml.c 2.1 (Berkeley) 8/5/83
16: */
17:
18: #include "ml.h"
19: #if NML > 0
20: #include "param.h"
21: #include <sys/systm.h>
22: #include <sys/buf.h>
23: #include <sys/conf.h>
24: #include <sys/dir.h>
25: #include <sys/user.h>
26: #include <sys/seg.h>
27: #include <sys/mlreg.h>
28:
29: bool_t ml_alive;
30: extern struct mldevice *MLADDR;
31:
32: /*
33: * Ml_sizes[] contains the size of each ML11
34: * unit in blocks. The size is set dynamicaly
35: * by reading the number of arrays from the ML maintenance
36: * register. The array type bit the the ML maintenacne
37: * register is used to adjust the number of blocks per array
38: * from 512 (16k chips) to 2048 (64k chips).
39: */
40: short ml_sizes[NML];
41:
42: struct buf mltab;
43: struct buf rmlbuf;
44:
45: void
46: mlprobe()
47: {
48: register unit;
49:
50: if (fioword (MLADDR) != -1) {
51: ml_alive++;
52: for (unit = 0; unit < NML; unit++) {
53: MLADDR->mlcs2.c[0] = unit;
54:
55: /*
56: * Find the size of the ML11 unit by reading
57: * the number of array modules from the ML
58: * maintenance register. There are 512
59: * blocks per array unless the array type
60: * bit is set, in which case there are 2048
61: * blocks per array.
62: */
63: ml_sizes[unit] = (MLADDR->mlmr >> 2) & 037000;
64: if (MLADDR->mlmr & 02000)
65: ml_sizes[unit] <<= 2;
66: }
67: #if PDP11 == 70 || PDP11 == GENERIC
68: if (fioword (&(MLADDR->mlbae)) != -1)
69: mltab.b_flags |= B_RH70;
70: #endif
71: }
72: }
73:
74:
75: mlstrategy(bp)
76: register struct buf *bp;
77: {
78: register struct buf *dp;
79: register unit;
80: int tr;
81: long sz, bn;
82:
83: unit = minor(bp->b_dev) & 07;
84: if (!ml_alive || unit >= NML)
85: goto bad;
86: #ifdef UNIBUS_MAP
87: if ((bp->b_flags & B_PHYS) && ((mltab.b_flags & B_RH70) == 0))
88: mapalloc(bp);
89: #endif
90:
91: (void) _spl5();
92: if ((MLADDR->mldt & 0377) != ML11)
93: goto bad;
94: MLADDR->mlcs2.c[0] = unit;
95:
96: /*
97: * Check the ML11 transfer rate.
98: * 2mb is too fast for any pdp11.
99: * 1mb allowed on pdp11/70 only.
100: * .5mb & .25mb ok on any processor.
101: */
102: tr = MLADDR->mlmr & 01400;
103: if ((tr == MLMR_2MB) || ((tr == MLMR_1MB)
104: && ((mltab.b_flags & B_RH70) == 0))) {
105: printf("\nML11 xfer rate error\n");
106: goto bad;
107: }
108: sz = bp->b_bcount;
109: sz = (sz + 511) >> 9;
110: if (bp->b_blkno < 0 || (bp->b_blkno + sz) > ml_sizes[unit]) {
111: goto bad;
112: }
113:
114: bp->av_forw = NULL;
115: dp = &mltab;
116: if (dp->b_actf == NULL)
117: dp->b_actf = bp;
118: else
119: dp->b_actl->av_forw = bp;
120: dp->b_actl = bp;
121: if (dp->b_active == NULL)
122: mlstart();
123: return;
124:
125: bad:
126: u.u_error = ENXIO;
127: bp->b_flags |= B_ERROR;
128: iodone(bp);
129: }
130:
131: mlstart()
132: {
133: register struct buf *bp;
134: register unit, com;
135:
136: if ((bp = mltab.b_actf) == NULL)
137: return;
138: mltab.b_active++;
139: unit = minor(bp->b_dev) & 07;
140: (void) _spl5();
141: MLADDR->mlcs2.w = unit;
142: if ((MLADDR->mlds & MLDS_VV) == 0)
143: MLADDR->mlcs1.w = ML_PRESET | ML_GO;
144: if ((MLADDR->mlds & (MLDS_DPR | MLDS_MOL)) != (MLDS_DPR | MLDS_MOL)) {
145: mltab.b_active = 0;
146: mltab.b_errcnt = 0;
147: bp->b_actf = bp->av_forw;
148: bp->b_flags |= B_ERROR;
149: iodone(bp);
150: (void) _spl0();
151: return;
152: }
153: MLADDR->mlda = bp->b_blkno;
154: MLADDR->mlba = bp->b_un.b_addr;
155: #if PDP11 == 70 || PDP11 == GENERIC
156: if (mltab.b_flags & B_RH70)
157: MLADDR->mlbae = bp->b_xmem;
158: #endif
159: MLADDR->mlwc = -(bp->b_bcount >> 1);
160: com = ((bp->b_xmem & 3) << 8) | ML_IE | ML_GO;
161: if (bp->b_flags & B_READ)
162: com |= ML_RCOM;
163: else
164: com |= ML_WCOM;
165: MLADDR->mlcs1.w = com;
166: #ifdef ML_DKN
167: dk_busy |= 1 << (ML_DKN + NML);
168: dk_numb[ML_DKN + NML] += 1;
169: dk_wds[ML_DKN + NML] += bp->b_bcount >> 6;
170: #endif ML_DKN
171: (void) _spl0();
172: }
173:
174: mlintr()
175: {
176: register struct buf *bp;
177: register unit;
178: int as;
179: int ctr;
180:
181: if (mltab.b_active == NULL)
182: return;
183: as = MLADDR->mlas & 0377;
184: bp = mltab.b_actf;
185: unit = minor(bp->b_dev) & 7;
186: #ifdef ML_DKN
187: dk_busy &= ~(1 << (ML_DKN + NML));
188: #endif
189: as &= ~(1<<unit);
190: MLADDR->mlas = as;
191: MLADDR->mlcs2.c[0] = unit;
192: if (MLADDR->mlcs1.w & ML_TRE) { /* error bit */
193: ctr = 0;
194: while (((MLADDR->mlds & MLDS_DRY) == 0) && --ctr)
195: ;
196: if (mltab.b_errcnt == 0)
197: #ifdef UCB_DEVERR
198: harderr (bp, "ml");
199: printf ("cs2=%b er=%b\n", MLADDR->mlcs2.w,
200: MLCS2_BITS, MLADDR->mler, MLER_BITS);
201: #else
202: deverror(bp, MLADDR->mlcs2.w, MLADDR->mler);
203: #endif UCB_DEVERR
204: MLADDR->mlcs1.w = ML_DCLR | ML_GO;
205: if (++mltab.b_errcnt <= 10) {
206: mlstart();
207: return;
208: }
209: bp->b_flags |= B_ERROR;
210: }
211: mltab.b_errcnt = 0;
212: mltab.b_actf = bp->av_forw;
213: bp->b_resid = 0;
214: iodone(bp);
215: mlstart();
216: }
217:
218: mlread(dev)
219: dev_t dev;
220: {
221: physio(mlstrategy, &rmlbuf, dev, B_READ);
222: }
223:
224: mlwrite(dev)
225: dev_t dev;
226: {
227: physio(mlstrategy, &rmlbuf, dev, B_WRITE);
228: }
229: #endif NML
Defined functions
Defined variables
mltab
defined in line
42; used 15 times
- in line 69,
87,
104,
115,
136-138(2),
145-146(2),
156,
181-184(2),
196,
205,
211-212(2)