isadma_copyfrombuf((caddr_t)ccb, CCB_PHYS_SIZE, 1, ccb->ccb_phys);
aha_finish_ccbs(sc)	struct aha_softc *sc;{	struct aha_mbx_in *wmbi;	struct aha_ccb *ccb;	int i;	wmbi = wmbx->tmbi;	if (wmbi->stat == AHA_MBI_FREE) {		for (i = 0; i < AHA_MBX_SIZE; i++) {			if (wmbi->stat != AHA_MBI_FREE) {				printf("%s: mbi not in round-robin order\n",				    sc->sc_dev.dv_xname);				goto AGAIN;			}			aha_nextmbx(wmbi, wmbx, mbi);		}#ifdef AHADIAGnot		printf("%s: mbi interrupt with no full mailboxes\n",		    sc->sc_dev.dv_xname);#endif		return;	}AGAIN:	do {		ccb = aha_ccb_phys_kv(sc, phystol(wmbi->ccb_addr));		if (!ccb) {			printf("%s: bad mbi ccb pointer; skipping\n",			    sc->sc_dev.dv_xname);			goto next;		}#ifdef AHADEBUG		if (aha_debug) {			u_char *cp = &ccb->scsi_cmd;			printf("op=%x %x %x %x %x %x\n",			    cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);			printf("stat %x for mbi addr = 0x%08x, ",			    wmbi->stat, wmbi);			printf("ccb addr = 0x%x\n", ccb);		}#endif /* AHADEBUG */		switch (wmbi->stat) {		case AHA_MBI_OK:		case AHA_MBI_ERROR:			if ((ccb->flags & CCB_ABORT) != 0) {				/*				 * If we already started an abort, wait for it				 * to complete before clearing the CCB.  We				 * could instead just clear CCB_SENDING, but				 * what if the mailbox was already received?				 * The worst that happens here is that we clear				 * the CCB a bit later than we need to.  BFD.				 */				goto next;			}			break;		case AHA_MBI_ABORT:		case AHA_MBI_UNKNOWN:			/*			 * Even if the CCB wasn't found, we clear it anyway.			 * See preceeding comment.			 */			break;		default:			printf("%s: bad mbi status %02x; skipping\n",			    sc->sc_dev.dv_xname, wmbi->stat);			goto next;		}		untimeout(aha_timeout, ccb);		aha_done(sc, ccb);	next:		wmbi->stat = AHA_MBI_FREE;		aha_nextmbx(wmbi, wmbx, mbi);	} while (wmbi->stat != AHA_MBI_FREE);	wmbx->tmbi = wmbi;}