Annotation of Net2/arch/hp300/dev/ppi.c, revision 1.1.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.