[BACK]Return to satlink.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / isa

Annotation of src/sys/dev/isa/satlink.c, Revision 1.37

1.37    ! cegger      1: /*     $NetBSD: satlink.c,v 1.36 2008/03/01 14:16:50 rmind Exp $       */
1.4       thorpej     2:
1.1       hpeyerl     3: /*-
                      4:  * Copyright (c) 1997 The NetBSD Foundation, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Canada Connect Corp.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *     This product includes software developed by the NetBSD
                     21:  *     Foundation, Inc. and its contributors.
                     22:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     23:  *    contributors may be used to endorse or promote products derived
                     24:  *    from this software without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     27:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1.2       jtc        29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1.1       hpeyerl    31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     36:  * POSSIBILITY OF SUCH DAMAGE.
                     37:  */
                     38:
                     39: /*
                     40:  * Device driver for SatLink interface.
                     41:  *
                     42:  * This thing is really simple.  We essentially DMA into a ring buffer
                     43:  * which the user then reads from, and provide an ioctl interface to
                     44:  * reset the card, etc.
                     45:  */
1.14      lukem      46:
                     47: #include <sys/cdefs.h>
1.37    ! cegger     48: __KERNEL_RCSID(0, "$NetBSD: satlink.c,v 1.36 2008/03/01 14:16:50 rmind Exp $");
1.1       hpeyerl    49:
                     50: #include <sys/param.h>
                     51: #include <sys/systm.h>
1.9       thorpej    52: #include <sys/callout.h>
1.1       hpeyerl    53: #include <sys/errno.h>
                     54: #include <sys/ioctl.h>
                     55: #include <sys/device.h>
                     56: #include <sys/conf.h>
                     57: #include <sys/proc.h>
                     58: #include <sys/uio.h>
                     59: #include <sys/select.h>
                     60: #include <sys/poll.h>
                     61: #include <sys/kernel.h>
                     62: #include <sys/file.h>
                     63: #include <sys/tty.h>
                     64:
1.34      ad         65: #include <sys/cpu.h>
                     66: #include <sys/bus.h>
                     67: #include <sys/intr.h>
1.1       hpeyerl    68:
                     69: #include <dev/isa/isareg.h>
                     70: #include <dev/isa/isavar.h>
                     71: #include <dev/isa/isadmavar.h>
                     72:
                     73: #include <dev/isa/satlinkreg.h>
                     74: #include <dev/isa/satlinkio.h>
                     75:
                     76: struct satlink_softc {
                     77:        struct  device sc_dev;          /* device glue */
                     78:        bus_space_tag_t sc_iot;         /* space tag */
                     79:        bus_space_handle_t sc_ioh;      /* space handle */
1.6       thorpej    80:        isa_chipset_tag_t sc_ic;        /* ISA chipset info */
1.1       hpeyerl    81:        int     sc_drq;                 /* the DRQ we're using */
1.8       thorpej    82:        bus_size_t sc_bufsize;          /* DMA buffer size */
1.31      christos   83:        void *  sc_buf;                 /* ring buffer for incoming data */
1.1       hpeyerl    84:        int     sc_uptr;                /* user index into ring buffer */
                     85:        int     sc_sptr;                /* satlink index into ring buffer */
                     86:        int     sc_flags;               /* misc. flags. */
                     87:        int     sc_lastresid;           /* residual */
                     88:        struct selinfo sc_selq;         /* our select/poll queue */
                     89:        struct  satlink_id sc_id;       /* ID cached at attach time */
1.32      ad         90:        callout_t sc_ch;                /* callout pseudo-interrupt */
1.1       hpeyerl    91: };
                     92:
                     93: /* sc_flags */
                     94: #define        SATF_ISOPEN             0x01    /* device is open */
                     95: #define        SATF_DATA               0x02    /* waiting for data */
                     96:
                     97: /*
1.33      tsutsui    98:  * Our pseudo-interrupt.  Since up to 328 bytes can arrive in 1/100 of
1.1       hpeyerl    99:  * a second, this gives us 3280 bytes per timeout.
                    100:  */
1.8       thorpej   101: #define        SATLINK_TIMEOUT         (hz/10)
1.1       hpeyerl   102:
1.24      perry     103: int    satlinkprobe(struct device *, struct cfdata *, void *);
                    104: void   satlinkattach(struct device *, struct device *, void *);
                    105: void   satlinktimeout(void *);
