printf("DMA IRQ:"); if (dstat & DSTAT_IID) printf(" Illegal instruction"); if (dstat & DSTAT_BF) printf(" bus fault"); if (dstat & DSTAT_MDPE) printf(" parity"); if (dstat & DSTAT_DFE) printf(" dma fifo empty"); else siop_clearfifo(&sc->sc_c); printf(", DSP=0x%x DSA=0x%x: ", (int)(bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSP) - sc->sc_c.sc_scriptaddr), bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSA)); if (siop_cmd) printf("last msg_in=0x%x status=0x%x\n", siop_cmd->cmd_tables->msg_in[0], letoh32(siop_cmd->cmd_tables->status)); else printf("%s: current DSA invalid\n", sc->sc_c.sc_dev.dv_xname); need_reset = 1;
printf("%s: DMA IRQ:", sc->sc_c.sc_dev.dv_xname); if (dstat & DSTAT_IID) printf(" illegal instruction"); if (dstat & DSTAT_BF) printf(" bus fault"); if (dstat & DSTAT_MDPE) printf(" parity"); if (dstat & DSTAT_DFE) printf(" dma fifo empty"); else siop_clearfifo(&sc->sc_c); printf(", DSP=0x%x DSA=0x%x: ", (int)(bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSP) - sc->sc_c.sc_scriptaddr), bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSA)); if (siop_cmd) printf("last msg_in=0x%x status=0x%x\n", siop_cmd->cmd_tables->msg_in[0], letoh32(siop_cmd->cmd_tables->status)); else printf("current DSA invalid\n"); need_reset = 1;
siop_intr(v)	void *v;{	struct siop_softc *sc = v;	struct siop_target *siop_target;	struct siop_cmd *siop_cmd;	struct siop_lun *siop_lun;	struct scsi_xfer *xs;	int istat, sist, sstat1, dstat;	u_int32_t irqcode;	int need_reset = 0;	int offset, target, lun, tag;	bus_addr_t dsa;	struct siop_cbd *cbdp;	int freetarget = 0;	int restart = 0;	istat = bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_ISTAT);	if ((istat & (ISTAT_INTF | ISTAT_DIP | ISTAT_SIP)) == 0)		return 0;	INCSTAT(siop_stat_intr);	if (istat & ISTAT_INTF) {		printf("INTRF\n");		bus_space_write_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,		    SIOP_ISTAT, ISTAT_INTF);	}	if ((istat &(ISTAT_DIP | ISTAT_SIP | ISTAT_ABRT)) ==	    (ISTAT_DIP | ISTAT_ABRT)) {		/* clear abort */		bus_space_write_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,		    SIOP_ISTAT, 0);	}	/* use DSA to find the current siop_cmd */	dsa = bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSA);	for (cbdp = TAILQ_FIRST(&sc->cmds); cbdp != NULL;	    cbdp = TAILQ_NEXT(cbdp, next)) {		if (dsa >= cbdp->xferdma->dm_segs[0].ds_addr &&	    	    dsa < cbdp->xferdma->dm_segs[0].ds_addr + PAGE_SIZE) {			dsa -= cbdp->xferdma->dm_segs[0].ds_addr;			siop_cmd = &cbdp->cmds[dsa / sizeof(struct siop_xfer)];			siop_table_sync(siop_cmd,			    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);			break;		}	} 	if (cbdp == NULL) {		siop_cmd = NULL;	}	if (siop_cmd) {		xs = siop_cmd->cmd_c.xs;		siop_target = (struct siop_target *)siop_cmd->cmd_c.siop_target;		target = siop_cmd->cmd_c.xs->sc_link->target;		lun = siop_cmd->cmd_c.xs->sc_link->lun;		tag = siop_cmd->cmd_c.tag;		siop_lun = siop_target->siop_lun[lun];#ifdef DIAGNOSTIC		if (siop_cmd->cmd_c.status != CMDST_ACTIVE &&		    siop_cmd->cmd_c.status != CMDST_SENSE_ACTIVE) { 			printf("siop_cmd (lun %d) for DSA 0x%x "			    "not active (%d)\n", lun, (u_int)dsa,			    siop_cmd->cmd_c.status);			xs = NULL;			siop_target = NULL;			target = -1;			lun = -1;			tag = -1;			siop_lun = NULL;			siop_cmd = NULL;		} else if (siop_lun->siop_tag[tag].active != siop_cmd) {			printf("siop_cmd (lun %d tag %d) not in siop_lun "			    "active (%p != %p)\n", lun, tag, siop_cmd,			    siop_lun->siop_tag[tag].active);		}#endif	} else {		xs = NULL;		siop_target = NULL;		target = -1;		lun = -1;		tag = -1;		siop_lun = NULL;	}	if (istat & ISTAT_DIP) {		dstat = bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,		    SIOP_DSTAT);		if (dstat & DSTAT_ABRT) {			/* was probably generated by a bus reset IOCTL */			if ((dstat & DSTAT_DFE) == 0)				siop_clearfifo(&sc->sc_c);			goto reset;		}		if (dstat & DSTAT_SSI) {			printf("single step dsp 0x%08x dsa 0x08%x\n",			    (int)(bus_space_read_4(sc->sc_c.sc_rt,			    sc->sc_c.sc_rh, SIOP_DSP) -			    sc->sc_c.sc_scriptaddr),			    bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,				SIOP_DSA));			if ((dstat & ~(DSTAT_DFE | DSTAT_SSI)) == 0 &&			    (istat & ISTAT_SIP) == 0) {				bus_space_write_1(sc->sc_c.sc_rt,				    sc->sc_c.sc_rh, SIOP_DCNTL,				    bus_space_read_1(sc->sc_c.sc_rt,				    sc->sc_c.sc_rh, SIOP_DCNTL) | DCNTL_STD);			}			return 1;		}		if (dstat & ~(DSTAT_SIR | DSTAT_DFE | DSTAT_SSI)) {		printf("DMA IRQ:");		if (dstat & DSTAT_IID)			printf(" Illegal instruction");		if (dstat & DSTAT_BF)			printf(" bus fault");		if (dstat & DSTAT_MDPE)			printf(" parity");		if (dstat & DSTAT_DFE)			printf(" dma fifo empty");		else			siop_clearfifo(&sc->sc_c);		printf(", DSP=0x%x DSA=0x%x: ",		    (int)(bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,			SIOP_DSP) - sc->sc_c.sc_scriptaddr),		    bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSA));		if (siop_cmd)			printf("last msg_in=0x%x status=0x%x\n",			    siop_cmd->cmd_tables->msg_in[0],			    letoh32(siop_cmd->cmd_tables->status));		else 			printf("%s: current DSA invalid\n",			    sc->sc_c.sc_dev.dv_xname);		need_reset = 1;		}	}	if (istat & ISTAT_SIP) {		if (istat & ISTAT_DIP)			delay(10);		/*		 * Can't read sist0 & sist1 independantly, or we have to		 * insert delay		 */		sist = bus_space_read_2(sc->sc_c.sc_rt, sc->sc_c.sc_rh,		    SIOP_SIST0);		sstat1 = bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,		    SIOP_SSTAT1);#ifdef SIOP_DEBUG_INTR		printf("scsi interrupt, sist=0x%x sstat1=0x%x "		    "DSA=0x%x DSP=0x%lx\n", sist,		    bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,			SIOP_SSTAT1),		    bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSA),		    (u_long)(bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,			SIOP_DSP) -		    sc->sc_c.sc_scriptaddr));#endif		if (sist & SIST0_RST) {			siop_handle_reset(sc);			siop_start(sc);			/* no table to flush here */			return 1;		}		if (sist & SIST0_SGE) {			if (siop_cmd)				sc_print_addr(xs->sc_link);			else				printf("%s:", sc->sc_c.sc_dev.dv_xname);			printf("scsi gross error\n");			goto reset;		}		if ((sist & SIST0_MA) && need_reset == 0) {			if (siop_cmd) { 				int scratcha0;				dstat = bus_space_read_1(sc->sc_c.sc_rt,				    sc->sc_c.sc_rh, SIOP_DSTAT);				/*				 * first restore DSA, in case we were in a S/G				 * operation.				 */				bus_space_write_4(sc->sc_c.sc_rt,				    sc->sc_c.sc_rh,				    SIOP_DSA, siop_cmd->cmd_c.dsa);				scratcha0 = bus_space_read_1(sc->sc_c.sc_rt,				    sc->sc_c.sc_rh, SIOP_SCRATCHA);				switch (sstat1 & SSTAT1_PHASE_MASK) {				case SSTAT1_PHASE_STATUS:				/*				 * previous phase may be aborted for any reason				 * ( for example, the target has less data to				 * transfer than requested). Just go to status				 * and the command should terminate.				 */					INCSTAT(siop_stat_intr_shortxfer);					if ((dstat & DSTAT_DFE) == 0)						siop_clearfifo(&sc->sc_c);					/* no table to flush here */					CALL_SCRIPT(Ent_status);					return 1;				case SSTAT1_PHASE_MSGIN:					/*					 * target may be ready to disconnect					 * Save data pointers just in case.					 */					INCSTAT(siop_stat_intr_xferdisc);					if (scratcha0 & A_flag_data)						siop_sdp(&siop_cmd->cmd_c);					else if ((dstat & DSTAT_DFE) == 0)						siop_clearfifo(&sc->sc_c);					bus_space_write_1(sc->sc_c.sc_rt,					    sc->sc_c.sc_rh, SIOP_SCRATCHA,					    scratcha0 & ~A_flag_data);					siop_table_sync(siop_cmd,					    BUS_DMASYNC_PREREAD |					    BUS_DMASYNC_PREWRITE);					CALL_SCRIPT(Ent_msgin);					return 1;				}				printf("%s: unexpected phase mismatch %d\n",				    sc->sc_c.sc_dev.dv_xname,				    sstat1 & SSTAT1_PHASE_MASK);			} else {				printf("%s: phase mismatch without command\n",				    sc->sc_c.sc_dev.dv_xname);			}			need_reset = 1;		}		if (sist & SIST0_PAR) {			/* parity error, reset */			if (siop_cmd)				sc_print_addr(xs->sc_link);			else				printf("%s:", sc->sc_c.sc_dev.dv_xname);			printf("parity error\n");			goto reset;		}		if ((sist & (SIST1_STO << 8)) && need_reset == 0) {			/* selection time out, assume there's no device here */			if (siop_cmd) {				siop_cmd->cmd_c.status = CMDST_DONE;				xs->error = XS_SELTIMEOUT;				freetarget = 1;				goto end;			} else {				printf("%s: selection timeout without "				    "command\n", sc->sc_c.sc_dev.dv_xname);				need_reset = 1;			}		}		if (sist & SIST0_UDC) {			/*			 * unexpected disconnect. Usually the target signals			 * a fatal condition this way. Attempt to get sense.			 */			 if (siop_cmd) {				siop_cmd->cmd_tables->status =				    htole32(SCSI_CHECK);				goto end;			}			printf("%s: unexpected disconnect without "			    "command\n", sc->sc_c.sc_dev.dv_xname);			goto reset;		}		if (sist & (SIST1_SBMC << 8)) {			/* SCSI bus mode change */			if (siop_modechange(&sc->sc_c) == 0 || need_reset == 1)				goto reset;			if ((istat & ISTAT_DIP) && (dstat & DSTAT_SIR)) {				/*				 * we have a script interrupt, it will				 * restart the script.				 */				goto scintr;			}			/*			 * else we have to restart it ourselve, at the			 * interrupted instruction.			 */			bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,			    SIOP_DSP,			    bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,			    SIOP_DSP) - 8);			return 1;		}		/* Else it's an unhandled exeption (for now). */		printf("%s: unhandled scsi interrupt, sist=0x%x sstat1=0x%x "		    "DSA=0x%x DSP=0x%x\n", sc->sc_c.sc_dev.dv_xname, sist,		    bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,			SIOP_SSTAT1),		    bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSA),		    (int)(bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,			SIOP_DSP) - sc->sc_c.sc_scriptaddr));		if (siop_cmd) {			siop_cmd->cmd_c.status = CMDST_DONE;			xs->error = XS_SELTIMEOUT;			goto end;		}		need_reset = 1;	}	if (need_reset) {reset:		/* fatal error, reset the bus */		siop_resetbus(&sc->sc_c);		/* no table to flush here */		return 1;	}scintr:	if ((istat & ISTAT_DIP) && (dstat & DSTAT_SIR)) { /* script interrupt */		irqcode = bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,		    SIOP_DSPS);#ifdef SIOP_DEBUG_INTR		printf("script interrupt 0x%x\n", irqcode);#endif		/*		 * no command, or an inactive command is only valid for a		 * reselect interrupt		 */		if ((irqcode & 0x80) == 0) {			if (siop_cmd == NULL) {				printf(			"%s: script interrupt (0x%x) with invalid DSA !!!\n",				    sc->sc_c.sc_dev.dv_xname, irqcode);				goto reset;			}			if (siop_cmd->cmd_c.status != CMDST_ACTIVE &&			    siop_cmd->cmd_c.status != CMDST_SENSE_ACTIVE) {				printf("%s: command with invalid status "				    "(IRQ code 0x%x current status %d) !\n",				    sc->sc_c.sc_dev.dv_xname,				    irqcode, siop_cmd->cmd_c.status);				xs = NULL;			}		}		switch(irqcode) {		case A_int_err:			printf("error, DSP=0x%x\n",			    (int)(bus_space_read_4(sc->sc_c.sc_rt,			    sc->sc_c.sc_rh, SIOP_DSP) - sc->sc_c.sc_scriptaddr));			if (xs) {				xs->error = XS_SELTIMEOUT;				goto end;			} else {				goto reset;			}		case A_int_reseltarg:			printf("%s: reselect with invalid target\n",				    sc->sc_c.sc_dev.dv_xname);			goto reset;		case A_int_resellun: 			INCSTAT(siop_stat_intr_lunresel);			target = bus_space_read_1(sc->sc_c.sc_rt,			    sc->sc_c.sc_rh, SIOP_SCRATCHA) & 0xf;			lun = bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,			    SIOP_SCRATCHA + 1);			tag = bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,			    SIOP_SCRATCHA + 2);			siop_target =			    (struct siop_target *)sc->sc_c.targets[target];			if (siop_target == NULL) {				printf("%s: reselect with invalid target %d\n",				    sc->sc_c.sc_dev.dv_xname, target);				goto reset;			}			siop_lun = siop_target->siop_lun[lun];			if (siop_lun == NULL) {				printf("%s: target %d reselect with invalid "				    "lun %d\n", sc->sc_c.sc_dev.dv_xname,				    target, lun);				goto reset;			}			if (siop_lun->siop_tag[tag].active == NULL) {				printf("%s: target %d lun %d tag %d reselect "				    "without command\n",				    sc->sc_c.sc_dev.dv_xname,				    target, lun, tag);				goto reset;			}			siop_cmd = siop_lun->siop_tag[tag].active;			bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,			    SIOP_DSP, siop_cmd->cmd_c.dsa +			    sizeof(struct siop_common_xfer) +			    Ent_ldsa_reload_dsa);			siop_table_sync(siop_cmd, BUS_DMASYNC_PREWRITE);			return 1;		case A_int_reseltag:			printf("%s: reselect with invalid tag\n",				    sc->sc_c.sc_dev.dv_xname);			goto reset;		case A_int_msgin:		{			int msgin = bus_space_read_1(sc->sc_c.sc_rt,			    sc->sc_c.sc_rh, SIOP_SFBR);			if (msgin == MSG_MESSAGE_REJECT) {				int msg, extmsg;				if (siop_cmd->cmd_tables->msg_out[0] & 0x80) {					/*					 * message was part of a identify +					 * something else. Identify shouldn't					 * have been rejected.					 */					msg =					    siop_cmd->cmd_tables->msg_out[1];					extmsg =					    siop_cmd->cmd_tables->msg_out[3];				} else {					msg = siop_cmd->cmd_tables->msg_out[0];					extmsg =					    siop_cmd->cmd_tables->msg_out[2];				}				if (msg == MSG_MESSAGE_REJECT) {					/* MSG_REJECT  for a MSG_REJECT  !*/					if (xs)						sc_print_addr(xs->sc_link);					else						printf("%s: ",						   sc->sc_c.sc_dev.dv_xname);					printf("our reject message was "					    "rejected\n");					goto reset;				}				if (msg == MSG_EXTENDED &&				    extmsg == MSG_EXT_WDTR) {					/* WDTR rejected, initiate sync */					if ((siop_target->target_c.flags &					   TARF_SYNC) == 0) {						siop_target->target_c.status =						    TARST_OK;						siop_update_xfer_mode(&sc->sc_c,						    target);						/* no table to flush here */						CALL_SCRIPT(Ent_msgin_ack);						return 1;					}					siop_target->target_c.status =					    TARST_SYNC_NEG;					siop_sdtr_msg(&siop_cmd->cmd_c, 0,					    sc->sc_c.st_minsync,					    sc->sc_c.maxoff);					siop_table_sync(siop_cmd,					    BUS_DMASYNC_PREREAD |					    BUS_DMASYNC_PREWRITE);					CALL_SCRIPT(Ent_send_msgout);					return 1;				} else if (msg == MSG_EXTENDED &&				    extmsg == MSG_EXT_SDTR) {					/* sync rejected */					siop_target->target_c.offset = 0;					siop_target->target_c.period = 0;					siop_target->target_c.status = TARST_OK;					siop_update_xfer_mode(&sc->sc_c,					    target);					/* no table to flush here */					CALL_SCRIPT(Ent_msgin_ack);					return 1;				} else if (msg == MSG_SIMPLE_Q_TAG || 				    msg == MSG_HEAD_OF_Q_TAG ||				    msg == MSG_ORDERED_Q_TAG) {					if (siop_handle_qtag_reject(					    siop_cmd) == -1)						goto reset;					CALL_SCRIPT(Ent_msgin_ack);					return 1;				}				if (xs)					sc_print_addr(xs->sc_link);				else					printf("%s: ",					    sc->sc_c.sc_dev.dv_xname);				if (msg == MSG_EXTENDED) {					printf("scsi message reject, extended "					    "message sent was 0x%x\n", extmsg);				} else {					printf("scsi message reject, message "					    "sent was 0x%x\n", msg);				}				/* no table to flush here */				CALL_SCRIPT(Ent_msgin_ack);				return 1;			}			if (xs)				sc_print_addr(xs->sc_link);			else				printf("%s: ", sc->sc_c.sc_dev.dv_xname);			printf("unhandled message 0x%x\n",			    siop_cmd->cmd_tables->msg_in[0]);			siop_cmd->cmd_tables->msg_out[0] = MSG_MESSAGE_REJECT;			siop_cmd->cmd_tables->t_msgout.count= htole32(1);			siop_table_sync(siop_cmd,			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);			CALL_SCRIPT(Ent_send_msgout);			return 1;		}		case A_int_extmsgin:#ifdef SIOP_DEBUG_INTR			printf("extended message: msg 0x%x len %d\n",			    siop_cmd->cmd_tables->msg_in[2], 			    siop_cmd->cmd_tables->msg_in[1]);#endif			if (siop_cmd->cmd_tables->msg_in[1] >			    sizeof(siop_cmd->cmd_tables->msg_in) - 2)				printf("%s: extended message too big (%d)\n",				    sc->sc_c.sc_dev.dv_xname,				    siop_cmd->cmd_tables->msg_in[1]);			siop_cmd->cmd_tables->t_extmsgdata.count =			    htole32(siop_cmd->cmd_tables->msg_in[1] - 1);			siop_table_sync(siop_cmd,			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);			CALL_SCRIPT(Ent_get_extmsgdata);			return 1;		case A_int_extmsgdata:#ifdef SIOP_DEBUG_INTR			{			int i;			printf("extended message: 0x%x, data:",			    siop_cmd->cmd_tables->msg_in[2]);			for (i = 3; i < 2 + siop_cmd->cmd_tables->msg_in[1];			    i++)				printf(" 0x%x",				    siop_cmd->cmd_tables->msg_in[i]);			printf("\n");			}#endif			if (siop_cmd->cmd_tables->msg_in[2] == MSG_EXT_WDTR) {				switch (siop_wdtr_neg(&siop_cmd->cmd_c)) {				case SIOP_NEG_MSGOUT:					siop_update_scntl3(sc,					    siop_cmd->cmd_c.siop_target);					siop_table_sync(siop_cmd,					    BUS_DMASYNC_PREREAD |					    BUS_DMASYNC_PREWRITE);					CALL_SCRIPT(Ent_send_msgout);					return(1);				case SIOP_NEG_ACK:					siop_update_scntl3(sc,					    siop_cmd->cmd_c.siop_target);					CALL_SCRIPT(Ent_msgin_ack);					return(1);				default:					panic("invalid retval from "					    "siop_wdtr_neg()");				}				return(1);			}			if (siop_cmd->cmd_tables->msg_in[2] == MSG_EXT_SDTR) {				switch (siop_sdtr_neg(&siop_cmd->cmd_c)) {				case SIOP_NEG_MSGOUT:					siop_update_scntl3(sc,					    siop_cmd->cmd_c.siop_target);					siop_table_sync(siop_cmd,					    BUS_DMASYNC_PREREAD |					    BUS_DMASYNC_PREWRITE);					CALL_SCRIPT(Ent_send_msgout);					return(1);				case SIOP_NEG_ACK:					siop_update_scntl3(sc,					    siop_cmd->cmd_c.siop_target);					CALL_SCRIPT(Ent_msgin_ack);					return(1);				default:					panic("invalid retval from "					    "siop_wdtr_neg()");				}				return(1);			}			if (siop_cmd->cmd_tables->msg_in[2] == MSG_EXT_PPR) {				switch (siop_ppr_neg(&siop_cmd->cmd_c)) {				case SIOP_NEG_MSGOUT:					siop_update_scntl3(sc,					    siop_cmd->cmd_c.siop_target);					siop_table_sync(siop_cmd,					    BUS_DMASYNC_PREREAD |					    BUS_DMASYNC_PREWRITE);					CALL_SCRIPT(Ent_send_msgout);					return(1);				case SIOP_NEG_ACK:					siop_update_scntl3(sc,					    siop_cmd->cmd_c.siop_target);					CALL_SCRIPT(Ent_msgin_ack);					return(1);				default:					panic("invalid retval from "					    "siop_wdtr_neg()");				}				return(1);			}			/* send a message reject */			siop_cmd->cmd_tables->msg_out[0] = MSG_MESSAGE_REJECT;			siop_cmd->cmd_tables->t_msgout.count = htole32(1);			siop_table_sync(siop_cmd,			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);			CALL_SCRIPT(Ent_send_msgout);			return 1;		case A_int_disc:			INCSTAT(siop_stat_intr_sdp);			offset = bus_space_read_1(sc->sc_c.sc_rt,			    sc->sc_c.sc_rh, SIOP_SCRATCHA + 1);#ifdef SIOP_DEBUG_DR			printf("disconnect offset %d\n", offset);#endif			if (offset > SIOP_NSG) {				printf("%s: bad offset for disconnect (%d)\n",				    sc->sc_c.sc_dev.dv_xname, offset);				goto reset;			}			/* 			 * offset == SIOP_NSG may be a valid condition if			 * we get a sdp when the xfer is done.			 * Don't call bcopy in this case.			 */			if (offset < SIOP_NSG) {				bcopy(&siop_cmd->cmd_tables->data[offset],				    &siop_cmd->cmd_tables->data[0],				    (SIOP_NSG - offset) * sizeof(scr_table_t));				siop_table_sync(siop_cmd,				    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);			}			/* check if we can put some command in scheduler */			siop_start(sc);			CALL_SCRIPT(Ent_script_sched);			return 1;		case A_int_resfail:			printf("reselect failed\n");			/* check if we can put some command in scheduler */			siop_start(sc);			CALL_SCRIPT(Ent_script_sched);			return  1;		case A_int_done:			if (xs == NULL) {				printf("%s: done without command, DSA=0x%lx\n",				    sc->sc_c.sc_dev.dv_xname,				    (u_long)siop_cmd->cmd_c.dsa);				siop_cmd->cmd_c.status = CMDST_FREE;				siop_start(sc);				CALL_SCRIPT(Ent_script_sched);				return 1;			}#ifdef SIOP_DEBUG_INTR			printf("done, DSA=0x%lx target id 0x%x last msg "			    "in=0x%x status=0x%x\n", (u_long)siop_cmd->cmd_c.dsa,			    letoh32(siop_cmd->cmd_tables->id),			    siop_cmd->cmd_tables->msg_in[0],			    letoh32(siop_cmd->cmd_tables->status));#endif			INCSTAT(siop_stat_intr_done);			if (siop_cmd->cmd_c.status == CMDST_SENSE_ACTIVE)				siop_cmd->cmd_c.status = CMDST_SENSE_DONE;			else				siop_cmd->cmd_c.status = CMDST_DONE;			goto end;		default:			printf("unknown irqcode %x\n", irqcode);			if (xs) {				xs->error = XS_SELTIMEOUT;				goto end;			}			goto reset;		}		return 1;	}	/* We can get here if ISTAT_DIP and DSTAT_DFE are the only bits set. */	/* But that *SHOULDN'T* happen. It does on powerpc (at least).	     */	printf("%s: siop_intr() - we should not be here!\n"	    "   istat = 0x%x, dstat = 0x%x, sist = 0x%x, sstat1 = 0x%x\n"	    "   need_reset = %x, irqcode = %x, siop_cmd %s\n",	    sc->sc_c.sc_dev.dv_xname,	    istat, dstat, sist, sstat1, need_reset, irqcode,	    (siop_cmd == NULL) ? "== NULL" : "!= NULL");	goto reset; /* Where we should have gone in the first place! */end:	/*	 * restart the script now if command completed properly	 * Otherwise wait for siop_scsicmd_end(), we may need to cleanup the	 * queue	 */	xs->status = letoh32(siop_cmd->cmd_tables->status);	if (xs->status == SCSI_OK)		CALL_SCRIPT(Ent_script_sched);	else		restart = 1;	siop_lun->siop_tag[tag].active = NULL;	siop_scsicmd_end(siop_cmd);	if (freetarget && siop_target->target_c.status == TARST_PROBING)		siop_del_dev(sc, target, lun);	siop_start(sc);	if (restart)		CALL_SCRIPT(Ent_script_sched);	return 1;}