nhpib.c revision 1.2 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 * from: @(#)nhpib.c 7.4 (Berkeley) 5/7/91
34 * $Id: nhpib.c,v 1.2 1993/05/22 07:56:39 cgd Exp $
35 */
36
37 /*
38 * Internal/98624 HPIB driver
39 */
40 #include "hpib.h"
41 #if NHPIB > 0
42
43 #include "sys/param.h"
44 #include "sys/systm.h"
45 #include "sys/buf.h"
46
47 #include "device.h"
48 #include "nhpibreg.h"
49 #include "hpibvar.h"
50 #include "dmavar.h"
51
52 nhpibtype(hc)
53 register struct hp_ctlr *hc;
54 {
55 register struct hpib_softc *hs = &hpib_softc[hc->hp_unit];
56 register struct nhpibdevice *hd = (struct nhpibdevice *)hc->hp_addr;
57
58 if (hc->hp_addr == internalhpib) {
59 hs->sc_type = HPIBA;
60 hs->sc_ba = HPIBA_BA;
61 hc->hp_ipl = HPIBA_IPL;
62 }
63 else if (hd->hpib_cid == HPIBB) {
64 hs->sc_type = HPIBB;
65 hs->sc_ba = hd->hpib_csa & CSA_BA;
66 hc->hp_ipl = HPIB_IPL(hd->hpib_ids);
67 }
68 else
69 return(0);
70 return(1);
71 }
72
73 nhpibreset(unit)
74 {
75 register struct hpib_softc *hs = &hpib_softc[unit];
76 register struct nhpibdevice *hd;
77
78 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
79 hd->hpib_acr = AUX_SSWRST;
80 hd->hpib_ar = hs->sc_ba;
81 hd->hpib_lim = LIS_ERR;
82 hd->hpib_mim = 0;
83 hd->hpib_acr = AUX_CDAI;
84 hd->hpib_acr = AUX_CSHDW;
85 hd->hpib_acr = AUX_SSTD1;
86 hd->hpib_acr = AUX_SVSTD1;
87 hd->hpib_acr = AUX_CPP;
88 hd->hpib_acr = AUX_CHDFA;
89 hd->hpib_acr = AUX_CHDFE;
90 hd->hpib_acr = AUX_RHDF;
91 hd->hpib_acr = AUX_CSWRST;
92 nhpibifc(hd);
93 hd->hpib_ie = IDS_IE;
94 hd->hpib_data = C_DCL;
95 DELAY(100000);
96 }
97
98 nhpibifc(hd)
99 register struct nhpibdevice *hd;
100 {
101 hd->hpib_acr = AUX_TCA;
102 hd->hpib_acr = AUX_CSRE;
103 hd->hpib_acr = AUX_SSIC;
104 DELAY(100);
105 hd->hpib_acr = AUX_CSIC;
106 hd->hpib_acr = AUX_SSRE;
107 }
108
109 nhpibsend(unit, slave, sec, addr, origcnt)
110 register char *addr;
111 {
112 register struct hpib_softc *hs = &hpib_softc[unit];
113 register struct nhpibdevice *hd;
114 register int cnt = origcnt;
115
116 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
117 hd->hpib_acr = AUX_TCA;
118 hd->hpib_data = C_UNL;
119 if (nhpibwait(hd, MIS_BO))
120 goto senderror;
121 hd->hpib_data = C_TAG + hs->sc_ba;
122 hd->hpib_acr = AUX_STON;
123 if (nhpibwait(hd, MIS_BO))
124 goto senderror;
125 hd->hpib_data = C_LAG + slave;
126 if (nhpibwait(hd, MIS_BO))
127 goto senderror;
128 if (sec != -1) {
129 hd->hpib_data = C_SCG + sec;
130 if (nhpibwait(hd, MIS_BO))
131 goto senderror;
132 }
133 hd->hpib_acr = AUX_GTS;
134 if (cnt) {
135 while (--cnt > 0) {
136 hd->hpib_data = *addr++;
137 if (nhpibwait(hd, MIS_BO))
138 goto senderror;
139 }
140 hd->hpib_acr = AUX_EOI;
141 hd->hpib_data = *addr;
142 if (nhpibwait(hd, MIS_BO))
143 goto senderror;
144 hd->hpib_acr = AUX_TCA;
145 #if 0
146 /*
147 * May be causing 345 disks to hang due to interference
148 * with PPOLL mechanism.
149 */
150 hd->hpib_data = C_UNL;
151 (void) nhpibwait(hd, MIS_BO);
152 #endif
153 }
154 return(origcnt);
155 senderror:
156 nhpibifc(hd);
157 return(origcnt - cnt - 1);
158 }
159
160 nhpibrecv(unit, slave, sec, addr, origcnt)
161 register char *addr;
162 {
163 register struct hpib_softc *hs = &hpib_softc[unit];
164 register struct nhpibdevice *hd;
165 register int cnt = origcnt;
166
167 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
168 hd->hpib_acr = AUX_TCA;
169 hd->hpib_data = C_UNL;
170 if (nhpibwait(hd, MIS_BO))
171 goto recverror;
172 hd->hpib_data = C_LAG + hs->sc_ba;
173 hd->hpib_acr = AUX_SLON;
174 if (nhpibwait(hd, MIS_BO))
175 goto recverror;
176 hd->hpib_data = C_TAG + slave;
177 if (nhpibwait(hd, MIS_BO))
178 goto recverror;
179 if (sec != -1) {
180 hd->hpib_data = C_SCG + sec;
181 if (nhpibwait(hd, MIS_BO))
182 goto recverror;
183 }
184 hd->hpib_acr = AUX_RHDF;
185 hd->hpib_acr = AUX_GTS;
186 if (cnt) {
187 while (--cnt >= 0) {
188 if (nhpibwait(hd, MIS_BI))
189 goto recvbyteserror;
190 *addr++ = hd->hpib_data;
191 }
192 hd->hpib_acr = AUX_TCA;
193 hd->hpib_data = (slave == 31) ? C_UNA : C_UNT;
194 (void) nhpibwait(hd, MIS_BO);
195 }
196 return(origcnt);
197 recverror:
198 nhpibifc(hd);
199 recvbyteserror:
200 return(origcnt - cnt - 1);
201 }
202
203 nhpibgo(unit, slave, sec, addr, count, rw)
204 register int unit, slave;
205 char *addr;
206 {
207 register struct hpib_softc *hs = &hpib_softc[unit];
208 register struct nhpibdevice *hd;
209
210 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
211 hs->sc_flags |= HPIBF_IO;
212 if (rw == B_READ)
213 hs->sc_flags |= HPIBF_READ;
214 #ifdef DEBUG
215 else if (hs->sc_flags & HPIBF_READ) {
216 printf("nhpibgo: HPIBF_READ still set\n");
217 hs->sc_flags &= ~HPIBF_READ;
218 }
219 #endif
220 hs->sc_count = count;
221 hs->sc_addr = addr;
222 if (hs->sc_flags & HPIBF_READ) {
223 hs->sc_curcnt = count;
224 dmago(hs->sc_dq.dq_ctlr, addr, count, DMAGO_BYTE|DMAGO_READ);
225 nhpibrecv(unit, slave, sec, 0, 0);
226 hd->hpib_mim = MIS_END;
227 } else {
228 hd->hpib_mim = 0;
229 if (count < hpibdmathresh) {
230 hs->sc_curcnt = count;
231 nhpibsend(unit, slave, sec, addr, count);
232 nhpibdone(unit);
233 return;
234 }
235 hs->sc_curcnt = --count;
236 dmago(hs->sc_dq.dq_ctlr, addr, count, DMAGO_BYTE);
237 nhpibsend(unit, slave, sec, 0, 0);
238 }
239 hd->hpib_ie = IDS_IE | IDS_DMA(hs->sc_dq.dq_ctlr);
240 }
241
242 nhpibdone(unit)
243 register int unit;
244 {
245 register struct hpib_softc *hs = &hpib_softc[unit];
246 register struct nhpibdevice *hd;
247 register int cnt;
248
249 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
250 cnt = hs->sc_curcnt;
251 hs->sc_addr += cnt;
252 hs->sc_count -= cnt;
253 hs->sc_flags |= HPIBF_DONE;
254 hd->hpib_ie = IDS_IE;
255 if ((hs->sc_flags & HPIBF_READ) == 0) {
256 if (hs->sc_count == 1) {
257 (void) nhpibwait(hd, MIS_BO);
258 hd->hpib_acr = AUX_EOI;
259 hd->hpib_data = *hs->sc_addr;
260 hd->hpib_mim = MIS_BO;
261 }
262 #ifdef DEBUG
263 else if (hs->sc_count)
264 panic("nhpibdone");
265 #endif
266 }
267 }
268
269 nhpibintr(unit)
270 register int unit;
271 {
272 register struct hpib_softc *hs = &hpib_softc[unit];
273 register struct nhpibdevice *hd;
274 register struct devqueue *dq;
275 register int stat0;
276 int stat1;
277
278 #ifdef lint
279 if (stat1 = unit) return(1);
280 #endif
281 hd = (struct nhpibdevice *)hs->sc_hc->hp_addr;
282 if ((hd->hpib_ids & IDS_IR) == 0)
283 return(0);
284 stat0 = hd->hpib_mis;
285 stat1 = hd->hpib_lis;
286 dq = hs->sc_sq.dq_forw;
287 if (hs->sc_flags & HPIBF_IO) {
288 hd->hpib_mim = 0;
289 if ((hs->sc_flags & HPIBF_DONE) == 0)
290 dmastop(hs->sc_dq.dq_ctlr);
291 hd->hpib_acr = AUX_TCA;
292 hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ);
293 dmafree(&hs->sc_dq);
294 (dq->dq_driver->d_intr)(dq->dq_unit);
295 } else if (hs->sc_flags & HPIBF_PPOLL) {
296 hd->hpib_mim = 0;
297 stat0 = nhpibppoll(unit);
298 if (stat0 & (0x80 >> dq->dq_slave)) {
299 hs->sc_flags &= ~HPIBF_PPOLL;
300 (dq->dq_driver->d_intr)(dq->dq_unit);
301 }
302 #ifdef DEBUG
303 else
304 printf("hpib%d: PPOLL intr bad status %x\n",
305 unit, stat0);
306 #endif
307 }
308 return(1);
309 }
310
311 nhpibppoll(unit)
312 int unit;
313 {
314 register struct nhpibdevice *hd;
315 register int ppoll;
316
317 hd = (struct nhpibdevice *)hpib_softc[unit].sc_hc->hp_addr;
318 hd->hpib_acr = AUX_SPP;
319 DELAY(25);
320 ppoll = hd->hpib_cpt;
321 hd->hpib_acr = AUX_CPP;
322 return(ppoll);
323 }
324
325 nhpibwait(hd, x)
326 register struct nhpibdevice *hd;
327 {
328 register int timo = hpibtimeout;
329
330 while ((hd->hpib_mis & x) == 0 && --timo)
331 DELAY(1);
332 if (timo == 0)
333 return(-1);
334 return(0);
335 }
336
337 nhpibppwatch(unit)
338 register int unit;
339 {
340 register struct hpib_softc *hs = &hpib_softc[unit];
341
342 if ((hs->sc_flags & HPIBF_PPOLL) == 0)
343 return;
344 if (nhpibppoll(unit) & (0x80 >> hs->sc_sq.dq_forw->dq_slave))
345 ((struct nhpibdevice *)hs->sc_hc->hp_addr)->hpib_mim = MIS_BO;
346 else
347 timeout(nhpibppwatch, unit, 1);
348 }
349 #endif
350