Annotation of 43BSDReno/sys/hpdev/cd.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1988 University of Utah.
        !             3:  * Copyright (c) 1990 The Regents of the University of California.
        !             4:  * All rights reserved.
        !             5:  *
        !             6:  * This code is derived from software contributed to Berkeley by
        !             7:  * the Systems Programming Group of the University of Utah Computer
        !             8:  * Science Department.
        !             9:  *
        !            10:  * Redistribution is only permitted until one year after the first shipment
        !            11:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
        !            12:  * binary forms are permitted provided that: (1) source distributions retain
        !            13:  * this entire copyright notice and comment, and (2) distributions including
        !            14:  * binaries display the following acknowledgement:  This product includes
        !            15:  * software developed by the University of California, Berkeley and its
        !            16:  * contributors'' in the documentation or other materials provided with the
        !            17:  * distribution and in all advertising materials mentioning features or use
        !            18:  * of this software.  Neither the name of the University nor the names of
        !            19:  * its contributors may be used to endorse or promote products derived from
        !            20:  * this software without specific prior written permission.
        !            21:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            22:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            23:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            24:  *
        !            25:  * from: Utah $Hdr: cd.c 1.4 89/09/17$
        !            26:  *
        !            27:  *     @(#)cd.c        7.1 (Berkeley) 5/8/90
        !            28:  */
        !            29: 
        !            30: /*
        !            31:  * "Concatenated" disk driver.
        !            32:  */
        !            33: #include "cd.h"
        !            34: #if NCD > 0
        !            35: 
        !            36: #include "param.h"
        !            37: #include "systm.h"
        !            38: #include "errno.h"
        !            39: #include "dkstat.h"
        !            40: #include "buf.h"
        !            41: #include "malloc.h"
        !            42: #include "conf.h"
        !            43: 
        !            44: #include "cdvar.h"
        !            45: 
        !            46: #ifdef DEBUG
        !            47: int cddebug = 0x00;
        !            48: #define CDB_FOLLOW     0x01
        !            49: #define CDB_INIT       0x02
        !            50: #define CDB_IO         0x04
        !            51: #endif
        !            52: 
        !            53: struct buf cdbuf[NCD];
        !            54: struct buf *cdbuffer();
        !            55: int    cdiodone();
        !            56: 
        !            57: #define        cdunit(x)       ((minor(x) >> 3) & 0x7) /* for consistency */
        !            58: 
        !            59: #define        getcbuf()       \
        !            60:        ((struct buf *)malloc(sizeof(struct buf), M_DEVBUF, M_WAITOK))
        !            61: #define putcbuf(bp)    \
        !            62:        free((caddr_t)(bp), M_DEVBUF)
        !            63: 
        !            64: struct cd_softc {
        !            65:        int              sc_flags;              /* flags */
        !            66:        size_t           sc_size;               /* size of cd */
        !            67:        int              sc_ileave;             /* interleave */
        !            68:        int              sc_ncdisks;            /* number of components */
        !            69:        struct cdcinfo   sc_cinfo[NCDISKS];     /* component info */
        !            70:        struct cdiinfo   *sc_itable;            /* interleave table */
        !            71:        int              sc_usecnt;             /* number of requests active */
        !            72:        struct buf       *sc_bp;                /* "current" request */
        !            73:        int              sc_dk;                 /* disk index */
        !            74: } cd_softc[NCD];
        !            75: 
        !            76: /* sc_flags */
        !            77: #define        CDF_ALIVE       0x01
        !            78: #define CDF_INITED     0x02
        !            79: 
        !            80: cdinit(cd)
        !            81:        struct cddevice *cd;
        !            82: {
        !            83:        register struct cd_softc *cs = &cd_softc[cd->cd_unit];
        !            84:        register struct cdcinfo *ci;
        !            85:        register size_t size;
        !            86:        register int ix;
        !            87:        size_t minsize;
        !            88:        dev_t dev;
        !            89: 
        !            90: #ifdef DEBUG
        !            91:        if (cddebug & (CDB_FOLLOW|CDB_INIT))
        !            92:                printf("cdinit: unit %d\n", cd->cd_unit);
        !            93: #endif
        !            94:        cs->sc_dk = cd->cd_dk;
        !            95:        cs->sc_size = 0;
        !            96:        cs->sc_ileave = cd->cd_interleave;
        !            97:        cs->sc_ncdisks = 0;
        !            98:        /*
        !            99:         * Verify that each component piece exists and record
        !           100:         * relevant information about it.
        !           101:         */
        !           102:        minsize = 0;
        !           103:        for (ix = 0; ix < NCDISKS; ix++) {
        !           104:                if ((dev = cd->cd_dev[ix]) == NODEV)
        !           105:                        break;
        !           106:                ci = &cs->sc_cinfo[ix];
        !           107:                ci->ci_dev = dev;
        !           108:                /*
        !           109:                 * Calculate size (truncated to interleave boundary
        !           110:                 * if necessary.
        !           111:                 */
        !           112:                if (bdevsw[major(dev)].d_psize) {
        !           113:                        size = (*bdevsw[major(dev)].d_psize)(dev);
        !           114:                        if (size <= 0)
        !           115:                                size = 0;
        !           116:                } else
        !           117:                        size = 0;
        !           118:                if (cs->sc_ileave > 1)
        !           119:                        size -= size % cs->sc_ileave;
        !           120:                if (size == 0)
        !           121:                        return(0);
        !           122:                if (minsize == 0 || size < minsize)
        !           123:                        minsize = size;
        !           124:                ci->ci_size = size;
        !           125:                cs->sc_size += size;
        !           126:                cs->sc_ncdisks++;
        !           127:        }
        !           128:        /*
        !           129:         * If uniform interleave is desired set all sizes to that of
        !           130:         * the smallest component.
        !           131:         */
        !           132:        if (cd->cd_flags & CDF_UNIFORM) {
        !           133:                for (ci = cs->sc_cinfo;
        !           134:                     ci < &cs->sc_cinfo[cs->sc_ncdisks]; ci++)
        !           135:                        ci->ci_size = minsize;
        !           136:                cs->sc_size = cs->sc_ncdisks * minsize;
        !           137:        }
        !           138:        /*
        !           139:         * Construct the interleave table
        !           140:         */
        !           141:        if (!cdinterleave(cs))
        !           142:                return(0);
        !           143:        if (cd->cd_dk >= 0)
        !           144:                dk_wpms[cd->cd_dk] = 32 * (60 * DEV_BSIZE / 2); /* XXX */
        !           145:        printf("cd%d: %d components (%d blocks) concatenated",
        !           146:               cd->cd_unit, cs->sc_ncdisks, cs->sc_size);
        !           147:        if (cs->sc_ileave)
        !           148:                printf(", %d block interleave\n", cs->sc_ileave);
        !           149:        else
        !           150:                printf(" serially\n");
        !           151:        cs->sc_flags = CDF_ALIVE | CDF_INITED;
        !           152:        return(1);
        !           153: }
        !           154: 
        !           155: cdinterleave(cs)
        !           156:        register struct cd_softc *cs;
        !           157: {
        !           158:        register struct cdcinfo *ci, *smallci;
        !           159:        register struct cdiinfo *ii;
        !           160:        register daddr_t bn, lbn;
        !           161:        register int ix;
        !           162:        u_long size;
        !           163: 
        !           164: #ifdef DEBUG
        !           165:        if (cddebug & CDB_INIT)
        !           166:                printf("cdinterleave(%x): ileave %d\n", cs, cs->sc_ileave);
        !           167: #endif
        !           168:        /*
        !           169:         * Allocate an interleave table.
        !           170:         * Chances are this is too big, but we don't care.
        !           171:         */
        !           172:        size = (cs->sc_ncdisks + 1) * sizeof(struct cdiinfo);
        !           173:        cs->sc_itable = (struct cdiinfo *)malloc(size, M_DEVBUF, M_WAITOK);
        !           174:        bzero((caddr_t)cs->sc_itable, size);
        !           175:        /*
        !           176:         * Trivial case: no interleave (actually interleave of disk size).
        !           177:         * Each table entry represent a single component in its entirety.
        !           178:         */
        !           179:        if (cs->sc_ileave == 0) {
        !           180:                bn = 0;
        !           181:                ii = cs->sc_itable;
        !           182:                for (ix = 0; ix < cs->sc_ncdisks; ix++) {
        !           183:                        ii->ii_ndisk = 1;
        !           184:                        ii->ii_startblk = bn;
        !           185:                        ii->ii_startoff = 0;
        !           186:                        ii->ii_index[0] = ix;
        !           187:                        bn += cs->sc_cinfo[ix].ci_size;
        !           188:                        ii++;
        !           189:                }
        !           190:                ii->ii_ndisk = 0;
        !           191: #ifdef DEBUG
        !           192:                if (cddebug & CDB_INIT)
        !           193:                        printiinfo(cs->sc_itable);
        !           194: #endif
        !           195:                return(1);
        !           196:        }
        !           197:        /*
        !           198:         * The following isn't fast or pretty; it doesn't have to be.
        !           199:         */
        !           200:        size = 0;
        !           201:        bn = lbn = 0;
        !           202:        for (ii = cs->sc_itable; ; ii++) {
        !           203:                /*
        !           204:                 * Locate the smallest of the remaining components
        !           205:                 */
        !           206:                smallci = NULL;
        !           207:                for (ci = cs->sc_cinfo;
        !           208:                     ci < &cs->sc_cinfo[cs->sc_ncdisks]; ci++)
        !           209:                        if (ci->ci_size > size &&
        !           210:                            (smallci == NULL ||
        !           211:                             ci->ci_size < smallci->ci_size))
        !           212:                                smallci = ci;
        !           213:                /*
        !           214:                 * Nobody left, all done
        !           215:                 */
        !           216:                if (smallci == NULL) {
        !           217:                        ii->ii_ndisk = 0;
        !           218:                        break;
        !           219:                }
        !           220:                /*
        !           221:                 * Record starting logical block and component offset
        !           222:                 */
        !           223:                ii->ii_startblk = bn / cs->sc_ileave;
        !           224:                ii->ii_startoff = lbn;
        !           225:                /*
        !           226:                 * Determine how many disks take part in this interleave
        !           227:                 * and record their indices.
        !           228:                 */
        !           229:                ix = 0;
        !           230:                for (ci = cs->sc_cinfo;
        !           231:                     ci < &cs->sc_cinfo[cs->sc_ncdisks]; ci++)
        !           232:                        if (ci->ci_size >= smallci->ci_size)
        !           233:                                ii->ii_index[ix++] = ci - cs->sc_cinfo;
        !           234:                ii->ii_ndisk = ix;
        !           235:                bn += ix * (smallci->ci_size - size);
        !           236:                lbn = smallci->ci_size / cs->sc_ileave;
        !           237:                size = smallci->ci_size;
        !           238:        }
        !           239: #ifdef DEBUG
        !           240:        if (cddebug & CDB_INIT)
        !           241:                printiinfo(cs->sc_itable);
        !           242: #endif
        !           243:        return(1);
        !           244: }
        !           245: 
        !           246: #ifdef DEBUG
        !           247: printiinfo(ii)
        !           248:        struct cdiinfo *ii;
        !           249: {
        !           250:        register int ix, i;
        !           251: 
        !           252:        for (ix = 0; ii->ii_ndisk; ix++, ii++) {
        !           253:                printf(" itab[%d]: #dk %d sblk %d soff %d",
        !           254:                       ix, ii->ii_ndisk, ii->ii_startblk, ii->ii_startoff);
        !           255:                for (i = 0; i < ii->ii_ndisk; i++)
        !           256:                        printf(" %d", ii->ii_index[i]);
        !           257:                printf("\n");
        !           258:        }
        !           259: }
        !           260: #endif
        !           261: 
        !           262: cdopen(dev, flags)
        !           263:        dev_t dev;
        !           264: {
        !           265:        int unit = cdunit(dev);
        !           266:        register struct cd_softc *cs = &cd_softc[unit];
        !           267: 
        !           268: #ifdef DEBUG
        !           269:        if (cddebug & CDB_FOLLOW)
        !           270:                printf("cdopen(%x, %x)\n", dev, flags);
        !           271: #endif
        !           272:        if (unit >= NCD || (cs->sc_flags & CDF_ALIVE) == 0)
        !           273:                return(ENXIO);
        !           274:        return(0);
        !           275: }
        !           276: 
        !           277: cdstrategy(bp)
        !           278:        register struct buf *bp;
        !           279: {
        !           280:        register int unit = cdunit(bp->b_dev);
        !           281:        register struct cd_softc *cs = &cd_softc[unit];
        !           282:        register int bn, sz;
        !           283:        int s;
        !           284: 
        !           285: #ifdef DEBUG
        !           286:        if (cddebug & CDB_FOLLOW)
        !           287:                printf("cdstrategy(%x): unit %d\n", bp, unit);
        !           288: #endif
        !           289:        if ((cs->sc_flags & CDF_INITED) == 0) {
        !           290:                bp->b_error = ENXIO;
        !           291:                goto bad;
        !           292:        }
        !           293:        bn = bp->b_blkno;
        !           294:        sz = (bp->b_bcount + (DEV_BSIZE - 1)) >> DEV_BSHIFT;
        !           295:        bp->b_resid = bp->b_bcount;
        !           296:        if (bn < 0 || bn + sz > cs->sc_size) {
        !           297:                if (bn == cs->sc_size)
        !           298:                        goto done;
        !           299:                bp->b_error = EINVAL;
        !           300:                goto bad;
        !           301:        }
        !           302:        /*
        !           303:         * "Start" the unit.
        !           304:         * XXX: the use of sc_bp is just to retain the "traditional"
        !           305:         * interface to the start routine.
        !           306:         */
        !           307:        s = splbio();
        !           308:        cs->sc_bp = bp;
        !           309:        cdstart(unit);
        !           310:        splx(s);
        !           311:        return;
        !           312: bad:
        !           313:        bp->b_flags |= B_ERROR;
        !           314: done:
        !           315:        iodone(bp);
        !           316: }
        !           317: 
        !           318: cdstart(unit)
        !           319:        int unit;
        !           320: {
        !           321:        register struct cd_softc *cs = &cd_softc[unit];
        !           322:        register struct buf *bp = cs->sc_bp;
        !           323:        register long bcount, rcount;
        !           324:        struct buf *cbp;
        !           325:        caddr_t addr;
        !           326:        daddr_t bn;
        !           327: 
        !           328: #ifdef DEBUG
        !           329:        if (cddebug & CDB_FOLLOW)
        !           330:                printf("cdstart(%d)\n", unit);
        !           331: #endif
        !           332:        /*
        !           333:         * Instumentation (not real meaningful)
        !           334:         */
        !           335:        cs->sc_usecnt++;
        !           336:        if (cs->sc_dk >= 0) {
        !           337:                dk_busy |= 1 << cs->sc_dk;
        !           338:                dk_xfer[cs->sc_dk]++;
        !           339:                dk_wds[cs->sc_dk] += bp->b_bcount >> 6;
        !           340:        }
        !           341:        /*
        !           342:         * Allocate component buffers and fire off the requests
        !           343:         */
        !           344:        bn = bp->b_blkno;
        !           345:        addr = bp->b_un.b_addr;
        !           346:        for (bcount = bp->b_bcount; bcount > 0; bcount -= rcount) {
        !           347:                cbp = cdbuffer(cs, bp, bn, addr, bcount);
        !           348:                rcount = cbp->b_bcount;
        !           349:                (*bdevsw[major(cbp->b_dev)].d_strategy)(cbp);
        !           350:                bn += btodb(rcount);
        !           351:                addr += rcount;
        !           352:        }
        !           353: }
        !           354: 
        !           355: /*
        !           356:  * Build a component buffer header.
        !           357:  */
        !           358: struct buf *
        !           359: cdbuffer(cs, bp, bn, addr, bcount)
        !           360:        register struct cd_softc *cs;
        !           361:        struct buf *bp;
        !           362:        daddr_t bn;
        !           363:        caddr_t addr;
        !           364:        long bcount;
        !           365: {
        !           366:        register struct cdcinfo *ci;
        !           367:        register struct buf *cbp;
        !           368:        register daddr_t cbn, cboff;
        !           369: 
        !           370: #ifdef DEBUG
        !           371:        if (cddebug & CDB_IO)
        !           372:                printf("cdbuffer(%x, %x, %d, %x, %d)\n",
        !           373:                       cs, bp, bn, addr, bcount);
        !           374: #endif
        !           375:        /*
        !           376:         * Determine which component bn falls in.
        !           377:         */
        !           378:        cbn = bn;
        !           379:        cboff = 0;
        !           380:        /*
        !           381:         * Serially concatenated
        !           382:         */
        !           383:        if (cs->sc_ileave == 0) {
        !           384:                register daddr_t sblk;
        !           385: 
        !           386:                sblk = 0;
        !           387:                for (ci = cs->sc_cinfo; cbn >= sblk + ci->ci_size; ci++)
        !           388:                        sblk += ci->ci_size;
        !           389:                cbn -= sblk;
        !           390:        }
        !           391:        /*
        !           392:         * Interleaved
        !           393:         */
        !           394:        else {
        !           395:                register struct cdiinfo *ii;
        !           396:                int cdisk, off;
        !           397: 
        !           398:                cboff = cbn % cs->sc_ileave;
        !           399:                cbn /= cs->sc_ileave;
        !           400:                for (ii = cs->sc_itable; ii->ii_ndisk; ii++)
        !           401:                        if (ii->ii_startblk > cbn)
        !           402:                                break;
        !           403:                ii--;
        !           404:                off = cbn - ii->ii_startblk;
        !           405:                if (ii->ii_ndisk == 1) {
        !           406:                        cdisk = ii->ii_index[0];
        !           407:                        cbn = ii->ii_startoff + off;
        !           408:                } else {
        !           409:                        cdisk = ii->ii_index[off % ii->ii_ndisk];
        !           410:                        cbn = ii->ii_startoff + off / ii->ii_ndisk;
        !           411:                }
        !           412:                cbn *= cs->sc_ileave;
        !           413:                ci = &cs->sc_cinfo[cdisk];
        !           414:        }
        !           415:        /*
        !           416:         * Fill in the component buf structure.
        !           417:         */
        !           418:        cbp = getcbuf();
        !           419:        cbp->b_flags = bp->b_flags | B_CALL;
        !           420:        cbp->b_iodone = cdiodone;
        !           421:        cbp->b_proc = bp->b_proc;
        !           422:        cbp->b_dev = ci->ci_dev;
        !           423:        cbp->b_blkno = cbn + cboff;
        !           424:        cbp->b_un.b_addr = addr;
        !           425:        if (cs->sc_ileave == 0)
        !           426:                cbp->b_bcount = dbtob(ci->ci_size - cbn);
        !           427:        else
        !           428:                cbp->b_bcount = dbtob(cs->sc_ileave - cboff);
        !           429:        if (cbp->b_bcount > bcount)
        !           430:                cbp->b_bcount = bcount;
        !           431:        /*
        !           432:         * XXX: context for cdiodone
        !           433:         */
        !           434:        cbp->b_vp = (struct vnode *)bp;
        !           435:        cbp->b_pfcent = ((cs - cd_softc) << 16) | (ci - cs->sc_cinfo);
        !           436: #ifdef DEBUG
        !           437:        if (cddebug & CDB_IO)
        !           438:                printf(" dev %x(u%d): cbp %x bn %d addr %x bcnt %d\n",
        !           439:                       ci->ci_dev, ci-cs->sc_cinfo, cbp, cbp->b_blkno,
        !           440:                       cbp->b_un.b_addr, cbp->b_bcount);
        !           441: #endif
        !           442:        return(cbp);
        !           443: }
        !           444: 
        !           445: cdintr(unit)
        !           446:        int unit;
        !           447: {
        !           448:        register struct cd_softc *cs = &cd_softc[unit];
        !           449:        register struct buf *bp = cs->sc_bp;
        !           450: 
        !           451: #ifdef DEBUG
        !           452:        if (cddebug & CDB_FOLLOW)
        !           453:                printf("cdintr(%d)\n", unit);
        !           454: #endif
        !           455:        /*
        !           456:         * Request is done for better or worse, wakeup the top half.
        !           457:         */
        !           458:        if (--cs->sc_usecnt == 0 && cs->sc_dk >= 0)
        !           459:                dk_busy &= ~(1 << cs->sc_dk);
        !           460:        if (bp->b_flags & B_ERROR)
        !           461:                bp->b_resid = bp->b_bcount;
        !           462:        iodone(bp);
        !           463: }
        !           464: 
        !           465: /*
        !           466:  * Called by iodone at interrupt time.
        !           467:  * Mark the component as done and if all components are done,
        !           468:  * take a cd interrupt.
        !           469:  */
        !           470: cdiodone(cbp)
        !           471:        register struct buf *cbp;
        !           472: {
        !           473:        register struct buf *bp = (struct buf *)cbp->b_vp;      /* XXX */
        !           474:        register int unit = (cbp->b_pfcent >> 16) & 0xFFFF;     /* XXX */
        !           475:        int count, s;
        !           476: 
        !           477:        s = splbio();
        !           478: #ifdef DEBUG
        !           479:        if (cddebug & CDB_FOLLOW)
        !           480:                printf("cdiodone(%x)\n", cbp);
        !           481:        if (cddebug & CDB_IO) {
        !           482:                printf("cdiodone: bp %x bcount %d resid %d\n",
        !           483:                       bp, bp->b_bcount, bp->b_resid);
        !           484:                printf(" dev %x(u%d), cbp %x bn %d addr %x bcnt %d\n",
        !           485:                       cbp->b_dev, cbp->b_pfcent & 0xFFFF, cbp,
        !           486:                       cbp->b_blkno, cbp->b_un.b_addr, cbp->b_bcount);
        !           487:        }
        !           488: #endif
        !           489: 
        !           490:        if (cbp->b_flags & B_ERROR) {
        !           491:                bp->b_flags |= B_ERROR;
        !           492:                bp->b_error = geterror(cbp);
        !           493: #ifdef DEBUG
        !           494:                printf("cd%d: error %d on component %d\n",
        !           495:                       unit, bp->b_error, cbp->b_pfcent & 0xFFFF);
        !           496: #endif
        !           497:        }
        !           498:        count = cbp->b_bcount;
        !           499:        putcbuf(cbp);
        !           500: 
        !           501:        /*
        !           502:         * If all done, "interrupt".
        !           503:         * Again, sc_bp is only used to preserve the traditional interface.
        !           504:         */
        !           505:        bp->b_resid -= count;
        !           506:        if (bp->b_resid < 0)
        !           507:                panic("cdiodone: count");
        !           508:        if (bp->b_resid == 0) {
        !           509:                cd_softc[unit].sc_bp = bp;
        !           510:                cdintr(unit);
        !           511:        }
        !           512:        splx(s);
        !           513: }
        !           514: 
        !           515: cdread(dev, uio)
        !           516:        dev_t dev;
        !           517:        struct uio *uio;
        !           518: {
        !           519:        register int unit = cdunit(dev);
        !           520: 
        !           521: #ifdef DEBUG
        !           522:        if (cddebug & CDB_FOLLOW)
        !           523:                printf("cdread(%x, %x)\n", dev, uio);
        !           524: #endif
        !           525:        return(physio(cdstrategy, &cdbuf[unit], dev, B_READ, minphys, uio));
        !           526: }
        !           527: 
        !           528: cdwrite(dev, uio)
        !           529:        dev_t dev;
        !           530:        struct uio *uio;
        !           531: {
        !           532:        register int unit = cdunit(dev);
        !           533: 
        !           534: #ifdef DEBUG
        !           535:        if (cddebug & CDB_FOLLOW)
        !           536:                printf("cdwrite(%x, %x)\n", dev, uio);
        !           537: #endif
        !           538:        return(physio(cdstrategy, &cdbuf[unit], dev, B_WRITE, minphys, uio));
        !           539: }
        !           540: 
        !           541: cdioctl(dev, cmd, data, flag)
        !           542:        dev_t dev;
        !           543:        int cmd;
        !           544:        caddr_t data;
        !           545:        int flag;
        !           546: {
        !           547:        return(EINVAL);
        !           548: }
        !           549: 
        !           550: cdsize(dev)
        !           551:        dev_t dev;
        !           552: {
        !           553:        int unit = cdunit(dev);
        !           554:        register struct cd_softc *cs = &cd_softc[unit];
        !           555: 
        !           556:        if (unit >= NCD || (cs->sc_flags & CDF_INITED) == 0)
        !           557:                return(-1);
        !           558:        return(cs->sc_size);
        !           559: }
        !           560: 
        !           561: cddump(dev)
        !           562: {
        !           563:        return(ENXIO);
        !           564: }
        !           565: #endif

unix.superglobalmegacorp.com

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