diff options
author | imp <imp@FreeBSD.org> | 2001-08-10 06:07:20 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2001-08-10 06:07:20 +0000 |
commit | bb40f57a7caad930203ee3bf5e653cd8d69e1019 (patch) | |
tree | 374f710edbd3b68599fd608c4de735d478d8ea94 /sys/pccard/pcic.c | |
parent | 41502082f3ff6465a04cd16ed0469c21b8cc1694 (diff) | |
download | FreeBSD-src-bb40f57a7caad930203ee3bf5e653cd8d69e1019.zip FreeBSD-src-bb40f57a7caad930203ee3bf5e653cd8d69e1019.tar.gz |
Move ISA interrupt ISR and timeout routines to pcic from pcic_isa so
that we can use them in the pci code when we have to fall back to ISA
interrupt routing.
Diffstat (limited to 'sys/pccard/pcic.c')
-rw-r--r-- | sys/pccard/pcic.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/sys/pccard/pcic.c b/sys/pccard/pcic.c index bb67631e..1cd257e 100644 --- a/sys/pccard/pcic.c +++ b/sys/pccard/pcic.c @@ -919,3 +919,71 @@ pcic_do_stat_delta(struct pcic_slot *sp) else pccard_event(sp->slt, card_inserted); } +/* + * Wrapper function for pcicintr so that signatures match. + */ +void +pcic_isa_intr(void *arg) +{ + pcic_isa_intr1(arg); +} + +/* + * PCIC timer. If the controller doesn't have a free IRQ to use + * or if interrupt steering doesn't work, poll the controller for + * insertion/removal events. + */ +void +pcic_timeout(void *chan) +{ + struct pcic_softc *sc = (struct pcic_softc *) chan; + + if (pcic_isa_intr1(chan) != 0) { + device_printf(sc->dev, + "Static bug detected, ignoring hardware."); + sc->slot_poll = 0; + return; + } + sc->timeout_ch = timeout(sc->slot_poll, chan, hz/2); +} + +/* + * PCIC Interrupt handler. + * Check each slot in turn, and read the card status change + * register. If this is non-zero, then a change has occurred + * on this card, so send an event to the main code. + */ +int +pcic_isa_intr1(void *arg) +{ + int slot, s; + u_int8_t chg; + struct pcic_softc *sc = (struct pcic_softc *) arg; + struct pcic_slot *sp = &sc->slots[0]; + + s = splhigh(); + for (slot = 0; slot < PCIC_CARD_SLOTS; slot++, sp++) { + if (sp->slt == NULL) + continue; + if ((chg = sp->getb(sp, PCIC_STAT_CHG)) != 0) { + /* + * if chg is 0xff, then we know that we've hit + * the famous "static bug" for some desktop + * pcmcia cards. This is caused by static + * discharge frying the poor card's mind and + * it starts return 0xff forever. We return + * an error and stop polling the card. When + * we're interrupt based, we never see this. + * The card just goes away silently. + */ + if (chg == 0xff) { + splx(s); + return (EIO); + } + if (chg & PCIC_CDTCH) + pcic_do_stat_delta(sp); + } + } + splx(s); + return (0); +} |