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

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

unix.superglobalmegacorp.com

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