1*41480Smckusick /* 2*41480Smckusick * Copyright (c) 1982, 1990 The Regents of the University of California. 3*41480Smckusick * All rights reserved. 4*41480Smckusick * 5*41480Smckusick * %sccs.include.redist.c% 6*41480Smckusick * 7*41480Smckusick * @(#)ppi.c 7.1 (Berkeley) 05/08/90 8*41480Smckusick */ 9*41480Smckusick 10*41480Smckusick /* 11*41480Smckusick * Printer/Plotter HPIB interface 12*41480Smckusick */ 13*41480Smckusick 14*41480Smckusick #include "ppi.h" 15*41480Smckusick #if NPPI > 0 16*41480Smckusick 17*41480Smckusick #include "param.h" 18*41480Smckusick #include "errno.h" 19*41480Smckusick #include "uio.h" 20*41480Smckusick #include "malloc.h" 21*41480Smckusick 22*41480Smckusick #include "device.h" 23*41480Smckusick 24*41480Smckusick int ppiattach(), ppistart(); 25*41480Smckusick struct driver ppidriver = { 26*41480Smckusick ppiattach, "ppi", ppistart, 27*41480Smckusick }; 28*41480Smckusick 29*41480Smckusick struct ppi_softc { 30*41480Smckusick int sc_flags; 31*41480Smckusick struct devqueue sc_dq; 32*41480Smckusick struct hp_device *sc_hd; 33*41480Smckusick } ppi_softc[NPPI]; 34*41480Smckusick 35*41480Smckusick /* sc_flags values */ 36*41480Smckusick #define PPIF_ALIVE 0x1 37*41480Smckusick #define PPIF_OPEN 0x2 38*41480Smckusick 39*41480Smckusick #define UNIT(x) minor(x) 40*41480Smckusick 41*41480Smckusick ppiattach(hd) 42*41480Smckusick register struct hp_device *hd; 43*41480Smckusick { 44*41480Smckusick register struct ppi_softc *sc = &ppi_softc[hd->hp_unit]; 45*41480Smckusick 46*41480Smckusick /* 47*41480Smckusick * XXX: the printer/plotter doesn't seem to really return 48*41480Smckusick * an ID but this will at least prevent us from mistaking 49*41480Smckusick * a cs80 disk or tape for a ppi device. 50*41480Smckusick */ 51*41480Smckusick if (hpibid(hd->hp_ctlr, hd->hp_slave) & 0x200) 52*41480Smckusick return(0); 53*41480Smckusick sc->sc_flags = PPIF_ALIVE; 54*41480Smckusick sc->sc_dq.dq_ctlr = hd->hp_ctlr; 55*41480Smckusick sc->sc_dq.dq_unit = hd->hp_unit; 56*41480Smckusick sc->sc_dq.dq_slave = hd->hp_slave; 57*41480Smckusick sc->sc_dq.dq_driver = &ppidriver; 58*41480Smckusick sc->sc_hd = hd; 59*41480Smckusick return(1); 60*41480Smckusick } 61*41480Smckusick 62*41480Smckusick ppiopen(dev, flags) 63*41480Smckusick dev_t dev; 64*41480Smckusick { 65*41480Smckusick register int unit = UNIT(dev); 66*41480Smckusick register struct ppi_softc *sc = &ppi_softc[unit]; 67*41480Smckusick 68*41480Smckusick if (unit >= NPPI || (sc->sc_flags & PPIF_ALIVE) == 0) 69*41480Smckusick return(ENXIO); 70*41480Smckusick if (sc->sc_flags & PPIF_OPEN) 71*41480Smckusick return(EBUSY); 72*41480Smckusick sc->sc_flags |= PPIF_OPEN; 73*41480Smckusick return(0); 74*41480Smckusick } 75*41480Smckusick 76*41480Smckusick ppiclose(dev, flags) 77*41480Smckusick dev_t dev; 78*41480Smckusick { 79*41480Smckusick register int unit = UNIT(dev); 80*41480Smckusick register struct ppi_softc *sc = &ppi_softc[unit]; 81*41480Smckusick 82*41480Smckusick sc->sc_flags &= ~PPIF_OPEN; 83*41480Smckusick return(0); 84*41480Smckusick } 85*41480Smckusick 86*41480Smckusick ppistart(unit) 87*41480Smckusick register int unit; 88*41480Smckusick { 89*41480Smckusick wakeup(&ppi_softc[unit]); 90*41480Smckusick } 91*41480Smckusick 92*41480Smckusick ppiread(dev, uio) 93*41480Smckusick dev_t dev; 94*41480Smckusick struct uio *uio; 95*41480Smckusick { 96*41480Smckusick 97*41480Smckusick return (ppirw(dev, uio, UIO_READ)); 98*41480Smckusick } 99*41480Smckusick 100*41480Smckusick ppiwrite(dev, uio) 101*41480Smckusick dev_t dev; 102*41480Smckusick struct uio *uio; 103*41480Smckusick { 104*41480Smckusick 105*41480Smckusick return (ppirw(dev, uio, UIO_WRITE)); 106*41480Smckusick } 107*41480Smckusick 108*41480Smckusick ppirw(dev, uio, rw) 109*41480Smckusick dev_t dev; 110*41480Smckusick register struct uio *uio; 111*41480Smckusick enum uio_rw rw; 112*41480Smckusick { 113*41480Smckusick register struct ppi_softc *sc = &ppi_softc[UNIT(dev)]; 114*41480Smckusick register int s, len, cnt; 115*41480Smckusick register char *cp; 116*41480Smckusick int error = 0; 117*41480Smckusick 118*41480Smckusick len = MIN(CLBYTES, uio->uio_resid); 119*41480Smckusick cp = (char *)malloc(len, M_TEMP, M_WAITOK); 120*41480Smckusick while (uio->uio_resid > 0) { 121*41480Smckusick len = MIN(CLBYTES, uio->uio_resid); 122*41480Smckusick if (rw == UIO_WRITE) { 123*41480Smckusick error = uiomove(cp, len, uio); 124*41480Smckusick if (error) 125*41480Smckusick break; 126*41480Smckusick } 127*41480Smckusick s = splbio(); 128*41480Smckusick if (hpibreq(&sc->sc_dq) == 0) 129*41480Smckusick sleep(sc, PRIBIO + 1); 130*41480Smckusick splx(s); 131*41480Smckusick if (rw == UIO_WRITE) 132*41480Smckusick cnt = hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, 133*41480Smckusick -1, cp, len); 134*41480Smckusick else 135*41480Smckusick cnt = hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, 136*41480Smckusick -1, cp, len); 137*41480Smckusick s = splbio(); 138*41480Smckusick hpibfree(&sc->sc_dq); 139*41480Smckusick splx(s); 140*41480Smckusick if (rw == UIO_READ) { 141*41480Smckusick error = uiomove(cp, cnt, uio); 142*41480Smckusick if (error) 143*41480Smckusick break; 144*41480Smckusick } 145*41480Smckusick if (cnt != len) { 146*41480Smckusick if (rw == UIO_WRITE) 147*41480Smckusick uio->uio_resid += len - cnt; 148*41480Smckusick break; 149*41480Smckusick } 150*41480Smckusick } 151*41480Smckusick free(cp, M_TEMP); 152*41480Smckusick return (error); 153*41480Smckusick } 154*41480Smckusick #endif 155