/* $OpenBSD: fhpib.c,v 1.1 1997/07/14 08:14:12 downsj Exp $ */ /* $NetBSD: fhpib.c,v 1.5 1995/08/05 16:47:42 thorpej Exp $ */ /* * Copyright (c) 1982, 1990, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)fhpib.c 8.1 (Berkeley) 6/10/93 */ /* * 98625A/B HPIB driver */ #include #include #include "hpibvar.h" #include "samachdep.h" fhpibinit(unit) register int unit; { register struct hpib_softc *hs = &hpib_softc[unit]; register struct fhpibdevice *hd = (struct fhpibdevice *)hs->sc_addr; if (hd->hpib_cid != HPIBC) return(0); hs->sc_type = HPIBC; hs->sc_ba = HPIBC_BA; fhpibreset(unit); return(1); } fhpibreset(unit) { register struct hpib_softc *hs = &hpib_softc[unit]; register struct fhpibdevice *hd; hd = (struct fhpibdevice *)hs->sc_addr; hd->hpib_cid = 0xFF; DELAY(100); hd->hpib_cmd = CT_8BIT; hd->hpib_ar = AR_ARONC; hd->hpib_cmd |= CT_IFC; hd->hpib_cmd |= CT_INITFIFO; DELAY(100); hd->hpib_cmd &= ~CT_IFC; hd->hpib_cmd |= CT_REN; hd->hpib_stat = ST_ATN; hd->hpib_data = C_DCL; DELAY(100000); } fhpibsend(unit, slave, sec, buf, cnt) register char *buf; register int cnt; { register struct hpib_softc *hs = &hpib_softc[unit]; register struct fhpibdevice *hd; int origcnt = cnt; hd = (struct fhpibdevice *)hs->sc_addr; hd->hpib_stat = 0; hd->hpib_imask = IM_IDLE | IM_ROOM; fhpibwait(hd, IM_IDLE); hd->hpib_stat = ST_ATN; hd->hpib_data = C_UNL; hd->hpib_data = C_TAG + hs->sc_ba; hd->hpib_data = C_LAG + slave; if (sec != -1) hd->hpib_data = C_SCG + sec; fhpibwait(hd, IM_IDLE); hd->hpib_stat = ST_WRITE; if (cnt) { while (--cnt) { hd->hpib_data = *buf++; if (fhpibwait(hd, IM_ROOM) < 0) break; } hd->hpib_stat = ST_EOI; hd->hpib_data = *buf; if (fhpibwait(hd, IM_ROOM) < 0) cnt++; hd->hpib_stat = ST_ATN; /* XXX: HP-UX claims bug with CS80 transparent messages */ if (sec == 0x12) DELAY(150); hd->hpib_data = C_UNL; fhpibwait(hd, IM_IDLE); } hd->hpib_imask = 0; return(origcnt - cnt); } fhpibrecv(unit, slave, sec, buf, cnt) register char *buf; register int cnt; { register struct hpib_softc *hs = &hpib_softc[unit]; register struct fhpibdevice *hd; int origcnt = cnt; hd = (struct fhpibdevice *)hs->sc_addr; hd->hpib_stat = 0; hd->hpib_imask = IM_IDLE | IM_ROOM | IM_BYTE; fhpibwait(hd, IM_IDLE); hd->hpib_stat = ST_ATN; hd->hpib_data = C_UNL; hd->hpib_data = C_LAG + hs->sc_ba; hd->hpib_data = C_TAG + slave; if (sec != -1) hd->hpib_data = C_SCG + sec; fhpibwait(hd, IM_IDLE); hd->hpib_stat = ST_READ0; hd->hpib_data = 0; if (cnt) { while (--cnt >= 0) { if (fhpibwait(hd, IM_BYTE) < 0) break; *buf++ = hd->hpib_data; } cnt++; fhpibwait(hd, IM_ROOM); hd->hpib_stat = ST_ATN; hd->hpib_data = (slave == 31) ? C_UNA : C_UNT; fhpibwait(hd, IM_IDLE); } hd->hpib_imask = 0; return(origcnt - cnt); } fhpibppoll(unit) register int unit; { register struct hpib_softc *hs = &hpib_softc[unit]; register struct fhpibdevice *hd; register int ppoll; hd = (struct fhpibdevice *)hs->sc_addr; hd->hpib_stat = 0; hd->hpib_psense = 0; hd->hpib_pmask = 0xFF; hd->hpib_imask = IM_PPRESP | IM_PABORT; DELAY(25); hd->hpib_intr = IM_PABORT; ppoll = hd->hpib_data; if (hd->hpib_intr & IM_PABORT) ppoll = 0; hd->hpib_imask = 0; hd->hpib_pmask = 0; hd->hpib_stat = ST_IENAB; return(ppoll); } fhpibwait(hd, x) register struct fhpibdevice *hd; { register int timo = 100000; while ((hd->hpib_intr & x) == 0 && --timo) ; if (timo == 0) return(-1); return(0); }