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