|
|
1.1 root 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: * @(#)fhpib.c 7.3 (Berkeley) 12/16/90
34: */
35:
36: /*
37: * 98625A/B 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: #include "device.h"
46: #include "fhpibreg.h"
47: #include "hpibvar.h"
48: #include "dmavar.h"
49:
50: /*
51: * Inline version of fhpibwait to be used in places where
52: * we don't worry about getting hung.
53: */
54: #define FHPIBWAIT(hd, m) while (((hd)->hpib_intr & (m)) == 0) DELAY(1)
55:
56: #ifdef DEBUG
57: int fhpibdebugunit = -1;
58: int fhpibdebug = 0;
59: #define FDB_FAIL 0x01
60: #define FDB_DMA 0x02
61: #define FDB_WAIT 0x04
62: #define FDB_PPOLL 0x08
63:
64: int dopriodma = 0; /* use high priority DMA */
65: int doworddma = 1; /* non-zero if we should attempt word dma */
66: int doppollint = 1; /* use ppoll interrupts instead of watchdog */
67:
68: long fhpibbadint[2] = { 0 };
69: long fhpibtransfer[NHPIB] = { 0 };
70: long fhpibnondma[NHPIB] = { 0 };
71: long fhpibworddma[NHPIB] = { 0 };
72: #endif
73:
74: int fhpibcmd[NHPIB];
75:
76: fhpibtype(hc)
77: register struct hp_ctlr *hc;
78: {
79: register struct hpib_softc *hs = &hpib_softc[hc->hp_unit];
80: register struct fhpibdevice *hd = (struct fhpibdevice *)hc->hp_addr;
81:
82: if (hd->hpib_cid != HPIBC)
83: return(0);
84: hs->sc_type = HPIBC;
85: hs->sc_ba = HPIBC_BA;
86: hc->hp_ipl = HPIB_IPL(hd->hpib_ids);
87: return(1);
88: }
89:
90: fhpibreset(unit)
91: {
92: register struct hpib_softc *hs = &hpib_softc[unit];
93: register struct fhpibdevice *hd;
94:
95: hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
96: hd->hpib_cid = 0xFF;
97: DELAY(100);
98: hd->hpib_cmd = CT_8BIT;
99: hd->hpib_ar = AR_ARONC;
100: fhpibifc(hd);
101: hd->hpib_ie = IDS_IE;
102: hd->hpib_data = C_DCL;
103: DELAY(100000);
104: /*
105: * See if we can do word dma.
106: * If so, we should be able to write and read back the appropos bit.
107: */
108: hd->hpib_ie |= IDS_WDMA;
109: if (hd->hpib_ie & IDS_WDMA) {
110: hd->hpib_ie &= ~IDS_WDMA;
111: hs->sc_flags |= HPIBF_DMA16;
112: #ifdef DEBUG
113: if (fhpibdebug & FDB_DMA)
114: printf("fhpibtype: unit %d has word dma\n", unit);
115:
116: #endif
117: }
118: }
119:
120: fhpibifc(hd)
121: register struct fhpibdevice *hd;
122: {
123: hd->hpib_cmd |= CT_IFC;
124: hd->hpib_cmd |= CT_INITFIFO;
125: DELAY(100);
126: hd->hpib_cmd &= ~CT_IFC;
127: hd->hpib_cmd |= CT_REN;
128: hd->hpib_stat = ST_ATN;
129: }
130:
131: fhpibsend(unit, slave, sec, addr, origcnt)
132: register char *addr;
133: {
134: register struct hpib_softc *hs = &hpib_softc[unit];
135: register struct fhpibdevice *hd;
136: register int cnt = origcnt;
137: register int timo;
138:
139: hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
140: hd->hpib_stat = 0;
141: hd->hpib_imask = IM_IDLE | IM_ROOM;
142: if (fhpibwait(hd, IM_IDLE) < 0)
143: goto senderr;
144: hd->hpib_stat = ST_ATN;
145: hd->hpib_data = C_UNL;
146: hd->hpib_data = C_TAG + hs->sc_ba;
147: hd->hpib_data = C_LAG + slave;
148: if (sec != -1)
149: hd->hpib_data = C_SCG + sec;
150: if (fhpibwait(hd, IM_IDLE) < 0)
151: goto senderr;
152: if (cnt) {
153: hd->hpib_stat = ST_WRITE;
154: while (--cnt) {
155: hd->hpib_data = *addr++;
156: timo = hpibtimeout;
157: while ((hd->hpib_intr & IM_ROOM) == 0) {
158: if (--timo <= 0)
159: goto senderr;
160: DELAY(1);
161: }
162: }
163: hd->hpib_stat = ST_EOI;
164: hd->hpib_data = *addr;
165: FHPIBWAIT(hd, IM_ROOM);
166: hd->hpib_stat = ST_ATN;
167: /* XXX: HP-UX claims bug with CS80 transparent messages */
168: if (sec == 0x12)
169: DELAY(150);
170: hd->hpib_data = C_UNL;
171: (void) fhpibwait(hd, IM_IDLE);
172: }
173: hd->hpib_imask = 0;
174: return (origcnt);
175: senderr:
176: hd->hpib_imask = 0;
177: fhpibifc(hd);
178: #ifdef DEBUG
179: if (fhpibdebug & FDB_FAIL) {
180: printf("hpib%d: fhpibsend failed: slave %d, sec %x, ",
181: unit, slave, sec);
182: printf("sent %d of %d bytes\n", origcnt-cnt-1, origcnt);
183: }
184: #endif
185: return(origcnt - cnt - 1);
186: }
187:
188: fhpibrecv(unit, slave, sec, addr, origcnt)
189: register char *addr;
190: {
191: register struct hpib_softc *hs = &hpib_softc[unit];
192: register struct fhpibdevice *hd;
193: register int cnt = origcnt;
194: register int timo;
195:
196: hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
197: hd->hpib_stat = 0;
198: hd->hpib_imask = IM_IDLE | IM_ROOM | IM_BYTE;
199: if (fhpibwait(hd, IM_IDLE) < 0)
200: goto recverror;
201: hd->hpib_stat = ST_ATN;
202: hd->hpib_data = C_UNL;
203: hd->hpib_data = C_LAG + hs->sc_ba;
204: hd->hpib_data = C_TAG + slave;
205: if (sec != -1)
206: hd->hpib_data = C_SCG + sec;
207: if (fhpibwait(hd, IM_IDLE) < 0)
208: goto recverror;
209: hd->hpib_stat = ST_READ0;
210: hd->hpib_data = 0;
211: if (cnt) {
212: while (--cnt >= 0) {
213: timo = hpibtimeout;
214: while ((hd->hpib_intr & IM_BYTE) == 0) {
215: if (--timo == 0)
216: goto recvbyteserror;
217: DELAY(1);
218: }
219: *addr++ = hd->hpib_data;
220: }
221: FHPIBWAIT(hd, IM_ROOM);
222: hd->hpib_stat = ST_ATN;
223: hd->hpib_data = (slave == 31) ? C_UNA : C_UNT;
224: (void) fhpibwait(hd, IM_IDLE);
225: }
226: hd->hpib_imask = 0;
227: return (origcnt);
228:
229: recverror:
230: fhpibifc(hd);
231: recvbyteserror:
232: hd->hpib_imask = 0;
233: #ifdef DEBUG
234: if (fhpibdebug & FDB_FAIL) {
235: printf("hpib%d: fhpibrecv failed: slave %d, sec %x, ",
236: unit, slave, sec);
237: printf("got %d of %d bytes\n", origcnt-cnt-1, origcnt);
238: }
239: #endif
240: return(origcnt - cnt - 1);
241: }
242:
243: fhpibgo(unit, slave, sec, addr, count, rw)
244: register int unit;
245: char *addr;
246: {
247: register struct hpib_softc *hs = &hpib_softc[unit];
248: register struct fhpibdevice *hd;
249: register int i;
250: int flags = 0;
251:
252: #ifdef lint
253: i = unit; if (i) return;
254: #endif
255: hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
256: hs->sc_flags |= HPIBF_IO;
257: if (rw == B_READ)
258: hs->sc_flags |= HPIBF_READ;
259: #ifdef DEBUG
260: else if (hs->sc_flags & HPIBF_READ) {
261: printf("fhpibgo: HPIBF_READ still set\n");
262: hs->sc_flags &= ~HPIBF_READ;
263: }
264: #endif
265: hs->sc_count = count;
266: hs->sc_addr = addr;
267: #ifdef DEBUG
268: fhpibtransfer[unit]++;
269: #endif
270: if ((hs->sc_flags & HPIBF_DMA16) &&
271: ((int)addr & 1) == 0 && count && (count & 1) == 0
272: #ifdef DEBUG
273: && doworddma
274: #endif
275: ) {
276: #ifdef DEBUG
277: fhpibworddma[unit]++;
278: #endif
279: flags |= DMAGO_WORD;
280: hd->hpib_latch = 0;
281: }
282: #ifdef DEBUG
283: if (dopriodma)
284: flags |= DMAGO_PRI;
285: #endif
286: if (hs->sc_flags & HPIBF_READ) {
287: fhpibcmd[unit] = CT_REN | CT_8BIT;
288: hs->sc_curcnt = count;
289: dmago(hs->sc_dq.dq_ctlr, addr, count, flags|DMAGO_READ);
290: if (fhpibrecv(unit, slave, sec, 0, 0) < 0) {
291: #ifdef DEBUG
292: printf("fhpibgo: recv failed, retrying...\n");
293: #endif
294: (void) fhpibrecv(unit, slave, sec, 0, 0);
295: }
296: i = hd->hpib_cmd;
297: hd->hpib_cmd = fhpibcmd[unit];
298: hd->hpib_ie = IDS_DMA(hs->sc_dq.dq_ctlr) |
299: ((flags & DMAGO_WORD) ? IDS_WDMA : 0);
300: return;
301: }
302: fhpibcmd[unit] = CT_REN | CT_8BIT | CT_FIFOSEL;
303: if (count < hpibdmathresh) {
304: #ifdef DEBUG
305: fhpibnondma[unit]++;
306: if (flags & DMAGO_WORD)
307: fhpibworddma[unit]--;
308: #endif
309: hs->sc_curcnt = count;
310: (void) fhpibsend(unit, slave, sec, addr, count);
311: fhpibdone(unit);
312: return;
313: }
314: count -= (flags & DMAGO_WORD) ? 2 : 1;
315: hs->sc_curcnt = count;
316: dmago(hs->sc_dq.dq_ctlr, addr, count, flags);
317: if (fhpibsend(unit, slave, sec, 0, 0) < 0) {
318: #ifdef DEBUG
319: printf("fhpibgo: send failed, retrying...\n");
320: #endif
321: (void) fhpibsend(unit, slave, sec, 0, 0);
322: }
323: i = hd->hpib_cmd;
324: hd->hpib_cmd = fhpibcmd[unit];
325: hd->hpib_ie = IDS_DMA(hs->sc_dq.dq_ctlr) | IDS_WRITE |
326: ((flags & DMAGO_WORD) ? IDS_WDMA : 0);
327: }
328:
329: fhpibdone(unit)
330: {
331: register struct hpib_softc *hs = &hpib_softc[unit];
332: register struct fhpibdevice *hd;
333: register char *addr;
334: register int cnt;
335:
336: hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
337: cnt = hs->sc_curcnt;
338: hs->sc_addr += cnt;
339: hs->sc_count -= cnt;
340: #ifdef DEBUG
341: if ((fhpibdebug & FDB_DMA) && fhpibdebugunit == unit)
342: printf("fhpibdone: addr %x cnt %d\n",
343: hs->sc_addr, hs->sc_count);
344: #endif
345: if (hs->sc_flags & HPIBF_READ)
346: hd->hpib_imask = IM_IDLE | IM_BYTE;
347: else {
348: cnt = hs->sc_count;
349: if (cnt) {
350: addr = hs->sc_addr;
351: hd->hpib_imask = IM_IDLE | IM_ROOM;
352: FHPIBWAIT(hd, IM_IDLE);
353: hd->hpib_stat = ST_WRITE;
354: while (--cnt) {
355: hd->hpib_data = *addr++;
356: FHPIBWAIT(hd, IM_ROOM);
357: }
358: hd->hpib_stat = ST_EOI;
359: hd->hpib_data = *addr;
360: }
361: hd->hpib_imask = IM_IDLE;
362: }
363: hs->sc_flags |= HPIBF_DONE;
364: hd->hpib_stat = ST_IENAB;
365: hd->hpib_ie = IDS_IE;
366: }
367:
368: fhpibintr(unit)
369: register int unit;
370: {
371: register struct hpib_softc *hs = &hpib_softc[unit];
372: register struct fhpibdevice *hd;
373: register struct devqueue *dq;
374: register int stat0;
375:
376: hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
377: stat0 = hd->hpib_ids;
378: if ((stat0 & (IDS_IE|IDS_IR)) != (IDS_IE|IDS_IR)) {
379: #ifdef DEBUG
380: if ((fhpibdebug & FDB_FAIL) && (stat0 & IDS_IR) &&
381: (hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) != HPIBF_IO)
382: printf("hpib%d: fhpibintr: bad status %x\n",
383: unit, stat0);
384: fhpibbadint[0]++;
385: #endif
386: return(0);
387: }
388: if ((hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) == HPIBF_IO) {
389: #ifdef DEBUG
390: fhpibbadint[1]++;
391: #endif
392: return(0);
393: }
394: #ifdef DEBUG
395: if ((fhpibdebug & FDB_DMA) && fhpibdebugunit == unit)
396: printf("fhpibintr: flags %x\n", hs->sc_flags);
397: #endif
398: dq = hs->sc_sq.dq_forw;
399: if (hs->sc_flags & HPIBF_IO) {
400: stat0 = hd->hpib_cmd;
401: hd->hpib_cmd = fhpibcmd[unit] & ~CT_8BIT;
402: hd->hpib_stat = 0;
403: hd->hpib_cmd = CT_REN | CT_8BIT;
404: stat0 = hd->hpib_intr;
405: hd->hpib_imask = 0;
406: hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ);
407: dmafree(&hs->sc_dq);
408: (dq->dq_driver->d_intr)(dq->dq_unit);
409: } else if (hs->sc_flags & HPIBF_PPOLL) {
410: stat0 = hd->hpib_intr;
411: #ifdef DEBUG
412: if ((fhpibdebug & FDB_FAIL) &&
413: doppollint && (stat0 & IM_PPRESP) == 0)
414: printf("hpib%d: fhpibintr: bad intr reg %x\n",
415: unit, stat0);
416: #endif
417: hd->hpib_stat = 0;
418: hd->hpib_imask = 0;
419: #ifdef DEBUG
420: stat0 = fhpibppoll(unit);
421: if ((fhpibdebug & FDB_PPOLL) && unit == fhpibdebugunit)
422: printf("fhpibintr: got PPOLL status %x\n", stat0);
423: if ((stat0 & (0x80 >> dq->dq_slave)) == 0) {
424: printf("fhpibintr: PPOLL: unit %d slave %d stat %x\n",
425: unit, dq->dq_slave, stat0);
426: return(1);
427: }
428: #endif
429: hs->sc_flags &= ~HPIBF_PPOLL;
430: (dq->dq_driver->d_intr)(dq->dq_unit);
431: }
432: return(1);
433: }
434:
435: fhpibppoll(unit)
436: {
437: register struct fhpibdevice *hd;
438: register int ppoll;
439:
440: hd = (struct fhpibdevice *)hpib_softc[unit].sc_hc->hp_addr;
441: hd->hpib_stat = 0;
442: hd->hpib_psense = 0;
443: hd->hpib_pmask = 0xFF;
444: hd->hpib_imask = IM_PPRESP | IM_PABORT;
445: DELAY(25);
446: hd->hpib_intr = IM_PABORT;
447: ppoll = hd->hpib_data;
448: if (hd->hpib_intr & IM_PABORT)
449: ppoll = 0;
450: hd->hpib_imask = 0;
451: hd->hpib_pmask = 0;
452: hd->hpib_stat = ST_IENAB;
453: return(ppoll);
454: }
455:
456: fhpibwait(hd, x)
457: register struct fhpibdevice *hd;
458: {
459: register int timo = hpibtimeout;
460:
461: while ((hd->hpib_intr & x) == 0 && --timo)
462: DELAY(1);
463: if (timo == 0) {
464: #ifdef DEBUG
465: if (fhpibdebug & FDB_FAIL)
466: printf("fhpibwait(%x, %x) timeout\n", hd, x);
467: #endif
468: return(-1);
469: }
470: return(0);
471: }
472:
473: /*
474: * XXX: this will have to change if we every allow more than one
475: * pending operation per HP-IB.
476: */
477: fhpibppwatch(unit)
478: {
479: register struct hpib_softc *hs = &hpib_softc[unit];
480: register struct fhpibdevice *hd;
481: register int slave;
482:
483: if ((hs->sc_flags & HPIBF_PPOLL) == 0)
484: return;
485: hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
486: slave = (0x80 >> hs->sc_sq.dq_forw->dq_slave);
487: #ifdef DEBUG
488: if (!doppollint) {
489: if (fhpibppoll(unit) & slave) {
490: hd->hpib_stat = ST_IENAB;
491: hd->hpib_imask = IM_IDLE | IM_ROOM;
492: } else
493: timeout(fhpibppwatch, unit, 1);
494: return;
495: }
496: if ((fhpibdebug & FDB_PPOLL) && unit == fhpibdebugunit)
497: printf("fhpibppwatch: sense request on %d\n", unit);
498: #endif
499: hd->hpib_psense = ~slave;
500: hd->hpib_pmask = slave;
501: hd->hpib_stat = ST_IENAB;
502: hd->hpib_imask = IM_PPRESP | IM_PABORT;
503: hd->hpib_ie = IDS_IE;
504: }
505: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.