/* The interrupt handler */ static void nm_intr(void *p) { struct sc_info *sc = (struct sc_info *)p; int status, x, active; active = (sc->pch.channel->buffer.dl || sc->rch.channel->buffer.dl); status = nm_rd(sc, NM_INT_REG, sc->irsz); if (status == 0 && active) { if (sc->badintr++ > 1000) { device_printf(sc->dev, "1000 bad intrs\n"); sc->badintr = 0; } return; } sc->badintr = 0; if (status & sc->playint) { status &= ~sc->playint; nm_ackint(sc, sc->playint); chn_intr(sc->pch.channel); } if (status & sc->recint) { status &= ~sc->recint; nm_ackint(sc, sc->recint); chn_intr(sc->rch.channel); } if (status & sc->misc1int) { status &= ~sc->misc1int; nm_ackint(sc, sc->misc1int); x = nm_rd(sc, 0x400, 1); nm_wr(sc, 0x400, x | 2, 1); device_printf(sc->dev, "misc int 1\n"); } if (status & sc->misc2int) { status &= ~sc->misc2int; nm_ackint(sc, sc->misc2int); x = nm_rd(sc, 0x400, 1); nm_wr(sc, 0x400, x & ~2, 1); device_printf(sc->dev, "misc int 2\n"); } if (status) { status &= ~sc->misc2int; nm_ackint(sc, sc->misc2int); device_printf(sc->dev, "unknown int\n"); } }
/* The interrupt handler */ static void nm_intr(void *p) { struct sc_info *sc = (struct sc_info *)p; int status, x; status = nm_rd(sc, NM_INT_REG, sc->irsz); if (status == 0) return; if (status & sc->playint) { status &= ~sc->playint; sc->pch.wmark += sc->pch.blksize; sc->pch.wmark %= NM_BUFFSIZE; nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + sc->pch.wmark, 4); nm_ackint(sc, sc->playint); chn_intr(sc->pch.channel); } if (status & sc->recint) { status &= ~sc->recint; sc->rch.wmark += sc->rch.blksize; sc->rch.wmark %= NM_BUFFSIZE; nm_wr(sc, NM_RBUFFER_WMARK, sc->rbuf + sc->rch.wmark, 4); nm_ackint(sc, sc->recint); chn_intr(sc->rch.channel); } if (status & sc->misc1int) { status &= ~sc->misc1int; nm_ackint(sc, sc->misc1int); x = nm_rd(sc, 0x400, 1); nm_wr(sc, 0x400, x | 2, 1); device_printf(sc->dev, "misc int 1\n"); } if (status & sc->misc2int) { status &= ~sc->misc2int; nm_ackint(sc, sc->misc2int); x = nm_rd(sc, 0x400, 1); nm_wr(sc, 0x400, x & ~2, 1); device_printf(sc->dev, "misc int 2\n"); } if (status) { nm_ackint(sc, status); device_printf(sc->dev, "unknown int\n"); } }
/* The interrupt handler */ int neo_intr(void *p) { struct neo_softc *sc = (struct neo_softc *)p; int status, x; int rv = 0; mtx_enter(&audio_lock); status = nm_rd(sc, NM_INT_REG, sc->irsz); if (status & sc->playint) { status &= ~sc->playint; sc->pwmark += sc->pblksize; sc->pwmark %= sc->pbufsize; nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + sc->pwmark, 4); nm_ackint(sc, sc->playint); if (sc->pintr) (*sc->pintr)(sc->parg); rv = 1; } if (status & sc->recint) { status &= ~sc->recint; sc->rwmark += sc->rblksize; sc->rwmark %= sc->rbufsize; nm_ackint(sc, sc->recint); if (sc->rintr) (*sc->rintr)(sc->rarg); rv = 1; } if (status & sc->misc1int) { status &= ~sc->misc1int; nm_ackint(sc, sc->misc1int); x = nm_rd(sc, 0x400, 1); nm_wr(sc, 0x400, x | 2, 1); printf("%s: misc int 1\n", sc->dev.dv_xname); rv = 1; } if (status & sc->misc2int) { status &= ~sc->misc2int; nm_ackint(sc, sc->misc2int); x = nm_rd(sc, 0x400, 1); nm_wr(sc, 0x400, x & ~2, 1); printf("%s: misc int 2\n", sc->dev.dv_xname); rv = 1; } if (status) { status &= ~sc->misc2int; nm_ackint(sc, sc->misc2int); printf("%s: unknown int\n", sc->dev.dv_xname); rv = 1; } mtx_leave(&audio_lock); return (rv); }