if (status & TWE_STAT_CMDI) {  lock = TWE_LOCK_TWE(sc); while (!(status & TWE_STAT_CQF) && !TAILQ_EMPTY(&sc->sc_ccb2q)) {  ccb = TAILQ_LAST(&sc->sc_ccb2q, twe_queue_head); TAILQ_REMOVE(&sc->sc_ccb2q, ccb, ccb_link);  ccb->ccb_state = TWE_CCB_QUEUED; TAILQ_INSERT_TAIL(&sc->sc_ccbq, ccb, ccb_link); bus_space_write_4(sc->iot, sc->ioh, TWE_COMMANDQUEUE, ccb->ccb_cmdpa);  rv++;  status = bus_space_read_4(sc->iot, sc->ioh, TWE_STATUS); TWE_DPRINTF(TWE_D_INTR, ("twe_intr stat=%b ", status & TWE_STAT_FLAGS, TWE_STAT_BITS)); }  if (TAILQ_EMPTY(&sc->sc_ccb2q)) bus_space_write_4(sc->iot, sc->ioh, TWE_CONTROL, TWE_CTRL_MCMDI);  TWE_UNLOCK_TWE(sc, lock); }
twe_intr(v)	void *v;{	struct twe_softc *sc = v;	struct twe_ccb	*ccb;	struct twe_cmd	*cmd;	u_int32_t	status;	twe_lock_t	lock;	int		rv = 0;	status = bus_space_read_4(sc->iot, sc->ioh, TWE_STATUS);	TWE_DPRINTF(TWE_D_INTR,  ("twe_intr stat=%b ",	    status & TWE_STAT_FLAGS, TWE_STAT_BITS));#if 0	if (status & TWE_STAT_HOSTI) {		bus_space_write_4(sc->iot, sc->ioh, TWE_CONTROL,		    TWE_CTRL_CHOSTI);	}#endif	if (status & TWE_STAT_CMDI) {		lock = TWE_LOCK_TWE(sc);		while (!(status & TWE_STAT_CQF) &&		    !TAILQ_EMPTY(&sc->sc_ccb2q)) {			ccb = TAILQ_LAST(&sc->sc_ccb2q, twe_queue_head);			TAILQ_REMOVE(&sc->sc_ccb2q, ccb, ccb_link);			ccb->ccb_state = TWE_CCB_QUEUED;			TAILQ_INSERT_TAIL(&sc->sc_ccbq, ccb, ccb_link);			bus_space_write_4(sc->iot, sc->ioh, TWE_COMMANDQUEUE,			    ccb->ccb_cmdpa);			rv++;			status = bus_space_read_4(sc->iot, sc->ioh, TWE_STATUS);			TWE_DPRINTF(TWE_D_INTR, ("twe_intr stat=%b ",			    status & TWE_STAT_FLAGS, TWE_STAT_BITS));		}		if (TAILQ_EMPTY(&sc->sc_ccb2q))			bus_space_write_4(sc->iot, sc->ioh, TWE_CONTROL,			    TWE_CTRL_MCMDI);		TWE_UNLOCK_TWE(sc, lock);	}	if (status & TWE_STAT_RDYI) {		while (!(status & TWE_STAT_RQE)) {			u_int32_t ready;			/*			 * it seems that reading ready queue			 * we get all the status bits in each ready word.			 * i wonder if it's legal to use those for			 * status and avoid extra read below			 */			ready = bus_space_read_4(sc->iot, sc->ioh,			    TWE_READYQUEUE);			if (!twe_done(sc, TWE_READYID(ready)))				rv++;			status = bus_space_read_4(sc->iot, sc->ioh, TWE_STATUS);			TWE_DPRINTF(TWE_D_INTR, ("twe_intr stat=%b ",			    status & TWE_STAT_FLAGS, TWE_STAT_BITS));		}	}	if (status & TWE_STAT_ATTNI) {		u_int16_t aen;		/*		 * we know no attentions of interest right now.		 * one of those would be mirror degradation i think.		 * or, what else exists in there?		 * maybe 3ware can answer that?		 */		bus_space_write_4(sc->iot, sc->ioh, TWE_CONTROL,		    TWE_CTRL_CATTNI);		lock = TWE_LOCK_TWE(sc);		for (aen = -1; aen != TWE_AEN_QEMPTY; ) {			u_int8_t param_buf[2 * TWE_SECTOR_SIZE + TWE_ALIGN - 1];			struct twe_param *pb = (void *) (((u_long)param_buf +			    TWE_ALIGN - 1) & ~(TWE_ALIGN - 1));			if ((ccb = twe_get_ccb(sc)) == NULL)				break;			ccb->ccb_xs = NULL;			ccb->ccb_data = pb;			ccb->ccb_length = TWE_SECTOR_SIZE;			ccb->ccb_state = TWE_CCB_READY;			cmd = ccb->ccb_cmd;			cmd->cmd_unit_host = TWE_UNITHOST(0, 0);			cmd->cmd_op = TWE_CMD_GPARAM;			cmd->cmd_flags = 0;			cmd->cmd_param.count = 1;			pb->table_id = TWE_PARAM_AEN;			pb->param_id = 2;			pb->param_size = 2;			if (twe_cmd(ccb, BUS_DMA_NOWAIT, 1)) {				printf(": error draining attention queue\n");				break;			}			aen = *(u_int16_t *)pb->data;			TWE_DPRINTF(TWE_D_AEN, ("aen=%x ", aen));		}		TWE_UNLOCK_TWE(sc, lock);	}	return rv;}