xref: /netbsd-src/sys/arch/hp300/dev/hpib.c (revision cda4f8f6ee55684e8d311b86c99ea59191e6b74f)
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: @(#)hpib.c	7.3 (Berkeley) 12/16/90
34  *	$Id: hpib.c,v 1.2 1993/05/22 07:56:20 cgd Exp $
35  */
36 
37 /*
38  * 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 #include "device.h"
47 #include "hpibvar.h"
48 #include "dmavar.h"
49 
50 #include "../include/cpu.h"
51 #include "../hp300/isr.h"
52 
53 int	hpibinit(), hpibstart(), hpibgo(), hpibintr(), hpibdone();
54 struct	driver hpibdriver = {
55 	hpibinit, "hpib", hpibstart, hpibgo, hpibintr, hpibdone,
56 };
57 
58 struct	hpib_softc hpib_softc[NHPIB];
59 struct	isr hpib_isr[NHPIB];
60 int	nhpibppoll(), fhpibppoll();
61 
62 int	hpibtimeout = 100000;	/* # of status tests before we give up */
63 int	hpibidtimeout = 20000;	/* # of status tests for hpibid() calls */
64 int	hpibdmathresh = 3;	/* byte count beyond which to attempt dma */
65 
66 hpibinit(hc)
67 	register struct hp_ctlr *hc;
68 {
69 	register struct hpib_softc *hs = &hpib_softc[hc->hp_unit];
70 
71 	if (!nhpibtype(hc) && !fhpibtype(hc))
72 		return(0);
73 	hs->sc_hc = hc;
74 	hs->sc_dq.dq_unit = hc->hp_unit;
75 	hs->sc_dq.dq_driver = &hpibdriver;
76 	hs->sc_sq.dq_forw = hs->sc_sq.dq_back = &hs->sc_sq;
77 	hpib_isr[hc->hp_unit].isr_intr = hpibintr;
78 	hpib_isr[hc->hp_unit].isr_ipl = hc->hp_ipl;
79 	hpib_isr[hc->hp_unit].isr_arg = hc->hp_unit;
80 	isrlink(&hpib_isr[hc->hp_unit]);
81 	hpibreset(hc->hp_unit);
82 	return(1);
83 }
84 
85 hpibreset(unit)
86 	register int unit;
87 {
88 	if (hpib_softc[unit].sc_type == HPIBC)
89 		fhpibreset(unit);
90 	else
91 		nhpibreset(unit);
92 }
93 
94 hpibreq(dq)
95 	register struct devqueue *dq;
96 {
97 	register struct devqueue *hq;
98 
99 	hq = &hpib_softc[dq->dq_ctlr].sc_sq;
100 	insque(dq, hq->dq_back);
101 	if (dq->dq_back == hq)
102 		return(1);
103 	return(0);
104 }
105 
106 hpibfree(dq)
107 	register struct devqueue *dq;
108 {
109 	register struct devqueue *hq;
110 
111 	hq = &hpib_softc[dq->dq_ctlr].sc_sq;
112 	remque(dq);
113 	if ((dq = hq->dq_forw) != hq)
114 		(dq->dq_driver->d_start)(dq->dq_unit);
115 }
116 
117 hpibid(unit, slave)
118 {
119 	short id;
120 	int ohpibtimeout;
121 
122 	/*
123 	 * XXX: shorten timeout value (so autoconfig doesn't take forever)
124 	 */
125 	ohpibtimeout = hpibtimeout;
126 	hpibtimeout = hpibidtimeout;
127 	if (hpibrecv(unit, 31, slave, &id, 2) != 2)
128 		id = 0;
129 	hpibtimeout = ohpibtimeout;
130 	return(id);
131 }
132 
133 hpibsend(unit, slave, sec, addr, cnt)
134 	register int unit;
135 {
136 	if (hpib_softc[unit].sc_type == HPIBC)
137 		return(fhpibsend(unit, slave, sec, addr, cnt));
138 	else
139 		return(nhpibsend(unit, slave, sec, addr, cnt));
140 }
141 
142 hpibrecv(unit, slave, sec, addr, cnt)
143 	register int unit;
144 {
145 	if (hpib_softc[unit].sc_type == HPIBC)
146 		return(fhpibrecv(unit, slave, sec, addr, cnt));
147 	else
148 		return(nhpibrecv(unit, slave, sec, addr, cnt));
149 }
150 
151 hpibpptest(unit, slave)
152 	register int unit;
153 {
154 	int (*ppoll)();
155 
156 	ppoll = (hpib_softc[unit].sc_type == HPIBC) ? fhpibppoll : nhpibppoll;
157 	return((*ppoll)(unit) & (0x80 >> slave));
158 }
159 
160 hpibawait(unit)
161 {
162 	register struct hpib_softc *hs = &hpib_softc[unit];
163 
164 	hs->sc_flags |= HPIBF_PPOLL;
165 	if (hs->sc_type == HPIBC)
166 		fhpibppwatch(unit);
167 	else
168 		nhpibppwatch(unit);
169 }
170 
171 hpibswait(unit, slave)
172 	register int unit;
173 {
174 	register int timo = hpibtimeout;
175 	register int mask, (*ppoll)();
176 
177 	ppoll = (hpib_softc[unit].sc_type == HPIBC) ? fhpibppoll : nhpibppoll;
178 	mask = 0x80 >> slave;
179 	while (((ppoll)(unit) & mask) == 0)
180 		if (--timo == 0) {
181 			printf("hpib%d: swait timeout\n", unit);
182 			return(-1);
183 		}
184 	return(0);
185 }
186 
187 hpibustart(unit)
188 {
189 	register struct hpib_softc *hs = &hpib_softc[unit];
190 
191 	if (hs->sc_type == HPIBA)
192 		hs->sc_dq.dq_ctlr = DMA0;
193 	else
194 		hs->sc_dq.dq_ctlr = DMA0 | DMA1;
195 	if (dmareq(&hs->sc_dq))
196 		return(1);
197 	return(0);
198 }
199 
200 hpibstart(unit)
201 {
202 	register struct devqueue *dq;
203 
204 	dq = hpib_softc[unit].sc_sq.dq_forw;
205 	(dq->dq_driver->d_go)(dq->dq_unit);
206 }
207 
208 hpibgo(unit, slave, sec, addr, count, rw)
209 	register int unit;
210 {
211 	if (hpib_softc[unit].sc_type == HPIBC)
212 		fhpibgo(unit, slave, sec, addr, count, rw);
213 	else
214 		nhpibgo(unit, slave, sec, addr, count, rw);
215 }
216 
217 hpibdone(unit)
218 	register int unit;
219 {
220 	if (hpib_softc[unit].sc_type == HPIBC)
221 		fhpibdone(unit);
222 	else
223 		nhpibdone(unit);
224 }
225 
226 hpibintr(unit)
227 	register int unit;
228 {
229 	int found;
230 
231 	if (hpib_softc[unit].sc_type == HPIBC)
232 		found = fhpibintr(unit);
233 	else
234 		found = nhpibintr(unit);
235 	return(found);
236 }
237 #endif
238