⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cd.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
				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 + -