[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.26.10.1

1.26.10.1! elad        1: /*     $NetBSD: satlink.c,v 1.27 2006/04/23 00:11:11 christos 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.26.10.1! elad       48: __KERNEL_RCSID(0, "$NetBSD: satlink.c,v 1.27 2006/04/23 00:11:11 christos 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:
                     65: #include <machine/cpu.h>
                     66: #include <machine/bus.h>
                     67: #include <machine/intr.h>
                     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.1       hpeyerl    83:        caddr_t sc_buf;                 /* ring buffer for incoming data */
                     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.9       thorpej    90:        struct callout 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: /*
                     98:  * Our pesudo-interrupt.  Since up to 328 bytes can arrive in 1/100 of
                     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.20      jdolecek  121:        nostop, notty, satlinkpoll, nommap, satlinkkqfilter,
1.16      gehenna   122: };
1.1       hpeyerl   123:
                    124: int
                    125: satlinkprobe(parent, match, aux)
                    126:        struct device *parent;
                    127:        struct cfdata *match;
                    128:        void *aux;
                    129: {
                    130:        struct isa_attach_args *ia = aux;
                    131:        bus_space_tag_t iot = ia->ia_iot;
                    132:        bus_space_handle_t ioh;
                    133:        int rv = 0;
                    134:
1.15      thorpej   135:        if (ia->ia_nio < 1)
                    136:                return (0);
                    137:        if (ia->ia_ndrq < 1)
                    138:                return (0);
                    139:
                    140:        if (ISA_DIRECT_CONFIG(ia))
                    141:                return (0);
                    142:
1.1       hpeyerl   143:        /* Don't allow wildcarding of iobase or drq. */
1.23      drochner  144:        if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT)
1.1       hpeyerl   145:                return (0);
1.23      drochner  146:        if (ia->ia_drq[0].ir_drq == ISA_UNKNOWN_DRQ)
1.1       hpeyerl   147:                return (0);
                    148:
1.15      thorpej   149:        if (bus_space_map(iot, ia->ia_io[0].ir_addr, SATLINK_IOSIZE, 0, &ioh))
1.1       hpeyerl   150:                return (0);
                    151:
                    152:        /*
                    153:         * XXX Should check manufacturer ID here, or something.
                    154:         */
                    155:
                    156:        rv = 1;
1.15      thorpej   157:
                    158:        ia->ia_nio = 1;
                    159:        ia->ia_io[0].ir_size = SATLINK_IOSIZE;
                    160:
                    161:        ia->ia_ndrq = 1;
                    162:
                    163:        ia->ia_nirq = 0;
                    164:        ia->ia_niomem = 0;
1.1       hpeyerl   165:
                    166:        bus_space_unmap(iot, ioh, SATLINK_IOSIZE);
                    167:        return (rv);
                    168: }
                    169:
                    170: void
                    171: satlinkattach(parent, self, aux)
                    172:        struct device *parent, *self;
                    173:        void *aux;
                    174: {
                    175:        struct satlink_softc *sc = (struct satlink_softc *)self;
                    176:        struct isa_attach_args *ia = aux;
                    177:        bus_space_tag_t iot = ia->ia_iot;
                    178:        bus_space_handle_t ioh;
                    179:        bus_addr_t ringaddr;
                    180:
                    181:        printf("\n");
                    182:
                    183:        /* Map the card. */
1.15      thorpej   184:        if (bus_space_map(iot, ia->ia_io[0].ir_addr, SATLINK_IOSIZE, 0, &ioh)) {
1.1       hpeyerl   185:                printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname);
                    186:                return;
                    187:        }
                    188:
                    189:        sc->sc_iot = iot;
                    190:        sc->sc_ioh = ioh;
