void isic_attach_siemens_isurf(struct isic_softc *sc) { /* setup access routines */ sc->clearirq = NULL; sc->readreg = siemens_isurf_read_reg; sc->writereg = siemens_isurf_write_reg; sc->readfifo = siemens_isurf_read_fifo; sc->writefifo = siemens_isurf_write_fifo; /* setup card type */ sc->sc_cardtyp = CARD_TYPEP_SIE_ISURF2; /* setup IOM bus type */ sc->sc_bustyp = BUS_TYPE_IOM2; /* setup chip type = IPAC ! */ sc->sc_ipac = 1; sc->sc_bfifolen = IPAC_BFIFO_LEN; /* enable hscx/isac irq's */ IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0)); IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */ IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */ (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2)); IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */ }
static void isic_enable_intr(struct isic_softc *sc, int enable) { #if NNISACSX > 0 if (sc->sc_cardtyp == CARD_TYPEP_AVMA1PCIV2) { if (enable) isic_isacsx_init(sc); else isic_isacsx_disable_intr(sc); return; } #endif /* NNISACSX > 0 */ #if NNISAC > 0 if (enable) { isic_isac_init(sc); } else { /* disable receiver */ ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_DIM0); /* mask interrupts */ if (sc->sc_ipac) { IPAC_WRITE(IPAC_MASK, 0xff); } else { ISAC_WRITE(I_MASK, 0xff); } } #endif /* NNISAC > 0 */ }
/*---------------------------------------------------------------------------* * Eicon Diehl DIVA 2.02 *---------------------------------------------------------------------------*/ int isic_attach_diva_ipac(device_t dev) { int unit = device_get_unit(dev); struct l1_softc *sc = &l1_sc[unit]; /* setup access routines */ sc->clearirq = NULL; sc->readreg = diva_ipac_read_reg; sc->writereg = diva_ipac_write_reg; sc->readfifo = diva_ipac_read_fifo; sc->writefifo = diva_ipac_write_fifo; /* setup card type */ sc->sc_cardtyp = CARD_TYPEP_DIVA_ISA; /* setup IOM bus type */ sc->sc_bustyp = BUS_TYPE_IOM2; /* setup chip type = IPAC */ sc->sc_ipac = 1; sc->sc_bfifolen = IPAC_BFIFO_LEN; /* enable hscx/isac irq's */ IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0)); IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */ IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */ (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2)); IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */ return(0); }
/*---------------------------------------------------------------------------* * isic_attach_siemens_isurf - attach for Siemens I-Surf 2.0 PnP *---------------------------------------------------------------------------*/ int isic_attach_siemens_isurf(struct isa_device *dev, unsigned int iobase2) { struct isic_softc *sc = &l1_sc[dev->id_unit]; /* setup ISAC and HSCX base addr */ ISAC_BASE = (void *) ((u_int)sc->sc_port | SIE_ISURF_IDISAC); HSCX_A_BASE = (void *) ((u_int)sc->sc_port | SIE_ISURF_IDHSCXA); HSCX_B_BASE = (void *) ((u_int)sc->sc_port | SIE_ISURF_IDHSCXB); IPAC_BASE = (void *) ((u_int)sc->sc_port | SIE_ISURF_IDIPAC); /* enable hscx/isac irq's */ IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0)); IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */ IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */ (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2)); IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */ return(1); }
/*---------------------------------------------------------------------------* * isic - device driver interrupt routine *---------------------------------------------------------------------------*/ void isicintr(struct l1_softc *sc) { if(sc->sc_ipac == 0) /* HSCX/ISAC interupt routine */ { u_char was_hscx_irq = 0; u_char was_isac_irq = 0; register u_char hscx_irq_stat; register u_char isac_irq_stat; for(;;) { /* get hscx irq status from hscx b ista */ hscx_irq_stat = HSCX_READ(HSCX_CH_B, H_ISTA) & ~HSCX_B_IMASK; /* get isac irq status */ isac_irq_stat = ISAC_READ(I_ISTA); /* do as long as there are pending irqs in the chips */ if(!hscx_irq_stat && !isac_irq_stat) break; if(hscx_irq_stat & (HSCX_ISTA_RME | HSCX_ISTA_RPF | HSCX_ISTA_RSC | HSCX_ISTA_XPR | HSCX_ISTA_TIN | HSCX_ISTA_EXB)) { isic_hscx_irq(sc, hscx_irq_stat, HSCX_CH_B, hscx_irq_stat & HSCX_ISTA_EXB); was_hscx_irq = 1; } if(hscx_irq_stat & (HSCX_ISTA_ICA | HSCX_ISTA_EXA)) { isic_hscx_irq(sc, HSCX_READ(HSCX_CH_A, H_ISTA) & ~HSCX_A_IMASK, HSCX_CH_A, hscx_irq_stat & HSCX_ISTA_EXA); was_hscx_irq = 1; } if(isac_irq_stat) { isic_isac_irq(sc, isac_irq_stat); /* isac handler */ was_isac_irq = 1; } } HSCX_WRITE(0, H_MASK, 0xff); ISAC_WRITE(I_MASK, 0xff); HSCX_WRITE(1, H_MASK, 0xff); #ifdef ELSA_QS1ISA DELAY(80); if((sc->sc_cardtyp == CARD_TYPEP_ELSAQS1ISA) && (sc->clearirq)) { sc->clearirq(sc); } #else DELAY(100); #endif HSCX_WRITE(0, H_MASK, HSCX_A_IMASK); ISAC_WRITE(I_MASK, ISAC_IMASK); HSCX_WRITE(1, H_MASK, HSCX_B_IMASK); } else /* IPAC interrupt routine */ { register u_char ipac_irq_stat; register u_char was_ipac_irq = 0; for(;;) { /* get global irq status */ ipac_irq_stat = (IPAC_READ(IPAC_ISTA)) & 0x3f; /* check hscx a */ if(ipac_irq_stat & (IPAC_ISTA_ICA | IPAC_ISTA_EXA)) { /* HSCX A interrupt */ isic_hscx_irq(sc, HSCX_READ(HSCX_CH_A, H_ISTA), HSCX_CH_A, ipac_irq_stat & IPAC_ISTA_EXA); was_ipac_irq = 1; } if(ipac_irq_stat & (IPAC_ISTA_ICB | IPAC_ISTA_EXB)) { /* HSCX B interrupt */ isic_hscx_irq(sc, HSCX_READ(HSCX_CH_B, H_ISTA), HSCX_CH_B, ipac_irq_stat & IPAC_ISTA_EXB); was_ipac_irq = 1; } if(ipac_irq_stat & IPAC_ISTA_ICD) { /* ISAC interrupt */ isic_isac_irq(sc, ISAC_READ(I_ISTA)); was_ipac_irq = 1; } if(ipac_irq_stat & IPAC_ISTA_EXD) { /* force ISAC interrupt handling */ isic_isac_irq(sc, ISAC_ISTA_EXI); was_ipac_irq = 1; } /* do as long as there are pending irqs in the chip */ if(!ipac_irq_stat) break; } IPAC_WRITE(IPAC_MASK, 0xff); DELAY(50); IPAC_WRITE(IPAC_MASK, 0xc0); } }
/*---------------------------------------------------------------------------* * isic - device driver interrupt routine *---------------------------------------------------------------------------*/ int isicintr(void *arg) { struct isic_softc *sc = arg; /* could this be an interrupt for us? */ if (sc->sc_intr_valid == ISIC_INTR_DYING) return 0; /* do not touch removed hardware */ if(sc->sc_ipac == 0) /* HSCX/ISAC interupt routine */ { u_char was_hscx_irq = 0; u_char was_isac_irq = 0; register u_char hscx_irq_stat; register u_char isac_irq_stat; for(;;) { /* get hscx irq status from hscx b ista */ hscx_irq_stat = HSCX_READ(HSCX_CH_B, H_ISTA) & ~HSCX_B_IMASK; /* get isac irq status */ isac_irq_stat = ISAC_READ(I_ISTA); /* do as long as there are pending irqs in the chips */ if(!hscx_irq_stat && !isac_irq_stat) break; if(hscx_irq_stat & (HSCX_ISTA_RME | HSCX_ISTA_RPF | HSCX_ISTA_RSC | HSCX_ISTA_XPR | HSCX_ISTA_TIN | HSCX_ISTA_EXB)) { isic_hscx_irq(sc, hscx_irq_stat, HSCX_CH_B, hscx_irq_stat & HSCX_ISTA_EXB); was_hscx_irq = 1; } if(hscx_irq_stat & (HSCX_ISTA_ICA | HSCX_ISTA_EXA)) { isic_hscx_irq(sc, HSCX_READ(HSCX_CH_A, H_ISTA) & ~HSCX_A_IMASK, HSCX_CH_A, hscx_irq_stat & HSCX_ISTA_EXA); was_hscx_irq = 1; } if(isac_irq_stat) { /* isac handler */ isic_isac_irq(sc, isac_irq_stat); was_isac_irq = 1; } } HSCX_WRITE(0, H_MASK, 0xff); ISAC_WRITE(I_MASK, 0xff); HSCX_WRITE(1, H_MASK, 0xff); if (sc->clearirq) { DELAY(80); sc->clearirq(sc); } else DELAY(100); HSCX_WRITE(0, H_MASK, HSCX_A_IMASK); ISAC_WRITE(I_MASK, ISAC_IMASK); HSCX_WRITE(1, H_MASK, HSCX_B_IMASK); return(was_hscx_irq || was_isac_irq); } else /* IPAC interrupt routine */ { register u_char ipac_irq_stat; register u_char was_ipac_irq = 0; for(;;) { /* get global irq status */ ipac_irq_stat = (IPAC_READ(IPAC_ISTA)) & 0x3f; /* check hscx a */ if(ipac_irq_stat & (IPAC_ISTA_ICA | IPAC_ISTA_EXA)) { /* HSCX A interrupt */ isic_hscx_irq(sc, HSCX_READ(HSCX_CH_A, H_ISTA), HSCX_CH_A, ipac_irq_stat & IPAC_ISTA_EXA); was_ipac_irq = 1; } if(ipac_irq_stat & (IPAC_ISTA_ICB | IPAC_ISTA_EXB)) { /* HSCX B interrupt */ isic_hscx_irq(sc, HSCX_READ(HSCX_CH_B, H_ISTA), HSCX_CH_B, ipac_irq_stat & IPAC_ISTA_EXB); was_ipac_irq = 1; } if(ipac_irq_stat & IPAC_ISTA_ICD) { /* ISAC interrupt, Obey ISAC-IPAC differences */ u_int8_t isac_ista = ISAC_READ(I_ISTA); if (isac_ista & 0xfe) isic_isac_irq(sc, isac_ista & 0xfe); if (isac_ista & 0x01) /* unexpected */ printf("%s: unexpected ipac timer2 irq\n", sc->sc_dev.dv_xname); was_ipac_irq = 1; } if(ipac_irq_stat & IPAC_ISTA_EXD) { /* ISAC EXI interrupt */ isic_isac_irq(sc, ISAC_ISTA_EXI); was_ipac_irq = 1; } /* do as long as there are pending irqs in the chip */ if(!ipac_irq_stat) break; } #if 0 /* * This seems not to be necessary on IPACs - no idea why * it is here - but due to limit range of test cards, leave * it in for now, in case we have to resurrect it. */ IPAC_WRITE(IPAC_MASK, 0xff); DELAY(50); IPAC_WRITE(IPAC_MASK, 0xc0); #endif return(was_ipac_irq); } }