Пример #1
0
void
drsc_handler(void)
{
	struct siop_softc *sc = drsc_softc;

	siop_regmap_p rp;
	int istat;

	if (sc->sc_flags & SIOP_INTSOFF)
		return;		/* interrupts are not active */

	rp = sc->sc_siopp;
	istat = rp->siop_istat;

	if ((istat & (SIOP_ISTAT_SIP | SIOP_ISTAT_DIP)) == 0)
		return;

	/*
	 * save interrupt status, DMA status, and SCSI status 0
	 * (may need to deal with stacked interrupts?)
	 */
	sc->sc_sstat0 = rp->siop_sstat0;
	sc->sc_istat = istat;
	sc->sc_dstat = rp->siop_dstat;
	/*
	 * disable interrupts until the callback can process this
	 * interrupt.
	 */
#ifdef DRSC_NOCALLBACK
	(void)spl1();
	siopintr(sc);
#else
	rp->siop_sien = 0;
	rp->siop_dien = 0;
	sc->sc_flags |= SIOP_INTDEFER | SIOP_INTSOFF;
	single_inst_bclr_b(*draco_intpen, DRIRQ_SCSI);
#ifdef DEBUG
	if (*draco_intpen & DRIRQ_SCSI)
		printf("%s: intpen still 0x%x\n", sc->sc_dev.dv_xname,
		    *draco_intpen);
#endif
	add_sicallback((sifunc_t)siopintr, sc, NULL);
#endif
	return;
}
static int
iifun(int slot, int sr)
{
	isa_intr_info_t *iinfo_p;
	int		s;

	iinfo_p = &iinfo[slot];

	/*
	 * Disable the interrupts
	 */
	if (slot == 0) {
		single_inst_bclr_b(MFP->mf_imrb, IB_ISA1);
	}
	else {
		single_inst_bclr_b(MFP->mf_imra, IA_ISA2);
	}

	if ((sr & PSL_IPL) >= (iinfo_p->ipl & PSL_IPL)) {
		/*
		 * We're running at a too high priority now.
		 */
		add_sicallback((si_farg)iifun, (void*)slot, 0);
	}
	else {
		s = splx(iinfo_p->ipl);
		if (slot == 0) {
			do {
				MFP->mf_iprb = (u_int8_t)~IB_ISA1;
				(void) (iinfo_p->ifunc)(iinfo_p->iarg);
			} while (MFP->mf_iprb & IB_ISA1);
			single_inst_bset_b(MFP->mf_imrb, IB_ISA1);
		}
		else {
			do {
				MFP->mf_ipra = (u_int8_t)~IA_ISA2;
				(void) (iinfo_p->ifunc)(iinfo_p->iarg);
			} while (MFP->mf_ipra & IA_ISA2);
			single_inst_bset_b(MFP->mf_imra, IA_ISA2);
		}
		splx(s);
	}
	return 1;
}