xdc->xdc_csr |= XDC_CLRRIO;
xdc->xdc_csr = XDC_CLRRIO;
xdc_remove_iorq(xdcsc)	struct xdc_softc *xdcsc;{	int     errno, rqno, comm, errs;	struct xdc *xdc = xdcsc->xdc;	u_long  addr;	struct xd_iopb *iopb;	struct xd_iorq *iorq;	struct buf *bp;	if (xdc->xdc_csr & XDC_F_ERROR) {		/*		 * FATAL ERROR: should never happen under normal use. This		 * error is so bad, you can't even tell which IOPB is bad, so		 * we dump them all.		 */		errno = xdc->xdc_f_err;		printf("%s: fatal error 0x%02x: %s\n", xdcsc->sc_dev.dv_xname,		    errno, xdc_e2str(errno));		if (xdc_reset(xdcsc, 0, XD_RSET_ALL, errno, 0) != XD_ERR_AOK) {			printf("%s: soft reset failed!\n",				xdcsc->sc_dev.dv_xname);			panic("xdc_remove_iorq: controller DEAD");		}		return (XD_ERR_AOK);	}	/*	 * get iopb that is done	 * 	 * hmm... I used to read the address of the done IOPB off the VME	 * registers and calculate the rqno directly from that.   that worked	 * until I started putting a load on the controller.   when loaded, i	 * would get interrupts but neither the REMIOPB or F_ERROR bits would	 * be set, even after DELAY'ing a while!   later on the timeout	 * routine would detect IOPBs that were marked "running" but their	 * "done" bit was set.   rather than dealing directly with this	 * problem, it is just easier to look at all running IOPB's for the	 * done bit.	 */	if (xdc->xdc_csr & XDC_REMIOPB) {		xdc->xdc_csr |= XDC_CLRRIO;	}	for (rqno = 0; rqno < XDC_MAXIOPB; rqno++) {		iorq = &xdcsc->reqs[rqno];		if (iorq->mode == 0 || XD_STATE(iorq->mode) == XD_SUB_DONE)			continue;	/* free, or done */		iopb = &xdcsc->iopbase[rqno];		if (iopb->done == 0)			continue;	/* not done yet */#ifdef XDC_DEBUG		{			u_char *rio = (u_char *) iopb;			int     sz = sizeof(struct xd_iopb), lcv;			printf("%s: rio #%d [", xdcsc->sc_dev.dv_xname, rqno);			for (lcv = 0; lcv < sz; lcv++)				printf(" %02x", rio[lcv]);			printf("]\n");		}#endif				/* XDC_DEBUG */		xdcsc->nrun--;		comm = iopb->comm;		errs = iopb->errs;		if (errs)			iorq->errno = iopb->errno;		else			iorq->errno = 0;		/* handle non-fatal errors */		if (errs &&		    xdc_error(xdcsc, iorq, iopb, rqno, comm) == XD_ERR_AOK)			continue;	/* AOK: we resubmitted it */		/* this iorq is now done (hasn't been restarted or anything) */		if ((iorq->mode & XD_MODE_VERBO) && iorq->lasterror)			xdc_perror(iorq, iopb, 0);		/* now, if read/write check to make sure we got all the data		 * we needed. (this may not be the case if we got an error in		 * the middle of a multisector request).   */		if ((iorq->mode & XD_MODE_B144) != 0 && errs == 0 &&		    (comm == XDCMD_RD || comm == XDCMD_WR)) {			/* we just successfully processed a bad144 sector			 * note: if we are in bad 144 mode, the pointers have			 * been advanced already (see above) and are pointing			 * at the bad144 sector.   to exit bad144 mode, we			 * must advance the pointers 1 sector and issue a new			 * request if there are still sectors left to process			 * 			 */			XDC_ADVANCE(iorq, 1);	/* advance 1 sector */			/* exit b144 mode */			iorq->mode = iorq->mode & (~XD_MODE_B144);			if (iorq->sectcnt) {	/* more to go! */				iorq->lasterror = iorq->errno = iopb->errno = 0;				iopb->errs = iopb->done = 0;				iorq->tries = 0;				iopb->sectcnt = iorq->sectcnt;				iopb->cylno = iorq->blockno /						iorq->xd->sectpercyl;				iopb->headno =					(iorq->blockno / iorq->xd->nhead) %						iorq->xd->nhead;				iopb->sectno = iorq->blockno % XDFM_BPS;				iopb->daddr = 					dvma_kvtopa((long)iorq->dbuf, BUS_VME32);				XDC_HWAIT(xdcsc, rqno);				xdc_start(xdcsc, 1);	/* resubmit */				continue;			}		}		/* final cleanup, totally done with this request */		switch (XD_STATE(iorq->mode)) {		case XD_SUB_NORM:			bp = iorq->buf;			if (errs) {				bp->b_error = EIO;				bp->b_flags |= B_ERROR;				bp->b_resid = iorq->sectcnt * XDFM_BPS;			} else {				bp->b_resid = 0;	/* done */			}			/* Sun3: map/unmap regardless of B_PHYS */			dvma_mapout(iorq->dbufbase,					    iorq->buf->b_bcount);			disk_unbusy(&iorq->xd->sc_dk,			    (bp->b_bcount - bp->b_resid));			XDC_FREE(xdcsc, rqno);			biodone(bp);			break;		case XD_SUB_WAIT:			iorq->mode = XD_NEWSTATE(iorq->mode, XD_SUB_DONE);			xdcsc->ndone++;			wakeup(iorq);			break;		case XD_SUB_POLL:			iorq->mode = XD_NEWSTATE(iorq->mode, XD_SUB_DONE);			xdcsc->ndone++;			break;		}	}	return (XD_ERR_AOK);}