📄 cd.c
字号:
smallci = ci; /* * Nobody left, all done */ if (smallci == NULL) { ii->ii_ndisk = 0; break; } /* * Record starting logical block and component offset */ ii->ii_startblk = bn / cs->sc_ileave; ii->ii_startoff = lbn; /* * Determine how many disks take part in this interleave * and record their indices. */ ix = 0; for (ci = cs->sc_cinfo; ci < &cs->sc_cinfo[cs->sc_ncdisks]; ci++) if (ci->ci_size >= smallci->ci_size) ii->ii_index[ix++] = ci - cs->sc_cinfo; ii->ii_ndisk = ix; bn += ix * (smallci->ci_size - size); lbn = smallci->ci_size / cs->sc_ileave; size = smallci->ci_size; }#ifdef DEBUG if (cddebug & CDB_INIT) printiinfo(cs->sc_itable);#endif return(1);}#ifdef DEBUGprintiinfo(ii) struct cdiinfo *ii;{ register int ix, i; for (ix = 0; ii->ii_ndisk; ix++, ii++) { printf(" itab[%d]: #dk %d sblk %d soff %d", ix, ii->ii_ndisk, ii->ii_startblk, ii->ii_startoff); for (i = 0; i < ii->ii_ndisk; i++) printf(" %d", ii->ii_index[i]); printf("\n"); }}#endifcdopen(dev, flags) dev_t dev;{ int unit = cdunit(dev); register struct cd_softc *cs = &cd_softc[unit];#ifdef DEBUG if (cddebug & CDB_FOLLOW) printf("cdopen(%x, %x)\n", dev, flags);#endif if (unit >= numcd || (cs->sc_flags & CDF_ALIVE) == 0) return(ENXIO); return(0);}cdstrategy(bp) register struct buf *bp;{ register int unit = cdunit(bp->b_dev); register struct cd_softc *cs = &cd_softc[unit]; register daddr_t bn; register int sz, s;#ifdef DEBUG if (cddebug & CDB_FOLLOW) printf("cdstrategy(%x): unit %d\n", bp, unit);#endif if ((cs->sc_flags & CDF_INITED) == 0) { bp->b_error = ENXIO; bp->b_flags |= B_ERROR; goto done; } bn = bp->b_blkno; sz = howmany(bp->b_bcount, DEV_BSIZE); if (bn < 0 || bn + sz > cs->sc_size) { sz = cs->sc_size - bn; if (sz == 0) { bp->b_resid = bp->b_bcount; goto done; } if (sz < 0) { bp->b_error = EINVAL; bp->b_flags |= B_ERROR; goto done; } bp->b_bcount = dbtob(sz); } bp->b_resid = bp->b_bcount; /* * "Start" the unit. */ s = splbio(); cdstart(cs, bp); splx(s); return;done: biodone(bp);}cdstart(cs, bp) register struct cd_softc *cs; register struct buf *bp;{ register long bcount, rcount; struct buf *cbp; caddr_t addr; daddr_t bn;#ifdef DEBUG if (cddebug & CDB_FOLLOW) printf("cdstart(%x, %x)\n", cs, bp);#endif /* * Instumentation (not real meaningful) */ cs->sc_usecnt++; if (cs->sc_dk >= 0) { dk_busy |= 1 << cs->sc_dk; dk_xfer[cs->sc_dk]++; dk_wds[cs->sc_dk] += bp->b_bcount >> 6; } /* * Allocate component buffers and fire off the requests */ bn = bp->b_blkno; addr = bp->b_data; for (bcount = bp->b_bcount; bcount > 0; bcount -= rcount) { cbp = cdbuffer(cs, bp, bn, addr, bcount); rcount = cbp->b_bcount; (*bdevsw[major(cbp->b_dev)].d_strategy)(cbp); bn += btodb(rcount); addr += rcount; }}/* * Build a component buffer header. */struct buf *cdbuffer(cs, bp, bn, addr, bcount) register struct cd_softc *cs; struct buf *bp; daddr_t bn; caddr_t addr; long bcount;{ register struct cdcinfo *ci; register struct buf *cbp; register daddr_t cbn, cboff;#ifdef DEBUG if (cddebug & CDB_IO) printf("cdbuffer(%x, %x, %d, %x, %d)\n", cs, bp, bn, addr, bcount);#endif /* * Determine which component bn falls in. */ cbn = bn; cboff = 0; /* * Serially concatenated */ if (cs->sc_ileave == 0) { register daddr_t sblk; sblk = 0; for (ci = cs->sc_cinfo; cbn >= sblk + ci->ci_size; ci++) sblk += ci->ci_size; cbn -= sblk; } /* * Interleaved */ else { register struct cdiinfo *ii; int cdisk, off; cboff = cbn % cs->sc_ileave; cbn /= cs->sc_ileave; for (ii = cs->sc_itable; ii->ii_ndisk; ii++) if (ii->ii_startblk > cbn) break; ii--; off = cbn - ii->ii_startblk; if (ii->ii_ndisk == 1) { cdisk = ii->ii_index[0]; cbn = ii->ii_startoff + off; } else { cdisk = ii->ii_index[off % ii->ii_ndisk]; cbn = ii->ii_startoff + off / ii->ii_ndisk; } cbn *= cs->sc_ileave; ci = &cs->sc_cinfo[cdisk]; } /* * Fill in the component buf structure. */ cbp = getcbuf(); cbp->b_flags = bp->b_flags | B_CALL; cbp->b_iodone = cdiodone; cbp->b_proc = bp->b_proc; cbp->b_dev = ci->ci_dev; cbp->b_blkno = cbn + cboff; cbp->b_data = addr; cbp->b_vp = 0; if (cs->sc_ileave == 0) cbp->b_bcount = dbtob(ci->ci_size - cbn); else cbp->b_bcount = dbtob(cs->sc_ileave - cboff); if (cbp->b_bcount > bcount) cbp->b_bcount = bcount; /* * XXX context for cdiodone */ cbp->b_saveaddr = (caddr_t)bp; cbp->b_pfcent = ((cs - cd_softc) << 16) | (ci - cs->sc_cinfo);#ifdef DEBUG if (cddebug & CDB_IO) printf(" dev %x(u%d): cbp %x bn %d addr %x bcnt %d\n", ci->ci_dev, ci-cs->sc_cinfo, cbp, cbp->b_blkno, cbp->b_data, cbp->b_bcount);#endif return(cbp);}cdintr(cs, bp) register struct cd_softc *cs; register struct buf *bp;{#ifdef DEBUG if (cddebug & CDB_FOLLOW) printf("cdintr(%x, %x)\n", cs, bp);#endif /* * Request is done for better or worse, wakeup the top half. */ if (--cs->sc_usecnt == 0 && cs->sc_dk >= 0) dk_busy &= ~(1 << cs->sc_dk); if (bp->b_flags & B_ERROR) bp->b_resid = bp->b_bcount; biodone(bp);}/* * Called by biodone at interrupt time. * Mark the component as done and if all components are done, * take a cd interrupt. */voidcdiodone(cbp) register struct buf *cbp;{ register struct buf *bp = (struct buf *)cbp->b_saveaddr;/* XXX */ register int unit = (cbp->b_pfcent >> 16) & 0xFFFF; /* XXX */ int count, s; s = splbio();#ifdef DEBUG if (cddebug & CDB_FOLLOW) printf("cdiodone(%x)\n", cbp); if (cddebug & CDB_IO) { printf("cdiodone: bp %x bcount %d resid %d\n", bp, bp->b_bcount, bp->b_resid); printf(" dev %x(u%d), cbp %x bn %d addr %x bcnt %d\n", cbp->b_dev, cbp->b_pfcent & 0xFFFF, cbp, cbp->b_blkno, cbp->b_data, cbp->b_bcount); }#endif if (cbp->b_flags & B_ERROR) { bp->b_flags |= B_ERROR; bp->b_error = biowait(cbp);#ifdef DEBUG printf("cd%d: error %d on component %d\n", unit, bp->b_error, cbp->b_pfcent & 0xFFFF);#endif } count = cbp->b_bcount; putcbuf(cbp); /* * If all done, "interrupt". */ bp->b_resid -= count; if (bp->b_resid < 0) panic("cdiodone: count"); if (bp->b_resid == 0) cdintr(&cd_softc[unit], bp); splx(s);}cdread(dev, uio) dev_t dev; struct uio *uio;{ register int unit = cdunit(dev);#ifdef DEBUG if (cddebug & CDB_FOLLOW) printf("cdread(%x, %x)\n", dev, uio);#endif return(physio(cdstrategy, NULL, dev, B_READ, minphys, uio));}cdwrite(dev, uio) dev_t dev; struct uio *uio;{ register int unit = cdunit(dev);#ifdef DEBUG if (cddebug & CDB_FOLLOW) printf("cdwrite(%x, %x)\n", dev, uio);#endif return(physio(cdstrategy, NULL, dev, B_WRITE, minphys, uio));}cdioctl(dev, cmd, data, flag) dev_t dev; int cmd; caddr_t data; int flag;{ return(EINVAL);}cdsize(dev) dev_t dev;{ int unit = cdunit(dev); register struct cd_softc *cs = &cd_softc[unit]; if (unit >= numcd || (cs->sc_flags & CDF_INITED) == 0) return(-1); return(cs->sc_size);}cddump(dev){ return(ENXIO);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -