1: /*
2: * SCCS id @(#)rp.c 2.1 (Berkeley) 8/31/83
3: */
4:
5: /*
6: * RP03 disk driver
7: */
8:
9: #include "rp.h"
10: #if NRP > 0
11: #include "param.h"
12: #include <sys/systm.h>
13: #include <sys/buf.h>
14: #include <sys/dir.h>
15: #include <sys/conf.h>
16: #include <sys/user.h>
17: #include <sys/rpreg.h>
18:
19: extern struct size rp_sizes[];
20: struct rpdevice *RPADDR;
21:
22: struct buf rptab;
23: #ifdef UCB_DBUFS
24: struct buf rrpbuf[NRP];
25: #else
26: struct buf rrpbuf;
27: #endif
28:
29: #define RP_NSECT 10
30: #define RP_NTRAC 20
31:
32: rpattach(addr, unit)
33: struct rpdevice *addr;
34: {
35: if (unit != 0)
36: return(0);
37: RPADDR = addr;
38: return(1);
39: }
40:
41: rpstrategy(bp)
42: register struct buf *bp;
43: {
44: register struct buf *dp;
45: register int unit;
46: long sz;
47:
48: unit = minor(bp->b_dev);
49: sz = bp->b_bcount;
50: sz = (sz + 511) >> 9;
51: if (RPADDR == (struct rpdevice *) NULL) {
52: bp->b_error = ENXIO;
53: goto errexit;
54: }
55: if (unit >= (NRP << 3) || bp->b_blkno + sz > rp_sizes[unit & 07].nblocks) {
56: bp->b_error = EINVAL;
57: errexit:
58: bp->b_flags |= B_ERROR;
59: iodone(bp);
60: return;
61: }
62: #ifdef UNIBUS_MAP
63: mapalloc(bp);
64: #endif
65: bp->av_forw = NULL;
66: unit >>= 3;
67: (void) _spl5();
68: dp = &rptab;
69: if (dp->b_actf == NULL)
70: dp->b_actf = bp;
71: else
72: dp->b_actl->av_forw = bp;
73: dp->b_actl = bp;
74: if (dp->b_active == NULL)
75: rpstart();
76: (void) _spl0();
77: }
78:
79: rpstart()
80: {
81: register struct rpdevice *rpaddr = RPADDR;
82: register struct buf *bp;
83: register int unit;
84: int com, cn, tn, sn, dn;
85: daddr_t bn;
86:
87:
88: if ((bp = rptab.b_actf) == NULL)
89: return;
90: rptab.b_active++;
91: unit = minor(bp->b_dev);
92: dn = unit >> 3;
93: bn = bp->b_blkno;
94: cn = bn / (RP_NTRAC * RP_NSECT) + rp_sizes[unit & 07].cyloff;
95: sn = bn % (RP_NTRAC * RP_NSECT);
96: tn = sn / RP_NSECT;
97: sn = sn % RP_NSECT;
98: rpaddr->rpcs.w = (dn << 8);
99: rpaddr->rpda = (tn << 8) | sn;
100: rpaddr->rpca = cn;
101: rpaddr->rpba = bp->b_un.b_addr;
102: rpaddr->rpwc = -(bp->b_bcount >> 1);
103: com = ((bp->b_xmem & 3) << 4) | RP_IDE | RP_GO;
104: if (bp->b_flags & B_READ)
105: com |= RP_RCOM;
106: else
107: com |= RP_WCOM;
108:
109: rpaddr->rpcs.w |= com;
110: #ifdef RP_DKN
111: dk_busy |= 1 << RP_DKN;
112: dk_numb[RP_DKN]++;
113: dk_wds[RP_DKN] += bp->b_bcount >> 6;
114: #endif RP_DKN
115: }
116:
117: rpintr()
118: {
119: register struct rpdevice *rpaddr = RPADDR;
120: register struct buf *bp;
121: register int ctr;
122:
123: if (rptab.b_active == NULL)
124: return;
125: #ifdef RP_DKN
126: dk_busy &= ~(1 << RP_DKN);
127: #endif RP_DKN
128: bp = rptab.b_actf;
129: rptab.b_active = NULL;
130: if (rpaddr->rpcs.w & RP_ERR) {
131: while ((rpaddr->rpcs.w & RP_RDY) == 0)
132: ;
133: if (rpaddr->rper & RPER_WPV)
134: /*
135: * Give up on write locked devices
136: * immediately.
137: */
138: printf("rp%d: write locked\n", minor(bp->b_dev));
139: else
140: {
141: #ifdef UCB_DEVERR
142: harderr(bp, "rp");
143: printf("er=%b ds=%b\n", rpaddr->rper, RPER_BITS,
144: rpaddr->rpds, RPDS_BITS);
145: #else
146: deverror(bp, rpaddr->rper, rpaddr->rpds);
147: #endif
148: if(rpaddr->rpds & (RPDS_SUFU | RPDS_SUSI | RPDS_HNF)) {
149: rpaddr->rpcs.c[0] = RP_HSEEK | RP_GO;
150: ctr = 0;
151: while ((rpaddr->rpds & RPDS_SUSU) && --ctr)
152: ;
153: }
154: rpaddr->rpcs.w = RP_IDLE | RP_GO;
155: ctr = 0;
156: while ((rpaddr->rpcs.w & RP_RDY) == 0 && --ctr)
157: ;
158: if (++rptab.b_errcnt <= 10) {
159: rpstart();
160: return;
161: }
162: }
163: bp->b_flags |= B_ERROR;
164: }
165: rptab.b_errcnt = 0;
166: rptab.b_actf = bp->av_forw;
167: bp->b_resid = -(rpaddr->rpwc << 1);
168: iodone(bp);
169: rpstart();
170: }
171:
172: rpread(dev)
173: dev_t dev;
174: {
175: #ifdef UCB_DBUFS
176: register int unit = (minor(dev) >> 3) & 07;
177:
178: if (unit >= NRP)
179: u.u_error = ENXIO;
180: else
181: physio(rpstrategy, &rrpbuf[unit], dev, B_READ);
182: #else
183: physio(rpstrategy, &rrpbuf, dev, B_READ);
184: #endif
185: }
186:
187: rpwrite(dev)
188: dev_t dev;
189: {
190: #ifdef UCB_DBUFS
191: register int unit = (minor(dev) >> 3) & 07;
192:
193: if (unit >= NRP)
194: u.u_error = ENXIO;
195: else
196: physio(rpstrategy, &rrpbuf[unit], dev, B_WRITE);
197: #else
198: physio(rpstrategy, &rrpbuf, dev, B_WRITE);
199: #endif
200: }
201: #endif NRP
Defined functions
Defined variables
rptab
defined in line
22; used 11 times
Defined macros