141488Smckusick /* 241488Smckusick * Copyright (c) 1982, 1990 The Regents of the University of California. 341488Smckusick * All rights reserved. 441488Smckusick * 541488Smckusick * %sccs.include.redist.c% 641488Smckusick * 7*56510Sbostic * @(#)fhpib.c 7.3 (Berkeley) 10/11/92 841488Smckusick */ 941488Smckusick 1041488Smckusick /* 1141488Smckusick * 98625A/B HPIB driver 1241488Smckusick */ 1341488Smckusick 14*56510Sbostic #include <sys/param.h> 15*56510Sbostic #include <hp300/dev/fhpibreg.h> 16*56510Sbostic #include <hp300/stand/hpibvar.h> 1741488Smckusick 1841488Smckusick fhpibinit(unit) 1941488Smckusick register int unit; 2041488Smckusick { 2141488Smckusick register struct hpib_softc *hs = &hpib_softc[unit]; 2241488Smckusick register struct fhpibdevice *hd = (struct fhpibdevice *)hs->sc_addr; 2341488Smckusick 2441488Smckusick if (hd->hpib_cid != HPIBC) 2541488Smckusick return(0); 2641488Smckusick hs->sc_type = HPIBC; 2741488Smckusick hs->sc_ba = HPIBC_BA; 2841488Smckusick fhpibreset(unit); 2941488Smckusick return(1); 3041488Smckusick } 3141488Smckusick 3241488Smckusick fhpibreset(unit) 3341488Smckusick { 3441488Smckusick register struct hpib_softc *hs = &hpib_softc[unit]; 3541488Smckusick register struct fhpibdevice *hd; 3641488Smckusick 3741488Smckusick hd = (struct fhpibdevice *)hs->sc_addr; 3841488Smckusick hd->hpib_cid = 0xFF; 3941488Smckusick DELAY(100); 4041488Smckusick hd->hpib_cmd = CT_8BIT; 4141488Smckusick hd->hpib_ar = AR_ARONC; 4241488Smckusick hd->hpib_cmd |= CT_IFC; 4341488Smckusick hd->hpib_cmd |= CT_INITFIFO; 4441488Smckusick DELAY(100); 4541488Smckusick hd->hpib_cmd &= ~CT_IFC; 4641488Smckusick hd->hpib_cmd |= CT_REN; 4741488Smckusick hd->hpib_stat = ST_ATN; 4841488Smckusick hd->hpib_data = C_DCL; 4941488Smckusick DELAY(100000); 5041488Smckusick } 5141488Smckusick 5241488Smckusick fhpibsend(unit, slave, sec, buf, cnt) 5341488Smckusick register char *buf; 5441488Smckusick register int cnt; 5541488Smckusick { 5641488Smckusick register struct hpib_softc *hs = &hpib_softc[unit]; 5741488Smckusick register struct fhpibdevice *hd; 5841488Smckusick int origcnt = cnt; 5941488Smckusick 6041488Smckusick hd = (struct fhpibdevice *)hs->sc_addr; 6141488Smckusick hd->hpib_stat = 0; 6241488Smckusick hd->hpib_imask = IM_IDLE | IM_ROOM; 6341488Smckusick fhpibwait(hd, IM_IDLE); 6441488Smckusick hd->hpib_stat = ST_ATN; 6541488Smckusick hd->hpib_data = C_UNL; 6641488Smckusick hd->hpib_data = C_TAG + hs->sc_ba; 6741488Smckusick hd->hpib_data = C_LAG + slave; 6841488Smckusick if (sec != -1) 6941488Smckusick hd->hpib_data = C_SCG + sec; 7041488Smckusick fhpibwait(hd, IM_IDLE); 7141488Smckusick hd->hpib_stat = ST_WRITE; 7241488Smckusick if (cnt) { 7341488Smckusick while (--cnt) { 7441488Smckusick hd->hpib_data = *buf++; 7541488Smckusick if (fhpibwait(hd, IM_ROOM) < 0) 7641488Smckusick break; 7741488Smckusick } 7841488Smckusick hd->hpib_stat = ST_EOI; 7941488Smckusick hd->hpib_data = *buf; 8041488Smckusick if (fhpibwait(hd, IM_ROOM) < 0) 8141488Smckusick cnt++; 8241488Smckusick hd->hpib_stat = ST_ATN; 8341488Smckusick /* XXX: HP-UX claims bug with CS80 transparent messages */ 8441488Smckusick if (sec == 0x12) 8541488Smckusick DELAY(150); 8641488Smckusick hd->hpib_data = C_UNL; 8741488Smckusick fhpibwait(hd, IM_IDLE); 8841488Smckusick } 8941488Smckusick hd->hpib_imask = 0; 9041488Smckusick return(origcnt - cnt); 9141488Smckusick } 9241488Smckusick 9341488Smckusick fhpibrecv(unit, slave, sec, buf, cnt) 9441488Smckusick register char *buf; 9541488Smckusick register int cnt; 9641488Smckusick { 9741488Smckusick register struct hpib_softc *hs = &hpib_softc[unit]; 9841488Smckusick register struct fhpibdevice *hd; 9941488Smckusick int origcnt = cnt; 10041488Smckusick 10141488Smckusick hd = (struct fhpibdevice *)hs->sc_addr; 10241488Smckusick hd->hpib_stat = 0; 10341488Smckusick hd->hpib_imask = IM_IDLE | IM_ROOM | IM_BYTE; 10441488Smckusick fhpibwait(hd, IM_IDLE); 10541488Smckusick hd->hpib_stat = ST_ATN; 10641488Smckusick hd->hpib_data = C_UNL; 10741488Smckusick hd->hpib_data = C_LAG + hs->sc_ba; 10841488Smckusick hd->hpib_data = C_TAG + slave; 10941488Smckusick if (sec != -1) 11041488Smckusick hd->hpib_data = C_SCG + sec; 11141488Smckusick fhpibwait(hd, IM_IDLE); 11241488Smckusick hd->hpib_stat = ST_READ0; 11341488Smckusick hd->hpib_data = 0; 11441488Smckusick if (cnt) { 11541488Smckusick while (--cnt >= 0) { 11641488Smckusick if (fhpibwait(hd, IM_BYTE) < 0) 11741488Smckusick break; 11841488Smckusick *buf++ = hd->hpib_data; 11941488Smckusick } 12041488Smckusick cnt++; 12141488Smckusick fhpibwait(hd, IM_ROOM); 12241488Smckusick hd->hpib_stat = ST_ATN; 12341488Smckusick hd->hpib_data = (slave == 31) ? C_UNA : C_UNT; 12441488Smckusick fhpibwait(hd, IM_IDLE); 12541488Smckusick } 12641488Smckusick hd->hpib_imask = 0; 12741488Smckusick return(origcnt - cnt); 12841488Smckusick } 12941488Smckusick 13041488Smckusick fhpibppoll(unit) 13141488Smckusick register int unit; 13241488Smckusick { 13341488Smckusick register struct hpib_softc *hs = &hpib_softc[unit]; 13441488Smckusick register struct fhpibdevice *hd; 13541488Smckusick register int ppoll; 13641488Smckusick 13741488Smckusick hd = (struct fhpibdevice *)hs->sc_addr; 13841488Smckusick hd->hpib_stat = 0; 13941488Smckusick hd->hpib_psense = 0; 14041488Smckusick hd->hpib_pmask = 0xFF; 14141488Smckusick hd->hpib_imask = IM_PPRESP | IM_PABORT; 14241488Smckusick DELAY(25); 14341488Smckusick hd->hpib_intr = IM_PABORT; 14441488Smckusick ppoll = hd->hpib_data; 14541488Smckusick if (hd->hpib_intr & IM_PABORT) 14641488Smckusick ppoll = 0; 14741488Smckusick hd->hpib_imask = 0; 14841488Smckusick hd->hpib_pmask = 0; 14941488Smckusick hd->hpib_stat = ST_IENAB; 15041488Smckusick return(ppoll); 15141488Smckusick } 15241488Smckusick 15341488Smckusick fhpibwait(hd, x) 15441488Smckusick register struct fhpibdevice *hd; 15541488Smckusick { 15641488Smckusick register int timo = 100000; 15741488Smckusick 15841488Smckusick while ((hd->hpib_intr & x) == 0 && --timo) 15941488Smckusick ; 16041488Smckusick if (timo == 0) 16141488Smckusick return(-1); 16241488Smckusick return(0); 16341488Smckusick } 164