1.1       hpeyerl   106:
1.18      thorpej   107: CFATTACH_DECL(satlink, sizeof(struct satlink_softc),
1.19      thorpej   108:     satlinkprobe, satlinkattach, NULL, NULL);
1.1       hpeyerl   109:
1.4       thorpej   110: extern struct cfdriver satlink_cd;
1.1       hpeyerl   111:
1.16      gehenna   112: dev_type_open(satlinkopen);
                    113: dev_type_close(satlinkclose);
                    114: dev_type_read(satlinkread);
                    115: dev_type_ioctl(satlinkioctl);
                    116: dev_type_poll(satlinkpoll);
1.20      jdolecek  117: dev_type_kqfilter(satlinkkqfilter);
1.16      gehenna   118:
                    119: const struct cdevsw satlink_cdevsw = {
                    120:        satlinkopen, satlinkclose, satlinkread, nowrite, satlinkioctl,
1.28      christos  121:        nostop, notty, satlinkpoll, nommap, satlinkkqfilter, D_OTHER,
1.16      gehenna   122: };
1.1       hpeyerl   123:
                    124: int
1.30      christos  125: satlinkprobe(struct device *parent, struct cfdata *match,
1.29      christos  126:     void *aux)
1.1       hpeyerl   127: {
                    128:        struct isa_attach_args *ia = aux;
                    129:        bus_space_tag_t iot = ia->ia_iot;
                    130:        bus_space_handle_t ioh;
                    131:        int rv = 0;
                    132:
1.15      thorpej   133:        if (ia->ia_nio < 1)
                    134:                return (0);
                    135:        if (ia->ia_ndrq < 1)
                    136:                return (0);
                    137:
                    138:        if (ISA_DIRECT_CONFIG(ia))
                    139:                return (0);
                    140:
1.1       hpeyerl   141:        /* Don't allow wildcarding of iobase or drq. */
1.23      drochner  142:        if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT)
1.1       hpeyerl   143:                return (0);
1.23      drochner  144:        if (ia->ia_drq[0].ir_drq == ISA_UNKNOWN_DRQ)
1.1       hpeyerl   145:                return (0);
                    146:
1.15      thorpej   147:        if (bus_space_map(iot, ia->ia_io[0].ir_addr, SATLINK_IOSIZE, 0, &ioh))
1.1       hpeyerl   148:                return (0);
                    149:
                    150:        /*
                    151:         * XXX Should check manufacturer ID here, or something.
                    152:         */
                    153:
                    154:        rv = 1;
1.15      thorpej   155:
                    156:        ia->ia_nio = 1;
                    157:        ia->ia_io[0].ir_size = SATLINK_IOSIZE;
                    158:
                    159:        ia->ia_ndrq = 1;
                    160:
                    161:        ia->ia_nirq = 0;
                    162:        ia->ia_niomem = 0;
1.1       hpeyerl   163:
                    164:        bus_space_unmap(iot, ioh, SATLINK_IOSIZE);
                    165:        return (rv);
                    166: }
                    167:
                    168: void
