Annotation of Net2/arch/hp300/dev/ppi.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1982, 1990 The Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms, with or without
        !             6:  * modification, are permitted provided that the following conditions
        !             7:  * are met:
        !             8:  * 1. Redistributions of source code must retain the above copyright
        !             9:  *    notice, this list of conditions and the following disclaimer.
        !            10:  * 2. Redistributions in binary form must reproduce the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer in the
        !            12:  *    documentation and/or other materials provided with the distribution.
        !            13:  * 3. All advertising materials mentioning features or use of this software
        !            14:  *    must display the following acknowledgement:
        !            15:  *     This product includes software developed by the University of
        !            16:  *     California, Berkeley and its contributors.
        !            17:  * 4. Neither the name of the University nor the names of its contributors
        !            18:  *    may be used to endorse or promote products derived from this software
        !            19:  *    without specific prior written permission.
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            31:  * SUCH DAMAGE.
        !            32:  *
        !            33:  *     @(#)ppi.c       7.3 (Berkeley) 12/16/90
        !            34:  */
        !            35: 
        !            36: /*
        !            37:  * Printer/Plotter HPIB interface
        !            38:  */
        !            39: 
        !            40: #include "ppi.h"
        !            41: #if NPPI > 0
        !            42: 
        !            43: #include "sys/param.h"
        !            44: #include "sys/errno.h"
        !            45: #include "sys/uio.h"
        !            46: #include "sys/malloc.h"
        !            47: 
        !            48: #include "device.h"
        !            49: #include "ppiioctl.h"
        !            50: 
        !            51: int    ppiattach(), ppistart(), ppitimo();
        !            52: struct driver ppidriver = {
        !            53:        ppiattach, "ppi", ppistart,
        !            54: };
        !            55: 
        !            56: struct ppi_softc {
        !            57:        int     sc_flags;
        !            58:        struct  devqueue sc_dq;
        !            59:        struct  hp_device *sc_hd;
        !            60:        struct  ppiparam sc_param;
        !            61: #define sc_burst sc_param.burst
        !            62: #define sc_timo  sc_param.timo
        !            63: #define sc_delay sc_param.delay
        !            64:        int     sc_sec;
        !            65: } ppi_softc[NPPI];
        !            66: 
        !            67: /* sc_flags values */
        !            68: #define        PPIF_ALIVE      0x01    
        !            69: #define        PPIF_OPEN       0x02    
        !            70: #define PPIF_UIO       0x04
        !            71: #define PPIF_TIMO      0x08
        !            72: #define PPIF_DELAY     0x10
        !            73: 
        !            74: #define UNIT(x)                minor(x)
        !            75: 
        !            76: #ifdef DEBUG
        !            77: int    ppidebug = 0x80;
        !            78: #define PDB_FOLLOW     0x01
        !            79: #define PDB_IO         0x02
        !            80: #define PDB_NOCHECK    0x80
        !            81: #endif
        !            82: 
        !            83: ppiattach(hd)
        !            84:        register struct hp_device *hd;
        !            85: {
        !            86:        register struct ppi_softc *sc = &ppi_softc[hd->hp_unit];
        !            87: 
        !            88: #ifdef DEBUG
        !            89:        if ((ppidebug & PDB_NOCHECK) == 0)
        !            90: #endif
        !            91:        /*
        !            92:         * XXX: the printer/plotter doesn't seem to really return
        !            93:         * an ID but this will at least prevent us from mistaking
        !            94:         * a cs80 disk or tape for a ppi device.
        !            95:         */
        !            96:        if (hpibid(hd->hp_ctlr, hd->hp_slave) & 0x200)
        !            97:                return(0);
        !            98:        sc->sc_flags = PPIF_ALIVE;
        !            99:        sc->sc_dq.dq_ctlr = hd->hp_ctlr;
        !           100:        sc->sc_dq.dq_unit = hd->hp_unit;
        !           101:        sc->sc_dq.dq_slave = hd->hp_slave;
        !           102:        sc->sc_dq.dq_driver = &ppidriver;
        !           103:        sc->sc_hd = hd;
        !           104:        return(1);
        !           105: }
        !           106: 
        !           107: ppiopen(dev, flags)
        !           108:        dev_t dev;
        !           109: {
        !           110:        register int unit = UNIT(dev);
        !           111:        register struct ppi_softc *sc = &ppi_softc[unit];
        !           112: 
        !           113:        if (unit >= NPPI || (sc->sc_flags & PPIF_ALIVE) == 0)
        !           114:                return(ENXIO);
        !           115: #ifdef DEBUG
        !           116:        if (ppidebug & PDB_FOLLOW)
        !           117:                printf("ppiopen(%x, %x): flags %x\n",
        !           118:                       dev, flags, sc->sc_flags);
        !           119: #endif
        !           120:        if (sc->sc_flags & PPIF_OPEN)
        !           121:                return(EBUSY);
        !           122:        sc->sc_flags |= PPIF_OPEN;
        !           123:        sc->sc_burst = PPI_BURST;
        !           124:        sc->sc_timo = ppimstohz(PPI_TIMO);
        !           125:        sc->sc_delay = ppimstohz(PPI_DELAY);
        !           126:        sc->sc_sec = -1;
        !           127:        return(0);
        !           128: }
        !           129: 
        !           130: ppiclose(dev, flags)
        !           131:        dev_t dev;
        !           132: {
        !           133:        register int unit = UNIT(dev);
        !           134:        register struct ppi_softc *sc = &ppi_softc[unit];
        !           135: 
        !           136: #ifdef DEBUG
        !           137:        if (ppidebug & PDB_FOLLOW)
        !           138:                printf("ppiclose(%x, %x): flags %x\n",
        !           139:                       dev, flags, sc->sc_flags);
        !           140: #endif
        !           141:        sc->sc_flags &= ~PPIF_OPEN;
        !           142:        return(0);
        !           143: }
        !           144: 
        !           145: ppistart(unit)
        !           146:        int unit;
        !           147: {
        !           148: #ifdef DEBUG
        !           149:        if (ppidebug & PDB_FOLLOW)
        !           150:                printf("ppistart(%x)\n", unit);
        !           151: #endif
        !           152:        ppi_softc[unit].sc_flags &= ~PPIF_DELAY;
        !           153:        wakeup(&ppi_softc[unit]);
        !           154: }
        !           155: 
        !           156: ppitimo(unit)
        !           157:        int unit;
        !           158: {
        !           159: #ifdef DEBUG
        !           160:        if (ppidebug & PDB_FOLLOW)
        !           161:                printf("ppitimo(%x)\n", unit);
        !           162: #endif
        !           163:        ppi_softc[unit].sc_flags &= ~(PPIF_UIO|PPIF_TIMO);
        !           164:        wakeup(&ppi_softc[unit]);
        !           165: }
        !           166: 
        !           167: ppiread(dev, uio)
        !           168:        dev_t dev;
        !           169:        struct uio *uio;
        !           170: {
        !           171: 
        !           172: #ifdef DEBUG
        !           173:        if (ppidebug & PDB_FOLLOW)
        !           174:                printf("ppiread(%x, %x)\n", dev, uio);
        !           175: #endif
        !           176:        return (ppirw(dev, uio));
        !           177: }
        !           178: 
        !           179: ppiwrite(dev, uio)
        !           180:        dev_t dev;
        !           181:        struct uio *uio;
        !           182: {
        !           183: 
        !           184: #ifdef DEBUG
        !           185:        if (ppidebug & PDB_FOLLOW)
        !           186:                printf("ppiwrite(%x, %x)\n", dev, uio);
        !           187: #endif
        !           188:        return (ppirw(dev, uio));
        !           189: }
        !           190: 
        !           191: ppirw(dev, uio)
        !           192:        dev_t dev;
        !           193:        register struct uio *uio;
        !           194: {
        !           195:        int unit = UNIT(dev);
        !           196:        register struct ppi_softc *sc = &ppi_softc[unit];
        !           197:        register int s, len, cnt;
        !           198:        register char *cp;
        !           199:        int error = 0, gotdata = 0;
        !           200:        int buflen;
        !           201:        char *buf;
        !           202: 
        !           203:        if (uio->uio_resid == 0)
        !           204:                return(0);
        !           205: 
        !           206: #ifdef DEBUG
        !           207:        if (ppidebug & (PDB_FOLLOW|PDB_IO))
        !           208:                printf("ppirw(%x, %x, %c): burst %d, timo %d, resid %x\n",
        !           209:                       dev, uio, uio->uio_rw == UIO_READ ? 'R' : 'W',
        !           210:                       sc->sc_burst, sc->sc_timo, uio->uio_resid);
        !           211: #endif
        !           212:        buflen = MIN(sc->sc_burst, uio->uio_resid);
        !           213:        buf = (char *)malloc(buflen, M_DEVBUF, M_WAITOK);
        !           214:        sc->sc_flags |= PPIF_UIO;
        !           215:        if (sc->sc_timo > 0) {
        !           216:                sc->sc_flags |= PPIF_TIMO;
        !           217:                timeout(ppitimo, unit, sc->sc_timo);
        !           218:        }
        !           219:        while (uio->uio_resid > 0) {
        !           220:                len = MIN(buflen, uio->uio_resid);
        !           221:                cp = buf;
        !           222:                if (uio->uio_rw == UIO_WRITE) {
        !           223:                        error = uiomove(cp, len, uio);
        !           224:                        if (error)
        !           225:                                break;
        !           226:                }
        !           227: again:
        !           228:                s = splbio();
        !           229:                if ((sc->sc_flags & PPIF_UIO) && hpibreq(&sc->sc_dq) == 0)
        !           230:                        sleep(sc, PRIBIO+1);
        !           231:                /*
        !           232:                 * Check if we timed out during sleep or uiomove
        !           233:                 */
        !           234:                (void) splsoftclock();
        !           235:                if ((sc->sc_flags & PPIF_UIO) == 0) {
        !           236: #ifdef DEBUG
        !           237:                        if (ppidebug & PDB_IO)
        !           238:                                printf("ppirw: uiomove/sleep timo, flags %x\n",
        !           239:                                       sc->sc_flags);
        !           240: #endif
        !           241:                        if (sc->sc_flags & PPIF_TIMO) {
        !           242:                                untimeout(ppitimo, unit);
        !           243:                                sc->sc_flags &= ~PPIF_TIMO;
        !           244:                        }
        !           245:                        splx(s);
        !           246:                        break;
        !           247:                }
        !           248:                splx(s);
        !           249:                /*
        !           250:                 * Perform the operation
        !           251:                 */
        !           252:                if (uio->uio_rw == UIO_WRITE)
        !           253:                        cnt = hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave,
        !           254:                                       sc->sc_sec, cp, len);
        !           255:                else
        !           256:                        cnt = hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave,
        !           257:                                       sc->sc_sec, cp, len);
        !           258:                s = splbio();
        !           259:                hpibfree(&sc->sc_dq);
        !           260: #ifdef DEBUG
        !           261:                if (ppidebug & PDB_IO)
        !           262:                        printf("ppirw: %s(%d, %d, %x, %x, %d) -> %d\n",
        !           263:                               uio->uio_rw == UIO_READ ? "recv" : "send",
        !           264:                               sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave,
        !           265:                               sc->sc_sec, cp, len, cnt);
        !           266: #endif
        !           267:                splx(s);
        !           268:                if (uio->uio_rw == UIO_READ) {
        !           269:                        if (cnt) {
        !           270:                                error = uiomove(cp, cnt, uio);
        !           271:                                if (error)
        !           272:                                        break;
        !           273:                                gotdata++;
        !           274:                        }
        !           275:                        /*
        !           276:                         * Didn't get anything this time, but did in the past.
        !           277:                         * Consider us done.
        !           278:                         */
        !           279:                        else if (gotdata)
        !           280:                                break;
        !           281:                }
        !           282:                s = splsoftclock();
        !           283:                /*
        !           284:                 * Operation timeout (or non-blocking), quit now.
        !           285:                 */
        !           286:                if ((sc->sc_flags & PPIF_UIO) == 0) {
        !           287: #ifdef DEBUG
        !           288:                        if (ppidebug & PDB_IO)
        !           289:                                printf("ppirw: timeout/done\n");
        !           290: #endif
        !           291:                        splx(s);
        !           292:                        break;
        !           293:                }
        !           294:                /*
        !           295:                 * Implement inter-read delay
        !           296:                 */
        !           297:                if (sc->sc_delay > 0) {
        !           298:                        sc->sc_flags |= PPIF_DELAY;
        !           299:                        timeout(ppistart, unit, sc->sc_delay);
        !           300:                        error = tsleep(sc, PCATCH|PZERO+1, "hpib", 0);
        !           301:                        if (error) {
        !           302:                                splx(s);
        !           303:                                break;
        !           304:                        }
        !           305:                }
        !           306:                splx(s);
        !           307:                /*
        !           308:                 * Must not call uiomove again til we've used all data
        !           309:                 * that we already grabbed.
        !           310:                 */
        !           311:                if (uio->uio_rw == UIO_WRITE && cnt != len) {
        !           312:                        cp += cnt;
        !           313:                        len -= cnt;
        !           314:                        cnt = 0;
        !           315:                        goto again;
        !           316:                }
        !           317:        }
        !           318:        s = splsoftclock();
        !           319:        if (sc->sc_flags & PPIF_TIMO) {
        !           320:                untimeout(ppitimo, unit);
        !           321:                sc->sc_flags &= ~PPIF_TIMO;
        !           322:        }
        !           323:        if (sc->sc_flags & PPIF_DELAY) {
        !           324:                untimeout(ppistart, unit);
        !           325:                sc->sc_flags &= ~PPIF_DELAY;
        !           326:        }
        !           327:        splx(s);
        !           328:        /*
        !           329:         * Adjust for those chars that we uiomove'ed but never wrote
        !           330:         */
        !           331:        if (uio->uio_rw == UIO_WRITE && cnt != len) {
        !           332:                uio->uio_resid += (len - cnt);
        !           333: #ifdef DEBUG
        !           334:                if (ppidebug & PDB_IO)
        !           335:                        printf("ppirw: short write, adjust by %d\n",
        !           336:                               len-cnt);
        !           337: #endif
        !           338:        }
        !           339:        free(buf, M_DEVBUF);
        !           340: #ifdef DEBUG
        !           341:        if (ppidebug & (PDB_FOLLOW|PDB_IO))
        !           342:                printf("ppirw: return %d, resid %d\n", error, uio->uio_resid);
        !           343: #endif
        !           344:        return (error);
        !           345: }
        !           346: 
        !           347: ppiioctl(dev, cmd, data, flag)
        !           348:        dev_t dev;
        !           349:        int cmd;
        !           350:        caddr_t data;
        !           351:        int flag;
        !           352: {
        !           353:        struct ppi_softc *sc = &ppi_softc[UNIT(dev)];
        !           354:        struct ppiparam *pp, *upp;
        !           355:        int error = 0;
        !           356: 
        !           357:        switch (cmd) {
        !           358:        case PPIIOCGPARAM:
        !           359:                pp = &sc->sc_param;
        !           360:                upp = (struct ppiparam *)data;
        !           361:                upp->burst = pp->burst;
        !           362:                upp->timo = ppihztoms(pp->timo);
        !           363:                upp->delay = ppihztoms(pp->delay);
        !           364:                break;
        !           365:        case PPIIOCSPARAM:
        !           366:                pp = &sc->sc_param;
        !           367:                upp = (struct ppiparam *)data;
        !           368:                if (upp->burst < PPI_BURST_MIN || upp->burst > PPI_BURST_MAX ||
        !           369:                    upp->delay < PPI_DELAY_MIN || upp->delay > PPI_DELAY_MAX)
        !           370:                        return(EINVAL);
        !           371:                pp->burst = upp->burst;
        !           372:                pp->timo = ppimstohz(upp->timo);
        !           373:                pp->delay = ppimstohz(upp->delay);
        !           374:                break;
        !           375:        case PPIIOCSSEC:
        !           376:                sc->sc_sec = *(int *)data;
        !           377:                break;
        !           378:        default:
        !           379:                return(EINVAL);
        !           380:        }
        !           381:        return (error);
        !           382: }
        !           383: 
        !           384: ppihztoms(h)
        !           385:        int h;
        !           386: {
        !           387:        extern int hz;
        !           388:        register int m = h;
        !           389: 
        !           390:        if (m > 0)
        !           391:                m = m * 1000 / hz;
        !           392:        return(m);
        !           393: }
        !           394: 
        !           395: ppimstohz(m)
        !           396:        int m;
        !           397: {
        !           398:        extern int hz;
        !           399:        register int h = m;
        !           400: 
        !           401:        if (h > 0) {
        !           402:                h = h * hz / 1000;
        !           403:                if (h == 0)
        !           404:                        h = 1000 / hz;
        !           405:        }
        !           406:        return(h);
        !           407: }
        !           408: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.