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

unix.superglobalmegacorp.com

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