nhpib.c revision 1.1 1 /*
2 * Copyright (c) 1982, 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)nhpib.c 7.4 (Berkeley) 5/7/91
34 */
35
36 /*
37 * Internal/98624 HPIB driver
38 */
39 #include "hpib.h"
40 #if NHPIB > 0
41
42 #include "sys/param.h"
43 #include "sys/systm.h"
44 #include "sys/buf.h"
45
46 #include "device.h"
47 #include "nhpibreg.h"
48 #include "hpibvar.h"
49 #include "dmavar.h"
50
51 nhpibtype(hc)
52 register struct hp_ctlr *hc;
53 {
54 register struct hpib_softc *hs = &hpib_softc[hc->hp_unit];
55 register struct nhpibdevice *hd = (struct nhpibdevice *)hc->hp_addr;
56
57 if (hc->hp_addr == internalhpib) {
58 hs->sc_type = HPIBA;
59 hs->sc_ba = HPIBA_BA;
60 hc->hp_ipl = HPIBA_IPL;
61 }
62 else if (hd->hpib_cid == HPIBB) {
63 hs->sc_type = HPIBB;
64 hs->sc_ba = hd->hpib_csa & CSA_BA;
65 hc->hp_ipl = HPIB_IPL(hd->hpib_ids);
66 }
67 else
68 return(0);
69 return(1);
70 }
71
72 nhpibreset(unit)
73 {
74 register struct hpib_softc *hs = &hpib_softc[unit];
75 register struct nhpibdevice *hd;
76
77 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
78 hd->hpib_acr = AUX_SSWRST;
79 hd->hpib_ar = hs->sc_ba;
80 hd->hpib_lim = LIS_ERR;
81 hd->hpib_mim = 0;
82 hd->hpib_acr = AUX_CDAI;
83 hd->hpib_acr = AUX_CSHDW;
84 hd->hpib_acr = AUX_SSTD1;
85 hd->hpib_acr = AUX_SVSTD1;
86 hd->hpib_acr = AUX_CPP;
87 hd->hpib_acr = AUX_CHDFA;
88 hd->hpib_acr = AUX_CHDFE;
89 hd->hpib_acr = AUX_RHDF;
90 hd->hpib_acr = AUX_CSWRST;
91 nhpibifc(hd);
92 hd->hpib_ie = IDS_IE;
93 hd->hpib_data = C_DCL;
94 DELAY(100000);
95 }
96
97 nhpibifc(hd)
98 register struct nhpibdevice *hd;
99 {
100 hd->hpib_acr = AUX_TCA;
101 hd->hpib_acr = AUX_CSRE;
102 hd->hpib_acr = AUX_SSIC;
103 DELAY(100);
104 hd->hpib_acr = AUX_CSIC;
105 hd->hpib_acr = AUX_SSRE;
106 }
107
108 nhpibsend(unit, slave, sec, addr, origcnt)
109 register char *addr;
110 {
111 register struct hpib_softc *hs = &hpib_softc[unit];
112 register struct nhpibdevice *hd;
113 register int cnt = origcnt;
114
115 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
116 hd->hpib_acr = AUX_TCA;
117 hd->hpib_data = C_UNL;
118 if (nhpibwait(hd, MIS_BO))
119 goto senderror;
120 hd->hpib_data = C_TAG + hs->sc_ba;
121 hd->hpib_acr = AUX_STON;
122 if (nhpibwait(hd, MIS_BO))
123 goto senderror;
124 hd->hpib_data = C_LAG + slave;
125 if (nhpibwait(hd, MIS_BO))
126 goto senderror;
127 if (sec != -1) {
128 hd->hpib_data = C_SCG + sec;
129 if (nhpibwait(hd, MIS_BO))
130 goto senderror;
131 }
132 hd->hpib_acr = AUX_GTS;
133 if (cnt) {
134 while (--cnt > 0) {
135 hd->hpib_data = *addr++;
136 if (nhpibwait(hd, MIS_BO))
137 goto senderror;
138 }
139 hd->hpib_acr = AUX_EOI;
140 hd->hpib_data = *addr;
141 if (nhpibwait(hd, MIS_BO))
142 goto senderror;
143 hd->hpib_acr = AUX_TCA;
144 #if 0
145 /*
146 * May be causing 345 disks to hang due to interference
147 * with PPOLL mechanism.
148 */
149 hd->hpib_data = C_UNL;
150 (void) nhpibwait(hd, MIS_BO);
151 #endif
152 }
153 return(origcnt);
154 senderror:
155 nhpibifc(hd);
156 return(origcnt - cnt - 1);
157 }
158
159 nhpibrecv(unit, slave, sec, addr, origcnt)
160 register char *addr;
161 {
162 register struct hpib_softc *hs = &hpib_softc[unit];
163 register struct nhpibdevice *hd;
164 register int cnt = origcnt;
165
166 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
167 hd->hpib_acr = AUX_TCA;
168 hd->hpib_data = C_UNL;
169 if (nhpibwait(hd, MIS_BO))
170 goto recverror;
171 hd->hpib_data = C_LAG + hs->sc_ba;
172 hd->hpib_acr = AUX_SLON;
173 if (nhpibwait(hd, MIS_BO))
174 goto recverror;
175 hd->hpib_data = C_TAG + slave;
176 if (nhpibwait(hd, MIS_BO))
177 goto recverror;
178 if (sec != -1) {
179 hd->hpib_data = C_SCG + sec;
180 if (nhpibwait(hd, MIS_BO))
181 goto recverror;
182 }
183 hd->hpib_acr = AUX_RHDF;
184 hd->hpib_acr = AUX_GTS;
185 if (cnt) {
186 while (--cnt >= 0) {
187 if (nhpibwait(hd, MIS_BI))
188 goto recvbyteserror;
189 *addr++ = hd->hpib_data;
190 }
191 hd->hpib_acr = AUX_TCA;
192 hd->hpib_data = (slave == 31) ? C_UNA : C_UNT;
193 (void) nhpibwait(hd, MIS_BO);
194 }
195 return(origcnt);
196 recverror:
197 nhpibifc(hd);
198 recvbyteserror:
199 return(origcnt - cnt - 1);
200 }
201
202 nhpibgo(unit, slave, sec, addr, count, rw)
203 register int unit, slave;
204 char *addr;
205 {
206 register struct hpib_softc *hs = &hpib_softc[unit];
207 register struct nhpibdevice *hd;
208
209 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
210 hs->sc_flags |= HPIBF_IO;
211 if (rw == B_READ)
212 hs->sc_flags |= HPIBF_READ;
213 #ifdef DEBUG
214 else if (hs->sc_flags & HPIBF_READ) {
215 printf("nhpibgo: HPIBF_READ still set\n");
216 hs->sc_flags &= ~HPIBF_READ;
217 }
218 #endif
219 hs->sc_count = count;
220 hs->sc_addr = addr;
221 if (hs->sc_flags & HPIBF_READ) {
222 hs->sc_curcnt = count;
223 dmago(hs->sc_dq.dq_ctlr, addr, count, DMAGO_BYTE|DMAGO_READ);
224 nhpibrecv(unit, slave, sec, 0, 0);
225 hd->hpib_mim = MIS_END;
226 } else {
227 hd->hpib_mim = 0;
228 if (count < hpibdmathresh) {
229 hs->sc_curcnt = count;
230 nhpibsend(unit, slave, sec, addr, count);
231 nhpibdone(unit);
232 return;
233 }
234 hs->sc_curcnt = --count;
235 dmago(hs->sc_dq.dq_ctlr, addr, count, DMAGO_BYTE);
236 nhpibsend(unit, slave, sec, 0, 0);
237 }
238 hd->hpib_ie = IDS_IE | IDS_DMA(hs->sc_dq.dq_ctlr);
239 }
240
241 nhpibdone(unit)
242 register int unit;
243 {
244 register struct hpib_softc *hs = &hpib_softc[unit];
245 register struct nhpibdevice *hd;
246 register int cnt;
247
248 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
249 cnt = hs->sc_curcnt;
250 hs->sc_addr += cnt;
251 hs->sc_count -= cnt;
252 hs->sc_flags |= HPIBF_DONE;
253 hd->hpib_ie = IDS_IE;
254 if ((hs->sc_flags & HPIBF_READ) == 0) {
255 if (hs->sc_count == 1) {
256 (void) nhpibwait(hd, MIS_BO);
257 hd->hpib_acr = AUX_EOI;
258 hd->hpib_data = *hs->sc_addr;
259 hd->hpib_mim = MIS_BO;
260 }
261 #ifdef DEBUG
262 else if (hs->sc_count)
263 panic("nhpibdone");
264 #endif
265 }
266 }
267
268 nhpibintr(unit)
269 register int unit;
270 {
271 register struct hpib_softc *hs = &hpib_softc[unit];
272 register struct nhpibdevice *hd;
273 register struct devqueue *dq;
274 register int stat0;
275 int stat1;
276
277 #ifdef lint
278 if (stat1 = unit) return(1);
279 #endif
280 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
281 if ((hd->hpib_ids & IDS_IR) == 0)
282 return(0);
283 stat0 = hd->hpib_mis;
284 stat1 = hd->hpib_lis;
285 dq = hs->sc_sq.dq_forw;
286 if (hs->sc_flags & HPIBF_IO) {
287 hd->hpib_mim = 0;
288 if ((hs->sc_flags & HPIBF_DONE) == 0)
289 dmastop(hs->sc_dq.dq_ctlr);
290 hd->hpib_acr = AUX_TCA;
291 hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ);
292 dmafree(&hs->sc_dq);
293 (dq->dq_driver->d_intr)(dq->dq_unit);
294 } else if (hs->sc_flags & HPIBF_PPOLL) {
295 hd->hpib_mim = 0;
296 stat0 = nhpibppoll(unit);
297 if (stat0 & (0x80 >> dq->dq_slave)) {
298 hs->sc_flags &= ~HPIBF_PPOLL;
299 (dq->dq_driver->d_intr)(dq->dq_unit);
300 }
301 #ifdef DEBUG
302 else
303 printf("hpib%d: PPOLL intr bad status %x\n",
304 unit, stat0);
305 #endif
306 }
307 return(1);
308 }
309
310 nhpibppoll(unit)
311 int unit;
312 {
313 register struct nhpibdevice *hd;
314 register int ppoll;
315
316 hd = (struct nhpibdevice *)hpib_softc[unit].sc_hc->hp_addr;
317 hd->hpib_acr = AUX_SPP;
318 DELAY(25);
319 ppoll = hd->hpib_cpt;
320 hd->hpib_acr = AUX_CPP;
321 return(ppoll);
322 }
323
324 nhpibwait(hd, x)
325 register struct nhpibdevice *hd;
326 {
327 register int timo = hpibtimeout;
328
329 while ((hd->hpib_mis & x) == 0 && --timo)
330 DELAY(1);
331 if (timo == 0)
332 return(-1);
333 return(0);
334 }
335
336 nhpibppwatch(unit)
337 register int unit;
338 {
339 register struct hpib_softc *hs = &hpib_softc[unit];
340
341 if ((hs->sc_flags & HPIBF_PPOLL) == 0)
342 return;
343 if (nhpibppoll(unit) & (0x80 >> hs->sc_sq.dq_forw->dq_slave))
344 ((struct nhpibdevice *)hs->sc_hc->hp_addr)->hpib_mim = MIS_BO;
345 else
346 timeout(nhpibppwatch, unit, 1);
347 }
348 #endif
349