u_long  block, dp;
u_long  block;
xdc_startbuf(xdcsc, xdsc, bp)	struct xdc_softc *xdcsc;	struct xd_softc *xdsc;	struct buf *bp;{	int     rqno, partno;	struct xd_iorq *iorq;	struct xd_iopb *iopb;	struct buf *wq;	u_long  block, dp;	caddr_t dbuf;	if (!xdcsc->nfree)		panic("xdc_startbuf free");	rqno = XDC_RQALLOC(xdcsc);	iorq = &xdcsc->reqs[rqno];	iopb = iorq->iopb;	/* get buf */	if (bp == NULL) {		bp = xdcsc->sc_wq.b_actf;		if (!bp)			panic("xdc_startbuf bp");		wq = bp->b_actf;		if (wq)			wq->b_actb = bp->b_actb;		else			xdcsc->sc_wq.b_actb = bp->b_actb;		*bp->b_actb = wq;		xdsc = xdcsc->sc_drives[DISKUNIT(bp->b_dev)];	}	partno = DISKPART(bp->b_dev);#ifdef XDC_DEBUG	printf("xdc_startbuf: %s%c: %s block %d\n", xdsc->sc_dev.dv_xname,	    'a' + partno, (bp->b_flags & B_READ) ? "read" : "write", bp->b_blkno);	printf("xdc_startbuf: b_bcount %d, b_data 0x%x\n",	    bp->b_bcount, bp->b_data);#endif	/*	 * load request.  we have to calculate the correct block number based	 * on partition info.	 * 	 * also, note that there are two kinds of buf structures, those with	 * B_PHYS set and those without B_PHYS.   if B_PHYS is set, then it is	 * a raw I/O (to a cdevsw) and we are doing I/O directly to the users'	 * buffer which has already been mapped into DVMA space. (Not on sun3)	 * However, if B_PHYS is not set, then the buffer is a normal system	 * buffer which does *not* live in DVMA space.  In that case we call	 * dvma_mapin to map it into DVMA space so we can do the DMA to it.	 * 	 * in cases where we do a dvma_mapin, note that iorq points to the buffer	 * as mapped into DVMA space, where as the bp->b_data points to its	 * non-DVMA mapping.	 *	 * XXX - On the sun3, B_PHYS does NOT mean the buffer is mapped	 * into dvma space, only that it was remapped into the kernel.	 * We ALWAYS have to remap the kernel buf into DVMA space.	 * (It is done inexpensively, using whole segments!)	 */	block = bp->b_blkno + ((partno == RAW_PART) ? 0 :	    xdsc->sc_dk.dk_label->d_partitions[partno].p_offset);	dbuf = dvma_mapin(bp->b_data, bp->b_bcount);	if (dbuf == NULL) {	/* out of DVMA space */		printf("%s: warning: out of DVMA space\n", xdcsc->sc_dev.dv_xname);		XDC_FREE(xdcsc, rqno);		wq = &xdcsc->sc_wq;	/* put at end of queue */		bp->b_actf = 0;		bp->b_actb = wq->b_actb;		*wq->b_actb = bp;		wq->b_actb = &bp->b_actf;		return (XD_ERR_FAIL);	/* XXX: need some sort of		                         * call-back scheme here? */	}	/* init iorq and load iopb from it */	xdc_rqinit(iorq, xdcsc, xdsc, XD_SUB_NORM | XD_MODE_VERBO, block,	    bp->b_bcount / XDFM_BPS, dbuf, bp);	xdc_rqtopb(iorq, iopb, (bp->b_flags & B_READ) ? XDCMD_RD : XDCMD_WR, 0);	/* Instrumentation. */	disk_busy(&xdsc->sc_dk);	/* now submit [note that xdc_submit_iorq can never fail on NORM reqs] */	xdc_submit_iorq(xdcsc, rqno, XD_SUB_NORM);	return (XD_ERR_AOK);}