Annotation of Net2/arch/hp300/dev/cd.c, revision 1.1.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.