The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/sbus/bpp.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: bpp.c,v 1.22 2004/03/17 17:04:58 pk Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 1998 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Paul Kranenburg.
    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
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   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 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: bpp.c,v 1.22 2004/03/17 17:04:58 pk Exp $");
   41 
   42 #include <sys/param.h>
   43 #include <sys/ioctl.h>
   44 #include <sys/fcntl.h>
   45 #include <sys/systm.h>
   46 #include <sys/kernel.h>
   47 #include <sys/vnode.h>
   48 #include <sys/poll.h>
   49 #include <sys/select.h>
   50 #include <sys/malloc.h>
   51 #include <sys/proc.h>
   52 #include <sys/signalvar.h>
   53 #include <sys/conf.h>
   54 #include <sys/errno.h>
   55 #include <sys/device.h>
   56 
   57 #include <machine/bus.h>
   58 #include <machine/intr.h>
   59 #include <machine/autoconf.h>
   60 
   61 #include <dev/ic/lsi64854reg.h>
   62 #include <dev/ic/lsi64854var.h>
   63 
   64 #include <dev/sbus/sbusvar.h>
   65 #include <dev/sbus/bppreg.h>
   66 
   67 #define splbpp()        spltty()        /* XXX */
   68 
   69 #ifdef DEBUG
   70 #define DPRINTF(x) do { if (bppdebug) printf x ; } while (0)
   71 int bppdebug = 1;
   72 #else
   73 #define DPRINTF(x)
   74 #endif
   75 
   76 #if 0
   77 struct bpp_param {
   78         int     bpp_dss;                /* data setup to strobe */
   79         int     bpp_dsw;                /* data strobe width */
   80         int     bpp_outputpins;         /* Select/Autofeed/Init pins */
   81         int     bpp_inputpins;          /* Error/Select/Paperout pins */
   82 };
   83 #endif
   84 
   85 struct hwstate {
   86         u_int16_t       hw_hcr;         /* Hardware config register */
   87         u_int16_t       hw_ocr;         /* Operation config register */
   88         u_int8_t        hw_tcr;         /* Transfer Control register */
   89         u_int8_t        hw_or;          /* Output register */
   90         u_int16_t       hw_irq;         /* IRQ; polarity bits only */
   91 };
   92 
   93 struct bpp_softc {
   94         struct lsi64854_softc   sc_lsi64854;    /* base device */
   95         struct sbusdev  sc_sd;                  /* sbus device */
   96 
   97         size_t          sc_bufsz;               /* temp buffer */
   98         caddr_t         sc_buf;
   99 
  100         int             sc_error;               /* bottom-half error */
  101         int             sc_flags;
  102 #define BPP_OPEN        0x01            /* Device is open */
  103 #define BPP_XCLUDE      0x02            /* Exclusive-open mode */
  104 #define BPP_ASYNC       0x04            /* Asynchronous I/O mode */
  105 #define BPP_LOCKED      0x08            /* DMA in progress */
  106 #define BPP_WANT        0x10            /* Waiting for DMA */
  107 
  108         struct selinfo  sc_rsel;
  109         struct selinfo  sc_wsel;
  110         struct proc     *sc_asyncproc;  /* Process to notify if async */
  111 
  112         /* Hardware state */
  113         struct hwstate          sc_hwdefault;
  114         struct hwstate          sc_hwcurrent;
  115 };
  116 
  117 static int      bppmatch        __P((struct device *, struct cfdata *, void *));
  118 static void     bppattach       __P((struct device *, struct device *, void *));
  119 static int      bppintr         __P((void *));
  120 static void     bpp_setparams   __P((struct bpp_softc *, struct hwstate *));
  121 
  122 CFATTACH_DECL(bpp, sizeof(struct bpp_softc),
  123     bppmatch, bppattach, NULL, NULL);
  124 
  125 extern struct cfdriver bpp_cd;
  126 
  127 dev_type_open(bppopen);
  128 dev_type_close(bppclose);
  129 dev_type_write(bppwrite);
  130 dev_type_ioctl(bppioctl);
  131 dev_type_poll(bpppoll);
  132 dev_type_kqfilter(bppkqfilter);
  133 
  134 const struct cdevsw bpp_cdevsw = {
  135         bppopen, bppclose, noread, bppwrite, bppioctl,
  136         nostop, notty, bpppoll, nommap, bppkqfilter,
  137 };
  138 
  139 #define BPPUNIT(dev)    (minor(dev))
  140 
  141 
  142 int
  143 bppmatch(parent, cf, aux)
  144         struct device *parent;
  145         struct cfdata *cf;
  146         void *aux;
  147 {
  148         struct sbus_attach_args *sa = aux;
  149 
  150         return (strcmp("SUNW,bpp", sa->sa_name) == 0);
  151 }
  152 
  153 void
  154 bppattach(parent, self, aux)
  155         struct device *parent, *self;
  156         void *aux;
  157 {
  158         struct sbus_attach_args *sa = aux;
  159         struct bpp_softc *dsc = (void *)self;
  160         struct lsi64854_softc *sc = &dsc->sc_lsi64854;
  161         int burst, sbusburst;
  162         int node;
  163 
  164         sc->sc_bustag = sa->sa_bustag;
  165         sc->sc_dmatag = sa->sa_dmatag;
  166         node = sa->sa_node;
  167 
  168         /* Map device registers */
  169         if (sbus_bus_map(sa->sa_bustag,
  170                          sa->sa_slot, sa->sa_offset, sa->sa_size,
  171                          0, &sc->sc_regs) != 0) {
  172                 printf("%s: cannot map registers\n", self->dv_xname);
  173                 return;
  174         }
  175 
  176         /*
  177          * Get transfer burst size from PROM and plug it into the
  178          * controller registers. This is needed on the Sun4m; do
  179          * others need it too?
  180          */
  181         sbusburst = ((struct sbus_softc *)parent)->sc_burst;
  182         if (sbusburst == 0)
  183                 sbusburst = SBUS_BURST_32 - 1; /* 1->16 */
  184 
  185         burst = prom_getpropint(node, "burst-sizes", -1);
  186         if (burst == -1)
  187                 /* take SBus burst sizes */
  188                 burst = sbusburst;
  189 
  190         /* Clamp at parent's burst sizes */
  191         burst &= sbusburst;
  192         sc->sc_burst = (burst & SBUS_BURST_32) ? 32 :
  193                        (burst & SBUS_BURST_16) ? 16 : 0;
  194 
  195         /* Join the Sbus device family */
  196         dsc->sc_sd.sd_reset = (void *)0;
  197         sbus_establish(&dsc->sc_sd, self);
  198 
  199         /* Initialize the DMA channel */
  200         sc->sc_channel = L64854_CHANNEL_PP;
  201         lsi64854_attach(sc);
  202 
  203         /* Establish interrupt handler */
  204         if (sa->sa_nintr) {
  205                 sc->sc_intrchain = bppintr;
  206                 sc->sc_intrchainarg = dsc;
  207                 (void)bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_TTY,
  208                                          bppintr, sc);
  209         }
  210 
  211         /* Allocate buffer XXX - should actually use dmamap_uio() */
  212         dsc->sc_bufsz = 1024;
  213         dsc->sc_buf = malloc(dsc->sc_bufsz, M_DEVBUF, M_NOWAIT);
  214 
  215         /* XXX read default state */
  216         {
  217         bus_space_handle_t h = sc->sc_regs;
  218         struct hwstate *hw = &dsc->sc_hwdefault;
  219         int ack_rate = sa->sa_frequency/1000000;
  220 
  221         hw->hw_hcr = bus_space_read_2(sc->sc_bustag, h, L64854_REG_HCR);
  222         hw->hw_ocr = bus_space_read_2(sc->sc_bustag, h, L64854_REG_OCR);
  223         hw->hw_tcr = bus_space_read_1(sc->sc_bustag, h, L64854_REG_TCR);
  224         hw->hw_or = bus_space_read_1(sc->sc_bustag, h, L64854_REG_OR);
  225 
  226         DPRINTF(("bpp: hcr %x ocr %x tcr %x or %x\n",
  227                  hw->hw_hcr, hw->hw_ocr, hw->hw_tcr, hw->hw_or));
  228         /* Set these to sane values */
  229         hw->hw_hcr = ((ack_rate<<BPP_HCR_DSS_SHFT)&BPP_HCR_DSS_MASK)
  230                 | ((ack_rate<<BPP_HCR_DSW_SHFT)&BPP_HCR_DSW_MASK);
  231         hw->hw_ocr |= BPP_OCR_ACK_OP;
  232         }
  233 }
  234 
  235 void
  236 bpp_setparams(sc, hw)
  237         struct bpp_softc *sc;
  238         struct hwstate *hw;
  239 {
  240         u_int16_t irq;
  241         bus_space_tag_t t = sc->sc_lsi64854.sc_bustag;
  242         bus_space_handle_t h = sc->sc_lsi64854.sc_regs;
  243 
  244         bus_space_write_2(t, h, L64854_REG_HCR, hw->hw_hcr);
  245         bus_space_write_2(t, h, L64854_REG_OCR, hw->hw_ocr);
  246         bus_space_write_1(t, h, L64854_REG_TCR, hw->hw_tcr);
  247         bus_space_write_1(t, h, L64854_REG_OR, hw->hw_or);
  248 
  249         /* Only change IRP settings in interrupt status register */
  250         irq = bus_space_read_2(t, h, L64854_REG_ICR);
  251         irq &= ~BPP_ALLIRP;
  252         irq |= (hw->hw_irq & BPP_ALLIRP);
  253         bus_space_write_2(t, h, L64854_REG_ICR, irq);
  254         DPRINTF(("bpp_setparams: hcr %x ocr %x tcr %x or %x, irq %x\n",
  255                  hw->hw_hcr, hw->hw_ocr, hw->hw_tcr, hw->hw_or, irq));
  256 }
  257 
  258 int
  259 bppopen(dev, flags, mode, p)
  260         dev_t dev;
  261         int flags, mode;
  262         struct proc *p;
  263 {
  264         int unit = BPPUNIT(dev);
  265         struct bpp_softc *sc;
  266         struct lsi64854_softc *lsi;
  267         u_int16_t irq;
  268         int s;
  269 
  270         if (unit >= bpp_cd.cd_ndevs)
  271                 return (ENXIO);
  272         sc = bpp_cd.cd_devs[unit];
  273 
  274         if ((sc->sc_flags & (BPP_OPEN|BPP_XCLUDE)) == (BPP_OPEN|BPP_XCLUDE))
  275                 return (EBUSY);
  276 
  277         lsi = &sc->sc_lsi64854;
  278 
  279         /* Set default parameters */
  280         sc->sc_hwcurrent = sc->sc_hwdefault;
  281         s = splbpp();
  282         bpp_setparams(sc, &sc->sc_hwdefault);
  283         splx(s);
  284 
  285         /* Enable interrupts */
  286         irq = BPP_ERR_IRQ_EN;
  287         irq |= sc->sc_hwdefault.hw_irq;
  288         bus_space_write_2(lsi->sc_bustag, lsi->sc_regs, L64854_REG_ICR, irq);
  289         return (0);
  290 }
  291 
  292 int
  293 bppclose(dev, flags, mode, p)
  294         dev_t dev;
  295         int flags, mode;
  296         struct proc *p;
  297 {
  298         struct bpp_softc *sc = bpp_cd.cd_devs[BPPUNIT(dev)];
  299         struct lsi64854_softc *lsi = &sc->sc_lsi64854;
  300         u_int16_t irq;
  301 
  302         /* Turn off all interrupt enables */
  303         irq = sc->sc_hwdefault.hw_irq | BPP_ALLIRQ;
  304         irq &= ~BPP_ALLEN;
  305         bus_space_write_2(lsi->sc_bustag, lsi->sc_regs, L64854_REG_ICR, irq);
  306 
  307         sc->sc_asyncproc = NULL;
  308         sc->sc_flags = 0;
  309         return (0);
  310 }
  311 
  312 int
  313 bppwrite(dev, uio, flags)
  314         dev_t dev;
  315         struct uio *uio;
  316         int flags;
  317 {
  318         struct bpp_softc *sc = bpp_cd.cd_devs[BPPUNIT(dev)];
  319         struct lsi64854_softc *lsi = &sc->sc_lsi64854;
  320         int error = 0;
  321         int s;
  322 
  323         /*
  324          * Wait until the DMA engine is free.
  325          */
  326         s = splbpp();
  327         while ((sc->sc_flags & BPP_LOCKED) != 0) {
  328                 if ((flags & IO_NDELAY) != 0) {
  329                         splx(s);
  330                         return (EWOULDBLOCK);
  331                 }
  332 
  333                 sc->sc_flags |= BPP_WANT;
  334                 error = tsleep(sc->sc_buf, PZERO|PCATCH, "bppwrite", 0);
  335                 if (error != 0) {
  336                         splx(s);
  337                         return (error);
  338                 }
  339         }
  340         sc->sc_flags |= BPP_LOCKED;
  341         splx(s);
  342 
  343         /*
  344          * Move data from user space into our private buffer
  345          * and start DMA.
  346          */
  347         while (uio->uio_resid > 0) {
  348                 caddr_t bp = sc->sc_buf;
  349                 size_t len = min(sc->sc_bufsz, uio->uio_resid);
  350 
  351                 if ((error = uiomove(bp, len, uio)) != 0)
  352                         break;
  353 
  354                 while (len > 0) {
  355                         u_int8_t tcr;
  356                         size_t size = len;
  357                         DMA_SETUP(lsi, &bp, &len, 0, &size);
  358         
  359 #ifdef DEBUG
  360                         if (bppdebug) { 
  361                                 int i;
  362                                 printf("bpp: writing %ld : ", len);
  363                                 for (i=0; i<len; i++) printf("%c(0x%x)", bp[i], bp[i]);
  364                                 printf("\n");
  365                         }
  366 #endif
  367 
  368                         /* Clear direction control bit */
  369                         tcr = bus_space_read_1(lsi->sc_bustag, lsi->sc_regs,
  370                                                 L64854_REG_TCR);
  371                         tcr &= ~BPP_TCR_DIR;
  372                         bus_space_write_1(lsi->sc_bustag, lsi->sc_regs,
  373                                           L64854_REG_TCR, tcr);
  374 
  375                         /* Enable DMA */
  376                         s = splbpp();
  377                         DMA_GO(lsi);
  378                         error = tsleep(sc, PZERO|PCATCH, "bppdma", 0);
  379                         splx(s);
  380                         if (error != 0)
  381                                 goto out;
  382 
  383                         /* Bail out if bottom half reported an error */
  384                         if ((error = sc->sc_error) != 0)
  385                                 goto out;
  386 
  387                         /* 
  388                          * lsi64854_pp_intr() does this part.
  389                          *
  390                          * len -= size;
  391                          */
  392                 }
  393         }
  394 
  395 out:
  396         DPRINTF(("bpp done %x\n", error));
  397         s = splbpp();
  398         sc->sc_flags &= ~BPP_LOCKED;
  399         if ((sc->sc_flags & BPP_WANT) != 0) {
  400                 sc->sc_flags &= ~BPP_WANT;
  401                 wakeup(sc->sc_buf);
  402         }
  403         splx(s);
  404         return (error);
  405 }
  406 
  407 /* move to header: */
  408 #define BPPIOCSPARAM    _IOW('P', 0x1, struct hwstate)
  409 #define BPPIOCGPARAM    _IOR('P', 0x2, struct hwstate)
  410 
  411 int
  412 bppioctl(dev, cmd, data, flag, p)
  413         dev_t   dev;
  414         u_long  cmd;
  415         caddr_t data;
  416         int     flag;
  417         struct  proc *p;
  418 {
  419         struct bpp_softc *sc = bpp_cd.cd_devs[BPPUNIT(dev)];
  420         struct hwstate *hw, *chw;
  421         int error = 0;
  422         int s;
  423 
  424         switch(cmd) {
  425         case BPPIOCSPARAM:
  426                 chw = &sc->sc_hwcurrent;
  427                 hw = (struct hwstate *)data;
  428 
  429                 /*
  430                  * Extract and store user-settable bits.
  431                  */
  432 #define _bpp_set(reg,mask) do {         \
  433         chw->reg &= ~(mask);            \
  434         chw->reg |= (hw->reg & (mask)); \
  435 } while (0)
  436                 _bpp_set(hw_hcr, BPP_HCR_DSS_MASK|BPP_HCR_DSW_MASK);
  437                 _bpp_set(hw_ocr, BPP_OCR_USER);
  438                 _bpp_set(hw_tcr, BPP_TCR_USER);
  439                 _bpp_set(hw_or,  BPP_OR_USER);
  440                 _bpp_set(hw_irq, BPP_IRQ_USER);
  441 #undef _bpp_set
  442 
  443                 /* Apply settings */
  444                 s = splbpp();
  445                 bpp_setparams(sc, chw);
  446                 splx(s);
  447                 break;
  448         case BPPIOCGPARAM:
  449                 *((struct hwstate *)data) = sc->sc_hwcurrent;
  450                 break;
  451         case TIOCEXCL:
  452                 s = splbpp();
  453                 sc->sc_flags |= BPP_XCLUDE;
  454                 splx(s);
  455                 break;
  456         case TIOCNXCL:
  457                 s = splbpp();
  458                 sc->sc_flags &= ~BPP_XCLUDE;
  459                 splx(s);
  460                 break;
  461         case FIOASYNC:
  462                 s = splbpp();
  463                 if (*(int *)data) {
  464                         if (sc->sc_asyncproc != NULL)
  465                                 error = EBUSY;
  466                         else
  467                                 sc->sc_asyncproc = p;
  468                 } else
  469                         sc->sc_asyncproc = NULL;
  470                 splx(s);
  471                 break;
  472         default:
  473                 break;
  474         }
  475 
  476         return (error);
  477 }
  478 
  479 int
  480 bpppoll(dev, events, p)
  481         dev_t dev;
  482         int events;
  483         struct proc *p;
  484 {
  485         struct bpp_softc *sc = bpp_cd.cd_devs[BPPUNIT(dev)];
  486         int revents = 0;
  487 
  488         if (events & (POLLIN | POLLRDNORM)) {
  489                 /* read is not yet implemented */
  490         }
  491 
  492         if (events & (POLLOUT | POLLWRNORM)) {
  493                 if ((sc->sc_flags & BPP_LOCKED) == 0)
  494                         revents |= (POLLOUT | POLLWRNORM);
  495         }
  496 
  497         if (revents == 0) {
  498                 if (events & (POLLIN | POLLRDNORM))
  499                         selrecord(p, &sc->sc_rsel);
  500                 if (events & (POLLOUT | POLLWRNORM))
  501                         selrecord(p, &sc->sc_wsel);
  502         }
  503 
  504         return (revents);
  505 }
  506 
  507 static void
  508 filt_bpprdetach(struct knote *kn)
  509 {
  510         struct bpp_softc *sc = kn->kn_hook;
  511         int s;
  512 
  513         s = splbpp();
  514         SLIST_REMOVE(&sc->sc_rsel.sel_klist, kn, knote, kn_selnext);
  515         splx(s);
  516 }
  517 
  518 static int
  519 filt_bppread(struct knote *kn, long hint)
  520 {
  521         /* XXX Read not yet implemented. */
  522         return (0);
  523 }
  524 
  525 static const struct filterops bppread_filtops =
  526         { 1, NULL, filt_bpprdetach, filt_bppread };
  527 
  528 static void
  529 filt_bppwdetach(struct knote *kn)
  530 {
  531         struct bpp_softc *sc = kn->kn_hook;
  532         int s;
  533 
  534         s = splbpp();
  535         SLIST_REMOVE(&sc->sc_wsel.sel_klist, kn, knote, kn_selnext);
  536         splx(s);
  537 }
  538 
  539 static int
  540 filt_bpfwrite(struct knote *kn, long hint)
  541 {
  542         struct bpp_softc *sc = kn->kn_hook;
  543 
  544         if (sc->sc_flags & BPP_LOCKED)
  545                 return (0);
  546 
  547         kn->kn_data = 0;        /* XXXLUKEM (thorpej): what to put here? */
  548         return (1);
  549 }
  550 
  551 static const struct filterops bppwrite_filtops =
  552         { 1, NULL, filt_bppwdetach, filt_bpfwrite };
  553 
  554 int
  555 bppkqfilter(dev_t dev, struct knote *kn)
  556 {
  557         struct bpp_softc *sc = bpp_cd.cd_devs[BPPUNIT(dev)];
  558         struct klist *klist;
  559         int s;
  560 
  561         switch (kn->kn_filter) {
  562         case EVFILT_READ:
  563                 klist = &sc->sc_rsel.sel_klist;
  564                 kn->kn_fop = &bppread_filtops;
  565                 break;
  566 
  567         case EVFILT_WRITE:
  568                 klist = &sc->sc_wsel.sel_klist;
  569                 kn->kn_fop = &bppwrite_filtops;
  570                 break;
  571 
  572         default:
  573                 return (1);
  574         }
  575 
  576         kn->kn_hook = sc;
  577 
  578         s = splbpp();
  579         SLIST_INSERT_HEAD(klist, kn, kn_selnext);
  580         splx(s);
  581 
  582         return (0);
  583 }
  584 
  585 int
  586 bppintr(arg)
  587         void *arg;
  588 {
  589         struct bpp_softc *sc = arg;
  590         struct lsi64854_softc *lsi = &sc->sc_lsi64854;
  591         u_int16_t irq;
  592 
  593         /* First handle any possible DMA interrupts */
  594         if (lsi64854_pp_intr((void *)lsi) == -1)
  595                 sc->sc_error = 1;
  596 
  597         irq = bus_space_read_2(lsi->sc_bustag, lsi->sc_regs, L64854_REG_ICR);
  598         /* Ack all interrupts */
  599         bus_space_write_2(lsi->sc_bustag, lsi->sc_regs, L64854_REG_ICR,
  600                           irq | BPP_ALLIRQ);
  601 
  602         DPRINTF(("bpp_intr: %x\n", irq));
  603         /* Did our device interrupt? */
  604         if ((irq & BPP_ALLIRQ) == 0)
  605                 return (0);
  606 
  607         if ((sc->sc_flags & BPP_LOCKED) != 0)
  608                 wakeup(sc);
  609         else if ((sc->sc_flags & BPP_WANT) != 0) {
  610                 sc->sc_flags &= ~BPP_WANT;
  611                 wakeup(sc->sc_buf);
  612         } else {
  613                 selnotify(&sc->sc_wsel, 0);
  614                 if (sc->sc_asyncproc != NULL)
  615                         psignal(sc->sc_asyncproc, SIGIO);
  616         }
  617         return (1);
  618 }

Cache object: c59f5c45516560596b84e505fac27377


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.