1.6       thorpej   191:        sc->sc_ic = ia->ia_ic;
1.15      thorpej   192:        sc->sc_drq = ia->ia_drq[0].ir_drq;
1.1       hpeyerl   193:
                    194:        /* Reset the card. */
                    195:        bus_space_write_1(iot, ioh, SATLINK_COMMAND, SATLINK_CMD_RESET);
                    196:
                    197:        /* Read ID from the card. */
                    198:        sc->sc_id.sid_mfrid =
                    199:            bus_space_read_1(iot, ioh, SATLINK_MFRID_L) |
                    200:            (bus_space_read_1(iot, ioh, SATLINK_MFRID_H) << 8);
                    201:        sc->sc_id.sid_grpid = bus_space_read_1(iot, ioh, SATLINK_GRPID);
                    202:        sc->sc_id.sid_userid =
                    203:            bus_space_read_1(iot, ioh, SATLINK_USERID_L) |
                    204:            (bus_space_read_1(iot, ioh, SATLINK_USERID_H) << 8);
                    205:        sc->sc_id.sid_serial =
                    206:            bus_space_read_1(iot, ioh, SATLINK_SER_L) |
                    207:            (bus_space_read_1(iot, ioh, SATLINK_SER_M0) << 8) |
                    208:            (bus_space_read_1(iot, ioh, SATLINK_SER_M1) << 16) |
                    209:            (bus_space_read_1(iot, ioh, SATLINK_SER_H) << 24);
                    210:
                    211:        printf("%s: mfrid 0x%x, grpid 0x%x, userid 0x%x, serial %d\n",
                    212:            sc->sc_dev.dv_xname, sc->sc_id.sid_mfrid,
                    213:            sc->sc_id.sid_grpid, sc->sc_id.sid_userid,
                    214:            sc->sc_id.sid_serial);
                    215:
1.10      thorpej   216:        callout_init(&sc->sc_ch);
1.9       thorpej   217:
1.8       thorpej   218:        sc->sc_bufsize = isa_dmamaxsize(sc->sc_ic, sc->sc_drq);
                    219:
1.1       hpeyerl   220:        /* Allocate and map the ring buffer. */
1.8       thorpej   221:        if (isa_dmamem_alloc(sc->sc_ic, sc->sc_drq, sc->sc_bufsize,
1.1       hpeyerl   222:            &ringaddr, BUS_DMA_NOWAIT)) {
                    223:                printf("%s: can't allocate ring buffer\n",
                    224:                    sc->sc_dev.dv_xname);
                    225:                return;
                    226:        }
1.8       thorpej   227:        if (isa_dmamem_map(sc->sc_ic, sc->sc_drq, ringaddr, sc->sc_bufsize,
1.5       thorpej   228:            &sc->sc_buf, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
1.1       hpeyerl   229:                printf("%s: can't map ring buffer\n", sc->sc_dev.dv_xname);
1.6       thorpej   230:                isa_dmamem_free(sc->sc_ic, sc->sc_drq, ringaddr,
1.8       thorpej   231:                    sc->sc_bufsize);
1.1       hpeyerl   232:                return;
                    233:        }
                    234:
1.22      fvdl      235:        if (isa_drq_alloc(sc->sc_ic, sc->sc_drq) != 0) {
                    236:                printf("%s: can't reserve drq %d\n",
                    237:                    sc->sc_dev.dv_xname, sc->sc_drq);
                    238:                isa_dmamem_unmap(sc->sc_ic, sc->sc_drq, sc->sc_buf,
                    239:                    sc->sc_bufsize);
                    240:                isa_dmamem_free(sc->sc_ic, sc->sc_drq, ringaddr,
                    241:                    sc->sc_bufsize);
                    242:                return;
                    243:        }
                    244:
1.1       hpeyerl   245:        /* Create the DMA map. */
1.8       thorpej   246:        if (isa_dmamap_create(sc->sc_ic, sc->sc_drq, sc->sc_bufsize,
1.22      fvdl      247:            BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
1.1       hpeyerl   248:                printf("%s: can't create DMA map\n", sc->sc_dev.dv_xname);
1.6       thorpej   249:                isa_dmamem_unmap(sc->sc_ic, sc->sc_drq, sc->sc_buf,
1.8       thorpej   250:                    sc->sc_bufsize);
1.6       thorpej   251:                isa_dmamem_free(sc->sc_ic, sc->sc_drq, ringaddr,
1.8       thorpej   252:                    sc->sc_bufsize);
1.1       hpeyerl   253:                return;
                    254:        }
                    255: }
                    256:
                    257: int
1.26.10.1! elad      258: satlinkopen(dev, flags, fmt, l)
1.1       hpeyerl   259:        dev_t dev;
                    260:        int flags, fmt;
1.26.10.1! elad      261:        struct lwp *l;
1.1       hpeyerl   262: {
                    263:        struct satlink_softc *sc;
1.11      thorpej   264:        int error;
1.1       hpeyerl   265:
1.11      thorpej   266:        sc = device_lookup(&satlink_cd, minor(dev));
                    267:        if (sc == NULL)
1.1       hpeyerl   268:                return (ENXIO);
                    269:
                    270:        if (sc->sc_flags & SATF_ISOPEN)
                    271:                return (EBUSY);
                    272:
                    273:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, SATLINK_COMMAND,
                    274:                    SATLINK_CMD_RESET);
                    275:
                    276:        /* Reset the ring buffer, and start the DMA loop. */
1.25      perry     277:        sc->sc_uptr = 0;
                    278:        sc->sc_sptr = 0;
1.8       thorpej   279:        sc->sc_lastresid = sc->sc_bufsize;
1.12      thorpej   280:        memset(sc->sc_buf, 0, sc->sc_bufsize);
1.6       thorpej   281:        error = isa_dmastart(sc->sc_ic, sc->sc_drq, sc->sc_buf,
1.8       thorpej   282:            sc->sc_bufsize, NULL, DMAMODE_READ|DMAMODE_LOOP, BUS_DMA_WAITOK);
1.1       hpeyerl   283:        if (error)
                    284:                return (error);
                    285:
                    286:        sc->sc_flags |= SATF_ISOPEN;
                    287:
1.9       thorpej   288:        callout_reset(&sc->sc_ch, SATLINK_TIMEOUT, satlinktimeout, sc);
1.1       hpeyerl   289:
                    290:        return (0);
                    291: }
                    292:
                    293: int
