xref: /netbsd-src/sys/arch/hp300/dev/hpib.c (revision ce0bb6e8d2e560ecacbe865a848624f94498063b)
1 /*	$NetBSD: hpib.c,v 1.5 1995/01/07 10:30:12 mycroft Exp $	*/
2 
3 /*
4  * Copyright (c) 1982, 1990, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the University of
18  *	California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *	@(#)hpib.c	8.2 (Berkeley) 1/12/94
36  */
37 
38 /*
39  * HPIB driver
40  */
41 #include "hpib.h"
42 #if NHPIB > 0
43 
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/buf.h>
47 
48 #include <hp300/dev/device.h>
49 #include <hp300/dev/hpibvar.h>
50 #include <hp300/dev/dmavar.h>
51 
52 #include <machine/cpu.h>
53 #include <hp300/hp300/isr.h>
54 
55 int	hpibinit(), hpibstart(), hpibgo(), hpibintr(), hpibdone();
56 struct	driver hpibdriver = {
57 	hpibinit, "hpib", hpibstart, hpibgo, hpibintr, hpibdone,
58 };
59 
60 struct	hpib_softc hpib_softc[NHPIB];
61 struct	isr hpib_isr[NHPIB];
62 int	nhpibppoll(), fhpibppoll();
63 
64 int	hpibtimeout = 100000;	/* # of status tests before we give up */
65 int	hpibidtimeout = 10000;	/* # of status tests for hpibid() calls */
66 int	hpibdmathresh = 3;	/* byte count beyond which to attempt dma */
67 
68 hpibinit(hc)
69 	register struct hp_ctlr *hc;
70 {
71 	register struct hpib_softc *hs = &hpib_softc[hc->hp_unit];
72 
73 	if (!nhpibtype(hc) && !fhpibtype(hc))
74 		return(0);
75 	hs->sc_hc = hc;
76 	hs->sc_dq.dq_unit = hc->hp_unit;
77 	hs->sc_dq.dq_driver = &hpibdriver;
78 	hs->sc_sq.dq_forw = hs->sc_sq.dq_back = &hs->sc_sq;
79 	hpib_isr[hc->hp_unit].isr_intr = hpibintr;
80 	hpib_isr[hc->hp_unit].isr_ipl = hc->hp_ipl;
81 	hpib_isr[hc->hp_unit].isr_arg = hc->hp_unit;
82 	isrlink(&hpib_isr[hc->hp_unit]);
83 	hpibreset(hc->hp_unit);
84 	return(1);
85 }
86 
87 hpibreset(unit)
88 	register int unit;
89 {
90 	if (hpib_softc[unit].sc_type == HPIBC)
91 		fhpibreset(unit);
92 	else
93 		nhpibreset(unit);
94 }
95 
96 hpibreq(dq)
97 	register struct devqueue *dq;
98 {
99 	register struct devqueue *hq;
100 
101 	hq = &hpib_softc[dq->dq_ctlr].sc_sq;
102 	insque(dq, hq->dq_back);
103 	if (dq->dq_back == hq)
104 		return(1);
105 	return(0);
106 }
107 
108 hpibfree(dq)
109 	register struct devqueue *dq;
110 {
111 	register struct devqueue *hq;
112 
113 	hq = &hpib_softc[dq->dq_ctlr].sc_sq;
114 	remque(dq);
115 	if ((dq = hq->dq_forw) != hq)
116 		(dq->dq_driver->d_start)(dq->dq_unit);
117 }
118 
119 hpibid(unit, slave)
120 	int unit, slave;
121 {
122 	short id;
123 	int ohpibtimeout;
124 
125 	/*
126 	 * XXX shorten timeout value so autoconfig doesn't
127 	 * take forever on slow CPUs.
128 	 */
129 	ohpibtimeout = hpibtimeout;
130 	hpibtimeout = hpibidtimeout * cpuspeed;
131 	if (hpibrecv(unit, 31, slave, &id, 2) != 2)
132 		id = 0;
133 	hpibtimeout = ohpibtimeout;
134 	return(id);
135 }
136 
137 hpibsend(unit, slave, sec, addr, cnt)
138 	register int unit;
139 	int slave, sec, addr, cnt;
140 {
141 	if (hpib_softc[unit].sc_type == HPIBC)
142 		return(fhpibsend(unit, slave, sec, addr, cnt));
143 	else
144 		return(nhpibsend(unit, slave, sec, addr, cnt));
145 }
146 
147 hpibrecv(unit, slave, sec, addr, cnt)
148 	register int unit;
149 	int slave, sec, addr, cnt;
150 {
151 	if (hpib_softc[unit].sc_type == HPIBC)
152 		return(fhpibrecv(unit, slave, sec, addr, cnt));
153 	else
154 		return(nhpibrecv(unit, slave, sec, addr, cnt));
155 }
156 
157 hpibpptest(unit, slave)
158 	register int unit;
159 	int slave;
160 {
161 	int (*ppoll)();
162 
163 	ppoll = (hpib_softc[unit].sc_type == HPIBC) ? fhpibppoll : nhpibppoll;
164 	return((*ppoll)(unit) & (0x80 >> slave));
165 }
166 
167 hpibppclear(unit)
168 	int unit;
169 {
170 	hpib_softc[unit].sc_flags &= ~HPIBF_PPOLL;
171 }
172 
173 hpibawait(unit)
174 	int unit;
175 {
176 	register struct hpib_softc *hs = &hpib_softc[unit];
177 
178 	hs->sc_flags |= HPIBF_PPOLL;
179 	if (hs->sc_type == HPIBC)
180 		fhpibppwatch((void *)unit);
181 	else
182 		nhpibppwatch((void *)unit);
183 }
184 
185 hpibswait(unit, slave)
186 	register int unit;
187 	int slave;
188 {
189 	register int timo = hpibtimeout;
190 	register int mask, (*ppoll)();
191 
192 	ppoll = (hpib_softc[unit].sc_type == HPIBC) ? fhpibppoll : nhpibppoll;
193 	mask = 0x80 >> slave;
194 	while (((ppoll)(unit) & mask) == 0)
195 		if (--timo == 0) {
196 			printf("hpib%d: swait timeout\n", unit);
197 			return(-1);
198 		}
199 	return(0);
200 }
201 
202 hpibustart(unit)
203 	int unit;
204 {
205 	register struct hpib_softc *hs = &hpib_softc[unit];
206 
207 	if (hs->sc_type == HPIBA)
208 		hs->sc_dq.dq_ctlr = DMA0;
209 	else
210 		hs->sc_dq.dq_ctlr = DMA0 | DMA1;
211 	if (dmareq(&hs->sc_dq))
212 		return(1);
213 	return(0);
214 }
215 
216 hpibstart(unit)
217 	int unit;
218 {
219 	register struct devqueue *dq;
220 
221 	dq = hpib_softc[unit].sc_sq.dq_forw;
222 	(dq->dq_driver->d_go)(dq->dq_unit);
223 }
224 
225 hpibgo(unit, slave, sec, addr, count, rw, timo)
226 	register int unit;
227 	int slave, sec, addr, count, rw;
228 {
229 	if (hpib_softc[unit].sc_type == HPIBC)
230 		fhpibgo(unit, slave, sec, addr, count, rw, timo);
231 	else
232 		nhpibgo(unit, slave, sec, addr, count, rw, timo);
233 }
234 
235 hpibdone(unit)
236 	register int unit;
237 {
238 	if (hpib_softc[unit].sc_type == HPIBC)
239 		fhpibdone(unit);
240 	else
241 		nhpibdone(unit);
242 }
243 
244 hpibintr(unit)
245 	register int unit;
246 {
247 	int found;
248 
249 	if (hpib_softc[unit].sc_type == HPIBC)
250 		found = fhpibintr(unit);
251 	else
252 		found = nhpibintr(unit);
253 	return(found);
254 }
255 #endif
256