Annotation of coherent/d/PS2_KERNEL/coh.286/bio.c, revision 1.1.1.1

1.1       root        1: /* $Header: /kernel/kersrc/coh.286/RCS/bio.c,v 1.1 92/07/17 15:17:57 bin Exp Locker: bin $ */
                      2: /* (lgl-
                      3:  *     The information contained herein is a trade secret of Mark Williams
                      4:  *     Company, and  is confidential information.  It is provided  under a
                      5:  *     license agreement,  and may be  copied or disclosed  only under the
                      6:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
                      7:  *     material without the express written authorization of Mark Williams
                      8:  *     Company or persuant to the license agreement is unlawful.
                      9:  *
                     10:  *     COHERENT Version 2.3.37
                     11:  *     Copyright (c) 1982, 1983, 1984.
                     12:  *     An unpublished work by Mark Williams Company, Chicago.
                     13:  *     All rights reserved.
                     14:  -lgl) */
                     15: /*
                     16:  * Coherent.
                     17:  * Buffered I/O.
                     18:  *
                     19:  * $Log:       bio.c,v $
                     20:  * Revision 1.1  92/07/17  15:17:57  bin
                     21:  * Initial revision
                     22:  * 
                     23:  * Revision 1.1  91/11/08  12:46:39  hal
                     24:  * Used in COH 3.2.0
                     25:  * 
                     26:  * Revision 1.1        88/03/24  16:13:29      src
                     27:  * Initial revision
                     28:  * 
                     29:  * 87/11/25    Allan Cornish           /usr/src/sys/coh/bio.c
                     30:  * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr.
                     31:  *
                     32:  * 87/11/05    Allan Cornish           /usr/src/sys/coh/bio.c
                     33:  * New seg struct now used to allow extended addressing.
                     34:  *
                     35:  * 87/01/05    Allan Cornish           /usr/src/sys/coh/bio.c
                     36:  * ioreq() now only wakes &stimer if the swap timer is active.
                     37:  *
                     38:  * 86/12/12    Allan Cornish           /usr/src/sys/coh/bio.c
                     39:  * Added 3rd arg to dpoll() to specify blocking poll if non-zero.
                     40:  *
                     41:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/bio.c
                     42:  * Added dpoll() routine to perform device polls [System V.3 compatible].
                     43:  *
                     44:  * 86/07/24    Allan Cornish           /usr/src/sys/coh/bio.c
                     45:  * Added check in devinit() for null dp->d_conp->c_load function pointer.
                     46:  */
                     47: #include <sys/coherent.h>
                     48: #include <sys/buf.h>
                     49: #include <sys/con.h>
                     50: #include <errno.h>
                     51: #include <sys/io.h>
                     52: #include <sys/proc.h>
                     53: #include <sys/sched.h>
                     54: #include <sys/seg.h>
                     55: #include <sys/stat.h>
                     56: 
                     57: /*
                     58:  * Initialise buffer headers.
                     59:  */
                     60: bufinit()
                     61: {
                     62:        register BUF *bp;
                     63:        faddr_t f;
                     64:        paddr_t p;
                     65: 
                     66:        FP_SEL(f) = sds;
                     67:        FP_OFF(f) = 0;
                     68:        p = blockp;
                     69:        FP_OFF(f) = blockp - vtop(f);
                     70: 
                     71:        bufl = kalloc(NBUF * sizeof(BUF));
                     72:        if (bufl == NULL)
                     73:                panic("bufinit: no space for BUF's");
                     74: 
                     75:        for (bp=&bufl[NBUF-1]; bp >= bufl; --bp) {
                     76:                bp->b_dev = NODEV;
                     77:                bp->b_faddr = f;
                     78:                bp->b_paddr = p;
                     79:                FP_OFF(f) += BSIZE;
                     80:                p += BSIZE;
                     81:        }
                     82: }
                     83: 
                     84: /*
                     85:  * Synchronise the buffer cache.
                     86:  */
                     87: bsync()
                     88: {
                     89:        register BUF *bp;
                     90: 
                     91:        for (bp=&bufl[NBUF-1]; bp >= bufl; --bp) {
                     92:                if ((bp->b_flag&BFMOD) == 0)
                     93:                        continue;
                     94:                lock(bp->b_gate);
                     95:                if ((bp->b_flag&BFMOD) != 0)
                     96:                        bwrite(bp, 1);
                     97:                unlock(bp->b_gate);
                     98:        }
                     99: }
                    100: 
                    101: /*
                    102:  * Synchronise all block for a particular device in the buffer cache
                    103:  * and invalidate all references.
                    104:  */
                    105: bflush(dev)
                    106: register dev_t dev;
                    107: {
                    108:        register BUF *bp;
                    109: 
                    110:        for (bp=&bufl[NBUF-1]; bp >= bufl; --bp) {
                    111:                if (bp->b_dev != dev)
                    112:                        continue;
                    113:                lock(bp->b_gate);
                    114:                if (bp->b_dev == dev) {
                    115:                        if ((bp->b_flag&BFMOD) != 0)
                    116:                                bwrite(bp, 1);
                    117:                        bp->b_dev = NODEV;
                    118:                }
                    119:                unlock(bp->b_gate);
                    120:        }
                    121: }
                    122: 
                    123: /*
                    124:  * Return a buffer containing the given block from the given device.
                    125:  * If `f' is not set, the read is asynchronous and no buffer is returned.
                    126:  */
                    127: BUF *
                    128: bread(dev, bno, f)
                    129: dev_t dev;
                    130: daddr_t bno;
                    131: register int f;
                    132: {
                    133:        register BUF *bp;
                    134:        register int s;
                    135: 
                    136:        bp = bclaim(dev, bno);
                    137:        if ((bp->b_flag&BFNTP) != 0) {
                    138:                if (f != 0)
                    139:                        bp->b_flag &= ~BFASY;
                    140:                else {
                    141:                        bp->b_flag |= BFASY;
                    142:                        bumap(bp);
                    143:                }
                    144:                bp->b_req = BREAD;
                    145:                bp->b_count = BSIZE;
                    146:                s = sphi();
                    147:                dblock(dev, bp);
                    148:                if (f == 0) {
                    149:                        spl(s);
                    150:                        return (NULL);
                    151:                }
                    152:                while ((bp->b_flag&BFNTP) != 0)
                    153:                        sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
                    154:                spl(s);
                    155:                if ((bp->b_flag&BFERR) != 0) {
                    156:                        u.u_error = bp->b_err ? bp->b_err : EIO;
                    157:                        brelease(bp);
                    158:                        return (NULL);
                    159:                }
                    160:                if (bp->b_resid == BSIZE) {
                    161:                        brelease(bp);
                    162:                        return (NULL);
                    163:                }
                    164:        }
                    165:        if (f == 0) {
                    166:                brelease(bp);
                    167:                return (NULL);
                    168:        }
                    169:        u.u_block++;
                    170:        return (bp);
                    171: }
                    172: 
                    173: /*
                    174:  * If the requested buffer is in the buffer cache, return a pointer to
                    175:  * it.  If not, pick an empty buffer, set it up and return it.
                    176:  */
                    177: BUF *
                    178: bclaim(dev, bno)
                    179: dev_t dev;
                    180: daddr_t bno;
                    181: {
                    182:        register BUF *bp;
                    183:        register BUF *bp1;
                    184:        register unsigned seqn;
                    185:        register int s;
                    186: 
                    187: again:
                    188:        bp1 = NULL;
                    189:        seqn = 0;
                    190:        for (bp=&bufl[NBUF-1]; bp >= bufl; --bp) {
                    191:                if (bp->b_bno == bno  &&  bp->b_dev == dev) {
                    192:                        lock(bp->b_gate);
                    193:                        if (bp->b_bno != bno  ||  bp->b_dev != dev) {
                    194:                                unlock(bp->b_gate);
                    195:                                goto again;
                    196:                        }
                    197:                        if ((bp->b_flag&BFERR) != 0)
                    198:                                bp->b_flag |= BFNTP;
                    199:                        bsmap(bp);
                    200:                        return (bp);
                    201:                }
                    202:                if (locked(bp->b_gate) == 0) {
                    203:                        if (bufseqn-bp->b_seqn >= seqn) {
                    204:                                bp1 = bp;
                    205:                                seqn = bufseqn - bp->b_seqn;
                    206:                        }
                    207:                }
                    208:        }
                    209:        if (bp1 == NULL) {
                    210:                s = sphi();
                    211:                for (bp=&bufl[NBUF-1]; bp >= bufl; --bp) {
                    212:                        if (locked(bp->b_gate) == 0) {
                    213:                                if (bufseqn-bp->b_seqn >= seqn) {
                    214:                                        bp1 = bp;
                    215:                                        seqn = bufseqn - bp->b_seqn;
                    216:                                }
                    217:                        }
                    218:                }
                    219:                if (bp1 == NULL) {
                    220:                        bufneed = 1;
                    221:                        sleep((char *)&bufneed, CVBLKIO, IVBLKIO, SVBLKIO);
                    222:                        spl(s);
                    223:                        goto again;
                    224:                }
                    225:                spl(s);
                    226:        }
                    227:        bp = bp1;
                    228:        lock(bp->b_gate);
                    229:        if ((bp->b_flag&BFMOD) != 0) {
                    230:                bwrite(bp, 0);
                    231:                goto again;
                    232:        }
                    233:        bp->b_flag = BFNTP;
                    234:        bp->b_dev = dev;
                    235:        bp->b_bno = bno;
                    236:        bsmap(bp);
                    237:        return (bp);
                    238: }
                    239: 
                    240: /*
                    241:  * Write the given buffer out.  If `f' is set, the write is synchronous,
                    242:  * otherwise asynchronous.  This routine must be called with the buffer
                    243:  * gate locked.
                    244:  */
                    245: bwrite(bp, f)
                    246: register BUF *bp;
                    247: {
                    248:        register int s;
                    249: 
                    250:        if (f != 0)
                    251:                bp->b_flag &= ~BFASY;
                    252:        else {
                    253:                bp->b_flag |= BFASY;
                    254:                bumap(bp);
                    255:        }
                    256:        bp->b_flag |= BFNTP;
                    257:        bp->b_req = BWRITE;
                    258:        bp->b_count = BSIZE;
                    259:        s = sphi();
                    260:        dblock(bp->b_dev, bp);
                    261:        if (f == 0) {
                    262:                spl(s);
                    263:                return;
                    264:        }
                    265:        while ((bp->b_flag&BFNTP) != 0)
                    266:                sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
                    267:        spl(s);
                    268: }
                    269: 
                    270: /*
                    271:  * This is called by the driver when I/O has completed on a buffer.
                    272:  */
                    273: bdone(bp)
                    274: register BUF *bp;
                    275: {
                    276:        if (bp->b_req == BWRITE)
                    277:                bp->b_flag &= ~BFMOD;
                    278:        if (bp->b_req == BREAD) {
                    279:                if ((bp->b_flag&BFERR) != 0)
                    280:                        bp->b_dev = NODEV;
                    281:        }
                    282:        if ((bp->b_flag&BFASY) != 0) {
                    283:                bp->b_flag &= ~BFASY;
                    284:                brelease(bp);
                    285:        }
                    286:        bp->b_flag &= ~BFNTP;
                    287:        wakeup((char *)bp);
                    288: }
                    289: 
                    290: /*
                    291:  * Release the given buffer.
                    292:  */
                    293: brelease(bp)
                    294: register BUF *bp;
                    295: {
                    296:        if ((bp->b_flag&BFERR) == 0)
                    297:                bp->b_seqn = bufseqn++;
                    298:        else {
                    299:                bp->b_flag &= ~BFERR;
                    300:                bp->b_dev = NODEV;
                    301:        }
                    302:        bp->b_flag &= ~BFNTP;
                    303:        bumap(bp);
                    304:        unlock(bp->b_gate);
                    305:        if (bufneed != 0) {
                    306:                bufneed = 0;
                    307:                wakeup((char *)&bufneed);
                    308:        }
                    309: }
                    310: 
                    311: /*
                    312:  * Map the given buffer.
                    313:  */
                    314: bsmap(bp)
                    315: register BUF *bp;
                    316: {
                    317:        bsave(bp->b_map);
                    318:        bp->b_flag |= BFMAP;
                    319:        bmapv(bconv(bp->b_paddr));
                    320: }
                    321: 
                    322: /*
                    323:  * Unmap the given buffer.
                    324:  */
                    325: bumap(bp)
                    326: register BUF *bp;
                    327: {
                    328:        if ((bp->b_flag&BFMAP) == 0)
                    329:                return;
                    330:        bp->b_flag &= ~BFMAP;
                    331:        brest(bp->b_map);
                    332: }
                    333: 
                    334: /*
                    335:  * Read data from the I/O segment into kernel space.
                    336:  */
                    337: ioread(iop, v, n)
                    338: register IO *iop;
                    339: register char *v;
                    340: register unsigned n;
                    341: {
                    342:        switch (iop->io_seg) {
                    343:        case IOSYS:
                    344:                iop->io_base += kkcopy(iop->io_base, v, n);
                    345:                break;
                    346:        case IOUSR:
                    347:                iop->io_base += ukcopy(iop->io_base, v, n);
                    348:                break;
                    349:        case IOPHY:
                    350:                iop->io_phys += pkcopy(iop->io_phys, v, n);
                    351:                break;
                    352:        }
                    353:        iop->io_ioc -= n;
                    354: }
                    355: 
                    356: /*
                    357:  * Write data from kernel space to the I/O segment.
                    358:  */
                    359: iowrite(iop, v, n)
                    360: register IO *iop;
                    361: register char *v;
                    362: register unsigned n;
                    363: {
                    364:        switch (iop->io_seg) {
                    365:        case IOSYS:
                    366:                iop->io_base += kkcopy(v, iop->io_base, n);
                    367:                break;
                    368:        case IOUSR:
                    369:                iop->io_base += kucopy(v, iop->io_base, n);
                    370:                break;
                    371:        case IOPHY:
                    372:                iop->io_phys += kpcopy(v, iop->io_phys, n);
                    373:                break;
                    374:        }
                    375:        iop->io_ioc -= n;
                    376: }
                    377: 
                    378: /*
                    379:  * Get a character from the I/O segment.
                    380:  */
                    381: iogetc(iop)
                    382: register IO *iop;
                    383: {
                    384:        register int c;
                    385: 
                    386:        if (iop->io_ioc == 0)
                    387:                return (-1);
                    388:        --iop->io_ioc;
                    389:        if (iop->io_seg == IOSYS)
                    390:                c = *iop->io_base++ & 0377;
                    391:        else {
                    392:                c = getubd(iop->io_base++);
                    393:                if (u.u_error)
                    394:                        return (-1);
                    395:        }
                    396:        return (c);
                    397: }
                    398: 
                    399: /*
                    400:  * Put a character using the I/O segment.
                    401:  */
                    402: ioputc(c, iop)
                    403: register IO *iop;
                    404: {
                    405:        if (iop->io_ioc == 0)
                    406:                return (-1);
                    407:        --iop->io_ioc;
                    408:        if (iop->io_seg == IOSYS)
                    409:                *iop->io_base++ = c;
                    410:        else {
                    411:                putubd(iop->io_base++, c);
                    412:                if (u.u_error)
                    413:                        return (-1);
                    414:        }
                    415:        return (c);
                    416: }
                    417: 
                    418: /*
                    419:  * Given a buffer pointer, an I/O structure, a device, request type, and
                    420:  * a flags word, check the I/O structure and perform the I/O request.
                    421:  */
                    422: ioreq(bp, iop, dev, req, f)
                    423: register BUF *bp;
                    424: register IO *iop;
                    425: dev_t dev;
                    426: {
                    427:        register SEG *sp;
                    428:        register int n;
                    429:        register int s;
                    430:        register CON *cp;
                    431:        dold_t dold;
                    432: 
                    433:        if ((cp=drvmap(dev, &dold)) == NULL)
                    434:                return;
                    435:        lock(bp->b_gate);
                    436:        n = cp->c_flag; /* n should do something with that flag */
                    437:        drest(dold);
                    438:        sp = NULL;
                    439:        if (iop != NULL) {
                    440:                if ((f&BFBLK) != 0) {
                    441:                        if (blocko(iop->io_seek) != 0) {
                    442:                                u.u_error = EIO;
                    443:                                goto out;
                    444:                        }
                    445:                }
                    446:                if ((f&BFIOC) != 0) {
                    447:                        if ((sp=iomapvp(iop, bp)) == NULL) {
                    448:                                u.u_error = EIO;
                    449:                                goto out;
                    450:                        }
                    451:                }
                    452:        }
                    453:        bp->b_flag = f|BFNTP;
                    454:        bp->b_req = req;
                    455:        bp->b_dev = dev;
                    456:        if (iop != NULL) {
                    457:                bp->b_bno = blockn(iop->io_seek);
                    458:                bp->b_count = iop->io_ioc;
                    459:        }
                    460:        if (sp != NULL) {
                    461:                bp->b_faddr = ptov( bp->b_paddr, (fsize_t) bp->b_count );
                    462:                sp->s_lrefc++;
                    463:        }
                    464:        s = sphi();
                    465:        dblock(dev, bp);
                    466:        while ((bp->b_flag&BFNTP) != 0)
                    467:                sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO);
                    468:        spl(s);
                    469:        if (sp != NULL) {
                    470:                vrelse( bp->b_faddr );
                    471:                sp->s_lrefc--;
                    472:        }
                    473:        if (stimer.t_last != 0)
                    474:                wakeup((char *)&stimer);
                    475:        if ((bp->b_flag&BFERR) != 0) {
                    476:                u.u_error = bp->b_err ? bp->b_err : EIO;
                    477:                goto out;
                    478:        }
                    479:        if (iop != NULL) {
                    480:                n = iop->io_ioc - bp->b_resid;
                    481:                iop->io_seek += n;
                    482:                iop->io_ioc -= n;
                    483:        }
                    484: out:
                    485:        unlock(bp->b_gate);
                    486: }
                    487: 
                    488: /*
                    489:  * Given an I/O structure and a buffer header, see if the addresses
                    490:  * in the I/O structure are valid and set up the buffer header.
                    491:  */
                    492: SEG *
                    493: iomapvp(iop, bp)
                    494: register IO *iop;
                    495: register BUF *bp;
                    496: {
                    497:        register SR *srp;
                    498:        register SEG *sp;
                    499:        register vaddr_t b;
                    500: 
                    501:        if (iop->io_seg != IOUSR)
                    502:                panic("Raw I/O from non user");
                    503:        for (srp=u.u_segl; srp<&u.u_segl[NUSEG]; srp++) {
                    504:                if ((sp=srp->sr_segp) == NULL)
                    505:                        continue;
                    506:                if ((srp->sr_flag&SRFDATA) == 0)
                    507:                        continue;
                    508: /* Yet another bug in the 8000 C compiler
                    509:                if ((long)(b=iop->io_base) < (long)srp->sr_base)
                    510: */
                    511:                if ((b=iop->io_base) < srp->sr_base)
                    512:                        continue;
                    513:                if ((long)b+iop->io_ioc > (long)srp->sr_base + sp->s_size)
                    514:                        continue;
                    515:                bp->b_paddr = sp->s_paddr + (vaddr_t) (b - srp->sr_base);
                    516:                return (sp);
                    517:        }
                    518:        return (NULL);
                    519: }
                    520: 
                    521: /*
                    522:  * Initialise devices.
                    523:  */
                    524: devinit()
                    525: {
                    526:        register DRV *dp;
                    527:        register int mind;
                    528: 
                    529:        for ( dp = drvl, mind = 0; mind < drvn; mind++, dp++ ) {
                    530:                if ((dp->d_conp != NULL) && (dp->d_conp->c_load != NULL)) {
                    531:                        (*dp->d_conp->c_load)();
                    532:                }
                    533:        }
                    534: }
                    535: 
                    536: /*
                    537:  * Open a device.
                    538:  */
                    539: dopen(dev, m, f)
                    540: register dev_t dev;
                    541: {
                    542:        register CON *cp;
                    543:        dold_t dold;
                    544: 
                    545:        if ((cp=drvmap(dev, &dold)) == NULL)
                    546:                return;
                    547:        if ((cp->c_flag&f) == 0) {
                    548:                u.u_error = ENXIO;
                    549:                return;
                    550:        }
                    551:        (*cp->c_open)(dev, m);
                    552:        drest(dold);
                    553: }
                    554: 
                    555: /*
                    556:  * Close a device.
                    557:  */
                    558: dclose(dev)
                    559: register dev_t dev;
                    560: {
                    561:        register CON *cp;
                    562:        dold_t dold;
                    563: 
                    564:        if ((cp=drvmap(dev, &dold)) == NULL)
                    565:                return;
                    566:        (*cp->c_close)(dev);
                    567:        drest(dold);
                    568: }
                    569: 
                    570: /*
                    571:  * Call the block entry point of a device.
                    572:  */
                    573: dblock(dev, bp)
                    574: dev_t dev;
                    575: BUF *bp;
                    576: {
                    577:        register CON *cp;
                    578:        dold_t dold;
                    579: 
                    580:        if ((cp=drvmap(dev, &dold)) == NULL)
                    581:                return;
                    582:        (*cp->c_block)(bp);
                    583:        drest(dold);
                    584: }
                    585: 
                    586: /*
                    587:  * Read from a device.
                    588:  */
                    589: dread(dev, iop)
                    590: register dev_t dev;
                    591: register IO *iop;
                    592: {
                    593:        register CON *cp;
                    594:        dold_t dold;
                    595: 
                    596:        if ((cp=drvmap(dev, &dold)) == NULL)
                    597:                return;
                    598:        (*cp->c_read)(dev, iop);
                    599:        drest(dold);
                    600: }
                    601: 
                    602: /*
                    603:  * Write to a device.
                    604:  */
                    605: dwrite(dev, iop)
                    606: register dev_t dev;
                    607: register IO *iop;
                    608: {
                    609:        register CON *cp;
                    610:        dold_t dold;
                    611: 
                    612:        if ((cp=drvmap(dev, &dold)) == NULL)
                    613:                return;
                    614:        (*cp->c_write)(dev, iop);
                    615:        drest(dold);
                    616: }
                    617: 
                    618: /*
                    619:  * Call the ioctl function for a device.
                    620:  */
                    621: dioctl(dev, com, vec)
                    622: register dev_t dev;
                    623: union ioctl *vec;
                    624: {
                    625:        register CON *cp;
                    626:        dold_t dold;
                    627: 
                    628:        if ((cp=drvmap(dev, &dold)) == NULL)
                    629:                return;
                    630:        (*cp->c_ioctl)(dev, com, vec);
                    631:        drest(dold);
                    632: }
                    633: 
                    634: /*
                    635:  * Call the powerfail entry point of a device.
                    636:  */
                    637: dpower(dev)
                    638: register dev_t dev;
                    639: {
                    640:        register CON *cp;
                    641:        dold_t dold;
                    642: 
                    643:        if ((cp=drvmap(dev, &dold)) == NULL)
                    644:                return;
                    645:        (*cp->c_power)(dev);
                    646:        drest(dold);
                    647: }
                    648: 
                    649: /*
                    650:  * Call the timeout entry point of a device.
                    651:  */
                    652: dtime(dev)
                    653: register dev_t dev;
                    654: {
                    655:        register CON *cp;
                    656:        dold_t dold;
                    657: 
                    658:        if ((cp=drvmap(dev, &dold)) == NULL)
                    659:                return;
                    660:        (*cp->c_timer)(dev);
                    661:        drest(dold);
                    662: }
                    663: 
                    664: /*
                    665:  * Poll a device.
                    666:  */
                    667: dpoll(dev, ev, msec)
                    668: register dev_t dev;
                    669: int ev;
                    670: int msec;
                    671: {
                    672:        register CON *cp;
                    673:        dold_t dold;
                    674: 
                    675:        if ((cp=drvmap(dev, &dold)) == NULL)
                    676:                return POLLNVAL;
                    677: 
                    678:        if ( cp->c_flag & DFPOL )
                    679:                ev = (*cp->c_poll)(dev, ev, msec);
                    680:        else
                    681:                ev = POLLNVAL;
                    682: 
                    683:        drest(dold);
                    684:        return ev;
                    685: }
                    686: 
                    687: /*
                    688:  * Given a device, return the flags word.
                    689:  */
                    690: dflag(dev)
                    691: dev_t dev;
                    692: {
                    693:        register CON *cp;
                    694:        register int f;
                    695:        dold_t dold;
                    696: 
                    697:        if ((cp=drvmap(dev, &dold)) == NULL)
                    698:                return (DFERR);
                    699:        f = cp->c_flag;
                    700:        drest(dold);
                    701:        return (f);
                    702: }
                    703: 
                    704: /*
                    705:  * Given a device, and a pointer to a driver map save area, save the
                    706:  * current map in the driver map save area and map in the new device,
                    707:  * returning a pointer to the configuration entry for that device.
                    708:  */
                    709: CON *
                    710: drvmap(dev, doldp)
                    711: dev_t dev;
                    712: dold_t *doldp;
                    713: {
                    714:        register DRV *dp;
                    715:        register unsigned m;
                    716: 
                    717:        if ((m=major(dev)) >= drvn) {
                    718:                u.u_error = ENXIO;
                    719:                return (NULL);
                    720:        }
                    721:        dp = &drvl[m];
                    722:        if (locked(dp->d_gate)) {
                    723:                u.u_error = ENXIO;
                    724:                return (NULL);
                    725:        }
                    726:        if (dp->d_conp == NULL) {
                    727:                u.u_error = ENXIO;
                    728:                return (NULL);
                    729:        }
                    730:        dsave(*doldp);
                    731:        if (dp->d_map != 0)
                    732:                dmapv(dp->d_map);
                    733:        return (dp->d_conp);
                    734: }
                    735: 
                    736: /*
                    737:  * Non existant device.
                    738:  */
                    739: nonedev()
                    740: {
                    741:        u.u_error = ENXIO;
                    742: }
                    743: 
                    744: /*
                    745:  * Null device.
                    746:  */
                    747: nulldev()
                    748: {
                    749: }

unix.superglobalmegacorp.com

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