1.26.10.1! elad      294: satlinkclose(dev, flags, fmt, l)
1.1       hpeyerl   295:        dev_t dev;
                    296:        int flags, fmt;
1.26.10.1! elad      297:        struct lwp *l;
1.1       hpeyerl   298: {
1.11      thorpej   299:        struct satlink_softc *sc = device_lookup(&satlink_cd, minor(dev));
1.1       hpeyerl   300:        int s;
                    301:
                    302:        s = splsoftclock();
                    303:        sc->sc_flags &= ~SATF_ISOPEN;
                    304:        splx(s);
                    305:
1.6       thorpej   306:        isa_dmaabort(sc->sc_ic, sc->sc_drq);
1.9       thorpej   307:        callout_stop(&sc->sc_ch);
1.1       hpeyerl   308:
                    309:        return (0);
                    310: }
                    311:
                    312: int
                    313: satlinkread(dev, uio, flags)
                    314:        dev_t dev;
                    315:        struct uio *uio;
                    316:        int flags;
                    317: {
1.11      thorpej   318:        struct satlink_softc *sc = device_lookup(&satlink_cd, minor(dev));
1.1       hpeyerl   319:        int error, s, count, sptr;
                    320:        int wrapcnt, oresid;
                    321:
                    322:        s = splsoftclock();
                    323:
                    324:        /* Wait for data to be available. */
                    325:        while (sc->sc_sptr == sc->sc_uptr) {
                    326:                if (flags & O_NONBLOCK) {
                    327:                        splx(s);
                    328:                        return (EWOULDBLOCK);
                    329:                }
                    330:                sc->sc_flags |= SATF_DATA;
                    331:                if ((error = tsleep(sc, TTIPRI | PCATCH, "satio", 0)) != 0) {
                    332:                        splx(s);
                    333:                        return (error);
                    334:                }
                    335:        }
                    336:
                    337:        sptr = sc->sc_sptr;
                    338:        splx(s);
                    339:
                    340:        /* Compute number of readable bytes. */
                    341:        if (sptr > sc->sc_uptr)
                    342:                count = sptr - sc->sc_uptr;
                    343:        else
1.8       thorpej   344:                count = sc->sc_bufsize - sc->sc_uptr + sptr;
1.1       hpeyerl   345:
                    346:        if (count > uio->uio_resid)
                    347:                count = uio->uio_resid;
                    348:
                    349:        /* Send data out to user. */
                    350:        if (sptr > sc->sc_uptr) {
                    351:                /*
                    352:                 * Easy case - no wrap-around.
                    353:                 */
                    354:                error = uiomove(&sc->sc_buf[sc->sc_uptr], count, uio);
                    355:                if (error == 0) {
                    356:                        sc->sc_uptr += count;
1.8       thorpej   357:                        if (sc->sc_uptr == sc->sc_bufsize)
1.1       hpeyerl   358:                                sc->sc_uptr = 0;
                    359:                }
                    360:                return (error);
                    361:        }
                    362:
                    363:        /*
                    364:         * We wrap around.  Copy to the end of the ring...
                    365:         */
1.8       thorpej   366:        wrapcnt = sc->sc_bufsize - sc->sc_uptr;
1.1       hpeyerl   367:        oresid = uio->uio_resid;
                    368:        if (wrapcnt > uio->uio_resid)
                    369:                wrapcnt = uio->uio_resid;
                    370:        error = uiomove(&sc->sc_buf[sc->sc_uptr], wrapcnt, uio);
                    371:        sc->sc_uptr = 0;
                    372:        if (error != 0 || wrapcnt == oresid)
                    373:                return (error);
                    374:
                    375:        /* ...and the rest. */
                    376:        count -= wrapcnt;
                    377:        error = uiomove(sc->sc_buf, count, uio);
                    378:        sc->sc_uptr += count;
1.8       thorpej   379:        if (sc->sc_uptr == sc->sc_bufsize)
1.1       hpeyerl   380:                sc->sc_uptr = 0;
                    381:
                    382:        return (error);
                    383: }
                    384:
                    385: int
