/* $NetBSD: fhpib.c,v 1.6 2006/06/25 17:37:43 tsutsui 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. 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 #include static int fhpibwait(struct fhpibdevice *, uint8_t); int fhpibinit(int unit) { struct hpib_softc *hs = &hpib_softc[unit]; struct fhpibdevice *hd = (void *)hs->sc_addr; if (hd->hpib_cid != HPIBC) return 0; hs->sc_type = HPIBC; hs->sc_ba = HPIBC_BA; fhpibreset(unit); return 1; } void fhpibreset(int unit) { struct hpib_softc *hs = &hpib_softc[unit]; struct fhpibdevice *hd; hd = (void *)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); } int fhpibsend(int unit, int slave, int sec, uint8_t *buf, int cnt) { struct hpib_softc *hs = &hpib_softc[unit]; struct fhpibdevice *hd; int origcnt = cnt; hd = (void *)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; } int fhpibrecv(int unit, int slave, int sec, uint8_t *buf, int cnt) { struct hpib_softc *hs = &hpib_softc[unit]; struct fhpibdevice *hd; int origcnt = cnt; hd = (void *)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; } int fhpibppoll(int unit) { struct hpib_softc *hs = &hpib_softc[unit]; struct fhpibdevice *hd; int ppoll; hd = (void *)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; } static int fhpibwait(struct fhpibdevice *hd, uint8_t x) { int timo = 100000; while ((hd->hpib_intr & x) == 0 && --timo) ; if (timo == 0) return -1; return 0; }