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

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:  *
1.1.1.2 ! root       33:  *     from: @(#)ppi.c 7.3 (Berkeley) 12/16/90
        !            34:  *     ppi.c,v 1.2 1993/05/22 07:56:41 cgd Exp
1.1       root       35:  */
                     36: 
                     37: /*
                     38:  * Printer/Plotter HPIB interface
                     39:  */
                     40: 
                     41: #include "ppi.h"
                     42: #if NPPI > 0
                     43: 
                     44: #include "sys/param.h"
                     45: #include "sys/errno.h"
                     46: #include "sys/uio.h"
                     47: #include "sys/malloc.h"
                     48: 
                     49: #include "device.h"
                     50: #include "ppiioctl.h"
                     51: 
                     52: int    ppiattach(), ppistart(), ppitimo();
                     53: struct driver ppidriver = {
                     54:        ppiattach, "ppi", ppistart,
                     55: };
                     56: 
                     57: struct ppi_softc {
                     58:        int     sc_flags;
                     59:        struct  devqueue sc_dq;
                     60:        struct  hp_device *sc_hd;
                     61:        struct  ppiparam sc_param;
                     62: #define sc_burst sc_param.burst
                     63: #define sc_timo  sc_param.timo
                     64: #define sc_delay sc_param.delay
                     65:        int     sc_sec;
                     66: } ppi_softc[NPPI];
                     67: 
                     68: /* sc_flags values */
                     69: #define        PPIF_ALIVE      0x01    
                     70: #define        PPIF_OPEN       0x02    
                     71: #define PPIF_UIO       0x04
                     72: #define PPIF_TIMO      0x08
                     73: #define PPIF_DELAY     0x10
                     74: 
                     75: #define UNIT(x)                minor(x)
                     76: 
                     77: #ifdef DEBUG
                     78: int    ppidebug = 0x80;
                     79: #define PDB_FOLLOW     0x01
                     80: #define PDB_IO         0x02
                     81: #define PDB_NOCHECK    0x80
                     82: #endif
                     83: 
                     84: ppiattach(hd)
                     85:        register struct hp_device *hd;
                     86: {
                     87:        register struct ppi_softc *sc = &ppi_softc[hd->hp_unit];
                     88: 
                     89: #ifdef DEBUG
                     90:        if ((ppidebug & PDB_NOCHECK) == 0)
                     91: #endif
                     92:        /*
                     93:         * XXX: the printer/plotter doesn't seem to really return
                     94:         * an ID but this will at least prevent us from mistaking
                     95:         * a cs80 disk or tape for a ppi device.
                     96:         */
                     97:        if (hpibid(hd->hp_ctlr, hd->hp_slave) & 0x200)
                     98:                return(0);
                     99:        sc->sc_flags = PPIF_ALIVE;
                    100:        sc->sc_dq.dq_ctlr = hd->hp_ctlr;
                    101:        sc->sc_dq.dq_unit = hd->hp_unit;
                    102:        sc->sc_dq.dq_slave = hd->hp_slave;
                    103:        sc->sc_dq.dq_driver = &ppidriver;
                    104:        sc->sc_hd = hd;
                    105:        return(1);
                    106: }
                    107: 
                    108: ppiopen(dev, flags)
                    109:        dev_t dev;
                    110: {
                    111:        register int unit = UNIT(dev);
                    112:        register struct ppi_softc *sc = &ppi_softc[unit];
                    113: 
                    114:        if (unit >= NPPI || (sc->sc_flags & PPIF_ALIVE) == 0)
                    115:                return(ENXIO);
                    116: #ifdef DEBUG
                    117:        if (ppidebug & PDB_FOLLOW)
                    118:                printf("ppiopen(%x, %x): flags %x\n",
                    119:                       dev, flags, sc->sc_flags);
                    120: #endif
                    121:        if (sc->sc_flags & PPIF_OPEN)
                    122:                return(EBUSY);
                    123:        sc->sc_flags |= PPIF_OPEN;
                    124:        sc->sc_burst = PPI_BURST;
                    125:        sc->sc_timo = ppimstohz(PPI_TIMO);
                    126:        sc->sc_delay = ppimstohz(PPI_DELAY);
                    127:        sc->sc_sec = -1;
                    128:        return(0);
                    129: }
                    130: 
                    131: ppiclose(dev, flags)
                    132:        dev_t dev;
                    133: {
                    134:        register int unit = UNIT(dev);
                    135:        register struct ppi_softc *sc = &ppi_softc[unit];
                    136: 
                    137: #ifdef DEBUG
                    138:        if (ppidebug & PDB_FOLLOW)
                    139:                printf("ppiclose(%x, %x): flags %x\n",
                    140:                       dev, flags, sc->sc_flags);
                    141: #endif
                    142:        sc->sc_flags &= ~PPIF_OPEN;
                    143:        return(0);
                    144: }
                    145: 
                    146: ppistart(unit)
                    147:        int unit;
                    148: {
                    149: #ifdef DEBUG
                    150:        if (ppidebug & PDB_FOLLOW)
                    151:                printf("ppistart(%x)\n", unit);
                    152: #endif
                    153:        ppi_softc[unit].sc_flags &= ~PPIF_DELAY;
                    154:        wakeup(&ppi_softc[unit]);
                    155: }
                    156: 
                    157: ppitimo(unit)
                    158:        int unit;
                    159: {
                    160: #ifdef DEBUG
                    161:        if (ppidebug & PDB_FOLLOW)
                    162:                printf("ppitimo(%x)\n", unit);
                    163: #endif
                    164:        ppi_softc[unit].sc_flags &= ~(PPIF_UIO|PPIF_TIMO);
                    165:        wakeup(&ppi_softc[unit]);
                    166: }
                    167: 
                    168: ppiread(dev, uio)
                    169:        dev_t dev;
                    170:        struct uio *uio;
                    171: {
                    172: 
                    173: #ifdef DEBUG
                    174:        if (ppidebug & PDB_FOLLOW)
                    175:                printf("ppiread(%x, %x)\n", dev, uio);
                    176: #endif
                    177:        return (ppirw(dev, uio));
                    178: }
                    179: 
                    180: ppiwrite(dev, uio)
                    181:        dev_t dev;
                    182:        struct uio *uio;
                    183: {
                    184: 
                    185: #ifdef DEBUG
                    186:        if (ppidebug & PDB_FOLLOW)
                    187:                printf("ppiwrite(%x, %x)\n", dev, uio);
                    188: #endif
                    189:        return (ppirw(dev, uio));
                    190: }
                    191: 
                    192: ppirw(dev, uio)
                    193:        dev_t dev;
                    194:        register struct uio *uio;
                    195: {
                    196:        int unit = UNIT(dev);
                    197:        register struct ppi_softc *sc = &ppi_softc[unit];
                    198:        register int s, len, cnt;
                    199:        register char *cp;
                    200:        int error = 0, gotdata = 0;
                    201:        int buflen;
                    202:        char *buf;
                    203: 
                    204:        if (uio->uio_resid == 0)
                    205:                return(0);
                    206: 
                    207: #ifdef DEBUG
                    208:        if (ppidebug & (PDB_FOLLOW|PDB_IO))
                    209:                printf("ppirw(%x, %x, %c): burst %d, timo %d, resid %x\n",
                    210:                       dev, uio, uio->uio_rw == UIO_READ ? 'R' : 'W',
                    211:                       sc->sc_burst, sc->sc_timo, uio->uio_resid);
                    212: #endif
                    213:        buflen = MIN(sc->sc_burst, uio->uio_resid);
                    214:        buf = (char *)malloc(buflen, M_DEVBUF, M_WAITOK);
                    215:        sc->sc_flags |= PPIF_UIO;
                    216:        if (sc->sc_timo > 0) {
                    217:                sc->sc_flags |= PPIF_TIMO;
                    218:                timeout(ppitimo, unit, sc->sc_timo);
                    219:        }
                    220:        while (uio->uio_resid > 0) {
                    221:                len = MIN(buflen, uio->uio_resid);
                    222:                cp = buf;
                    223:                if (uio->uio_rw == UIO_WRITE) {
                    224:                        error = uiomove(cp, len, uio);
                    225:                        if (error)
                    226:                                break;
                    227:                }
                    228: again:
                    229:                s = splbio();
                    230:                if ((sc->sc_flags & PPIF_UIO) && hpibreq(&sc->sc_dq) == 0)
                    231:                        sleep(sc, PRIBIO+1);
                    232:                /*
                    233:                 * Check if we timed out during sleep or uiomove
                    234:                 */
                    235:                (void) splsoftclock();
                    236:                if ((sc->sc_flags & PPIF_UIO) == 0) {
                    237: #ifdef DEBUG
                    238:                        if (ppidebug & PDB_IO)
                    239:                                printf("ppirw: uiomove/sleep timo, flags %x\n",
                    240:                                       sc->sc_flags);
                    241: #endif
                    242:                        if (sc->sc_flags & PPIF_TIMO) {
                    243:                                untimeout(ppitimo, unit);
                    244:                                sc->sc_flags &= ~PPIF_TIMO;
                    245:                        }
                    246:                        splx(s);
                    247:                        break;
                    248:                }
                    249:                splx(s);
                    250:                /*
                    251:                 * Perform the operation
                    252:                 */
                    253:                if (uio->uio_rw == UIO_WRITE)
                    254:                        cnt = hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave,
                    255:                                       sc->sc_sec, cp, len);
                    256:                else
                    257:                        cnt = hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave,
                    258:                                       sc->sc_sec, cp, len);
                    259:                s = splbio();
                    260:                hpibfree(&sc->sc_dq);
                    261: #ifdef DEBUG
                    262:                if (ppidebug & PDB_IO)
                    263:                        printf("ppirw: %s(%d, %d, %x, %x, %d) -> %d\n",
                    264:                               uio->uio_rw == UIO_READ ? "recv" : "send",
                    265:                               sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave,
                    266:                               sc->sc_sec, cp, len, cnt);
                    267: #endif
                    268:                splx(s);
                    269:                if (uio->uio_rw == UIO_READ) {
                    270:                        if (cnt) {
                    271:                                error = uiomove(cp, cnt, uio);
                    272:                                if (error)
                    273:                                        break;
                    274:                                gotdata++;
                    275:                        }
                    276:                        /*
                    277:                         * Didn't get anything this time, but did in the past.
                    278:                         * Consider us done.
                    279:                         */
                    280:                        else if (gotdata)
                    281:                                break;
                    282:                }
                    283:                s = splsoftclock();
                    284:                /*
                    285:                 * Operation timeout (or non-blocking), quit now.
                    286:                 */
                    287:                if ((sc->sc_flags & PPIF_UIO) == 0) {
                    288: #ifdef DEBUG
                    289:                        if (ppidebug & PDB_IO)
                    290:                                printf("ppirw: timeout/done\n");
                    291: #endif
                    292:                        splx(s);
                    293:                        break;
                    294:                }
                    295:                /*
                    296:                 * Implement inter-read delay
                    297:                 */
                    298:                if (sc->sc_delay > 0) {
                    299:                        sc->sc_flags |= PPIF_DELAY;
                    300:                        timeout(ppistart, unit, sc->sc_delay);
                    301:                        error = tsleep(sc, PCATCH|PZERO+1, "hpib", 0);
                    302:                        if (error) {
                    303:                                splx(s);
                    304:                                break;
                    305:                        }
                    306:                }
                    307:                splx(s);
                    308:                /*
                    309:                 * Must not call uiomove again til we've used all data
                    310:                 * that we already grabbed.
                    311:                 */
                    312:                if (uio->uio_rw == UIO_WRITE && cnt != len) {
                    313:                        cp += cnt;
                    314:                        len -= cnt;
                    315:                        cnt = 0;
                    316:                        goto again;
                    317:                }
                    318:        }
                    319:        s = splsoftclock();
                    320:        if (sc->sc_flags & PPIF_TIMO) {
                    321:                untimeout(ppitimo, unit);
                    322:                sc->sc_flags &= ~PPIF_TIMO;
                    323:        }
                    324:        if (sc->sc_flags & PPIF_DELAY) {
                    325:                untimeout(ppistart, unit);
                    326:                sc->sc_flags &= ~PPIF_DELAY;
                    327:        }
                    328:        splx(s);
                    329:        /*
                    330:         * Adjust for those chars that we uiomove'ed but never wrote
                    331:         */
                    332:        if (uio->uio_rw == UIO_WRITE && cnt != len) {
                    333:                uio->uio_resid += (len - cnt);
                    334: #ifdef DEBUG
                    335:                if (ppidebug & PDB_IO)
                    336:                        printf("ppirw: short write, adjust by %d\n",
                    337:                               len-cnt);
                    338: #endif
                    339:        }
                    340:        free(buf, M_DEVBUF);
                    341: #ifdef DEBUG
                    342:        if (ppidebug & (PDB_FOLLOW|PDB_IO))
                    343:                printf("ppirw: return %d, resid %d\n", error, uio->uio_resid);
                    344: #endif
                    345:        return (error);
                    346: }
                    347: 
                    348: ppiioctl(dev, cmd, data, flag)
                    349:        dev_t dev;
                    350:        int cmd;
                    351:        caddr_t data;
                    352:        int flag;
                    353: {
                    354:        struct ppi_softc *sc = &ppi_softc[UNIT(dev)];
                    355:        struct ppiparam *pp, *upp;
                    356:        int error = 0;
                    357: 
                    358:        switch (cmd) {
                    359:        case PPIIOCGPARAM:
                    360:                pp = &sc->sc_param;
                    361:                upp = (struct ppiparam *)data;
                    362:                upp->burst = pp->burst;
                    363:                upp->timo = ppihztoms(pp->timo);
                    364:                upp->delay = ppihztoms(pp->delay);
                    365:                break;
                    366:        case PPIIOCSPARAM:
                    367:                pp = &sc->sc_param;
                    368:                upp = (struct ppiparam *)data;
                    369:                if (upp->burst < PPI_BURST_MIN || upp->burst > PPI_BURST_MAX ||
                    370:                    upp->delay < PPI_DELAY_MIN || upp->delay > PPI_DELAY_MAX)
                    371:                        return(EINVAL);
                    372:                pp->burst = upp->burst;
                    373:                pp->timo = ppimstohz(upp->timo);
                    374:                pp->delay = ppimstohz(upp->delay);
                    375:                break;
                    376:        case PPIIOCSSEC:
                    377:                sc->sc_sec = *(int *)data;
                    378:                break;
                    379:        default:
                    380:                return(EINVAL);
                    381:        }
                    382:        return (error);
                    383: }
                    384: 
                    385: ppihztoms(h)
                    386:        int h;
                    387: {
                    388:        extern int hz;
                    389:        register int m = h;
                    390: 
                    391:        if (m > 0)
                    392:                m = m * 1000 / hz;
                    393:        return(m);
                    394: }
                    395: 
                    396: ppimstohz(m)
                    397:        int m;
                    398: {
                    399:        extern int hz;
                    400:        register int h = m;
                    401: 
                    402:        if (h > 0) {
                    403:                h = h * hz / 1000;
                    404:                if (h == 0)
                    405:                        h = 1000 / hz;
                    406:        }
                    407:        return(h);
                    408: }
                    409: #endif

unix.superglobalmegacorp.com

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