1.26.10.1! elad      386: satlinkioctl(dev, cmd, data, flags, l)
1.1       hpeyerl   387:        dev_t dev;
                    388:        u_long cmd;
                    389:        caddr_t data;
                    390:        int flags;
1.26.10.1! elad      391:        struct lwp *l;
1.1       hpeyerl   392: {
1.11      thorpej   393:        struct satlink_softc *sc = device_lookup(&satlink_cd, minor(dev));
1.1       hpeyerl   394:
                    395:        switch (cmd) {
                    396:        case SATIORESET:
                    397:                bus_space_write_1(sc->sc_iot, sc->sc_ioh, SATLINK_COMMAND,
                    398:                    SATLINK_CMD_RESET);
1.6       thorpej   399:                sc->sc_uptr = isa_dmacount(sc->sc_ic, sc->sc_drq);
1.1       hpeyerl   400:                sc->sc_sptr = sc->sc_uptr;
                    401:                break;
                    402:
                    403:        case SATIOGID:
1.13      thorpej   404:                memcpy(data, &sc->sc_id, sizeof(sc->sc_id));
1.1       hpeyerl   405:                break;
                    406:
                    407:        default:
                    408:                return (ENOTTY);
                    409:        }
                    410:
                    411:        return (0);
                    412: }
                    413:
                    414: int
1.26.10.1! elad      415: satlinkpoll(dev, events, l)
1.1       hpeyerl   416:        dev_t dev;
                    417:        int events;
1.26.10.1! elad      418:        struct lwp *l;
1.1       hpeyerl   419: {
1.11      thorpej   420:        struct satlink_softc *sc = device_lookup(&satlink_cd, minor(dev));
1.1       hpeyerl   421:        int s, revents;
                    422:
                    423:        revents = events & (POLLOUT | POLLWRNORM);
                    424:
                    425:        /* Attempt to save some work. */
                    426:        if ((events & (POLLIN | POLLRDNORM)) == 0)
                    427:                return (revents);
                    428:
                    429:        /* We're timeout-driven, so must block the clock. */
                    430:        s = splsoftclock();
                    431:        if (sc->sc_uptr != sc->sc_sptr)
                    432:                revents |= events & (POLLIN | POLLRDNORM);
                    433:        else
1.26.10.1! elad      434:                selrecord(l, &sc->sc_selq);
1.1       hpeyerl   435:        splx(s);
                    436:
                    437:        return (revents);
                    438: }
                    439:
