1/*	$NetBSD: fhpib.c,v 1.5 2005/12/11 12:17:19 christos 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. Neither the name of the University nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 *	@(#)fhpib.c	8.1 (Berkeley) 6/10/93
32 */
33
34/*
35 * 98625A/B HPIB driver
36 */
37
38#include <sys/param.h>
39
40#include <hp300/dev/fhpibreg.h>
41
42#include <hp300/stand/common/hpibvar.h>
43#include <hp300/stand/common/samachdep.h>
44
45static int fhpibwait(struct fhpibdevice *, uint8_t);
46
47int
48fhpibinit(int unit)
49{
50	struct hpib_softc *hs = &hpib_softc[unit];
51	struct fhpibdevice *hd = (void *)hs->sc_addr;
52
53	if (hd->hpib_cid != HPIBC)
54		return 0;
55	hs->sc_type = HPIBC;
56	hs->sc_ba = HPIBC_BA;
57	fhpibreset(unit);
58	return 1;
59}
60
61void
62fhpibreset(int unit)
63{
64	struct hpib_softc *hs = &hpib_softc[unit];
65	struct fhpibdevice *hd;
66
67	hd = (void *)hs->sc_addr;
68	hd->hpib_cid = 0xFF;
69	DELAY(100);
70	hd->hpib_cmd = CT_8BIT;
71	hd->hpib_ar = AR_ARONC;
72	hd->hpib_cmd |= CT_IFC;
73	hd->hpib_cmd |= CT_INITFIFO;
74	DELAY(100);
75	hd->hpib_cmd &= ~CT_IFC;
76	hd->hpib_cmd |= CT_REN;
77	hd->hpib_stat = ST_ATN;
78	hd->hpib_data = C_DCL;
79	DELAY(100000);
80}
81
82int
83fhpibsend(int unit, int slave, int sec, uint8_t *buf, int cnt)
84{
85	struct hpib_softc *hs = &hpib_softc[unit];
86	struct fhpibdevice *hd;
87	int origcnt = cnt;
88
89	hd = (void *)hs->sc_addr;
90	hd->hpib_stat = 0;
91	hd->hpib_imask = IM_IDLE | IM_ROOM;
92	fhpibwait(hd, IM_IDLE);
93	hd->hpib_stat = ST_ATN;
94	hd->hpib_data = C_UNL;
95	hd->hpib_data = C_TAG + hs->sc_ba;
96	hd->hpib_data = C_LAG + slave;
97	if (sec != -1)
98		hd->hpib_data = C_SCG + sec;
99	fhpibwait(hd, IM_IDLE);
100	hd->hpib_stat = ST_WRITE;
101	if (cnt) {
102		while (--cnt) {
103			hd->hpib_data = *buf++;
104			if (fhpibwait(hd, IM_ROOM) < 0)
105				break;
106		}
107		hd->hpib_stat = ST_EOI;
108		hd->hpib_data = *buf;
109		if (fhpibwait(hd, IM_ROOM) < 0)
110			cnt++;
111		hd->hpib_stat = ST_ATN;
112		/* XXX: HP-UX claims bug with CS80 transparent messages */
113		if (sec == 0x12)
114			DELAY(150);
115		hd->hpib_data = C_UNL;
116		fhpibwait(hd, IM_IDLE);
117	}
118	hd->hpib_imask = 0;
119	return origcnt - cnt;
120}
121
122int
123fhpibrecv(int unit, int slave, int sec, uint8_t *buf, int cnt)
124{
125	struct hpib_softc *hs = &hpib_softc[unit];
126	struct fhpibdevice *hd;
127	int origcnt = cnt;
128
129	hd = (void *)hs->sc_addr;
130	hd->hpib_stat = 0;
131	hd->hpib_imask = IM_IDLE | IM_ROOM | IM_BYTE;
132	fhpibwait(hd, IM_IDLE);
133	hd->hpib_stat = ST_ATN;
134	hd->hpib_data = C_UNL;
135	hd->hpib_data = C_LAG + hs->sc_ba;
136	hd->hpib_data = C_TAG + slave;
137	if (sec != -1)
138		hd->hpib_data = C_SCG + sec;
139	fhpibwait(hd, IM_IDLE);
140	hd->hpib_stat = ST_READ0;
141	hd->hpib_data = 0;
142	if (cnt) {
143		while (--cnt >= 0) {
144			if (fhpibwait(hd, IM_BYTE) < 0)
145				break;
146			*buf++ = hd->hpib_data;
147		}
148		cnt++;
149		fhpibwait(hd, IM_ROOM);
150		hd->hpib_stat = ST_ATN;
151		hd->hpib_data = (slave == 31) ? C_UNA : C_UNT;
152		fhpibwait(hd, IM_IDLE);
153	}
154	hd->hpib_imask = 0;
155	return origcnt - cnt;
156}
157
158int
159fhpibppoll(int unit)
160{
161	struct hpib_softc *hs = &hpib_softc[unit];
162	struct fhpibdevice *hd;
163	int ppoll;
164
165	hd = (void *)hs->sc_addr;
166	hd->hpib_stat = 0;
167	hd->hpib_psense = 0;
168	hd->hpib_pmask = 0xFF;
169	hd->hpib_imask = IM_PPRESP | IM_PABORT;
170	DELAY(25);
171	hd->hpib_intr = IM_PABORT;
172	ppoll = hd->hpib_data;
173	if (hd->hpib_intr & IM_PABORT)
174		ppoll = 0;
175	hd->hpib_imask = 0;
176	hd->hpib_pmask = 0;
177	hd->hpib_stat = ST_IENAB;
178	return ppoll;
179}
180
181static int
182fhpibwait(struct fhpibdevice *hd, uint8_t x)
183{
184	int timo = 100000;
185
186	while ((hd->hpib_intr & x) == 0 && --timo)
187		;
188	if (timo == 0)
189		return -1;
190	return 0;
191}
192