1.30      christos  169: satlinkattach(struct device *parent, struct device *self, void *aux)
1.1       hpeyerl   170: {
                    171:        struct satlink_softc *sc = (struct satlink_softc *)self;
                    172:        struct isa_attach_args *ia = aux;
                    173:        bus_space_tag_t iot = ia->ia_iot;
                    174:        bus_space_handle_t ioh;
                    175:        bus_addr_t ringaddr;
                    176:
                    177:        printf("\n");
                    178:
                    179:        /* Map the card. */
1.15      thorpej   180:        if (bus_space_map(iot, ia->ia_io[0].ir_addr, SATLINK_IOSIZE, 0, &ioh)) {
1.37    ! cegger    181:                aprint_error_dev(&sc->sc_dev, "can't map i/o space\n");
1.1       hpeyerl   182:                return;
                    183:        }
                    184:
                    185:        sc->sc_iot = iot;
                    186:        sc->sc_ioh = ioh;
1.6       thorpej   187:        sc->sc_ic = ia->ia_ic;
1.15      thorpej   188:        sc->sc_drq = ia->ia_drq[0].ir_drq;
1.1       hpeyerl   189:
                    190:        /* Reset the card. */
                    191:        bus_space_write_1(iot, ioh, SATLINK_COMMAND, SATLINK_CMD_RESET);
                    192:
                    193:        /* Read ID from the card. */
                    194:        sc->sc_id.sid_mfrid =
                    195:            bus_space_read_1(iot, ioh, SATLINK_MFRID_L) |
                    196:            (bus_space_read_1(iot, ioh, SATLINK_MFRID_H) << 8);
                    197:        sc->sc_id.sid_grpid = bus_space_read_1(iot, ioh, SATLINK_GRPID);
                    198:        sc->sc_id.sid_userid =
                    199:            bus_space_read_1(iot, ioh, SATLINK_USERID_L) |
                    200:            (bus_space_read_1(iot, ioh, SATLINK_USERID_H) << 8);
                    201:        sc->sc_id.sid_serial =
                    202:            bus_space_read_1(iot, ioh, SATLINK_SER_L) |
                    203:            (bus_space_read_1(iot, ioh, SATLINK_SER_M0) << 8) |
                    204:            (bus_space_read_1(iot, ioh, SATLINK_SER_M1) << 16) |
                    205:            (bus_space_read_1(iot, ioh, SATLINK_SER_H) << 24);
                    206:
                    207:        printf("%s: mfrid 0x%x, grpid 0x%x, userid 0x%x, serial %d\n",
1.37    ! cegger    208:            device_xname(&sc->sc_dev), sc->sc_id.sid_mfrid,
1.1       hpeyerl   209:            sc->sc_id.sid_grpid, sc->sc_id.sid_userid,
                    210:            sc->sc_id.sid_serial);
                    211:
1.32      ad        212:        callout_init(&sc->sc_ch, 0);
1.36      rmind     213:        selinit(&sc->sc_selq);
1.9       thorpej   214:
1.8       thorpej   215:        sc->sc_bufsize = isa_dmamaxsize(sc->sc_ic, sc->sc_drq);
                    216:
1.1       hpeyerl   217:        /* Allocate and map the ring buffer. */
1.8       thorpej   218:        if (isa_dmamem_alloc(sc->sc_ic, sc->sc_drq, sc->sc_bufsize,
1.1       hpeyerl   219:            &ringaddr, BUS_DMA_NOWAIT)) {
1.37    ! cegger    220:                aprint_error_dev(&sc->sc_dev, "can't allocate ring buffer\n");
1.1       hpeyerl   221:                return;
                    222:        }
1.8       thorpej   223:        if (isa_dmamem_map(sc->sc_ic, sc->sc_drq, ringaddr, sc->sc_bufsize,
1.5       thorpej   224:            &sc->sc_buf, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
1.37    ! cegger    225:                aprint_error_dev(&sc->sc_dev, "can't map ring buffer\n");
1.6       thorpej   226:                isa_dmamem_free(sc->sc_ic, sc->sc_drq, ringaddr,
1.8       thorpej   227:                    sc->sc_bufsize);
1.1       hpeyerl   228:                return;
                    229:        }
                    230:
1.22      fvdl      231:        if (isa_drq_alloc(sc->sc_ic, sc->sc_drq) != 0) {
1.37    ! cegger    232:                aprint_error_dev(&sc->sc_dev, "can't reserve drq %d\n",
        !           233:                    sc->sc_drq);
1.22      fvdl      234:                isa_dmamem_unmap(sc->sc_ic, sc->sc_drq, sc->sc_buf,
                    235:                    sc->sc_bufsize);
                    236:                isa_dmamem_free(sc->sc_ic, sc->sc_drq, ringaddr,
                    237:                    sc->sc_bufsize);
                    238:                return;
                    239:        }
                    240:
1.1       hpeyerl   241:        /* Create the DMA map. */
1.8       thorpej   242:        if (isa_dmamap_create(sc->sc_ic, sc->sc_drq, sc->sc_bufsize,
1.22      fvdl      243:            BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
1.37    ! cegger    244:                aprint_error_dev(&sc->sc_dev, "can't create DMA map\n");
1.6       thorpej   245:                isa_dmamem_unmap(sc->sc_ic, sc->sc_drq, sc->sc_buf,
1.8       thorpej   246:                    sc->sc_bufsize);
1.6       thorpej   247:                isa_dmamem_free(sc->sc_ic, sc->sc_drq, ringaddr,
1.8       thorpej   248:                    sc->sc_bufsize);
1.1       hpeyerl   249:                return;
                    250:        }
                    251: }
                    252:
                    253: int
1.30      christos  254: satlinkopen(dev_t dev, int flags, int fmt,
                    255:     struct lwp *l)
1.1       hpeyerl   256: {
                    257:        struct satlink_softc *sc;
1.11      thorpej   258:        int error;
1.1       hpeyerl   259:
1.11      thorpej   260:        sc = device_lookup(&satlink_cd, minor(dev));
                    261:        if (sc == NULL)
1.1       hpeyerl   262:                return (ENXIO);
                    263:
                    264:        if (sc->sc_flags & SATF_ISOPEN)
                    265:                return (EBUSY);
                    266:
                    267:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, SATLINK_COMMAND,
                    268:                    SATLINK_CMD_RESET);
                    269:
                    270:        /* Reset the ring buffer, and start the DMA loop. */
1.25      perry     271:        sc->sc_uptr = 0;
                    272:        sc->sc_sptr = 0;
1.8       thorpej   273:        sc->sc_lastresid = sc->sc_bufsize;
1.12      thorpej   274:        memset(sc->sc_buf, 0, sc->sc_bufsize);
1.6       thorpej   275:        error = isa_dmastart(sc->sc_ic, sc->sc_drq, sc->sc_buf,
1.8       thorpej   276:            sc->sc_bufsize, NULL, DMAMODE_READ|DMAMODE_LOOP, BUS_DMA_WAITOK);
1.1       hpeyerl   277:        if (error)
                    278:                return (error);
                    279:
                    280:        sc->sc_flags |= SATF_ISOPEN;
                    281:
1.9       thorpej   282:        callout_reset(&sc->sc_ch, SATLINK_TIMEOUT, satlinktimeout, sc);
1.1       hpeyerl   283:
                    284:        return (0);
                    285: }
                    286:
                    287: int
1.30      christos  288: satlinkclose(dev_t dev, int flags, int fmt,
                    289:     struct lwp *l)
1.1       hpeyerl   290: {
1.11      thorpej   291:        struct satlink_softc *sc = device_lookup(&satlink_cd, minor(dev));
1.1       hpeyerl   292:        int s;
                    293:
                    294:        s = splsoftclock();
                    295:        sc->sc_flags &= ~SATF_ISOPEN;
                    296:        splx(s);
                    297:
1.6       thorpej   298:        isa_dmaabort(sc->sc_ic, sc->sc_drq);
1.9       thorpej   299:        callout_stop(&sc->sc_ch);
1.1       hpeyerl   300:
                    301:        return (0);
                    302: }
                    303:
                    304: int
                    305: satlinkread(dev, uio, flags)
                    306:        dev_t dev;
                    307:        struct uio *uio;
                    308:        int flags;
                    309: {
1.11      thorpej   310:        struct satlink_softc *sc = device_lookup(&satlink_cd, minor(dev));
1.1       hpeyerl   311:        int error, s, count, sptr;
                    312:        int wrapcnt, oresid;
                    313:
                    314:        s = splsoftclock();
                    315:
                    316:        /* Wait for data to be available. */
                    317:        while (sc->sc_sptr == sc->sc_uptr) {
                    318:                if (flags & O_NONBLOCK) {
                    319:                        splx(s);
                    320:                        return (EWOULDBLOCK);
                    321:                }
                    322:                sc->sc_flags |= SATF_DATA;
                    323:                if ((error = tsleep(sc, TTIPRI | PCATCH, "satio", 0)) != 0) {
                    324:                        splx(s);
                    325:                        return (error);
                    326:                }
                    327:        }
                    328:
                    329:        sptr = sc->sc_sptr;
                    330:        splx(s);
                    331:
                    332:        /* Compute number of readable bytes. */
                    333:        if (sptr > sc->sc_uptr)
                    334:                count = sptr - sc->sc_uptr;
                    335:        else
1.8       thorpej   336:                count = sc->sc_bufsize - sc->sc_uptr + sptr;
1.1       hpeyerl   337:
                    338:        if (count > uio->uio_resid)
                    339:                count = uio->uio_resid;
                    340:
                    341:        /* Send data out to user. */
                    342:        if (sptr > sc->sc_uptr) {
                    343:                /*
                    344:                 * Easy case - no wrap-around.
                    345:                 */
1.31      christos  346:                error = uiomove((char *)sc->sc_buf + sc->sc_uptr, count, uio);
1.1       hpeyerl   347:                if (error == 0) {
                    348:                        sc->sc_uptr += count;
1.8       thorpej   349:                        if (sc->sc_uptr == sc->sc_bufsize)
1.1       hpeyerl   350:                                sc->sc_uptr = 0;
                    351:                }
                    352:                return (error);
                    353:        }
                    354:
                    355:        /*
                    356:         * We wrap around.  Copy to the end of the ring...
                    357:         */
1.8       thorpej   358:        wrapcnt = sc->sc_bufsize - sc->sc_uptr;
1.1       hpeyerl   359:        oresid = uio->uio_resid;
                    360:        if (wrapcnt > uio->uio_resid)
                    361:                wrapcnt = uio->uio_resid;
1.31      christos  362:        error = uiomove((char *)sc->sc_buf + sc->sc_uptr, wrapcnt, uio);
1.1       hpeyerl   363:        sc->sc_uptr = 0;
                    364:        if (error != 0 || wrapcnt == oresid)
                    365:                return (error);
                    366:
                    367:        /* ...and the rest. */
                    368:        count -= wrapcnt;
                    369:        error = uiomove(sc->sc_buf, count, uio);
                    370:        sc->sc_uptr += count;
1.8       thorpej   371:        if (sc->sc_uptr == sc->sc_bufsize)
1.1       hpeyerl   372:                sc->sc_uptr = 0;
                    373:
                    374:        return (error);
                    375: }
                    376:
                    377: int
1.31      christos  378: satlinkioctl(dev_t dev, u_long cmd, void *data, int flags,
1.30      christos  379:     struct lwp *l)
1.1       hpeyerl   380: {
1.11      thorpej   381:        struct satlink_softc *sc = device_lookup(&satlink_cd, minor(dev));
1.1       hpeyerl   382:
                    383:        switch (cmd) {
                    384:        case SATIORESET:
                    385:                bus_space_write_1(sc->sc_iot, sc->sc_ioh, SATLINK_COMMAND,
                    386:                    SATLINK_CMD_RESET);
1.6       thorpej   387:                sc->sc_uptr = isa_dmacount(sc->sc_ic, sc->sc_drq);
1.1       hpeyerl   388:                sc->sc_sptr = sc->sc_uptr;
                    389:                break;
                    390:
                    391:        case SATIOGID:
1.13      thorpej   392:                memcpy(data, &sc->sc_id, sizeof(sc->sc_id));
1.1       hpeyerl   393:                break;
                    394:
                    395:        default:
                    396:                return (ENOTTY);
                    397:        }
                    398:
                    399:        return (0);
                    400: }
                    401:
                    402: int
1.27      christos  403: satlinkpoll(dev, events, l)
1.1       hpeyerl   404:        dev_t dev;
                    405:        int events;
1.27      christos  406:        struct lwp *l;
1.1       hpeyerl   407: {
1.11      thorpej   408:        struct satlink_softc *sc = device_lookup(&satlink_cd, minor(dev));
1.1       hpeyerl   409:        int s, revents;
                    410:
                    411:        revents = events & (POLLOUT | POLLWRNORM);
                    412:
                    413:        /* Attempt to save some work. */
                    414:        if ((events & (POLLIN | POLLRDNORM)) == 0)
                    415:                return (revents);
                    416:
                    417:        /* We're timeout-driven, so must block the clock. */
                    418:        s = splsoftclock();
                    419:        if (sc->sc_uptr != sc->sc_sptr)
                    420:                revents |= events & (POLLIN | POLLRDNORM);
                    421:        else
1.27      christos  422:                selrecord(l, &sc->sc_selq);
1.1       hpeyerl   423:        splx(s);
                    424:
                    425:        return (revents);
                    426: }
                    427:
1.20      jdolecek  428: static void
                    429: filt_satlinkrdetach(struct knote *kn)
                    430: {
                    431:        struct satlink_softc *sc = kn->kn_hook;
                    432:        int s;
                    433:
                    434:        s = splsoftclock();
1.21      christos  435:        SLIST_REMOVE(&sc->sc_selq.sel_klist, kn, knote, kn_selnext);
1.20      jdolecek  436:        splx(s);
                    437: }
                    438:
                    439: static int
1.30      christos  440: filt_satlinkread(struct knote *kn, long hint)
1.20      jdolecek  441: {
                    442:        struct satlink_softc *sc = kn->kn_hook;
                    443:
                    444:        if (sc->sc_uptr == sc->sc_sptr)
                    445:                return (0);
                    446:
                    447:        if (sc->sc_sptr > sc->sc_uptr)
                    448:                kn->kn_data = sc->sc_sptr - sc->sc_uptr;
                    449:        else
                    450:                kn->kn_data = (sc->sc_bufsize - sc->sc_uptr) +
                    451:                    sc->sc_sptr;
                    452:        return (1);
                    453: }
                    454:
                    455: static const struct filterops satlinkread_filtops =
                    456:        { 1, NULL, filt_satlinkrdetach, filt_satlinkread };
                    457:
                    458: static const struct filterops satlink_seltrue_filtops =
                    459:        { 1, NULL, filt_satlinkrdetach, filt_seltrue };
                    460:
                    461: int
                    462: satlinkkqfilter(dev_t dev, struct knote *kn)
                    463: {
                    464:        struct satlink_softc *sc = device_lookup(&satlink_cd, minor(dev));
                    465:        struct klist *klist;
                    466:        int s;
                    467:
                    468:        switch (kn->kn_filter) {
                    469:        case EVFILT_READ:
1.21      christos  470:                klist = &sc->sc_selq.sel_klist;
1.20      jdolecek  471:                kn->kn_fop = &satlinkread_filtops;
                    472:                break;
                    473:
                    474:        case EVFILT_WRITE:
1.21      christos  475:                klist = &sc->sc_selq.sel_klist;
1.20      jdolecek  476:                kn->kn_fop = &satlink_seltrue_filtops;
                    477:                break;
                    478:
                    479:        default:
1.35      pooka     480:                return (EINVAL);
1.20      jdolecek  481:        }
                    482:
                    483:        kn->kn_hook = sc;
                    484:
                    485:        s = splsoftclock();
                    486:        SLIST_INSERT_HEAD(klist, kn, kn_selnext);
                    487:        splx(s);
                    488:
                    489:        return (0);
                    490: }
                    491:
1.1       hpeyerl   492: void
                    493: satlinktimeout(arg)
                    494:        void *arg;
                    495: {
                    496:        struct satlink_softc *sc = arg;
                    497:        bus_size_t resid;
                    498:        int newidx;
                    499:
                    500:        if ((sc->sc_flags & SATF_ISOPEN) == 0)
                    501:                return;
                    502:
                    503:        /*
                    504:         * Get the current residual count from the DMA controller
                    505:         * and compute the satlink's index into the ring buffer.
                    506:         */
1.6       thorpej   507:        resid = isa_dmacount(sc->sc_ic, sc->sc_drq);
1.8       thorpej   508:        newidx = sc->sc_bufsize - resid;
                    509:        if (newidx == sc->sc_bufsize)
1.1       hpeyerl   510:                newidx = 0;
                    511:
                    512:        if (newidx == sc->sc_sptr)
                    513:                goto out;
                    514:
                    515:        sc->sc_sptr = newidx;
                    516:
                    517:        /* Wake up anyone blocked in read... */
                    518:        if (sc->sc_flags & SATF_DATA) {
                    519:                sc->sc_flags &= ~SATF_DATA;
                    520:                wakeup(sc);
                    521:        }
                    522:
                    523:        /* Wake up anyone blocked in poll... */
1.36      rmind     524:        selnotify(&sc->sc_selq, 0, 0);
1.1       hpeyerl   525:
                    526:  out:
1.9       thorpej   527:        callout_reset(&sc->sc_ch, SATLINK_TIMEOUT, satlinktimeout, sc);
1.1       hpeyerl   528: }

CVSweb <webmaster@jp.NetBSD.org>