xref: /netbsd-src/sys/arch/hp300/stand/common/fhpib.c (revision c06815799ecb35b60df9572a4d93e8418d79beda)
1*c0681579Stsutsui /*	$NetBSD: fhpib.c,v 1.6 2006/06/25 17:37:43 tsutsui Exp $	*/
2a0864b3eSthorpej 
3a0864b3eSthorpej /*
4a0864b3eSthorpej  * Copyright (c) 1982, 1990, 1993
5a0864b3eSthorpej  *	The Regents of the University of California.  All rights reserved.
6a0864b3eSthorpej  *
7a0864b3eSthorpej  * Redistribution and use in source and binary forms, with or without
8a0864b3eSthorpej  * modification, are permitted provided that the following conditions
9a0864b3eSthorpej  * are met:
10a0864b3eSthorpej  * 1. Redistributions of source code must retain the above copyright
11a0864b3eSthorpej  *    notice, this list of conditions and the following disclaimer.
12a0864b3eSthorpej  * 2. Redistributions in binary form must reproduce the above copyright
13a0864b3eSthorpej  *    notice, this list of conditions and the following disclaimer in the
14a0864b3eSthorpej  *    documentation and/or other materials provided with the distribution.
15aad01611Sagc  * 3. Neither the name of the University nor the names of its contributors
16a0864b3eSthorpej  *    may be used to endorse or promote products derived from this software
17a0864b3eSthorpej  *    without specific prior written permission.
18a0864b3eSthorpej  *
19a0864b3eSthorpej  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20a0864b3eSthorpej  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21a0864b3eSthorpej  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22a0864b3eSthorpej  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23a0864b3eSthorpej  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24a0864b3eSthorpej  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25a0864b3eSthorpej  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26a0864b3eSthorpej  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27a0864b3eSthorpej  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28a0864b3eSthorpej  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29a0864b3eSthorpej  * SUCH DAMAGE.
30a0864b3eSthorpej  *
31a0864b3eSthorpej  *	@(#)fhpib.c	8.1 (Berkeley) 6/10/93
32a0864b3eSthorpej  */
33a0864b3eSthorpej 
34a0864b3eSthorpej /*
35a0864b3eSthorpej  * 98625A/B HPIB driver
36a0864b3eSthorpej  */
37a0864b3eSthorpej 
38a0864b3eSthorpej #include <sys/param.h>
39a0864b3eSthorpej 
40a0864b3eSthorpej #include <hp300/dev/fhpibreg.h>
41a0864b3eSthorpej 
42a0864b3eSthorpej #include <hp300/stand/common/hpibvar.h>
43a0864b3eSthorpej #include <hp300/stand/common/samachdep.h>
44a0864b3eSthorpej 
45212f884fStsutsui static int fhpibwait(struct fhpibdevice *, uint8_t);
46212f884fStsutsui 
47212f884fStsutsui int
fhpibinit(int unit)48d3dc0553Stsutsui fhpibinit(int unit)
49a0864b3eSthorpej {
50212f884fStsutsui 	struct hpib_softc *hs = &hpib_softc[unit];
51212f884fStsutsui 	struct fhpibdevice *hd = (void *)hs->sc_addr;
52a0864b3eSthorpej 
53a0864b3eSthorpej 	if (hd->hpib_cid != HPIBC)
54212f884fStsutsui 		return 0;
55a0864b3eSthorpej 	hs->sc_type = HPIBC;
56a0864b3eSthorpej 	hs->sc_ba = HPIBC_BA;
57a0864b3eSthorpej 	fhpibreset(unit);
58212f884fStsutsui 	return 1;
59a0864b3eSthorpej }
60a0864b3eSthorpej 
61212f884fStsutsui void
fhpibreset(int unit)62d3dc0553Stsutsui fhpibreset(int unit)
63a0864b3eSthorpej {
64212f884fStsutsui 	struct hpib_softc *hs = &hpib_softc[unit];
65212f884fStsutsui 	struct fhpibdevice *hd;
66a0864b3eSthorpej 
67212f884fStsutsui 	hd = (void *)hs->sc_addr;
68a0864b3eSthorpej 	hd->hpib_cid = 0xFF;
69a0864b3eSthorpej 	DELAY(100);
70a0864b3eSthorpej 	hd->hpib_cmd = CT_8BIT;
71a0864b3eSthorpej 	hd->hpib_ar = AR_ARONC;
72a0864b3eSthorpej 	hd->hpib_cmd |= CT_IFC;
73a0864b3eSthorpej 	hd->hpib_cmd |= CT_INITFIFO;
74a0864b3eSthorpej 	DELAY(100);
75a0864b3eSthorpej 	hd->hpib_cmd &= ~CT_IFC;
76a0864b3eSthorpej 	hd->hpib_cmd |= CT_REN;
77a0864b3eSthorpej 	hd->hpib_stat = ST_ATN;
78a0864b3eSthorpej 	hd->hpib_data = C_DCL;
79a0864b3eSthorpej 	DELAY(100000);
80a0864b3eSthorpej }
81a0864b3eSthorpej 
82212f884fStsutsui int
fhpibsend(int unit,int slave,int sec,uint8_t * buf,int cnt)83*c0681579Stsutsui fhpibsend(int unit, int slave, int sec, uint8_t *buf, int cnt)
84a0864b3eSthorpej {
85212f884fStsutsui 	struct hpib_softc *hs = &hpib_softc[unit];
86212f884fStsutsui 	struct fhpibdevice *hd;
87a0864b3eSthorpej 	int origcnt = cnt;
88a0864b3eSthorpej 
89212f884fStsutsui 	hd = (void *)hs->sc_addr;
90a0864b3eSthorpej 	hd->hpib_stat = 0;
91a0864b3eSthorpej 	hd->hpib_imask = IM_IDLE | IM_ROOM;
92a0864b3eSthorpej 	fhpibwait(hd, IM_IDLE);
93a0864b3eSthorpej 	hd->hpib_stat = ST_ATN;
94a0864b3eSthorpej 	hd->hpib_data = C_UNL;
95a0864b3eSthorpej 	hd->hpib_data = C_TAG + hs->sc_ba;
96a0864b3eSthorpej 	hd->hpib_data = C_LAG + slave;
97a0864b3eSthorpej 	if (sec != -1)
98a0864b3eSthorpej 		hd->hpib_data = C_SCG + sec;
99a0864b3eSthorpej 	fhpibwait(hd, IM_IDLE);
100a0864b3eSthorpej 	hd->hpib_stat = ST_WRITE;
101a0864b3eSthorpej 	if (cnt) {
102a0864b3eSthorpej 		while (--cnt) {
103a0864b3eSthorpej 			hd->hpib_data = *buf++;
104a0864b3eSthorpej 			if (fhpibwait(hd, IM_ROOM) < 0)
105a0864b3eSthorpej 				break;
106a0864b3eSthorpej 		}
107a0864b3eSthorpej 		hd->hpib_stat = ST_EOI;
108a0864b3eSthorpej 		hd->hpib_data = *buf;
109a0864b3eSthorpej 		if (fhpibwait(hd, IM_ROOM) < 0)
110a0864b3eSthorpej 			cnt++;
111a0864b3eSthorpej 		hd->hpib_stat = ST_ATN;
112a0864b3eSthorpej 		/* XXX: HP-UX claims bug with CS80 transparent messages */
113a0864b3eSthorpej 		if (sec == 0x12)
114a0864b3eSthorpej 			DELAY(150);
115a0864b3eSthorpej 		hd->hpib_data = C_UNL;
116a0864b3eSthorpej 		fhpibwait(hd, IM_IDLE);
117a0864b3eSthorpej 	}
118a0864b3eSthorpej 	hd->hpib_imask = 0;
119212f884fStsutsui 	return origcnt - cnt;
120a0864b3eSthorpej }
121a0864b3eSthorpej 
122212f884fStsutsui int
fhpibrecv(int unit,int slave,int sec,uint8_t * buf,int cnt)123*c0681579Stsutsui fhpibrecv(int unit, int slave, int sec, uint8_t *buf, int cnt)
124a0864b3eSthorpej {
125212f884fStsutsui 	struct hpib_softc *hs = &hpib_softc[unit];
126212f884fStsutsui 	struct fhpibdevice *hd;
127a0864b3eSthorpej 	int origcnt = cnt;
128a0864b3eSthorpej 
129212f884fStsutsui 	hd = (void *)hs->sc_addr;
130a0864b3eSthorpej 	hd->hpib_stat = 0;
131a0864b3eSthorpej 	hd->hpib_imask = IM_IDLE | IM_ROOM | IM_BYTE;
132a0864b3eSthorpej 	fhpibwait(hd, IM_IDLE);
133a0864b3eSthorpej 	hd->hpib_stat = ST_ATN;
134a0864b3eSthorpej 	hd->hpib_data = C_UNL;
135a0864b3eSthorpej 	hd->hpib_data = C_LAG + hs->sc_ba;
136a0864b3eSthorpej 	hd->hpib_data = C_TAG + slave;
137a0864b3eSthorpej 	if (sec != -1)
138a0864b3eSthorpej 		hd->hpib_data = C_SCG + sec;
139a0864b3eSthorpej 	fhpibwait(hd, IM_IDLE);
140a0864b3eSthorpej 	hd->hpib_stat = ST_READ0;
141a0864b3eSthorpej 	hd->hpib_data = 0;
142a0864b3eSthorpej 	if (cnt) {
143a0864b3eSthorpej 		while (--cnt >= 0) {
144a0864b3eSthorpej 			if (fhpibwait(hd, IM_BYTE) < 0)
145a0864b3eSthorpej 				break;
146a0864b3eSthorpej 			*buf++ = hd->hpib_data;
147a0864b3eSthorpej 		}
148a0864b3eSthorpej 		cnt++;
149a0864b3eSthorpej 		fhpibwait(hd, IM_ROOM);
150a0864b3eSthorpej 		hd->hpib_stat = ST_ATN;
151a0864b3eSthorpej 		hd->hpib_data = (slave == 31) ? C_UNA : C_UNT;
152a0864b3eSthorpej 		fhpibwait(hd, IM_IDLE);
153a0864b3eSthorpej 	}
154a0864b3eSthorpej 	hd->hpib_imask = 0;
155212f884fStsutsui 	return origcnt - cnt;
156a0864b3eSthorpej }
157a0864b3eSthorpej 
158212f884fStsutsui int
fhpibppoll(int unit)159d3dc0553Stsutsui fhpibppoll(int unit)
160a0864b3eSthorpej {
161212f884fStsutsui 	struct hpib_softc *hs = &hpib_softc[unit];
162212f884fStsutsui 	struct fhpibdevice *hd;
163212f884fStsutsui 	int ppoll;
164a0864b3eSthorpej 
165212f884fStsutsui 	hd = (void *)hs->sc_addr;
166a0864b3eSthorpej 	hd->hpib_stat = 0;
167a0864b3eSthorpej 	hd->hpib_psense = 0;
168a0864b3eSthorpej 	hd->hpib_pmask = 0xFF;
169a0864b3eSthorpej 	hd->hpib_imask = IM_PPRESP | IM_PABORT;
170a0864b3eSthorpej 	DELAY(25);
171a0864b3eSthorpej 	hd->hpib_intr = IM_PABORT;
172a0864b3eSthorpej 	ppoll = hd->hpib_data;
173a0864b3eSthorpej 	if (hd->hpib_intr & IM_PABORT)
174a0864b3eSthorpej 		ppoll = 0;
175a0864b3eSthorpej 	hd->hpib_imask = 0;
176a0864b3eSthorpej 	hd->hpib_pmask = 0;
177a0864b3eSthorpej 	hd->hpib_stat = ST_IENAB;
178212f884fStsutsui 	return ppoll;
179a0864b3eSthorpej }
180a0864b3eSthorpej 
181212f884fStsutsui static int
fhpibwait(struct fhpibdevice * hd,uint8_t x)182d3dc0553Stsutsui fhpibwait(struct fhpibdevice *hd, uint8_t x)
183a0864b3eSthorpej {
184212f884fStsutsui 	int timo = 100000;
185a0864b3eSthorpej 
186a0864b3eSthorpej 	while ((hd->hpib_intr & x) == 0 && --timo)
187a0864b3eSthorpej 		;
188a0864b3eSthorpej 	if (timo == 0)
189212f884fStsutsui 		return -1;
190212f884fStsutsui 	return 0;
191a0864b3eSthorpej }
192