Date: Wed, 13 Dec 2006 22:39:51 GMT From: Paolo Pisati <piso@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 111664 for review Message-ID: <200612132239.kBDMdp7Q080619@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=111664 Change 111664 by piso@piso_newluxor on 2006/12/13 22:38:54 Teach scc about filters: o added a new wrapper function (scc_bfe_ihand()) for ithread handler. o axe the condition into which bus_setup_intr() could fail to setup a filter. o teach scc_bfe_filter() to return the filter return codes. filters. o put an XXX comment in case different filters attached to the same scc would return opposite values (STRAY and any other values). Affected files ... .. //depot/projects/soc2006/intr_filter/dev/scc/scc_bfe.h#4 edit .. //depot/projects/soc2006/intr_filter/dev/scc/scc_core.c#11 edit Differences ... ==== //depot/projects/soc2006/intr_filter/dev/scc/scc_bfe.h#4 (text) ==== @@ -72,10 +72,12 @@ u_int m_mode; int m_attached:1; int m_hasintr:1; + int m_hasihand:1; int m_probed:1; int m_sysdev:1; - driver_intr_t *ih; + driver_filter_t *ihf; + driver_intr_t *ih; serdev_intr_t *ih_src[SCC_ISRCCNT]; void *ih_arg; }; ==== //depot/projects/soc2006/intr_filter/dev/scc/scc_core.c#11 (text) ==== @@ -51,14 +51,32 @@ MALLOC_DEFINE(M_SCC, "SCC", "SCC driver"); +static void +scc_bfe_ihand(void *arg) +{ + struct scc_softc *sc = arg; + struct scc_class *cl; + struct scc_mode *m; + int c; + + cl = sc->sc_class; + for (c = 0; c < cl->cl_channels; c++) { + m = &sc->sc_chan[c].ch_mode[0]; + if (m->m_hasihand) { + (*m->ih)(m->ih_arg); + m->m_hasihand = 0; + } + } +} + static int -scc_bfe_intr(void *arg) +scc_bfe_filter(void *arg) { struct scc_softc *sc = arg; struct scc_chan *ch; struct scc_class *cl; struct scc_mode *m; - int c, i, ipend, isrc; + int c, i, ipend, isrc, res; cl = sc->sc_class; while (!sc->sc_leaving && (ipend = SCC_IPEND(sc)) != 0) { @@ -79,19 +97,34 @@ ch->ch_ipend &= ~isrc; } } + res = FILTER_HANDLED; for (c = 0; c < cl->cl_channels; c++) { ch = &sc->sc_chan[c]; if (!ch->ch_ipend) continue; m = &ch->ch_mode[0]; - if (m->ih != NULL) - (*m->ih)(m->ih_arg); - else + // XXX propagation of filter return value is broken: + // XXX what if one handler returns STRAY and another + // XXX one returns HANDLED | SCHEDULE_THREAD? + // XXX what i'm supposed to do? for now, just OR all + // XXX the return values. + m->m_hasihand = 0; + if (m->ihf != NULL) { + res |= (*m->ihf)(m->ih_arg); + if (res & FILTER_SCHEDULE_THREAD) + m->m_hasihand = 1; + } else { + if (m->ih != NULL) { + res |= FILTER_HANDLED | + FILTER_SCHEDULE_THREAD; + m->m_hasihand = 1; + } SCC_ICLEAR(sc, ch); + } } - return(FILTER_HANDLED); + return (res); } - return(FILTER_STRAY); + return (FILTER_STRAY); } int @@ -220,15 +253,8 @@ if (ch->ch_ires == NULL) continue; error = bus_setup_intr(dev, ch->ch_ires, - INTR_TYPE_TTY, scc_bfe_intr, NULL, + INTR_TYPE_TTY, scc_bfe_filter, scc_bfe_ihand, sc, &ch->ch_icookie); - if (error) { - error = bus_setup_intr(dev, ch->ch_ires, - INTR_TYPE_TTY | INTR_MPSAFE, - NULL, (driver_intr_t *)scc_bfe_intr, sc, - &ch->ch_icookie); - } else - sc->sc_fastintr = 1; if (error) { device_printf(dev, "could not activate interrupt\n"); @@ -502,40 +528,24 @@ driver_filter_t *filter, void (*ihand)(void *), void *arg, void **cookiep) { - struct scc_chan *ch; struct scc_mode *m; struct scc_softc *sc; - int c, i, isrc; + int i, isrc; if (device_get_parent(child) != dev) return (EINVAL); /* Interrupt handlers must be FAST or MPSAFE. */ - if (!(IS_FAST(filter, ihand)) || ((flags & INTR_MPSAFE) == 0)) + if ((filter == NULL) && !(flags & INTR_MPSAFE)) return (EINVAL); sc = device_get_softc(dev); if (sc->sc_polled) return (ENXIO); - if (sc->sc_fastintr && !(IS_FAST(filter, ihand))) { - sc->sc_fastintr = 0; - for (c = 0; c < sc->sc_class->cl_channels; c++) { - ch = &sc->sc_chan[c]; - if (ch->ch_ires == NULL) - continue; - bus_teardown_intr(dev, ch->ch_ires, ch->ch_icookie); - bus_setup_intr(dev, ch->ch_ires, - INTR_TYPE_TTY | INTR_MPSAFE, - scc_bfe_intr, NULL, sc, &ch->ch_icookie); - } - } - m = device_get_ivars(child); m->m_hasintr = 1; - /* - * XXX_FILTER this code doesn't take care of filters. - */ + m->ihf = filter; m->ih = ihand; m->ih_arg = arg;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200612132239.kBDMdp7Q080619>