1.20      jdolecek  440: static void
                    441: filt_satlinkrdetach(struct knote *kn)
                    442: {
                    443:        struct satlink_softc *sc = kn->kn_hook;
                    444:        int s;
                    445:
                    446:        s = splsoftclock();
1.21      christos  447:        SLIST_REMOVE(&sc->sc_selq.sel_klist, kn, knote, kn_selnext);
1.20      jdolecek  448:        splx(s);
                    449: }
                    450:
                    451: static int
                    452: filt_satlinkread(struct knote *kn, long hint)
                    453: {
                    454:        struct satlink_softc *sc = kn->kn_hook;
                    455:
                    456:        if (sc->sc_uptr == sc->sc_sptr)
                    457:                return (0);
                    458:
                    459:        if (sc->sc_sptr > sc->sc_uptr)
                    460:                kn->kn_data = sc->sc_sptr - sc->sc_uptr;
                    461:        else
                    462:                kn->kn_data = (sc->sc_bufsize - sc->sc_uptr) +
                    463:                    sc->sc_sptr;
                    464:        return (1);
                    465: }
                    466:
                    467: static const struct filterops satlinkread_filtops =
                    468:        { 1, NULL, filt_satlinkrdetach, filt_satlinkread };
                    469:
                    470: static const struct filterops satlink_seltrue_filtops =
                    471:        { 1, NULL, filt_satlinkrdetach, filt_seltrue };
                    472:
                    473: int
                    474: satlinkkqfilter(dev_t dev, struct knote *kn)
                    475: {
                    476:        struct satlink_softc *sc = device_lookup(&satlink_cd, minor(dev));
                    477:        struct klist *klist;
                    478:        int s;
                    479:
                    480:        switch (kn->kn_filter) {
                    481:        case EVFILT_READ:
1.21      christos  482:                klist = &sc->sc_selq.sel_klist;
1.20      jdolecek  483:                kn->kn_fop = &satlinkread_filtops;
                    484:                break;
                    485:
                    486:        case EVFILT_WRITE:
1.21      christos  487:                klist = &sc->sc_selq.sel_klist;
1.20      jdolecek  488:                kn->kn_fop = &satlink_seltrue_filtops;
                    489:                break;
                    490:
                    491:        default:
                    492:                return (1);
                    493:        }
                    494:
                    495:        kn->kn_hook = sc;
                    496:
                    497:        s = splsoftclock();
                    498:        SLIST_INSERT_HEAD(klist, kn, kn_selnext);
                    499:        splx(s);
                    500:
                    501:        return (0);
                    502: }
                    503:
1.1       hpeyerl   504: void
                    505: satlinktimeout(arg)
                    506:        void *arg;
                    507: {
                    508:        struct satlink_softc *sc = arg;
                    509:        bus_size_t resid;
                    510:        int newidx;
                    511:
                    512:        if ((sc->sc_flags & SATF_ISOPEN) == 0)
                    513:                return;
                    514:
                    515:        /*
                    516:         * Get the current residual count from the DMA controller
                    517:         * and compute the satlink's index into the ring buffer.
                    518:         */
1.6       thorpej   519:        resid = isa_dmacount(sc->sc_ic, sc->sc_drq);
1.8       thorpej   520:        newidx = sc->sc_bufsize - resid;
                    521:        if (newidx == sc->sc_bufsize)
1.1       hpeyerl   522:                newidx = 0;
                    523:
                    524:        if (newidx == sc->sc_sptr)
                    525:                goto out;
                    526:
                    527:        sc->sc_sptr = newidx;
                    528:
                    529:        /* Wake up anyone blocked in read... */
                    530:        if (sc->sc_flags & SATF_DATA) {
                    531:                sc->sc_flags &= ~SATF_DATA;
                    532:                wakeup(sc);
                    533:        }
                    534:
                    535:        /* Wake up anyone blocked in poll... */
1.20      jdolecek  536:        selnotify(&sc->sc_selq, 0);
1.1       hpeyerl   537:
                    538:  out:
1.9       thorpej   539:        callout_reset(&sc->sc_ch, SATLINK_TIMEOUT, satlinktimeout, sc);
1.1       hpeyerl   540: }

CVSweb <webmaster@jp.NetBSD.org>