int unit = cbp->cb_unit; struct ccd_softc *cs = &ccd_softc[unit];
struct ccd_softc *cs = cbp->cb_sc;
ccdiodone(vbp)	struct buf *vbp;{	struct ccdbuf *cbp = (struct ccdbuf *)vbp;	struct buf *bp = cbp->cb_obp;	int unit = cbp->cb_unit;	struct ccd_softc *cs = &ccd_softc[unit];	int old_io = cbp->cb_flags & CBF_OLD;	int cbflags, i;	long count = bp->b_bcount, off;	char *comptype;	splassert(IPL_BIO);#ifdef DEBUG	if (ccddebug & CCDB_FOLLOW)		printf("ccdiodone(%p)\n", cbp);	if (ccddebug & CCDB_IO) {		if (cbp->cb_flags & CBF_MIRROR)			printf("ccdiodone: mirror component\n");		else			printf("ccdiodone: bp %p bcount %ld resid %ld\n",			    bp, bp->b_bcount, bp->b_resid);		printf(" dev %x(u%d), cbp %p bn %d addr %p bcnt %ld\n",		    vbp->b_dev, cbp->cb_comp, cbp, vbp->b_blkno,		    vbp->b_data, vbp->b_bcount);	}#endif	if (vbp->b_flags & B_ERROR) {		if (cbp->cb_flags & CBF_MIRROR)			comptype = " (mirror)";		else {			bp->b_flags |= B_ERROR;			bp->b_error = vbp->b_error ?			    vbp->b_error : EIO;			comptype = "";		}		printf("%s: error %d on component %d%s\n",		    cs->sc_xname, bp->b_error, cbp->cb_comp, comptype);	}	cbflags = cbp->cb_flags;	if (!old_io) {		/*		 * Gather all the pieces and put them where they should be.		 */		for (i = 0, off = 0; i < cbp->cb_sgcnt; i++) {#ifdef DEBUG			if (ccddebug & CCDB_IO)				printf("ccdiodone: sg %d (%p/%x) off %x\n", i,				    cbp->cb_sg[i].cs_sgaddr,				    cbp->cb_sg[i].cs_sglen, off);#endif			pagemove(vbp->b_data + off, cbp->cb_sg[i].cs_sgaddr,			    round_page(cbp->cb_sg[i].cs_sglen));			off += cbp->cb_sg[i].cs_sglen;		}		uvm_km_free(ccdmap, (vaddr_t)vbp->b_data, count);		if (ccd_need_kvm) {			ccd_need_kvm = 0;			wakeup(ccdmap);		}	}	count = vbp->b_bcount;	putccdbuf(cbp);	if ((cbflags & CBF_MIRROR) == 0) {		/*		 * If all done, "interrupt".		 *		 * Note that mirror component buffers aren't counted against		 * the original I/O buffer.		 */		if (count > bp->b_resid)			panic("ccdiodone: count");		bp->b_resid -= count;		if (bp->b_resid == 0)			ccdintr(&ccd_softc[unit], bp);	}}